Google
  Web www.spinics.net

Re: 2.6.23.11 : ehci not working with a710 camera

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


On Sunday 16 December 2007, David Brownell wrote:
> > When I plug the camera I got [1]. When I plug a pendrive i got [3].
> > When I plug the camera on another port I got [2].
> 
> (Appended text is slightly edited to remove line wraps.)
> 
> Summary:  [1] failed, but [2] and [3] worked.
> 
> 
> > Could it be an hadware problem on the port. But then why it works with 
> > the pen drive ?
> 
> Clearly there is *some* difference at the hardware level.  Different
> devices (even of the same make/model) have different characteristics.
> So do different host ports and cables.  I'd try using different cables
> with that camera, to start with.
> 
> But I don't like blaming this on hardware, since I still recall that
> these problems started to crop up sometime in the 2.6.5 to 2.6.10 time
> frame ... making me suspect changes that were made in that period were
> a bit less hardware-friendly than before.
> 
> I'm going to dust off some old patches and send you one to try...

Here's that patch.  Please give it at try with USB_DEBUG enabled.
Note that the patch has two behavioral changes -- avoid the "what
maxpacket should I use?" dance that's not needed, and use a longer
delay at one point -- plus a diagnostic change to make EHCI report
what control transfers are making trouble.

We should at least be able to find out just what calls are making
the trouble (and at what point in the sequence), even if the behavior
changes don't help.  :)

- Dave


================
EXPERIMENTAL ...

 * During enumeration, only full speed USB devices need the "ask for
   partial descriptor, then reset" dance to get the maxpacket size for
   ep0.  Don't dance except with those devices.

 * Allow a bit more time for devices to recover after SET_ADDRESS.

 * When debugging, dump ep0 status for EHCI so we can find out which
   highspeed calls are borked in one hardware config

---
 drivers/usb/core/hub.c    |   39 +++++++++++++++++++++++++++------------
 drivers/usb/host/ehci-q.c |    3 ++-
 2 files changed, 29 insertions(+), 13 deletions(-)

--- g26.orig/drivers/usb/core/hub.c	2007-12-16 11:32:09.000000000 -0800
+++ g26/drivers/usb/core/hub.c	2007-12-16 12:39:00.000000000 -0800
@@ -2216,9 +2216,11 @@ hub_port_init (struct usb_hub *hub, stru
 	 */
 	switch (udev->speed) {
 	case USB_SPEED_VARIABLE:	/* fixed at 512 */
+		udev->descriptor.bMaxPacketSize0 =
 		udev->ep0.desc.wMaxPacketSize = __constant_cpu_to_le16(512);
 		break;
 	case USB_SPEED_HIGH:		/* fixed at 64 */
+		udev->descriptor.bMaxPacketSize0 =
 		udev->ep0.desc.wMaxPacketSize = __constant_cpu_to_le16(64);
 		break;
 	case USB_SPEED_FULL:		/* 8, 16, 32, or 64 */
@@ -2229,12 +2231,13 @@ hub_port_init (struct usb_hub *hub, stru
 		udev->ep0.desc.wMaxPacketSize = __constant_cpu_to_le16(64);
 		break;
 	case USB_SPEED_LOW:		/* fixed at 8 */
+		udev->descriptor.bMaxPacketSize0 =
 		udev->ep0.desc.wMaxPacketSize = __constant_cpu_to_le16(8);
 		break;
 	default:
 		goto fail;
 	}
- 
+
 	type = "";
 	switch (udev->speed) {
 	case USB_SPEED_LOW:	speed = "low";	break;
@@ -2260,11 +2263,20 @@ hub_port_init (struct usb_hub *hub, stru
 		udev->tt = &hub->tt;
 		udev->ttport = port1;
 	}
- 
-	/* Why interleave GET_DESCRIPTOR and SET_ADDRESS this way?
-	 * Because device hardware and firmware is sometimes buggy in
-	 * this area, and this is how Linux has done it for ages.
-	 * Change it cautiously.
+
+	/* There are three tasks getting interleaved here:
+	 *  (a) for fullspeed, determine ep0 maxpacket;
+	 *  (b) set nonzero device address;
+	 *  (c) read the full device descriptor.
+	 *
+	 * Device hardware and firmware is sometimes buggy in this early
+	 * enumeration stage.  Change with caution; few devices get much
+	 * more testing here than "does windows work", so legal protocol
+	 * sequences may easily fail.  The "old" scheme is what Linux used
+	 * before about 2.6.8; the "new" one is used by later kernels and
+	 * works more like MS-Windows.  (Although now they've been modified
+	 * to understand that ep0 maxpacket is always known except for full
+	 * speed devices.)
 	 *
 	 * NOTE:  If USE_NEW_SCHEME() is true we will start by issuing
 	 * a 64-byte GET_DESCRIPTOR request.  This is what Windows does,
@@ -2274,7 +2286,8 @@ hub_port_init (struct usb_hub *hub, stru
 	 * value.
 	 */
 	for (i = 0; i < GET_DESCRIPTOR_TRIES; (++i, msleep(100))) {
-		if (USE_NEW_SCHEME(retry_counter)) {
+		if (USE_NEW_SCHEME(retry_counter)
+				&& !udev->descriptor.bMaxPacketSize0) {
 			struct usb_device_descriptor *buf;
 			int r = 0;
 
@@ -2307,6 +2320,7 @@ hub_port_init (struct usb_hub *hub, stru
 				default:
 					if (r == 0)
 						r = -EPROTO;
+					buf->bMaxPacketSize0 = 0;
 					break;
 				}
 				if (r == 0)
@@ -2347,13 +2361,14 @@ hub_port_init (struct usb_hub *hub, stru
 				devnum, retval);
 			goto fail;
 		}
- 
+
 		/* cope with hardware quirkiness:
 		 *  - let SET_ADDRESS settle, some device hardware wants it
-		 *  - read ep0 maxpacket even for high and low speed,
-  		 */
-		msleep(10);
-		if (USE_NEW_SCHEME(retry_counter))
+		 *  - read ep0 maxpacket iff needed
+		 */
+		msleep(50);
+		if (udev->descriptor.bMaxPacketSize0
+				|| USE_NEW_SCHEME(retry_counter))
 			break;
 
 		retval = usb_get_device_descriptor(udev, 8);
--- g26.orig/drivers/usb/host/ehci-q.c	2007-12-16 19:51:09.000000000 -0800
+++ g26/drivers/usb/host/ehci-q.c	2007-12-16 19:52:09.000000000 -0800
@@ -189,7 +189,8 @@ static int qtd_copy_status (
 		else	/* unknown */
 			status = -EPROTO;
 
-		ehci_vdbg (ehci,
+		if (usb_pipeendpoint(urb->pipe) == 0) ehci_dbg (ehci,
+		// ehci_vdbg (ehci,
 			"dev%d ep%d%s qtd token %08x --> status %d\n",
 			usb_pipedevice (urb->pipe),
 			usb_pipeendpoint (urb->pipe),

-------------------------------------------------------------------------
SF.Net email is sponsored by:
Check out the new SourceForge.net Marketplace.
It's the best place to buy or sell services
for just about anything Open Source.
http://ad.doubleclick.net/clk;164216239;13503038;w?http://sf.net/marketplace
_______________________________________________
linux-usb-devel@xxxxxxxxxxxxxxxxxxxxx
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel

[Home]     [Video for Linux]     [Photo]     [Yosemite Forum]     [Yosemite Photos]    [Video Projectors]     [PDAs]     [Hacking TiVo]     [Linux Kernel]     [Linux SCSI]     [XFree86]     [Devices]     [Big List of Linux Books]     [Free Dating]

  Powered by Linux