Commit db7dabf7 authored by H Hartley Sweeten's avatar H Hartley Sweeten Committed by Greg Kroah-Hartman

staging: comedi: vmk80xx: make sure private data is clean when detached

Currently the private data used in this driver is stored in a static
array. During the usb (*probe) and empty location is found in this
array for use by the usb device. Some initialization of the private
data is then done before comedi_usb_auto_config() is called to allow
the comedi core to attach its comedi_device to the usb device.

The (*probe) can fail for various reasons. If it does, make sure that
the private data is clean before returning an error.

The usb (*disconnect) simply calls comedi_usb_auto_unconfig() to
allow the comedi core to disconnect its comedi_device from the usb
device. Since the private data points to the static array it cannot
be kfree'ed during the detach. Instead make sure it clean before
leaving the detach.
Signed-off-by: default avatarH Hartley Sweeten <hsweeten@visionengravers.com>
Cc: Ian Abbott <abbotti@mev.co.uk>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 1cc8f885
...@@ -1323,8 +1323,6 @@ static void vmk80xx_detach(struct comedi_device *dev) ...@@ -1323,8 +1323,6 @@ static void vmk80xx_detach(struct comedi_device *dev)
dev->private = NULL; dev->private = NULL;
devpriv->attached = 0;
devpriv->probed = 0;
usb_set_intfdata(devpriv->intf, NULL); usb_set_intfdata(devpriv->intf, NULL);
usb_kill_anchored_urbs(&devpriv->rx_anchor); usb_kill_anchored_urbs(&devpriv->rx_anchor);
...@@ -1334,6 +1332,14 @@ static void vmk80xx_detach(struct comedi_device *dev) ...@@ -1334,6 +1332,14 @@ static void vmk80xx_detach(struct comedi_device *dev)
kfree(devpriv->usb_tx_buf); kfree(devpriv->usb_tx_buf);
up(&devpriv->limit_sem); 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); mutex_unlock(&glb_mutex);
} }
...@@ -1359,25 +1365,19 @@ static int vmk80xx_usb_probe(struct usb_interface *intf, ...@@ -1359,25 +1365,19 @@ static int vmk80xx_usb_probe(struct usb_interface *intf,
break; break;
if (i == VMK80XX_MAX_BOARDS) { if (i == VMK80XX_MAX_BOARDS) {
mutex_unlock(&glb_mutex); ret = -EMFILE;
return -EMFILE; goto fail;
} }
devpriv = &vmb[i]; devpriv = &vmb[i];
memset(devpriv, 0x00, sizeof(*devpriv));
ret = vmk80xx_find_usb_endpoints(devpriv, intf); ret = vmk80xx_find_usb_endpoints(devpriv, intf);
if (ret) { if (ret)
mutex_unlock(&glb_mutex); goto error;
return ret;
}
ret = vmk80xx_alloc_usb_buffers(devpriv); ret = vmk80xx_alloc_usb_buffers(devpriv);
if (ret) { if (ret)
mutex_unlock(&glb_mutex); goto error;
return ret;
}
devpriv->usb = interface_to_usbdev(intf); devpriv->usb = interface_to_usbdev(intf);
devpriv->intf = intf; devpriv->intf = intf;
...@@ -1416,6 +1416,17 @@ static int vmk80xx_usb_probe(struct usb_interface *intf, ...@@ -1416,6 +1416,17 @@ static int vmk80xx_usb_probe(struct usb_interface *intf,
comedi_usb_auto_config(intf, &vmk80xx_driver); comedi_usb_auto_config(intf, &vmk80xx_driver);
return 0; return 0;
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;
} }
static const struct usb_device_id vmk80xx_usb_id_table[] = { static const struct usb_device_id vmk80xx_usb_id_table[] = {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment