diff options
author | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-07-12 16:46:58 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-07-12 16:46:58 -0700 |
commit | 9374430a52dfae5c013b88f7f030c04a6774d410 (patch) | |
tree | ce1ee8eee4e79fbb9486e810278d1092afc74a44 /drivers/usb/core/file.c | |
parent | 66f49739fe1591197364f2dad1b67b975e8f5e85 (diff) | |
parent | 13f9966b3ba5b45f47f2ea0eb0a90afceedfbb1f (diff) |
Merge master.kernel.org:/pub/scm/linux/kernel/git/gregkh/usb-2.6
* master.kernel.org:/pub/scm/linux/kernel/git/gregkh/usb-2.6: (149 commits)
USB: ohci-pnx4008: Remove unnecessary cast of return value of kzalloc
USB: additions to the quirk list
usb-storage: implement autosuspend
USB: cdc-acm: add new device id to option driver
USB: goku_udc trivial cleanups
USB: usb gadget stack can now -DDEBUG with Kconfig
usb gadget stack: remove usb_ep_*_buffer(), part 2
usb gadget stack: remove usb_ep_*_buffer(), part 1
USB: pxa2xx_udc -- cleanups, mostly removing dma hooks
USB: pxa2xx_udc: use generic gpio layer
USB: quirk for samsung printer
USB: usb/dma doc updates
USB: drivers/usb/storage/unusual_devs.h whitespace cleanup
USB: remove Makefile reference to obsolete OHCI_AT91
USB: io_*: remove bogus termios no change checks
USB: mos7720: remove bogus no termios change check
USB: visor and whiteheat: remove bogus termios change checks
USB: pl2303: remove bogus checks and fix speed support to use tty_get_baud_rate()
USB: mos7840.c: turn this into a serial driver
USB: make the usb_device numa_node get assigned from controller
...
Diffstat (limited to 'drivers/usb/core/file.c')
-rw-r--r-- | drivers/usb/core/file.c | 29 |
1 files changed, 13 insertions, 16 deletions
diff --git a/drivers/usb/core/file.c b/drivers/usb/core/file.c index 01c857ac27a..5d860bc9b42 100644 --- a/drivers/usb/core/file.c +++ b/drivers/usb/core/file.c @@ -16,15 +16,15 @@ */ #include <linux/module.h> -#include <linux/spinlock.h> #include <linux/errno.h> +#include <linux/rwsem.h> #include <linux/usb.h> #include "usb.h" #define MAX_USB_MINORS 256 static const struct file_operations *usb_minors[MAX_USB_MINORS]; -static DEFINE_SPINLOCK(minor_lock); +static DECLARE_RWSEM(minor_rwsem); static int usb_open(struct inode * inode, struct file * file) { @@ -33,14 +33,11 @@ static int usb_open(struct inode * inode, struct file * file) int err = -ENODEV; const struct file_operations *old_fops, *new_fops = NULL; - spin_lock (&minor_lock); + down_read(&minor_rwsem); c = usb_minors[minor]; - if (!c || !(new_fops = fops_get(c))) { - spin_unlock(&minor_lock); - return err; - } - spin_unlock(&minor_lock); + if (!c || !(new_fops = fops_get(c))) + goto done; old_fops = file->f_op; file->f_op = new_fops; @@ -52,6 +49,8 @@ static int usb_open(struct inode * inode, struct file * file) file->f_op = fops_get(old_fops); } fops_put(old_fops); + done: + up_read(&minor_rwsem); return err; } @@ -166,7 +165,7 @@ int usb_register_dev(struct usb_interface *intf, if (class_driver->fops == NULL) goto exit; - spin_lock (&minor_lock); + down_write(&minor_rwsem); for (minor = minor_base; minor < MAX_USB_MINORS; ++minor) { if (usb_minors[minor]) continue; @@ -176,7 +175,7 @@ int usb_register_dev(struct usb_interface *intf, retval = 0; break; } - spin_unlock (&minor_lock); + up_write(&minor_rwsem); if (retval) goto exit; @@ -197,9 +196,9 @@ int usb_register_dev(struct usb_interface *intf, intf->usb_dev = device_create(usb_class->class, &intf->dev, MKDEV(USB_MAJOR, minor), "%s", temp); if (IS_ERR(intf->usb_dev)) { - spin_lock (&minor_lock); + down_write(&minor_rwsem); usb_minors[intf->minor] = NULL; - spin_unlock (&minor_lock); + up_write(&minor_rwsem); retval = PTR_ERR(intf->usb_dev); } exit: @@ -236,9 +235,9 @@ void usb_deregister_dev(struct usb_interface *intf, dbg ("removing %d minor", intf->minor); - spin_lock (&minor_lock); + down_write(&minor_rwsem); usb_minors[intf->minor] = NULL; - spin_unlock (&minor_lock); + up_write(&minor_rwsem); snprintf(name, BUS_ID_SIZE, class_driver->name, intf->minor - minor_base); device_destroy(usb_class->class, MKDEV(USB_MAJOR, intf->minor)); @@ -247,5 +246,3 @@ void usb_deregister_dev(struct usb_interface *intf, destroy_usb_class(); } EXPORT_SYMBOL(usb_deregister_dev); - - |