Discussion:
[Libusbx-devel] [Released] PyUSB 1.0.0 beta 1
Wander Lairson Costa
2013-10-16 11:51:24 UTC
Permalink
Dear all,

I am proud to announce that PyUSB 1.0.0 beta is out.

What's new in PyUSB 1.0.0 (beta 1)?
-----------------------------------

* Isochronous transfer for libusb 1.0 (by David Halter).
* Experimental OpenUSB support.
* Documentation update.
* PYUSB_DEBUG_LEVEL environment variable is now called PYUSB_DEBUG.
* Legacy module nwo groups according to their bus.
* Version information available for apps (by Chris Clark).
* Faster read operation (by themperek).
* Tox support (by ponty).
* Support for port number info (by Stefano Di Martino).
* Several bug fixes (please, check the Changelog file).

Known issues
------------

* OpenUSB backend hangs on some control transfers.

TODO
----

* More tests with legacy module.
* Isochronous transfers for libusb-win32.

Download page
-------------

https://sourceforge.net/projects/pyusb/files/PyUSB%201.0/1.0.0-beta-1/

This release took much more time than I was expecting to, so I would like
to thank you all for your patience, and specially for those whose contributed
for this release.
--
Best Regards,
Wander Lairson Costa
Wander Lairson Costa
2013-10-29 14:16:51 UTC
Permalink
Hi,
Hi Johannes,
Post by Wander Lairson Costa
I am proud to announce that PyUSB 1.0.0 beta is out.
...
Post by Wander Lairson Costa
TODO
----
* More tests with legacy module.
* Isochronous transfers for libusb-win32.
Download page
-------------
https://sourceforge.net/projects/pyusb/files/PyUSB%201.0/1.0.0-beta-1/
This release took much more time than I was expecting to, so I would like
to thank you all for your patience, and specially for those whose contributed
for this release.
I've been using pyusb-1.0.0-a1.tar.gz some time back, and
the new beta release still works perfectly on Linux for
some ad-hoc testing.
One remark: The "Let's get it started" example in
cfg = dev.get_active_configuration()
interface_number = cfg[(0,0)].bInterfaceNumber
alternate_setting = usb.control.get_interface(dev, interface_number)
intf = usb.util.find_descriptor(
cfg, bInterfaceNumber = interface_number,
bAlternateSetting = alternate_setting
)
instead of just this:?
intf = cfg[(0,0)]
The code above finds the interface by its interface number, not its
index inside the configuration (they are not necessarily the same
thing).
Also, the code lacks an
intf.set_altsetting()
set_altsetting is only needed by device with alternate settings.
otherwise the EPs are not reset which might lead to errors
Stalled endpoints are not something expected in normal cases.
[2249737.372143] usb 1-1.1: usbfs: process 32478 (python) did not claim interface 0 before use
Interface claiming, in another hand, is handled internally by PyUSB,
this might be a bug.
I hope you can do the 1.0.0 final release soon and PyUSB 1.x will be picked
up by Linux distributions. Currently most seem to ship PyUSB 0.4, which
is a pity given the 1.0 API is so much better. It slso would be a good idea
to clearly state in the README that both Python 2.x and Python 3.x are supported.
I hope too.
--
Best Regards,
Wander Lairson Costa
Johannes Stezenbach
2013-10-29 14:33:45 UTC
Permalink
Post by Wander Lairson Costa
One remark: The "Let's get it started" example in
cfg = dev.get_active_configuration()
interface_number = cfg[(0,0)].bInterfaceNumber
alternate_setting = usb.control.get_interface(dev, interface_number)
intf = usb.util.find_descriptor(
cfg, bInterfaceNumber = interface_number,
bAlternateSetting = alternate_setting
)
instead of just this:?
intf = cfg[(0,0)]
The code above finds the interface by its interface number, not its
index inside the configuration (they are not necessarily the same
thing).
Well, I guess the intention is to show how to look up interface
by bInterfaceNumber, but if you take cfg[(0,0)].bInterfaceNumber
and look it up then you end with cfg[(0,0)], right?
Post by Wander Lairson Costa
Also, the code lacks an
intf.set_altsetting()
set_altsetting is only needed by device with alternate settings.
otherwise the EPs are not reset which might lead to errors
Stalled endpoints are not something expected in normal cases.
set_altsetting() is always required before using an interface since it
resets it into a known state. I mean the tutorial should just work
and not cause new users to wonder if pyusb is broken...
Post by Wander Lairson Costa
[2249737.372143] usb 1-1.1: usbfs: process 32478 (python) did not claim interface 0 before use
Interface claiming, in another hand, is handled internally by PyUSB,
this might be a bug.
usb.control.get_interface() does not claim the interface.


Thanks,
Johannes
Wander Lairson Costa
2013-10-29 16:58:45 UTC
Permalink
Post by Johannes Stezenbach
Post by Wander Lairson Costa
One remark: The "Let's get it started" example in
cfg = dev.get_active_configuration()
interface_number = cfg[(0,0)].bInterfaceNumber
alternate_setting = usb.control.get_interface(dev, interface_number)
intf = usb.util.find_descriptor(
cfg, bInterfaceNumber = interface_number,
bAlternateSetting = alternate_setting
)
instead of just this:?
intf = cfg[(0,0)]
The code above finds the interface by its interface number, not its
index inside the configuration (they are not necessarily the same
thing).
Well, I guess the intention is to show how to look up interface
by bInterfaceNumber, but if you take cfg[(0,0)].bInterfaceNumber
and look it up then you end with cfg[(0,0)], right?
What if cfg[0,0].bInterfaceNumber == 2?
Post by Johannes Stezenbach
Post by Wander Lairson Costa
Also, the code lacks an
intf.set_altsetting()
set_altsetting is only needed by device with alternate settings.
otherwise the EPs are not reset which might lead to errors
Stalled endpoints are not something expected in normal cases.
set_altsetting() is always required before using an interface since it
resets it into a known state. I mean the tutorial should just work
and not cause new users to wonder if pyusb is broken...
IIRC, according to USB spec, a device that receives a SET_INTERFACE request and
does not have additional alternate settings is allowed to return an error.
Post by Johannes Stezenbach
Post by Wander Lairson Costa
[2249737.372143] usb 1-1.1: usbfs: process 32478 (python) did not claim interface 0 before use
Interface claiming, in another hand, is handled internally by PyUSB,
this might be a bug.
usb.control.get_interface() does not claim the interface.
Ah, no because control requests against endpoint 0 does not need
interface claiming.
--
Best Regards,
Wander Lairson Costa
Johannes Stezenbach
2013-10-29 19:54:14 UTC
Permalink
Post by Wander Lairson Costa
Post by Johannes Stezenbach
Post by Wander Lairson Costa
One remark: The "Let's get it started" example in
cfg = dev.get_active_configuration()
interface_number = cfg[(0,0)].bInterfaceNumber
alternate_setting = usb.control.get_interface(dev, interface_number)
intf = usb.util.find_descriptor(
cfg, bInterfaceNumber = interface_number,
bAlternateSetting = alternate_setting
)
instead of just this:?
intf = cfg[(0,0)]
The code above finds the interface by its interface number, not its
index inside the configuration (they are not necessarily the same
thing).
Well, I guess the intention is to show how to look up interface
by bInterfaceNumber, but if you take cfg[(0,0)].bInterfaceNumber
and look it up then you end with cfg[(0,0)], right?
What if cfg[0,0].bInterfaceNumber == 2?
We're running in cirecles... maybe I don't understand
what the (0,0) index in cfg[(0,0)] means? My assumption
is it means the first Interface Descriptor as listed
in lsusb -v output.

And if the first descriptor has bInterfaceNumber==2 and
you look it up with usb.util.find_descriptor() you would
get the same first descriptor.
Post by Wander Lairson Costa
Post by Johannes Stezenbach
Post by Wander Lairson Costa
Also, the code lacks an
intf.set_altsetting()
set_altsetting is only needed by device with alternate settings.
otherwise the EPs are not reset which might lead to errors
Stalled endpoints are not something expected in normal cases.
set_altsetting() is always required before using an interface since it
resets it into a known state. I mean the tutorial should just work
and not cause new users to wonder if pyusb is broken...
IIRC, according to USB spec, a device that receives a SET_INTERFACE request and
does not have additional alternate settings is allowed to return an error.
Hm, that's true.

I was testing with a Linux based device and gadget g_zero, and
the EPIPE error stuck unless I added either intf.set_altsetting()
or explicit CLEAR_FEATURE(ENDPOINT_STALL). I remember having read
both SET_INTERFACE and SET_CONFIGURATION should reset the endpoint state
including data toggles and any device FIFOs, but I'm not sure
where I read it. Might have been Cypress FX2 documentation.

Now that I think about it the dev.set_configuration() did not seem
to have the desired effect. I'll test again tomorrow.
Post by Wander Lairson Costa
Post by Johannes Stezenbach
Post by Wander Lairson Costa
[2249737.372143] usb 1-1.1: usbfs: process 32478 (python) did not claim interface 0 before use
Interface claiming, in another hand, is handled internally by PyUSB,
this might be a bug.
usb.control.get_interface() does not claim the interface.
Ah, no because control requests against endpoint 0 does not need
interface claiming.
So I wonder what cause the kernel to complain.


Thanks,
Johannes
Wander Lairson Costa
2013-10-29 20:06:43 UTC
Permalink
Post by Johannes Stezenbach
Post by Wander Lairson Costa
Post by Johannes Stezenbach
Post by Wander Lairson Costa
One remark: The "Let's get it started" example in
cfg = dev.get_active_configuration()
interface_number = cfg[(0,0)].bInterfaceNumber
alternate_setting = usb.control.get_interface(dev, interface_number)
intf = usb.util.find_descriptor(
cfg, bInterfaceNumber = interface_number,
bAlternateSetting = alternate_setting
)
instead of just this:?
intf = cfg[(0,0)]
The code above finds the interface by its interface number, not its
index inside the configuration (they are not necessarily the same
thing).
Well, I guess the intention is to show how to look up interface
by bInterfaceNumber, but if you take cfg[(0,0)].bInterfaceNumber
and look it up then you end with cfg[(0,0)], right?
What if cfg[0,0].bInterfaceNumber == 2?
We're running in cirecles... maybe I don't understand
what the (0,0) index in cfg[(0,0)] means? My assumption
is it means the first Interface Descriptor as listed
in lsusb -v output.
And if the first descriptor has bInterfaceNumber==2 and
you look it up with usb.util.find_descriptor() you would
get the same first descriptor.
I am affraid you are confusing the relative order in which the
interface descriptor appears inside a configuration descriptor (which
is irrelevant to USB spec), and the interface number, which is
actually used for USB, say, for interface claiming. They are not
necessarily equal...
Post by Johannes Stezenbach
Post by Wander Lairson Costa
Post by Johannes Stezenbach
Post by Wander Lairson Costa
Also, the code lacks an
intf.set_altsetting()
set_altsetting is only needed by device with alternate settings.
otherwise the EPs are not reset which might lead to errors
Stalled endpoints are not something expected in normal cases.
set_altsetting() is always required before using an interface since it
resets it into a known state. I mean the tutorial should just work
and not cause new users to wonder if pyusb is broken...
IIRC, according to USB spec, a device that receives a SET_INTERFACE request and
does not have additional alternate settings is allowed to return an error.
Hm, that's true.
I was testing with a Linux based device and gadget g_zero, and
the EPIPE error stuck unless I added either intf.set_altsetting()
or explicit CLEAR_FEATURE(ENDPOINT_STALL). I remember having read
both SET_INTERFACE and SET_CONFIGURATION should reset the endpoint state
including data toggles and any device FIFOs, but I'm not sure
where I read it. Might have been Cypress FX2 documentation.
This probably is device specific, that's the reason is real hard to
have generic sample code that will work for you, and that's because I
chose to post minimum code snippets in the tutorial.
Post by Johannes Stezenbach
Now that I think about it the dev.set_configuration() did not seem
to have the desired effect. I'll test again tomorrow.
Post by Wander Lairson Costa
Post by Johannes Stezenbach
Post by Wander Lairson Costa
[2249737.372143] usb 1-1.1: usbfs: process 32478 (python) did not claim interface 0 before use
Interface claiming, in another hand, is handled internally by PyUSB,
this might be a bug.
usb.control.get_interface() does not claim the interface.
Ah, no because control requests against endpoint 0 does not need
interface claiming.
So I wonder what cause the kernel to complain.
Maybe it is just a debug info without real meaning...
--
Best Regards,
Wander Lairson Costa
Tormod Volden
2013-10-29 20:31:00 UTC
Permalink
Post by Wander Lairson Costa
Post by Johannes Stezenbach
We're running in cirecles... maybe I don't understand
what the (0,0) index in cfg[(0,0)] means? My assumption
is it means the first Interface Descriptor as listed
in lsusb -v output.
And if the first descriptor has bInterfaceNumber==2 and
you look it up with usb.util.find_descriptor() you would
get the same first descriptor.
I am affraid you are confusing the relative order in which the
interface descriptor appears inside a configuration descriptor (which
is irrelevant to USB spec), and the interface number, which is
actually used for USB, say, for interface claiming. They are not
necessarily equal...
No, he is not. He is just saying that the code in question will simply
look up the first (in appearing order) interface, whatever its
interface number is. So the question is why go via the interface
number in this example.

