Re: USB issue with kernel 3.6

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

 



On Mon, 3 Dec 2012, Piergiorgio Sartor wrote:

> Hi Alan,
> 
> I updated the bug report with dmesg dump.
> 
> I hope this time it is correct...

Yes, it is.  It shows a couple of strange things; I need more 
information.

Below is a new test patch; try running the test with this patch in 
place of the previous one.  I don't need to see the usbmon trace, just 
the dmesg log.  And not even all of that; just the part from "alan 
start" to "alan end" -- this will be near the end of the log.

Also, what output do you get from "lspci -v -s b.1"?

Alan Stern



Index: usb-3.7/drivers/usb/host/ehci-hcd.c
===================================================================
--- usb-3.7.orig/drivers/usb/host/ehci-hcd.c
+++ usb-3.7/drivers/usb/host/ehci-hcd.c
@@ -825,8 +825,10 @@ dead:
 		bh = 0;
 	}
 
-	if (bh)
+	if (bh) {
+		ehci->last_scan_time = jiffies;
 		ehci_work (ehci);
+	}
 	spin_unlock (&ehci->lock);
 	if (pcd_status)
 		usb_hcd_poll_rh_status(hcd);
@@ -884,6 +886,53 @@ static int ehci_urb_enqueue (
 	}
 }
 
+static void alan_debug(struct ehci_hcd *ehci, struct urb *urb, struct ehci_qh *qh)
+{
+	static int done;
+	struct ehci_qh *qh2;
+	struct ehci_qtd *td;
+	char label[24];
+
+	if (done)
+		return;
+	if (urb->transfer_buffer_length != 31) {
+		ehci_dbg(ehci, "unlink urb len %d\n", urb->transfer_buffer_length);
+		return;
+	}
+
+	ehci->alan_urb = urb;
+	done = 1;
+	ehci_dbg(ehci, "alan start  cur time %lu last scan %lu\n",
+		jiffies, ehci->last_scan_time);
+	ehci_dbg(ehci, "command %x cmd reg %x io watchdog %d async count %d\n",
+		ehci->command, ehci_readl(ehci, &ehci->regs->command),
+		ehci->need_io_watchdog, ehci->async_count);
+
+	ehci_dbg(ehci, "async list:\n");
+	qh2 = ehci->async;
+	while (qh2) {
+		ehci_dbg(ehci, " qh %p hw %p dma %x next %p hw_next %x\n",
+			qh2, qh2->hw, (u32) qh2->qh_dma, qh2->qh_next.qh,
+			hc32_to_cpu(ehci, qh2->hw->hw_next));
+		qh2 = qh2->qh_next.qh;
+	}
+
+	ehci_dbg(ehci, "This qh link time %lu enqueue time %lu td token %x ov token %x\n",
+		qh->link_time, qh->enqueue_time,
+		hc32_to_cpu(ehci, qh->tdtoken),
+		hc32_to_cpu(ehci, qh->ovtoken));
+	dbg_qh(" ", ehci, qh);
+
+	list_for_each_entry(td, &qh->qtd_list, qtd_list) {
+		sprintf(label, "  dma %x", (u32) td->qtd_dma);
+		dbg_qtd(label, ehci, td);
+	}
+
+	sprintf(label, "  dummy %x", (u32) qh->dummy->qtd_dma);
+	dbg_qtd(label, ehci, qh->dummy);
+}
+
+
 /* remove from hardware lists
  * completions normally happen asynchronously
  */
@@ -907,6 +956,10 @@ static int ehci_urb_dequeue(struct usb_h
 		qh = (struct ehci_qh *) urb->hcpriv;
 		if (!qh)
 			break;
+
+		if (usb_pipetype(urb->pipe) == PIPE_BULK)
+			alan_debug(ehci, urb, qh);
+
 		switch (qh->qh_state) {
 		case QH_STATE_LINKED:
 		case QH_STATE_COMPLETING:
Index: usb-3.7/drivers/usb/host/ehci.h
===================================================================
--- usb-3.7.orig/drivers/usb/host/ehci.h
+++ usb-3.7/drivers/usb/host/ehci.h
@@ -221,6 +221,10 @@ struct ehci_hcd {			/* one per controlle
 #ifdef DEBUG
 	struct dentry		*debug_dir;
 #endif
+
+	struct urb		*alan_urb;
+	unsigned long		last_scan_time;
+
 };
 
 /* convert between an HCD pointer and the corresponding EHCI_HCD */
@@ -400,6 +404,9 @@ struct ehci_qh {
 	struct usb_device	*dev;		/* access to TT */
 	unsigned		is_out:1;	/* bulk or intr OUT */
 	unsigned		clearing_tt:1;	/* Clear-TT-Buf in progress */
+
+	unsigned long		link_time, enqueue_time;
+	__hc32			tdtoken, ovtoken;
 };
 
 /*-------------------------------------------------------------------------*/
Index: usb-3.7/drivers/usb/host/ehci-q.c
===================================================================
--- usb-3.7.orig/drivers/usb/host/ehci-q.c
+++ usb-3.7/drivers/usb/host/ehci-q.c
@@ -291,6 +291,11 @@ __acquires(ehci->lock)
 	/* complete() can reenter this HCD */
 	usb_hcd_unlink_urb_from_ep(ehci_to_hcd(ehci), urb);
 	spin_unlock (&ehci->lock);
+	if (urb == ehci->alan_urb) {
+		ehci->alan_urb = NULL;
+		ehci_dbg(ehci, "giveback urb %p actual %d\n", urb, urb->actual_length);
+		ehci_dbg(ehci, "alan end\n");
+	}
 	usb_hcd_giveback_urb(ehci_to_hcd(ehci), urb, status);
 	spin_lock (&ehci->lock);
 }
@@ -1002,6 +1007,7 @@ static void qh_link_async (struct ehci_h
 
 	/* clear halt and/or toggle; and maybe recover from silicon quirk */
 	qh_refresh(ehci, qh);
+	qh->link_time = jiffies;
 
 	/* splice right after start */
 	head = ehci->async;
@@ -1101,6 +1107,7 @@ static struct ehci_qh *qh_append_tds (
 			dummy->hw_token = token;
 
 			urb->hcpriv = qh;
+			qh->tdtoken = token;
 		}
 	}
 	return qh;
@@ -1154,8 +1161,11 @@ submit_async (
 	/* Control/bulk operations through TTs don't need scheduling,
 	 * the HC and TT handle it when the TT has a buffer ready.
 	 */
+	qh->enqueue_time = jiffies;
 	if (likely (qh->qh_state == QH_STATE_IDLE))
 		qh_link_async(ehci, qh);
+	qh->ovtoken = qh->hw->hw_token;
+
  done:
 	spin_unlock_irqrestore (&ehci->lock, flags);
 	if (unlikely (qh == NULL))

--
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