[PATCH v3 0/2] Submission of XillyUSB driver
From: Eli Billauer This is a resubmission of the XillyUSB driver, which is the USB variant of the existing Xillybus driver. Because these driver share some API related functions, this submission consists of two patches: (1) A patch moving away Xillybus' class related functions to a separate module file. (2) A patch adding the new XillyUSB driver, based upon this new separate module. As far as I can tell, the shared code between the Xillybus and XillyUSB drivers covers everything that makes sense to share. I submit XillyUSB as a staging driver, with the hope for a detailed review on this issue, as well as a general code audit. Thanks, Eli Eli Billauer (2): char: xillybus: Move class-related functions to new xillybus_class.c staging: Add driver for XillyUSB (Xillybus variant for USB) MAINTAINERS|1 + drivers/char/xillybus/Kconfig |4 + drivers/char/xillybus/Makefile |1 + drivers/char/xillybus/xillybus.h | 10 +- drivers/char/xillybus/xillybus_class.c | 263 +++ drivers/char/xillybus/xillybus_core.c | 181 +- drivers/staging/Kconfig|2 + drivers/staging/Makefile |1 + drivers/staging/xillyusb/Kconfig | 20 + drivers/staging/xillyusb/Makefile |6 + drivers/staging/xillyusb/TODO | 13 + drivers/staging/xillyusb/xillyusb.c| 2184 include/linux/xillybus_class.h | 30 + 13 files changed, 2549 insertions(+), 167 deletions(-) create mode 100644 drivers/char/xillybus/xillybus_class.c create mode 100644 drivers/staging/xillyusb/Kconfig create mode 100644 drivers/staging/xillyusb/Makefile create mode 100644 drivers/staging/xillyusb/TODO create mode 100644 drivers/staging/xillyusb/xillyusb.c create mode 100644 include/linux/xillybus_class.h -- 2.17.1 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v3 1/2] char: xillybus: Move class-related functions to new xillybus_class.c
From: Eli Billauer This patch is a preparation for adding another related driver, XillyUSB. In order to share some code between the existing Xillybus driver and the one to be added, some functions are moved to xillybus_class.c The header file, xillybus_class.h, is temporarily placed in include/linux/, because the new XillyUSB driver is intended as a staging driver for the time being. Signed-off-by: Eli Billauer --- Notes: Changelog: This patch did not exist prior to v3. drivers/char/xillybus/Kconfig | 4 + drivers/char/xillybus/Makefile | 1 + drivers/char/xillybus/xillybus.h | 10 +- drivers/char/xillybus/xillybus_class.c | 263 + drivers/char/xillybus/xillybus_core.c | 181 +++-- include/linux/xillybus_class.h | 30 +++ 6 files changed, 322 insertions(+), 167 deletions(-) create mode 100644 drivers/char/xillybus/xillybus_class.c create mode 100644 include/linux/xillybus_class.h diff --git a/drivers/char/xillybus/Kconfig b/drivers/char/xillybus/Kconfig index 130dbdce858f..e7800f025249 100644 --- a/drivers/char/xillybus/Kconfig +++ b/drivers/char/xillybus/Kconfig @@ -3,10 +3,14 @@ # Xillybus devices # +config XILLYBUS_CLASS + tristate + config XILLYBUS tristate "Xillybus generic FPGA interface" depends on PCI || OF select CRC32 + select XILLYBUS_CLASS help Xillybus is a generic interface for peripherals designed on programmable logic (FPGA). The driver probes the hardware for diff --git a/drivers/char/xillybus/Makefile b/drivers/char/xillybus/Makefile index 099e9a3585fc..591615264591 100644 --- a/drivers/char/xillybus/Makefile +++ b/drivers/char/xillybus/Makefile @@ -3,6 +3,7 @@ # Makefile for Xillybus driver # +obj-$(CONFIG_XILLYBUS_CLASS) += xillybus_class.o obj-$(CONFIG_XILLYBUS) += xillybus_core.o obj-$(CONFIG_XILLYBUS_PCIE)+= xillybus_pcie.o obj-$(CONFIG_XILLYBUS_OF) += xillybus_of.o diff --git a/drivers/char/xillybus/xillybus.h b/drivers/char/xillybus/xillybus.h index 8e3ed4d1bb7f..c63ffc56637c 100644 --- a/drivers/char/xillybus/xillybus.h +++ b/drivers/char/xillybus/xillybus.h @@ -30,7 +30,8 @@ struct xilly_buffer { struct xilly_idt_handle { unsigned char *chandesc; - unsigned char *idt; + unsigned char *names; + int names_len; int entries; }; @@ -94,7 +95,6 @@ struct xilly_endpoint { struct device *dev; struct xilly_endpoint_hardware *ephw; - struct list_head ep_list; int dma_using_dac; /* =1 if 64-bit DMA is used, =0 otherwise. */ __iomem void *registers; int fatal_error; @@ -102,12 +102,6 @@ struct xilly_endpoint { struct mutex register_mutex; wait_queue_head_t ep_wait; - /* Channels and message handling */ - struct cdev cdev; - - int major; - int lowest_minor; /* Highest minor = lowest_minor + num_channels - 1 */ - int num_channels; /* EXCLUDING message buffer */ struct xilly_channel **channels; int msg_counter; diff --git a/drivers/char/xillybus/xillybus_class.c b/drivers/char/xillybus/xillybus_class.c new file mode 100644 index ..f3cfb76623c8 --- /dev/null +++ b/drivers/char/xillybus/xillybus_class.c @@ -0,0 +1,263 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright 2021 Xillybus Ltd, http://xillybus.com + * + * Driver for the Xillybus class + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +MODULE_DESCRIPTION("Driver for Xillybus class"); +MODULE_AUTHOR("Eli Billauer, Xillybus Ltd."); +MODULE_VERSION("1.0"); +MODULE_ALIAS("xillybus_class"); +MODULE_LICENSE("GPL v2"); + +static DEFINE_MUTEX(unit_mutex); +static LIST_HEAD(unit_list); +static struct class *xillybus_class; + +#define UNITNAMELEN 16 + +struct xilly_unit { + struct list_head list_entry; + void *private_data; + + struct cdev *cdev; + char name[UNITNAMELEN]; + int major; + int lowest_minor; + int num_nodes; +}; + +int xillybus_init_chrdev(struct device *dev, +const struct file_operations *fops, +struct module *owner, +void *private_data, +unsigned char *idt, unsigned int len, +int num_nodes, +const char *prefix, bool enumerate) +{ + int rc; + dev_t mdev; + int i; + char devname[48]; + + struct device *device; + size_t namelen; + struct xilly_unit *unit, *u; + + unit = kzalloc(sizeof(*unit), GFP_KERNEL); + + if (!unit) + return -ENOMEM; + + mutex_lock(&unit_mutex); + + if (!enumerate) + snprintf(unit->name, UNITNAMELEN, "%s", prefix); + + for (i = 0;
[PATCH v3 2/2] staging: Add driver for XillyUSB (Xillybus variant for USB)
From: Eli Billauer The XillyUSB driver is the USB variant for the Xillybus FPGA IP core. Even though it presents a nearly identical API on the FPGA and host, it's almost a complete rewrite of the driver: The framework for exchanging data on a USB bus is fundamentally different from doing the same with a PCIe interface, which leaves very little in common between the existing driver and the new one for XillyUSB. Signed-off-by: Eli Billauer --- Notes: Changelog: v3: - Move to staging - Rely on xillybus_class for device file operations - Fix no return value bug in xillyusb_discovery() - Add module parameters for URB buffer size and count v2: - Add comment in Kconfig file, saying XILLYUSB really doesn't depend on XILLYBUS (following comment by Randy Dunlap) - Use SEEK_* predefined constants instead of numbers MAINTAINERS |1 + drivers/staging/Kconfig |2 + drivers/staging/Makefile|1 + drivers/staging/xillyusb/Kconfig| 20 + drivers/staging/xillyusb/Makefile |6 + drivers/staging/xillyusb/TODO | 13 + drivers/staging/xillyusb/xillyusb.c | 2184 +++ 7 files changed, 2227 insertions(+) create mode 100644 drivers/staging/xillyusb/Kconfig create mode 100644 drivers/staging/xillyusb/Makefile create mode 100644 drivers/staging/xillyusb/TODO create mode 100644 drivers/staging/xillyusb/xillyusb.c diff --git a/MAINTAINERS b/MAINTAINERS index d92f85ca831d..1bf73b132e31 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -19749,6 +19749,7 @@ M: Eli Billauer L: linux-ker...@vger.kernel.org S: Supported F: drivers/char/xillybus/ +F: drivers/staging/xillyusb/ XLP9XX I2C DRIVER M: George Cherian diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig index b22f73d7bfc4..6fcbc6f90224 100644 --- a/drivers/staging/Kconfig +++ b/drivers/staging/Kconfig @@ -114,4 +114,6 @@ source "drivers/staging/wfx/Kconfig" source "drivers/staging/hikey9xx/Kconfig" +source "drivers/staging/xillyusb/Kconfig" + endif # STAGING diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile index 2245059e69c7..42dfd6a4ca28 100644 --- a/drivers/staging/Makefile +++ b/drivers/staging/Makefile @@ -47,3 +47,4 @@ obj-$(CONFIG_QLGE)+= qlge/ obj-$(CONFIG_WIMAX)+= wimax/ obj-$(CONFIG_WFX) += wfx/ obj-y += hikey9xx/ +obj-$(CONFIG_XILLYUSB) += xillyusb/ diff --git a/drivers/staging/xillyusb/Kconfig b/drivers/staging/xillyusb/Kconfig new file mode 100644 index ..af7251104b42 --- /dev/null +++ b/drivers/staging/xillyusb/Kconfig @@ -0,0 +1,20 @@ +# SPDX-License-Identifier: GPL-2.0-only +# +# XillyUSB devices +# + +config XILLYUSB + tristate "Xillybus generic FPGA interface for USB" + depends on USB + select CRC32 + select XILLYBUS_CLASS + help + XillyUSB is the Xillybus variant which uses USB for communicating + with the FPGA. + + Xillybus is a generic interface for peripherals designed on + programmable logic (FPGA). The driver probes the hardware for + its capabilities, and creates device files accordingly. + + Set to M if you want Xillybus to use USB for communicating with + the FPGA. diff --git a/drivers/staging/xillyusb/Makefile b/drivers/staging/xillyusb/Makefile new file mode 100644 index ..1b45211992f5 --- /dev/null +++ b/drivers/staging/xillyusb/Makefile @@ -0,0 +1,6 @@ +# SPDX-License-Identifier: GPL-2.0-only +# +# Makefile for XillyUSB driver +# + +obj-$(CONFIG_XILLYUSB) += xillyusb.o diff --git a/drivers/staging/xillyusb/TODO b/drivers/staging/xillyusb/TODO new file mode 100644 index ..0cb6a005ada4 --- /dev/null +++ b/drivers/staging/xillyusb/TODO @@ -0,0 +1,13 @@ +XillyUSB driver +=== + +This driver is the USB counterpart for the driver at drivers/char/xillybus/. +See Documentation/driver-api/xillybus.rst. + +TODO + + - Enhance code reuse with the existing Xillybus driver. + + - General code review. + +Patches to: Eli Billauer \ No newline at end of file diff --git a/drivers/staging/xillyusb/xillyusb.c b/drivers/staging/xillyusb/xillyusb.c new file mode 100644 index ..bcf55c1a380d --- /dev/null +++ b/drivers/staging/xillyusb/xillyusb.c @@ -0,0 +1,2184 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright 2020 Xillybus Ltd, http://xillybus.com + * + * Driver for the XillyUSB FPGA/host framework. + * + * This driver interfaces with a special IP core in an FPGA, setting up + * a pipe between a hardware FIFO in the programmable logic and a device + * file in the host. The number of such pipes and their attributes are + * set up on the logic. This driver detects these automatically and + * creates the device files accordingly. + */ + +#include +#i
Re: [kbuild] Re: [PATCH v3 1/2] char: xillybus: Move class-related functions to new xillybus_class.c
On 09/03/21 18:03, Dan Carpenter wrote: url:https://github.com/0day-ci/linux/commits/eli-billauer-gmail-com/Submission-of-XillyUSB-driver/20210309-193645 base:https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc.git 080951f99de1e483a9a48f34c079b634f2912a54 config: x86_64-randconfig-m001-20210309 (attached as .config) compiler: gcc-9 (Debian 9.3.0-22) 9.3.0 If you fix the issue, kindly add following tag as appropriate Reported-by: kernel test robot Reported-by: Dan Carpenter smatch warnings: drivers/char/xillybus/xillybus_class.c:86 xillybus_init_chrdev() warn: ignoring unreachable code. drivers/char/xillybus/xillybus_class.c:96 xillybus_init_chrdev() warn: missing error code 'rc' Thanks a lot. I guess there's a patch v4 coming up. Regards, Eli ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v4 0/2] Submission of XillyUSB driver
From: Eli Billauer This is a resubmission of the XillyUSB driver, which is the USB variant of the existing Xillybus driver. Because these driver share some API related functions, this submission consists of two patches: (1) A patch moving away Xillybus' class related functions to a separate module file. (2) A patch adding the new XillyUSB driver, based upon this new separate module. As far as I can tell, the shared code between the Xillybus and XillyUSB drivers covers everything that makes sense to share. I submit XillyUSB as a staging driver, with the hope for a detailed review on this issue, as well as a general code audit. Thanks, Eli Eli Billauer (2): char: xillybus: Move class-related functions to new xillybus_class.c staging: Add driver for XillyUSB (Xillybus variant for USB) MAINTAINERS|1 + drivers/char/xillybus/Kconfig |4 + drivers/char/xillybus/Makefile |1 + drivers/char/xillybus/xillybus.h | 10 +- drivers/char/xillybus/xillybus_class.c | 263 +++ drivers/char/xillybus/xillybus_core.c | 181 +- drivers/staging/Kconfig|2 + drivers/staging/Makefile |1 + drivers/staging/xillyusb/Kconfig | 20 + drivers/staging/xillyusb/Makefile |6 + drivers/staging/xillyusb/TODO | 13 + drivers/staging/xillyusb/xillyusb.c| 2184 include/linux/xillybus_class.h | 30 + 13 files changed, 2549 insertions(+), 167 deletions(-) create mode 100644 drivers/char/xillybus/xillybus_class.c create mode 100644 drivers/staging/xillyusb/Kconfig create mode 100644 drivers/staging/xillyusb/Makefile create mode 100644 drivers/staging/xillyusb/TODO create mode 100644 drivers/staging/xillyusb/xillyusb.c create mode 100644 include/linux/xillybus_class.h -- 2.17.1 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v4 1/2] char: xillybus: Move class-related functions to new xillybus_class.c
From: Eli Billauer This patch is a preparation for adding another related driver, XillyUSB. In order to share some code between the existing Xillybus driver and the one to be added, some functions are moved to xillybus_class.c The header file, xillybus_class.h, is temporarily placed in include/linux/, because the new XillyUSB driver is intended as a staging driver for the time being. Signed-off-by: Eli Billauer --- Notes: Changelog: v4: - Fix error code return value bugs in xillybus_init_chrdev() as detected by Smatch test robot, and reported by Dan Carpenter. This patch did not exist prior to v3. drivers/char/xillybus/Kconfig | 4 + drivers/char/xillybus/Makefile | 1 + drivers/char/xillybus/xillybus.h | 10 +- drivers/char/xillybus/xillybus_class.c | 263 + drivers/char/xillybus/xillybus_core.c | 181 +++-- include/linux/xillybus_class.h | 30 +++ 6 files changed, 322 insertions(+), 167 deletions(-) create mode 100644 drivers/char/xillybus/xillybus_class.c create mode 100644 include/linux/xillybus_class.h diff --git a/drivers/char/xillybus/Kconfig b/drivers/char/xillybus/Kconfig index 130dbdce858f..e7800f025249 100644 --- a/drivers/char/xillybus/Kconfig +++ b/drivers/char/xillybus/Kconfig @@ -3,10 +3,14 @@ # Xillybus devices # +config XILLYBUS_CLASS + tristate + config XILLYBUS tristate "Xillybus generic FPGA interface" depends on PCI || OF select CRC32 + select XILLYBUS_CLASS help Xillybus is a generic interface for peripherals designed on programmable logic (FPGA). The driver probes the hardware for diff --git a/drivers/char/xillybus/Makefile b/drivers/char/xillybus/Makefile index 099e9a3585fc..591615264591 100644 --- a/drivers/char/xillybus/Makefile +++ b/drivers/char/xillybus/Makefile @@ -3,6 +3,7 @@ # Makefile for Xillybus driver # +obj-$(CONFIG_XILLYBUS_CLASS) += xillybus_class.o obj-$(CONFIG_XILLYBUS) += xillybus_core.o obj-$(CONFIG_XILLYBUS_PCIE)+= xillybus_pcie.o obj-$(CONFIG_XILLYBUS_OF) += xillybus_of.o diff --git a/drivers/char/xillybus/xillybus.h b/drivers/char/xillybus/xillybus.h index 8e3ed4d1bb7f..c63ffc56637c 100644 --- a/drivers/char/xillybus/xillybus.h +++ b/drivers/char/xillybus/xillybus.h @@ -30,7 +30,8 @@ struct xilly_buffer { struct xilly_idt_handle { unsigned char *chandesc; - unsigned char *idt; + unsigned char *names; + int names_len; int entries; }; @@ -94,7 +95,6 @@ struct xilly_endpoint { struct device *dev; struct xilly_endpoint_hardware *ephw; - struct list_head ep_list; int dma_using_dac; /* =1 if 64-bit DMA is used, =0 otherwise. */ __iomem void *registers; int fatal_error; @@ -102,12 +102,6 @@ struct xilly_endpoint { struct mutex register_mutex; wait_queue_head_t ep_wait; - /* Channels and message handling */ - struct cdev cdev; - - int major; - int lowest_minor; /* Highest minor = lowest_minor + num_channels - 1 */ - int num_channels; /* EXCLUDING message buffer */ struct xilly_channel **channels; int msg_counter; diff --git a/drivers/char/xillybus/xillybus_class.c b/drivers/char/xillybus/xillybus_class.c new file mode 100644 index ..f97edb719df1 --- /dev/null +++ b/drivers/char/xillybus/xillybus_class.c @@ -0,0 +1,263 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright 2021 Xillybus Ltd, http://xillybus.com + * + * Driver for the Xillybus class + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +MODULE_DESCRIPTION("Driver for Xillybus class"); +MODULE_AUTHOR("Eli Billauer, Xillybus Ltd."); +MODULE_VERSION("1.0"); +MODULE_ALIAS("xillybus_class"); +MODULE_LICENSE("GPL v2"); + +static DEFINE_MUTEX(unit_mutex); +static LIST_HEAD(unit_list); +static struct class *xillybus_class; + +#define UNITNAMELEN 16 + +struct xilly_unit { + struct list_head list_entry; + void *private_data; + + struct cdev *cdev; + char name[UNITNAMELEN]; + int major; + int lowest_minor; + int num_nodes; +}; + +int xillybus_init_chrdev(struct device *dev, +const struct file_operations *fops, +struct module *owner, +void *private_data, +unsigned char *idt, unsigned int len, +int num_nodes, +const char *prefix, bool enumerate) +{ + int rc; + dev_t mdev; + int i; + char devname[48]; + + struct device *device; + size_t namelen; + struct xilly_unit *unit, *u; + + unit = kzalloc(sizeof(*unit), GFP_KERNEL); + + if (!unit) + return -ENOMEM;
[PATCH v4 2/2] staging: Add driver for XillyUSB (Xillybus variant for USB)
From: Eli Billauer The XillyUSB driver is the USB variant for the Xillybus FPGA IP core. Even though it presents a nearly identical API on the FPGA and host, it's almost a complete rewrite of the driver: The framework for exchanging data on a USB bus is fundamentally different from doing the same with a PCIe interface, which leaves very little in common between the existing driver and the new one for XillyUSB. Signed-off-by: Eli Billauer --- Notes: Changelog: v4: (No changes) v3: - Move to staging - Rely on xillybus_class for device file operations - Fix no return value bug in xillyusb_discovery() - Add module parameters for URB buffer size and count v2: - Add comment in Kconfig file, saying XILLYUSB really doesn't depend on XILLYBUS (following comment by Randy Dunlap) - Use SEEK_* predefined constants instead of numbers MAINTAINERS |1 + drivers/staging/Kconfig |2 + drivers/staging/Makefile|1 + drivers/staging/xillyusb/Kconfig| 20 + drivers/staging/xillyusb/Makefile |6 + drivers/staging/xillyusb/TODO | 13 + drivers/staging/xillyusb/xillyusb.c | 2184 +++ 7 files changed, 2227 insertions(+) create mode 100644 drivers/staging/xillyusb/Kconfig create mode 100644 drivers/staging/xillyusb/Makefile create mode 100644 drivers/staging/xillyusb/TODO create mode 100644 drivers/staging/xillyusb/xillyusb.c diff --git a/MAINTAINERS b/MAINTAINERS index d92f85ca831d..1bf73b132e31 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -19749,6 +19749,7 @@ M: Eli Billauer L: linux-ker...@vger.kernel.org S: Supported F: drivers/char/xillybus/ +F: drivers/staging/xillyusb/ XLP9XX I2C DRIVER M: George Cherian diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig index b22f73d7bfc4..6fcbc6f90224 100644 --- a/drivers/staging/Kconfig +++ b/drivers/staging/Kconfig @@ -114,4 +114,6 @@ source "drivers/staging/wfx/Kconfig" source "drivers/staging/hikey9xx/Kconfig" +source "drivers/staging/xillyusb/Kconfig" + endif # STAGING diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile index 2245059e69c7..42dfd6a4ca28 100644 --- a/drivers/staging/Makefile +++ b/drivers/staging/Makefile @@ -47,3 +47,4 @@ obj-$(CONFIG_QLGE)+= qlge/ obj-$(CONFIG_WIMAX)+= wimax/ obj-$(CONFIG_WFX) += wfx/ obj-y += hikey9xx/ +obj-$(CONFIG_XILLYUSB) += xillyusb/ diff --git a/drivers/staging/xillyusb/Kconfig b/drivers/staging/xillyusb/Kconfig new file mode 100644 index ..af7251104b42 --- /dev/null +++ b/drivers/staging/xillyusb/Kconfig @@ -0,0 +1,20 @@ +# SPDX-License-Identifier: GPL-2.0-only +# +# XillyUSB devices +# + +config XILLYUSB + tristate "Xillybus generic FPGA interface for USB" + depends on USB + select CRC32 + select XILLYBUS_CLASS + help + XillyUSB is the Xillybus variant which uses USB for communicating + with the FPGA. + + Xillybus is a generic interface for peripherals designed on + programmable logic (FPGA). The driver probes the hardware for + its capabilities, and creates device files accordingly. + + Set to M if you want Xillybus to use USB for communicating with + the FPGA. diff --git a/drivers/staging/xillyusb/Makefile b/drivers/staging/xillyusb/Makefile new file mode 100644 index ..1b45211992f5 --- /dev/null +++ b/drivers/staging/xillyusb/Makefile @@ -0,0 +1,6 @@ +# SPDX-License-Identifier: GPL-2.0-only +# +# Makefile for XillyUSB driver +# + +obj-$(CONFIG_XILLYUSB) += xillyusb.o diff --git a/drivers/staging/xillyusb/TODO b/drivers/staging/xillyusb/TODO new file mode 100644 index ..0cb6a005ada4 --- /dev/null +++ b/drivers/staging/xillyusb/TODO @@ -0,0 +1,13 @@ +XillyUSB driver +=== + +This driver is the USB counterpart for the driver at drivers/char/xillybus/. +See Documentation/driver-api/xillybus.rst. + +TODO + + - Enhance code reuse with the existing Xillybus driver. + + - General code review. + +Patches to: Eli Billauer \ No newline at end of file diff --git a/drivers/staging/xillyusb/xillyusb.c b/drivers/staging/xillyusb/xillyusb.c new file mode 100644 index ..bcf55c1a380d --- /dev/null +++ b/drivers/staging/xillyusb/xillyusb.c @@ -0,0 +1,2184 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright 2020 Xillybus Ltd, http://xillybus.com + * + * Driver for the XillyUSB FPGA/host framework. + * + * This driver interfaces with a special IP core in an FPGA, setting up + * a pipe between a hardware FIFO in the programmable logic and a device + * file in the host. The number of such pipes and their attributes are + * set up on the logic. This driver detects these automatically and + * creates the device files a
Re: [PATCH v4 2/2] staging: Add driver for XillyUSB (Xillybus variant for USB)
Hello, Greg. Thanks for your comments. I'd like to address a couple of them. First, there's the lockless FIFO that is implemented in the driver: On 21/03/21 14:23, Greg KH wrote: + +static unsigned int fifo_read(struct xillyfifo *fifo, + void *data, unsigned int len, + int (*copier)(void *, const void *, int)) +{ + unsigned int done = 0; + unsigned int todo = len; + unsigned int fill; + unsigned int readpos = fifo->readpos; + unsigned int readbuf = fifo->readbuf; + + fill = atomic_read(&fifo->fill); And the number changed right after reading it :( Again, no atomics, use a lock please. This is a USB device, you are NOT doing high-speed data transfers at all. The current XillyUSB hardware is USB 3.0 based, running at ~400 MB/s, and this is just the beginning. For comparison, when the PCIe-based Xillybus started at 200 MB/s, I didn't believe it would reach 6.6 GB/s. So that's why I made the effort to implement a lockless FIFO, with all the extra synchronization fuss. And yes, it works perfectly, and has been heavily fuzz tested on an x86_64 machine. The memory barriers are carefully placed to make this work on less favorable platforms as well, but even if I got it wrong -- odds are that the fix will be a line or two. Replacing atomics with spinlocks is a piece of cake, of course. But given this extra information, do you still think it's a good idea? As for the specific remark on fifo->fill changing after reading it -- that's OK, since it would just mean that the reader of the FIFO doesn't see the extra data that has just been written to it. This doesn't break anything. Moving on to the second topic: +static loff_t xillyusb_llseek(struct file *filp, loff_t offset, int whence) USB devices do not have a "seek", why is this needed? Xillybus' device nodes are optionally seekable, which gives the user application access to a RAM array on the FPGA (or logic emulating it, such as registers). This holds true for the existing Xillybus API as well as the one for XillyUSB. Thanks and regards, Eli ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [PATCH v4 1/2] char: xillybus: Move class-related functions to new xillybus_class.c
On 21/03/21 14:24, Greg KH wrote: +config XILLYBUS_CLASS > + tristate > + >config XILLYBUS >tristate "Xillybus generic FPGA interface" >depends on PCI || OF >select CRC32 > + select XILLYBUS_CLASS depends on, do not select. XILLYBUS and XILLYBUS_PCIE are currently enabled as M in several Linux distributions. Making them depend on, rather than select XILLYBUS_CLASS is likely to disable the driver in those distributions. With "select", "make oldconfig" sets XILLYBUS_CLASS to the correct value smoothly and silently. Besides, isn't this the intended use case for "select"? A config symbol that doesn't depend on anything else, and solves a technical need to compile Y if X is enabled? Or is there a way to use "depends on" without this problem? Regards, Eli ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [PATCH v4 1/2] char: xillybus: Move class-related functions to new xillybus_class.c
On 22/03/21 13:11, Greg KH wrote: XILLYBUS and XILLYBUS_PCIE are currently enabled as M in several Linux distributions. Making them depend on, rather than select XILLYBUS_CLASS is likely to disable the driver in those distributions. That's not an issue here, depends-on will allow those distros to also enable this option. But wait, why is this a separate option at all? Shouldn't the class code just be part of the "core" XILLYBUS code anyway? I'll try to explain the whole picture: XILLYBUS_CLASS /\ | | XILLYBUS XILLYUSB / \ | | XILLYBUS_PCIE XILLYBUS_OF XILLYBUS_CLASS is new and common to all drivers in this group. XILLYBUS is for drivers based upon memory registers + DMA-based interfaces, and it's combined with XILLYBUS_PCIE and/or XILLYBUS_OF. XILLYUSB is for the USB variant only. Or a more detailed, bottom-up outline: * CONFIG_XILLYBUS_PCIE -> xillybus_pcie.c: Functions related to PCIe. * CONFIG_XILLYBUS_OF -> xillybus_of.c: Functions related to Xillybus as a peripheral on an FPGA / Processor combo chip. * CONFIG_XILLYBUS -> xillybus_core.c: Functions that are common to the two above, mainly access to the peripheral with memory-mapped registers and DMA. * CONFIG_XILLYUSB -> xillyusb.c: The driver for the USB variant, accesses the peripheral through the USB framework. * CONFIG_XILLYBUS_CLASS -> xillybus_class.c: The new module, which contains the class and API parts that would otherwise appear both in xillybus_core.c and xillyusb.c. Contains utility functions for the two latter. Because XILLYBUS_CLASS is new and "N" by default, making a "depends on" relationship means that "make olddefconfig" silently turns off CONFIG_XILLYBUS and CONFIG_XILLYBUS_PCIE. That's a bug: Adding a new driver shouldn't change anything in the existing configuration. That's why I had the "select XILLYBUS_CLASS" to begin with: It ensures a smooth transition on a kernel upgrade, by adding XILLYBUS_CLASS to kernels that had CONFIG_XILLYBUS enabled. Is there another way to prevent the said bug, without "select"? Thanks and regards, Eli ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH] staging: Add xillyusb driver (Xillybus variant for USB)
From: Eli Billauer Xillybus is a means for exchanging data between an FPGA and a Linux host, which helps making the task easier on both sides. The already existing driver resides in drivers/char/xillybus/ and it supports communication with the FPGA over the PCIe bus. For Xilinx' Zynq-7000 processors, it also supports the device's native AXI3 bus. The XillyUSB driver, which is added with this patch as a staging driver, uses the USB transport for communicating with the FPGA. Even though it presents a nearly identical API on the FPGA and host, it's almost a complete rewrite of the driver: The framework for exchanging data on a USB bus is fundamentally different from doing the same with a PCIe interface, which leaves very little in common between the existing driver and the new one for XillyUSB. Signed-off-by: Eli Billauer --- MAINTAINERS |1 + drivers/staging/Kconfig |2 + drivers/staging/Makefile|1 + drivers/staging/xillyusb/Kconfig| 19 + drivers/staging/xillyusb/Makefile |6 + drivers/staging/xillyusb/xillyusb.c | 2363 +++ 6 files changed, 2392 insertions(+) create mode 100644 drivers/staging/xillyusb/Kconfig create mode 100644 drivers/staging/xillyusb/Makefile create mode 100644 drivers/staging/xillyusb/xillyusb.c diff --git a/MAINTAINERS b/MAINTAINERS index 2ac5688db43a..e30d87e09fe4 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -19263,6 +19263,7 @@ M: Eli Billauer L: linux-ker...@vger.kernel.org S: Supported F: drivers/char/xillybus/ +F: drivers/staging/xillyusb/ XLP9XX I2C DRIVER M: George Cherian diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig index c42708e60afc..b796580b20f7 100644 --- a/drivers/staging/Kconfig +++ b/drivers/staging/Kconfig @@ -116,4 +116,6 @@ source "drivers/staging/wfx/Kconfig" source "drivers/staging/hikey9xx/Kconfig" +source "drivers/staging/xillyusb/Kconfig" + endif # STAGING diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile index ebcc646d7b51..5229657194b7 100644 --- a/drivers/staging/Makefile +++ b/drivers/staging/Makefile @@ -48,3 +48,4 @@ obj-$(CONFIG_QLGE)+= qlge/ obj-$(CONFIG_WIMAX)+= wimax/ obj-$(CONFIG_WFX) += wfx/ obj-y += hikey9xx/ +obj-$(CONFIG_XILLYUSB) += xillyusb/ diff --git a/drivers/staging/xillyusb/Kconfig b/drivers/staging/xillyusb/Kconfig new file mode 100644 index ..16ca1c7e5f97 --- /dev/null +++ b/drivers/staging/xillyusb/Kconfig @@ -0,0 +1,19 @@ +# SPDX-License-Identifier: GPL-2.0-only +# +# XillyUSB devices +# + +config XILLYUSB + tristate "Xillybus generic FPGA interface for USB" + depends on USB + select CRC32 + help + XillyUSB is the Xillybus variant which uses USB for communicating + with the FPGA. + + Xillybus is a generic interface for peripherals designed on + programmable logic (FPGA). The driver probes the hardware for + its capabilities, and creates device files accordingly. + + Set to M if you want Xillybus to use USB for communicating with + the FPGA. diff --git a/drivers/staging/xillyusb/Makefile b/drivers/staging/xillyusb/Makefile new file mode 100644 index ..1b45211992f5 --- /dev/null +++ b/drivers/staging/xillyusb/Makefile @@ -0,0 +1,6 @@ +# SPDX-License-Identifier: GPL-2.0-only +# +# Makefile for XillyUSB driver +# + +obj-$(CONFIG_XILLYUSB) += xillyusb.o diff --git a/drivers/staging/xillyusb/xillyusb.c b/drivers/staging/xillyusb/xillyusb.c new file mode 100644 index ..58f007e742e3 --- /dev/null +++ b/drivers/staging/xillyusb/xillyusb.c @@ -0,0 +1,2363 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright 2020 Xillybus Ltd, http://xillybus.com + * + * Driver for the XillyUSB FPGA/host framework. + * + * This driver interfaces with a special IP core in an FPGA, setting up + * a pipe between a hardware FIFO in the programmable logic and a device + * file in the host. The number of such pipes and their attributes are + * set up on the logic. This driver detects these automatically and + * creates the device files accordingly. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +MODULE_DESCRIPTION("Driver for XillyUSB FPGA IP Core"); +MODULE_AUTHOR("Eli Billauer, Xillybus Ltd."); +MODULE_VERSION("1.0"); +MODULE_ALIAS("xillyusb"); +MODULE_LICENSE("GPL v2"); + +#define XILLY_RX_TIMEOUT (10 * HZ / 1000) +#define XILLY_RESPONSE_TIMEOUT (500 * HZ / 1000) + +#define MAX_XILLYUSB_DEVS 64 +#define BUF_SIZE_ORDER 4 +#define BUFNUM 8 +#define LOG2_IDT_FIFO_SIZE 16 +#define LOG2_INITIAL_FIFO_BUF_SIZE 16 +
Re: [PATCH] staging: Add xillyusb driver (Xillybus variant for USB)
Hello Greg, There's no TODO file because it would have been empty: There is nothing to do, as far as I know. I submitted this to staging because I failed to push the Xillybus driver to non-staging back in 2013. In the end, the way in was through staging + a review that got it out a year later or so. So I expected the same story. I'll submit a patch for this driver to char/xillybus/ soon. Thanks, Eli On 13/12/20 16:41, Greg KH wrote: Why add this driver to staging? All drivers in staging need a TODO file that lists what is needed to be done to it in order to get it out of staging. Why not just submit it to the "real" part of the kernel? thanks, greg k-h ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [PATCH] staging/xillybus: Handle OOM in xillybus_init()
Hi, I stand (shamefully) corrected. Thanks. Eli On 19/03/14 01:07, Richard Weinberger wrote: alloc_workqueue() can fail and returns NULL in case of OOM. Handle this case and undo class_create(). Signed-off-by: Richard Weinberger --- drivers/staging/xillybus/xillybus_core.c | 6 +- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/staging/xillybus/xillybus_core.c b/drivers/staging/xillybus/xillybus_core.c index 2ebaf16..b0a6696 100644 --- a/drivers/staging/xillybus/xillybus_core.c +++ b/drivers/staging/xillybus/xillybus_core.c @@ -2318,8 +2318,12 @@ static int __init xillybus_init(void) } xillybus_wq = alloc_workqueue(xillyname, 0, 0); + if (!xillybus_wq) { + class_destroy(xillybus_class); + rc = -ENOMEM; + } - return 0; /* Success */ + return rc; } static void __exit xillybus_exit(void) ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 2/2] staging: xillybus: XILLYBUS_PCIE depends on PCI_MSI
xillybus_pcie.c will compile and load properly on PCI only, but will do nothing useful without PCI_MSI. PCI_MSI depends on PCI, so depending on PCI_MSI covers both. Signed-off-by: Eli Billauer --- drivers/staging/xillybus/Kconfig |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/drivers/staging/xillybus/Kconfig b/drivers/staging/xillybus/Kconfig index 1b88330..b53bdf1 100644 --- a/drivers/staging/xillybus/Kconfig +++ b/drivers/staging/xillybus/Kconfig @@ -17,7 +17,7 @@ if XILLYBUS config XILLYBUS_PCIE tristate "Xillybus over PCIe" - depends on PCI + depends on PCI_MSI help Set to M if you want Xillybus to use PCI Express for communicating with the FPGA. -- 1.7.2.3 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 1/2] staging: xillybus: Added "select CRC32" for XILLYBUS in Kconfig
Reason: xillybus_core.c uses crc32_le() Reported-by: Fengguang Wu Signed-off-by: Eli Billauer --- drivers/staging/xillybus/Kconfig |1 + 1 files changed, 1 insertions(+), 0 deletions(-) diff --git a/drivers/staging/xillybus/Kconfig b/drivers/staging/xillybus/Kconfig index 75c38c8..1b88330 100644 --- a/drivers/staging/xillybus/Kconfig +++ b/drivers/staging/xillybus/Kconfig @@ -5,6 +5,7 @@ config XILLYBUS tristate "Xillybus generic FPGA interface" depends on PCI || (OF_ADDRESS && OF_IRQ) + select CRC32 help Xillybus is a generic interface for peripherals designed on programmable logic (FPGA). The driver probes the hardware for -- 1.7.2.3 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [PATCH 2/2] Staging: xillybus: fix for quoted string split across lines
Hello Greg, On 16/10/13 21:06, Greg KH wrote: rc = of_address_to_resource(dev->of_node, 0,&endpoint->res); >if (rc) { > - pr_warn("xillybus: Failed to obtain device tree " > - "resource\n"); > + pr_warn("xillybus: Failed to obtain device tree resource\n"); This should be using dev_warn() instead. So I understand that I should replace *all* occurrences of pr_warn() and pr_err() with their dev_* counterparts? If so, please give me a week or so to handle that. It's going to be rather chunky patch... Regards, Eli ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 1/4] staging: xillybus: Remember device pointer for use with dev_* functions
This is necessary so that xillybus_core uses the correct device pointer for PCIe devices in diagnostic message calls (dev_err, dev_warn and dev_info) Signed-off-by: Eli Billauer --- drivers/staging/xillybus/xillybus_pcie.c |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/drivers/staging/xillybus/xillybus_pcie.c b/drivers/staging/xillybus/xillybus_pcie.c index 6701365..bf26f68 100644 --- a/drivers/staging/xillybus/xillybus_pcie.c +++ b/drivers/staging/xillybus/xillybus_pcie.c @@ -134,7 +134,7 @@ static int xilly_probe(struct pci_dev *pdev, struct xilly_endpoint *endpoint; int rc = 0; - endpoint = xillybus_init_endpoint(pdev, NULL, &pci_hw); + endpoint = xillybus_init_endpoint(pdev, &pdev->dev, &pci_hw); if (!endpoint) return -ENOMEM; -- 1.7.2.3 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 4/4] staging: xillybus: Use dev_* functions instead of pr_* in xillybus_core
Suggested-by: Greg Kroah-Hartman Signed-off-by: Eli Billauer --- drivers/staging/xillybus/xillybus_core.c | 115 ++ 1 files changed, 69 insertions(+), 46 deletions(-) diff --git a/drivers/staging/xillybus/xillybus_core.c b/drivers/staging/xillybus/xillybus_core.c index e77fb28..2ebaf16 100644 --- a/drivers/staging/xillybus/xillybus_core.c +++ b/drivers/staging/xillybus/xillybus_core.c @@ -101,7 +101,7 @@ static struct workqueue_struct *xillybus_wq; * wr_mutex -> rd_mutex -> register_mutex -> wr_spinlock -> rd_spinlock */ -static void malformed_message(u32 *buf) +static void malformed_message(struct xilly_endpoint *endpoint, u32 *buf) { int opcode; int msg_channel, msg_bufno, msg_data, msg_dir; @@ -112,8 +112,9 @@ static void malformed_message(u32 *buf) msg_bufno = (buf[0] >> 12) & 0x3ff; msg_data = buf[1] & 0xfff; - pr_warn("xillybus: Malformed message (skipping): opcode=%d, channel=%03x, dir=%d, bufno=%03x, data=%07x\n", - opcode, msg_channel, msg_dir, msg_bufno, msg_data); + dev_warn(endpoint->dev, +"Malformed message (skipping): opcode=%d, channel=%03x, dir=%d, bufno=%03x, data=%07x\n", +opcode, msg_channel, msg_dir, msg_bufno, msg_data); } /* @@ -151,14 +152,16 @@ irqreturn_t xillybus_isr(int irq, void *data) for (i = 0; i < buf_size; i += 2) if (((buf[i+1] >> 28) & 0xf) != ep->msg_counter) { - malformed_message(&buf[i]); - pr_warn("xillybus: Sending a NACK on counter %x (instead of %x) on entry %d\n", + malformed_message(ep, &buf[i]); + dev_warn(ep->dev, +"Sending a NACK on counter %x (instead of %x) on entry %d\n", ((buf[i+1] >> 28) & 0xf), ep->msg_counter, i/2); if (++ep->failed_messages > 10) - pr_err("xillybus: Lost sync with interrupt messages. Stopping.\n"); + dev_err(ep->dev, + "Lost sync with interrupt messages. Stopping.\n"); else { ep->ephw->hw_sync_sgl_for_device( ep, @@ -174,7 +177,7 @@ irqreturn_t xillybus_isr(int irq, void *data) break; if (i >= buf_size) { - pr_err("xillybus: Bad interrupt message. Stopping.\n"); + dev_err(ep->dev, "Bad interrupt message. Stopping.\n"); return IRQ_HANDLED; } @@ -193,7 +196,7 @@ irqreturn_t xillybus_isr(int irq, void *data) if ((msg_channel > ep->num_channels) || (msg_channel == 0)) { - malformed_message(&buf[i]); + malformed_message(ep, &buf[i]); break; } @@ -201,7 +204,7 @@ irqreturn_t xillybus_isr(int irq, void *data) if (msg_dir) { /* Write channel */ if (msg_bufno >= channel->num_wr_buffers) { - malformed_message(&buf[i]); + malformed_message(ep, &buf[i]); break; } spin_lock(&channel->wr_spinlock); @@ -218,7 +221,7 @@ irqreturn_t xillybus_isr(int irq, void *data) /* Read channel */ if (msg_bufno >= channel->num_rd_buffers) { - malformed_message(&buf[i]); + malformed_message(ep, &buf[i]); break; } @@ -240,14 +243,14 @@ irqreturn_t xillybus_isr(int irq, void *data) if ((msg_channel > ep->num_channels) || (msg_channel == 0) || (!msg_dir) || !ep->channels[msg_channel]->wr_supports_nonempty) { - malformed_message(&buf[i]); + malformed_message(ep, &buf[i]); break; } channel = ep->channels[msg_channel]; if (msg_bufno >= channel->num_wr_buffers) { - malformed_message(&buf[i]); + malformed_message(e
[PATCH 3/4] staging: xillybus: Use dev_* functions instead of pr_* in xillybus_of
Suggested-by: Greg Kroah-Hartman Signed-off-by: Eli Billauer --- drivers/staging/xillybus/xillybus_of.c | 14 -- 1 files changed, 8 insertions(+), 6 deletions(-) diff --git a/drivers/staging/xillybus/xillybus_of.c b/drivers/staging/xillybus/xillybus_of.c index 2ae045e..394bfea 100644 --- a/drivers/staging/xillybus/xillybus_of.c +++ b/drivers/staging/xillybus/xillybus_of.c @@ -117,14 +117,15 @@ static int xilly_drv_probe(struct platform_device *op) rc = of_address_to_resource(dev->of_node, 0, &endpoint->res); if (rc) { - pr_warn("xillybus: Failed to obtain device tree " - "resource\n"); + dev_warn(endpoint->dev, +"Failed to obtain device tree resource\n"); goto failed_request_regions; } if (!request_mem_region(endpoint->res.start, resource_size(&endpoint->res), xillyname)) { - pr_err("xillybus: request_mem_region failed. Aborting.\n"); + dev_err(endpoint->dev, + "request_mem_region failed. Aborting.\n"); rc = -EBUSY; goto failed_request_regions; } @@ -132,7 +133,8 @@ static int xilly_drv_probe(struct platform_device *op) endpoint->registers = of_iomap(dev->of_node, 0); if (!endpoint->registers) { - pr_err("xillybus: Failed to map I/O memory. Aborting.\n"); + dev_err(endpoint->dev, + "Failed to map I/O memory. Aborting.\n"); goto failed_iomap0; } @@ -141,8 +143,8 @@ static int xilly_drv_probe(struct platform_device *op) rc = request_irq(irq, xillybus_isr, 0, xillyname, endpoint); if (rc) { - pr_err("xillybus: Failed to register IRQ handler. " - "Aborting.\n"); + dev_err(endpoint->dev, + "Failed to register IRQ handler. Aborting.\n"); rc = -ENODEV; goto failed_register_irq; } -- 1.7.2.3 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 2/4] staging: xillybus: Use dev_* functions instead of pr_* in xillybus_pcie
Suggested-by: Greg Kroah-Hartman Signed-off-by: Eli Billauer --- drivers/staging/xillybus/xillybus_pcie.c | 25 - 1 files changed, 12 insertions(+), 13 deletions(-) diff --git a/drivers/staging/xillybus/xillybus_pcie.c b/drivers/staging/xillybus/xillybus_pcie.c index bf26f68..1811aa7 100644 --- a/drivers/staging/xillybus/xillybus_pcie.c +++ b/drivers/staging/xillybus/xillybus_pcie.c @@ -148,29 +148,29 @@ static int xilly_probe(struct pci_dev *pdev, pci_disable_link_state(pdev, PCIE_LINK_STATE_L0S); if (rc) { - pr_err("xillybus: pci_enable_device() failed. " - "Aborting.\n"); + dev_err(endpoint->dev, + "pci_enable_device() failed. Aborting.\n"); goto no_enable; } if (!(pci_resource_flags(pdev, 0) & IORESOURCE_MEM)) { - pr_err("xillybus: Incorrect BAR configuration. " - "Aborting.\n"); + dev_err(endpoint->dev, + "Incorrect BAR configuration. Aborting.\n"); rc = -ENODEV; goto bad_bar; } rc = pci_request_regions(pdev, xillyname); if (rc) { - pr_err("xillybus: pci_request_regions() failed. " - "Aborting.\n"); + dev_err(endpoint->dev, + "pci_request_regions() failed. Aborting.\n"); goto failed_request_regions; } endpoint->registers = pci_iomap(pdev, 0, 128); if (!endpoint->registers) { - pr_err("xillybus: Failed to map BAR 0. Aborting.\n"); + dev_err(endpoint->dev, "Failed to map BAR 0. Aborting.\n"); goto failed_iomap0; } @@ -178,16 +178,16 @@ static int xilly_probe(struct pci_dev *pdev, /* Set up a single MSI interrupt */ if (pci_enable_msi(pdev)) { - pr_err("xillybus: Failed to enable MSI interrupts. " - "Aborting.\n"); + dev_err(endpoint->dev, + "Failed to enable MSI interrupts. Aborting.\n"); rc = -ENODEV; goto failed_enable_msi; } rc = request_irq(pdev->irq, xillybus_isr, 0, xillyname, endpoint); if (rc) { - pr_err("xillybus: Failed to register MSI handler. " - "Aborting.\n"); + dev_err(endpoint->dev, + "Failed to register MSI handler. Aborting.\n"); rc = -ENODEV; goto failed_register_msi; } @@ -202,8 +202,7 @@ static int xilly_probe(struct pci_dev *pdev, if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) endpoint->dma_using_dac = 0; else { - pr_err("xillybus: Failed to set DMA mask. " - "Aborting.\n"); + dev_err(endpoint->dev, "Failed to set DMA mask. Aborting.\n"); rc = -ENODEV; goto failed_dmamask; } -- 1.7.2.3 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH] staging: xillybus: Removed force to be a module
The driver was forced to "module only" following a previous failure to build into the kernel. The problem was resolved several months ago. This has been successfully tested with "make allyesconfig" on x86_64. Reported-by: Stephen Rothwell Signed-off-by: Eli Billauer --- drivers/staging/xillybus/Kconfig |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/drivers/staging/xillybus/Kconfig b/drivers/staging/xillybus/Kconfig index b15f778..75c38c8 100644 --- a/drivers/staging/xillybus/Kconfig +++ b/drivers/staging/xillybus/Kconfig @@ -4,7 +4,7 @@ config XILLYBUS tristate "Xillybus generic FPGA interface" - depends on PCI || (OF_ADDRESS && OF_IRQ) && m + depends on PCI || (OF_ADDRESS && OF_IRQ) help Xillybus is a generic interface for peripherals designed on programmable logic (FPGA). The driver probes the hardware for -- 1.7.2.3 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [PATCH -next] staging: xillybus: fix error return code in xilly_probe()
Thanks for reporting this bug. The same bug exists in the driver for OF (xillybus_of.c). As for the choice of -EIO, I've surveyed several drivers calling of_iomap() and pci_iomap(), and it turns out that some fail on -ENOMEM, some on -EIO and some on -EBUSY. Personally, I'm inclined towards -ENOMEM, since the problem is a memory mapping failure. I'll submit a patch fixing both files soon. Thanks again, Eli On 16/12/13 12:06, Jingoo Han wrote: On Monday, December 16, 2013 2:51 PM, Wei Yongjun wrote: From: Wei Yongjun Fix to return negative error code -EIO from the error handling case instead of 0. Signed-off-by: Wei Yongjun --- drivers/staging/xillybus/xillybus_pcie.c | 2 +- It looks good. Reviewed-by: Jingoo Han Best regards, Jingoo Han 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/xillybus/xillybus_pcie.c b/drivers/staging/xillybus/xillybus_pcie.c index 0564f97..51426d8 100644 --- a/drivers/staging/xillybus/xillybus_pcie.c +++ b/drivers/staging/xillybus/xillybus_pcie.c @@ -168,9 +168,9 @@ static int xilly_probe(struct pci_dev *pdev, } endpoint->registers = pci_iomap(pdev, 0, 128); - if (!endpoint->registers) { dev_err(endpoint->dev, "Failed to map BAR 0. Aborting.\n"); + rc = -EIO; goto failed_iomap0; } ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH] staging: xillybus: Return -ENOMEM if *_iomap fails instead of 0
Bug fix: The error code was not set, so the error condition wasn't reflected in the return value. Reported-by: Wei Yongjun Signed-off-by: Eli Billauer --- drivers/staging/xillybus/xillybus_of.c |2 +- drivers/staging/xillybus/xillybus_pcie.c |2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/xillybus/xillybus_of.c b/drivers/staging/xillybus/xillybus_of.c index 394bfea..97fbcf4 100644 --- a/drivers/staging/xillybus/xillybus_of.c +++ b/drivers/staging/xillybus/xillybus_of.c @@ -131,10 +131,10 @@ static int xilly_drv_probe(struct platform_device *op) } endpoint->registers = of_iomap(dev->of_node, 0); - if (!endpoint->registers) { dev_err(endpoint->dev, "Failed to map I/O memory. Aborting.\n"); + rc = -ENOMEM; goto failed_iomap0; } diff --git a/drivers/staging/xillybus/xillybus_pcie.c b/drivers/staging/xillybus/xillybus_pcie.c index 0564f97..bf1f7e3 100644 --- a/drivers/staging/xillybus/xillybus_pcie.c +++ b/drivers/staging/xillybus/xillybus_pcie.c @@ -168,9 +168,9 @@ static int xilly_probe(struct pci_dev *pdev, } endpoint->registers = pci_iomap(pdev, 0, 128); - if (!endpoint->registers) { dev_err(endpoint->dev, "Failed to map BAR 0. Aborting.\n"); + rc = -ENOMEM; goto failed_iomap0; } -- 1.7.2.3 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH] staging: xillybus: Return -EIO if *_iomap fails, instead of 0
This patch replicates the correction made by Wei Yongjun on a second occurrence of the same bug. The first correction was in commit 8eec411bfa1f8a2e0a2de45c988fd30c3efb. Bug fixed: The error code was not set, so the error condition wasn't reflected in the return value. Reported-by: Wei Yongjun Signed-off-by: Eli Billauer --- drivers/staging/xillybus/xillybus_of.c |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/drivers/staging/xillybus/xillybus_of.c b/drivers/staging/xillybus/xillybus_of.c index 394bfea..3b25b0e 100644 --- a/drivers/staging/xillybus/xillybus_of.c +++ b/drivers/staging/xillybus/xillybus_of.c @@ -131,10 +131,10 @@ static int xilly_drv_probe(struct platform_device *op) } endpoint->registers = of_iomap(dev->of_node, 0); - if (!endpoint->registers) { dev_err(endpoint->dev, "Failed to map I/O memory. Aborting.\n"); + rc = -EIO; goto failed_iomap0; } -- 1.7.2.3 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 2/3] staging: xillybus: Changed Open Firmware "compatible" property
The previous "compatible" string was poorly chosen, but remains in the match list to support existing DTBs. There is no risk for a naming clash. Signed-off-by: Eli Billauer --- drivers/staging/xillybus/xillybus_of.c |3 ++- 1 files changed, 2 insertions(+), 1 deletions(-) diff --git a/drivers/staging/xillybus/xillybus_of.c b/drivers/staging/xillybus/xillybus_of.c index 3b25b0e..be12440 100644 --- a/drivers/staging/xillybus/xillybus_of.c +++ b/drivers/staging/xillybus/xillybus_of.c @@ -31,7 +31,8 @@ static const char xillyname[] = "xillybus_of"; /* Match table for of_platform binding */ static struct of_device_id xillybus_of_match[] = { - { .compatible = "xlnx,xillybus-1.00.a", }, + { .compatible = "xillybus,xillybus-1.00.a", }, + { .compatible = "xlnx,xillybus-1.00.a", }, /* Deprecated */ {} }; -- 1.7.2.3 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 3/3] staging: xillybus: Open Firmware driver supporting coherent DMA
If the "dma-coherent" property is present in the device tree, the driver will not perform cache invalidations. This feature significantly improves data throughput and reduces CPU load. Signed-off-by: Eli Billauer --- drivers/staging/xillybus/xillybus_of.c | 21 - 1 files changed, 20 insertions(+), 1 deletions(-) diff --git a/drivers/staging/xillybus/xillybus_of.c b/drivers/staging/xillybus/xillybus_of.c index be12440..23a609b 100644 --- a/drivers/staging/xillybus/xillybus_of.c +++ b/drivers/staging/xillybus/xillybus_of.c @@ -54,6 +54,13 @@ static void xilly_dma_sync_single_for_device_of(struct xilly_endpoint *ep, dma_sync_single_for_device(ep->dev, dma_handle, size, direction); } +static void xilly_dma_sync_single_nop(struct xilly_endpoint *ep, + dma_addr_t dma_handle, + size_t size, + int direction) +{ +} + static dma_addr_t xilly_map_single_of(struct xilly_cleanup *mem, struct xilly_endpoint *ep, void *ptr, @@ -102,14 +109,26 @@ static struct xilly_endpoint_hardware of_hw = { .unmap_single = xilly_unmap_single_of }; +static struct xilly_endpoint_hardware of_hw_coherent = { + .owner = THIS_MODULE, + .hw_sync_sgl_for_cpu = xilly_dma_sync_single_nop, + .hw_sync_sgl_for_device = xilly_dma_sync_single_nop, + .map_single = xilly_map_single_of, + .unmap_single = xilly_unmap_single_of +}; + static int xilly_drv_probe(struct platform_device *op) { struct device *dev = &op->dev; struct xilly_endpoint *endpoint; int rc = 0; int irq; + struct xilly_endpoint_hardware *ephw = &of_hw; + + if (of_property_read_bool(dev->of_node, "dma-coherent")) + ephw = &of_hw_coherent; - endpoint = xillybus_init_endpoint(NULL, dev, &of_hw); + endpoint = xillybus_init_endpoint(NULL, dev, ephw); if (!endpoint) return -ENOMEM; -- 1.7.2.3 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 1/3] staging: xillybus: Added documentation on device tree bindings
Signed-off-by: Eli Billauer --- .../devicetree/bindings/staging/xillybus.txt | 20 1 files changed, 20 insertions(+), 0 deletions(-) create mode 100644 Documentation/devicetree/bindings/staging/xillybus.txt diff --git a/Documentation/devicetree/bindings/staging/xillybus.txt b/Documentation/devicetree/bindings/staging/xillybus.txt new file mode 100644 index 000..9e316dc --- /dev/null +++ b/Documentation/devicetree/bindings/staging/xillybus.txt @@ -0,0 +1,20 @@ +* Xillybus driver for generic FPGA interface + +Required properties: +- compatible: Should be "xillybus,xillybus-1.00.a" +- reg: Address and length of the register set for the device +- interrupts: Contains one interrupt node, typically consisting of three cells. +- interrupt-parent: the phandle for the interrupt controller that +services interrupts for this device. + +Optional properties: +- dma-coherent: Present if DMA operations are coherent + +Example: + + xillybus@ff200400 { + compatible = "xillybus,xillybus-1.00.a"; + reg = < 0xff200400 0x0080 >; + interrupts = < 0 40 1 >; + interrupt-parent = <&intc>; + } ; -- 1.7.2.3 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH] staging: xillybus: Use devm_ API on probe and remove
Suggested-by: Baruch Siach Signed-off-by: Eli Billauer --- drivers/staging/xillybus/xillybus.h |1 - drivers/staging/xillybus/xillybus_core.c |2 +- drivers/staging/xillybus/xillybus_of.c | 47 - drivers/staging/xillybus/xillybus_pcie.c | 65 -- 4 files changed, 27 insertions(+), 88 deletions(-) diff --git a/drivers/staging/xillybus/xillybus.h b/drivers/staging/xillybus/xillybus.h index e5e91d6..78a749a 100644 --- a/drivers/staging/xillybus/xillybus.h +++ b/drivers/staging/xillybus/xillybus.h @@ -116,7 +116,6 @@ struct xilly_endpoint { */ struct pci_dev *pdev; struct device *dev; - struct resource res; /* OF devices only */ struct xilly_endpoint_hardware *ephw; struct list_head ep_list; diff --git a/drivers/staging/xillybus/xillybus_core.c b/drivers/staging/xillybus/xillybus_core.c index b0a6696..fe8f9d2 100644 --- a/drivers/staging/xillybus/xillybus_core.c +++ b/drivers/staging/xillybus/xillybus_core.c @@ -2094,7 +2094,7 @@ struct xilly_endpoint *xillybus_init_endpoint(struct pci_dev *pdev, { struct xilly_endpoint *endpoint; - endpoint = kzalloc(sizeof(*endpoint), GFP_KERNEL); + endpoint = devm_kzalloc(dev, sizeof(*endpoint), GFP_KERNEL); if (!endpoint) { dev_err(dev, "Failed to allocate memory. Aborting.\n"); return NULL; diff --git a/drivers/staging/xillybus/xillybus_of.c b/drivers/staging/xillybus/xillybus_of.c index 23a609b..46ea010 100644 --- a/drivers/staging/xillybus/xillybus_of.c +++ b/drivers/staging/xillybus/xillybus_of.c @@ -19,6 +19,7 @@ #include #include #include +#include #include "xillybus.h" MODULE_DESCRIPTION("Xillybus driver for Open Firmware"); @@ -123,6 +124,7 @@ static int xilly_drv_probe(struct platform_device *op) struct xilly_endpoint *endpoint; int rc = 0; int irq; + struct resource res; struct xilly_endpoint_hardware *ephw = &of_hw; if (of_property_read_bool(dev->of_node, "dma-coherent")) @@ -135,38 +137,26 @@ static int xilly_drv_probe(struct platform_device *op) dev_set_drvdata(dev, endpoint); - rc = of_address_to_resource(dev->of_node, 0, &endpoint->res); + rc = of_address_to_resource(dev->of_node, 0, &res); if (rc) { dev_warn(endpoint->dev, "Failed to obtain device tree resource\n"); - goto failed_request_regions; + return rc; } - if (!request_mem_region(endpoint->res.start, -resource_size(&endpoint->res), xillyname)) { - dev_err(endpoint->dev, - "request_mem_region failed. Aborting.\n"); - rc = -EBUSY; - goto failed_request_regions; - } + endpoint->registers = devm_ioremap_resource(dev, &res); - endpoint->registers = of_iomap(dev->of_node, 0); - if (!endpoint->registers) { - dev_err(endpoint->dev, - "Failed to map I/O memory. Aborting.\n"); - rc = -EIO; - goto failed_iomap0; - } + if (IS_ERR(endpoint->registers)) + return PTR_ERR(endpoint->registers); irq = irq_of_parse_and_map(dev->of_node, 0); - rc = request_irq(irq, xillybus_isr, 0, xillyname, endpoint); + rc = devm_request_irq(dev, irq, xillybus_isr, 0, xillyname, endpoint); if (rc) { dev_err(endpoint->dev, "Failed to register IRQ handler. Aborting.\n"); - rc = -ENODEV; - goto failed_register_irq; + return -ENODEV; } rc = xillybus_endpoint_discovery(endpoint); @@ -174,18 +164,8 @@ static int xilly_drv_probe(struct platform_device *op) if (!rc) return 0; - free_irq(irq, endpoint); - -failed_register_irq: - iounmap(endpoint->registers); -failed_iomap0: - release_mem_region(endpoint->res.start, - resource_size(&endpoint->res)); - -failed_request_regions: xillybus_do_cleanup(&endpoint->cleanup, endpoint); - kfree(endpoint); return rc; } @@ -193,20 +173,11 @@ static int xilly_drv_remove(struct platform_device *op) { struct device *dev = &op->dev; struct xilly_endpoint *endpoint = dev_get_drvdata(dev); - int irq = irq_of_parse_and_map(dev->of_node, 0); xillybus_endpoint_remove(endpoint); - free_irq(irq, endpoint); - - iounmap(endpoint->registers); - release_mem_region(endpoint->res.start, - resource_size(&endpoint->res)); - xillybus_do_cleanup(&endpoint-&g
[PATCH 2/5] dma-mapping: Add devm_ interface for dma_map_single()
dmam_map_single() and dmam_unmap_single() are the managed counterparts for the respective dma_* functions. Note that dmam_map_single() returns zero on failure, and not a value to be handled by dma_mapping_error(): The error check is done by dmam_map_single() to avoid the registration of a mapping that failed. Signed-off-by: Eli Billauer --- Documentation/driver-model/devres.txt |2 + drivers/base/dma-mapping.c| 80 + include/linux/dma-mapping.h |5 ++- 3 files changed, 86 insertions(+), 1 deletions(-) diff --git a/Documentation/driver-model/devres.txt b/Documentation/driver-model/devres.txt index e1a2707..13b8be0 100644 --- a/Documentation/driver-model/devres.txt +++ b/Documentation/driver-model/devres.txt @@ -266,6 +266,8 @@ DMA dmam_declare_coherent_memory() dmam_pool_create() dmam_pool_destroy() + dmam_map_single() + dmam_unmap_single() PCI pcim_enable_device() : after success, all PCI ops become managed diff --git a/drivers/base/dma-mapping.c b/drivers/base/dma-mapping.c index 0ce39a3..db1c496 100644 --- a/drivers/base/dma-mapping.c +++ b/drivers/base/dma-mapping.c @@ -19,6 +19,7 @@ struct dma_devres { size_t size; void*vaddr; dma_addr_t dma_handle; + enum dma_data_direction direction; }; static void dmam_coherent_release(struct device *dev, void *res) @@ -267,3 +268,82 @@ int dma_common_mmap(struct device *dev, struct vm_area_struct *vma, return ret; } EXPORT_SYMBOL(dma_common_mmap); + +static int dmam_map_match(struct device *dev, void *res, void *match_data) +{ + struct dma_devres *this = res, *match = match_data; + + if (this->dma_handle == match->dma_handle) { + WARN_ON(this->size != match->size || + this->direction != match->direction); + return 1; + } + return 0; +} + +static void dmam_map_single_release(struct device *dev, void *res) +{ + struct dma_devres *this = res; + + dma_unmap_single(dev, this->dma_handle, this->size, this->direction); +} + +/** + * dmam_map_single - Managed dma_map_single() + * @dev: Device to map DMA region for + * @ptr: Pointer to region + * @size: Size to map + * @direction: The mapping's direction + * + * Managed dma_map_single(). The region mapped using this + * function will be automatically unmapped on driver detach. + * + * RETURNS: + * The DMA handle of the mapped region upon success, 0 otherwise. + */ +dma_addr_t dmam_map_single(struct device *dev, void *ptr, size_t size, + enum dma_data_direction direction) + +{ + struct dma_devres *dr; + dma_addr_t dma_handle; + + dr = devres_alloc(dmam_map_single_release, sizeof(*dr), GFP_KERNEL); + if (!dr) + return 0; + + dma_handle = dma_map_single(dev, ptr, size, direction); + if (dma_mapping_error(dev, dma_handle)) { + devres_free(dr); + return 0; + } + + dr->vaddr = ptr; + dr->dma_handle = dma_handle; + dr->size = size; + dr->direction = direction; + + devres_add(dev, dr); + + return dma_handle; +} +EXPORT_SYMBOL(dmam_map_single); + +/** + * dmam_unmap_single - Managed dma_unmap_single() + * @dev: Device to map DMA region for + * @dma_handle: DMA handle of the region to unmap + * @size: Size to unmap + * @direction: The mapping's direction + * + * Managed dma_unmap_single(). + */ +void dmam_unmap_single(struct device *dev, dma_addr_t dma_handle, + size_t size, enum dma_data_direction direction) +{ + struct dma_devres match_data = { size, NULL, dma_handle, direction }; + + WARN_ON(devres_release(dev, dmam_map_single_release, dmam_map_match, + &match_data)); +} +EXPORT_SYMBOL(dmam_unmap_single); diff --git a/include/linux/dma-mapping.h b/include/linux/dma-mapping.h index fd4aee2..cdb14a8 100644 --- a/include/linux/dma-mapping.h +++ b/include/linux/dma-mapping.h @@ -233,7 +233,10 @@ static inline void dmam_release_declared_memory(struct device *dev) { } #endif /* ARCH_HAS_DMA_DECLARE_COHERENT_MEMORY */ - +dma_addr_t dmam_map_single(struct device *dev, void *ptr, size_t size, + enum dma_data_direction direction); +void dmam_unmap_single(struct device *dev, dma_addr_t dma_handle, + size_t size, enum dma_data_direction direction); #ifndef CONFIG_HAVE_DMA_ATTRS struct dma_attrs; -- 1.7.2.3 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 4/5] staging: xillybus: Use devm_ API on probe and remove
Suggested-by: Baruch Siach Signed-off-by: Eli Billauer --- drivers/staging/xillybus/xillybus.h |1 - drivers/staging/xillybus/xillybus_core.c |2 +- drivers/staging/xillybus/xillybus_of.c | 47 - drivers/staging/xillybus/xillybus_pcie.c | 65 -- 4 files changed, 27 insertions(+), 88 deletions(-) diff --git a/drivers/staging/xillybus/xillybus.h b/drivers/staging/xillybus/xillybus.h index e5e91d6..78a749a 100644 --- a/drivers/staging/xillybus/xillybus.h +++ b/drivers/staging/xillybus/xillybus.h @@ -116,7 +116,6 @@ struct xilly_endpoint { */ struct pci_dev *pdev; struct device *dev; - struct resource res; /* OF devices only */ struct xilly_endpoint_hardware *ephw; struct list_head ep_list; diff --git a/drivers/staging/xillybus/xillybus_core.c b/drivers/staging/xillybus/xillybus_core.c index b0a6696..fe8f9d2 100644 --- a/drivers/staging/xillybus/xillybus_core.c +++ b/drivers/staging/xillybus/xillybus_core.c @@ -2094,7 +2094,7 @@ struct xilly_endpoint *xillybus_init_endpoint(struct pci_dev *pdev, { struct xilly_endpoint *endpoint; - endpoint = kzalloc(sizeof(*endpoint), GFP_KERNEL); + endpoint = devm_kzalloc(dev, sizeof(*endpoint), GFP_KERNEL); if (!endpoint) { dev_err(dev, "Failed to allocate memory. Aborting.\n"); return NULL; diff --git a/drivers/staging/xillybus/xillybus_of.c b/drivers/staging/xillybus/xillybus_of.c index 23a609b..46ea010 100644 --- a/drivers/staging/xillybus/xillybus_of.c +++ b/drivers/staging/xillybus/xillybus_of.c @@ -19,6 +19,7 @@ #include #include #include +#include #include "xillybus.h" MODULE_DESCRIPTION("Xillybus driver for Open Firmware"); @@ -123,6 +124,7 @@ static int xilly_drv_probe(struct platform_device *op) struct xilly_endpoint *endpoint; int rc = 0; int irq; + struct resource res; struct xilly_endpoint_hardware *ephw = &of_hw; if (of_property_read_bool(dev->of_node, "dma-coherent")) @@ -135,38 +137,26 @@ static int xilly_drv_probe(struct platform_device *op) dev_set_drvdata(dev, endpoint); - rc = of_address_to_resource(dev->of_node, 0, &endpoint->res); + rc = of_address_to_resource(dev->of_node, 0, &res); if (rc) { dev_warn(endpoint->dev, "Failed to obtain device tree resource\n"); - goto failed_request_regions; + return rc; } - if (!request_mem_region(endpoint->res.start, -resource_size(&endpoint->res), xillyname)) { - dev_err(endpoint->dev, - "request_mem_region failed. Aborting.\n"); - rc = -EBUSY; - goto failed_request_regions; - } + endpoint->registers = devm_ioremap_resource(dev, &res); - endpoint->registers = of_iomap(dev->of_node, 0); - if (!endpoint->registers) { - dev_err(endpoint->dev, - "Failed to map I/O memory. Aborting.\n"); - rc = -EIO; - goto failed_iomap0; - } + if (IS_ERR(endpoint->registers)) + return PTR_ERR(endpoint->registers); irq = irq_of_parse_and_map(dev->of_node, 0); - rc = request_irq(irq, xillybus_isr, 0, xillyname, endpoint); + rc = devm_request_irq(dev, irq, xillybus_isr, 0, xillyname, endpoint); if (rc) { dev_err(endpoint->dev, "Failed to register IRQ handler. Aborting.\n"); - rc = -ENODEV; - goto failed_register_irq; + return -ENODEV; } rc = xillybus_endpoint_discovery(endpoint); @@ -174,18 +164,8 @@ static int xilly_drv_probe(struct platform_device *op) if (!rc) return 0; - free_irq(irq, endpoint); - -failed_register_irq: - iounmap(endpoint->registers); -failed_iomap0: - release_mem_region(endpoint->res.start, - resource_size(&endpoint->res)); - -failed_request_regions: xillybus_do_cleanup(&endpoint->cleanup, endpoint); - kfree(endpoint); return rc; } @@ -193,20 +173,11 @@ static int xilly_drv_remove(struct platform_device *op) { struct device *dev = &op->dev; struct xilly_endpoint *endpoint = dev_get_drvdata(dev); - int irq = irq_of_parse_and_map(dev->of_node, 0); xillybus_endpoint_remove(endpoint); - free_irq(irq, endpoint); - - iounmap(endpoint->registers); - release_mem_region(endpoint->res.start, - resource_size(&endpoint->res)); - xillybus_do_cleanup(&endpoint-&g
[PATCH 3/5] dma-mapping: pci: Add devm_ interface for pci_map_single
Signed-off-by: Eli Billauer --- Documentation/driver-model/devres.txt |2 ++ include/asm-generic/pci-dma-compat.h | 17 + 2 files changed, 19 insertions(+), 0 deletions(-) diff --git a/Documentation/driver-model/devres.txt b/Documentation/driver-model/devres.txt index 13b8be0..09b03c9 100644 --- a/Documentation/driver-model/devres.txt +++ b/Documentation/driver-model/devres.txt @@ -272,6 +272,8 @@ DMA PCI pcim_enable_device() : after success, all PCI ops become managed pcim_pin_device(): keep PCI device enabled after release + pcim_map_single() + pcim_unmap_single() IOMAP devm_ioport_map() diff --git a/include/asm-generic/pci-dma-compat.h b/include/asm-generic/pci-dma-compat.h index 1437b7d..444e598 100644 --- a/include/asm-generic/pci-dma-compat.h +++ b/include/asm-generic/pci-dma-compat.h @@ -113,4 +113,21 @@ static inline int pci_set_consistent_dma_mask(struct pci_dev *dev, u64 mask) } #endif +/* + * Managed DMA API + */ + +static inline dma_addr_t +pcim_map_single(struct pci_dev *hwdev, void *ptr, size_t size, int direction) +{ + return dmam_map_single(hwdev == NULL ? NULL : &hwdev->dev, ptr, size, (enum dma_data_direction)direction); +} + +static inline void +pcim_unmap_single(struct pci_dev *hwdev, dma_addr_t dma_addr, +size_t size, int direction) +{ + dmam_unmap_single(hwdev == NULL ? NULL : &hwdev->dev, dma_addr, size, (enum dma_data_direction)direction); +} + #endif -- 1.7.2.3 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 1/5] devres: Add devm_get_free_pages API
devm_get_free_pages() and devm_free_pages() are the managed counterparts for __get_free_pages() and free_pages(). Signed-off-by: Eli Billauer --- Documentation/driver-model/devres.txt |2 + drivers/base/devres.c | 76 + include/linux/device.h|4 ++ 3 files changed, 82 insertions(+), 0 deletions(-) diff --git a/Documentation/driver-model/devres.txt b/Documentation/driver-model/devres.txt index 4999518..e1a2707 100644 --- a/Documentation/driver-model/devres.txt +++ b/Documentation/driver-model/devres.txt @@ -237,6 +237,8 @@ MEM devm_kzalloc() devm_kfree() devm_kmemdup() + devm_get_free_pages() + devm_free_pages() IIO devm_iio_device_alloc() diff --git a/drivers/base/devres.c b/drivers/base/devres.c index d0914cb..5230294 100644 --- a/drivers/base/devres.c +++ b/drivers/base/devres.c @@ -852,3 +852,79 @@ void *devm_kmemdup(struct device *dev, const void *src, size_t len, gfp_t gfp) return p; } EXPORT_SYMBOL_GPL(devm_kmemdup); + +struct pages_devres { + unsigned long addr; + unsigned int order; +}; + +static int devm_pages_match(struct device *dev, void *res, void *p) +{ + struct pages_devres *devres = res; + struct pages_devres *target = p; + + return devres->addr == target->addr; +} + +static void devm_pages_release(struct device *dev, void *res) +{ + struct pages_devres *devres = res; + + free_pages(devres->addr, devres->order); +} + +/** + * devm_get_free_pages - Resource-managed __get_free_pages + * @dev: Device to allocate memory for + * @gfp_mask: Allocation gfp flags + * @order: Allocation size is (1 << order) pages + * + * Managed get_free_pages. Memory allocated with this function is + * automatically freed on driver detach. + * + * RETURNS: + * Address of allocated memory on success, 0 on failure. + */ + +unsigned long devm_get_free_pages(struct device *dev, + gfp_t gfp_mask, unsigned int order) +{ + struct pages_devres *devres; + unsigned long addr; + + addr = __get_free_pages(gfp_mask, order); + + if (unlikely(!addr)) + return 0; + + devres = devres_alloc(devm_pages_release, + sizeof(struct pages_devres), GFP_KERNEL); + if (unlikely(!devres)) { + free_pages(addr, order); + return 0; + } + + devres->addr = addr; + devres->order = order; + + devres_add(dev, devres); + return addr; +} +EXPORT_SYMBOL_GPL(devm_get_free_pages); + +/** + * devm_free_pages - Resource-managed free_pages + * @dev: Device this memory belongs to + * @addr: Memory to free + * + * Free memory allocated with devm_get_free_pages(). Unlike free_pages, + * there is no need to supply the @order. + */ +void devm_free_pages(struct device *dev, unsigned long addr) +{ + struct pages_devres devres = { .addr = addr }; + + WARN_ON(devres_release(dev, devm_pages_release, devm_pages_match, + &devres)); +} +EXPORT_SYMBOL_GPL(devm_free_pages); diff --git a/include/linux/device.h b/include/linux/device.h index ab87158..3dc69a2 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -626,6 +626,10 @@ extern char *devm_kstrdup(struct device *dev, const char *s, gfp_t gfp); extern void *devm_kmemdup(struct device *dev, const void *src, size_t len, gfp_t gfp); +extern unsigned long devm_get_free_pages(struct device *dev, +gfp_t gfp_mask, unsigned int order); +extern void devm_free_pages(struct device *dev, unsigned long addr); + void __iomem *devm_ioremap_resource(struct device *dev, struct resource *res); void __iomem *devm_request_and_ioremap(struct device *dev, struct resource *res); -- 1.7.2.3 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 5/5] staging: xillybus: Use devm_ API for memory allocation and DMA mapping
Managed device resource API replaces code that reinvents it for memory allocation, page allocation and DMA mapping. Suggested-by: Baruch Siach Signed-off-by: Eli Billauer --- drivers/staging/xillybus/xillybus.h | 31 +-- drivers/staging/xillybus/xillybus_core.c | 160 -- drivers/staging/xillybus/xillybus_of.c | 54 +-- drivers/staging/xillybus/xillybus_pcie.c | 46 + 4 files changed, 48 insertions(+), 243 deletions(-) diff --git a/drivers/staging/xillybus/xillybus.h b/drivers/staging/xillybus/xillybus.h index 78a749a..88bb6e5 100644 --- a/drivers/staging/xillybus/xillybus.h +++ b/drivers/staging/xillybus/xillybus.h @@ -25,33 +25,12 @@ struct xilly_endpoint_hardware; -struct xilly_page { - struct list_head node; - unsigned long addr; - unsigned int order; -}; - -struct xilly_dma { - struct list_head node; - struct pci_dev *pdev; - struct device *dev; - dma_addr_t dma_addr; - size_t size; - int direction; -}; - struct xilly_buffer { void *addr; dma_addr_t dma_addr; int end_offset; /* Counting elements, not bytes */ }; -struct xilly_cleanup { - struct list_head to_kfree; - struct list_head to_pagefree; - struct list_head to_unmap; -}; - struct xilly_idt_handle { unsigned char *chandesc; unsigned char *idt; @@ -126,9 +105,6 @@ struct xilly_endpoint { struct mutex register_mutex; wait_queue_head_t ep_wait; - /* List of memory allocations, to make release easy */ - struct xilly_cleanup cleanup; - /* Channels and message handling */ struct cdev cdev; @@ -156,19 +132,14 @@ struct xilly_endpoint_hardware { dma_addr_t, size_t, int); - dma_addr_t (*map_single)(struct xilly_cleanup *, -struct xilly_endpoint *, + dma_addr_t (*map_single)(struct xilly_endpoint *, void *, size_t, int); - void (*unmap_single)(struct xilly_dma *entry); }; irqreturn_t xillybus_isr(int irq, void *data); -void xillybus_do_cleanup(struct xilly_cleanup *mem, -struct xilly_endpoint *endpoint); - struct xilly_endpoint *xillybus_init_endpoint(struct pci_dev *pdev, struct device *dev, struct xilly_endpoint_hardware diff --git a/drivers/staging/xillybus/xillybus_core.c b/drivers/staging/xillybus/xillybus_core.c index fe8f9d2..ff78937 100644 --- a/drivers/staging/xillybus/xillybus_core.c +++ b/drivers/staging/xillybus/xillybus_core.c @@ -311,85 +311,14 @@ EXPORT_SYMBOL(xillybus_isr); * no locks are applied! */ -void xillybus_do_cleanup(struct xilly_cleanup *mem, -struct xilly_endpoint *endpoint) -{ - struct list_head *this, *next; - - list_for_each_safe(this, next, &mem->to_unmap) { - struct xilly_dma *entry = - list_entry(this, struct xilly_dma, node); - - endpoint->ephw->unmap_single(entry); - kfree(entry); - } - - INIT_LIST_HEAD(&mem->to_unmap); - - list_for_each_safe(this, next, &mem->to_kfree) - kfree(this); - - INIT_LIST_HEAD(&mem->to_kfree); - - list_for_each_safe(this, next, &mem->to_pagefree) { - struct xilly_page *entry = - list_entry(this, struct xilly_page, node); - - free_pages(entry->addr, entry->order); - kfree(entry); - } - INIT_LIST_HEAD(&mem->to_pagefree); -} -EXPORT_SYMBOL(xillybus_do_cleanup); - -static void *xilly_malloc(struct xilly_cleanup *mem, size_t size) -{ - void *ptr; - - ptr = kzalloc(sizeof(struct list_head) + size, GFP_KERNEL); - - if (!ptr) - return ptr; - - list_add_tail((struct list_head *) ptr, &mem->to_kfree); - - return ptr + sizeof(struct list_head); -} - -static unsigned long xilly_pagealloc(struct xilly_cleanup *mem, -unsigned long order) -{ - unsigned long addr; - struct xilly_page *this; - - this = kmalloc(sizeof(struct xilly_page), GFP_KERNEL); - if (!this) - return 0; - - addr = __get_free_pages(GFP_KERNEL | __GFP_DMA32 | __GFP_ZERO, order); - - if (!addr) { - kfree(this); - return 0; - } - - this->addr = addr; - this->order = order; - - list_add_tail(&this->node, &mem->to_pagefree); - - return addr; -} - - static void xillybus_autoflush(struct work_struct *work); static int xilly_setupchannels(st
[PATCH 0/5] devres: Add functions + migrate Xillybus driver
This patchset consists of new functions to the managed device resource API, followed by patches for the Xillybus driver that now relies on these. Rationale: While migrating the staging/xillybus driver to rely completely on managed resources, some functionalities were missing, and hence added: * devm_get_free_pages() * devm_free_pages() * dmam_map_single() * dmam_unmap_single() * pcim_map_single() * pcim_unmap_single() After applying these patches, the Xillybus driver uses all six functions, and has been hardware tested on arm and x86_32. A compilation check went cleanly on x86_64 as well. Dependencies: Patch #3 relies on patch #2 (quite obviously). Patch #5 relies on all previous patches. Thanks, Eli Eli Billauer (5): devres: Add devm_get_free_pages API dma-mapping: Add devm_ interface for dma_map_single() dma-mapping: pci: Add devm_ interface for pci_map_single staging: xillybus: Use devm_ API on probe and remove staging: xillybus: Use devm_ API for memory allocation and DMA mapping Documentation/driver-model/devres.txt|6 + drivers/base/devres.c| 76 ++ drivers/base/dma-mapping.c | 80 +++ drivers/staging/xillybus/xillybus.h | 32 +-- drivers/staging/xillybus/xillybus_core.c | 162 -- drivers/staging/xillybus/xillybus_of.c | 99 ++ drivers/staging/xillybus/xillybus_pcie.c | 111 - include/asm-generic/pci-dma-compat.h | 17 +++ include/linux/device.h |4 + include/linux/dma-mapping.h |5 +- 10 files changed, 261 insertions(+), 331 deletions(-) -- 1.7.2.3 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 2/3] dma-mapping: Add devm_ interface for dma_map_single_attrs()
dmam_map_single_attrs() and dmam_unmap_single_attrs() replace the non-*_attrs functions, which are implemented as defines instead. The case of a non-NULL @attrs parameter has not been tested. Suggested-by: Tejun Heo Signed-off-by: Eli Billauer --- Documentation/driver-model/devres.txt|2 + drivers/base/dma-mapping.c | 43 + include/asm-generic/dma-mapping-common.h |2 + include/linux/dma-mapping.h | 10 --- 4 files changed, 41 insertions(+), 16 deletions(-) diff --git a/Documentation/driver-model/devres.txt b/Documentation/driver-model/devres.txt index 13b8be0..2112a00 100644 --- a/Documentation/driver-model/devres.txt +++ b/Documentation/driver-model/devres.txt @@ -268,6 +268,8 @@ DMA dmam_pool_destroy() dmam_map_single() dmam_unmap_single() + dmam_map_single_attrs() + dmam_unmap_single_attrs() PCI pcim_enable_device() : after success, all PCI ops become managed diff --git a/drivers/base/dma-mapping.c b/drivers/base/dma-mapping.c index db1c496..4e80db1 100644 --- a/drivers/base/dma-mapping.c +++ b/drivers/base/dma-mapping.c @@ -11,6 +11,7 @@ #include #include #include +#include /* * Managed DMA API @@ -20,6 +21,7 @@ struct dma_devres { void*vaddr; dma_addr_t dma_handle; enum dma_data_direction direction; + struct dma_attrs *attrs; }; static void dmam_coherent_release(struct device *dev, void *res) @@ -285,24 +287,29 @@ static void dmam_map_single_release(struct device *dev, void *res) { struct dma_devres *this = res; - dma_unmap_single(dev, this->dma_handle, this->size, this->direction); + dma_unmap_single_attrs(dev, this->dma_handle, this->size, + this->direction, this->attrs); + + kfree(this->attrs); } /** - * dmam_map_single - Managed dma_map_single() + * dmam_map_single_attrs - Managed dma_map_single_attrs() * @dev: Device to map DMA region for * @ptr: Pointer to region * @size: Size to map * @direction: The mapping's direction + * @attrs: Attributes associated with the DMA mapping * - * Managed dma_map_single(). The region mapped using this + * Managed dma_map_single_attrs(). The region mapped using this * function will be automatically unmapped on driver detach. * * RETURNS: * The DMA handle of the mapped region upon success, 0 otherwise. */ -dma_addr_t dmam_map_single(struct device *dev, void *ptr, size_t size, - enum dma_data_direction direction) +dma_addr_t dmam_map_single_attrs(struct device *dev, void *ptr, size_t size, +enum dma_data_direction direction, +struct dma_attrs *attrs) { struct dma_devres *dr; @@ -312,8 +319,18 @@ dma_addr_t dmam_map_single(struct device *dev, void *ptr, size_t size, if (!dr) return 0; - dma_handle = dma_map_single(dev, ptr, size, direction); + if (attrs) { + dr->attrs = kmemdup(attrs, sizeof(*attrs), GFP_KERNEL); + if (!dr->attrs) { + devres_free(dr); + return 0; + } + } else + dr->attrs = NULL; + + dma_handle = dma_map_single_attrs(dev, ptr, size, direction, attrs); if (dma_mapping_error(dev, dma_handle)) { + kfree(dr->attrs); devres_free(dr); return 0; } @@ -327,23 +344,25 @@ dma_addr_t dmam_map_single(struct device *dev, void *ptr, size_t size, return dma_handle; } -EXPORT_SYMBOL(dmam_map_single); +EXPORT_SYMBOL(dmam_map_single_attrs); /** - * dmam_unmap_single - Managed dma_unmap_single() + * dmam_unmap_single_attrs - Managed dma_unmap_single_attrs() * @dev: Device to map DMA region for * @dma_handle: DMA handle of the region to unmap * @size: Size to unmap * @direction: The mapping's direction + * @attrs: Attributes associated with the DMA mapping. * - * Managed dma_unmap_single(). + * Managed dma_unmap_single_attrs(). */ -void dmam_unmap_single(struct device *dev, dma_addr_t dma_handle, - size_t size, enum dma_data_direction direction) +void dmam_unmap_single_attrs(struct device *dev, dma_addr_t dma_handle, +size_t size, enum dma_data_direction direction, +struct dma_attrs *attrs) { struct dma_devres match_data = { size, NULL, dma_handle, direction }; WARN_ON(devres_release(dev, dmam_map_single_release, dmam_map_match, &match_data)); } -EXPORT_SYMBOL(dmam_unmap_single); +EXPORT_SYMBOL(dmam_unmap_single_attrs); diff --git a/include/asm-generic/dma-mapping-common.h b/include/asm-generic/dma-mapping-common.h index de8bf89..aaa7c68 100644 --- a/include/asm-generic/dma-mapping-common.h +++ b/include
[PATCH 1/3] dma-mapping: Add devm_ interface for dma_map_single()
dmam_map_single() and dmam_unmap_single() are the managed counterparts for the respective dma_* functions. Note that dmam_map_single() returns zero on failure, and not a value to be handled by dma_mapping_error(): The error check is done by dmam_map_single() to avoid the registration of a mapping that failed. Signed-off-by: Eli Billauer --- Documentation/driver-model/devres.txt |2 + drivers/base/dma-mapping.c| 80 + include/linux/dma-mapping.h |5 ++- 3 files changed, 86 insertions(+), 1 deletions(-) diff --git a/Documentation/driver-model/devres.txt b/Documentation/driver-model/devres.txt index e1a2707..13b8be0 100644 --- a/Documentation/driver-model/devres.txt +++ b/Documentation/driver-model/devres.txt @@ -266,6 +266,8 @@ DMA dmam_declare_coherent_memory() dmam_pool_create() dmam_pool_destroy() + dmam_map_single() + dmam_unmap_single() PCI pcim_enable_device() : after success, all PCI ops become managed diff --git a/drivers/base/dma-mapping.c b/drivers/base/dma-mapping.c index 0ce39a3..db1c496 100644 --- a/drivers/base/dma-mapping.c +++ b/drivers/base/dma-mapping.c @@ -19,6 +19,7 @@ struct dma_devres { size_t size; void*vaddr; dma_addr_t dma_handle; + enum dma_data_direction direction; }; static void dmam_coherent_release(struct device *dev, void *res) @@ -267,3 +268,82 @@ int dma_common_mmap(struct device *dev, struct vm_area_struct *vma, return ret; } EXPORT_SYMBOL(dma_common_mmap); + +static int dmam_map_match(struct device *dev, void *res, void *match_data) +{ + struct dma_devres *this = res, *match = match_data; + + if (this->dma_handle == match->dma_handle) { + WARN_ON(this->size != match->size || + this->direction != match->direction); + return 1; + } + return 0; +} + +static void dmam_map_single_release(struct device *dev, void *res) +{ + struct dma_devres *this = res; + + dma_unmap_single(dev, this->dma_handle, this->size, this->direction); +} + +/** + * dmam_map_single - Managed dma_map_single() + * @dev: Device to map DMA region for + * @ptr: Pointer to region + * @size: Size to map + * @direction: The mapping's direction + * + * Managed dma_map_single(). The region mapped using this + * function will be automatically unmapped on driver detach. + * + * RETURNS: + * The DMA handle of the mapped region upon success, 0 otherwise. + */ +dma_addr_t dmam_map_single(struct device *dev, void *ptr, size_t size, + enum dma_data_direction direction) + +{ + struct dma_devres *dr; + dma_addr_t dma_handle; + + dr = devres_alloc(dmam_map_single_release, sizeof(*dr), GFP_KERNEL); + if (!dr) + return 0; + + dma_handle = dma_map_single(dev, ptr, size, direction); + if (dma_mapping_error(dev, dma_handle)) { + devres_free(dr); + return 0; + } + + dr->vaddr = ptr; + dr->dma_handle = dma_handle; + dr->size = size; + dr->direction = direction; + + devres_add(dev, dr); + + return dma_handle; +} +EXPORT_SYMBOL(dmam_map_single); + +/** + * dmam_unmap_single - Managed dma_unmap_single() + * @dev: Device to map DMA region for + * @dma_handle: DMA handle of the region to unmap + * @size: Size to unmap + * @direction: The mapping's direction + * + * Managed dma_unmap_single(). + */ +void dmam_unmap_single(struct device *dev, dma_addr_t dma_handle, + size_t size, enum dma_data_direction direction) +{ + struct dma_devres match_data = { size, NULL, dma_handle, direction }; + + WARN_ON(devres_release(dev, dmam_map_single_release, dmam_map_match, + &match_data)); +} +EXPORT_SYMBOL(dmam_unmap_single); diff --git a/include/linux/dma-mapping.h b/include/linux/dma-mapping.h index fd4aee2..cdb14a8 100644 --- a/include/linux/dma-mapping.h +++ b/include/linux/dma-mapping.h @@ -233,7 +233,10 @@ static inline void dmam_release_declared_memory(struct device *dev) { } #endif /* ARCH_HAS_DMA_DECLARE_COHERENT_MEMORY */ - +dma_addr_t dmam_map_single(struct device *dev, void *ptr, size_t size, + enum dma_data_direction direction); +void dmam_unmap_single(struct device *dev, dma_addr_t dma_handle, + size_t size, enum dma_data_direction direction); #ifndef CONFIG_HAVE_DMA_ATTRS struct dma_attrs; -- 1.7.2.3 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 3/3] dma-mapping: pci: Add devm_ interface for pci_map_single
Signed-off-by: Eli Billauer --- Documentation/driver-model/devres.txt |2 ++ include/asm-generic/pci-dma-compat.h | 17 + 2 files changed, 19 insertions(+), 0 deletions(-) diff --git a/Documentation/driver-model/devres.txt b/Documentation/driver-model/devres.txt index 2112a00..fea2c69 100644 --- a/Documentation/driver-model/devres.txt +++ b/Documentation/driver-model/devres.txt @@ -274,6 +274,8 @@ DMA PCI pcim_enable_device() : after success, all PCI ops become managed pcim_pin_device(): keep PCI device enabled after release + pcim_map_single() + pcim_unmap_single() IOMAP devm_ioport_map() diff --git a/include/asm-generic/pci-dma-compat.h b/include/asm-generic/pci-dma-compat.h index 1437b7d..444e598 100644 --- a/include/asm-generic/pci-dma-compat.h +++ b/include/asm-generic/pci-dma-compat.h @@ -113,4 +113,21 @@ static inline int pci_set_consistent_dma_mask(struct pci_dev *dev, u64 mask) } #endif +/* + * Managed DMA API + */ + +static inline dma_addr_t +pcim_map_single(struct pci_dev *hwdev, void *ptr, size_t size, int direction) +{ + return dmam_map_single(hwdev == NULL ? NULL : &hwdev->dev, ptr, size, (enum dma_data_direction)direction); +} + +static inline void +pcim_unmap_single(struct pci_dev *hwdev, dma_addr_t dma_addr, +size_t size, int direction) +{ + dmam_unmap_single(hwdev == NULL ? NULL : &hwdev->dev, dma_addr, size, (enum dma_data_direction)direction); +} + #endif -- 1.7.2.3 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [PATCH 2/5] dma-mapping: Add devm_ interface for dma_map_single()
Hello Tejun, On 17/05/14 00:08, Tejun Heo wrote: Don't we wanna map the underlying operation - dma_map_single_attrs() - instead? I'll resubmit this patch promptly, with a follow-up patch for the diff to implement dmam_map_single_attrs() instead. Plus a define-statement for dmam_map_single(). I can't test the case of a non-NULL value for @attrs however. + if (dma_mapping_error(dev, dma_handle)) { + devres_free(dr); + return 0; Can't we just keep returning dma_handle? Even if that means invoking ->mapping_error() twice? It's yucky to have subtly different error return especially because in most cases it won't fail. Yucky it is indeed. There are however two problems with keeping the existing API: * What to do if devres_alloc() fails. How do I signal back an error? The only way I can think of is returning zero. But if the caller should know that zero means failure, I've already broken the API. I might as well return zero for any kind of failure. * It seems like a lot of dma_mapping_error() implementations always return no-error, since the DMA mapping can't fail on specific architectures. If callers use dma_mapping_error(), the possible devres_alloc() failure will be missed. By the way, where I've seen dma_mapping_error() doing something, it checks for dma_handle == 0. Submitting updated patches for the DMA mapping part soon. Regards, Eli ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [PATCH 2/5] dma-mapping: Add devm_ interface for dma_map_single()
Hello, Tejun. On 19/05/14 23:17, Tejun Heo wrote: What can't it just do the following? if (dma_mapping_error(dev, dma_handle)) { devres_free(dr); return dma_handle; } The caller would have to invoke dma_mapping_error() again but is that a problem? That seems OK to me, but the problem I'm concerned with is this: In devm_get_free_pages() it says devres = devres_alloc(devm_pages_release, sizeof(struct pages_devres), GFP_KERNEL); if (unlikely(!devres)) { free_pages(addr, order); return 0; } What should I put instead of this "return 0" to conform with the current API? And to make things even worse, on some architectures, dma_mapping_error() always returns success, regardless of dma_handle. So if we stick to the current API, the caller of devm_get_free_pages() will never know it failed on these architectures. So my conclusion was that the caller must be aware that if devm_get_free_pages() returns zero it's an error, regardless of dma_mapping_error(). That breaks the API. Once it's broken, why not return zero on all possible errors? Maybe I didn't understand what you suggested. Regards, Eli Thanks. ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v2 4/4] staging: xillybus: Use devm_ API for memory allocation and DMA mapping
Managed device resource API replaces code that reinvents it for memory allocation, page allocation and DMA mapping. Suggested-by: Baruch Siach Signed-off-by: Eli Billauer --- drivers/staging/xillybus/xillybus.h | 38 +-- drivers/staging/xillybus/xillybus_core.c | 186 +- drivers/staging/xillybus/xillybus_of.c | 61 +- drivers/staging/xillybus/xillybus_pcie.c | 54 ++ 4 files changed, 74 insertions(+), 265 deletions(-) diff --git a/drivers/staging/xillybus/xillybus.h b/drivers/staging/xillybus/xillybus.h index 78a749a..d88e458 100644 --- a/drivers/staging/xillybus/xillybus.h +++ b/drivers/staging/xillybus/xillybus.h @@ -25,33 +25,12 @@ struct xilly_endpoint_hardware; -struct xilly_page { - struct list_head node; - unsigned long addr; - unsigned int order; -}; - -struct xilly_dma { - struct list_head node; - struct pci_dev *pdev; - struct device *dev; - dma_addr_t dma_addr; - size_t size; - int direction; -}; - struct xilly_buffer { void *addr; dma_addr_t dma_addr; int end_offset; /* Counting elements, not bytes */ }; -struct xilly_cleanup { - struct list_head to_kfree; - struct list_head to_pagefree; - struct list_head to_unmap; -}; - struct xilly_idt_handle { unsigned char *chandesc; unsigned char *idt; @@ -126,9 +105,6 @@ struct xilly_endpoint { struct mutex register_mutex; wait_queue_head_t ep_wait; - /* List of memory allocations, to make release easy */ - struct xilly_cleanup cleanup; - /* Channels and message handling */ struct cdev cdev; @@ -156,19 +132,15 @@ struct xilly_endpoint_hardware { dma_addr_t, size_t, int); - dma_addr_t (*map_single)(struct xilly_cleanup *, -struct xilly_endpoint *, -void *, -size_t, -int); - void (*unmap_single)(struct xilly_dma *entry); + int (*map_single)(struct xilly_endpoint *, + void *, + size_t, + int, + dma_addr_t *); }; irqreturn_t xillybus_isr(int irq, void *data); -void xillybus_do_cleanup(struct xilly_cleanup *mem, -struct xilly_endpoint *endpoint); - struct xilly_endpoint *xillybus_init_endpoint(struct pci_dev *pdev, struct device *dev, struct xilly_endpoint_hardware diff --git a/drivers/staging/xillybus/xillybus_core.c b/drivers/staging/xillybus/xillybus_core.c index fe8f9d2..5fca58e 100644 --- a/drivers/staging/xillybus/xillybus_core.c +++ b/drivers/staging/xillybus/xillybus_core.c @@ -311,85 +311,14 @@ EXPORT_SYMBOL(xillybus_isr); * no locks are applied! */ -void xillybus_do_cleanup(struct xilly_cleanup *mem, -struct xilly_endpoint *endpoint) -{ - struct list_head *this, *next; - - list_for_each_safe(this, next, &mem->to_unmap) { - struct xilly_dma *entry = - list_entry(this, struct xilly_dma, node); - - endpoint->ephw->unmap_single(entry); - kfree(entry); - } - - INIT_LIST_HEAD(&mem->to_unmap); - - list_for_each_safe(this, next, &mem->to_kfree) - kfree(this); - - INIT_LIST_HEAD(&mem->to_kfree); - - list_for_each_safe(this, next, &mem->to_pagefree) { - struct xilly_page *entry = - list_entry(this, struct xilly_page, node); - - free_pages(entry->addr, entry->order); - kfree(entry); - } - INIT_LIST_HEAD(&mem->to_pagefree); -} -EXPORT_SYMBOL(xillybus_do_cleanup); - -static void *xilly_malloc(struct xilly_cleanup *mem, size_t size) -{ - void *ptr; - - ptr = kzalloc(sizeof(struct list_head) + size, GFP_KERNEL); - - if (!ptr) - return ptr; - - list_add_tail((struct list_head *) ptr, &mem->to_kfree); - - return ptr + sizeof(struct list_head); -} - -static unsigned long xilly_pagealloc(struct xilly_cleanup *mem, -unsigned long order) -{ - unsigned long addr; - struct xilly_page *this; - - this = kmalloc(sizeof(struct xilly_page), GFP_KERNEL); - if (!this) - return 0; - - addr = __get_free_pages(GFP_KERNEL | __GFP_DMA32 | __GFP_ZERO, order); - - if (!addr) { - kfree(this); - return 0; - } - - this->addr = addr; - this->order = order; - - list_add_tail(&this->node, &mem->t
[PATCH v2 0/4] devres: dma-mapping: Introducing new functions
This patchset consists of new functions to the managed device resource API, followed by a patch for the Xillybus driver, which is my motivation and what I tested with. This is a resubmission after changing the API slightly. Rationale: While migrating the staging/xillybus driver to rely completely on managed resources, some functionalities were missing, and hence added: * dmam_map_single() * dmam_unmap_single() * pcim_map_single() * pcim_unmap_single() Tejun suggested that dma_map_single_attrs() should have a managed version as well. The second patch in this set turns dmam_map_single() into dma_map_single_attrs(), and implements the former as a macro. Functions added: * dmam_map_single_attrs() * dmam_unmap_single_attrs() Xillybus' driver works with and without this patch (depends on patches #1 and #3 only). Thanks, Eli Eli Billauer (4): dma-mapping: Add devm_ interface for dma_map_single() dma-mapping: Add devm_ interface for dma_map_single_attrs() dma-mapping: pci: Add devm_ interface for pci_map_single staging: xillybus: Use devm_ API for memory allocation and DMA mapping Documentation/driver-model/devres.txt|6 + drivers/base/dma-mapping.c | 106 + drivers/staging/xillybus/xillybus.h | 38 +-- drivers/staging/xillybus/xillybus_core.c | 186 +- drivers/staging/xillybus/xillybus_of.c | 61 +- drivers/staging/xillybus/xillybus_pcie.c | 54 ++ include/asm-generic/dma-mapping-common.h |3 + include/asm-generic/pci-dma-compat.h | 18 +++ include/linux/dma-mapping.h |8 +- 9 files changed, 214 insertions(+), 266 deletions(-) -- 1.7.2.3 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v2 3/4] dma-mapping: pci: Add devm_ interface for pci_map_single
Signed-off-by: Eli Billauer --- Documentation/driver-model/devres.txt |2 ++ include/asm-generic/pci-dma-compat.h | 18 ++ 2 files changed, 20 insertions(+), 0 deletions(-) diff --git a/Documentation/driver-model/devres.txt b/Documentation/driver-model/devres.txt index 2112a00..fea2c69 100644 --- a/Documentation/driver-model/devres.txt +++ b/Documentation/driver-model/devres.txt @@ -274,6 +274,8 @@ DMA PCI pcim_enable_device() : after success, all PCI ops become managed pcim_pin_device(): keep PCI device enabled after release + pcim_map_single() + pcim_unmap_single() IOMAP devm_ioport_map() diff --git a/include/asm-generic/pci-dma-compat.h b/include/asm-generic/pci-dma-compat.h index 1437b7d..796a892 100644 --- a/include/asm-generic/pci-dma-compat.h +++ b/include/asm-generic/pci-dma-compat.h @@ -113,4 +113,22 @@ static inline int pci_set_consistent_dma_mask(struct pci_dev *dev, u64 mask) } #endif +/* + * Managed DMA API + */ + +static inline int +pcim_map_single(struct pci_dev *hwdev, void *ptr, size_t size, int direction, + dma_addr_t *ret_dma_handle) +{ + return dmam_map_single(hwdev == NULL ? NULL : &hwdev->dev, ptr, size, (enum dma_data_direction)direction, ret_dma_handle); +} + +static inline void +pcim_unmap_single(struct pci_dev *hwdev, dma_addr_t dma_addr, +size_t size, int direction) +{ + dmam_unmap_single(hwdev == NULL ? NULL : &hwdev->dev, dma_addr, size, (enum dma_data_direction)direction); +} + #endif -- 1.7.2.3 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v2 1/4] dma-mapping: Add devm_ interface for dma_map_single()
dmam_map_single() and dmam_unmap_single() are the managed counterparts for the respective dma_* functions. Note that dmam_map_single() returns a status value rather than the DMA handle. The DMA handle is passed to the caller through a pointer in the arguments. The reason for this API change is that dmam_map_single() allocates memory, which may fail even if the DMA mapping is successful. On the other hand, it seems like there's no platform-independent value for dma_handle that can be used to indicate an error. This leaves dmam_map_single() with no safe way to tell its caller that the memory allocation has failed, except for returning a status as an int. Trying to keep close to the non-devres API could also tempt programmers into using dma_mapping_error() on the dmam_* functions. This would work incorrectly on platforms, for which dma_mapping_error() ignores its argument, and always returns success. Thanks to Tejun Heo for suggesting this API. Signed-off-by: Eli Billauer --- Documentation/driver-model/devres.txt |2 + drivers/base/dma-mapping.c| 86 + include/linux/dma-mapping.h |6 ++- 3 files changed, 93 insertions(+), 1 deletions(-) diff --git a/Documentation/driver-model/devres.txt b/Documentation/driver-model/devres.txt index e1a2707..13b8be0 100644 --- a/Documentation/driver-model/devres.txt +++ b/Documentation/driver-model/devres.txt @@ -266,6 +266,8 @@ DMA dmam_declare_coherent_memory() dmam_pool_create() dmam_pool_destroy() + dmam_map_single() + dmam_unmap_single() PCI pcim_enable_device() : after success, all PCI ops become managed diff --git a/drivers/base/dma-mapping.c b/drivers/base/dma-mapping.c index 0ce39a3..f76ea0f 100644 --- a/drivers/base/dma-mapping.c +++ b/drivers/base/dma-mapping.c @@ -19,6 +19,7 @@ struct dma_devres { size_t size; void*vaddr; dma_addr_t dma_handle; + enum dma_data_direction direction; }; static void dmam_coherent_release(struct device *dev, void *res) @@ -267,3 +268,88 @@ int dma_common_mmap(struct device *dev, struct vm_area_struct *vma, return ret; } EXPORT_SYMBOL(dma_common_mmap); + +static int dmam_map_match(struct device *dev, void *res, void *match_data) +{ + struct dma_devres *this = res, *match = match_data; + + if (this->dma_handle == match->dma_handle) { + WARN_ON(this->size != match->size || + this->direction != match->direction); + return 1; + } + return 0; +} + +static void dmam_map_single_release(struct device *dev, void *res) +{ + struct dma_devres *this = res; + + dma_unmap_single(dev, this->dma_handle, this->size, this->direction); +} + +/** + * dmam_map_single - Managed dma_map_single() + * @dev: Device to map DMA region for + * @ptr: Pointer to region + * @size: Size to map + * @direction: The mapping's direction + * @ret_dma_handle: Pointer to return the value of the DMA handle + * + * Managed dma_map_single(). The region mapped using this + * function will be automatically unmapped on driver detach. + * + * RETURNED VALUE: + * 0 is returned on success + * -EIO if the DMA mapping failed + * -ENOMEM on failure to allocate memory for internal data structure + */ +int dmam_map_single(struct device *dev, void *ptr, size_t size, + enum dma_data_direction direction, + dma_addr_t *ret_dma_handle) + +{ + struct dma_devres *dr; + dma_addr_t dma_handle; + + dr = devres_alloc(dmam_map_single_release, sizeof(*dr), GFP_KERNEL); + if (!dr) + return -ENOMEM; + + dma_handle = dma_map_single(dev, ptr, size, direction); + if (dma_mapping_error(dev, dma_handle)) { + devres_free(dr); + return -EIO; + } + + *ret_dma_handle = dma_handle; + + dr->vaddr = ptr; + dr->dma_handle = dma_handle; + dr->size = size; + dr->direction = direction; + + devres_add(dev, dr); + + return 0; /* Success */ +} +EXPORT_SYMBOL(dmam_map_single); + +/** + * dmam_unmap_single - Managed dma_unmap_single() + * @dev: Device to map DMA region for + * @dma_handle: DMA handle of the region to unmap + * @size: Size to unmap + * @direction: The mapping's direction + * + * Managed dma_unmap_single(). + */ +void dmam_unmap_single(struct device *dev, dma_addr_t dma_handle, + size_t size, enum dma_data_direction direction) +{ + struct dma_devres match_data = { size, NULL, dma_handle, direction }; + + WARN_ON(devres_release(dev, dmam_map_single_release, dmam_map_match, + &match_data)); +} +EXPORT_SYMBOL(dmam_unmap_single); diff --git a/include/linux/dma-mapping.h b/include/linux/dma-mapping.h index fd4aee2..cad63de 100644 --- a/include/linux/dma-mapping.h +++ b/include/l
[PATCH v2 2/4] dma-mapping: Add devm_ interface for dma_map_single_attrs()
dmam_map_single_attrs() and dmam_unmap_single_attrs() replace the non-*_attrs functions, which are implemented as defines instead. The case of a non-NULL @attrs parameter has not been tested. Suggested-by: Tejun Heo Signed-off-by: Eli Billauer --- Documentation/driver-model/devres.txt|2 + drivers/base/dma-mapping.c | 46 + include/asm-generic/dma-mapping-common.h |3 ++ include/linux/dma-mapping.h | 12 --- 4 files changed, 45 insertions(+), 18 deletions(-) diff --git a/Documentation/driver-model/devres.txt b/Documentation/driver-model/devres.txt index 13b8be0..2112a00 100644 --- a/Documentation/driver-model/devres.txt +++ b/Documentation/driver-model/devres.txt @@ -268,6 +268,8 @@ DMA dmam_pool_destroy() dmam_map_single() dmam_unmap_single() + dmam_map_single_attrs() + dmam_unmap_single_attrs() PCI pcim_enable_device() : after success, all PCI ops become managed diff --git a/drivers/base/dma-mapping.c b/drivers/base/dma-mapping.c index f76ea0f..b24ae17 100644 --- a/drivers/base/dma-mapping.c +++ b/drivers/base/dma-mapping.c @@ -11,6 +11,7 @@ #include #include #include +#include /* * Managed DMA API @@ -20,6 +21,7 @@ struct dma_devres { void*vaddr; dma_addr_t dma_handle; enum dma_data_direction direction; + struct dma_attrs *attrs; }; static void dmam_coherent_release(struct device *dev, void *res) @@ -285,18 +287,22 @@ static void dmam_map_single_release(struct device *dev, void *res) { struct dma_devres *this = res; - dma_unmap_single(dev, this->dma_handle, this->size, this->direction); + dma_unmap_single_attrs(dev, this->dma_handle, this->size, + this->direction, this->attrs); + + kfree(this->attrs); } /** - * dmam_map_single - Managed dma_map_single() + * dmam_map_single_attrs - Managed dma_map_single_attrs() * @dev: Device to map DMA region for * @ptr: Pointer to region * @size: Size to map * @direction: The mapping's direction + * @attrs: Attributes associated with the DMA mapping * @ret_dma_handle: Pointer to return the value of the DMA handle * - * Managed dma_map_single(). The region mapped using this + * Managed dma_map_single_attrs(). The region mapped using this * function will be automatically unmapped on driver detach. * * RETURNED VALUE: @@ -304,9 +310,11 @@ static void dmam_map_single_release(struct device *dev, void *res) * -EIO if the DMA mapping failed * -ENOMEM on failure to allocate memory for internal data structure */ -int dmam_map_single(struct device *dev, void *ptr, size_t size, - enum dma_data_direction direction, - dma_addr_t *ret_dma_handle) + +int dmam_map_single_attrs(struct device *dev, void *ptr, size_t size, + enum dma_data_direction direction, + struct dma_attrs *attrs, + dma_addr_t *ret_dma_handle) { struct dma_devres *dr; @@ -316,8 +324,18 @@ int dmam_map_single(struct device *dev, void *ptr, size_t size, if (!dr) return -ENOMEM; - dma_handle = dma_map_single(dev, ptr, size, direction); + if (attrs) { + dr->attrs = kmemdup(attrs, sizeof(*attrs), GFP_KERNEL); + if (!dr->attrs) { + devres_free(dr); + return -ENOMEM; + } + } else + dr->attrs = NULL; + + dma_handle = dma_map_single_attrs(dev, ptr, size, direction, attrs); if (dma_mapping_error(dev, dma_handle)) { + kfree(dr->attrs); devres_free(dr); return -EIO; } @@ -333,23 +351,25 @@ int dmam_map_single(struct device *dev, void *ptr, size_t size, return 0; /* Success */ } -EXPORT_SYMBOL(dmam_map_single); +EXPORT_SYMBOL(dmam_map_single_attrs); /** - * dmam_unmap_single - Managed dma_unmap_single() + * dmam_unmap_single_attrs - Managed dma_unmap_single_attrs() * @dev: Device to map DMA region for * @dma_handle: DMA handle of the region to unmap * @size: Size to unmap * @direction: The mapping's direction + * @attrs: Attributes associated with the DMA mapping. * - * Managed dma_unmap_single(). + * Managed dma_unmap_single_attrs(). */ -void dmam_unmap_single(struct device *dev, dma_addr_t dma_handle, - size_t size, enum dma_data_direction direction) +void dmam_unmap_single_attrs(struct device *dev, dma_addr_t dma_handle, +size_t size, enum dma_data_direction direction, +struct dma_attrs *attrs) { struct dma_devres match_data = { size, NULL, dma_handle, direction }; WARN_ON(devres_release(dev, dmam_map_single_release, dmam_map_match, &match_data)); }
Re: [PATCH v2 1/4] dma-mapping: Add devm_ interface for dma_map_single()
Hi, I believe that I need a managed dma_map_single() my own driver, which doesn't fall in the case of a single use: The driver allocates its buffers with __get_free_pages() (or the to-be managed version of it). Then it cuts the allocated memory into smaller buffers (in some cases, and with certain alignment rules), and then calls dma_map_single() to do the DMA mapping for each. The buffers are held along the driver's lifetime, with DMA sync API juggling control back and forth to the hardware. Note that the DMA is noncoherent. Once could argue, that since dma_map_noncoherent() calls __get_free_pages() under the hood, I could request the larger chunk from dma_map_noncoherent(), and cut it into smaller DMA buffers. My concern is that the dma_sync_single_*() functions expect a DMA handle, not a physical address I've made up with my own buffer splitting. I don't see any problem with this trick on platforms I've worked with, but I'm not sure if this is the proper way to go. dma_map_single(), on the other hand, returns a DMA handle. The DMA pool functions could be interesting, but I understand that they would supply me with coherent memory only. Anything I missed? Thanks, Eli On 04/06/14 17:14, Tejun Heo wrote: Hello, On Wed, Jun 04, 2014 at 04:12:11PM +0200, Joerg Roedel wrote: Yes, but those drivers usually get DMA buffers at init time with the dma_alloc_* interfaces. The dma_map_* interfaces discussed here belong to the streaming DMA-API, so they are usually used for only one DMA transaction before dma_unmap_* is called on them. A devm interface for the dma_alloc_* family of functions would actually make sense, but not for the dma_map_* functions. Ah, okay. Fair enough. Thanks. ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [PATCH v2 1/4] dma-mapping: Add devm_ interface for dma_map_single()
Hello Joerg. On 05/06/14 00:25, Joerg Roedel wrote: What you are trying to do should work with dma_alloc_noncoherent(). The API allows partial syncs on this memory, so you should be fine. Please try to put yourself in my position: I have a driver that I care about, which works fine for a few years. It's based upon dma_map_single(), which seems to be the common way to get non-coherent memory, even for the driver's entire lifespan. I realize that dma_alloc_* was the intended way to do it, but fact is that dma_map_* has become the common choice. Now I need to switch to dma_alloc_noncoherent(), which isn't used by many drivers, it seems. It should work the same, but there's always the worry if I'll cover all the corners. So will I take this risk of a nasty DMA bug on some esoteric platform, just to cut some lines in the code? And if I choose to keep the unmanaged dma_map_single(), maybe I'll mess up if I convert other allocations to the managed API? Hmmm, maybe it's best to forget all about it. The problem with a devm variant of dma_map_* is that it is too easy to misuse or to use it wrong so that a driver could eat up all available DMA handles on some platforms. I suppose you mean that those who use dma_map_* for a one-off DMA session will drop the unmapping, thinking that it's "managed anyhow"...? Well, you can say that about any of the managed functions. For example, when devm_kzalloc() was introduced, someone maybe argued that people would drop kfree()s where they shouldn't, causing memory leaks. So I think it boils down to whether devres is a good idea or not. Someone who thinks it's bad, will reject any new API, referring to memory efficiency, additional causes of failure and the risk of misleading the herd. But if devres is to become commonly used in the future, I think drop-in replacements are necessary. In my opinion, telling people to adopt another methodology (e.g. dma_alloc_noncoherent vs. mapping), even if functionally equivalent, is a good way to make sure devres is never adopted. Regards, Eli Joerg ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [PATCH v2 1/4] dma-mapping: Add devm_ interface for dma_map_single()
On 06/06/14 19:01, Greg KH wrote: Please try to put yourself in my position: I have a driver that I care > about, which works fine for a few years. It's based upon dma_map_single(), > which seems to be the common way to get non-coherent memory, even for the > driver's entire lifespan. I realize that dma_alloc_* was the intended way to > do it, but fact is that dma_map_* has become the common choice. Is your driver in the kernel tree? If not, you really are on your own :( It's the Xillybus driver in the staging area. I don't know if this counts for being in the kernel tree... The suggested patchset would allow replacing my use of dma_map_single() with a managed version of that function. This will clean the driver's code considerably. But I think that the discussion here is if it's valid to use dma_map_single() for a device-permanent DMA mapping, or if dma_alloc_noncoherent() is the only way. If the answer is no, there's quite obviously no point in a devres version for that function. Regards, Eli greg k-h ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [PATCH v2 1/4] dma-mapping: Add devm_ interface for dma_map_single()
Hello Shuah, We agree that the streaming API was originally *intended* for short map-unmap DMA sessions, and that dma_alloc_noncoherent() was the *intended* API for those who want to hold the DMA during a device's lifetime. We also agree that on some platforms, DMA mappings are precious, and therefore any driver should unmap a region as soon as it's not needed anymore. But if we stick to the citation you gave, it says "...unmapped right after it (unless you use dma_sync_* below)". So even in the streaming API's definition, there's an understanding, that the "streaming" DMA buffer can be held for more than a single session. And a good sync tool for that is made available. Using cross-reference on Linux' code, I get a strong impression, that dma_alloc_NONcoherent() is pretty much unused (I counted 8 drivers). The streaming API's sync functions are heavily used, on the other hand. So one gets a hunch, that there's a lot of use of the streaming API in the kernel tree for long-term DMA mappings. This wasn't the original intention -- we agree on that. But why is it wrong? Assuming that a driver needs to hold a DMA mapping for a long while, why does it matter if it was done with dma_alloc_noncoherent() or with dma_map_*()? They are equally wasteful, aren't they? Why maintaining two API sets doing the same thing? Or is there a subtle functional difference I'm not aware of? Thanks, Eli On 06/06/14 20:02, Shuah Khan wrote: dma_map_single() and dma_unmap_single() are streaming DMA APIs. These are intended for one DMA transfer and unmapped right after it is done. dma buffers are limited shared resources for streaming that are shared by several drivers. Hence the need for use and release model. Please refer to the Using Streaming DMA mappings in DMA-API-HOWTO.txt "- Streaming DMA mappings which are usually mapped for one DMA transfer, unmapped right after it (unless you use dma_sync_* below) and for which hardware can optimize for sequential accesses. This of "streaming" as "asynchronous" or "outside the coherency domain". Good examples of what to use streaming mappings for are: - Networking buffers transmitted/received by a device. - Filesystem buffers written/read by a SCSI device." If I understand your intended usage correctly, you are looking to allocate and hold the buffers for the lifetime of the driver. For such cases, dma_alloc_*() interfaces are the ones to use. Please also refer to DMA-API.txt as well. Hope this helps. -- Shuah ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [PATCH] staging: xillybus: Consolidate return statements in xilly_probe()
Hello, Thanks for the patch. However in the patch I'm trying to push, xillybus_do_cleanup() is eliminated completely from the code (with no success so far, because it depends on inserting a patch that adds a devres version of dma_map_single). See https://lkml.org/lkml/2014/6/1/10 So your patch makes sense, and I have no objection to it, but it fixes a piece of code that must go away soon anyhow. Thanks, Eli On 18/06/14 15:10, Tobias Klauser wrote: No need for two return statements, just call xillybus_do_cleanup() in case of an error before returning. Signed-off-by: Tobias Klauser --- drivers/staging/xillybus/xillybus_pcie.c |7 ++- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/drivers/staging/xillybus/xillybus_pcie.c b/drivers/staging/xillybus/xillybus_pcie.c index a4fe51c..518ba6c 100644 --- a/drivers/staging/xillybus/xillybus_pcie.c +++ b/drivers/staging/xillybus/xillybus_pcie.c @@ -200,11 +200,8 @@ static int xilly_probe(struct pci_dev *pdev, } rc = xillybus_endpoint_discovery(endpoint); - - if (!rc) - return 0; - - xillybus_do_cleanup(&endpoint->cleanup, endpoint); + if (rc) + xillybus_do_cleanup(&endpoint->cleanup, endpoint); return rc; } ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v3] staging: xillybus: Use devm_ API for memory allocation and DMA mapping
Managed device resource API replaces code that reinvents it for memory allocation, page allocation and DMA mapping. devm_add_action() is used for unwinding DMA mappings, since there is no devm_* API for dma_map_single(). A recent patch that introduces such API was rejected, mainly on the grounds that it may cause an unnecessary waste of resources. Suggested-by: Baruch Siach Signed-off-by: Eli Billauer --- drivers/staging/xillybus/xillybus.h | 46 ++-- drivers/staging/xillybus/xillybus_core.c | 186 +- drivers/staging/xillybus/xillybus_of.c | 72 +--- drivers/staging/xillybus/xillybus_pcie.c | 66 ++-- 4 files changed, 132 insertions(+), 238 deletions(-) diff --git a/drivers/staging/xillybus/xillybus.h b/drivers/staging/xillybus/xillybus.h index 78a749a..ae58a3e 100644 --- a/drivers/staging/xillybus/xillybus.h +++ b/drivers/staging/xillybus/xillybus.h @@ -25,33 +25,12 @@ struct xilly_endpoint_hardware; -struct xilly_page { - struct list_head node; - unsigned long addr; - unsigned int order; -}; - -struct xilly_dma { - struct list_head node; - struct pci_dev *pdev; - struct device *dev; - dma_addr_t dma_addr; - size_t size; - int direction; -}; - struct xilly_buffer { void *addr; dma_addr_t dma_addr; int end_offset; /* Counting elements, not bytes */ }; -struct xilly_cleanup { - struct list_head to_kfree; - struct list_head to_pagefree; - struct list_head to_unmap; -}; - struct xilly_idt_handle { unsigned char *chandesc; unsigned char *idt; @@ -126,9 +105,6 @@ struct xilly_endpoint { struct mutex register_mutex; wait_queue_head_t ep_wait; - /* List of memory allocations, to make release easy */ - struct xilly_cleanup cleanup; - /* Channels and message handling */ struct cdev cdev; @@ -156,18 +132,22 @@ struct xilly_endpoint_hardware { dma_addr_t, size_t, int); - dma_addr_t (*map_single)(struct xilly_cleanup *, -struct xilly_endpoint *, -void *, -size_t, -int); - void (*unmap_single)(struct xilly_dma *entry); + int (*map_single)(struct xilly_endpoint *, + void *, + size_t, + int, + dma_addr_t *); }; -irqreturn_t xillybus_isr(int irq, void *data); +struct xilly_mapping { + void *device; + dma_addr_t dma_addr; + size_t size; + int direction; +}; -void xillybus_do_cleanup(struct xilly_cleanup *mem, -struct xilly_endpoint *endpoint); + +irqreturn_t xillybus_isr(int irq, void *data); struct xilly_endpoint *xillybus_init_endpoint(struct pci_dev *pdev, struct device *dev, diff --git a/drivers/staging/xillybus/xillybus_core.c b/drivers/staging/xillybus/xillybus_core.c index fe8f9d2..5fca58e 100644 --- a/drivers/staging/xillybus/xillybus_core.c +++ b/drivers/staging/xillybus/xillybus_core.c @@ -311,85 +311,14 @@ EXPORT_SYMBOL(xillybus_isr); * no locks are applied! */ -void xillybus_do_cleanup(struct xilly_cleanup *mem, -struct xilly_endpoint *endpoint) -{ - struct list_head *this, *next; - - list_for_each_safe(this, next, &mem->to_unmap) { - struct xilly_dma *entry = - list_entry(this, struct xilly_dma, node); - - endpoint->ephw->unmap_single(entry); - kfree(entry); - } - - INIT_LIST_HEAD(&mem->to_unmap); - - list_for_each_safe(this, next, &mem->to_kfree) - kfree(this); - - INIT_LIST_HEAD(&mem->to_kfree); - - list_for_each_safe(this, next, &mem->to_pagefree) { - struct xilly_page *entry = - list_entry(this, struct xilly_page, node); - - free_pages(entry->addr, entry->order); - kfree(entry); - } - INIT_LIST_HEAD(&mem->to_pagefree); -} -EXPORT_SYMBOL(xillybus_do_cleanup); - -static void *xilly_malloc(struct xilly_cleanup *mem, size_t size) -{ - void *ptr; - - ptr = kzalloc(sizeof(struct list_head) + size, GFP_KERNEL); - - if (!ptr) - return ptr; - - list_add_tail((struct list_head *) ptr, &mem->to_kfree); - - return ptr + sizeof(struct list_head); -} - -static unsigned long xilly_pagealloc(struct xilly_cleanup *mem, -unsigned long order) -{ - unsigned long addr; - struct xilly_page *this; - - this = kmalloc(sizeof(struct xilly_page), GFP_KERNEL)
[PATCH 3/4] staging: xillybus: Register's address offset notation update
In iowrite32() calls, the address of registers was expressed as e.g. &ep->registers[fpga_msg_ctrl_reg]. This changes to the more common format e.g. ep->registers + fpga_msg_ctrl_reg. There is no functional change. Signed-off-by: Eli Billauer --- drivers/staging/xillybus/xillybus.h |2 +- drivers/staging/xillybus/xillybus_core.c | 88 +++--- 2 files changed, 45 insertions(+), 45 deletions(-) diff --git a/drivers/staging/xillybus/xillybus.h b/drivers/staging/xillybus/xillybus.h index ae58a3e..a0806b5 100644 --- a/drivers/staging/xillybus/xillybus.h +++ b/drivers/staging/xillybus/xillybus.h @@ -99,7 +99,7 @@ struct xilly_endpoint { struct list_head ep_list; int dma_using_dac; /* =1 if 64-bit DMA is used, =0 otherwise. */ - __iomem u32 *registers; + __iomem void *registers; int fatal_error; struct mutex register_mutex; diff --git a/drivers/staging/xillybus/xillybus_core.c b/drivers/staging/xillybus/xillybus_core.c index 134800d..ab6502c 100644 --- a/drivers/staging/xillybus/xillybus_core.c +++ b/drivers/staging/xillybus/xillybus_core.c @@ -44,14 +44,14 @@ MODULE_LICENSE("GPL v2"); #define XILLY_RX_TIMEOUT (10*HZ/1000) #define XILLY_TIMEOUT (100*HZ/1000) -#define fpga_msg_ctrl_reg 0x0002 -#define fpga_dma_control_reg 0x0008 -#define fpga_dma_bufno_reg 0x0009 -#define fpga_dma_bufaddr_lowaddr_reg 0x000a -#define fpga_dma_bufaddr_highaddr_reg 0x000b -#define fpga_buf_ctrl_reg 0x000c -#define fpga_buf_offset_reg 0x000d -#define fpga_endian_reg 0x0010 +#define fpga_msg_ctrl_reg 0x0008 +#define fpga_dma_control_reg 0x0020 +#define fpga_dma_bufno_reg 0x0024 +#define fpga_dma_bufaddr_lowaddr_reg 0x0028 +#define fpga_dma_bufaddr_highaddr_reg 0x002c +#define fpga_buf_ctrl_reg 0x0030 +#define fpga_buf_offset_reg0x0034 +#define fpga_endian_reg0x0040 #define XILLYMSG_OPCODE_RELEASEBUF 1 #define XILLYMSG_OPCODE_QUIESCEACK 2 @@ -170,7 +170,7 @@ irqreturn_t xillybus_isr(int irq, void *data) DMA_FROM_DEVICE); iowrite32(0x01, /* Message NACK */ - &ep->registers[fpga_msg_ctrl_reg]); + ep->registers + fpga_msg_ctrl_reg); } return IRQ_HANDLED; } else if (buf[i] & (1 << 22)) /* Last message */ @@ -305,7 +305,7 @@ irqreturn_t xillybus_isr(int irq, void *data) ep->msg_counter = (ep->msg_counter + 1) & 0xf; ep->failed_messages = 0; - iowrite32(0x03, &ep->registers[fpga_msg_ctrl_reg]); /* Message ACK */ + iowrite32(0x03, ep->registers + fpga_msg_ctrl_reg); /* Message ACK */ return IRQ_HANDLED; } @@ -387,9 +387,9 @@ static int xilly_get_dma_buffers(struct xilly_endpoint *ep, return rc; iowrite32((u32) (dma_addr & 0x), - &ep->registers[fpga_dma_bufaddr_lowaddr_reg]); + ep->registers + fpga_dma_bufaddr_lowaddr_reg); iowrite32(((u32) u64) dma_addr) >> 32) & 0x)), - &ep->registers[fpga_dma_bufaddr_highaddr_reg]); + ep->registers + fpga_dma_bufaddr_highaddr_reg); mmiowb(); if (buffers) { /* Not the message buffer */ @@ -398,14 +398,14 @@ static int xilly_get_dma_buffers(struct xilly_endpoint *ep, buffers[i] = this_buffer++; iowrite32(s->regdirection | s->nbuffer++, - &ep->registers[fpga_dma_bufno_reg]); + ep->registers + fpga_dma_bufno_reg); } else { ep->msgbuf_addr = s->salami; ep->msgbuf_dma_addr = dma_addr; ep->msg_buf_size = bytebufsize; iowrite32(s->regdirection, - &ep->registers[fpga_dma_bufno_reg]); + ep->registers + fpga_dma_bufno_reg); } s->left_of_salami -= bytebufsize; @@ -640,7 +640,7 @@ static int xilly_obtain_idt(struct xilly_endpoint *endpoint) iowrite32(1 | (3 << 24), /* Opcode 3 for channel 0 = Send IDT */ - &endpoint->registers[fpga_buf_ctrl_reg]); + endpoint->registers + fpga_buf_ctrl_reg); mmiowb(); /* Just to appear safe */ wait_event_interruptible_timeout(channel->wr_wait, @@ -812,8 +812,8 @@ static ssize_t xillybus_read(struct file *filp, char __user *userbuf, iowrite32(1
[PATCH 1/4] staging: xillybus: Add sanity check in interrupt handler
Data arriving from the hardware is verified prior to its use. The lack of this check has never been reported to cause a problem, but it's necessary nevertheless. Signed-off-by: Eli Billauer --- drivers/staging/xillybus/xillybus_core.c |6 ++ 1 files changed, 6 insertions(+), 0 deletions(-) diff --git a/drivers/staging/xillybus/xillybus_core.c b/drivers/staging/xillybus/xillybus_core.c index 5fca58e..fa79979 100644 --- a/drivers/staging/xillybus/xillybus_core.c +++ b/drivers/staging/xillybus/xillybus_core.c @@ -267,6 +267,12 @@ irqreturn_t xillybus_isr(int irq, void *data) break; case XILLYMSG_OPCODE_FIFOEOF: + if ((msg_channel > ep->num_channels) || + (msg_channel == 0) || (!msg_dir) || + !ep->channels[msg_channel]->num_wr_buffers) { + malformed_message(ep, &buf[i]); + break; + } channel = ep->channels[msg_channel]; spin_lock(&channel->wr_spinlock); channel->wr_eof = msg_bufno; -- 1.7.2.3 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 2/4] staging: xillybus: Reorganizing xilly_setupchannels()
Duplicate code in this function was moved into a new function, xilly_get_dma_buffers(). There is no change in functionality. Signed-off-by: Eli Billauer --- drivers/staging/xillybus/xillybus_core.c | 345 -- 1 files changed, 138 insertions(+), 207 deletions(-) diff --git a/drivers/staging/xillybus/xillybus_core.c b/drivers/staging/xillybus/xillybus_core.c index fa79979..134800d 100644 --- a/drivers/staging/xillybus/xillybus_core.c +++ b/drivers/staging/xillybus/xillybus_core.c @@ -319,28 +319,130 @@ EXPORT_SYMBOL(xillybus_isr); static void xillybus_autoflush(struct work_struct *work); +struct xilly_alloc_state { + void *salami; + int left_of_salami; + int nbuffer; + enum dma_data_direction direction; + u32 regdirection; +}; + +static int xilly_get_dma_buffers(struct xilly_endpoint *ep, +struct xilly_alloc_state *s, +struct xilly_buffer **buffers, +int bufnum, int bytebufsize) +{ + int i, rc; + dma_addr_t dma_addr; + struct device *dev = ep->dev; + struct xilly_buffer *this_buffer = NULL; /* Init to silence warning */ + + if (buffers) { /* Not the message buffer */ + this_buffer = devm_kzalloc( + dev, bufnum * sizeof(struct xilly_buffer), + GFP_KERNEL); + + if (!this_buffer) + return -ENOMEM; + } + + for (i = 0; i < bufnum; i++) { + /* +* Buffers are expected in descending size order, so there +* is either enough space for this buffer or none at all. +*/ + + if ((s->left_of_salami < bytebufsize) && + (s->left_of_salami > 0)) { + dev_err(ep->dev, + "Corrupt buffer allocation in IDT. Aborting.\n"); + return -ENODEV; + } + + if (s->left_of_salami == 0) { + int allocorder, allocsize; + + allocsize = PAGE_SIZE; + allocorder = 0; + while (bytebufsize > allocsize) { + allocsize *= 2; + allocorder++; + } + + s->salami = (void *) devm_get_free_pages( + dev, + GFP_KERNEL | __GFP_DMA32 | __GFP_ZERO, + allocorder); + + if (!s->salami) + return -ENOMEM; + s->left_of_salami = allocsize; + } + + rc = ep->ephw->map_single(ep, s->salami, + bytebufsize, s->direction, + &dma_addr); + + if (rc) + return rc; + + iowrite32((u32) (dma_addr & 0x), + &ep->registers[fpga_dma_bufaddr_lowaddr_reg]); + iowrite32(((u32) u64) dma_addr) >> 32) & 0x)), + &ep->registers[fpga_dma_bufaddr_highaddr_reg]); + mmiowb(); + + if (buffers) { /* Not the message buffer */ + this_buffer->addr = s->salami; + this_buffer->dma_addr = dma_addr; + buffers[i] = this_buffer++; + + iowrite32(s->regdirection | s->nbuffer++, + &ep->registers[fpga_dma_bufno_reg]); + } else { + ep->msgbuf_addr = s->salami; + ep->msgbuf_dma_addr = dma_addr; + ep->msg_buf_size = bytebufsize; + + iowrite32(s->regdirection, + &ep->registers[fpga_dma_bufno_reg]); + } + + s->left_of_salami -= bytebufsize; + s->salami += bytebufsize; + } + return 0; /* Success */ +} + static int xilly_setupchannels(struct xilly_endpoint *ep, unsigned char *chandesc, int entries ) { struct device *dev = ep->dev; - int i, entry, wr_nbuffer, rd_nbuffer; + int i, entry, rc; struct xilly_channel *channel; int channelnum, bufnum, bufsize, format, is_writebuf; int bytebufsize; int synchronous, allowpartial, exclusive_open, seekable; int supports_nonempty; - void *wr_salami = NULL; - void *rd_salami = NULL; - int left_of_wr_salami = 0; - int left_of_rd_salami = 0; - dma_addr_t dma_addr; in
[PATCH 4/4] staging: xillybus: Remove sparse error on IS_ERR()
IS_ERR() expects a non-__iomem pointer. Signed-off-by: Eli Billauer --- drivers/staging/xillybus/xillybus_of.c |4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/xillybus/xillybus_of.c b/drivers/staging/xillybus/xillybus_of.c index e0ae234..fb97845 100644 --- a/drivers/staging/xillybus/xillybus_of.c +++ b/drivers/staging/xillybus/xillybus_of.c @@ -147,8 +147,8 @@ static int xilly_drv_probe(struct platform_device *op) rc = of_address_to_resource(dev->of_node, 0, &res); endpoint->registers = devm_ioremap_resource(dev, &res); - if (IS_ERR(endpoint->registers)) - return PTR_ERR(endpoint->registers); + if (IS_ERR((__force void *) endpoint->registers)) + return PTR_ERR((__force void *) endpoint->registers); irq = irq_of_parse_and_map(dev->of_node, 0); -- 1.7.2.3 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [PATCH] staging: xillybus: Move out of staging
Hello, Dan. Thanks a lot for reviewing the driver. There are indeed a few things that need fixing. I'll be back with patches and responses in a matter of a few days. As for the --strict option, I wasn't aware of it. I learn something new every time. :) Thanks again, Eli On 01/09/14 15:13, Dan Carpenter wrote: Pretty nice. This is very special purpose hardware and the UAPI for this is fine. The documentation seems good. I had some minor style comments but nothing major stands out. These days I quite like the --strict option for checkpatch.pl. for i in $(find drivers/staging/xillybus/ -name \*\.c) do ./scripts/checkpatch.pl --strict -f $i done ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [PATCH] staging: xillybus: Move out of staging
Hello Tobias, Thanks for that heads-up. I'll make a separate patch for MAINTAINERS if and when the driver goes out of staging. No point risking the failure to apply the major patch because of a clash on MAINTAINERS. Regards, Eli On 01/09/14 15:33, Tobias Klauser wrote: I shall continue being responsible for its maintenance. In this case a entry in MAINTAINERS would make sense. This way you'll make sure patches get submitted to you. ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [PATCH] staging: xillybus: Move out of staging
Hello, Arend. On 01/09/14 16:08, Arend van Spriel wrote: Maybe it would be better to use the DMA-API instead of the PCI wrappers. I just found out that the PCI wrappers were indeed removed from the DMA-API.txt documentation back in 2010, saying that "driver writers are always able to use the DMA API with any bus": https://lkml.org/lkml/2010/3/8/470 On the other hand, I was under the impression that the PCI API is for (future?) platforms which may need a distinction between PCI and non-PCI. That is why the Xillybus driver does some acrobatics, so that the PCI API is used for PCI devices, and the general DMA API for non-PCI devices. Given that the distinction is already there, is it wise to remove it, and use the plain DMA API for all? That will simplify the code, of course, but if there's any esoteric platform that needs a different treatment for PCI devices, it's better to stay as is, I suppose. Thanks, Eli ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH] MAINTAINERS: Add an entry for staging/xillybus
Suggested-by: Greg Kroah-Hartman Signed-off-by: Eli Billauer --- MAINTAINERS |6 ++ 1 files changed, 6 insertions(+), 0 deletions(-) diff --git a/MAINTAINERS b/MAINTAINERS index 57e8c3d..acf1a27 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -8789,6 +8789,12 @@ M: Arnaud Patard S: Odd Fixes F: drivers/staging/xgifb/ +STAGING - XILLYBUS DRIVER +M: Eli Billauer +L: de...@driverdev.osuosl.org +S: Supported +F: drivers/staging/xillybus/ + STARFIRE/DURALAN NETWORK DRIVER M: Ion Badulescu S: Odd Fixes -- 1.7.2.3 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 06/18] staging: xillybus: Improved error handling
xilly_scan_idt() now returns an error status code, rather than being a void function and hint the status through an entry in a data structure. Suggested-by: Dan Carpenter Signed-off-by: Eli Billauer --- drivers/staging/xillybus/xillybus_core.c | 20 1 files changed, 8 insertions(+), 12 deletions(-) diff --git a/drivers/staging/xillybus/xillybus_core.c b/drivers/staging/xillybus/xillybus_core.c index 222457f..fc14b14 100644 --- a/drivers/staging/xillybus/xillybus_core.c +++ b/drivers/staging/xillybus/xillybus_core.c @@ -568,8 +568,8 @@ static int xilly_setupchannels(struct xilly_endpoint *ep, return 0; } -static void xilly_scan_idt(struct xilly_endpoint *endpoint, - struct xilly_idt_handle *idt_handle) +static int xilly_scan_idt(struct xilly_endpoint *endpoint, + struct xilly_idt_handle *idt_handle) { int count = 0; unsigned char *idt = endpoint->channels[1]->wr_buffers[0]->addr; @@ -593,23 +593,22 @@ static void xilly_scan_idt(struct xilly_endpoint *endpoint, if (scan > end_of_idt) { dev_err(endpoint->dev, "IDT device name list overflow. Aborting.\n"); - idt_handle->chandesc = NULL; - return; + return -ENODEV; } idt_handle->chandesc = scan; len = endpoint->idtlen - (3 + ((int) (scan - idt))); if (len & 0x03) { - idt_handle->chandesc = NULL; - dev_err(endpoint->dev, "Corrupt IDT device name list. Aborting.\n"); + return -ENODEV; } idt_handle->entries = len >> 2; - endpoint->num_channels = count; + + return 0; } static int xilly_obtain_idt(struct xilly_endpoint *endpoint) @@ -2041,12 +2040,9 @@ int xillybus_endpoint_discovery(struct xilly_endpoint *endpoint) if (rc) goto failed_idt; - xilly_scan_idt(endpoint, &idt_handle); - - if (!idt_handle.chandesc) { - rc = -ENODEV; + rc = xilly_scan_idt(endpoint, &idt_handle); + if (rc) goto failed_idt; - } devres_close_group(dev, bootstrap_resources); -- 1.7.2.3 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 02/18] staging: xillybus: Use SEEK_* predefined constants
Suggested-by: Dan Carpenter Signed-off-by: Eli Billauer --- drivers/staging/xillybus/xillybus_core.c |6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/xillybus/xillybus_core.c b/drivers/staging/xillybus/xillybus_core.c index cacd560..61699fa 100644 --- a/drivers/staging/xillybus/xillybus_core.c +++ b/drivers/staging/xillybus/xillybus_core.c @@ -1720,13 +1720,13 @@ static loff_t xillybus_llseek(struct file *filp, loff_t offset, int whence) mutex_lock(&channel->rd_mutex); switch (whence) { - case 0: + case SEEK_SET: pos = offset; break; - case 1: + case SEEK_CUR: pos += offset; break; - case 2: + case SEEK_END: pos = offset; /* Going to the end => to the beginning */ break; default: -- 1.7.2.3 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 09/18] staging: xillybus: Fixes related to "rc" variable
"rc" is often used to hold the return value of a function call. This patch removes unnecessary assignments to this variable, and makes a few related execution flow improvements. Suggested-by: Dan Carpenter Signed-off-by: Eli Billauer --- drivers/staging/xillybus/xillybus_core.c | 32 +++-- drivers/staging/xillybus/xillybus_of.c |5 ++- drivers/staging/xillybus/xillybus_pcie.c | 10 +++- 3 files changed, 15 insertions(+), 32 deletions(-) diff --git a/drivers/staging/xillybus/xillybus_core.c b/drivers/staging/xillybus/xillybus_core.c index f66ffa7..53d5e42 100644 --- a/drivers/staging/xillybus/xillybus_core.c +++ b/drivers/staging/xillybus/xillybus_core.c @@ -613,7 +613,6 @@ static int xilly_scan_idt(struct xilly_endpoint *endpoint, static int xilly_obtain_idt(struct xilly_endpoint *endpoint) { - int rc = 0; struct xilly_channel *channel; unsigned char *version; @@ -635,8 +634,7 @@ static int xilly_obtain_idt(struct xilly_endpoint *endpoint) if (endpoint->fatal_error) return -EIO; - rc = -ENODEV; - return rc; + return -ENODEV; } endpoint->ephw->hw_sync_sgl_for_cpu( @@ -649,15 +647,13 @@ static int xilly_obtain_idt(struct xilly_endpoint *endpoint) dev_err(endpoint->dev, "IDT length mismatch (%d != %d). Aborting.\n", channel->wr_buffers[0]->end_offset, endpoint->idtlen); - rc = -ENODEV; - return rc; + return -ENODEV; } if (crc32_le(~0, channel->wr_buffers[0]->addr, endpoint->idtlen+1) != 0) { dev_err(endpoint->dev, "IDT failed CRC check. Aborting.\n"); - rc = -ENODEV; - return rc; + return -ENODEV; } version = channel->wr_buffers[0]->addr; @@ -667,8 +663,7 @@ static int xilly_obtain_idt(struct xilly_endpoint *endpoint) dev_err(endpoint->dev, "No support for IDT version 0x%02x. Maybe the xillybus driver needs an upgarde. Aborting.\n", (int) *version); - rc = -ENODEV; - return rc; + return -ENODEV; } return 0; /* Success */ @@ -696,12 +691,9 @@ static ssize_t xillybus_read(struct file *filp, char __user *userbuf, deadline = jiffies + 1 + XILLY_RX_TIMEOUT; rc = mutex_lock_interruptible(&channel->wr_mutex); - if (rc) return rc; - rc = 0; /* Just to be clear about it. Compiler optimizes this out */ - while (1) { /* Note that we may drop mutex within this loop */ int bytes_to_do = count - bytes_done; @@ -1010,7 +1002,7 @@ desperate: static int xillybus_myflush(struct xilly_channel *channel, long timeout) { - int rc = 0; + int rc; unsigned long flags; int end_offset_plus1; @@ -1022,7 +1014,6 @@ static int xillybus_myflush(struct xilly_channel *channel, long timeout) if (channel->endpoint->fatal_error) return -EIO; rc = mutex_lock_interruptible(&channel->rd_mutex); - if (rc) return rc; @@ -1120,8 +,6 @@ static int xillybus_myflush(struct xilly_channel *channel, long timeout) * If bufidx == channel->rd_fpga_buf_idx we're either empty or full. */ - rc = 0; - while (1) { /* Loop waiting for draining of buffers */ spin_lock_irqsave(&channel->rd_spinlock, flags); @@ -1217,12 +1206,9 @@ static ssize_t xillybus_write(struct file *filp, const char __user *userbuf, return -EIO; rc = mutex_lock_interruptible(&channel->rd_mutex); - if (rc) return rc; - rc = 0; /* Just to be clear about it. Compiler optimizes this out */ - while (1) { int bytes_to_do = count - bytes_done; @@ -1840,7 +1826,6 @@ static int xillybus_init_chrdev(struct xilly_endpoint *endpoint, rc = alloc_chrdev_region(&dev, 0, /* minor start */ endpoint->num_channels, xillyname); - if (rc) { dev_warn(endpoint->dev, "Failed to obtain major/minors"); return rc; @@ -1965,7 +1950,7 @@ static int xilly_quiesce(struct xilly_endpoint *endpoint) int xillybus_endpoint_discovery(struct xilly_endpoint *endpoint) { - int rc = 0; + int rc; void *bootstrap_resources; int idtbuffersize = (1 << PAGE_SHIFT); @@ -1999,7 +1984,6 @@ int xillybus_endpoint_discovery(struct xilly_endpoint *endpoint) endpoint->num_channels = 0; rc = xilly_setupchannels(
[PATCH 10/18] staging: xillybus: Use the return value of wait_event_interruptible
Rather than checking the wait condition, the return value of wait_event_interruptible() and wait_event_interruptible_timeout() is used. Suggested-by: Dan Carpenter Signed-off-by: Eli Billauer --- drivers/staging/xillybus/xillybus_core.c | 38 +++--- 1 files changed, 19 insertions(+), 19 deletions(-) diff --git a/drivers/staging/xillybus/xillybus_core.c b/drivers/staging/xillybus/xillybus_core.c index 53d5e42..63c2c14 100644 --- a/drivers/staging/xillybus/xillybus_core.c +++ b/drivers/staging/xillybus/xillybus_core.c @@ -615,6 +615,7 @@ static int xilly_obtain_idt(struct xilly_endpoint *endpoint) { struct xilly_channel *channel; unsigned char *version; + long t; channel = endpoint->channels[1]; /* This should be generated ad-hoc */ @@ -624,11 +625,11 @@ static int xilly_obtain_idt(struct xilly_endpoint *endpoint) (3 << 24), /* Opcode 3 for channel 0 = Send IDT */ endpoint->registers + fpga_buf_ctrl_reg); - wait_event_interruptible_timeout(channel->wr_wait, -(!channel->wr_sleepy), -XILLY_TIMEOUT); + t = wait_event_interruptible_timeout(channel->wr_wait, +(!channel->wr_sleepy), +XILLY_TIMEOUT); - if (channel->wr_sleepy) { + if (t <= 0) { dev_err(endpoint->dev, "Failed to obtain IDT. Aborting.\n"); if (endpoint->fatal_error) @@ -943,7 +944,7 @@ interrupted: /* Mutex is not held if got here */ (!channel->wr_sleepy), left_to_sleep); - if (!channel->wr_sleepy) + if (left_to_sleep > 0) /* wr_sleepy deasserted */ continue; if (left_to_sleep < 0) { /* Interrupt */ @@ -1379,10 +1380,8 @@ static ssize_t xillybus_write(struct file *filp, const char __user *userbuf, break; } - wait_event_interruptible(channel->rd_wait, -(!channel->rd_full)); - - if (channel->rd_full) { + if (wait_event_interruptible(channel->rd_wait, +(!channel->rd_full))) { mutex_unlock(&channel->rd_mutex); if (channel->endpoint->fatal_error) @@ -1931,16 +1930,17 @@ EXPORT_SYMBOL(xillybus_init_endpoint); static int xilly_quiesce(struct xilly_endpoint *endpoint) { + long t; + endpoint->idtlen = -1; iowrite32((u32) (endpoint->dma_using_dac & 0x0001), endpoint->registers + fpga_dma_control_reg); - wait_event_interruptible_timeout(endpoint->ep_wait, -(endpoint->idtlen >= 0), -XILLY_TIMEOUT); - - if (endpoint->idtlen < 0) { + t = wait_event_interruptible_timeout(endpoint->ep_wait, +(endpoint->idtlen >= 0), +XILLY_TIMEOUT); + if (t <= 0) { dev_err(endpoint->dev, "Failed to quiesce the device on exit.\n"); return -ENODEV; @@ -1951,6 +1951,7 @@ static int xilly_quiesce(struct xilly_endpoint *endpoint) int xillybus_endpoint_discovery(struct xilly_endpoint *endpoint) { int rc; + long t; void *bootstrap_resources; int idtbuffersize = (1 << PAGE_SHIFT); @@ -1999,11 +2000,10 @@ int xillybus_endpoint_discovery(struct xilly_endpoint *endpoint) iowrite32((u32) (endpoint->dma_using_dac & 0x0001), endpoint->registers + fpga_dma_control_reg); - wait_event_interruptible_timeout(endpoint->ep_wait, -(endpoint->idtlen >= 0), -XILLY_TIMEOUT); - - if (endpoint->idtlen < 0) { + t = wait_event_interruptible_timeout(endpoint->ep_wait, +(endpoint->idtlen >= 0), +XILLY_TIMEOUT); + if (t <= 0) { dev_err(endpoint->dev, "No response from FPGA. Aborting.\n"); return -ENODEV; } -- 1.7.2.3 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 00/18] staging: xillybus: Coding style fixes
These patches are a result of Dan Carpenter's remarks after looking at the driver. A huge thanks goes to him for taking the time to review the code, and his clear and helpful comments. A significant part of the corrections is my extrapolation of Dan's remarks on similar cases. If something silly stands out in these patches, odds are it's me, not Dan. :) Regards, Eli Eli Billauer (18): staging: xillybus: Use devm_kcalloc() for arrays staging: xillybus: Use SEEK_* predefined constants staging: xillybus: Non-interruptible mutex_lock() on release method staging: xillybus: Removed unnecessary warning message staging: xillybus: Removed unnecessary error message staging: xillybus: Improved error handling staging: xillybus: Improved goto flow for error handling staging: xillybus: EAGAIN status handling improvement staging: xillybus: Fixes related to "rc" variable staging: xillybus: Use the return value of wait_event_interruptible staging: xillybus: Clarified the stop condition for a loop staging: xillybus: Added curly brackets as required staging: xillybus: Fix comments staging: xillybus: Fix incorrect cast staging: xillybus: Reorganize line breaks for clarity staging: xillybus: Trivial coding style fixes staging: xillybus: Fix indentations staging: xillybus: Blank lines add/remove drivers/staging/xillybus/xillybus.h |1 - drivers/staging/xillybus/xillybus_core.c | 325 -- drivers/staging/xillybus/xillybus_of.c |5 +- drivers/staging/xillybus/xillybus_pcie.c | 16 +- 4 files changed, 144 insertions(+), 203 deletions(-) -- 1.7.2.3 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 07/18] staging: xillybus: Improved goto flow for error handling
Suggested-by: Dan Carpenter Signed-off-by: Eli Billauer --- drivers/staging/xillybus/xillybus_core.c | 12 ++-- 1 files changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/staging/xillybus/xillybus_core.c b/drivers/staging/xillybus/xillybus_core.c index fc14b14..45dbf07 100644 --- a/drivers/staging/xillybus/xillybus_core.c +++ b/drivers/staging/xillybus/xillybus_core.c @@ -1837,7 +1837,7 @@ static int xillybus_init_chrdev(struct xilly_endpoint *endpoint, if (rc) { dev_warn(endpoint->dev, "Failed to obtain major/minors"); - goto error1; + return rc; } endpoint->major = major = MAJOR(dev); @@ -1849,7 +1849,7 @@ static int xillybus_init_chrdev(struct xilly_endpoint *endpoint, endpoint->num_channels); if (rc) { dev_warn(endpoint->dev, "Failed to add cdev. Aborting.\n"); - goto error2; + goto unregister_chrdev; } idt++; @@ -1874,7 +1874,8 @@ static int xillybus_init_chrdev(struct xilly_endpoint *endpoint, dev_warn(endpoint->dev, "Failed to create %s device. Aborting.\n", devname); - goto error3; + rc = -ENODEV; + goto unroll_device_create; } } @@ -1882,15 +1883,14 @@ static int xillybus_init_chrdev(struct xilly_endpoint *endpoint, endpoint->num_channels); return 0; /* succeed */ -error3: +unroll_device_create: devnum--; i--; for (; devnum >= 0; devnum--, i--) device_destroy(xillybus_class, MKDEV(major, i)); cdev_del(&endpoint->cdev); -error2: +unregister_chrdev: unregister_chrdev_region(MKDEV(major, minor), endpoint->num_channels); -error1: return rc; } -- 1.7.2.3 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 08/18] staging: xillybus: EAGAIN status handling improvement
The -EAGAIN status is passed through an "rc" variable instead of a less common flow. Suggested-by: Dan Carpenter Signed-off-by: Eli Billauer --- drivers/staging/xillybus/xillybus_core.c | 16 +++- 1 files changed, 11 insertions(+), 5 deletions(-) diff --git a/drivers/staging/xillybus/xillybus_core.c b/drivers/staging/xillybus/xillybus_core.c index 45dbf07..f66ffa7 100644 --- a/drivers/staging/xillybus/xillybus_core.c +++ b/drivers/staging/xillybus/xillybus_core.c @@ -833,7 +833,7 @@ static ssize_t xillybus_read(struct file *filp, char __user *userbuf, if (ready) goto desperate; - bytes_done = -EAGAIN; + rc = -EAGAIN; break; } @@ -995,6 +995,9 @@ desperate: if (channel->endpoint->fatal_error) return -EIO; + if (rc) + return rc; + return bytes_done; } @@ -1386,7 +1389,7 @@ static ssize_t xillybus_write(struct file *filp, const char __user *userbuf, */ if (filp->f_flags & O_NONBLOCK) { - bytes_done = -EAGAIN; + rc = -EAGAIN; break; } @@ -1412,6 +1415,12 @@ static ssize_t xillybus_write(struct file *filp, const char __user *userbuf, &channel->rd_workitem, XILLY_RX_TIMEOUT); + if (channel->endpoint->fatal_error) + return -EIO; + + if (rc) + return rc; + if ((channel->rd_synchronous) && (bytes_done > 0)) { rc = xillybus_myflush(filp->private_data, 0); /* No timeout */ @@ -1419,9 +1428,6 @@ static ssize_t xillybus_write(struct file *filp, const char __user *userbuf, return rc; } - if (channel->endpoint->fatal_error) - return -EIO; - return bytes_done; } -- 1.7.2.3 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 03/18] staging: xillybus: Non-interruptible mutex_lock() on release method
Responding to an interrupt while handling the "release" method can't end well anyhow. In practical cases, this can force the user to wait up to one second while flushing remaining data is attempted (a timeout on the flush mechanism limits the time for flushing). Suggested-by: Dan Carpenter Signed-off-by: Eli Billauer --- drivers/staging/xillybus/xillybus_core.c | 16 ++-- 1 files changed, 2 insertions(+), 14 deletions(-) diff --git a/drivers/staging/xillybus/xillybus_core.c b/drivers/staging/xillybus/xillybus_core.c index 61699fa..3e14198 100644 --- a/drivers/staging/xillybus/xillybus_core.c +++ b/drivers/staging/xillybus/xillybus_core.c @@ -1588,7 +1588,6 @@ unlock_wr: static int xillybus_release(struct inode *inode, struct file *filp) { - int rc; unsigned long flags; struct xilly_channel *channel = filp->private_data; @@ -1599,13 +1598,7 @@ static int xillybus_release(struct inode *inode, struct file *filp) return -EIO; if (filp->f_mode & FMODE_WRITE) { - rc = mutex_lock_interruptible(&channel->rd_mutex); - - if (rc) { - dev_warn(channel->endpoint->dev, -"Failed to close file. Hardware left in messy state.\n"); - return rc; - } + mutex_lock(&channel->rd_mutex); channel->rd_ref_count--; @@ -1625,12 +1618,7 @@ static int xillybus_release(struct inode *inode, struct file *filp) } if (filp->f_mode & FMODE_READ) { - rc = mutex_lock_interruptible(&channel->wr_mutex); - if (rc) { - dev_warn(channel->endpoint->dev, -"Failed to close file. Hardware left in messy state.\n"); - return rc; - } + mutex_lock(&channel->wr_mutex); channel->wr_ref_count--; -- 1.7.2.3 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 01/18] staging: xillybus: Use devm_kcalloc() for arrays
Replace devm_kzalloc where it applies. Suggested-by: Dan Carpenter Signed-off-by: Eli Billauer --- drivers/staging/xillybus/xillybus_core.c | 16 1 files changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/staging/xillybus/xillybus_core.c b/drivers/staging/xillybus/xillybus_core.c index d5a7202..cacd560 100644 --- a/drivers/staging/xillybus/xillybus_core.c +++ b/drivers/staging/xillybus/xillybus_core.c @@ -329,9 +329,9 @@ static int xilly_get_dma_buffers(struct xilly_endpoint *ep, struct xilly_buffer *this_buffer = NULL; /* Init to silence warning */ if (buffers) { /* Not the message buffer */ - this_buffer = devm_kzalloc( - dev, bufnum * sizeof(struct xilly_buffer), - GFP_KERNEL); + this_buffer = devm_kcalloc(dev, bufnum, + sizeof(struct xilly_buffer), + GFP_KERNEL); if (!this_buffer) return -ENOMEM; @@ -434,13 +434,13 @@ static int xilly_setupchannels(struct xilly_endpoint *ep, .regdirection = 0x8000, }; - channel = devm_kzalloc(dev, ep->num_channels * + channel = devm_kcalloc(dev, ep->num_channels, sizeof(struct xilly_channel), GFP_KERNEL); if (!channel) goto memfail; - ep->channels = devm_kzalloc(dev, (ep->num_channels + 1) * + ep->channels = devm_kcalloc(dev, ep->num_channels + 1, sizeof(struct xilly_channel *), GFP_KERNEL); @@ -517,9 +517,9 @@ static int xilly_setupchannels(struct xilly_endpoint *ep, bytebufsize = channel->rd_buf_size = bufsize * (1 << channel->log2_element_size); - buffers = devm_kzalloc(dev, - bufnum * sizeof(struct xilly_buffer *), - GFP_KERNEL); + buffers = devm_kcalloc(dev, bufnum, + sizeof(struct xilly_buffer *), + GFP_KERNEL); if (!buffers) goto memfail; -- 1.7.2.3 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 05/18] staging: xillybus: Removed unnecessary error message
Suggested-by: Dan Carpenter Signed-off-by: Eli Billauer --- drivers/staging/xillybus/xillybus_core.c | 13 - 1 files changed, 4 insertions(+), 9 deletions(-) diff --git a/drivers/staging/xillybus/xillybus_core.c b/drivers/staging/xillybus/xillybus_core.c index 3050815..222457f 100644 --- a/drivers/staging/xillybus/xillybus_core.c +++ b/drivers/staging/xillybus/xillybus_core.c @@ -438,14 +438,14 @@ static int xilly_setupchannels(struct xilly_endpoint *ep, sizeof(struct xilly_channel), GFP_KERNEL); if (!channel) - goto memfail; + return -ENOMEM; ep->channels = devm_kcalloc(dev, ep->num_channels + 1, sizeof(struct xilly_channel *), GFP_KERNEL); if (!ep->channels) - goto memfail; + return -ENOMEM; ep->channels[0] = NULL; /* Channel 0 is message buf. */ @@ -522,7 +522,7 @@ static int xilly_setupchannels(struct xilly_endpoint *ep, GFP_KERNEL); if (!buffers) - goto memfail; + return -ENOMEM; } else { bytebufsize = bufsize << 2; } @@ -557,7 +557,7 @@ static int xilly_setupchannels(struct xilly_endpoint *ep, } if (rc) - goto memfail; + return -ENOMEM; } if (!msg_buf_done) { @@ -566,11 +566,6 @@ static int xilly_setupchannels(struct xilly_endpoint *ep, return -ENODEV; } return 0; - -memfail: - dev_err(ep->dev, - "Failed to assign DMA buffer memory. Aborting.\n"); - return -ENOMEM; } static void xilly_scan_idt(struct xilly_endpoint *endpoint, -- 1.7.2.3 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 04/18] staging: xillybus: Removed unnecessary warning message
Suggested-by: Dan Carpenter Signed-off-by: Eli Billauer --- drivers/staging/xillybus/xillybus_core.c | 10 ++ 1 files changed, 2 insertions(+), 8 deletions(-) diff --git a/drivers/staging/xillybus/xillybus_core.c b/drivers/staging/xillybus/xillybus_core.c index 3e14198..3050815 100644 --- a/drivers/staging/xillybus/xillybus_core.c +++ b/drivers/staging/xillybus/xillybus_core.c @@ -2115,17 +2115,11 @@ EXPORT_SYMBOL(xillybus_endpoint_remove); static int __init xillybus_init(void) { - int rc = 0; - mutex_init(&ep_list_lock); xillybus_class = class_create(THIS_MODULE, xillyname); - if (IS_ERR(xillybus_class)) { - rc = PTR_ERR(xillybus_class); - pr_warn("Failed to register class xillybus\n"); - - return rc; - } + if (IS_ERR(xillybus_class)) + return PTR_ERR(xillybus_class); xillybus_wq = alloc_workqueue(xillyname, 0, 0); if (!xillybus_wq) { -- 1.7.2.3 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 16/18] staging: xillybus: Trivial coding style fixes
Suggested-by: Dan Carpenter Signed-off-by: Eli Billauer --- drivers/staging/xillybus/xillybus_core.c |7 +++ 1 files changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/staging/xillybus/xillybus_core.c b/drivers/staging/xillybus/xillybus_core.c index 65bbebb..c678b6c 100644 --- a/drivers/staging/xillybus/xillybus_core.c +++ b/drivers/staging/xillybus/xillybus_core.c @@ -407,8 +407,7 @@ static int xilly_get_dma_buffers(struct xilly_endpoint *ep, static int xilly_setupchannels(struct xilly_endpoint *ep, unsigned char *chandesc, - int entries - ) + int entries) { struct device *dev = ep->dev; int i, entry, rc; @@ -784,8 +783,8 @@ static ssize_t xillybus_read(struct file *filp, char __user *userbuf, * the channel-specific mutex. */ - iowrite32(1 | (channel->chan_num << 1) - | (bufidx << 12), + iowrite32(1 | (channel->chan_num << 1) | + (bufidx << 12), channel->endpoint->registers + fpga_buf_ctrl_reg); } -- 1.7.2.3 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 12/18] staging: xillybus: Added curly brackets as required
Suggested-by: Dan Carpenter Signed-off-by: Eli Billauer --- drivers/staging/xillybus/xillybus_core.c |8 +--- drivers/staging/xillybus/xillybus_pcie.c |4 ++-- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/drivers/staging/xillybus/xillybus_core.c b/drivers/staging/xillybus/xillybus_core.c index 1b63197..0001d18 100644 --- a/drivers/staging/xillybus/xillybus_core.c +++ b/drivers/staging/xillybus/xillybus_core.c @@ -141,7 +141,7 @@ irqreturn_t xillybus_isr(int irq, void *data) ep->msg_buf_size, DMA_FROM_DEVICE); - for (i = 0; i < buf_size; i += 2) + for (i = 0; i < buf_size; i += 2) { if (((buf[i+1] >> 28) & 0xf) != ep->msg_counter) { malformed_message(ep, &buf[i]); dev_warn(ep->dev, @@ -166,6 +166,7 @@ irqreturn_t xillybus_isr(int irq, void *data) return IRQ_HANDLED; } else if (buf[i] & (1 << 22)) /* Last message */ break; + } if (i >= buf_size) { dev_err(ep->dev, "Bad interrupt message. Stopping.\n"); @@ -1093,10 +1094,11 @@ static int xillybus_myflush(struct xilly_channel *channel, long timeout) channel->endpoint->registers + fpga_buf_ctrl_reg); mutex_unlock(&channel->endpoint->register_mutex); - } else if (bufidx == 0) + } else if (bufidx == 0) { bufidx = channel->num_rd_buffers - 1; - else + } else { bufidx--; + } channel->rd_host_buf_pos = new_rd_host_buf_pos; diff --git a/drivers/staging/xillybus/xillybus_pcie.c b/drivers/staging/xillybus/xillybus_pcie.c index 371cec3..ec9b923 100644 --- a/drivers/staging/xillybus/xillybus_pcie.c +++ b/drivers/staging/xillybus/xillybus_pcie.c @@ -199,9 +199,9 @@ static int xilly_probe(struct pci_dev *pdev, * nobody and use 32 bits DMA addressing in any case. */ - if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) + if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) { endpoint->dma_using_dac = 0; - else { + } else { dev_err(endpoint->dev, "Failed to set DMA mask. Aborting.\n"); return -ENODEV; } -- 1.7.2.3 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 13/18] staging: xillybus: Fix comments
Trivial comments removed, and one comment clarified Suggested-by: Dan Carpenter Signed-off-by: Eli Billauer --- drivers/staging/xillybus/xillybus_core.c | 15 --- 1 files changed, 8 insertions(+), 7 deletions(-) diff --git a/drivers/staging/xillybus/xillybus_core.c b/drivers/staging/xillybus/xillybus_core.c index 0001d18..04c60c6 100644 --- a/drivers/staging/xillybus/xillybus_core.c +++ b/drivers/staging/xillybus/xillybus_core.c @@ -402,7 +402,7 @@ static int xilly_get_dma_buffers(struct xilly_endpoint *ep, s->left_of_salami -= bytebufsize; s->salami += bytebufsize; } - return 0; /* Success */ + return 0; } static int xilly_setupchannels(struct xilly_endpoint *ep, @@ -668,7 +668,7 @@ static int xilly_obtain_idt(struct xilly_endpoint *endpoint) return -ENODEV; } - return 0; /* Success */ + return 0; } static ssize_t xillybus_read(struct file *filp, char __user *userbuf, @@ -977,10 +977,11 @@ desperate: } /* -* Formally speaking, we should block for data at this point. -* But to keep the code cleaner, we'll just finish the loop, -* make the unlikely check for data, and then block at the -* usual place. +* Reaching here means that we *do* have data in the buffer, +* but the "partial" flag disallows returning less than +* required. And we don't have as much. So loop again, +* which is likely to end up blocking indefinitely until +* enough data has arrived. */ } @@ -1947,7 +1948,7 @@ static int xilly_quiesce(struct xilly_endpoint *endpoint) "Failed to quiesce the device on exit.\n"); return -ENODEV; } - return 0; /* Success */ + return 0; } int xillybus_endpoint_discovery(struct xilly_endpoint *endpoint) -- 1.7.2.3 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 15/18] staging: xillybus: Reorganize line breaks for clarity
Suggested-by: Dan Carpenter Signed-off-by: Eli Billauer --- drivers/staging/xillybus/xillybus_core.c | 29 + 1 files changed, 13 insertions(+), 16 deletions(-) diff --git a/drivers/staging/xillybus/xillybus_core.c b/drivers/staging/xillybus/xillybus_core.c index 5ed89ce..65bbebb 100644 --- a/drivers/staging/xillybus/xillybus_core.c +++ b/drivers/staging/xillybus/xillybus_core.c @@ -770,14 +770,11 @@ static ssize_t xillybus_read(struct file *filp, char __user *userbuf, bytes_done += howmany; if (bufferdone) { - channel->endpoint->ephw-> - hw_sync_sgl_for_device - ( - channel->endpoint, - channel->wr_buffers[bufidx]-> - dma_addr, - channel->wr_buf_size, - DMA_FROM_DEVICE); + channel->endpoint->ephw->hw_sync_sgl_for_device( + channel->endpoint, + channel->wr_buffers[bufidx]->dma_addr, + channel->wr_buf_size, + DMA_FROM_DEVICE); /* * Tell FPGA the buffer is done with. It's an @@ -1031,7 +1028,9 @@ static int xillybus_myflush(struct xilly_channel *channel, long timeout) bufidx = channel->rd_host_buf_idx; - bufidx_minus1 = (bufidx == 0) ? channel->num_rd_buffers - 1 : bufidx-1; + bufidx_minus1 = (bufidx == 0) ? + channel->num_rd_buffers - 1 : + bufidx - 1; end_offset_plus1 = channel->rd_host_buf_pos >> channel->log2_element_size; @@ -1320,13 +1319,11 @@ static ssize_t xillybus_write(struct file *filp, const char __user *userbuf, bytes_done += howmany; if (bufferdone) { - channel->endpoint->ephw-> - hw_sync_sgl_for_device( - channel->endpoint, - channel->rd_buffers[bufidx]-> - dma_addr, - channel->rd_buf_size, - DMA_TO_DEVICE); + channel->endpoint->ephw->hw_sync_sgl_for_device( + channel->endpoint, + channel->rd_buffers[bufidx]->dma_addr, + channel->rd_buf_size, + DMA_TO_DEVICE); mutex_lock(&channel->endpoint->register_mutex); -- 1.7.2.3 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 17/18] staging: xillybus: Fix indentations
Signed-off-by: Eli Billauer --- drivers/staging/xillybus/xillybus_core.c | 58 +++--- drivers/staging/xillybus/xillybus_pcie.c |2 +- 2 files changed, 30 insertions(+), 30 deletions(-) diff --git a/drivers/staging/xillybus/xillybus_core.c b/drivers/staging/xillybus/xillybus_core.c index c678b6c..c985774 100644 --- a/drivers/staging/xillybus/xillybus_core.c +++ b/drivers/staging/xillybus/xillybus_core.c @@ -146,9 +146,9 @@ irqreturn_t xillybus_isr(int irq, void *data) malformed_message(ep, &buf[i]); dev_warn(ep->dev, "Sending a NACK on counter %x (instead of %x) on entry %d\n", - ((buf[i+1] >> 28) & 0xf), - ep->msg_counter, - i/2); +((buf[i+1] >> 28) & 0xf), +ep->msg_counter, +i/2); if (++ep->failed_messages > 10) { dev_err(ep->dev, @@ -622,8 +622,8 @@ static int xilly_obtain_idt(struct xilly_endpoint *endpoint) channel->wr_sleepy = 1; iowrite32(1 | - (3 << 24), /* Opcode 3 for channel 0 = Send IDT */ - endpoint->registers + fpga_buf_ctrl_reg); + (3 << 24), /* Opcode 3 for channel 0 = Send IDT */ + endpoint->registers + fpga_buf_ctrl_reg); t = wait_event_interruptible_timeout(channel->wr_wait, (!channel->wr_sleepy), @@ -647,7 +647,7 @@ static int xilly_obtain_idt(struct xilly_endpoint *endpoint) if (channel->wr_buffers[0]->end_offset != endpoint->idtlen) { dev_err(endpoint->dev, "IDT length mismatch (%d != %d). Aborting.\n", - channel->wr_buffers[0]->end_offset, endpoint->idtlen); + channel->wr_buffers[0]->end_offset, endpoint->idtlen); return -ENODEV; } @@ -785,8 +785,8 @@ static ssize_t xillybus_read(struct file *filp, char __user *userbuf, iowrite32(1 | (channel->chan_num << 1) | (bufidx << 12), - channel->endpoint->registers + - fpga_buf_ctrl_reg); + channel->endpoint->registers + + fpga_buf_ctrl_reg); } if (rc) { @@ -875,10 +875,10 @@ static ssize_t xillybus_read(struct file *filp, char __user *userbuf, fpga_buf_offset_reg); iowrite32(1 | (channel->chan_num << 1) | - (2 << 24) | /* 2 = offset limit */ - (waiting_bufidx << 12), - channel->endpoint->registers + - fpga_buf_ctrl_reg); + (2 << 24) | /* 2 = offset limit */ + (waiting_bufidx << 12), + channel->endpoint->registers + + fpga_buf_ctrl_reg); mutex_unlock(&channel->endpoint-> register_mutex); @@ -966,10 +966,10 @@ desperate: */ iowrite32(1 | (channel->chan_num << 1) | - (3 << 24) | /* Opcode 3, flush it all! */ - (waiting_bufidx << 12), - channel->endpoint->registers + - fpga_buf_ctrl_reg); + (3 << 24) | /* Opcode 3, flush it all! */ + (waiting_bufidx << 12), + channel->endpoint->registers + + fpga_buf_ctrl_reg); } /* @@ -1088,9 +1088,9 @@ static int xillybus_myflush(struct xilly_channel *channel, long timeout) channel->endpoint->registers + fpga_buf_offset_reg); iowrite32((channel->chan_num << 1) | /* Channel ID */ - (2 << 24) | /* Opcode 2, submit buffer */ - (bufidx << 12), - channel->endpoint->registers + fpga_buf_ctrl_reg); +
[PATCH 18/18] staging: xillybus: Blank lines add/remove
* Blank lines between a function call and its return status check were removed. * Double blank lines were removed. * Blank lines were added and removed as to silence checkpatch.pl --strict Suggested-by: Dan Carpenter Signed-off-by: Eli Billauer --- drivers/staging/xillybus/xillybus.h |1 - drivers/staging/xillybus/xillybus_core.c | 23 ++- 2 files changed, 2 insertions(+), 22 deletions(-) diff --git a/drivers/staging/xillybus/xillybus.h b/drivers/staging/xillybus/xillybus.h index a0806b5..b9a9eb6 100644 --- a/drivers/staging/xillybus/xillybus.h +++ b/drivers/staging/xillybus/xillybus.h @@ -146,7 +146,6 @@ struct xilly_mapping { int direction; }; - irqreturn_t xillybus_isr(int irq, void *data); struct xilly_endpoint *xillybus_init_endpoint(struct pci_dev *pdev, diff --git a/drivers/staging/xillybus/xillybus_core.c b/drivers/staging/xillybus/xillybus_core.c index c985774..4dca14e 100644 --- a/drivers/staging/xillybus/xillybus_core.c +++ b/drivers/staging/xillybus/xillybus_core.c @@ -185,7 +185,6 @@ irqreturn_t xillybus_isr(int irq, void *data) switch (opcode) { case XILLYMSG_OPCODE_RELEASEBUF: - if ((msg_channel > ep->num_channels) || (msg_channel == 0)) { malformed_message(ep, &buf[i]); @@ -333,7 +332,6 @@ static int xilly_get_dma_buffers(struct xilly_endpoint *ep, this_buffer = devm_kcalloc(dev, bufnum, sizeof(struct xilly_buffer), GFP_KERNEL); - if (!this_buffer) return -ENOMEM; } @@ -365,16 +363,15 @@ static int xilly_get_dma_buffers(struct xilly_endpoint *ep, dev, GFP_KERNEL | __GFP_DMA32 | __GFP_ZERO, allocorder); - if (!s->salami) return -ENOMEM; + s->left_of_salami = allocsize; } rc = ep->ephw->map_single(ep, s->salami, bytebufsize, s->direction, &dma_addr); - if (rc) return rc; @@ -436,14 +433,12 @@ static int xilly_setupchannels(struct xilly_endpoint *ep, channel = devm_kcalloc(dev, ep->num_channels, sizeof(struct xilly_channel), GFP_KERNEL); - if (!channel) return -ENOMEM; ep->channels = devm_kcalloc(dev, ep->num_channels + 1, sizeof(struct xilly_channel *), GFP_KERNEL); - if (!ep->channels) return -ENOMEM; @@ -520,7 +515,6 @@ static int xilly_setupchannels(struct xilly_endpoint *ep, buffers = devm_kcalloc(dev, bufnum, sizeof(struct xilly_buffer *), GFP_KERNEL); - if (!buffers) return -ENOMEM; } else { @@ -867,7 +861,6 @@ static ssize_t xillybus_read(struct file *filp, char __user *userbuf, if (channel->wr_synchronous || (offsetlimit < (buf_elements - 1))) { - mutex_lock(&channel->endpoint->register_mutex); iowrite32(offsetlimit, @@ -883,7 +876,6 @@ static ssize_t xillybus_read(struct file *filp, char __user *userbuf, mutex_unlock(&channel->endpoint-> register_mutex); } - } /* @@ -894,7 +886,6 @@ static ssize_t xillybus_read(struct file *filp, char __user *userbuf, if (!channel->wr_allow_partial || (no_time_left && (bytes_done == 0))) { - /* * This do-loop will run more than once if another * thread reasserted wr_sleepy before we got the mutex @@ -1104,7 +1095,6 @@ static int xillybus_myflush(struct xilly_channel *channel, long timeout) if (timeout < 0) goto done; /* Autoflush */ - /* * bufidx is now the last buffer written to (or equal to * rd_fpga_buf_idx if buffer was never written to), and @@ -1181,7 +1171,6 @@ static void xillybus_autoflush(struct work_struct *work) int rc; rc = xillybus_myflush(channel, -1); - if (rc == -EINTR) dev_warn(channel->endpoint->dev, "Autoflush failed because work queue thread got
[PATCH 14/18] staging: xillybus: Fix incorrect cast
Suggested-by: Dan Carpenter Signed-off-by: Eli Billauer --- drivers/staging/xillybus/xillybus_core.c |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/drivers/staging/xillybus/xillybus_core.c b/drivers/staging/xillybus/xillybus_core.c index 04c60c6..5ed89ce 100644 --- a/drivers/staging/xillybus/xillybus_core.c +++ b/drivers/staging/xillybus/xillybus_core.c @@ -664,7 +664,7 @@ static int xilly_obtain_idt(struct xilly_endpoint *endpoint) if (*version > 0x82) { dev_err(endpoint->dev, "No support for IDT version 0x%02x. Maybe the xillybus driver needs an upgarde. Aborting.\n", - (int) *version); + (unsigned int) *version); return -ENODEV; } -- 1.7.2.3 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 11/18] staging: xillybus: Clarified the stop condition for a loop
Suggested-by: Dan Carpenter Signed-off-by: Eli Billauer --- drivers/staging/xillybus/xillybus_core.c |4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/xillybus/xillybus_core.c b/drivers/staging/xillybus/xillybus_core.c index 63c2c14..1b63197 100644 --- a/drivers/staging/xillybus/xillybus_core.c +++ b/drivers/staging/xillybus/xillybus_core.c @@ -172,9 +172,9 @@ irqreturn_t xillybus_isr(int irq, void *data) return IRQ_HANDLED; } - buf_size = i; + buf_size = i + 2; - for (i = 0; i <= buf_size; i += 2) { /* Scan through messages */ + for (i = 0; i < buf_size; i += 2) { /* Scan through messages */ opcode = (buf[i] >> 24) & 0xff; msg_dir = buf[i] & 1; -- 1.7.2.3 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [PATCH] staging: xillybus: Move out of staging
Hello Dan. I've just submitted the patches for the staging git tree (yourself Cc'ed). I didn't have any objections on your comments, so there isn't much to add -- except for thank you. :) Regards, Eli On 01/09/14 15:13, Dan Carpenter wrote: Pretty nice. This is very special purpose hardware and the UAPI for this is fine. The documentation seems good. I had some minor style comments but nothing major stands out. These days I quite like the --strict option for checkpatch.pl. for i in $(find drivers/staging/xillybus/ -name \*\.c) do ./scripts/checkpatch.pl --strict -f $i done ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH] staging: xillybus: Removed unnecessary cast
Suggested-by: Dan Carpenter Signed-off-by: Eli Billauer --- drivers/staging/xillybus/xillybus_core.c |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/drivers/staging/xillybus/xillybus_core.c b/drivers/staging/xillybus/xillybus_core.c index 30bb7ac..b827fa0 100644 --- a/drivers/staging/xillybus/xillybus_core.c +++ b/drivers/staging/xillybus/xillybus_core.c @@ -657,7 +657,7 @@ static int xilly_obtain_idt(struct xilly_endpoint *endpoint) if (*version > 0x82) { dev_err(endpoint->dev, "No support for IDT version 0x%02x. Maybe the xillybus driver needs an upgarde. Aborting.\n", - (int) *version); + *version); return -ENODEV; } -- 1.7.2.3 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [PATCH 14/18] staging: xillybus: Fix incorrect cast
On 05/09/14 12:26, Dan Carpenter wrote: Sorry, I was just wrong on here. I misread the code and also my review comments were too vague and must have puzzled you. (Feel free to call me out on this if I'm wrong next time.) I beg to differ on this one: Your comments were crystal clear. The fact that I got it on 17 out of 18, proves my point. :) Looking at it now, before and after of this are basically the same. Really, I don't think there is any casting needed. Indeed, no casting is needed there. I've submitted a new patch instead of this one. Thanks again. Eli ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH] MAINTAINERS: Move Xillybus out of staging
Signed-off-by: Eli Billauer --- MAINTAINERS | 12 ++-- 1 files changed, 6 insertions(+), 6 deletions(-) diff --git a/MAINTAINERS b/MAINTAINERS index f040e7f..95bcdee 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -8789,12 +8789,6 @@ M: Arnaud Patard S: Odd Fixes F: drivers/staging/xgifb/ -STAGING - XILLYBUS DRIVER -M: Eli Billauer -L: de...@driverdev.osuosl.org -S: Supported -F: drivers/staging/xillybus/ - STARFIRE/DURALAN NETWORK DRIVER M: Ion Badulescu S: Odd Fixes @@ -10203,6 +10197,12 @@ L: linux-ser...@vger.kernel.org S: Maintained F: drivers/tty/serial/uartlite.c +XILLYBUS DRIVER +M: Eli Billauer +L: linux-ker...@vger.kernel.org +S: Supported +F: drivers/char/xillybus/ + XTENSA XTFPGA PLATFORM SUPPORT M: Max Filippov L: linux-xte...@linux-xtensa.org -- 1.7.2.3 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [PATCH 4/4] staging: xillybus: Remove sparse error on IS_ERR()
Hi, Indeed -- I upgraded to sparse 0.5.0, and there's no need for this fix anymore. I'll start keeping track of sparse's git repo from now on. Dan -- Thanks for pointing this out. Greg -- Please don't apply this patch. Eli On 08/07/14 14:36, Dan Carpenter wrote: On Sat, Jul 05, 2014 at 12:45:10PM +0300, Eli Billauer wrote: IS_ERR() expects a non-__iomem pointer. This should be fixed in the latest versions of Sparse. Don't make the code worse to work around bugs in the tools. regards, dan carpenter ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [PATCH] xillybus: place 'else' on same line as '}'
Hi, Thanks for this. And since I looked at the part in Codingstyle that deals with if-else, I found another few mistakes regarding braces around a single statement. The rules say, it turns out, that if one of the clauses in an if-else is longer than one statement, both clauses should be wrapped with braces. This rule is broken in lines 162, 536 and 613 of the same file. To avoid possible conflicts, I'll wait for this patch to be applied, and submit my corrections after that. Regards, Eli On 14/07/14 06:07, Jeremiah Mahler wrote: Place 'else' on same line as closing brace '}' as per Documentation/CodingStyle. Fixes 1 error found by checkpatch.pl. Signed-off-by: Jeremiah Mahler --- drivers/staging/xillybus/xillybus_core.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/staging/xillybus/xillybus_core.c b/drivers/staging/xillybus/xillybus_core.c index ab6502c..7de4c11 100644 --- a/drivers/staging/xillybus/xillybus_core.c +++ b/drivers/staging/xillybus/xillybus_core.c @@ -546,8 +546,7 @@ static int xilly_setupchannels(struct xilly_endpoint *ep, channel->rd_buffers = buffers; rc = xilly_get_dma_buffers(ep,&rd_alloc, buffers, bufnum, bytebufsize); - } - else if (channelnum> 0) { + } else if (channelnum> 0) { channel->num_wr_buffers = bufnum; channel->seekable = seekable; ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 1/2] staging: xillybus: Fix if-else coding style errors
According to Documentation/CodingStyle, when one branch of an if-else statement has multiple statements, both branches should be enclosed in curly brackets. Signed-off-by: Eli Billauer --- drivers/staging/xillybus/xillybus_core.c |7 --- 1 files changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/staging/xillybus/xillybus_core.c b/drivers/staging/xillybus/xillybus_core.c index 2d59734..0214009 100644 --- a/drivers/staging/xillybus/xillybus_core.c +++ b/drivers/staging/xillybus/xillybus_core.c @@ -158,10 +158,10 @@ irqreturn_t xillybus_isr(int irq, void *data) ep->msg_counter, i/2); - if (++ep->failed_messages > 10) + if (++ep->failed_messages > 10) { dev_err(ep->dev, "Lost sync with interrupt messages. Stopping.\n"); - else { + } else { ep->ephw->hw_sync_sgl_for_device( ep, ep->msgbuf_dma_addr, @@ -532,8 +532,9 @@ static int xilly_setupchannels(struct xilly_endpoint *ep, if (!buffers) goto memfail; - } else + } else { bytebufsize = bufsize << 2; + } if (!is_writebuf) { channel->num_rd_buffers = bufnum; -- 1.7.2.3 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 2/2] staging: xillybus: Removed outdated part in README
The dedicated memory management routines have been replaced with devres API, so the related part is removed from the doc. Signed-off-by: Eli Billauer --- drivers/staging/xillybus/README | 23 --- 1 files changed, 0 insertions(+), 23 deletions(-) diff --git a/drivers/staging/xillybus/README b/drivers/staging/xillybus/README index d2d848a..81d111b 100644 --- a/drivers/staging/xillybus/README +++ b/drivers/staging/xillybus/README @@ -26,7 +26,6 @@ Contents: -- Data granularity -- Probing -- Buffer allocation - -- Memory management -- The "nonempty" message (supporting poll) @@ -365,28 +364,6 @@ Or, if there already is a partially used page at hand, the buffer is packed into that page. It can be shown that all pages requested from the kernel (except possibly for the last) are 100% utilized this way. -Memory management -- - -The tricky part about the buffer allocation procedure described above is -freeing and unmapping the buffers, in particular if something goes wrong in -the middle, and the allocations need to be rolled back. The three-stage -probing procedure makes this even more crucial, since temporary buffers are -set up and mapped in the first of its two stages. - -To keep the code clean from complicated and bug-prone memory release routines, -there are special routines for allocating memory. For example, instead of -calling kzalloc, there's - -void *xilly_malloc(struct xilly_cleanup *mem, size_t size) - -which effectively allocates a zeroed buffer of size "size". Its first -argument, "mem", is where this allocation is enlisted, so that it's released -when xillybus_do_cleanup() is called with the same "mem" structure. - -Two other functions enlist allocations in this structure: xilly_pagealloc() -for page allocations and xilly_map_single_*() for DMA mapping. - The "nonempty" message (supporting poll) --- -- 1.7.2.3 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 0/6] staging: xillybus: Removal of memory barriers
This patchset removes several memory barriers that seem to be unnecessary. Most of them were originally inserted in a "better safe than sorry" spirit, but these may turn out confusing in the long run. Each patch removes memory barriers based upon a different argument, in order to simplify their review. Even though the driver has been tested on both platforms that are relevant today (arm and x86), this doesn't guarantee that I haven't done something foolish that will cause problems in some new platform. Reviews and comments on these patches are therefore most welcome. Thanks, Eli Eli Billauer (6): staging: xillybus: Remove mmiowb() before wait_event_*() calls staging: xillybus: Removed mmiowb() before mutex_unlock() staging: xillybus: Removed mmiowb() as iowrite32() is ordered staging: xillybus: Removed write memory barriers before wait_event_*() staging: xillybus: Removed unnecessary smp_wmb() staging: xillybus: Removed read barrier at beginning of ISR drivers/staging/xillybus/xillybus_core.c | 41 ++--- 1 files changed, 3 insertions(+), 38 deletions(-) -- 1.7.2.3 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 5/6] staging: xillybus: Removed unnecessary smp_wmb()
These memory barriers were added "just to be safe". Signed-off-by: Eli Billauer --- drivers/staging/xillybus/xillybus_core.c |4 1 files changed, 0 insertions(+), 4 deletions(-) diff --git a/drivers/staging/xillybus/xillybus_core.c b/drivers/staging/xillybus/xillybus_core.c index f48e4de..8de4fbd 100644 --- a/drivers/staging/xillybus/xillybus_core.c +++ b/drivers/staging/xillybus/xillybus_core.c @@ -2061,8 +2061,6 @@ int xillybus_endpoint_discovery(struct xilly_endpoint *endpoint) if (rc) goto failed_idt; - smp_wmb(); - rc = xilly_obtain_idt(endpoint); if (rc) @@ -2086,8 +2084,6 @@ int xillybus_endpoint_discovery(struct xilly_endpoint *endpoint) if (rc) goto failed_idt; - smp_wmb(); /* mutex_lock below should suffice, but won't hurt.*/ - /* * endpoint is now completely configured. We put it on the list * available to open() before registering the char device(s) -- 1.7.2.3 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 3/6] staging: xillybus: Removed mmiowb() as iowrite32() is ordered
mmiowb() was used to make sure that iowrite32() take place in the correct order, which is an unnecessary precuation. Signed-off-by: Eli Billauer --- drivers/staging/xillybus/xillybus_core.c | 17 ++--- 1 files changed, 2 insertions(+), 15 deletions(-) diff --git a/drivers/staging/xillybus/xillybus_core.c b/drivers/staging/xillybus/xillybus_core.c index 138c069..bee58a2 100644 --- a/drivers/staging/xillybus/xillybus_core.c +++ b/drivers/staging/xillybus/xillybus_core.c @@ -389,7 +389,6 @@ static int xilly_get_dma_buffers(struct xilly_endpoint *ep, ep->registers + fpga_dma_bufaddr_lowaddr_reg); iowrite32(((u32) u64) dma_addr) >> 32) & 0x)), ep->registers + fpga_dma_bufaddr_highaddr_reg); - mmiowb(); if (buffers) { /* Not the message buffer */ this_buffer->addr = s->salami; @@ -813,7 +812,6 @@ static ssize_t xillybus_read(struct file *filp, char __user *userbuf, | (bufidx << 12), channel->endpoint->registers + fpga_buf_ctrl_reg); - mmiowb(); /* Just to appear safe */ } if (rc) { @@ -900,7 +898,6 @@ static ssize_t xillybus_read(struct file *filp, char __user *userbuf, iowrite32(offsetlimit, channel->endpoint->registers + fpga_buf_offset_reg); - mmiowb(); iowrite32(1 | (channel->chan_num << 1) | (2 << 24) | /* 2 = offset limit */ @@ -998,7 +995,6 @@ desperate: (waiting_bufidx << 12), channel->endpoint->registers + fpga_buf_ctrl_reg); - mmiowb(); /* Just to appear safe */ } /* @@ -1110,7 +1106,6 @@ static int xillybus_myflush(struct xilly_channel *channel, long timeout) iowrite32(end_offset_plus1 - 1, channel->endpoint->registers + fpga_buf_offset_reg); - mmiowb(); iowrite32((channel->chan_num << 1) | /* Channel ID */ (2 << 24) | /* Opcode 2, submit buffer */ @@ -1360,7 +1355,7 @@ static ssize_t xillybus_write(struct file *filp, const char __user *userbuf, iowrite32(end_offset_plus1 - 1, channel->endpoint->registers + fpga_buf_offset_reg); - mmiowb(); + iowrite32((channel->chan_num << 1) | (2 << 24) | /* 2 = submit buffer */ (bufidx << 12), @@ -1561,7 +1556,6 @@ static int xillybus_open(struct inode *inode, struct file *filp) ((channel->wr_synchronous & 1) << 23), channel->endpoint->registers + fpga_buf_ctrl_reg); - mmiowb(); /* Just to appear safe */ } channel->wr_ref_count++; @@ -1583,7 +1577,6 @@ static int xillybus_open(struct inode *inode, struct file *filp) (4 << 24), /* Opcode 4, open channel */ channel->endpoint->registers + fpga_buf_ctrl_reg); - mmiowb(); /* Just to appear safe */ } channel->rd_ref_count++; @@ -1636,7 +1629,6 @@ static int xillybus_release(struct inode *inode, struct file *filp) (5 << 24), /* Opcode 5, close channel */ channel->endpoint->registers + fpga_buf_ctrl_reg); - mmiowb(); /* Just to appear safe */ } mutex_unlock(&channel->rd_mutex); } @@ -1657,7 +1649,6 @@ static int xillybus_release(struct inode *inode, struct file *filp) (5 << 24), /* Opcode 5, close channel */ channel->endpoint->registers + fpga_buf_ctrl_reg); - mmiowb(); /* Just to appear safe */ /* * This is crazily cautious: We make sure that not @@ -1762,11 +1753,10 @@ static loff_t xil
[PATCH 1/6] staging: xillybus: Remove mmiowb() before wait_event_*() calls
According to Documentation/memory-barriers.txt, a memory barrier is put in place by wait_event_*() Signed-off-by: Eli Billauer --- drivers/staging/xillybus/xillybus_core.c |3 --- 1 files changed, 0 insertions(+), 3 deletions(-) diff --git a/drivers/staging/xillybus/xillybus_core.c b/drivers/staging/xillybus/xillybus_core.c index 0214009..93a3c61 100644 --- a/drivers/staging/xillybus/xillybus_core.c +++ b/drivers/staging/xillybus/xillybus_core.c @@ -640,7 +640,6 @@ static int xilly_obtain_idt(struct xilly_endpoint *endpoint) iowrite32(1 | (3 << 24), /* Opcode 3 for channel 0 = Send IDT */ endpoint->registers + fpga_buf_ctrl_reg); - mmiowb(); /* Just to appear safe */ wait_event_interruptible_timeout(channel->wr_wait, (!channel->wr_sleepy), @@ -1986,7 +1985,6 @@ static int xilly_quiesce(struct xilly_endpoint *endpoint) wmb(); /* Make sure idtlen is set before sending command */ iowrite32((u32) (endpoint->dma_using_dac & 0x0001), endpoint->registers + fpga_dma_control_reg); - mmiowb(); wait_event_interruptible_timeout(endpoint->ep_wait, (endpoint->idtlen >= 0), @@ -2055,7 +2053,6 @@ int xillybus_endpoint_discovery(struct xilly_endpoint *endpoint) */ iowrite32((u32) (endpoint->dma_using_dac & 0x0001), endpoint->registers + fpga_dma_control_reg); - mmiowb(); wait_event_interruptible_timeout(endpoint->ep_wait, (endpoint->idtlen >= 0), -- 1.7.2.3 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 2/6] staging: xillybus: Removed mmiowb() before mutex_unlock()
The relevant sequences consist of two I/O memory writes. The second write depends on the first one. mmiowb() was inserted to make sure that no other thread inserts a "first write" before the current one finished its second. As a mutex protects this critical sequence, mmiowb() is unnecessary. Signed-off-by: Eli Billauer --- drivers/staging/xillybus/xillybus_core.c |4 1 files changed, 0 insertions(+), 4 deletions(-) diff --git a/drivers/staging/xillybus/xillybus_core.c b/drivers/staging/xillybus/xillybus_core.c index 93a3c61..138c069 100644 --- a/drivers/staging/xillybus/xillybus_core.c +++ b/drivers/staging/xillybus/xillybus_core.c @@ -908,8 +908,6 @@ static ssize_t xillybus_read(struct file *filp, char __user *userbuf, channel->endpoint->registers + fpga_buf_ctrl_reg); - mmiowb(); /* Just to appear safe */ - mutex_unlock(&channel->endpoint-> register_mutex); } @@ -1118,7 +1116,6 @@ static int xillybus_myflush(struct xilly_channel *channel, long timeout) (2 << 24) | /* Opcode 2, submit buffer */ (bufidx << 12), channel->endpoint->registers + fpga_buf_ctrl_reg); - mmiowb(); /* Just to appear safe */ mutex_unlock(&channel->endpoint->register_mutex); } else if (bufidx == 0) @@ -1369,7 +1366,6 @@ static ssize_t xillybus_write(struct file *filp, const char __user *userbuf, (bufidx << 12), channel->endpoint->registers + fpga_buf_ctrl_reg); - mmiowb(); /* Just to appear safe */ mutex_unlock(&channel->endpoint-> register_mutex); -- 1.7.2.3 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 6/6] staging: xillybus: Removed read barrier at beginning of ISR
The comment (also removed) explains why it was there in the first place, but that doesn't make much sense. Signed-off-by: Eli Billauer --- drivers/staging/xillybus/xillybus_core.c |8 1 files changed, 0 insertions(+), 8 deletions(-) diff --git a/drivers/staging/xillybus/xillybus_core.c b/drivers/staging/xillybus/xillybus_core.c index 8de4fbd..d5a7202 100644 --- a/drivers/staging/xillybus/xillybus_core.c +++ b/drivers/staging/xillybus/xillybus_core.c @@ -133,17 +133,9 @@ irqreturn_t xillybus_isr(int irq, void *data) unsigned int msg_channel, msg_bufno, msg_data, msg_dir; struct xilly_channel *channel; - /* -* The endpoint structure is altered during periods when it's -* guaranteed no interrupt will occur, but in theory, the cache -* lines may not be updated. So a memory barrier is issued. -*/ - smp_rmb(); - buf = ep->msgbuf_addr; buf_size = ep->msg_buf_size/sizeof(u32); - ep->ephw->hw_sync_sgl_for_cpu(ep, ep->msgbuf_dma_addr, ep->msg_buf_size, -- 1.7.2.3 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 4/6] staging: xillybus: Removed write memory barriers before wait_event_*()
According to Documentation/memory-barriers.txt, a memory barrier is put in place by wait_event_*() Signed-off-by: Eli Billauer --- drivers/staging/xillybus/xillybus_core.c |5 + 1 files changed, 1 insertions(+), 4 deletions(-) diff --git a/drivers/staging/xillybus/xillybus_core.c b/drivers/staging/xillybus/xillybus_core.c index bee58a2..f48e4de 100644 --- a/drivers/staging/xillybus/xillybus_core.c +++ b/drivers/staging/xillybus/xillybus_core.c @@ -634,7 +634,6 @@ static int xilly_obtain_idt(struct xilly_endpoint *endpoint) channel = endpoint->channels[1]; /* This should be generated ad-hoc */ channel->wr_sleepy = 1; - wmb(); /* Setting wr_sleepy must come before the command */ iowrite32(1 | (3 << 24), /* Opcode 3 for channel 0 = Send IDT */ @@ -1968,7 +1967,7 @@ EXPORT_SYMBOL(xillybus_init_endpoint); static int xilly_quiesce(struct xilly_endpoint *endpoint) { endpoint->idtlen = -1; - wmb(); /* Make sure idtlen is set before sending command */ + iowrite32((u32) (endpoint->dma_using_dac & 0x0001), endpoint->registers + fpga_dma_control_reg); @@ -2029,8 +2028,6 @@ int xillybus_endpoint_discovery(struct xilly_endpoint *endpoint) endpoint->idtlen = -1; - smp_wmb(); - /* * Set DMA 32/64 bit mode, quiesce the device (?!) and get IDT * buffer size. -- 1.7.2.3 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH] documentation: devicetree: Added xillybus to vendor-prefixes
Signed-off-by: Eli Billauer --- .../devicetree/bindings/vendor-prefixes.txt|1 + 1 files changed, 1 insertions(+), 0 deletions(-) diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt index ac7269f..06e698a 100644 --- a/Documentation/devicetree/bindings/vendor-prefixes.txt +++ b/Documentation/devicetree/bindings/vendor-prefixes.txt @@ -147,6 +147,7 @@ winbond Winbond Electronics corp. wlfWolfson Microelectronics wm Wondermedia Technologies, Inc. xesExtreme Engineering Solutions (X-ES) +xillybus Xillybus Ltd. xlnx Xilinx zyxel ZyXEL Communications Corp. zarlinkZarlink Semiconductor -- 1.7.2.3 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH] staging: xillybus: Multiple definition of xillyname resolved (bug fix)
Signed-off-by: Eli Billauer --- drivers/staging/xillybus/xillybus.h |2 -- drivers/staging/xillybus/xillybus_core.c |2 ++ drivers/staging/xillybus/xillybus_of.c |2 ++ drivers/staging/xillybus/xillybus_pcie.c |2 ++ 4 files changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/staging/xillybus/xillybus.h b/drivers/staging/xillybus/xillybus.h index c260ebc..b62faeb 100644 --- a/drivers/staging/xillybus/xillybus.h +++ b/drivers/staging/xillybus/xillybus.h @@ -24,8 +24,6 @@ #include #include -char xillyname[] = "xillybus"; - struct xilly_endpoint_hardware; struct xilly_page { diff --git a/drivers/staging/xillybus/xillybus_core.c b/drivers/staging/xillybus/xillybus_core.c index dd0a71c..7991e57 100644 --- a/drivers/staging/xillybus/xillybus_core.c +++ b/drivers/staging/xillybus/xillybus_core.c @@ -61,6 +61,8 @@ MODULE_LICENSE("GPL v2"); #define XILLYMSG_OPCODE_FATAL_ERROR 4 #define XILLYMSG_OPCODE_NONEMPTY 5 +static const char xillyname[] = "xillybus"; + static struct class *xillybus_class; /* diff --git a/drivers/staging/xillybus/xillybus_of.c b/drivers/staging/xillybus/xillybus_of.c index b875376..122d9ba 100644 --- a/drivers/staging/xillybus/xillybus_of.c +++ b/drivers/staging/xillybus/xillybus_of.c @@ -27,6 +27,8 @@ MODULE_VERSION("1.06"); MODULE_ALIAS("xillybus_of"); MODULE_LICENSE("GPL v2"); +static const char xillyname[] = "xillybus_of"; + /* Match table for of_platform binding */ static struct of_device_id xillybus_of_match[] = { { .compatible = "xlnx,xillybus-1.00.a", }, diff --git a/drivers/staging/xillybus/xillybus_pcie.c b/drivers/staging/xillybus/xillybus_pcie.c index 592f8f7..ad45bdb 100644 --- a/drivers/staging/xillybus/xillybus_pcie.c +++ b/drivers/staging/xillybus/xillybus_pcie.c @@ -28,6 +28,8 @@ MODULE_LICENSE("GPL v2"); #define PCI_VENDOR_ID_ACTEL0x11aa #define PCI_VENDOR_ID_LATTICE 0x1204 +static const char xillyname[] = "xillybus_pcie"; + static DEFINE_PCI_DEVICE_TABLE(xillyids) = { {PCI_DEVICE(PCI_VENDOR_ID_XILINX, PCI_DEVICE_ID_XILLYBUS)}, {PCI_DEVICE(PCI_VENDOR_ID_ALTERA, PCI_DEVICE_ID_XILLYBUS)}, -- 1.7.2.3 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 2/2] staging: xillybus: Fixed sparse errors
Changes: * xillybus.h: __iomem added to struct xilly_endpoint -> registers to suppress "different address spaces" errors. * xillybus_core.c: __user added as required for the same reason. * The two member names of struct xilly_endpoint_hardware of the form sync_single_for_{cpu,device} were changed to something that won't look like the well-known functions. * All *.c files: Variables and functions made static as required. Reported-by: Greg Kroah-Hartman Signed-off-by: Eli Billauer --- drivers/staging/xillybus/xillybus.h |6 +++--- drivers/staging/xillybus/xillybus_core.c | 28 ++-- drivers/staging/xillybus/xillybus_of.c |6 +++--- drivers/staging/xillybus/xillybus_pcie.c |6 +++--- 4 files changed, 23 insertions(+), 23 deletions(-) diff --git a/drivers/staging/xillybus/xillybus.h b/drivers/staging/xillybus/xillybus.h index b62faeb..d3fc8aa 100644 --- a/drivers/staging/xillybus/xillybus.h +++ b/drivers/staging/xillybus/xillybus.h @@ -122,7 +122,7 @@ struct xilly_endpoint { struct list_head ep_list; int dma_using_dac; /* =1 if 64-bit DMA is used, =0 otherwise. */ - u32 *registers; + __iomem u32 *registers; int fatal_error; struct mutex register_mutex; @@ -150,11 +150,11 @@ struct xilly_endpoint { struct xilly_endpoint_hardware { struct module *owner; - void (*sync_single_for_cpu)(struct xilly_endpoint *, + void (*hw_sync_sgl_for_cpu)(struct xilly_endpoint *, dma_addr_t, size_t, int); - void (*sync_single_for_device)(struct xilly_endpoint *, + void (*hw_sync_sgl_for_device)(struct xilly_endpoint *, dma_addr_t, size_t, int); diff --git a/drivers/staging/xillybus/xillybus_core.c b/drivers/staging/xillybus/xillybus_core.c index 9ccd6aa..3d7471a 100644 --- a/drivers/staging/xillybus/xillybus_core.c +++ b/drivers/staging/xillybus/xillybus_core.c @@ -71,7 +71,7 @@ static struct class *xillybus_class; static LIST_HEAD(list_of_endpoints); static struct mutex ep_list_lock; -struct workqueue_struct *xillybus_wq; +static struct workqueue_struct *xillybus_wq; /* * Locking scheme: Mutexes protect invocations of character device methods. @@ -145,7 +145,7 @@ irqreturn_t xillybus_isr(int irq, void *data) buf_size = ep->msg_buf_size/sizeof(u32); - ep->ephw->sync_single_for_cpu(ep, + ep->ephw->hw_sync_sgl_for_cpu(ep, ep->msgbuf_dma_addr, ep->msg_buf_size, DMA_FROM_DEVICE); @@ -163,7 +163,7 @@ irqreturn_t xillybus_isr(int irq, void *data) pr_err("xillybus: Lost sync with " "interrupt messages. Stopping.\n"); else { - ep->ephw->sync_single_for_device( + ep->ephw->hw_sync_sgl_for_device( ep, ep->msgbuf_dma_addr, ep->msg_buf_size, @@ -297,7 +297,7 @@ irqreturn_t xillybus_isr(int irq, void *data) } } - ep->ephw->sync_single_for_device(ep, + ep->ephw->hw_sync_sgl_for_device(ep, ep->msgbuf_dma_addr, ep->msg_buf_size, DMA_FROM_DEVICE); @@ -796,7 +796,7 @@ static int xilly_obtain_idt(struct xilly_endpoint *endpoint) return rc; } - endpoint->ephw->sync_single_for_cpu( + endpoint->ephw->hw_sync_sgl_for_cpu( channel->endpoint, channel->wr_buffers[0]->dma_addr, channel->wr_buf_size, @@ -832,8 +832,8 @@ static int xilly_obtain_idt(struct xilly_endpoint *endpoint) return 0; /* Success */ } -static ssize_t xillybus_read(struct file *filp, char *userbuf, size_t count, -loff_t *f_pos) +static ssize_t xillybus_read(struct file *filp, char __user *userbuf, +size_t count, loff_t *f_pos) { ssize_t rc; unsigned long flags; @@ -917,7 +917,7 @@ static ssize_t xillybus_read(struct file *filp, char *userbuf, size_t count, if (!empty) { /* Go on, now without the spinlock */ if (bufpos == 0) /* Position zero means it's virgin */ - channel->endpoint->ephw->sync_single_for_cpu( + channel->endpoint->ephw->hw_s
[PATCH 1/2] staging: xillybus: Removed dependency on OF_DEVICE in Kconfig
This variable was removed from the kernel a while ago. Signed-off-by: Eli Billauer --- drivers/staging/xillybus/Kconfig |4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/xillybus/Kconfig b/drivers/staging/xillybus/Kconfig index 459d050..8a4181f 100644 --- a/drivers/staging/xillybus/Kconfig +++ b/drivers/staging/xillybus/Kconfig @@ -4,7 +4,7 @@ config XILLYBUS tristate "Xillybus generic FPGA interface" - depends on PCI || (OF_ADDRESS && OF_DEVICE && OF_IRQ) && m + depends on PCI || (OF_ADDRESS && OF_IRQ) && m help Xillybus is a generic interface for peripherals designed on programmable logic (FPGA). The driver probes the hardware for @@ -23,7 +23,7 @@ config XILLYBUS_PCIE config XILLYBUS_OF tristate "Xillybus over Device Tree" - depends on XILLYBUS && OF_ADDRESS && OF_DEVICE && OF_IRQ + depends on XILLYBUS && OF_ADDRESS && OF_IRQ help Set to M if you want Xillybus to find its resources from the Open Firmware Flattened Device Tree. If the target is an embedded -- 1.7.2.3 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel