Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Fix bMaxPower conversion for USB 3 devices#479

Merged
jonasmalacofilho merged 3 commits intopyusb:masterfrom
andygoulden:fix-current
May 21, 2023
Merged

Fix bMaxPower conversion for USB 3 devices#479
jonasmalacofilho merged 3 commits intopyusb:masterfrom
andygoulden:fix-current

Conversation

@andygoulden
Copy link
Contributor

As per the 'FIXME' comment, the current value uses a different multiplier for USB 3 (ie superspeed) devices.

This change uses the USB version from bcdUSB to determine the correct multiplier.

usb/core.py Outdated


def _str(self):
power_multiplier = _lu.MAX_POWER_UNITS_USB_SUPERSPEED if ((self.device.bcdUSB & 0xff00)>>8) == 3 else _lu.MAX_POWER_UNITS_USB2p0
Copy link
Member

@jonasmalacofilho jonasmalacofilho May 19, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for looking into this.

I think we should first check self.device.speed (from libusb_get_device_speed), and only fallback to bcdUSB when that isn't available.

Also, I suggest replacing the mask and exact comparison with self.device.bcdUSB >= 0x0300.

Finally, the choice of multiplier is duplicated between this function and _get_full_descriptor_str, and non trivial; can you make sure it's only done in a single place?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for your feedback. I've pushed up a commit which addresses your comments - let me know what you think.

Changes:

* Put power multiplier calculation in its own function
* Try to use `self.device.speed` if available
* Compare bcdUSB directly rather than masking off the major version
usb/core.py Outdated

def _get_power_multiplier(self):
if self.device.speed is not None:
power_multiplier = _lu.MAX_POWER_UNITS_USB_SUPERSPEED if self.device.speed == 3 else _lu.MAX_POWER_UNITS_USB2p0
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
power_multiplier = _lu.MAX_POWER_UNITS_USB_SUPERSPEED if self.device.speed == 3 else _lu.MAX_POWER_UNITS_USB2p0
power_multiplier = _lu.MAX_POWER_UNITS_USB_SUPERSPEED if self.device.speed >= 4 else _lu.MAX_POWER_UNITS_USB2p0

libusb_supported_speed constants also form a bitmap, and LIBUSB_SUPER_SPEED_OPERATION has value 4, not 3.1

And while some future SuperDuperSpeed mode will likely change the bMaxPower multiplier again (to some value we can't predict), it might be a bit better to (mis)handle that future case as SuperSpeed, instead of <= HighSpeed.

Thanks again!

Footnotes

  1. https://github.com/libusb/libusb/blob/cc498ded18fb2c6e4506c546d0351c4ae91ef2cc/libusb/libusb.h#L498

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the suggestion - I've committed it. Is there anything else that you'd like me to change before it's pulled?

@jonasmalacofilho
Copy link
Member

Everything looks good to me now, merging...

Thanks again!

@jonasmalacofilho jonasmalacofilho merged commit 3ce8f38 into pyusb:master May 21, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants