From 4c093a6dc2240fd54d71a25b284e02d51509e430 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Fri, 30 Mar 2012 17:14:56 +0100 Subject: staging: comedi: pass 'struct comedi_driver *' to comedi_..._auto_config The comedi_pci_auto_config() and comedi_usb_auto_config() functions currently take a board name parameter which is actually a driver name parameter. Replace it with a pointer to the struct comedi_driver. This will allow comedi_pci_auto_config() and comedi_usb_auto_config() to call bus-type-specific auto-configuration hooks in the struct comedi_driver if they exist (they don't yet). The idea is that these bus-type-specific auto-configuration hooks won't have to search the bus for the device being auto-configured like 'attach()' hook has to. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'drivers/staging/comedi/drivers.c') diff --git a/drivers/staging/comedi/drivers.c b/drivers/staging/comedi/drivers.c index bf185e2807d1..9dd2da1e97ad 100644 --- a/drivers/staging/comedi/drivers.c +++ b/drivers/staging/comedi/drivers.c @@ -874,7 +874,7 @@ static void comedi_auto_unconfig(struct device *hardware_device) kfree(minor); } -int comedi_pci_auto_config(struct pci_dev *pcidev, const char *board_name) +int comedi_pci_auto_config(struct pci_dev *pcidev, struct comedi_driver *driver) { int options[2]; @@ -883,7 +883,7 @@ int comedi_pci_auto_config(struct pci_dev *pcidev, const char *board_name) /* pci slot */ options[1] = PCI_SLOT(pcidev->devfn); - return comedi_auto_config(&pcidev->dev, board_name, + return comedi_auto_config(&pcidev->dev, driver->driver_name, options, ARRAY_SIZE(options)); } EXPORT_SYMBOL_GPL(comedi_pci_auto_config); @@ -894,10 +894,11 @@ void comedi_pci_auto_unconfig(struct pci_dev *pcidev) } EXPORT_SYMBOL_GPL(comedi_pci_auto_unconfig); -int comedi_usb_auto_config(struct usb_device *usbdev, const char *board_name) +int comedi_usb_auto_config(struct usb_device *usbdev, + struct comedi_driver *driver) { BUG_ON(usbdev == NULL); - return comedi_auto_config(&usbdev->dev, board_name, NULL, 0); + return comedi_auto_config(&usbdev->dev, driver->driver_name, NULL, 0); } EXPORT_SYMBOL_GPL(comedi_usb_auto_config); -- cgit v1.2.3-59-g8ed1b From c43435d7722134ed1fda58ce1025f41029bd58ad Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Fri, 30 Mar 2012 17:14:58 +0100 Subject: staging: comedi: don't hijack hardware device private data comedi_auto_config() associates a Comedi minor device number with an auto-configured hardware device and comedi_auto_unconfig() disassociates it. Currently, these use the hardware device's private data pointer to point to some allocated storage holding the minor device number. This is a bit of a waste of the hardware device's private data pointer, preventing it from being used for something more useful by the low-level comedi device drivers. For example, it would make more sense if comedi_usb_auto_config() was passed a pointer to the struct usb_interface instead of the struct usb_device, but this cannot be done currently because the low-level comedi drivers already use the private data pointer in the struct usb_interface for something more useful. This patch stops the comedi core hijacking the hardware device's private data pointer. Instead, comedi_auto_config() stores a pointer to the hardware device's struct device in the struct comedi_device_file_info associated with the minor device number, and comedi_auto_unconfig() calls new function comedi_find_board_minor() to recover the minor device number associated with the hardware device. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/comedi_fops.c | 18 ++++++++++++++++++ drivers/staging/comedi/comedidev.h | 1 + drivers/staging/comedi/drivers.c | 34 ++++++++++------------------------ drivers/staging/comedi/internal.h | 1 + 4 files changed, 30 insertions(+), 24 deletions(-) (limited to 'drivers/staging/comedi/drivers.c') diff --git a/drivers/staging/comedi/comedi_fops.c b/drivers/staging/comedi/comedi_fops.c index f5417a3df240..fdf42822b962 100644 --- a/drivers/staging/comedi/comedi_fops.c +++ b/drivers/staging/comedi/comedi_fops.c @@ -2205,6 +2205,7 @@ int comedi_alloc_board_minor(struct device *hardware_device) kfree(info); return -ENOMEM; } + info->hardware_device = hardware_device; comedi_device_init(info->device); spin_lock(&comedi_file_info_table_lock); for (i = 0; i < COMEDI_NUM_BOARD_MINORS; ++i) { @@ -2292,6 +2293,23 @@ void comedi_free_board_minor(unsigned minor) } } +int comedi_find_board_minor(struct device *hardware_device) +{ + int minor; + struct comedi_device_file_info *info; + + for (minor = 0; minor < COMEDI_NUM_BOARD_MINORS; minor++) { + spin_lock(&comedi_file_info_table_lock); + info = comedi_file_info_table[minor]; + if (info && info->hardware_device == hardware_device) { + spin_unlock(&comedi_file_info_table_lock); + return minor; + } + spin_unlock(&comedi_file_info_table_lock); + } + return -ENODEV; +} + int comedi_alloc_subdevice_minor(struct comedi_device *dev, struct comedi_subdevice *s) { diff --git a/drivers/staging/comedi/comedidev.h b/drivers/staging/comedi/comedidev.h index 7e65addb91cb..965998f9d2d2 100644 --- a/drivers/staging/comedi/comedidev.h +++ b/drivers/staging/comedi/comedidev.h @@ -234,6 +234,7 @@ struct comedi_device_file_info { struct comedi_device *device; struct comedi_subdevice *read_subdevice; struct comedi_subdevice *write_subdevice; + struct device *hardware_device; }; #ifdef CONFIG_COMEDI_DEBUG diff --git a/drivers/staging/comedi/drivers.c b/drivers/staging/comedi/drivers.c index 9dd2da1e97ad..417aed2ab738 100644 --- a/drivers/staging/comedi/drivers.c +++ b/drivers/staging/comedi/drivers.c @@ -822,25 +822,14 @@ static int comedi_auto_config(struct device *hardware_device, int minor; struct comedi_device_file_info *dev_file_info; int retval; - unsigned *private_data = NULL; - if (!comedi_autoconfig) { - dev_set_drvdata(hardware_device, NULL); + if (!comedi_autoconfig) return 0; - } minor = comedi_alloc_board_minor(hardware_device); if (minor < 0) return minor; - private_data = kmalloc(sizeof(unsigned), GFP_KERNEL); - if (private_data == NULL) { - retval = -ENOMEM; - goto cleanup; - } - *private_data = minor; - dev_set_drvdata(hardware_device, private_data); - dev_file_info = comedi_get_device_file_info(minor); memset(&it, 0, sizeof(it)); @@ -853,25 +842,22 @@ static int comedi_auto_config(struct device *hardware_device, retval = comedi_device_attach(dev_file_info->device, &it); mutex_unlock(&dev_file_info->device->mutex); -cleanup: - if (retval < 0) { - kfree(private_data); + if (retval < 0) comedi_free_board_minor(minor); - } return retval; } static void comedi_auto_unconfig(struct device *hardware_device) { - unsigned *minor = (unsigned *)dev_get_drvdata(hardware_device); - if (minor == NULL) - return; - - BUG_ON(*minor >= COMEDI_NUM_BOARD_MINORS); + int minor; - comedi_free_board_minor(*minor); - dev_set_drvdata(hardware_device, NULL); - kfree(minor); + if (hardware_device == NULL) + return; + minor = comedi_find_board_minor(hardware_device); + if (minor < 0) + return; + BUG_ON(minor >= COMEDI_NUM_BOARD_MINORS); + comedi_free_board_minor(minor); } int comedi_pci_auto_config(struct pci_dev *pcidev, struct comedi_driver *driver) diff --git a/drivers/staging/comedi/internal.h b/drivers/staging/comedi/internal.h index 434ce3433368..4208fb4cf0ff 100644 --- a/drivers/staging/comedi/internal.h +++ b/drivers/staging/comedi/internal.h @@ -7,6 +7,7 @@ int insn_inval(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data); int comedi_alloc_board_minor(struct device *hardware_device); void comedi_free_board_minor(unsigned minor); +int comedi_find_board_minor(struct device *hardware_device); void comedi_reset_async_buf(struct comedi_async *async); int comedi_buf_alloc(struct comedi_device *dev, struct comedi_subdevice *s, unsigned long new_size); -- cgit v1.2.3-59-g8ed1b From d8b6ca0850c558f21989d468801ad1414b1372c4 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Fri, 30 Mar 2012 17:14:59 +0100 Subject: staging: comedi: pass usb interface to comedi_usb_auto_config The comedi_usb_auto_config() and comedi_usb_auto_unconfig() functions currently take a 'struct usb_device *'. It makes more sense to pass a 'struct usb_interface *' to allow for composite USB devices. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/comedidev.h | 6 +++--- drivers/staging/comedi/drivers.c | 12 ++++++------ drivers/staging/comedi/drivers/usbdux.c | 10 +++++----- drivers/staging/comedi/drivers/usbduxfast.c | 8 ++++---- drivers/staging/comedi/drivers/usbduxsigma.c | 10 +++++----- drivers/staging/comedi/drivers/vmk80xx.c | 4 ++-- 6 files changed, 25 insertions(+), 25 deletions(-) (limited to 'drivers/staging/comedi/drivers.c') diff --git a/drivers/staging/comedi/comedidev.h b/drivers/staging/comedi/comedidev.h index 965998f9d2d2..e4626b6231d6 100644 --- a/drivers/staging/comedi/comedidev.h +++ b/drivers/staging/comedi/comedidev.h @@ -460,10 +460,10 @@ void comedi_free_subdevice_minor(struct comedi_subdevice *s); int comedi_pci_auto_config(struct pci_dev *pcidev, struct comedi_driver *driver); void comedi_pci_auto_unconfig(struct pci_dev *pcidev); -struct usb_device; /* forward declaration */ -int comedi_usb_auto_config(struct usb_device *usbdev, +struct usb_interface; /* forward declaration */ +int comedi_usb_auto_config(struct usb_interface *intf, struct comedi_driver *driver); -void comedi_usb_auto_unconfig(struct usb_device *usbdev); +void comedi_usb_auto_unconfig(struct usb_interface *intf); #ifdef CONFIG_COMEDI_PCI_DRIVERS #define CONFIG_COMEDI_PCI diff --git a/drivers/staging/comedi/drivers.c b/drivers/staging/comedi/drivers.c index 417aed2ab738..feb33f86023b 100644 --- a/drivers/staging/comedi/drivers.c +++ b/drivers/staging/comedi/drivers.c @@ -880,17 +880,17 @@ void comedi_pci_auto_unconfig(struct pci_dev *pcidev) } EXPORT_SYMBOL_GPL(comedi_pci_auto_unconfig); -int comedi_usb_auto_config(struct usb_device *usbdev, +int comedi_usb_auto_config(struct usb_interface *intf, struct comedi_driver *driver) { - BUG_ON(usbdev == NULL); - return comedi_auto_config(&usbdev->dev, driver->driver_name, NULL, 0); + BUG_ON(intf == NULL); + return comedi_auto_config(&intf->dev, driver->driver_name, NULL, 0); } EXPORT_SYMBOL_GPL(comedi_usb_auto_config); -void comedi_usb_auto_unconfig(struct usb_device *usbdev) +void comedi_usb_auto_unconfig(struct usb_interface *intf) { - BUG_ON(usbdev == NULL); - comedi_auto_unconfig(&usbdev->dev); + BUG_ON(intf == NULL); + comedi_auto_unconfig(&intf->dev); } EXPORT_SYMBOL_GPL(comedi_usb_auto_unconfig); diff --git a/drivers/staging/comedi/drivers/usbdux.c b/drivers/staging/comedi/drivers/usbdux.c index 1420fcce79c0..781da446f3c4 100644 --- a/drivers/staging/comedi/drivers/usbdux.c +++ b/drivers/staging/comedi/drivers/usbdux.c @@ -2306,11 +2306,11 @@ static void usbdux_firmware_request_complete_handler(const struct firmware *fw, void *context) { struct usbduxsub *usbduxsub_tmp = context; - struct usb_device *usbdev = usbduxsub_tmp->usbdev; + struct usb_interface *uinterf = usbduxsub_tmp->interface; int ret; if (fw == NULL) { - dev_err(&usbdev->dev, + dev_err(&uinterf->dev, "Firmware complete handler without firmware!\n"); return; } @@ -2322,11 +2322,11 @@ static void usbdux_firmware_request_complete_handler(const struct firmware *fw, ret = firmwareUpload(usbduxsub_tmp, fw->data, fw->size); if (ret) { - dev_err(&usbdev->dev, + dev_err(&uinterf->dev, "Could not upload firmware (err=%d)\n", ret); goto out; } - comedi_usb_auto_config(usbdev, &driver_usbdux); + comedi_usb_auto_config(uinterf, &driver_usbdux); out: release_firmware(fw); } @@ -2608,7 +2608,7 @@ static void usbduxsub_disconnect(struct usb_interface *intf) dev_err(&intf->dev, "comedi_: BUG! called with wrong ptr!!!\n"); return; } - comedi_usb_auto_unconfig(udev); + comedi_usb_auto_unconfig(intf); down(&start_stop_sem); down(&usbduxsub_tmp->sem); tidy_up(usbduxsub_tmp); diff --git a/drivers/staging/comedi/drivers/usbduxfast.c b/drivers/staging/comedi/drivers/usbduxfast.c index bf6198ea4e2b..2b4d25128995 100644 --- a/drivers/staging/comedi/drivers/usbduxfast.c +++ b/drivers/staging/comedi/drivers/usbduxfast.c @@ -1442,7 +1442,7 @@ static void usbduxfast_firmware_request_complete_handler(const struct firmware *fw, void *context) { struct usbduxfastsub_s *usbduxfastsub_tmp = context; - struct usb_device *usbdev = usbduxfastsub_tmp->usbdev; + struct usb_interface *uinterf = usbduxfastsub_tmp->interface; int ret; if (fw == NULL) @@ -1455,12 +1455,12 @@ static void usbduxfast_firmware_request_complete_handler(const struct firmware ret = firmwareUpload(usbduxfastsub_tmp, fw->data, fw->size); if (ret) { - dev_err(&usbdev->dev, + dev_err(&uinterf->dev, "Could not upload firmware (err=%d)\n", ret); goto out; } - comedi_usb_auto_config(usbdev, &driver_usbduxfast); + comedi_usb_auto_config(uinterf, &driver_usbduxfast); out: release_firmware(fw); } @@ -1608,7 +1608,7 @@ static void usbduxfastsub_disconnect(struct usb_interface *intf) return; } - comedi_usb_auto_unconfig(udev); + comedi_usb_auto_unconfig(intf); down(&start_stop_sem); down(&udfs->sem); diff --git a/drivers/staging/comedi/drivers/usbduxsigma.c b/drivers/staging/comedi/drivers/usbduxsigma.c index e59d1c093095..f21bb0dd9167 100644 --- a/drivers/staging/comedi/drivers/usbduxsigma.c +++ b/drivers/staging/comedi/drivers/usbduxsigma.c @@ -2314,11 +2314,11 @@ static void usbdux_firmware_request_complete_handler(const struct firmware *fw, void *context) { struct usbduxsub *usbduxsub_tmp = context; - struct usb_device *usbdev = usbduxsub_tmp->usbdev; + struct usb_interface *uinterf = usbduxsub_tmp->interface; int ret; if (fw == NULL) { - dev_err(&usbdev->dev, + dev_err(&uinterf->dev, "Firmware complete handler without firmware!\n"); return; } @@ -2330,11 +2330,11 @@ static void usbdux_firmware_request_complete_handler(const struct firmware *fw, ret = firmwareUpload(usbduxsub_tmp, fw->data, fw->size); if (ret) { - dev_err(&usbdev->dev, + dev_err(&uinterf->dev, "Could not upload firmware (err=%d)\n", ret); goto out; } - comedi_usb_auto_config(usbdev, &driver_usbduxsigma); + comedi_usb_auto_config(uinterf, &driver_usbduxsigma); out: release_firmware(fw); } @@ -2625,7 +2625,7 @@ static void usbduxsigma_disconnect(struct usb_interface *intf) if (usbduxsub_tmp->ao_cmd_running) /* we are still running a command */ usbdux_ao_stop(usbduxsub_tmp, 1); - comedi_usb_auto_unconfig(udev); + comedi_usb_auto_unconfig(intf); down(&start_stop_sem); down(&usbduxsub_tmp->sem); tidy_up(usbduxsub_tmp); diff --git a/drivers/staging/comedi/drivers/vmk80xx.c b/drivers/staging/comedi/drivers/vmk80xx.c index 4bda1e8a007a..10ac58d0cddd 100644 --- a/drivers/staging/comedi/drivers/vmk80xx.c +++ b/drivers/staging/comedi/drivers/vmk80xx.c @@ -1484,7 +1484,7 @@ static int vmk80xx_probe(struct usb_interface *intf, mutex_unlock(&glb_mutex); - comedi_usb_auto_config(dev->udev, &driver_vmk80xx); + comedi_usb_auto_config(intf, &driver_vmk80xx); return 0; error: @@ -1502,7 +1502,7 @@ static void vmk80xx_disconnect(struct usb_interface *intf) if (!dev) return; - comedi_usb_auto_unconfig(dev->udev); + comedi_usb_auto_unconfig(intf); mutex_lock(&glb_mutex); down(&dev->limit_sem); -- cgit v1.2.3-59-g8ed1b From 3902a370281d2f2b130f141e8cf94eab40125769 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Fri, 30 Mar 2012 17:15:00 +0100 Subject: staging: comedi: refactor comedi_device_attach() a bit Split the post-config part of comedi_device_attach() into new function comedi_device_postconfig() and rearrange the rest of the function a bit. The new comedi_device_postconfig() function will be called by some new bus-type-specific auto-attach functions. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers.c | 87 +++++++++++++++++++--------------------- 1 file changed, 42 insertions(+), 45 deletions(-) (limited to 'drivers/staging/comedi/drivers.c') diff --git a/drivers/staging/comedi/drivers.c b/drivers/staging/comedi/drivers.c index feb33f86023b..cfb6fe94f782 100644 --- a/drivers/staging/comedi/drivers.c +++ b/drivers/staging/comedi/drivers.c @@ -106,6 +106,26 @@ void comedi_device_detach(struct comedi_device *dev) __comedi_device_detach(dev); } +/* do a little post-config cleanup */ +/* called with module refcount incremented, decrements it */ +static int comedi_device_postconfig(struct comedi_device *dev) +{ + int ret = postconfig(dev); + module_put(dev->driver->module); + if (ret < 0) { + __comedi_device_detach(dev); + return ret; + } + if (!dev->board_name) { + printk(KERN_WARNING "BUG: dev->board_name=<%p>\n", + dev->board_name); + dev->board_name = "BUG"; + } + smp_wmb(); + dev->attached = 1; + return 0; +} + int comedi_device_attach(struct comedi_device *dev, struct comedi_devconfig *it) { struct comedi_driver *driv; @@ -121,59 +141,36 @@ int comedi_device_attach(struct comedi_device *dev, struct comedi_devconfig *it) } if (driv->num_names) { dev->board_ptr = comedi_recognize(driv, it->board_name); - if (dev->board_ptr == NULL) { - module_put(driv->module); - continue; - } - } else { - if (strcmp(driv->driver_name, it->board_name)) { - module_put(driv->module); + if (dev->board_ptr) + break; + } else if (strcmp(driv->driver_name, it->board_name)) + break; + module_put(driv->module); + } + if (driv == NULL) { + /* recognize has failed if we get here */ + /* report valid board names before returning error */ + for (driv = comedi_drivers; driv; driv = driv->next) { + if (!try_module_get(driv->module)) { + printk(KERN_INFO + "comedi: failed to increment module count\n"); continue; } + comedi_report_boards(driv); + module_put(driv->module); } - /* initialize dev->driver here so - * comedi_error() can be called from attach */ - dev->driver = driv; - ret = driv->attach(dev, it); - if (ret < 0) { - module_put(dev->driver->module); - __comedi_device_detach(dev); - return ret; - } - goto attached; + return -EIO; } - - /* recognize has failed if we get here */ - /* report valid board names before returning error */ - for (driv = comedi_drivers; driv; driv = driv->next) { - if (!try_module_get(driv->module)) { - printk(KERN_INFO - "comedi: failed to increment module count\n"); - continue; - } - comedi_report_boards(driv); - module_put(driv->module); - } - return -EIO; - -attached: - /* do a little post-config cleanup */ - ret = postconfig(dev); - module_put(dev->driver->module); + /* initialize dev->driver here so + * comedi_error() can be called from attach */ + dev->driver = driv; + ret = driv->attach(dev, it); if (ret < 0) { + module_put(dev->driver->module); __comedi_device_detach(dev); return ret; } - - if (!dev->board_name) { - printk(KERN_WARNING "BUG: dev->board_name=<%p>\n", - dev->board_name); - dev->board_name = "BUG"; - } - smp_wmb(); - dev->attached = 1; - - return 0; + return comedi_device_postconfig(dev); } int comedi_driver_register(struct comedi_driver *driver) -- cgit v1.2.3-59-g8ed1b From f4011670023f28cf9081904f8986c0c1be5c9f1e Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Fri, 30 Mar 2012 17:15:01 +0100 Subject: staging: comedi: add bus-type-specific attach hooks for PCI and USB The Comedi auto-configuration mechanism used to bind hardware devices to comedi devices automatically is pretty kludgy. It fakes a "manual" configuration of the comedi device as though the COMEDI_DEVCONFIG ioctl (or the 'comedi_config' utility) were used. In particular, the low-level comedi driver's '->attach()' routine is called with a pointer to the struct comedi_device being attached and a pointer to a 'struct devconfig' containing a device name string and a few integer options to help the attach routine locate the device being attached. In the case of PCI devices, these integer options are the PCI bus and slot numbers. In the case of USB devices, there are no integer options and it relies more on pot luck to attach the correct device. This patch adds a couple of bus-type-specific attach routine hooks to the struct comedi_driver, which a low-level driver can optionally fill in if it supports auto-configuration. A low-level driver that supports auto-configuration of {PCI,USB} devices calls the existing comedi_{pci,usb}_auto_config() when it wishes to auto-configure a freshly probed device (maybe after loading firmware). This will call the new '->attach_{pci,usb}()' hook if the driver has defined it, otherwise it will fall back to calling the '->attach()' hook as before. The '->attach_{pci,usb}()' hook gets a pointer to the struct comedi_device and a pointer to the struct {pci_dev,usb_interface} and can figure out the {PCI,USB} device details for itself. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/comedidev.h | 6 ++- drivers/staging/comedi/drivers.c | 92 +++++++++++++++++++++++++++++++++++++- 2 files changed, 95 insertions(+), 3 deletions(-) (limited to 'drivers/staging/comedi/drivers.c') diff --git a/drivers/staging/comedi/comedidev.h b/drivers/staging/comedi/comedidev.h index e4626b6231d6..300fd8400a4b 100644 --- a/drivers/staging/comedi/comedidev.h +++ b/drivers/staging/comedi/comedidev.h @@ -180,6 +180,9 @@ struct comedi_async { unsigned int x); }; +struct pci_dev; +struct usb_interface; + struct comedi_driver { struct comedi_driver *next; @@ -187,6 +190,8 @@ struct comedi_driver { struct module *module; int (*attach) (struct comedi_device *, struct comedi_devconfig *); int (*detach) (struct comedi_device *); + int (*attach_pci) (struct comedi_device *, struct pci_dev *); + int (*attach_usb) (struct comedi_device *, struct usb_interface *); /* number of elements in board_name and board_id arrays */ unsigned int num_names; @@ -460,7 +465,6 @@ void comedi_free_subdevice_minor(struct comedi_subdevice *s); int comedi_pci_auto_config(struct pci_dev *pcidev, struct comedi_driver *driver); void comedi_pci_auto_unconfig(struct pci_dev *pcidev); -struct usb_interface; /* forward declaration */ int comedi_usb_auto_config(struct usb_interface *intf, struct comedi_driver *driver); void comedi_usb_auto_unconfig(struct usb_interface *intf); diff --git a/drivers/staging/comedi/drivers.c b/drivers/staging/comedi/drivers.c index cfb6fe94f782..69e6fa345d3f 100644 --- a/drivers/staging/comedi/drivers.c +++ b/drivers/staging/comedi/drivers.c @@ -811,6 +811,51 @@ void comedi_reset_async_buf(struct comedi_async *async) async->events = 0; } +static int +comedi_auto_config_helper(struct device *hardware_device, + struct comedi_driver *driver, + int (*attach_wrapper) (struct comedi_device *, + void *), void *context) +{ + int minor; + struct comedi_device_file_info *dev_file_info; + struct comedi_device *comedi_dev; + int ret; + + if (!comedi_autoconfig) + return 0; + + minor = comedi_alloc_board_minor(hardware_device); + if (minor < 0) + return minor; + + dev_file_info = comedi_get_device_file_info(minor); + comedi_dev = dev_file_info->device; + + mutex_lock(&comedi_dev->mutex); + if (comedi_dev->attached) + ret = -EBUSY; + else if (!try_module_get(driver->module)) { + printk(KERN_INFO "comedi: failed to increment module count\n"); + ret = -EIO; + } else { + /* set comedi_dev->driver here for attach wrapper */ + comedi_dev->driver = driver; + ret = (*attach_wrapper)(comedi_dev, context); + if (ret < 0) { + module_put(driver->module); + __comedi_device_detach(comedi_dev); + } else { + ret = comedi_device_postconfig(comedi_dev); + } + } + mutex_unlock(&comedi_dev->mutex); + + if (ret < 0) + comedi_free_board_minor(minor); + return ret; +} + static int comedi_auto_config(struct device *hardware_device, const char *board_name, const int *options, unsigned num_options) @@ -857,7 +902,8 @@ static void comedi_auto_unconfig(struct device *hardware_device) comedi_free_board_minor(minor); } -int comedi_pci_auto_config(struct pci_dev *pcidev, struct comedi_driver *driver) +static int comedi_old_pci_auto_config(struct pci_dev *pcidev, + struct comedi_driver *driver) { int options[2]; @@ -869,6 +915,27 @@ int comedi_pci_auto_config(struct pci_dev *pcidev, struct comedi_driver *driver) return comedi_auto_config(&pcidev->dev, driver->driver_name, options, ARRAY_SIZE(options)); } + +static int comedi_pci_attach_wrapper(struct comedi_device *dev, void *pcidev) +{ + return dev->driver->attach_pci(dev, pcidev); +} + +static int comedi_new_pci_auto_config(struct pci_dev *pcidev, + struct comedi_driver *driver) +{ + return comedi_auto_config_helper(&pcidev->dev, driver, + comedi_pci_attach_wrapper, pcidev); +} + +int comedi_pci_auto_config(struct pci_dev *pcidev, struct comedi_driver *driver) +{ + + if (driver->attach_pci) + return comedi_new_pci_auto_config(pcidev, driver); + else + return comedi_old_pci_auto_config(pcidev, driver); +} EXPORT_SYMBOL_GPL(comedi_pci_auto_config); void comedi_pci_auto_unconfig(struct pci_dev *pcidev) @@ -877,11 +944,32 @@ void comedi_pci_auto_unconfig(struct pci_dev *pcidev) } EXPORT_SYMBOL_GPL(comedi_pci_auto_unconfig); +static int comedi_old_usb_auto_config(struct usb_interface *intf, + struct comedi_driver *driver) +{ + return comedi_auto_config(&intf->dev, driver->driver_name, NULL, 0); +} + +static int comedi_usb_attach_wrapper(struct comedi_device *dev, void *intf) +{ + return dev->driver->attach_usb(dev, intf); +} + +static int comedi_new_usb_auto_config(struct usb_interface *intf, + struct comedi_driver *driver) +{ + return comedi_auto_config_helper(&intf->dev, driver, + comedi_usb_attach_wrapper, intf); +} + int comedi_usb_auto_config(struct usb_interface *intf, struct comedi_driver *driver) { BUG_ON(intf == NULL); - return comedi_auto_config(&intf->dev, driver->driver_name, NULL, 0); + if (driver->attach_usb) + return comedi_new_usb_auto_config(intf, driver); + else + return comedi_old_usb_auto_config(intf, driver); } EXPORT_SYMBOL_GPL(comedi_usb_auto_config); -- cgit v1.2.3-59-g8ed1b From 63bf3d11df34426caa81e5478b2ff0e99875e972 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Fri, 30 Mar 2012 17:15:02 +0100 Subject: staging: comedi: pass struct comedi_driver * to comedi_auto_config() Pass a pointer to the struct comedi_driver to comedi_auto_config() instead of the driver name. comedi_auto_config() will be changed to make use of this. It currently calls comedi_device_attach() which examines the whole list of struct comedi_driver objects. It will be changed to restrict itself to just the supplied struct comedi_driver object. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers/staging/comedi/drivers.c') diff --git a/drivers/staging/comedi/drivers.c b/drivers/staging/comedi/drivers.c index 69e6fa345d3f..aec9c35428cc 100644 --- a/drivers/staging/comedi/drivers.c +++ b/drivers/staging/comedi/drivers.c @@ -857,7 +857,7 @@ comedi_auto_config_helper(struct device *hardware_device, } static int comedi_auto_config(struct device *hardware_device, - const char *board_name, const int *options, + struct comedi_driver *driver, const int *options, unsigned num_options) { struct comedi_devconfig it; @@ -875,7 +875,7 @@ static int comedi_auto_config(struct device *hardware_device, dev_file_info = comedi_get_device_file_info(minor); memset(&it, 0, sizeof(it)); - strncpy(it.board_name, board_name, COMEDI_NAMELEN); + strncpy(it.board_name, driver->driver_name, COMEDI_NAMELEN); it.board_name[COMEDI_NAMELEN - 1] = '\0'; BUG_ON(num_options > COMEDI_NDEVCONFOPTS); memcpy(it.options, options, num_options * sizeof(int)); @@ -912,7 +912,7 @@ static int comedi_old_pci_auto_config(struct pci_dev *pcidev, /* pci slot */ options[1] = PCI_SLOT(pcidev->devfn); - return comedi_auto_config(&pcidev->dev, driver->driver_name, + return comedi_auto_config(&pcidev->dev, driver, options, ARRAY_SIZE(options)); } @@ -947,7 +947,7 @@ EXPORT_SYMBOL_GPL(comedi_pci_auto_unconfig); static int comedi_old_usb_auto_config(struct usb_interface *intf, struct comedi_driver *driver) { - return comedi_auto_config(&intf->dev, driver->driver_name, NULL, 0); + return comedi_auto_config(&intf->dev, driver, NULL, 0); } static int comedi_usb_attach_wrapper(struct comedi_device *dev, void *intf) -- cgit v1.2.3-59-g8ed1b From cf938c247307826e70f93dd9072c70d3020d6d67 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Fri, 30 Mar 2012 17:15:03 +0100 Subject: staging: comedi: restrict comedi_auto_config() to single driver comedi_auto_config() only needs to consider a single struct comedi_driver object, but it currently calls comedi_device_attach() which looks at all struct comedi_driver objects registered with the Comedi core. Instead, call the recently added comedi_auto_config_helper() with a new wrapper comedi_auto_config_wrapper() to mimic the effect of comedi_device_attach() for a single struct comedi_driver. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers.c | 43 +++++++++++++++++++++------------------- 1 file changed, 23 insertions(+), 20 deletions(-) (limited to 'drivers/staging/comedi/drivers.c') diff --git a/drivers/staging/comedi/drivers.c b/drivers/staging/comedi/drivers.c index aec9c35428cc..872b598b7939 100644 --- a/drivers/staging/comedi/drivers.c +++ b/drivers/staging/comedi/drivers.c @@ -856,37 +856,40 @@ comedi_auto_config_helper(struct device *hardware_device, return ret; } +static int comedi_auto_config_wrapper(struct comedi_device *dev, void *context) +{ + struct comedi_devconfig *it = context; + struct comedi_driver *driv = dev->driver; + + if (driv->num_names) { + /* look for generic board entry matching driver name, which + * has already been copied to it->board_name */ + dev->board_ptr = comedi_recognize(driv, it->board_name); + if (dev->board_ptr == NULL) { + printk(KERN_WARNING + "comedi: auto config failed to find board entry" + " '%s' for driver '%s'\n", it->board_name, + driv->driver_name); + comedi_report_boards(driv); + return -EINVAL; + } + } + return driv->attach(dev, it); +} + static int comedi_auto_config(struct device *hardware_device, struct comedi_driver *driver, const int *options, unsigned num_options) { struct comedi_devconfig it; - int minor; - struct comedi_device_file_info *dev_file_info; - int retval; - - if (!comedi_autoconfig) - return 0; - - minor = comedi_alloc_board_minor(hardware_device); - if (minor < 0) - return minor; - - dev_file_info = comedi_get_device_file_info(minor); memset(&it, 0, sizeof(it)); strncpy(it.board_name, driver->driver_name, COMEDI_NAMELEN); it.board_name[COMEDI_NAMELEN - 1] = '\0'; BUG_ON(num_options > COMEDI_NDEVCONFOPTS); memcpy(it.options, options, num_options * sizeof(int)); - - mutex_lock(&dev_file_info->device->mutex); - retval = comedi_device_attach(dev_file_info->device, &it); - mutex_unlock(&dev_file_info->device->mutex); - - if (retval < 0) - comedi_free_board_minor(minor); - return retval; + return comedi_auto_config_helper(hardware_device, driver, + comedi_auto_config_wrapper, &it); } static void comedi_auto_unconfig(struct device *hardware_device) -- cgit v1.2.3-59-g8ed1b From 4d7df821277e82ebe2fc9c9af07c928a83f572b8 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Fri, 13 Apr 2012 14:12:53 +0100 Subject: staging: comedi: Add module parameters for default buffer size For comedi subdevices that support asynchronous transfer commands, the initial buffer size and maximum buffer size for the transfer are both set to 64 KiB when the comedi device is "attached" to the hardware device. For many applications with reasonable fast sample rates and slow user-space (e.g. Python) these sizes are a bit too small. A task with CAP_SYS_ADMIN privileges can change the maximum buffer size for a comedi subdevice with an ioctl call or by writing to a device attribute file in sysfs, but that's not very convenient. For comedi devices attached during system startup, this could be done by a start-up script, but for hot-plugged devices it would require scripts run by udev rules, etc. Rather than use hardwired values, this patch introduces a couple of module parameters to set the defaults for the initial buffer size (comedi_default_buf_size_kb) and maximum buffer size (comedi_default_buf_maxsize_kb). These values are applied in place of the previous hard-wired values when the comedi device is "attached". The module parameter values are in units of KiB for consistency with the existing device attribute files. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/comedi_fops.c | 29 ++++++++++++++++++++++++++--- drivers/staging/comedi/drivers.c | 15 +++++++++------ drivers/staging/comedi/internal.h | 5 ++++- 3 files changed, 39 insertions(+), 10 deletions(-) (limited to 'drivers/staging/comedi/drivers.c') diff --git a/drivers/staging/comedi/comedi_fops.c b/drivers/staging/comedi/comedi_fops.c index fdf42822b962..ef7bbe416614 100644 --- a/drivers/staging/comedi/comedi_fops.c +++ b/drivers/staging/comedi/comedi_fops.c @@ -55,17 +55,40 @@ MODULE_AUTHOR("http://www.comedi.org"); MODULE_DESCRIPTION("Comedi core module"); MODULE_LICENSE("GPL"); +#define DEFAULT_BUF_MAXSIZE_KB 64 +#define DEFAULT_BUF_SIZE_KB 64 + #ifdef CONFIG_COMEDI_DEBUG int comedi_debug; EXPORT_SYMBOL(comedi_debug); -module_param(comedi_debug, int, 0644); +module_param(comedi_debug, int, S_IRUGO | S_IWUSR); +MODULE_PARM_DESC(comedi_debug, + "enable comedi core and driver debugging if non-zero (default 0)" + ); #endif bool comedi_autoconfig = 1; -module_param(comedi_autoconfig, bool, 0444); +module_param(comedi_autoconfig, bool, S_IRUGO); +MODULE_PARM_DESC(comedi_autoconfig, + "enable drivers to auto-configure comedi devices (default 1)"); static int comedi_num_legacy_minors; -module_param(comedi_num_legacy_minors, int, 0444); +module_param(comedi_num_legacy_minors, int, S_IRUGO); +MODULE_PARM_DESC(comedi_num_legacy_minors, + "number of comedi minor devices to reserve for non-auto-configured devices (default 0)" + ); + +unsigned int comedi_default_buf_size_kb = DEFAULT_BUF_SIZE_KB; +module_param(comedi_default_buf_size_kb, uint, S_IRUGO | S_IWUSR); +MODULE_PARM_DESC(comedi_default_buf_size_kb, + "default asynchronous buffer size in KiB (default " + __MODULE_STRING(DEFAULT_BUF_SIZE_KB) ")"); + +unsigned int comedi_default_buf_maxsize_kb = DEFAULT_BUF_MAXSIZE_KB; +module_param(comedi_default_buf_maxsize_kb, uint, S_IRUGO | S_IWUSR); +MODULE_PARM_DESC(comedi_default_buf_maxsize_kb, + "default maximum size of asynchronous buffer in KiB (default " + __MODULE_STRING(DEFAULT_BUF_MAXSIZE_KB) ")"); static DEFINE_SPINLOCK(comedi_file_info_table_lock); static struct comedi_device_file_info diff --git a/drivers/staging/comedi/drivers.c b/drivers/staging/comedi/drivers.c index 872b598b7939..49681a1a6fa6 100644 --- a/drivers/staging/comedi/drivers.c +++ b/drivers/staging/comedi/drivers.c @@ -239,6 +239,8 @@ static int postconfig(struct comedi_device *dev) s->len_chanlist = 1; if (s->do_cmd) { + unsigned int buf_size; + BUG_ON((s->subdev_flags & (SDF_CMD_READ | SDF_CMD_WRITE)) == 0); BUG_ON(!s->do_cmdtest); @@ -254,19 +256,20 @@ static int postconfig(struct comedi_device *dev) async->subdevice = s; s->async = async; -#define DEFAULT_BUF_MAXSIZE (64*1024) -#define DEFAULT_BUF_SIZE (64*1024) - - async->max_bufsize = DEFAULT_BUF_MAXSIZE; + async->max_bufsize = + comedi_default_buf_maxsize_kb * 1024; + buf_size = comedi_default_buf_size_kb * 1024; + if (buf_size > async->max_bufsize) + buf_size = async->max_bufsize; async->prealloc_buf = NULL; async->prealloc_bufsz = 0; - if (comedi_buf_alloc(dev, s, DEFAULT_BUF_SIZE) < 0) { + if (comedi_buf_alloc(dev, s, buf_size) < 0) { printk(KERN_INFO "Buffer allocation failed\n"); return -ENOMEM; } if (s->buf_change) { - ret = s->buf_change(dev, s, DEFAULT_BUF_SIZE); + ret = s->buf_change(dev, s, buf_size); if (ret < 0) return ret; } diff --git a/drivers/staging/comedi/internal.h b/drivers/staging/comedi/internal.h index 4208fb4cf0ff..7ed20a04eef5 100644 --- a/drivers/staging/comedi/internal.h +++ b/drivers/staging/comedi/internal.h @@ -1,5 +1,5 @@ /* - * various internal comedi functions + * various internal comedi stuff */ int do_rangeinfo_ioctl(struct comedi_device *dev, struct comedi_rangeinfo __user *arg); @@ -11,3 +11,6 @@ int comedi_find_board_minor(struct device *hardware_device); void comedi_reset_async_buf(struct comedi_async *async); int comedi_buf_alloc(struct comedi_device *dev, struct comedi_subdevice *s, unsigned long new_size); + +extern unsigned int comedi_default_buf_size_kb; +extern unsigned int comedi_default_buf_maxsize_kb; -- cgit v1.2.3-59-g8ed1b From d4899c6ff86ea9836c89250cb2127aa64765b35a Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 11 May 2012 16:15:39 -0700 Subject: staging: comedi: Add helper macro for comedi pci driver boilerplate Introduce the module_comedi_pci_driver macro, and the associated register/unregister functions, which is a convenience macro for comedi pci driver modules similar to module_platform_driver. It is intended to be used by drivers where the init/exit section does nothing but register/unregister the comedi driver and associated pci driver. By using this macro it is possible to eliminate a few lines of boilerplate code per comedi pci driver. Add a check to make sure that the pci_driver->name is set. Once all the comedi pci drivers have been fixed this will be removed. Also, when registering the pci driver check for failure and unregister the comedi driver. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/comedidev.h | 19 +++++++++++++++++++ drivers/staging/comedi/drivers.c | 31 +++++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+) (limited to 'drivers/staging/comedi/drivers.c') diff --git a/drivers/staging/comedi/comedidev.h b/drivers/staging/comedi/comedidev.h index 8828609f1ed6..92a119960a2c 100644 --- a/drivers/staging/comedi/comedidev.h +++ b/drivers/staging/comedi/comedidev.h @@ -310,6 +310,25 @@ int comedi_driver_unregister(struct comedi_driver *); module_driver(__comedi_driver, comedi_driver_register, \ comedi_driver_unregister) +struct pci_driver; + +int comedi_pci_driver_register(struct comedi_driver *, struct pci_driver *); +void comedi_pci_driver_unregister(struct comedi_driver *, struct pci_driver *); + +/** + * module_comedi_pci_driver() - Helper macro for registering a comedi PCI driver + * @__comedi_driver: comedi_driver struct + * @__pci_driver: pci_driver struct + * + * Helper macro for comedi PCI drivers which do not do anything special + * in module init/exit. This eliminates a lot of boilerplate. Each + * module may only use this macro once, and calling it replaces + * module_init() and module_exit() + */ +#define module_comedi_pci_driver(__comedi_driver, __pci_driver) \ + module_driver(__comedi_driver, comedi_pci_driver_register, \ + comedi_pci_driver_unregister, &(__pci_driver)) + void init_polling(void); void cleanup_polling(void); void start_polling(struct comedi_device *); diff --git a/drivers/staging/comedi/drivers.c b/drivers/staging/comedi/drivers.c index 49681a1a6fa6..3a8295080961 100644 --- a/drivers/staging/comedi/drivers.c +++ b/drivers/staging/comedi/drivers.c @@ -950,6 +950,37 @@ void comedi_pci_auto_unconfig(struct pci_dev *pcidev) } EXPORT_SYMBOL_GPL(comedi_pci_auto_unconfig); +int comedi_pci_driver_register(struct comedi_driver *comedi_driver, + struct pci_driver *pci_driver) +{ + int ret; + + ret = comedi_driver_register(comedi_driver); + if (ret < 0) + return ret; + + /* FIXME: Remove this test after auditing all comedi pci drivers */ + if (!pci_driver->name) + pci_driver->name = comedi_driver->driver_name; + + ret = pci_register_driver(pci_driver); + if (ret < 0) { + comedi_driver_unregister(comedi_driver); + return ret; + } + + return 0; +} +EXPORT_SYMBOL_GPL(comedi_pci_driver_register); + +void comedi_pci_driver_unregister(struct comedi_driver *comedi_driver, + struct pci_driver *pci_driver) +{ + pci_unregister_driver(pci_driver); + comedi_driver_unregister(comedi_driver); +} +EXPORT_SYMBOL_GPL(comedi_pci_driver_unregister); + static int comedi_old_usb_auto_config(struct usb_interface *intf, struct comedi_driver *driver) { -- cgit v1.2.3-59-g8ed1b From 64255031bde68bd0f7ec934b83842619d513cf91 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 16 May 2012 18:18:52 -0700 Subject: staging: comedi: Add helper macro for comedi usb driver boilerplate Introduce the module_comedi_usb_driver macro, and the associated register/unregister functions, which is a convenience macro for comedi usb driver modules similar to module_platform_driver. It is intended to be used by drivers where the init/exit section does nothing but register/unregister the comedi driver and associated usb driver. By using this macro it is possible to eliminate a few lines of boilerplate code per comedi usb driver. Also, when registering the usb driver check for failure and unregister the comedi driver. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/comedidev.h | 19 +++++++++++++++++++ drivers/staging/comedi/drivers.c | 27 +++++++++++++++++++++++++++ 2 files changed, 46 insertions(+) (limited to 'drivers/staging/comedi/drivers.c') diff --git a/drivers/staging/comedi/comedidev.h b/drivers/staging/comedi/comedidev.h index 92a119960a2c..f7f023cb95c1 100644 --- a/drivers/staging/comedi/comedidev.h +++ b/drivers/staging/comedi/comedidev.h @@ -329,6 +329,25 @@ void comedi_pci_driver_unregister(struct comedi_driver *, struct pci_driver *); module_driver(__comedi_driver, comedi_pci_driver_register, \ comedi_pci_driver_unregister, &(__pci_driver)) +struct usb_driver; + +int comedi_usb_driver_register(struct comedi_driver *, struct usb_driver *); +void comedi_usb_driver_unregister(struct comedi_driver *, struct usb_driver *); + +/** + * module_comedi_usb_driver() - Helper macro for registering a comedi USB driver + * @__comedi_driver: comedi_driver struct + * @__usb_driver: usb_driver struct + * + * Helper macro for comedi USB drivers which do not do anything special + * in module init/exit. This eliminates a lot of boilerplate. Each + * module may only use this macro once, and calling it replaces + * module_init() and module_exit() + */ +#define module_comedi_usb_driver(__comedi_driver, __usb_driver) \ + module_driver(__comedi_driver, comedi_usb_driver_register, \ + comedi_usb_driver_unregister, &(__usb_driver)) + void init_polling(void); void cleanup_polling(void); void start_polling(struct comedi_device *); diff --git a/drivers/staging/comedi/drivers.c b/drivers/staging/comedi/drivers.c index 3a8295080961..1c3d6386ea36 100644 --- a/drivers/staging/comedi/drivers.c +++ b/drivers/staging/comedi/drivers.c @@ -1016,3 +1016,30 @@ void comedi_usb_auto_unconfig(struct usb_interface *intf) comedi_auto_unconfig(&intf->dev); } EXPORT_SYMBOL_GPL(comedi_usb_auto_unconfig); + +int comedi_usb_driver_register(struct comedi_driver *comedi_driver, + struct usb_driver *usb_driver) +{ + int ret; + + ret = comedi_driver_register(comedi_driver); + if (ret < 0) + return ret; + + ret = usb_register(usb_driver); + if (ret < 0) { + comedi_driver_unregister(comedi_driver); + return ret; + } + + return 0; +} +EXPORT_SYMBOL_GPL(comedi_usb_driver_register); + +void comedi_usb_driver_unregister(struct comedi_driver *comedi_driver, + struct usb_driver *usb_driver) +{ + usb_deregister(usb_driver); + comedi_driver_unregister(comedi_driver); +} +EXPORT_SYMBOL_GPL(comedi_usb_driver_unregister); -- cgit v1.2.3-59-g8ed1b From 78b10615ad295393a7d66ea57218171c0a07c059 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Mon, 11 Jun 2012 16:35:50 -0700 Subject: staging/comedi: fix build for USB not enabled Calls to optional subsystems cannot be made indiscriminately. Enclose all of the usb helper functions inside #if IS_ENABLED(CONFIG_USB) to fix these build errors. (The pci helper functions are OK since there are stubs in linux/pci.h for the called functions when PCI is not enabled. Possibly the same could be done for the called USB functions.) ERROR: "usb_deregister" [drivers/staging/comedi/comedi.ko] undefined! ERROR: "usb_register_driver" [drivers/staging/comedi/comedi.ko] undefined! Signed-off-by: Randy Dunlap Cc: Ian Abbott Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers/staging/comedi/drivers.c') diff --git a/drivers/staging/comedi/drivers.c b/drivers/staging/comedi/drivers.c index 1c3d6386ea36..aeac1caba3f9 100644 --- a/drivers/staging/comedi/drivers.c +++ b/drivers/staging/comedi/drivers.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include @@ -981,6 +982,8 @@ void comedi_pci_driver_unregister(struct comedi_driver *comedi_driver, } EXPORT_SYMBOL_GPL(comedi_pci_driver_unregister); +#if IS_ENABLED(CONFIG_USB) + static int comedi_old_usb_auto_config(struct usb_interface *intf, struct comedi_driver *driver) { @@ -1043,3 +1046,5 @@ void comedi_usb_driver_unregister(struct comedi_driver *comedi_driver, comedi_driver_unregister(comedi_driver); } EXPORT_SYMBOL_GPL(comedi_usb_driver_unregister); + +#endif -- cgit v1.2.3-59-g8ed1b