aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOliver Neukum <oliver@neukum.org>2010-01-14 10:10:38 -0500
committerGreg Kroah-Hartman <gregkh@suse.de>2010-03-02 17:54:28 -0500
commit511e2d0218d04f544065eb277ad475bf14881efe (patch)
tree135ecfb228ba1941c4b12a10b06a1721b8995d6f
parent5a207b431174ecc8f995230d19c79242160b8888 (diff)
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>
-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;
77static int open_rio(struct inode *inode, struct file *file) 77static int open_rio(struct inode *inode, struct file *file)
78{ 78{
79 struct rio_usb_data *rio = &rio_instance; 79 struct rio_usb_data *rio = &rio_instance;
80
81 /* against disconnect() */
80 lock_kernel(); 82 lock_kernel();
81 mutex_lock(&(rio->lock)); 83 mutex_lock(&(rio->lock));
82 84
83 if (rio->isopen || !rio->present) { 85 if (rio->isopen || !rio->present) {
84 mutex_unlock(&(rio->lock)); 86 mutex_unlock(&(rio->lock));
87 unlock_kernel();
85 return -EBUSY; 88 return -EBUSY;
86 } 89 }
87 rio->isopen = 1; 90 rio->isopen = 1;
@@ -116,7 +119,6 @@ static long ioctl_rio(struct file *file, unsigned int cmd, unsigned long arg)
116 int retries; 119 int retries;
117 int retval=0; 120 int retval=0;
118 121
119 lock_kernel();
120 mutex_lock(&(rio->lock)); 122 mutex_lock(&(rio->lock));
121 /* Sanity check to make sure rio is connected, powered, etc */ 123 /* Sanity check to make sure rio is connected, powered, etc */
122 if (rio->present == 0 || rio->rio_dev == NULL) { 124 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 257
256err_out: 258err_out:
257 mutex_unlock(&(rio->lock)); 259 mutex_unlock(&(rio->lock));
258 unlock_kernel();
259 return retval; 260 return retval;
260} 261}
261 262
@@ -490,6 +491,7 @@ static void disconnect_rio(struct usb_interface *intf)
490 struct rio_usb_data *rio = usb_get_intfdata (intf); 491 struct rio_usb_data *rio = usb_get_intfdata (intf);
491 492
492 usb_set_intfdata (intf, NULL); 493 usb_set_intfdata (intf, NULL);
494 lock_kernel();
493 if (rio) { 495 if (rio) {
494 usb_deregister_dev(intf, &usb_rio_class); 496 usb_deregister_dev(intf, &usb_rio_class);
495 497
@@ -499,6 +501,7 @@ static void disconnect_rio(struct usb_interface *intf)
499 /* better let it finish - the release will do whats needed */ 501 /* better let it finish - the release will do whats needed */
500 rio->rio_dev = NULL; 502 rio->rio_dev = NULL;
501 mutex_unlock(&(rio->lock)); 503 mutex_unlock(&(rio->lock));
504 unlock_kernel();
502 return; 505 return;
503 } 506 }
504 kfree(rio->ibuf); 507 kfree(rio->ibuf);
@@ -509,6 +512,7 @@ static void disconnect_rio(struct usb_interface *intf)
509 rio->present = 0; 512 rio->present = 0;
510 mutex_unlock(&(rio->lock)); 513 mutex_unlock(&(rio->lock));
511 } 514 }
515 unlock_kernel();
512} 516}
513 517
514static const struct usb_device_id rio_table[] = { 518static const struct usb_device_id rio_table[] = {