Re: Trouble with D-Link hub.

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

 



On Fri, 15 May 2009, Karl Hiramoto wrote:

> Dave Higton wrote:
> > On Thursday May 14, Ethan wrote:
> >
> >   
> >> I'm having trouble with a 7-port, powered USB hub made by D-Link
> >> (model DUB-7).  The devices plugged into the hub seem to work fine for
> >> small transfers, but large transfers (such as to/from a scanner or
> >> usb-storage device) break something.  Once things are "broken" I see
> >> from the syslog that the bus is reset every few seconds.  It is not
> >> clear to me if any data moves at all between bus resets but it is very
> >> little if anything.  When the bus is in this state, all devices on the
> >> bus become inaccessible not just the one that was engaged in the
> >> transfer.  Removing and reinstalling the ehci_hcd and ohci_hcd modules
> >> seems to reset the bus and correct the problem until the next large
> >> transfer is initiated.
> >>
> >> I suspect the problem lies with the hub because all of the devices
> >> work fine when plugged directly into the computer or when plugged into
> >> a different brand hub.
> >>     
> >
> > I also have a DUB-7 that I use on RISC OS.  I noticed a long time ago
> > that most mass storage devices won't work through it, though they
> > work fine when connected directly to the computer.  I would be
> > interested in any insight that this thread might give me.
> >
> > Dave
> >   
> I thik this hub has the  philips ISP1521  chip in it..   It has only one 
> TT per port.   I've notitced if you have all high speed devices, it 
> seems to work.  If it stops working you have to unplug/plug it to reset it.
> 
> 
> I think windows has the same issue:
> http://www.techtalkz.com/microsoft-device-drivers/243707-usb-problem-when-using-philips-isp1521-based-hub.html

The problem described in that thread appears to be a genuine bug.  In 
short, ehci-hcd doesn't do a clear-TT-buffer when a low/full-speed 
async URB is unlinked.  When that happens the buffer remains busy 
indefinitely, and when all the buffers are busy the hub won't work 
right.

This patch may fix the problem.  I haven't tested it, so you guys will 
have to be the guinea pigs.  :-)

Dave B.: The patch makes a few significant changes.  Most notably, the
code for clearing the TT buffer no longer depends on QTD_STS_HALT, and
unlinked URBs no longer cause an early return.  It also doesn't depend
on status != -EPIPE; that seemed like an unnecessary optimization.  
It's more careful to run only for async endpoints (the old code only
checked for !Interrupt).  Last but not least, the test for QTD_STS_MMF
is changed to QTD_STS_STS -- the MMF value must have been a typo since
it applies only to periodic endpoints.

Alan Stern



Index: usb-2.6/drivers/usb/host/ehci-q.c
===================================================================
--- usb-2.6.orig/drivers/usb/host/ehci-q.c
+++ usb-2.6/drivers/usb/host/ehci-q.c
@@ -152,10 +152,6 @@ static int qtd_copy_status (
 	if (likely (QTD_PID (token) != 2))
 		urb->actual_length += length - QTD_LENGTH (token);
 
-	/* don't modify error codes */
-	if (unlikely(urb->unlinked))
-		return status;
-
 	/* force cleanup after short read; not always an error */
 	if (unlikely (IS_SHORT_READ (token)))
 		status = -EREMOTEIO;
@@ -195,30 +191,35 @@ static int qtd_copy_status (
 			usb_pipeendpoint (urb->pipe),
 			usb_pipein (urb->pipe) ? "in" : "out",
 			token, status);
+	}
 
-		/* if async CSPLIT failed, try cleaning out the TT buffer */
-		if (status != -EPIPE
-				&& urb->dev->tt
-				&& !usb_pipeint(urb->pipe)
-				&& ((token & QTD_STS_MMF) != 0
-					|| QTD_CERR(token) == 0)
-				&& (!ehci_is_TDI(ehci)
-			                || urb->dev->tt->hub !=
-					   ehci_to_hcd(ehci)->self.root_hub)) {
+	/* if async CSPLIT failed or an async URB was unlinked,
+	 * try cleaning out the TT buffer
+	 */
+	if (urb->dev->tt && (usb_pipecontrol(urb->pipe)
+				|| usb_pipebulk(urb->pipe))
+			&& ((token & QTD_STS_STS) != 0
+				|| QTD_CERR(token) == 0)
+			&& (!ehci_is_TDI(ehci)
+		                || urb->dev->tt->hub !=
+				   ehci_to_hcd(ehci)->self.root_hub)) {
 #ifdef DEBUG
-			struct usb_device *tt = urb->dev->tt->hub;
-			dev_dbg (&tt->dev,
-				"clear tt buffer port %d, a%d ep%d t%08x\n",
-				urb->dev->ttport, urb->dev->devnum,
-				usb_pipeendpoint (urb->pipe), token);
+		struct usb_device *tt = urb->dev->tt->hub;
+		dev_dbg(&tt->dev,
+			"clear tt buffer port %d, a%d ep%d t%08x\n",
+			urb->dev->ttport, urb->dev->devnum,
+			usb_pipeendpoint(urb->pipe), token);
 #endif /* DEBUG */
-			/* REVISIT ARC-derived cores don't clear the root
-			 * hub TT buffer in this way...
-			 */
-			usb_hub_tt_clear_buffer (urb->dev, urb->pipe);
-		}
+		/* REVISIT ARC-derived cores don't clear the root
+		 * hub TT buffer in this way...
+		 */
+		usb_hub_tt_clear_buffer(urb->dev, urb->pipe);
 	}
 
+	/* For unlinked URBs, don't change the unlink error code */
+	if (unlikely(urb->unlinked))
+		status = -EINPROGRESS;
+
 	return status;
 }
 

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