Commit 511e2d02 authored by Oliver Neukum's avatar Oliver Neukum Committed by Greg Kroah-Hartman

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: default avatarOliver Neukum <oliver@neukum.org>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent 5a207b43
...@@ -77,11 +77,14 @@ static struct rio_usb_data rio_instance; ...@@ -77,11 +77,14 @@ static struct rio_usb_data rio_instance;
static int open_rio(struct inode *inode, struct file *file) static int open_rio(struct inode *inode, struct file *file)
{ {
struct rio_usb_data *rio = &rio_instance; struct rio_usb_data *rio = &rio_instance;
/* against disconnect() */
lock_kernel(); lock_kernel();
mutex_lock(&(rio->lock)); mutex_lock(&(rio->lock));
if (rio->isopen || !rio->present) { if (rio->isopen || !rio->present) {
mutex_unlock(&(rio->lock)); mutex_unlock(&(rio->lock));
unlock_kernel();
return -EBUSY; return -EBUSY;
} }
rio->isopen = 1; rio->isopen = 1;
...@@ -116,7 +119,6 @@ static long ioctl_rio(struct file *file, unsigned int cmd, unsigned long arg) ...@@ -116,7 +119,6 @@ static long ioctl_rio(struct file *file, unsigned int cmd, unsigned long arg)
int retries; int retries;
int retval=0; int retval=0;
lock_kernel();
mutex_lock(&(rio->lock)); mutex_lock(&(rio->lock));
/* Sanity check to make sure rio is connected, powered, etc */ /* Sanity check to make sure rio is connected, powered, etc */
if (rio->present == 0 || rio->rio_dev == NULL) { 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) ...@@ -255,7 +257,6 @@ static long ioctl_rio(struct file *file, unsigned int cmd, unsigned long arg)
err_out: err_out:
mutex_unlock(&(rio->lock)); mutex_unlock(&(rio->lock));
unlock_kernel();
return retval; return retval;
} }
...@@ -490,6 +491,7 @@ static void disconnect_rio(struct usb_interface *intf) ...@@ -490,6 +491,7 @@ static void disconnect_rio(struct usb_interface *intf)
struct rio_usb_data *rio = usb_get_intfdata (intf); struct rio_usb_data *rio = usb_get_intfdata (intf);
usb_set_intfdata (intf, NULL); usb_set_intfdata (intf, NULL);
lock_kernel();
if (rio) { if (rio) {
usb_deregister_dev(intf, &usb_rio_class); usb_deregister_dev(intf, &usb_rio_class);
...@@ -499,6 +501,7 @@ static void disconnect_rio(struct usb_interface *intf) ...@@ -499,6 +501,7 @@ static void disconnect_rio(struct usb_interface *intf)
/* better let it finish - the release will do whats needed */ /* better let it finish - the release will do whats needed */
rio->rio_dev = NULL; rio->rio_dev = NULL;
mutex_unlock(&(rio->lock)); mutex_unlock(&(rio->lock));
unlock_kernel();
return; return;
} }
kfree(rio->ibuf); kfree(rio->ibuf);
...@@ -509,6 +512,7 @@ static void disconnect_rio(struct usb_interface *intf) ...@@ -509,6 +512,7 @@ static void disconnect_rio(struct usb_interface *intf)
rio->present = 0; rio->present = 0;
mutex_unlock(&(rio->lock)); mutex_unlock(&(rio->lock));
} }
unlock_kernel();
} }
static const struct usb_device_id rio_table[] = { static const struct usb_device_id rio_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