Hi, Here's a patch against 2.4.13-pre5 that fixes the locking bugs that David Miller found in the usb core code.
thanks, greg k-h (temporary USB maintainer) diff --minimal -Nru a/drivers/usb/devices.c b/drivers/usb/devices.c --- a/drivers/usb/devices.c Fri Oct 19 17:01:16 2001 +++ b/drivers/usb/devices.c Fri Oct 19 17:01:16 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 Fri Oct 19 17:01:16 2001 +++ b/drivers/usb/inode.c Fri Oct 19 17:01:16 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 Fri Oct 19 17:01:16 2001 +++ b/drivers/usb/usb.c Fri Oct 19 17:01:16 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 Fri Oct 19 17:01:16 2001 +++ b/include/linux/usb.h Fri Oct 19 17:01:16 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