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

Reply via email to