Tormod
Wander Lairson Costa
2013-10-29 22:13:45 UTC
Permalink
Post by Tormod Volden
Post by Wander Lairson Costa
Post by Johannes Stezenbach
We're running in cirecles... maybe I don't understand
what the (0,0) index in cfg[(0,0)] means? My assumption
is it means the first Interface Descriptor as listed
in lsusb -v output.
And if the first descriptor has bInterfaceNumber==2 and
you look it up with usb.util.find_descriptor() you would
get the same first descriptor.
I am affraid you are confusing the relative order in which the
interface descriptor appears inside a configuration descriptor (which
is irrelevant to USB spec), and the interface number, which is
actually used for USB, say, for interface claiming. They are not
necessarily equal...
No, he is not. He is just saying that the code in question will simply
look up the first (in appearing order) interface, whatever its
interface number is. So the question is why go via the interface
number in this example.
Ah, now I got it, thanks Tormod. It is needed because because we want
the interface descriptor related to the current active alternate
setting for the first interface found.
--
Best Regards,
Wander Lairson Costa
Johannes Stezenbach
2013-10-30 13:29:28 UTC
Permalink
Post by Wander Lairson Costa
Post by Tormod Volden
Post by Wander Lairson Costa
Post by Johannes Stezenbach
We're running in cirecles... maybe I don't understand
what the (0,0) index in cfg[(0,0)] means? My assumption
is it means the first Interface Descriptor as listed
in lsusb -v output.
And if the first descriptor has bInterfaceNumber==2 and
you look it up with usb.util.find_descriptor() you would
get the same first descriptor.
I am affraid you are confusing the relative order in which the
interface descriptor appears inside a configuration descriptor (which
is irrelevant to USB spec), and the interface number, which is
actually used for USB, say, for interface claiming. They are not
necessarily equal...
No, he is not. He is just saying that the code in question will simply
look up the first (in appearing order) interface, whatever its
interface number is. So the question is why go via the interface
number in this example.
Ah, now I got it, thanks Tormod. It is needed because because we want
the interface descriptor related to the current active alternate
setting for the first interface found.
I'm still not getting it.

cfg = dev.get_active_configuration()
# now we have the Configuration Descriptor for some arbitrary configuration
intf = cfg[(0,0)]
# first altsetting of first interface in the configuration

The usb.util.find_descriptor() in the tutorial would be useful
if we would know bInterfaceNumber for the desired interface
by some other means. A more realistic example for the
tutorial would search the interface by bInterfaceClass,
bInterfaceSubClass and bInterfaceProtocol. Or, for the
case of Linux g_zero, find the configuration with
iConfiguration pointing to "source and sink data" and
use the first (and only) interface.


