Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=3ddad8232c3802f7a602d1ea24938a8067114479
Commit:     3ddad8232c3802f7a602d1ea24938a8067114479
Parent:     f42449003114cc17cda0458c14f2deadfadf9f63
Author:     Oliver Neukum <[EMAIL PROTECTED]>
AuthorDate: Tue Jul 24 15:13:42 2007 +0200
Committer:  Greg Kroah-Hartman <[EMAIL PROTECTED]>
CommitDate: Mon Jul 30 13:27:46 2007 -0700

    USB: fix BUG: sleeping function called from invalid context at 
/home/jeremy/hg/xen/paravirt/linux/drivers/usb/core/urb.c:524, in_atomic():1, 
irqs_disabled():0
    
    Clearly there's a bug in
    drivers/usb/serial/usb-serial.c:usb_serial_put().  It shouldn't call
    kref_put() while holding a spinlock.
    
    Signed-off-by: Oliver Neukum <[EMAIL PROTECTED]>
    Signed-off-by: Greg Kroah-Hartman <[EMAIL PROTECTED]>
---
 drivers/usb/serial/usb-serial.c |   17 ++++++++---------
 1 files changed, 8 insertions(+), 9 deletions(-)

diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c
index 5e1cf78..9bf01a5 100644
--- a/drivers/usb/serial/usb-serial.c
+++ b/drivers/usb/serial/usb-serial.c
@@ -60,19 +60,19 @@ static struct usb_driver usb_serial_driver = {
 
 static int debug;
 static struct usb_serial *serial_table[SERIAL_TTY_MINORS];     /* initially 
all NULL */
-static spinlock_t table_lock;
+static DEFINE_MUTEX(table_lock);
 static LIST_HEAD(usb_serial_driver_list);
 
 struct usb_serial *usb_serial_get_by_index(unsigned index)
 {
        struct usb_serial *serial;
 
-       spin_lock(&table_lock);
+       mutex_lock(&table_lock);
        serial = serial_table[index];
 
        if (serial)
                kref_get(&serial->kref);
-       spin_unlock(&table_lock);
+       mutex_unlock(&table_lock);
        return serial;
 }
 
@@ -84,7 +84,7 @@ static struct usb_serial *get_free_serial (struct usb_serial 
*serial, int num_po
        dbg("%s %d", __FUNCTION__, num_ports);
 
        *minor = 0;
-       spin_lock(&table_lock);
+       mutex_lock(&table_lock);
        for (i = 0; i < SERIAL_TTY_MINORS; ++i) {
                if (serial_table[i])
                        continue;
@@ -106,10 +106,10 @@ static struct usb_serial *get_free_serial (struct 
usb_serial *serial, int num_po
                        serial_table[i] = serial;
                        serial->port[j++]->number = i;
                }
-               spin_unlock(&table_lock);
+               mutex_unlock(&table_lock);
                return serial;
        }
-       spin_unlock(&table_lock);
+       mutex_unlock(&table_lock);
        return NULL;
 }
 
@@ -172,9 +172,9 @@ static void destroy_serial(struct kref *kref)
 
 void usb_serial_put(struct usb_serial *serial)
 {
-       spin_lock(&table_lock);
+       mutex_lock(&table_lock);
        kref_put(&serial->kref, destroy_serial);
-       spin_unlock(&table_lock);
+       mutex_unlock(&table_lock);
 }
 
 /*****************************************************************************
@@ -1129,7 +1129,6 @@ static int __init usb_serial_init(void)
                return -ENOMEM;
 
        /* Initialize our global data */
-       spin_lock_init(&table_lock);
        for (i = 0; i < SERIAL_TTY_MINORS; ++i) {
                serial_table[i] = NULL;
        }
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to