mirror of
https://github.com/gdsports/USBHost_t36
synced 2024-12-21 14:58:53 -05:00
Improve hub descriptor parsing, find all interfaces
This commit is contained in:
parent
1494a02918
commit
62fbf401d2
@ -581,6 +581,10 @@ private:
|
||||
uint32_t changebits;
|
||||
uint32_t statusbits;
|
||||
uint8_t hub_desc[16];
|
||||
uint8_t interface_count;
|
||||
uint8_t interface_number;
|
||||
uint8_t altsetting;
|
||||
uint8_t protocol;
|
||||
uint8_t endpoint;
|
||||
uint8_t interval;
|
||||
uint8_t numports;
|
||||
|
65
hub.cpp
65
hub.cpp
@ -41,7 +41,7 @@ void USBHub::init()
|
||||
driver_ready_for_device(this);
|
||||
}
|
||||
|
||||
bool USBHub::claim(Device_t *dev, int type, const uint8_t *descriptors, uint32_t len)
|
||||
bool USBHub::claim(Device_t *dev, int type, const uint8_t *d, uint32_t len)
|
||||
{
|
||||
// only claim entire device, never at interface level
|
||||
if (type != 0) return false;
|
||||
@ -56,33 +56,44 @@ bool USBHub::claim(Device_t *dev, int type, const uint8_t *descriptors, uint32_t
|
||||
if (dev->bDeviceClass != 9 || dev->bDeviceSubClass != 0) return false;
|
||||
// protocol must be 0=FS, 1=HS Single-TT, or 2=HS Multi-TT
|
||||
if (dev->bDeviceProtocol > 2) return false;
|
||||
// check for endpoint descriptor
|
||||
if (descriptors[9] != 7 || descriptors[10] != 5) return false;
|
||||
// endpoint must be IN direction
|
||||
if ((descriptors[11] & 0xF0) != 0x80) return false;
|
||||
// endpoint type must be interrupt
|
||||
if (descriptors[12] != 3) return false;
|
||||
// get the endpoint number, must not be zero
|
||||
endpoint = descriptors[11] & 0x0F;
|
||||
if (endpoint == 0) return false;
|
||||
// get the maximum packet size
|
||||
uint32_t maxsize = descriptors[13] | (descriptors[14] << 8);
|
||||
if (maxsize == 0) return false;
|
||||
if (maxsize > 1) return false; // do hub chips with > 7 ports exist?
|
||||
interval = descriptors[15];
|
||||
println(" polling interval = ", interval);
|
||||
println(descriptors[9]);
|
||||
println(descriptors[10]);
|
||||
println(descriptors[11], HEX);
|
||||
println(maxsize);
|
||||
// bDeviceProtocol = 0 is full speed
|
||||
// bDeviceProtocol = 1 is high speed single TT
|
||||
// bDeviceProtocol = 2 is high speed multiple TT
|
||||
|
||||
println("bDeviceClass = ", dev->bDeviceClass);
|
||||
println("bDeviceSubClass = ", dev->bDeviceSubClass);
|
||||
println("bDeviceProtocol = ", dev->bDeviceProtocol);
|
||||
|
||||
interface_count = 0;
|
||||
while (len >= 16) {
|
||||
if (d[0] == 9 && d[1] == 4 && // valid interface descriptor
|
||||
d[4] == 1 && // has 1 endpoint
|
||||
d[5] == 9 && // bInterfaceClass is HUB type
|
||||
d[7] >= 0 && d[7] <= 2 && // bInterfaceProtocol is ok
|
||||
d[9] == 7 && d[10] == 5 && // valid endpoint descriptor
|
||||
(d[11] & 0xF0) == 0x80 && // endpoint direction is IN
|
||||
d[12] == 3 && // endpoint type is interrupt
|
||||
d[13] == 1 && d[14] == 0) { // max packet size is 1 byte
|
||||
println("found possible interface, altsetting=", d[3]);
|
||||
if (interface_count == 0) {
|
||||
interface_number = d[2];
|
||||
altsetting = d[3];
|
||||
protocol = d[7];
|
||||
endpoint = d[11] & 0x0F;
|
||||
interval = d[15];
|
||||
} else {
|
||||
if (d[2] != interface_number) break;
|
||||
if (d[7] > protocol) {
|
||||
altsetting = d[3];
|
||||
protocol = d[7];
|
||||
endpoint = d[11] & 0x0F;
|
||||
interval = d[15];
|
||||
}
|
||||
}
|
||||
interface_count++;
|
||||
}
|
||||
d += 16; // jump forward to next interface
|
||||
len -= 16;
|
||||
}
|
||||
if (interface_count == 0) return false; // no usable interface found
|
||||
println("number of interfaces found = ", interface_count);
|
||||
if (interface_count > 1) {
|
||||
print("best interface is ", interface_number);
|
||||
println(" using altsetting ", altsetting);
|
||||
}
|
||||
numports = 0; // unknown until hub descriptor is read
|
||||
changepipe = NULL;
|
||||
changebits = 0;
|
||||
|
Loading…
Reference in New Issue
Block a user