From 81e2a8e2898c7a4ceb01291466878fde775802bb Mon Sep 17 00:00:00 2001
From: Manohar Vanga <manohar.vanga@cern.ch>
Date: Wed, 23 Nov 2011 14:56:20 +0100
Subject: [PATCH] simulation: multiple fixes

Fix bugs in release method of device 0.
Change ops to additionally provide bus as argument.
Fix endian issues in bus scanning

Signed-off-by: Manohar Vanga <manohar.vanga@cern.ch>
---
 simulation/Makefile                 |  5 ++-
 simulation/fake_wb_bus.c            |  7 +++-
 simulation/include/linux/wishbone.h | 47 +++++++++++++------------
 simulation/wishbone.c               | 54 ++++++++++++++++++++++++-----
 4 files changed, 80 insertions(+), 33 deletions(-)

diff --git a/simulation/Makefile b/simulation/Makefile
index ac4d9fa..d27471a 100644
--- a/simulation/Makefile
+++ b/simulation/Makefile
@@ -1,7 +1,10 @@
 # Trivial top-level Makefile
 
 
-LINUX ?= $(HOME)/linux-for-wbonesim
+#LINUX ?= $(HOME)/linux-for-wbonesim
+CPU?=L865
+KVER?=2.6.24.7-rt27
+LINUX?=/acc/sys/$(CPU)/usr/src/kernels/$(KVER)
 
 # temporarily, use local <linux/wishbone.h>
 EXTRA_CFLAGS := -I$(obj)/include
diff --git a/simulation/fake_wb_bus.c b/simulation/fake_wb_bus.c
index 637207f..60e71e8 100644
--- a/simulation/fake_wb_bus.c
+++ b/simulation/fake_wb_bus.c
@@ -20,6 +20,7 @@
  * 02110-1301, USA.
  */
 
+#include <linux/version.h>
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/pci.h>
@@ -39,7 +40,7 @@ const struct firmware *wb_fw;
 LIST_HEAD(spec_devices);
 static struct mutex list_lock;
 
-void *fake_read_cfg(wb_addr_t addr, void *buf, size_t len)
+void *fake_read_cfg(struct wb_bus *bus, wb_addr_t addr, void *buf, size_t len)
 {
 	if (wb_fw->size < addr + len)
 		return NULL;
@@ -94,7 +95,11 @@ static void fake_wbbus_release(struct device *dev)
 }
 
 static struct device fake_wbbus_device = {
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29)
+	.bus_id = "fake-wbbus0",
+#else
 	.init_name = "fake-wbbus0",
+#endif
 	.release = fake_wbbus_release,
 };
 
diff --git a/simulation/include/linux/wishbone.h b/simulation/include/linux/wishbone.h
index 7c37b8d..2a32dfa 100644
--- a/simulation/include/linux/wishbone.h
+++ b/simulation/include/linux/wishbone.h
@@ -35,24 +35,24 @@
 #define WB_NO_CLASS ((uint32_t)(~0))
 
 /* Wishbone I/O operations */
-#define wb_readb(bus, addr) bus->ops->read8(addr)
-#define wb_readw(bus, addr) bus->ops->read16(addr)
-#define wb_readl(bus, addr) bus->ops->read32(addr)
-#define wb_readll(bus, addr) bus->ops->read64(addr)
+#define wb_readb(bus, addr) bus->ops->read8(bus, addr)
+#define wb_readw(bus, addr) bus->ops->read16(bus, addr)
+#define wb_readl(bus, addr) bus->ops->read32(bus, addr)
+#define wb_readll(bus, addr) bus->ops->read64(bus, addr)
 
-#define wb_writeb(bus, addr, val) bus->ops->write8(addr, val)
-#define wb_writew(bus, addr, val) bus->ops->write16(addr, val)
-#define wb_writel(bus, addr, val) bus->ops->write32(addr, val)
-#define wb_writell(bus, addr, val) bus->ops->write64(addr, val)
+#define wb_writeb(bus, addr, val) bus->ops->write8(bus, addr, val)
+#define wb_writew(bus, addr, val) bus->ops->write16(bus, addr, val)
+#define wb_writel(bus, addr, val) bus->ops->write32(bus, addr, val)
+#define wb_writell(bus, addr, val) bus->ops->write64(bus, addr, val)
 
 #define memcpy_from_wb(bus, addr, buf, len) \
