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>
diff --git a/drivers/usb/misc/rio500.c b/drivers/usb/misc/rio500.c
index 47ce46b..a85771b 100644
--- a/drivers/usb/misc/rio500.c
+++ b/drivers/usb/misc/rio500.c
@@ -77,11 +77,14 @@
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 @@
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 @@
err_out:
mutex_unlock(&(rio->lock));
- unlock_kernel();
return retval;
}
@@ -490,6 +491,7 @@
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 @@
/* 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 @@
rio->present = 0;
mutex_unlock(&(rio->lock));
}
+ unlock_kernel();
}
static const struct usb_device_id rio_table[] = {