You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Read common descriptors from sysfs, when available #458
Running Debian Linux 11 with Python 3.10 and libusb1. I am trying to connect to an LG UltraFine monitor via USB-C.
It works via lsusb (running as my user):
$ lsusb -D /dev/bus/usb/003/010
Device: ID 043e:9a39 LG Electronics USA, Inc. LG Monitor Controls
Couldn't open device, some information will be missing
Device Descriptor:
bLength 18
bDescriptorType 1
bcdUSB 2.00
bDeviceClass 239 Miscellaneous Device
bDeviceSubClass 2
bDeviceProtocol 1 Interface Association
bMaxPacketSize0 64
idVendor 0x043e LG Electronics USA, Inc.
idProduct 0x9a39
bcdDevice 4.11
iManufacturer 1 LG Electronics Inc.
iProduct 3 LG Monitor Controls
iSerial 4 107NTYTAD986
bNumConfigurations 1
fetching a descriptor like iManufacturer requires submitting a control transfer to the device;
and that, in turn, require suitable permissions, as specified by the corresponding kernel driver (in this case, usbfs).1
Regarding why lsusb seems to you to show a bit more information, that is because lsusb can try to use a few different ways to show you the manufacturer and similar infos: one of those is indeed just fetching the corresponding descriptor from the device, but it can also read that info from udev, or fallback to the USB IDs table. But PyUSB shouldn't be compared to lsusb; rather, it's something that can be used as building block to build something like lsusb (and, IIRC, the usbutils source code includes a PyUSB-based implementation).
Footnotes
Intuition about what should be a "read" or "write" operation can be tricky: it's necessary to consider how the USB protocol works, and how the kernel driver will decide to handle it, both for correctness and security. ↩
Well, as it seems, when you do cat /sys/bus/usb/devices/3-6.3/manufacturer you can also just read the information without write permissions from the kernel, without using usbfs and without using udev. Or who populates /sys/bus/usb?
Please send a patch/PR that implements this special case.
Or who populates /sys/bus/usb?
The Linux kernel, specifically the USB core. But I haven't checked whether they might be missing sometimes, you need to check that and handle any cases where they are present in the device, but somehow not in sysfs.
Well, if you're open to accepting a patch to fix this, I'd be willing to work on it. Can we reopen the ticket for this? It might take a bit as I am also busy with other stuff.
PS: I would probably not replace any existing logic but just whenever there is "Error Accessing String" do an extra step and try to find the string through /sys/bus/usb
Sounds pretty straight forward to me.
PS: I would probably not replace any existing logic but just whenever there is "Error Accessing String" do an extra step and try to find the string through /sys/bus/usb
Sounds pretty straight forward to me.
Actually, it should probably go in the Device.manufacturer and similar properties, not in Device.__str__ (which may then be reworked to use the new feature).
PyUSB is not a lsusb clone: sure, this feature will improve Device.__str__, but it's also necessary (and, arguably, more important) to make the data available for callers using PyUSB for something more than print(dev).
And the preference order should probably be: locally cached value > (on Linux:) sysfs value > GET_DESCRIPTOR transfer.
Activity
jonasmalacofilho commentedon Oct 2, 2022
Write permissions are required because:
iManufacturerrequires submitting a control transfer to the device;usbfs).1Regarding why lsusb seems to you to show a bit more information, that is because lsusb can try to use a few different ways to show you the manufacturer and similar infos: one of those is indeed just fetching the corresponding descriptor from the device, but it can also read that info from udev, or fallback to the USB IDs table. But PyUSB shouldn't be compared to lsusb; rather, it's something that can be used as building block to build something like lsusb (and, IIRC, the usbutils source code includes a PyUSB-based implementation).
Footnotes
Intuition about what should be a "read" or "write" operation can be tricky: it's necessary to consider how the USB protocol works, and how the kernel driver will decide to handle it, both for correctness and security. ↩
ronny-rentner commentedon Oct 4, 2022
Well, as it seems, when you do
cat /sys/bus/usb/devices/3-6.3/manufactureryou can also just read the information without write permissions from the kernel, without using usbfs and without using udev. Or who populates/sys/bus/usb?jonasmalacofilho commentedon Oct 4, 2022
Please send a patch/PR that implements this special case.
The Linux kernel, specifically the USB core. But I haven't checked whether they might be missing sometimes, you need to check that and handle any cases where they are present in the device, but somehow not in sysfs.
ronny-rentner commentedon Oct 5, 2022
Well, if you're open to accepting a patch to fix this, I'd be willing to work on it. Can we reopen the ticket for this? It might take a bit as I am also busy with other stuff.
ronny-rentner commentedon Oct 5, 2022
PS: I would probably not replace any existing logic but just whenever there is "Error Accessing String" do an extra step and try to find the string through /sys/bus/usb
Sounds pretty straight forward to me.
[-]Wrong permission error, "Error Accessing String"[/-][+]Read common descriptors from sysfs, when available[/+]jonasmalacofilho commentedon Oct 6, 2022
Done, but I also renamed for accuracy.
Actually, it should probably go in the
Device.manufacturerand similar properties, not inDevice.__str__(which may then be reworked to use the new feature).PyUSB is not a lsusb clone: sure, this feature will improve
Device.__str__, but it's also necessary (and, arguably, more important) to make the data available for callers using PyUSB for something more thanprint(dev).And the preference order should probably be: locally cached value > (on Linux:) sysfs value >
GET_DESCRIPTORtransfer.ronny-rentner commentedon Oct 9, 2022
Thanks for the direction, will do it like this.