Felipe Balbi
2010-08-02 10:21:19 UTC
Hi all,
I've been willing to write a chapter 9 tool for linux. The specification for it
can be found when you install usbcv from usb-if on a windows machine.
It's currently rather complicated to implement it with libusb because
we have a few missing "test features" on usbfs side and some features
that cause problems on libusb.
First of all it's impossible to set an address to a device via libusb. Well
I cooked the control message by hand, but then when I try to talk to device
the address is not updated to the libusb_device_handle * so every other
transfer to that device will fail if we set a different address.
Another one is that libusb caches the descriptors, so subsequent
get descriptor requests will just return the cached version, but USBCV
that's a no-no since we need to exercise a real GetDescriptor() request.
I understand why libusb does that (to avoid waking up a sleeping device),
but would there be a way to overcome that ?
The most critical part of the USBCV Spec that needs to be well supported
is the device states you have to handle and run the tests, I'm quoting
the spec below:
3. Test Descriptions
3.1 Chapter 9 (Device) Tests
The Chapter 9 tests cover the device support of the commands set
for the in Chapter 9 of the USB
specification. There are three different device states. Many of
the tests are run with the device under
test in more than one of these states. Each of the states and
procedure used to put the device into this
state are described here. This information is provided to help
with debugging in cases where the
device under test is not even reaching the desired starting state
for the test The individual tests
mention which device states they are run on – but don’t repeat the
setup procedure. The device states
are as follows:
Default State:
1. Put the device in the configured state following the procedure below.
2. Issue a valid Set Configuration command to the device with
configuration value zero.
3. Issue a valid Get Configuration command and verify that the
device responds with zero.
4. Issue a valid Set Address command to the device with address zero.
Address State:
1. Put the device in the configured state following the procedure below.
2. Issue a valid Set Configuration command to the device with
configuration value zero.
3. Issue a valid Get Configuration command to the device and
verify that device responds with zero.
Configured State: The device is enumerated using the following procedure.
1. Reset the USB host controller.
2. For each port on the USB host controller turn on port power.
3. Sleep for 1 Second.
4. Drive port reset on each host port. Sleep for 50
milliseconds. Clear port reset.
5. Check host port enable.
6. If host port is enabled enumerate the device on the port.
7. Issue a valid set configuration command for the
configuration to be tested.
8. Issue a valid get configuration command and verify that the
correct configuration is returned.
Enumerate Device Routine:
Get device descriptor using a maximum packet size of 64.
(This will cause a short packet for
1.
devices with maxpacketsize0 < 64)
2. Issue a Set Address command with the next available USB address.
3. Get the device descriptor again with the right maximum packet size.
4. Get configuration descriptor asking for a number of bytes
equal to configuration descriptor size
only.
5. Issue a Set Configuration command for the first configuration
supported by the device.
6. Get the configuration descriptor again asking for a number of
bytes equal to the configuration
descriptor size.
7. Get the configuration descriptor using the total length of
the entire descriptor.
If the descriptors indicated the device is a hub continue with the steps below:
8. Get the hub class descriptor.
9. Issue a Set Port Feature command with power selector
PORT_POWER for each port on the hub.
10. Sleep for 1 second.
11. Issue Get Port Status commands for each port.
12. If the connect bit is set in the port status issue a port
reset and proceed to step 13. Otherwise stop.
13. Sleep for 50 milliseconds.
14. Check the port status to ensure the enable bit has been set.
Then proceed to the enumerate device
routine.
If we support those operations, I believe a USBCV for linux could be
written (well, it would actually
work on Mac OSX and Windows too, I guess).
Any comments would be welcome.
I've been willing to write a chapter 9 tool for linux. The specification for it
can be found when you install usbcv from usb-if on a windows machine.
It's currently rather complicated to implement it with libusb because
we have a few missing "test features" on usbfs side and some features
that cause problems on libusb.
First of all it's impossible to set an address to a device via libusb. Well
I cooked the control message by hand, but then when I try to talk to device
the address is not updated to the libusb_device_handle * so every other
transfer to that device will fail if we set a different address.
Another one is that libusb caches the descriptors, so subsequent
get descriptor requests will just return the cached version, but USBCV
that's a no-no since we need to exercise a real GetDescriptor() request.
I understand why libusb does that (to avoid waking up a sleeping device),
but would there be a way to overcome that ?
The most critical part of the USBCV Spec that needs to be well supported
is the device states you have to handle and run the tests, I'm quoting
the spec below:
3. Test Descriptions
3.1 Chapter 9 (Device) Tests
The Chapter 9 tests cover the device support of the commands set
for the in Chapter 9 of the USB
specification. There are three different device states. Many of
the tests are run with the device under
test in more than one of these states. Each of the states and
procedure used to put the device into this
state are described here. This information is provided to help
with debugging in cases where the
device under test is not even reaching the desired starting state
for the test The individual tests
mention which device states they are run on – but don’t repeat the
setup procedure. The device states
are as follows:
Default State:
1. Put the device in the configured state following the procedure below.
2. Issue a valid Set Configuration command to the device with
configuration value zero.
3. Issue a valid Get Configuration command and verify that the
device responds with zero.
4. Issue a valid Set Address command to the device with address zero.
Address State:
1. Put the device in the configured state following the procedure below.
2. Issue a valid Set Configuration command to the device with
configuration value zero.
3. Issue a valid Get Configuration command to the device and
verify that device responds with zero.
Configured State: The device is enumerated using the following procedure.
1. Reset the USB host controller.
2. For each port on the USB host controller turn on port power.
3. Sleep for 1 Second.
4. Drive port reset on each host port. Sleep for 50
milliseconds. Clear port reset.
5. Check host port enable.
6. If host port is enabled enumerate the device on the port.
7. Issue a valid set configuration command for the
configuration to be tested.
8. Issue a valid get configuration command and verify that the
correct configuration is returned.
Enumerate Device Routine:
Get device descriptor using a maximum packet size of 64.
(This will cause a short packet for
1.
devices with maxpacketsize0 < 64)
2. Issue a Set Address command with the next available USB address.
3. Get the device descriptor again with the right maximum packet size.
4. Get configuration descriptor asking for a number of bytes
equal to configuration descriptor size
only.
5. Issue a Set Configuration command for the first configuration
supported by the device.
6. Get the configuration descriptor again asking for a number of
bytes equal to the configuration
descriptor size.
7. Get the configuration descriptor using the total length of
the entire descriptor.
If the descriptors indicated the device is a hub continue with the steps below:
8. Get the hub class descriptor.
9. Issue a Set Port Feature command with power selector
PORT_POWER for each port on the hub.
10. Sleep for 1 second.
11. Issue Get Port Status commands for each port.
12. If the connect bit is set in the port status issue a port
reset and proceed to step 13. Otherwise stop.
13. Sleep for 50 milliseconds.
14. Check the port status to ensure the enable bit has been set.
Then proceed to the enumerate device
routine.
If we support those operations, I believe a USBCV for linux could be
written (well, it would actually
work on Mac OSX and Windows too, I guess).
Any comments would be welcome.
--
Best Regards,
Felipe Balbi
***@users.sourceforge.net
Best Regards,
Felipe Balbi
***@users.sourceforge.net