Closed mpictor closed 6 years ago
Note that the failure I'm seeing even happens if the labrador is the only thing on the hub.
lsusb
output:
Bus 001 Device 021: ID 03eb:ba94 Atmel Corp.
Bus 001 Device 002: ID 0424:2514 Standard Microsystems Corp. USB 2.0 Hub
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
lsusb -t
/: Bus 01.Port 1: Dev 1, Class=root_hub, Driver=ehci-pci/5p, 480M
|__ Port 2: Dev 2, If 0, Class=Hub, Driver=hub/4p, 480M
|__ Port 3: Dev 21, If 0, Class=Vendor Specific Class, Driver=, 12M
This hub is built into a Dell monitor (ought to be decent quality) and I've never had trouble with it in the past.
Hi Mark. I fixed the problem with the thread termination a few months back. See commit here: https://github.com/EspoTek/Labrador/commit/0d66cb870bef4a59adcf2fa2b571a6000d2f6f1c You were right about QThread::Terminate. I should not have used that method.
Regarding your idea to notify the user directly of submiturb issues, that's a fantastic idea and something I'll definitely implement over the coming week. I think it would be better to use a qMessageBox rather than qDebugs, though, as that way the users would notice the messages straight away.
As for why Labrador is not working on that one particular hub, I honestly can't explain it. Looking at your lsusb -t output, it should work perfectly in theory. Possibly a quirk with that particular hub; maybe 12Mbit/s isochronous devices are not supported on Linux?
Ok, I'll switch to a version with thread termination fixed. I'd originally been using HEAD but thought I'd try a tagged version in the hopes my issue was not present.
A message box would certainly be a better idea, when I threw my solution together I wasn't trying for something polished :)
I've attached a zip with a pair of wireshark usb captures, one from a successful connection and one that failed. In both cases, I started the UI then plugged the board in. labrador-wireshark.zip
For these captures, I used HEAD (ca86c1da0a39c56) with my exit-on-urb-error patch, so in the failed session the app sends no more traffic after that initialization fails. There's also a patch for a missing function i2cDecoder::dataByteCompleted()
- just to get it to compile - but that shouldn't affect the packet capture.
Verbose lsusb output. Not sure whether the Resource temporarily unavailable
lines are significant or not; re-running as root doesn't make them go away.
$ lsusb -v -s 1:
Bus 001 Device 031: ID 03eb:ba94 Atmel Corp.
Device Descriptor:
bLength 18
bDescriptorType 1
bcdUSB 2.00
bDeviceClass 0
bDeviceSubClass 0
bDeviceProtocol 0
bMaxPacketSize0 64
idVendor 0x03eb Atmel Corp.
idProduct 0xba94
bcdDevice 2.00
iManufacturer 1 EspoTek
iProduct 2 Labrador
iSerial 0
bNumConfigurations 1
Configuration Descriptor:
bLength 9
bDescriptorType 2
wTotalLength 25
bNumInterfaces 1
bConfigurationValue 1
iConfiguration 0
bmAttributes 0x80
(Bus Powered)
MaxPower 500mA
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 0
bAlternateSetting 0
bNumEndpoints 1
bInterfaceClass 255 Vendor Specific Class
bInterfaceSubClass 255 Vendor Specific Subclass
bInterfaceProtocol 255 Vendor Specific Protocol
iInterface 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x81 EP 1 IN
bmAttributes 1
Transfer Type Isochronous
Synch Type None
Usage Type Data
wMaxPacketSize 0x03ff 1x 1023 bytes
bInterval 1
can't get device qualifier: Resource temporarily unavailable
can't get debug descriptor: Resource temporarily unavailable
Device Status: 0x0000
(Bus Powered)
Bus 001 Device 002: ID 0424:2514 Standard Microsystems Corp. USB 2.0 Hub
Device Descriptor:
bLength 18
bDescriptorType 1
bcdUSB 2.00
bDeviceClass 9 Hub
bDeviceSubClass 0
bDeviceProtocol 2 TT per port
bMaxPacketSize0 64
idVendor 0x0424 Standard Microsystems Corp.
idProduct 0x2514 USB 2.0 Hub
bcdDevice b.b3
iManufacturer 0
iProduct 0
iSerial 0
bNumConfigurations 1
Configuration Descriptor:
bLength 9
bDescriptorType 2
wTotalLength 41
bNumInterfaces 1
bConfigurationValue 1
iConfiguration 0
bmAttributes 0xe0
Self Powered
Remote Wakeup
MaxPower 2mA
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 0
bAlternateSetting 0
bNumEndpoints 1
bInterfaceClass 9 Hub
bInterfaceSubClass 0
bInterfaceProtocol 1 Single TT
iInterface 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x81 EP 1 IN
bmAttributes 3
Transfer Type Interrupt
Synch Type None
Usage Type Data
wMaxPacketSize 0x0001 1x 1 bytes
bInterval 12
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 0
bAlternateSetting 1
bNumEndpoints 1
bInterfaceClass 9 Hub
bInterfaceSubClass 0
bInterfaceProtocol 2 TT per port
iInterface 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x81 EP 1 IN
bmAttributes 3
Transfer Type Interrupt
Synch Type None
Usage Type Data
wMaxPacketSize 0x0001 1x 1 bytes
bInterval 12
Hub Descriptor:
bLength 9
bDescriptorType 41
nNbrPorts 4
wHubCharacteristic 0x000d
Per-port power switching
Compound device
Per-port overcurrent protection
TT think time 8 FS bits
bPwrOn2PwrGood 50 * 2 milli seconds
bHubContrCurrent 1 milli Ampere
DeviceRemovable 0x02
PortPwrCtrlMask 0xff
Hub Port Status:
Port 1: 0000.0100 power
Port 2: 0000.0100 power
Port 3: 0000.0103 power enable connect
Port 4: 0000.0100 power
Device Qualifier (for other device speed):
bLength 10
bDescriptorType 6
bcdUSB 2.00
bDeviceClass 9 Hub
bDeviceSubClass 0
bDeviceProtocol 0 Full speed (or root) hub
bMaxPacketSize0 64
bNumConfigurations 1
can't get debug descriptor: Resource temporarily unavailable
Device Status: 0x0001
Self Powered
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Device Descriptor:
bLength 18
bDescriptorType 1
bcdUSB 2.00
bDeviceClass 9 Hub
bDeviceSubClass 0
bDeviceProtocol 0 Full speed (or root) hub
bMaxPacketSize0 64
idVendor 0x1d6b Linux Foundation
idProduct 0x0002 2.0 root hub
bcdDevice 4.14
iManufacturer 3 Linux 4.14.52-gentoo ehci_hcd
iProduct 2 EHCI Host Controller
iSerial 1 0000:00:12.2
bNumConfigurations 1
Configuration Descriptor:
bLength 9
bDescriptorType 2
wTotalLength 25
bNumInterfaces 1
bConfigurationValue 1
iConfiguration 0
bmAttributes 0xe0
Self Powered
Remote Wakeup
MaxPower 0mA
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 0
bAlternateSetting 0
bNumEndpoints 1
bInterfaceClass 9 Hub
bInterfaceSubClass 0
bInterfaceProtocol 0 Full speed (or root) hub
iInterface 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x81 EP 1 IN
bmAttributes 3
Transfer Type Interrupt
Synch Type None
Usage Type Data
wMaxPacketSize 0x0004 1x 4 bytes
bInterval 12
Hub Descriptor:
bLength 9
bDescriptorType 41
nNbrPorts 5
wHubCharacteristic 0x000a
No power switching (usb 1.0)
Per-port overcurrent protection
bPwrOn2PwrGood 10 * 2 milli seconds
bHubContrCurrent 0 milli Ampere
DeviceRemovable 0x00
PortPwrCtrlMask 0xff
Hub Port Status:
Port 1: 0000.0100 power
Port 2: 0000.0503 highspeed power enable connect
Port 3: 0000.0100 power
Port 4: 0000.0100 power
Port 5: 0000.0100 power
can't get device qualifier: Resource temporarily unavailable
can't get debug descriptor: Resource temporarily unavailable
Device Status: 0x0001
Self Powered
Looked at the Wireshark traces. It's definitely a bandwidth related issue. ENOSPC on (only) the Isochronous endpoint pretty much confirms this. As to why this is happening, I'm not sure. It's definitely transmitting upstream at at least 480MBps (note the timings; they're occuring at intervals <1ms) and if nothing else is connected then this should not cause any problems.
Unless, of course, there's some kind of bug in (the driver for) that particular USB hub?
How good are you at kernel hacking? :)
How good are you at kernel hacking?
I've ported an NDIS filter driver from windows to linux, so could be worse ;)
I think the problem would be finding time, and/or finding a machine I can reboot frequently enough; I like my desktop to stay up for long periods without reboot.
It looks to me like all usb hubs use the same driver, hub.c/hub.h, which is >5k lines. Fixing this is not important enough to make me commit to digging into the driver, when I can instead plug into a slightly less convenient port :)
Hahaha, my thoughts exactly. The rabbit hole is just too deep. I'll keep this issue open until I have a notification for submiturb failure.
This has been implemented in the latest patch.
using e957460134d984 which is tagged v1.0 and 1.1, on amd64 linux:
The software consistently failed to communicate with my labrador when it was plugged into one port, though in the UI the only indication of this that I noticed was that the scope graph didn't show anything and calibration would always fail.
stdout/stderr, however, did include this text:
Once I read that the unit reserved all bandwidth, I switched to another port and it's working. However there should be a better indication that something's wrong.
One crude method of providing such an indication:
This also adds an unrelated debug statement, as I was seeing crashes on re-init. The QT docs make it sound like a very bad idea to ever use
QTThread::terminate()
.