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