On Fri, 23 Jul 2004 [EMAIL PROTECTED] wrote:
> Dears,
> May be a new challenge for you the USB Gurus :-).
>
> I just acquired a Camcorder Sony DCR-HC40(E).
> I use a Mandrake 10.0 with an upgraded kernel 2.6.7.
> I can capture the video stream from the IEEE1394 on my desktop. No problem.
> On my laptop, I only have a USB port and I would like also to catch the 'live
> video stream' from its USB port (not the pictures saved on the memory stick. I
> can already do that thanks to Leon and Stephen). It is feasable under Wins....I
> would like to make it work on my favorite OS :-).
> Any advice ? Any more details I could provide ?
> Thanks to all of you for your support,
>
> Luc
>From your log messages, it looks like your camcorder is one of those
devices that wants to be initialized (that is, have its address assigned
and be enumerated) the way Windows does it, not the way Linux does. Other
people have run into the same sort of problem with digital cameras.
Here is an experimental patch for 2.6.7. It changes the hub driver so
that on the second attempt to initialize a device it will use the Windows
strategy. Please let us know what happens and provide a USB trace log.
Alan Stern
--- 2.6.7/drivers/usb/core/hub.c.orig Fri Jul 23 15:46:02 2004
+++ 2.6.7/drivers/usb/core/hub.c Fri Jul 23 15:48:54 2004
@@ -1342,6 +1342,7 @@
int i, j, retval;
unsigned delay = HUB_SHORT_RESET_TIME;
enum usb_device_speed oldspeed = udev->speed;
+ int get_descriptor_first = 0;
/* root hub ports have a slightly longer reset period
* (from USB 2.0 spec, section 7.1.7.5)
@@ -1376,19 +1377,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",
@@ -1413,17 +1413,60 @@
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;
+ usb_endpoint_running(udev, 0, 1);
+ usb_endpoint_running(udev, 0, 0);
/* 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 the bMaxPacketSize0 field
+ * is initially set to 1 we will get the descriptor first,
+ * using a 64-byte transfer request. This is what Windows does,
+ * so it may help with some non-standards-compliant devices.
*/
- 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 (udev->descriptor.bMaxPacketSize0 < 8) {
+ retval = -EMSGSIZE;
+ continue;
+ }
+ }
+
for (j = 0; j < SET_ADDRESS_TRIES; ++j) {
retval = hub_set_address(udev);
if (retval >= 0)
@@ -1442,10 +1485,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",
@@ -1619,6 +1664,7 @@
}
/* reset and get descriptor */
+ udev->descriptor.bMaxPacketSize0 = (i & 1);
status = hub_port_init(hdev, udev, port);
if (status < 0)
goto loop;
-------------------------------------------------------
This SF.Net email is sponsored by BEA Weblogic Workshop
FREE Java Enterprise J2EE developer tools!
Get your free copy of BEA WebLogic Workshop 8.1 today.
http://ads.osdn.com/?ad_id=4721&alloc_id=10040&op=click
_______________________________________________
[EMAIL PROTECTED]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-users