USB serial device support
PATCH 1/1 USB serial device support
Add in usb serial pass through support, based on the current usb-linux.c.
Jason.
From: Jason Wessel <[email protected]>
Subject: [PATCH] USB serial device support
Add in a workaround to allow the usb serial devices to work with the usb pass through mechanism. The ioctl() to request an alternate interface will always return < 0 for a usb-serial device based on the kernel driver. This means there is no alternate interface end point.
This was fully tested with a pl2303 usb serial device.
--- usb-linux.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
usb-linux.c +1 -2
@@ -840,8 +840,7 @@ static int usb_linux_update_endp_table(U ret =ioctl (s->fd,USBDEVFS_CONTROL , &ct);if (ret <0 ) { -perror ("usb_linux_update_endp_table" ); -return 1 ; + alt_interface = interface; }/* the current interface descriptor is the active interface
Quoted 2 lines · Jason Wessel
Add in usb serial pass through support, based on the current
usb-linux.c.
Can you explain why this allows usb serial pass through support? It is not at all obvious from the patch.
Regards,
Anthony Liguori
Quoted 2 lines
Jason.
Quoted 7 lines · Anthony Liguori
Quoted 2 lines · Jason Wessel
Add in usb serial pass through support, based on the current
usb-linux.c.Can you explain why this allows usb serial pass through support? It is not at all obvious from the patch.
The patch header included the description of what causes it to work. The ioctl call qemu uses to the host linux kernel will always return less than 0 for the 3 different usb serial devices I tried.
Quoted 1 line
From QEMU's
usb-linux.c, the ioctl is setup with:
833 ct.bRequestType = USB_DIR_IN | USB_RECIP_INTERFACE;
834 ct.bRequest = USB_REQ_GET_INTERFACE;
...
841 ret = ioctl(s->fd, USBDEVFS_CONTROL, &ct);On the host kernel this request translates into a call to the usb high level code in linux-2.6/drivers/usb/core/devio.c in the function usdev_ioctl(). The request for information is formed into a URB and sent to the device. The device itself is responding that the request is not supported. If you turn on the USB core debug printk's in the kernel you get the following message in response to the user space ioctl:
usb 1-2: usbfs: USBDEVFS_CONTROL failed cmd qemu rqt 129 rq 10 len 1 ret -110
As an experiment, I even tried this ioctl against qemu's FTDI usb serial simulated device with the same result. The ioctl request can be made to succeed against qemu's simulated device by changing the request type from
833 ct.bRequestType = USB_DIR_IN | USB_RECIP_INTERFACE;
To:
833 ct.bRequestType = USB_DIR_IN | USB_RECIP_DEVICE;
It is important to note that even with the change above that this request still fails on the "real hardware", because the "real hardware" does not implement a response to either request type.
The patch I provided was simply to implement a fall back to assign the alternate interface number to be the same as the primary interface obtained from the /sys information. The only other approach would be to find an other ioctl request that actually succeeds for these serial devices which could be implemented as a fall back. I don't have any kind of documentation that states what type of request you can make to these type of devices to get "alternate interface" information via a usb control request, which leads me to believe the devices simply do not support it. Perhaps someone else out there has low level documentation that states how you might send a USB control request for this?
In the mean time, at least the usb serial devices work with the patch.
Jason.