Thanks,
Johannes
Johannes Stezenbach
2013-10-30 13:46:06 UTC
Permalink
Post by Wander Lairson Costa
Post by Johannes Stezenbach
I was testing with a Linux based device and gadget g_zero, and
the EPIPE error stuck unless I added either intf.set_altsetting()
or explicit CLEAR_FEATURE(ENDPOINT_STALL). I remember having read
both SET_INTERFACE and SET_CONFIGURATION should reset the endpoint state
including data toggles and any device FIFOs, but I'm not sure
where I read it. Might have been Cypress FX2 documentation.
This probably is device specific, that's the reason is real hard to
have generic sample code that will work for you, and that's because I
chose to post minimum code snippets in the tutorial.
OK, it looks like a bug in the PCD (peripheral controller driver)
which does not clear STALL in usb_ep_enable(). Thus I was
confused and the intf.set_altsetting() is not needed,
dev.set_configuration() is sufficient.
Post by Wander Lairson Costa
Post by Johannes Stezenbach
Post by Wander Lairson Costa
Post by Johannes Stezenbach
Post by Wander Lairson Costa
[2249737.372143] usb 1-1.1: usbfs: process 32478 (python) did not claim interface 0 before use
Interface claiming, in another hand, is handled internally by PyUSB,
this might be a bug.
usb.control.get_interface() does not claim the interface.
Ah, no because control requests against endpoint 0 does not need
interface claiming.
So I wonder what cause the kernel to complain.
Maybe it is just a debug info without real meaning...
I tried again and the
alternate_setting = usb.control.get_interface(dev, interface_number)
line in the tutorial causes the Linux kernel warning (Linux 3.10.14).

So it seems the Linux kernel disagrees with your assumption?
If the control request is for USB_RECIP_INTERFACE it checks if
the interface has been claimed:
https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/drivers/usb/core/devio.c#n765


Thanks,
Johannes
Wander Lairson Costa
2013-10-30 23:24:11 UTC
Permalink
Post by Johannes Stezenbach
Post by Wander Lairson Costa
Post by Johannes Stezenbach
Post by Wander Lairson Costa
Post by Johannes Stezenbach
Post by Wander Lairson Costa
[2249737.372143] usb 1-1.1: usbfs: process 32478 (python) did not claim interface 0 before use
Interface claiming, in another hand, is handled internally by PyUSB,
this might be a bug.
usb.control.get_interface() does not claim the interface.
Ah, no because control requests against endpoint 0 does not need
interface claiming.
So I wonder what cause the kernel to complain.
Maybe it is just a debug info without real meaning...
I tried again and the
alternate_setting = usb.control.get_interface(dev, interface_number)
line in the tutorial causes the Linux kernel warning (Linux 3.10.14).
So it seems the Linux kernel disagrees with your assumption?
If the control request is for USB_RECIP_INTERFACE it checks if
https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/drivers/usb/core/devio.c#n765
I don't have time right now, but I need to look further into this, as
it might be a problem with PyUSB. Thanks to pointing this out.
For now, what if you explicitly claim the interface (with
usb.util.claim_interface function) before calling get_interface?
--
Best Regards,
Wander Lairson Costa
Johannes Stezenbach
2013-10-31 05:58:20 UTC
Permalink
Post by Wander Lairson Costa
Post by Johannes Stezenbach
Post by Wander Lairson Costa
Post by Johannes Stezenbach
Post by Wander Lairson Costa
Post by Johannes Stezenbach
Post by Wander Lairson Costa
[2249737.372143] usb 1-1.1: usbfs: process 32478 (python) did not claim interface 0 before use
Interface claiming, in another hand, is handled internally by PyUSB,
this might be a bug.
usb.control.get_interface() does not claim the interface.
Ah, no because control requests against endpoint 0 does not need
interface claiming.
So I wonder what cause the kernel to complain.
Maybe it is just a debug info without real meaning...
I tried again and the
alternate_setting = usb.control.get_interface(dev, interface_number)
line in the tutorial causes the Linux kernel warning (Linux 3.10.14).
So it seems the Linux kernel disagrees with your assumption?
If the control request is for USB_RECIP_INTERFACE it checks if
https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/drivers/usb/core/devio.c#n765
I don't have time right now, but I need to look further into this, as
it might be a problem with PyUSB. Thanks to pointing this out.
For now, what if you explicitly claim the interface (with
usb.util.claim_interface function) before calling get_interface?
It works. And intf.set_altsetting() also claims the interface,
that's what I've been using.

