ChangeSet 1.1276.22.29, 2003/08/22 16:13:14-07:00, david-b@pacbell.net [PATCH] USB: usb_sg_cancel() + disconnect, fewer messages One tester reported that disconnecting in the middle of a scatterlist operation would give a lot of confusing messages. This should improve that situation a bunch: most of the messages were pointless. It also resolves some related FIXMEs for both queue cleanup modes (cancelation, and after transport fault). - now only urbs in flight have non-null urb->dev, so we can avoid trying to unlink unsubmitted or (common) already-completed urbs. - it's ok to get -EBUSY unlink status, it just means the urb's already being given back (though since it's in flight, it's not an error to try unlinking). Also, the relevant diagnostics now use dev_*() driver model calls, making the kernel strings smaller and the output more useful. drivers/usb/core/message.c | 30 +++++++++++++++++------------- 1 files changed, 17 insertions(+), 13 deletions(-) diff -Nru a/drivers/usb/core/message.c b/drivers/usb/core/message.c --- a/drivers/usb/core/message.c Tue Sep 2 12:46:21 2003 +++ b/drivers/usb/core/message.c Tue Sep 2 12:46:21 2003 @@ -246,21 +246,22 @@ io->status = urb->status; /* the previous urbs, and this one, completed already. - * unlink the later ones so they won't rx/tx bad data, - * - * FIXME don't bother unlinking urbs that haven't yet been - * submitted; those non-error cases shouldn't be syslogged + * unlink pending urbs so they won't rx/tx bad data. */ for (i = 0, found = 0; i < io->entries; i++) { + if (!io->urbs [i]) + continue; if (found) { status = usb_unlink_urb (io->urbs [i]); - if (status && status != -EINPROGRESS) - err ("sg_complete, unlink --> %d", - status); + if (status != -EINPROGRESS && status != -EBUSY) + dev_err (&io->dev->dev, + "%s, unlink --> %d\n", + __FUNCTION__, status); } else if (urb == io->urbs [i]) found = 1; } } + urb->dev = 0; /* on the last completion, signal usb_sg_wait() */ io->bytes += urb->actual_length; @@ -356,7 +357,7 @@ goto nomem; } - io->urbs [i]->dev = dev; + io->urbs [i]->dev = 0; io->urbs [i]->pipe = pipe; io->urbs [i]->interval = period; io->urbs [i]->transfer_flags = urb_flags; @@ -448,6 +449,7 @@ for (i = 0; i < io->entries && !io->status; i++) { int retval; + io->urbs [i]->dev = io->dev; retval = usb_submit_urb (io->urbs [i], SLAB_ATOMIC); /* after we submit, let completions or cancelations fire; @@ -459,9 +461,9 @@ case -ENXIO: // hc didn't queue this one case -EAGAIN: case -ENOMEM: + io->urbs [i]->dev = 0; retval = 0; i--; - // FIXME: should it usb_sg_cancel() on INTERRUPT? yield (); break; @@ -477,8 +479,10 @@ /* fail any uncompleted urbs */ default: + io->urbs [i]->dev = 0; io->urbs [i]->status = retval; - dbg ("usb_sg_msg, submit --> %d", retval); + dev_dbg (&io->dev->dev, "%s, submit --> %d\n", + __FUNCTION__, retval); usb_sg_cancel (io); } spin_lock_irqsave (&io->lock, flags); @@ -521,9 +525,9 @@ if (!io->urbs [i]->dev) continue; retval = usb_unlink_urb (io->urbs [i]); - if (retval && retval != -EINPROGRESS) - warn ("usb_sg_cancel, unlink --> %d", retval); - // FIXME don't warn on "not yet submitted" error + if (retval != -EINPROGRESS && retval != -EBUSY) + dev_warn (&io->dev->dev, "%s, unlink --> %d\n", + __FUNCTION__, retval); } } spin_unlock_irqrestore (&io->lock, flags);