summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorH Hartley Sweeten <hsweeten@visionengravers.com>2013-02-05 17:24:03 -0700
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2013-02-05 18:07:11 -0800
commit57cf09aeeeadf35ef7f678a870139894d67a794f (patch)
treec39c0e974b7b61b7e6fbf4540864011f132a755e
parent55ab4f641a3bfbdb7c59b80e194c7242234bbb1f (diff)
staging: comedi: vmk80xx: push usb (*probe) into comedi (*auto_attach)
Make the usb_driver (*probe) simply call comedi_usb_auto_config() and move all the (*probe) code into the (*auto_attach) function. This allows getting rid of the static private data array since we no longer do part of the initialization in the (*probe) and then finish it in the (*auto_attach). We can simply kzalloc the private data instead. The comedi core will then handle the kfree of the data when the driver is detached. We can also get rid of the static 'glb_mutex' since this mutex was only used to protect the static private data array. Change the parameters for a couple of the helper functions used during the auto attach. Now that the comedi_device is available we can simply pass that pointer and get the specific pointers needed by the helper functions from it. Signed-off-by: H Hartley Sweeten <hsweeten@visionengravers.com> Cc: Ian Abbott <abbotti@mev.co.uk> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--drivers/staging/comedi/drivers/vmk80xx.c163
1 files changed, 55 insertions, 108 deletions
diff --git a/drivers/staging/comedi/drivers/vmk80xx.c b/drivers/staging/comedi/drivers/vmk80xx.c
index c20202c5cb77..6ed70eef149c 100644
--- a/drivers/staging/comedi/drivers/vmk80xx.c
+++ b/drivers/staging/comedi/drivers/vmk80xx.c
@@ -212,10 +212,6 @@ struct vmk80xx_private {
unsigned long flags;
};
-static struct vmk80xx_private vmb[VMK80XX_MAX_BOARDS];
-
-static DEFINE_MUTEX(glb_mutex);
-
static void vmk80xx_tx_callback(struct urb *urb)
{
struct vmk80xx_private *devpriv = urb->context;
@@ -1131,9 +1127,10 @@ static int vmk80xx_pwm_winsn(struct comedi_device *dev,
return n;
}
-static int vmk80xx_find_usb_endpoints(struct vmk80xx_private *devpriv,
- struct usb_interface *intf)
+static int vmk80xx_find_usb_endpoints(struct comedi_device *dev)
{
+ struct vmk80xx_private *devpriv = dev->private;
+ struct usb_interface *intf = devpriv->intf;
struct usb_host_interface *iface_desc = intf->cur_altsetting;
struct usb_endpoint_descriptor *ep_desc;
int i;
@@ -1165,8 +1162,9 @@ static int vmk80xx_find_usb_endpoints(struct vmk80xx_private *devpriv,
return 0;
}
-static int vmk80xx_alloc_usb_buffers(struct vmk80xx_private *devpriv)
+static int vmk80xx_alloc_usb_buffers(struct comedi_device *dev)
{
+ struct vmk80xx_private *devpriv = dev->private;
size_t size;
size = le16_to_cpu(devpriv->ep_rx->wMaxPacketSize);
@@ -1184,21 +1182,16 @@ static int vmk80xx_alloc_usb_buffers(struct vmk80xx_private *devpriv)
return 0;
}
-static int vmk80xx_attach_common(struct comedi_device *dev,
- struct vmk80xx_private *devpriv)
+static int vmk80xx_attach_common(struct comedi_device *dev)
{
- const struct vmk80xx_board *boardinfo;
- int n_subd;
+ const struct vmk80xx_board *boardinfo = comedi_board(dev);
+ struct vmk80xx_private *devpriv = dev->private;
struct comedi_subdevice *s;
+ int n_subd;
int ret;
down(&devpriv->limit_sem);
- boardinfo = devpriv->board;
- dev->board_ptr = boardinfo;
- dev->board_name = boardinfo->name;
- dev->private = devpriv;
-
if (boardinfo->model == VMK8055_MODEL)
n_subd = 5;
else
@@ -1283,94 +1276,33 @@ static int vmk80xx_attach_common(struct comedi_device *dev,
}
static int vmk80xx_auto_attach(struct comedi_device *dev,
- unsigned long context_unused)
+ unsigned long context)
{
struct usb_interface *intf = comedi_to_usb_interface(dev);
- int i;
- int ret;
-
- mutex_lock(&glb_mutex);
- for (i = 0; i < VMK80XX_MAX_BOARDS; i++)
- if (vmb[i].intf == intf)
- break;
- if (i == VMK80XX_MAX_BOARDS)
- ret = -ENODEV;
- else
- ret = vmk80xx_attach_common(dev, &vmb[i]);
- mutex_unlock(&glb_mutex);
- return ret;
-}
-
-static void vmk80xx_detach(struct comedi_device *dev)
-{
- struct vmk80xx_private *devpriv = dev->private;
-
- if (!devpriv)
- return;
-
- mutex_lock(&glb_mutex);
- down(&devpriv->limit_sem);
-
- dev->private = NULL;
-
- usb_set_intfdata(devpriv->intf, NULL);
-
- usb_kill_anchored_urbs(&devpriv->rx_anchor);
- usb_kill_anchored_urbs(&devpriv->tx_anchor);
-
- kfree(devpriv->usb_rx_buf);
- kfree(devpriv->usb_tx_buf);
-
- up(&devpriv->limit_sem);
-
- /*
- * Since 'devpriv' points to an element of the static vmb array
- * we can't kfree it. Instead memset it to all '0' so subsequent
- * usb probes don't find any garbage in it.
- */
- memset(devpriv, 0x00, sizeof(*devpriv));
-
- mutex_unlock(&glb_mutex);
-}
-
-static struct comedi_driver vmk80xx_driver = {
- .module = THIS_MODULE,
- .driver_name = "vmk80xx",
- .auto_attach = vmk80xx_auto_attach,
- .detach = vmk80xx_detach,
-};
-
-static int vmk80xx_usb_probe(struct usb_interface *intf,
- const struct usb_device_id *id)
-{
const struct vmk80xx_board *boardinfo;
struct vmk80xx_private *devpriv;
int ret;
- int i;
-
- mutex_lock(&glb_mutex);
- for (i = 0; i < VMK80XX_MAX_BOARDS; i++)
- if (!vmb[i].intf)
- break;
+ boardinfo = &vmk80xx_boardinfo[context];
+ dev->board_ptr = boardinfo;
+ dev->board_name = boardinfo->name;
- if (i == VMK80XX_MAX_BOARDS) {
- ret = -EMFILE;
- goto fail;
- }
+ devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
+ if (!devpriv)
+ return -ENOMEM;
+ dev->private = devpriv;
- devpriv = &vmb[i];
+ devpriv->usb = interface_to_usbdev(intf);
+ devpriv->intf = intf;
+ devpriv->board = boardinfo;
- ret = vmk80xx_find_usb_endpoints(devpriv, intf);
+ ret = vmk80xx_find_usb_endpoints(dev);
if (ret)
- goto error;
+ return ret;
- ret = vmk80xx_alloc_usb_buffers(devpriv);
+ ret = vmk80xx_alloc_usb_buffers(dev);
if (ret)
- goto error;
-
- devpriv->usb = interface_to_usbdev(intf);
- devpriv->intf = intf;
+ return ret;
sema_init(&devpriv->limit_sem, 8);
init_waitqueue_head(&devpriv->read_wait);
@@ -1381,9 +1313,6 @@ static int vmk80xx_usb_probe(struct usb_interface *intf,
usb_set_intfdata(intf, devpriv);
- boardinfo = &vmk80xx_boardinfo[id->driver_info];
- devpriv->board = boardinfo;
-
if (boardinfo->model == VMK8061_MODEL) {
vmk80xx_read_eeprom(devpriv, IC3_VERSION);
dev_info(&intf->dev, "%s\n", devpriv->fw.ic3_vers);
@@ -1399,22 +1328,40 @@ static int vmk80xx_usb_probe(struct usb_interface *intf,
if (boardinfo->model == VMK8055_MODEL)
vmk80xx_reset_device(devpriv);
- mutex_unlock(&glb_mutex);
+ return vmk80xx_attach_common(dev);
+}
- comedi_usb_auto_config(intf, &vmk80xx_driver, id->driver_info);
+static void vmk80xx_detach(struct comedi_device *dev)
+{
+ struct vmk80xx_private *devpriv = dev->private;
- return 0;
+ if (!devpriv)
+ return;
-error:
- /*
- * Since 'devpriv' points to an element of the static vmb array
- * we can't kfree it. Instead memset it to all '0' so subsequent
- * usb probes don't find any garbage in it.
- */
- memset(devpriv, 0x00, sizeof(*devpriv));
-fail:
- mutex_unlock(&glb_mutex);
- return ret;
+ down(&devpriv->limit_sem);
+
+ usb_set_intfdata(devpriv->intf, NULL);
+
+ usb_kill_anchored_urbs(&devpriv->rx_anchor);
+ usb_kill_anchored_urbs(&devpriv->tx_anchor);
+
+ kfree(devpriv->usb_rx_buf);
+ kfree(devpriv->usb_tx_buf);
+
+ up(&devpriv->limit_sem);
+}
+
+static struct comedi_driver vmk80xx_driver = {
+ .module = THIS_MODULE,
+ .driver_name = "vmk80xx",
+ .auto_attach = vmk80xx_auto_attach,
+ .detach = vmk80xx_detach,
+};
+
+static int vmk80xx_usb_probe(struct usb_interface *intf,
+ const struct usb_device_id *id)
+{
+ return comedi_usb_auto_config(intf, &vmk80xx_driver, id->driver_info);
}
static const struct usb_device_id vmk80xx_usb_id_table[] = {