-	bus->ops->memcpy_from_wb(addr, buf, len)
+	bus->ops->memcpy_from_wb(bus, addr, buf, len)
 
 #define memcpy_to_wb(bus, addr, buf, len) \
-	bus->ops->memcpy_to_wb(addr, buf, len)
+	bus->ops->memcpy_to_wb(bus, addr, buf, len)
 
 #define wb_read_cfg(bus, addr, buf, len) \
-	bus->ops->read_cfg(addr, buf, len)
+	bus->ops->read_cfg(bus, addr, buf, len)
 
 typedef uint64_t wb_addr_t;
 
@@ -103,17 +103,20 @@ struct wb_device {
 #define to_wb_device(dev) container_of(dev, struct wb_device, dev);
 
 struct wb_ops {
-	uint8_t (*read8)(wb_addr_t);
-	uint16_t (*read16)(wb_addr_t);
-	uint32_t (*read32)(wb_addr_t);
-	uint64_t (*read64)(wb_addr_t);
-	void (*write8)(wb_addr_t, uint8_t);
-	void (*write16)(wb_addr_t, uint16_t);
-	void (*write32)(wb_addr_t, uint32_t);
-	void (*write64)(wb_addr_t, uint64_t);
-	void * (*memcpy_from_wb) (wb_addr_t addr, void *buf, size_t len);
-	void * (*memcpy_to_wb) (wb_addr_t addr, const void *buf, size_t len);
-	void * (*read_cfg)(wb_addr_t addr, void *buf, size_t len);
+	uint8_t (*read8)(struct wb_bus *, wb_addr_t);
+	uint16_t (*read16)(struct wb_bus *, wb_addr_t);
+	uint32_t (*read32)(struct wb_bus *, wb_addr_t);
+	uint64_t (*read64)(struct wb_bus *, wb_addr_t);
+	void (*write8)(struct wb_bus *, wb_addr_t, uint8_t);
+	void (*write16)(struct wb_bus *, wb_addr_t, uint16_t);
+	void (*write32)(struct wb_bus *, wb_addr_t, uint32_t);
+	void (*write64)(struct wb_bus *, wb_addr_t, uint64_t);
+	void * (*memcpy_from_wb) (struct wb_bus *, wb_addr_t addr, void *buf,
+		size_t len);
+	void * (*memcpy_to_wb) (struct wb_bus *, wb_addr_t addr,
+		const void *buf, size_t len);
+	void * (*read_cfg)(struct wb_bus *, wb_addr_t addr, void *buf,
+		size_t len);
 };
 
 struct wb_bus {
diff --git a/simulation/wishbone.c b/simulation/wishbone.c
index fa577fa..75c1889 100644
--- a/simulation/wishbone.c
+++ b/simulation/wishbone.c
@@ -36,9 +36,17 @@ static int wb_bus_match(struct device *, struct device_driver *);
 static int wb_drv_probe(struct device *);
 static int wb_drv_remove(struct device *);
 
+static void wb_zero_release(struct device *dev)
+{
+}
+
 static struct device wb_dev_zero = {
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29)
+	.bus_id = "wb0",
+#else
 	.init_name = "wb0",
-	.release = wb_dev_release,
+#endif
+	.release = wb_zero_release,
 };
 
 static struct bus_type wb_bus_type = {
@@ -79,8 +87,13 @@ int wb_register_device(struct wb_device *wbdev)
 	wbdev->dev.bus = &wb_bus_type;
 	wbdev->dev.parent = &wbdev->bus->dev;
 	wbdev->dev.release = wb_dev_release;
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29)
+	snprintf(wbdev->dev.bus_id, BUS_ID_SIZE, "wb%d-%s-%s", devno,
+		wbdev->wbd.vendor_name, wbdev->wbd.device_name);
+#else
 	dev_set_name(&wbdev->dev, "wb%d-%s-%s", devno, wbdev->wbd.vendor_name,
 		wbdev->wbd.device_name);
+#endif
 	INIT_LIST_HEAD(&wbdev->list);
 
 	return device_register(&wbdev->dev);
@@ -132,6 +145,9 @@ static struct wb_device *wb_get_next_device(struct wb_bus *bus, wb_addr_t wb_ptr
         if (wbd.wbd_magic != SDWB_WBD_MAGIC)
 		return NULL;
 
+	wbd.hdl_base = be64_to_cpu(wbd.hdl_base);
+	wbd.hdl_size = be64_to_cpu(wbd.hdl_size);
+
 	wbdev = kzalloc(sizeof(struct wb_device), GFP_KERNEL);
 	if (!wbdev)
 		return NULL;
@@ -142,6 +158,25 @@ static struct wb_device *wb_get_next_device(struct wb_bus *bus, wb_addr_t wb_ptr
 	return wbdev;
 }
 
+void wb_read_sdwb_header(struct wb_bus *bus, struct sdwb_head *head)
+{
+	wb_read_cfg(bus, bus->sdwb_header_base, (void *)head,
+		sizeof(struct sdwb_head));
+	head->wbid_address = be64_to_cpu(head->wbid_address);
+	head->wbd_address = be64_to_cpu(head->wbd_address);
+}
+
+void wb_read_sdwb_id(struct wb_bus *bus, struct sdwb_head *head,
+	struct sdwb_wbid *wbid)
+{
+	wb_read_cfg(bus, head->wbid_address, (void *)wbid,
+		sizeof(struct sdwb_wbid));
+
+	wbid->bstream_type = be64_to_cpu(wbid->bstream_type);
+	wbid->bstream_version = be64_to_cpu(wbid->bstream_version);
+	wbid->bstream_date = be64_to_cpu(wbid->bstream_date);
+}
+
 int wb_scan_bus(struct wb_bus *bus)
 {
 	int ret;
@@ -151,8 +186,7 @@ int wb_scan_bus(struct wb_bus *bus)
 	struct wb_device *wbdev;
 	struct wb_device *next;
 
-	wb_read_cfg(bus, bus->sdwb_header_base, (void *)&head,
-		sizeof(struct sdwb_head));
+	wb_read_sdwb_header(bus, &head);
 
 	/* verify our header using the magic field */
 	if (head.magic != SDWB_HEAD_MAGIC) {
@@ -161,9 +195,8 @@ int wb_scan_bus(struct wb_bus *bus)
 		return -ENODEV;
 	}
 
-	wb_read_cfg(bus, head.wbid_address, (void *)&wbid,
-		sizeof(struct sdwb_wbid));
-	pr_info(KBUILD_MODNAME ": found sdwb bistream: 0x%llx\n",
+	wb_read_sdwb_id(bus, &head, &wbid);
+	pr_info(KBUILD_MODNAME ": found sdwb bitstream: 0x%llx\n",
 		wbid.bstream_type);
 
 	wbd_ptr = head.wbd_address;
@@ -191,7 +224,6 @@ err_wbdev_register:
 	list_for_each_entry_safe(wbdev, next, &bus->devices, list) {
 		list_del(&wbdev->list);
 		wb_unregister_device(wbdev);
-		kfree(wbdev);
 	}
 	bus->ndev = 0;
 
@@ -215,7 +247,12 @@ int wb_register_bus(struct wb_bus *bus)
 	bus->dev.bus = &wb_bus_type;
 	bus->dev.parent = &wb_dev_zero;
 	bus->dev.release = wb_bus_release;
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29)
+	snprintf(bus->dev.bus_id, BUS_ID_SIZE, "wb-bus%d-%s", devno,
+		bus->name);
+#else
 	dev_set_name(&bus->dev, "wb-bus%d-%s", devno, bus->name);
+#endif
 
 	if (device_register(&bus->dev) < 0) {
 		pr_err(KBUILD_MODNAME ": failed to register bus device %d\n",
@@ -243,9 +280,8 @@ void wb_unregister_bus(struct wb_bus *bus)
 	struct wb_device *next;
 
 	list_for_each_entry_safe(wbdev, next, &bus->devices, list) {
-		list_del(&wbdev->list);
 		wb_unregister_device(wbdev);
-		kfree(wbdev);
+		list_del(&wbdev->list);
 	}
 	device_unregister(&bus->dev);
 }
-- 
GitLab