summaryrefslogtreecommitdiffstats
path: root/drivers/usb/misc
diff options
context:
space:
mode:
authorOliver Neukum <oliver@neukum.org>2010-01-14 16:10:38 +0100
committerGreg Kroah-Hartman <gregkh@suse.de>2010-03-02 14:54:28 -0800
commit511e2d0218d04f544065eb277ad475bf14881efe (patch)
tree135ecfb228ba1941c4b12a10b06a1721b8995d6f /drivers/usb/misc
parent5a207b431174ecc8f995230d19c79242160b8888 (diff)
downloadlinux-511e2d0218d04f544065eb277ad475bf14881efe.tar.bz2
USB: BKL removal: rio500
This driver had used BKL to guard against disconnect but was incorrectly converted leaving an SMP race. BKL was added to disconnect() to fix this race BKL was removed from ioctl() as the mutex is sufficient on its own. Signed-off-by: Oliver Neukum <oliver@neukum.org> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb/misc')
-rw-r--r--drivers/usb/misc/rio500.c8
1 files changed, 6 insertions, 2 deletions
diff --git a/drivers/usb/misc/rio500.c b/drivers/usb/misc/rio500.c
index 47ce46bb5b01..a85771b1563d 100644
--- a/drivers/usb/misc/rio500.c
+++ b/drivers/usb/misc/rio500.c
@@ -77,11 +77,14 @@ static struct rio_usb_data rio_instance;
static int open_rio(struct inode *inode, struct file *file)
{
struct rio_usb_data *rio = &rio_instance;
+
+ /* against disconnect() */
lock_kernel();
mutex_lock(&(rio->lock));
if (rio->isopen || !rio->present) {
mutex_unlock(&(rio->lock));
+ unlock_kernel();
return -EBUSY;
}
rio->isopen = 1;
@@ -116,7 +119,6 @@ static long ioctl_rio(struct file *file, unsigned int cmd, unsigned long arg)
int retries;
int retval=0;
- lock_kernel();
mutex_lock(&(rio->lock));
/* Sanity check to make sure rio is connected, powered, etc */
if (rio->present == 0 || rio->rio_dev == NULL) {
@@ -255,7 +257,6 @@ static long ioctl_rio(struct file *file, unsigned int cmd, unsigned long arg)
err_out:
mutex_unlock(&(rio->lock));
- unlock_kernel();
return retval;
}
@@ -490,6 +491,7 @@ static void disconnect_rio(struct usb_interface *intf)
struct rio_usb_data *rio = usb_get_intfdata (intf);
usb_set_intfdata (intf, NULL);
+ lock_kernel();
if (rio) {
usb_deregister_dev(intf, &usb_rio_class);
@@ -499,6 +501,7 @@ static void disconnect_rio(struct usb_interface *intf)
/* better let it finish - the release will do whats needed */
rio->rio_dev = NULL;
mutex_unlock(&(rio->lock));
+ unlock_kernel();
return;
}
kfree(rio->ibuf);
@@ -509,6 +512,7 @@ static void disconnect_rio(struct usb_interface *intf)
rio->present = 0;
mutex_unlock(&(rio->lock));
}
+ unlock_kernel();
}
static const struct usb_device_id rio_table[] = {