Thanks,
Johannes
Wander Lairson Costa
2014-04-18 16:29:21 UTC
Permalink
Post by Johannes Stezenbach
Post by Wander Lairson Costa
Post by Johannes Stezenbach
Post by Wander Lairson Costa
Post by Johannes Stezenbach
Post by Wander Lairson Costa
Post by Johannes Stezenbach
Post by Wander Lairson Costa
[2249737.372143] usb 1-1.1: usbfs: process 32478 (python) did not claim interface 0 before use
Interface claiming, in another hand, is handled internally by PyUSB,
this might be a bug.
usb.control.get_interface() does not claim the interface.
Ah, no because control requests against endpoint 0 does not need
interface claiming.
So I wonder what cause the kernel to complain.
Maybe it is just a debug info without real meaning...
I tried again and the
alternate_setting = usb.control.get_interface(dev, interface_number)
line in the tutorial causes the Linux kernel warning (Linux 3.10.14).
So it seems the Linux kernel disagrees with your assumption?
If the control request is for USB_RECIP_INTERFACE it checks if
https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/drivers/usb/core/devio.c#n765
I don't have time right now, but I need to look further into this, as
it might be a problem with PyUSB. Thanks to pointing this out.
For now, what if you explicitly claim the interface (with
usb.util.claim_interface function) before calling get_interface?
It works. And intf.set_altsetting() also claims the interface,
that's what I've been using.
It has been a very very long time, but finally I could go into this,
and you are right, when issuing a control request to an interface, I
must claim it.
I just pushed a fix [1]. Thanks for point me out this.

[1] https://github.com/walac/pyusb/commit/4c7d9a94c25a732c62db4515376bd90798a483d8
--
Best Regards,
Wander Lairson Costa
Johannes Stezenbach
2013-10-29 13:49:53 UTC
Permalink
Hi,
Post by Wander Lairson Costa
I am proud to announce that PyUSB 1.0.0 beta is out.
...
Post by Wander Lairson Costa
TODO
----
* More tests with legacy module.
* Isochronous transfers for libusb-win32.
Download page
-------------
https://sourceforge.net/projects/pyusb/files/PyUSB%201.0/1.0.0-beta-1/
This release took much more time than I was expecting to, so I would like
to thank you all for your patience, and specially for those whose contributed
for this release.
I've been using pyusb-1.0.0-a1.tar.gz some time back, and
the new beta release still works perfectly on Linux for
some ad-hoc testing.

One remark: The "Let's get it started" example in
docs/tutorial.rst looks confusing, why does it do this:

cfg = dev.get_active_configuration()
interface_number = cfg[(0,0)].bInterfaceNumber
alternate_setting = usb.control.get_interface(dev, interface_number)
intf = usb.util.find_descriptor(
cfg, bInterfaceNumber = interface_number,
bAlternateSetting = alternate_setting
)

instead of just this:?

intf = cfg[(0,0)]

Also, the code lacks an

intf.set_altsetting()

otherwise the EPs are not reset which might lead to errors
(e.g. STALL is not cleaared from previous use), and Linux complains:

[2249737.372143] usb 1-1.1: usbfs: process 32478 (python) did not claim interface 0 before use


I hope you can do the 1.0.0 final release soon and PyUSB 1.x will be picked
up by Linux distributions. Currently most seem to ship PyUSB 0.4, which
is a pity given the 1.0 API is so much better. It slso would be a good idea
to clearly state in the README that both Python 2.x and Python 3.x are supported.


Thanks,
Johannes
Loading...