Hi,
Here's a patch against 2.4.12-ac5 that fixes a bug found by David Miller
in the locking code. This fix is also in 2.4.13-pre6.
thanks,
greg k-h
diff --minimal -Nru a/drivers/usb/devices.c b/drivers/usb/devices.c
--- a/drivers/usb/devices.c Mon Oct 22 14:43:55 2001
+++ b/drivers/usb/devices.c Mon Oct 22 14:43:55 2001
@@ -488,7 +488,7 @@
return -EFAULT;
/* enumerate busses */
- read_lock_irq (&usb_bus_list_lock);
+ down (&usb_bus_list_lock);
for (buslist = usb_bus_list.next; buslist != &usb_bus_list; buslist =
buslist->next) {
/* print devices for this bus */
bus = list_entry(buslist, struct usb_bus, bus_list);
@@ -498,7 +498,7 @@
return ret;
total_written += ret;
}
- read_unlock_irq (&usb_bus_list_lock);
+ up (&usb_bus_list_lock);
return total_written;
}
diff --minimal -Nru a/drivers/usb/inode.c b/drivers/usb/inode.c
--- a/drivers/usb/inode.c Mon Oct 22 14:43:55 2001
+++ b/drivers/usb/inode.c Mon Oct 22 14:43:55 2001
@@ -260,15 +260,15 @@
struct list_head *list;
struct usb_bus *bus;
- read_lock_irq (&usb_bus_list_lock);
+ down (&usb_bus_list_lock);
for (list = usb_bus_list.next; list != &usb_bus_list; list = list->next) {
bus = list_entry(list, struct usb_bus, bus_list);
if (bus->busnum == busnr) {
- read_unlock_irq (&usb_bus_list_lock);
+ up (&usb_bus_list_lock);
return bus;
}
}
- read_unlock_irq (&usb_bus_list_lock);
+ up (&usb_bus_list_lock);
return NULL;
}
@@ -416,7 +416,7 @@
if (i < 2+NRSPECIAL)
return 0;
i -= 2+NRSPECIAL;
- read_lock_irq (&usb_bus_list_lock);
+ down (&usb_bus_list_lock);
for (list = usb_bus_list.next; list != &usb_bus_list; list =
list->next) {
if (i > 0) {
i--;
@@ -428,7 +428,7 @@
break;
filp->f_pos++;
}
- read_unlock_irq (&usb_bus_list_lock);
+ up (&usb_bus_list_lock);
return 0;
}
}
@@ -639,13 +639,13 @@
list_add_tail(&inode->u.usbdev_i.slist, &s->u.usbdevfs_sb.ilist);
list_add_tail(&inode->u.usbdev_i.dlist, &special[i].inodes);
}
- read_lock_irq (&usb_bus_list_lock);
+ down (&usb_bus_list_lock);
for (blist = usb_bus_list.next; blist != &usb_bus_list; blist = blist->next) {
bus = list_entry(blist, struct usb_bus, bus_list);
new_bus_inode(bus, s);
recurse_new_dev_inode(bus->root_hub, s);
}
- read_unlock_irq (&usb_bus_list_lock);
+ up (&usb_bus_list_lock);
return s;
out_no_root:
diff --minimal -Nru a/drivers/usb/usb.c b/drivers/usb/usb.c
--- a/drivers/usb/usb.c Mon Oct 22 14:43:55 2001
+++ b/drivers/usb/usb.c Mon Oct 22 14:43:55 2001
@@ -60,7 +60,7 @@
*/
LIST_HEAD(usb_driver_list);
LIST_HEAD(usb_bus_list);
-rwlock_t usb_bus_list_lock = RW_LOCK_UNLOCKED;
+struct semaphore usb_bus_list_lock;
devfs_handle_t usb_devfs_handle; /* /dev/usb dir. */
@@ -112,7 +112,7 @@
{
struct list_head *tmp;
- read_lock_irq (&usb_bus_list_lock);
+ down (&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);
@@ -120,7 +120,7 @@
tmp = tmp->next;
usb_check_support(bus->root_hub);
}
- read_unlock_irq (&usb_bus_list_lock);
+ up (&usb_bus_list_lock);
}
/*
@@ -182,7 +182,7 @@
*/
list_del(&driver->driver_list);
- read_lock_irq (&usb_bus_list_lock);
+ down (&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);
@@ -190,7 +190,7 @@
tmp = tmp->next;
usb_drivers_purge(driver, bus->root_hub);
}
- read_unlock_irq (&usb_bus_list_lock);
+ up (&usb_bus_list_lock);
}
struct usb_interface *usb_ifnum_to_if(struct usb_device *dev, unsigned ifnum)
@@ -421,7 +421,7 @@
{
int busnum;
- write_lock_irq (&usb_bus_list_lock);
+ down (&usb_bus_list_lock);
busnum = find_next_zero_bit(busmap.busmap, USB_MAXBUS, 1);
if (busnum < USB_MAXBUS) {
set_bit(busnum, busmap.busmap);
@@ -433,7 +433,7 @@
/* Add it to the list of buses */
list_add(&bus->bus_list, &usb_bus_list);
- write_unlock_irq (&usb_bus_list_lock);
+ up (&usb_bus_list_lock);
usbdevfs_add_bus(bus);
@@ -455,9 +455,9 @@
* controller code, as well as having it call this when cleaning
* itself up
*/
- write_lock_irq (&usb_bus_list_lock);
+ down (&usb_bus_list_lock);
list_del(&bus->bus_list);
- write_unlock_irq (&usb_bus_list_lock);
+ up (&usb_bus_list_lock);
usbdevfs_remove_bus(bus);
@@ -2332,6 +2332,7 @@
*/
static int __init usb_init(void)
{
+ init_MUTEX(&usb_bus_list_lock);
usb_major_init();
usbdevfs_init();
usb_hub_init();
diff --minimal -Nru a/include/linux/usb.h b/include/linux/usb.h
--- a/include/linux/usb.h Mon Oct 22 14:43:55 2001
+++ b/include/linux/usb.h Mon Oct 22 14:43:55 2001
@@ -855,7 +855,7 @@
extern struct list_head usb_driver_list;
extern struct list_head usb_bus_list;
-extern rwlock_t usb_bus_list_lock;
+extern struct semaphore usb_bus_list_lock;
/*
* USB device fs stuff
_______________________________________________
[EMAIL PROTECTED]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel