On Tue, 7 Sep 2004, Andrew Pilley wrote:

> Okay, here you go. I've got spare time tomorrow, so if you manage to get
> this back to me in the next 12 hours, I can bang on it repeatedly until
> it triggers, since I'll have time to spare.

Here's the patch.  I've verified that it compiles okay but I haven't 
tried running it on my system, so it's possible that it won't work quite 
right.  But it probably will.

You don't need usb-storage debugging enabled for this; in fact, you 
shouldn't enable it.  The patch will put extra messages in the system log 
whenever something strange happens in the particular region of code that's 
been causing problems.  I think that will happen as often as the hangs 
you used to get -- the earlier patch that seemed to help didn't actually 
prevent funny things from happening; it just made sure the system would 
continue running normally when they did.

Anyway, try it and see what happens.

Alan Stern


--- linux-usb/drivers/usb/core/message.c.orig   Mon Sep  6 12:16:12 2004
+++ linux-usb/drivers/usb/core/message.c        Mon Sep  6 12:23:28 2004
@@ -197,6 +197,67 @@
 
 /*-------------------------------------------------------------------*/
 
+#define USB_LOG_LINE_LEN       60
+
+static char    usb_log_buf[USB_LOG_LINE_LEN * 50];
+static char    *log_head = usb_log_buf,
+               *log_tail = usb_log_buf;
+static int     log_immediate;
+static spinlock_t log_lock = SPIN_LOCK_UNLOCKED;
+
+#define advance_logptr(x)                                      \
+       do {                                                    \
+               x += USB_LOG_LINE_LEN;                          \
+               if (x == usb_log_buf + sizeof(usb_log_buf))     \
+                       x = usb_log_buf;                        \
+       } while(0)
+
+static void usb_log(const char *fmt, ...)
+{
+       va_list args;
+       unsigned long flags;
+
+       va_start(args, fmt);
+       spin_lock_irqsave(&log_lock, flags);
+
+       vsnprintf(log_tail, USB_LOG_LINE_LEN, fmt, args);
+       advance_logptr(log_tail);
+       if (log_tail == log_head)
+               advance_logptr(log_head);
+       if (log_immediate) {
+               printk(KERN_INFO "%s", log_head);
+               log_head = log_tail;
+       }
+
+       spin_unlock_irqrestore(&log_lock, flags);
+       va_end(args);
+}
+
+static void usb_log_start_dump(void)
+{
+       unsigned long flags;
+
+       spin_lock_irqsave(&log_lock, flags);
+       while (log_head != log_tail) {
+               printk(KERN_INFO "%s", log_head);
+               advance_logptr(log_head);
+       }
+       log_immediate = 1;
+       spin_unlock_irqrestore(&log_lock, flags);
+}
+
+static void usb_log_stop_dump(void)
+{
+       unsigned long flags;
+
+       spin_lock_irqsave(&log_lock, flags);
+       log_immediate = 0;
+       spin_unlock_irqrestore(&log_lock, flags);
+}
+
+
+/*-------------------------------------------------------------------*/
+
 static void sg_clean (struct usb_sg_request *io)
 {
        if (io->urbs) {
@@ -214,6 +275,8 @@
 {
        struct usb_sg_request   *io = (struct usb_sg_request *) urb->context;
 
+       usb_log("complete %p (%d): %d\n", urb, urb->actual_length,
+                       urb->status);
        spin_lock (&io->lock);
 
        /* In 2.5 we require hcds' endpoint queues not to progress after fault
@@ -242,6 +305,7 @@
        if (urb->status && urb->status != -ECONNRESET) {
                int             i, found, status;
 
+               usb_log_start_dump();
                io->status = urb->status;
 
                /* the previous urbs, and this one, completed already.
@@ -252,6 +316,7 @@
                                continue;
                        if (found) {
                                status = usb_unlink_urb (io->urbs [i]);
+       usb_log("unlink1 %p: %d\n", io->urbs[i], status);
                                if (status != -EINPROGRESS && status != -EBUSY)
                                        dev_err (&io->dev->dev,
                                                "%s, unlink --> %d\n",
@@ -265,6 +330,7 @@
        /* on the last completion, signal usb_sg_wait() */
        io->bytes += urb->actual_length;
        io->count--;
+       usb_log("count: %d\n", io->count);
        if (!io->count)
                complete (&io->complete);
 
@@ -391,6 +457,7 @@
        io->status = 0;
        io->bytes = 0;
        init_completion (&io->complete);
+       usb_log("sg_init %d\n", io->entries);
        return 0;
 
 nomem:
@@ -449,6 +516,8 @@
 
                io->urbs [i]->dev = io->dev;
                retval = usb_submit_urb (io->urbs [i], SLAB_ATOMIC);
+               usb_log("submit %p (%d): %d\n", io->urbs[i],
+                       io->urbs[i]->transfer_buffer_length, retval);
 
                /* after we submit, let completions or cancelations fire;
                 * we handshake using io->status.
@@ -499,6 +568,7 @@
        wait_for_completion (&io->complete);
 
        sg_clean (io);
+       usb_log_stop_dump();
 }
 
 /**
@@ -513,6 +583,9 @@
 {
        unsigned long   flags;
 
+       usb_log_start_dump();
+       usb_log("cancel\n");
+
        spin_lock_irqsave (&io->lock, flags);
 
        /* shut everything down, if it didn't already */
@@ -526,6 +599,7 @@
                        if (!io->urbs [i]->dev)
                                continue;
                        retval = usb_unlink_urb (io->urbs [i]);
+       usb_log("unlink2 %p: %d\n", io->urbs[i], retval);
                        if (retval != -EINPROGRESS && retval != -EBUSY)
                                dev_warn (&io->dev->dev, "%s, unlink --> %d\n",
                                        __FUNCTION__, retval);



-------------------------------------------------------
This SF.Net email is sponsored by BEA Weblogic Workshop
FREE Java Enterprise J2EE developer tools!
Get your free copy of BEA WebLogic Workshop 8.1 today.
http://ads.osdn.com/?ad_id=5047&alloc_id=10808&op=click
_______________________________________________
[EMAIL PROTECTED]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel

Reply via email to