Failed control transfer
- Reply: Hans Petter Selasky : "Re: Failed control transfer"
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Tue, 11 Oct 2022 04:18:57 UTC
Hi,
I am trying to fix a bug in xc3sprog whereby it can't read the hardware ID (serial number) from the Xilinx programming tool.
It works fine on MacOS and Linux but on FreBSD it fails with ENODEV, eg..
In [1]: import usb.core
In [2]: d = usb.core.find(idVendor = 0x03fd, idProduct = 0x0008)
In [4]: d.ctrl_transfer(0xc0, 176, 0x42, 0, 8, 1000)
---------------------------------------------------------------------------
USBError Traceback (most recent call last)
<snip>
USBError: [Errno 19] No device
Other control commands work fine:
In [5]: d.ctrl_transfer(0xc0, 176, 0x50, 258, 2, 100)
Out[5]: array('B', [5, 0])
On MacOS it looks like:
In [4]: d.ctrl_transfer(0xc0, 176, 0x42, 0, 8, 1000)
Out[4]: array('B', [1, 191, 125, 103, 18, 0, 0, 140])
(I did the tests in Python as it's easier for isolation)
Also, the device works fine for programming FPGAs and the like so it seems quite peculiar that only this command fails.
I had a dig through the USB kernel stack and libusb code (the Python code is using libusb.so.3 FWIW) but I could not find anywhere relevant that set errno to ENODEV.
Output of sudo usbdump -d 0.4 -s 65535 -v -v:
04:15:17.243800 usbus0.4 SUBM-CTRL-EP=00000080,SPD=HIGH,NFR=2,SLEN=8,IVAL=0
frame[0] WRITE 8 bytes
0000 C0 B0 42 00 00 00 08 00 -- -- -- -- -- -- -- -- |..B..... |
frame[1] READ 8 bytes
flags 0x2 <SHORT_XFER_OK|0>
04:15:17.246029 usbus0.4 DONE-CTRL-EP=00000080,SPD=HIGH,NFR=2,SLEN=0,IVAL=0,ERR=STALLED
frame[0] WRITE 8 bytes
frame[1] READ 0 bytes
flags 0x2 <SHORT_XFER_OK|0>
I ran usbmon on Linux and this is the Wireshark output of the request:
Frame 13: 64 bytes on wire (512 bits), 64 bytes captured (512 bits)
USB URB
[Source: host]
[Destination: 1.5.0]
URB id: 0xffff9d9103b47440
URB type: URB_SUBMIT ('S')
URB transfer type: URB_CONTROL (0x02)
Endpoint: 0x80, Direction: IN
Device: 5
URB bus id: 1
Device setup request: relevant ('\0')
Data: not present ('<')
URB sec: 1665455649
URB usec: 867346
URB status: Operation now in progress (-EINPROGRESS) (-115)
URB length [bytes]: 8
Data length [bytes]: 0
[Response in: 14]
Interval: 0
Start frame: 0
Copy of Transfer Flags: 0x00000200, Dir IN
Number of ISO descriptors: 0
[bInterfaceClass: Unknown (0xffff)]
Setup Data
bmRequestType: 0xc0
bRequest: 176
wValue: 0x0042
wIndex: 0 (0x0000)
wLength: 8
And the reply:
Frame 14: 72 bytes on wire (576 bits), 72 bytes captured (576 bits)
USB URB
[Source: 1.5.0]
[Destination: host]
URB id: 0xffff9d9103b47440
URB type: URB_COMPLETE ('C')
URB transfer type: URB_CONTROL (0x02)
Endpoint: 0x80, Direction: IN
Device: 5
URB bus id: 1
Device setup request: not relevant ('-')
Data: present ('\0')
URB sec: 1665455649
URB usec: 879077
URB status: Success (0)
URB length [bytes]: 8
Data length [bytes]: 8
[Request in: 13]
[Time from request: 0.011731000 seconds]
Unused Setup Header
Interval: 0
Start frame: 0
Copy of Transfer Flags: 0x00000200, Dir IN
Number of ISO descriptors: 0
[bInterfaceClass: Unknown (0xffff)]
CONTROL response data: 01bf7d671200008c
Unfortunately I can't find any reason why it works on MacOS and Linux but not FreeBSD.. Does anyone have any suggestions?
Thanks.
--
Daniel O'Connor
"The nice thing about standards is that there
are so many of them to choose from."
-- Andrew Tanenbaum