Re: cannot submit urb 0, error -22: internal error followed by USB hung tasks

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Fri, 28 Sep 2012, [iso-8859-1] Lassi V��inen wrote:

> 
> On Sep 28, 2012, at 00:18 , Alan Stern <stern@xxxxxxxxxxxxxxxxxxx> wrote:
> > The usbmon trace does not show any errors at all.  The file doesn't 
> > contain any occurrences of "-22", for instance.
> 
> Ok. How can I tell when this error is visible in the logs? Status field is -22?

If that is the error you are most worried about, then yes.  There were 
other errors (URBs still pending) that caused khubd to hang, but there 
was no way to tell why they occurred.

> > To be most helpful, you should provide both a dmesg log and a usbmon
> > trace taken at the same time, from a kernel with CONFIG_USB_DEBUG
> > enabled.  First unplug all the USB devices, then do "dmesg -c
> >> /dev/null", then plug in all the USB devices, then start the usbmon
> > trace, then run the test.  After the failure occurs, collect the trace 
> > and the entire dmesg output and post them.
> 
> Would it be better to take the usbmon trace from all buses (0u, right?).

I don't know; it depends on what the test is doing.  Which USB devices 
does it read from and which devices does it write to?  Are there any 
other unrelated USB devices attached (hint: it helps if there aren't).

> Or which usbmon socket should I take the traces on?

The ones that get the errors you want to investigate.  Unforunately the 
error messages printed out by the snd-usb-audio driver aren't very 
helpful; they don't say what device they relate to.

> Also, just a document improvement suggestion: the usbmon.txt is a bit
> vague on the socket types:
> 
> # ls /sys/kernel/debug/usb/usbmon
> 0s  0u  1s  1t  1u  2s  2t  2u  3s  3t  3u  4s  4t  4u
> #
> 
> This would be a good place to have a short description about what the  s, u and t sockets mean. So far I have no clue..

The *t and *u files already are described in usbmon.txt.  Adding a 
description of the *s files would be a good idea; I am always ready to 
review patches.

> > Also, it would be good if you could test with the most recent 3.6-rc 
> > kernel.  The distribution you use doesn't really matter, only the 
> > kernel version.
> > 
> 
> Ok, I'll try and do that

In addition, you might want to try the patch below.  It might not make 
any difference; without knowing the cause of your problem I can't say.

Alan Stern



Index: usb-3.6/drivers/usb/host/ohci-hcd.c
===================================================================
--- usb-3.6.orig/drivers/usb/host/ohci-hcd.c
+++ usb-3.6/drivers/usb/host/ohci-hcd.c
@@ -231,13 +231,43 @@ static int ohci_urb_enqueue (
 			frame &= ~(ed->interval - 1);
 			frame |= ed->branch;
 			urb->start_frame = frame;
+		}
+	} else if (ed->type == PIPE_ISOCHRONOUS) {
+		u16	next = ohci_frame_no(ohci) + 2;
+		u16	frame = ed->last_iso + ed->interval;
+
+		/* Behind the scheduling threshold? */
+		if (unlikely(tick_before(frame, next))) {
+
+			/* USB_ISO_ASAP: Round up to the first available slot */
+			if (urb->transfer_flags & URB_ISO_ASAP) {
+				frame += (next - frame + ed->interval - 1) &
+						(- ed->interval);
+			}
+
+			/*
+			 * Not ASAP: Use the next slot in the stream.  If
+			 * the entire URB falls before the threshold, fail.
+			 */
+			else if (tick_before(frame + ed->interval *
+					(urb->number_of_packets - 1), next)) {
+				retval = -EXDEV;
+				usb_hcd_unlink_urb_from_ep(hcd, urb);
+				goto fail;
+			}
 
-			/* yes, only URB_ISO_ASAP is supported, and
-			 * urb->start_frame is never used as input.
+			/*
+			 * Some OHCI hardware doesn't handle late TDs
+			 * correctly.  After retiring them it proceeds to
+			 * the next ED instead of the next TD.  Therefore
+			 * we have to omit the late TDs entirely.
 			 */
+			urb_priv->td_cnt = DIV_ROUND_UP(next - frame,
+					ed->interval);
+			}
 		}
-	} else if (ed->type == PIPE_ISOCHRONOUS)
-		urb->start_frame = ed->last_iso + ed->interval;
+		urb->start_frame = frame;
+	}
 
 	/* fill the TDs and link them to the ed; and
 	 * enable that part of the schedule, if needed
Index: usb-3.6/drivers/usb/host/ohci-q.c
===================================================================
--- usb-3.6.orig/drivers/usb/host/ohci-q.c
+++ usb-3.6/drivers/usb/host/ohci-q.c
@@ -596,7 +596,6 @@ static void td_submit_urb (
 		urb_priv->ed->hwHeadP &= ~cpu_to_hc32 (ohci, ED_C);
 	}
 
-	urb_priv->td_cnt = 0;
 	list_add (&urb_priv->pending, &ohci->pending);
 
 	if (data_len)
@@ -672,7 +671,8 @@ static void td_submit_urb (
 	 * we could often reduce the number of TDs here.
 	 */
 	case PIPE_ISOCHRONOUS:
-		for (cnt = 0; cnt < urb->number_of_packets; cnt++) {
+		for (cnt = urb_priv->td_cnt; cnt < urb->number_of_packets;
+				cnt++) {
 			int	frame = urb->start_frame;
 
 			// FIXME scheduling should handle frame counter

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux