On Sun, 3 Oct 2004, Marr wrote:
> Til,
>
> There was a thread ('USB stream from camcorder Sony DCR-HC40(E)') on this list
> which began on 23 Jul 2004 that sounds a lot like your problem.
>
> When I first saw that thread, I tried to stream live video over my Sony
> DCR-TRV38 camcorder's USB port (under Slackware 9.1, 2.4.22 kernel) but had
> no luck at all. My camcorder never showed up in the 'cat /proc/bus/usb/
> devices' list, just like yours and just like Luc Dijon's (see below).
>
> Unfortunately, that thread seemed to die out after a partial success based
> upon a patch from Alan Stern. Here's some of the exchange that took place:
> Since you're using a recent kernel, I'm guessing Alan's patch is not in the
> latest kernel(s).
>
> Alan... Any more thoughts on this topic? Did that thread just sort of die out?
> Did any patch ever make it into the kernel? I greatly appreciate any input
> you might have.
I never followed through on that patch. But now I've picked it up again;
here's a new version updated for 2.6.8.1. Tell me how it works out.
Kyle, this is pretty much the same as before. Those usb_disable_endpoint
calls are still there because they are necessary; at some point you will
have to make it work with your HCD because it gets called every time a USB
device is unplugged. Also, I left the default scheme first and made the
Microsoft-type scheme the second choice.
Alan Stern
--- 2.6.8.1/drivers/usb/core/hub.c.orig 2004-10-04 15:39:26.000000000 -0400
+++ 2.6.8.1/drivers/usb/core/hub.c 2004-10-04 16:02:20.000000000 -0400
@@ -1127,7 +1127,7 @@
#define PORT_RESET_TRIES 5
#define SET_ADDRESS_TRIES 2
#define GET_DESCRIPTOR_TRIES 2
-#define SET_CONFIG_TRIES 2
+#define SET_CONFIG_TRIES 4
#define HUB_ROOT_RESET_TIME 50 /* times are in msec */
#define HUB_SHORT_RESET_TIME 10
@@ -1352,7 +1352,8 @@
* pointers, it's not necessary to lock the device.
*/
static int
-hub_port_init (struct usb_device *hdev, struct usb_device *udev, int port)
+hub_port_init (struct usb_device *hdev, struct usb_device *udev, int port,
+ int get_descriptor_first)
{
static DECLARE_MUTEX(usb_address0_sem);
@@ -1387,6 +1388,7 @@
dev_dbg(&udev->dev, "device reset changed speed!\n");
goto fail;
}
+ oldspeed = udev->speed;
/* USB 2.0 section 5.5.3 talks about ep0 maxpacket ...
* it's fixed size except for full speed devices.
@@ -1396,19 +1398,18 @@
i = 64;
break;
case USB_SPEED_FULL: /* 8, 16, 32, or 64 */
- /* to determine the ep0 maxpacket size, read the first 8
- * bytes from the device descriptor to get bMaxPacketSize0;
- * then correct our initial (small) guess.
+ /* to determine the ep0 maxpacket size, try to read
+ * the device descriptor to get bMaxPacketSize0 and
+ * then correct our initial guess.
*/
- // FALLTHROUGH
+ i = 64;
+ break;
case USB_SPEED_LOW: /* fixed at 8 */
i = 8;
break;
default:
goto fail;
}
- udev->epmaxpacketin [0] = i;
- udev->epmaxpacketout[0] = i;
dev_info (&udev->dev,
"%s %s speed USB device using address %d\n",
@@ -1433,17 +1434,64 @@
udev->tt = &hub->tt;
udev->ttport = port + 1;
}
+
+ /* Clear out any stale HC state pertaining to device 0 endpoint 0 */
+ j = udev->devnum;
+ udev->devnum = 0;
+ usb_disable_endpoint(udev, 0 + USB_DIR_IN);
+ usb_disable_endpoint(udev, 0 + USB_DIR_OUT);
+ udev->devnum = j;
+ udev->epmaxpacketin [0] = i;
+ udev->epmaxpacketout[0] = i;
/* 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.
*
- * NOTE: Windows gets the descriptor first, seemingly to help
- * work around device bugs like "can't use addresses with bit 3
- * set in certain configurations". Yes, really.
+ * NOTE: For full-speed devices, if get_descriptor_first
+ * is set we will start by issuing a 64-byte GET_DESCRIPTOR
+ * request. This is what Windows does, so it may help with some
+ * non-standards-compliant devices. Otherwise we start with
+ * SET_ADDRESS and then try to read the first 8 bytes of the
+ * device descriptor to get the ep0 maxpacket value.
*/
- for (i = 0; i < GET_DESCRIPTOR_TRIES; ++i) {
+ if (udev->descriptor.bMaxPacketSize0 == 1)
+ get_descriptor_first = 1;
+
+ for (i = 0; i < GET_DESCRIPTOR_TRIES; (++i, msleep(100))) {
+ if (get_descriptor_first) {
+ struct usb_device_descriptor *buf;
+
+ buf = kmalloc(64, GFP_NOIO);
+ if (!buf) {
+ retval = -ENOMEM;
+ continue;
+ }
+ memset(buf, 0, 64);
+ (void) usb_control_msg(udev,
+ /* Address 0 */
+ (PIPE_CONTROL << 30) | USB_DIR_IN,
+ USB_REQ_GET_DESCRIPTOR, USB_DIR_IN,
+ USB_DT_DEVICE << 8, 0,
+ buf, 64,
+ HZ * USB_CTRL_GET_TIMEOUT);
+ udev->descriptor = *buf;
+ kfree(buf);
+
+ retval = hub_port_reset(hdev, port, udev, delay);
+ if (retval < 0) /* error or disconnect */
+ goto fail;
+ if (oldspeed != udev->speed) {
+ retval = -ENODEV;
+ goto fail;
+ }
+ if (udev->descriptor.bMaxPacketSize0 < 8) {
+ retval = -EMSGSIZE;
+ continue;
+ }
+ }
+
for (j = 0; j < SET_ADDRESS_TRIES; ++j) {
retval = hub_set_address(udev);
if (retval >= 0)
@@ -1462,10 +1510,12 @@
* - read ep0 maxpacket even for high and low speed,
*/
msleep(10);
- retval = usb_get_device_descriptor(udev, 8);
+ if (get_descriptor_first)
+ retval = 8;
+ else
+ retval = usb_get_device_descriptor(udev, 8);
if (retval >= 8)
break;
- msleep(100);
}
if (retval != 8) {
dev_err(&udev->dev, "device descriptor read/%s, error %d\n",
@@ -1645,7 +1695,7 @@
}
/* reset and get descriptor */
- status = hub_port_init(hdev, udev, port);
+ status = hub_port_init(hdev, udev, port, (i >= 2));
if (status < 0)
goto loop;
@@ -2060,7 +2110,7 @@
{
struct usb_device *parent = udev->parent;
struct usb_device_descriptor descriptor = udev->descriptor;
- int i, ret, port = -1;
+ int i, ret = 0, port = -1;
struct usb_hub *hub;
if (udev->state == USB_STATE_NOTATTACHED ||
@@ -2092,7 +2142,11 @@
return -ENOENT;
}
- ret = hub_port_init(parent, udev, port);
+ for (i = 0; i < SET_CONFIG_TRIES; ++i) {
+ ret = hub_port_init(parent, udev, port, (i >= 2));
+ if (ret >= 0)
+ break;
+ }
if (ret < 0)
goto re_enumerate;
-------------------------------------------------------
This SF.net email is sponsored by: IT Product Guide on ITManagersJournal
Use IT products in your business? Tell us what you think of them. Give us
Your Opinions, Get Free ThinkGeek Gift Certificates! Click to find out more
http://productguide.itmanagersjournal.com/guidepromo.tmpl
_______________________________________________
[EMAIL PROTECTED]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-users