Dne 13. 05. 21 v 15:29 Pavel Hofman napsal(a):
Dne 07. 05. 21 v 10:50 Jaroslav Kysela napsal(a):
Dne 07. 05. 21 v 10:37 Pavel Hofman napsal(a):
Hi,
The X-Fi USB HD device (and likely the similar 5.1 model too) can run at USB1.1 (with limited samplerates) and USB2 modes (with full specs). In linux the device stays at USB1.1. If connected to Windows with stock windows USB driver the same happens. However, when the Creative proprietary driver is installed, the device switches to USB2 and supports all features. When rebooting to linux without re-plugging, the USB2 mode stays and the device offers its USB2 configurations to snd-usb-audio.
We captured USB packets in linux and Win7 with wireshark - both dumps are included. The windows dump shows that in windows as well as in linux the device starts as device 3.5.0 at USB1.1:
DEVICE DESCRIPTOR bLength: 18 bDescriptorType: 0x01 (DEVICE) bcdUSB: 0x0110 bDeviceClass: Device (0x00) bDeviceSubClass: 0 bDeviceProtocol: 0 (Use class code info from Interface Descriptors) bMaxPacketSize0: 64 idVendor: Creative Technology, Ltd (0x041e) idProduct: Unknown (0x30d7) bcdDevice: 0x0100 iManufacturer: 1 iProduct: 2 iSerialNumber: 3 bNumConfigurations: 1
After USB1.1 enumeration, the windows host controlled by the vendor driver sends a request USR_FUNCTION_ABORT_PIPE to EP IN 6:
The EP IN 6 descriptor (from USB1.1 configuration):
ENDPOINT DESCRIPTOR bLength: 7 bDescriptorType: 0x05 (ENDPOINT) bEndpointAddress: 0x86 IN Endpoint:6 1... .... = Direction: IN Endpoint .... 0110 = Endpoint Number: 0x6 bmAttributes: 0x03 .... ..11 = Transfertype: Interrupt-Transfer (0x3) wMaxPacketSize: 64 ...0 0... .... .... = Transactions per microframe: 1 (0) .... ..00 0100 0000 = Maximum Packet Size: 64 bInterval: 1
The request sent by the host is: USB URB [Source: host] [Destination: 3.5.6] USBPcap pseudoheader length: 27 IRP ID: 0xfffffa80073ee120 IRP USBD_STATUS: USBD_STATUS_SUCCESS (0x00000000) URB Function: URB_FUNCTION_ABORT_PIPE (0x0002) IRP information: 0x00, Direction: FDO -> PDO URB bus id: 3 Device address: 5 Endpoint: 0x86, Direction: IN URB transfer type: USB IRP Info (0xfe) Packet Data Length: 0
The device responds with a proprietary response, with a different source 3.5.127: USB URB [Source: 3.5.127] [Destination: host] USBPcap pseudoheader length: 27 IRP ID: 0xfffffa80073ee120 IRP USBD_STATUS: USBD_STATUS_SUCCESS (0x00000000) URB Function: URB_FUNCTION_ABORT_PIPE (0x0002) IRP information: 0x01, Direction: PDO -> FDO 0000 000. = Reserved: 0x00 .... ...1 = Direction: PDO -> FDO (0x1) URB bus id: 3 Device address: 5 Endpoint: 0xff, Direction: IN 1... .... = Direction: IN (1) .... 1111 = Endpoint number: 15 URB transfer type: Unknown (0xff) [Expert Info (Error/Malformed): USBPcap did not recognize URB Function code (report to desowin.org/USBPcap)] [USBPcap did not recognize URB Function code (report to desowin.org/USBPcap)] [Severity level: Error] [Group: Malformed] Packet Data Length: 0
Immediately after that the device re-connects as 3.6.0 and reports its USB2.0 description:
DEVICE DESCRIPTOR bLength: 18 bDescriptorType: 0x01 (DEVICE) bcdUSB: 0x0200 bDeviceClass: Device (0x00) bDeviceSubClass: 0 bDeviceProtocol: 0 (Use class code info from Interface Descriptors) bMaxPacketSize0: 64 idVendor: Creative Technology, Ltd (0x041e) idProduct: Unknown (0x30d7) bcdDevice: 0x0100 iManufacturer: 1 iProduct: 2 iSerialNumber: 3 bNumConfigurations: 1
This is a regular USB-audio device which works OK in snd-usb-audio, as tested after rebooting from windows to linux.
Please is there any similar case handled by the existing alsa usb driver which we could try to modify and test? My USB skills are not up to writing the required code myself from scratch, unfortunately.
The switch can be probably implemented in the user space (libusb + udev rules). There is something similar for modems (usb_modeswitch).
Jaroslav
Thank you for your useful suggestion. I am trying to send the command from userspace with pyusb. I can write/read from the given EP, but honestly, my knowledge of USB details is very poor. I found a discussion about MS Windows URB_FUNCTION_ABORT_PIPE which presumably is not available in linux kernel directly, but as usb_clear_halt() https://linux-usb-devel.narkive.com/jkl4OpsE/urb-function-abort-pipe . But here I am in user space.
Please what should be the steps in emulating the above captured USB? Just some quazi-code would suffice, I will find a way to send it from userspace.
Thank you very much for any help.
I'm also not an USB expert, but is seems that URB_FUNCTION_ABORT_PIPE is used only internally in the windows driver to clear all pending URBs to EP and does not do any USB traffic:
https://libusb-devel.narkive.com/H4rdKA67/how-to-generate-an-abort-pipe-and-...
So it seems that some other information is missing for the device mode switch.
Jaroslav