patch-2.4.7 linux/drivers/usb/usb.c
Next file: linux/drivers/video/Config.in
Previous file: linux/drivers/usb/usb-skeleton.c
Back to the patch index
Back to the overall index
- Lines: 141
- Date:
Thu Jul 12 14:21:05 2001
- Orig file:
v2.4.6/linux/drivers/usb/usb.c
- Orig date:
Tue Jul 3 17:08:21 2001
diff -u --recursive --new-file v2.4.6/linux/drivers/usb/usb.c linux/drivers/usb/usb.c
@@ -29,6 +29,7 @@
#include <linux/kmod.h>
#include <linux/init.h>
#include <linux/devfs_fs_kernel.h>
+#include <linux/spinlock.h>
#ifdef CONFIG_USB_DEBUG
#define DEBUG
@@ -59,6 +60,7 @@
*/
LIST_HEAD(usb_driver_list);
LIST_HEAD(usb_bus_list);
+rwlock_t usb_bus_list_lock = RW_LOCK_UNLOCKED;
devfs_handle_t usb_devfs_handle; /* /dev/usb dir. */
@@ -110,6 +112,7 @@
{
struct list_head *tmp;
+ read_lock_irq (&usb_bus_list_lock);
tmp = usb_bus_list.next;
while (tmp != &usb_bus_list) {
struct usb_bus *bus = list_entry(tmp,struct usb_bus, bus_list);
@@ -117,6 +120,7 @@
tmp = tmp->next;
usb_check_support(bus->root_hub);
}
+ read_unlock_irq (&usb_bus_list_lock);
}
/*
@@ -178,6 +182,7 @@
*/
list_del(&driver->driver_list);
+ read_lock_irq (&usb_bus_list_lock);
tmp = usb_bus_list.next;
while (tmp != &usb_bus_list) {
struct usb_bus *bus = list_entry(tmp,struct usb_bus,bus_list);
@@ -185,6 +190,7 @@
tmp = tmp->next;
usb_drivers_purge(driver, bus->root_hub);
}
+ read_unlock_irq (&usb_bus_list_lock);
}
struct usb_interface *usb_ifnum_to_if(struct usb_device *dev, unsigned ifnum)
@@ -415,6 +421,7 @@
{
int busnum;
+ write_lock_irq (&usb_bus_list_lock);
busnum = find_next_zero_bit(busmap.busmap, USB_MAXBUS, 1);
if (busnum < USB_MAXBUS) {
set_bit(busnum, busmap.busmap);
@@ -426,6 +433,7 @@
/* Add it to the list of buses */
list_add(&bus->bus_list, &usb_bus_list);
+ write_unlock_irq (&usb_bus_list_lock);
usbdevfs_add_bus(bus);
@@ -447,9 +455,11 @@
* controller code, as well as having it call this when cleaning
* itself up
*/
+ write_lock_irq (&usb_bus_list_lock);
list_del(&bus->bus_list);
+ write_unlock_irq (&usb_bus_list_lock);
- usbdevfs_remove_bus(bus);
+ usbdevfs_remove_bus(bus);
clear_bit(bus->busnum, busmap.busmap);
@@ -688,10 +698,12 @@
return -1;
}
+ down(&dev->serialize);
+
interface = dev->actconfig->interface + ifnum;
if (usb_interface_claimed(interface))
- return -1;
+ goto out_err;
private = NULL;
for (tmp = usb_driver_list.next; tmp != &usb_driver_list;) {
@@ -699,7 +711,6 @@
driver = list_entry(tmp, struct usb_driver, driver_list);
tmp = tmp->next;
- down(&driver->serialize);
id = driver->id_table;
/* new style driver? */
if (id) {
@@ -707,7 +718,9 @@
interface->act_altsetting = i;
id = usb_match_id(dev, interface, id);
if (id) {
+ down(&driver->serialize);
private = driver->probe(dev,ifnum,id);
+ up(&driver->serialize);
if (private != NULL)
break;
}
@@ -717,15 +730,21 @@
interface->act_altsetting = 0;
}
else /* "old style" driver */
+ {
+ down(&driver->serialize);
private = driver->probe(dev, ifnum, NULL);
+ up(&driver->serialize);
+ }
- up(&driver->serialize);
if (private) {
usb_driver_claim_interface(driver, interface, private);
+ up(&dev->serialize);
return 0;
}
}
+out_err:
+ up(&dev->serialize);
return -1;
}
@@ -924,6 +943,8 @@
atomic_set(&dev->refcnt, 1);
INIT_LIST_HEAD(&dev->inodes);
INIT_LIST_HEAD(&dev->filelist);
+
+ init_MUTEX(&dev->serialize);
dev->bus->op->allocate(dev);
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)