|
From: <gn...@is...> - 2004-06-10 15:35:14
|
The function usb_control_msg() in libusb can't seem to
handle control messages with recipient of zero. The errno
value returned is ENOENT (2). I traced it down to a
possible linux bug in the usb driver code. The endpoint
check in devio.c and function check_ctrlrecip() is where
the endpoint zero is rejected. I looked at kernels from
the 2.4.x and 2.6.x series. Can someone verify that this
is a valid USB request and that the driver is broken?
Thanx.
=======================================================
After open/claim with libusb, here's the calling function:
void
GetStatus(usb_dev_handle *devhandle, int which)
{
unsigned char gotdat[64];
int ret, index;
printf("Retrieving status for endpoint 0x%x... ", which);
// should work with 0x0 endpoint with fixed bug in linux
ret = usb_control_msg(devhandle,
USB_ENDPOINT_IN | USB_RECIP_ENDPOINT,
USB_REQ_GET_STATUS,
0, which, gotdat, 2, 1000);
if (ret > 0)
{
printf("\nStatus data: ");
for (index = 0; index < ret; index++)
printf("\t0x%x", gotdat[index]);
}
else if (ret < 0)
printf("\nUSB error code %d: %s\n", ret,
usb_strerror());
else
printf("\n");
printf("\n");
}
=======================================================
Here's the possible problem in the linux usb code with fix
in .....drivers/usb/devio.c:
static int check_ctrlrecip(struct dev_state *ps, unsigned int
requesttype, unsigned int index)
{
int ret;
if (USB_TYPE_VENDOR == (USB_TYPE_MASK & requesttype))
return 0;
switch (requesttype & USB_RECIP_MASK) {
case USB_RECIP_ENDPOINT:
#if 1
if ((index & ~USB_ENDPOINT_DIR_MASK) == 0) /* ep 0 OK
for control */
break;
#endif
if ((ret = findintfep(ps->dev, index & 0xff)) < 0)
return ret;
if ((ret = checkintf(ps, ret)))
return ret;
break;
case USB_RECIP_INTERFACE:
if ((ret = findintfif(ps->dev, index & 0xff)) < 0)
return ret;
if ((ret = checkintf(ps, ret)))
return ret;
break;
}
return 0;
}
|