summaryrefslogtreecommitdiffstats
path: root/src/drivers/bus
diff options
context:
space:
mode:
authorMichael Brown2015-09-14 18:52:25 +0200
committerMichael Brown2015-09-14 22:56:40 +0200
commit668dc73d526fa67957b9c10100f9ca5f2ab60522 (patch)
treecf6887506d5ac016fd04497cbd568463292903de /src/drivers/bus
parent[usb] Select preferred USB device configuration based on driver score (diff)
downloadipxe-668dc73d526fa67957b9c10100f9ca5f2ab60522.tar.gz
ipxe-668dc73d526fa67957b9c10100f9ca5f2ab60522.tar.xz
ipxe-668dc73d526fa67957b9c10100f9ca5f2ab60522.zip
[usb] Allow for wildcard USB class IDs
Make the class ID a property of the USB driver (rather than a property of the USB device ID), and allow USB drivers to specify a wildcard ID for any of the three component IDs (class, subclass, or protocol). Signed-off-by: Michael Brown <mcb30@ipxe.org>
Diffstat (limited to 'src/drivers/bus')
-rw-r--r--src/drivers/bus/usb.c25
1 files changed, 15 insertions, 10 deletions
diff --git a/src/drivers/bus/usb.c b/src/drivers/bus/usb.c
index d8d7f6b3..63a7e46a 100644
--- a/src/drivers/bus/usb.c
+++ b/src/drivers/bus/usb.c
@@ -985,6 +985,7 @@ static int usb_describe ( struct usb_device *usb,
unsigned int i;
/* Fill in vendor and product ID */
+ memset ( desc, 0, sizeof ( *desc ) );
desc->vendor = le16_to_cpu ( usb->device.vendor );
desc->product = le16_to_cpu ( usb->device.product );
@@ -1023,7 +1024,7 @@ static int usb_describe ( struct usb_device *usb,
interfaces[0] = first;
/* Look for a CDC union descriptor, if applicable */
- if ( ( desc->class.class == USB_CLASS_CDC ) &&
+ if ( ( desc->class.class.class == USB_CLASS_CDC ) &&
( cdc_union = cdc_union_descriptor ( config, interface ) ) ) {
/* Determine interface count */
@@ -1096,15 +1097,17 @@ struct usb_driver * usb_find_driver ( struct usb_function_descriptor *desc,
for_each_table_entry ( driver, USB_DRIVERS ) {
for ( i = 0 ; i < driver->id_count ; i++ ) {
- /* Check for a matching ID */
+ /* Ignore non-matching driver class */
+ if ( ( driver->class.class.scalar ^ desc->class.scalar )
+ & driver->class.mask.scalar )
+ continue;
+
+ /* Look for a matching ID */
*id = &driver->ids[i];
if ( ( ( (*id)->vendor == desc->vendor ) ||
( (*id)->vendor == USB_ANY_ID ) ) &&
( ( (*id)->product == desc->product ) ||
- ( (*id)->product == USB_ANY_ID ) ) &&
- ( (*id)->class.class == desc->class.class ) &&
- ( (*id)->class.subclass == desc->class.subclass )&&
- ( (*id)->class.protocol == desc->class.protocol ) )
+ ( (*id)->product == USB_ANY_ID ) ) )
return driver;
}
}
@@ -1178,8 +1181,9 @@ static int usb_probe ( struct usb_function *func,
if ( ! driver ) {
DBGC ( usb, "USB %s %04x:%04x class %d:%d:%d has no driver\n",
func->name, func->desc.vendor, func->desc.product,
- func->desc.class.class, func->desc.class.subclass,
- func->desc.class.protocol );
+ func->desc.class.class.class,
+ func->desc.class.class.subclass,
+ func->desc.class.class.protocol );
return -ENOENT;
}
@@ -1265,8 +1269,9 @@ usb_probe_all ( struct usb_device *usb,
goto err_probe;
DBGC ( usb, "USB %s %04x:%04x class %d:%d:%d interfaces ",
func->name, func->desc.vendor, func->desc.product,
- func->desc.class.class, func->desc.class.subclass,
- func->desc.class.protocol );
+ func->desc.class.class.class,
+ func->desc.class.class.subclass,
+ func->desc.class.class.protocol );
for ( i = 0 ; i < func->desc.count ; i++ )
DBGC ( usb, "%s%d", ( i ? "," : "" ),
func->interface[i] );