summaryrefslogtreecommitdiffstats
path: root/src/drivers/bus
diff options
context:
space:
mode:
authorMichael Brown2015-09-05 16:53:56 +0200
committerMichael Brown2015-09-06 22:51:38 +0200
commit866e52581451238e840be214a34648da2958dafd (patch)
treefda435e25eab8c09de591ab5e394215dad2e0aef /src/drivers/bus
parent[efi] Implement the EFI_PXE_BASE_CODE_PROTOCOL (diff)
downloadipxe-866e52581451238e840be214a34648da2958dafd.tar.gz
ipxe-866e52581451238e840be214a34648da2958dafd.tar.xz
ipxe-866e52581451238e840be214a34648da2958dafd.zip
[usb] Expose usb_find_driver()
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Diffstat (limited to 'src/drivers/bus')
-rw-r--r--src/drivers/bus/usb.c95
1 files changed, 52 insertions, 43 deletions
diff --git a/src/drivers/bus/usb.c b/src/drivers/bus/usb.c
index 2019e334..2520922e 100644
--- a/src/drivers/bus/usb.c
+++ b/src/drivers/bus/usb.c
@@ -972,22 +972,40 @@ static int usb_function ( struct usb_function *func,
}
/**
- * Check for a USB device ID match
+ * Find USB device driver
*
- * @v func USB function
- * @v id Device ID
- * @ret matches Device ID matches
- */
-static int
-usb_device_id_matches ( struct usb_function *func, struct usb_device_id *id ) {
-
- return ( ( ( id->vendor == func->dev.desc.vendor ) ||
- ( id->vendor == USB_ANY_ID ) ) &&
- ( ( id->product == func->dev.desc.device ) ||
- ( id->product == USB_ANY_ID ) ) &&
- ( id->class.class == func->class.class ) &&
- ( id->class.subclass == func->class.subclass ) &&
- ( id->class.protocol == func->class.protocol ) );
+ * @v vendor Vendor ID
+ * @v product Product ID
+ * @v class Class
+ * @ret id USB device ID, or NULL
+ * @ret driver USB device driver, or NULL
+ */
+struct usb_driver * usb_find_driver ( unsigned int vendor, unsigned int product,
+ struct usb_class *class,
+ struct usb_device_id **id ) {
+ struct usb_driver *driver;
+ unsigned int i;
+
+ /* Look for a matching driver */
+ for_each_table_entry ( driver, USB_DRIVERS ) {
+ for ( i = 0 ; i < driver->id_count ; i++ ) {
+
+ /* Check for a matching ID */
+ *id = &driver->ids[i];
+ if ( ( ( (*id)->vendor == vendor ) ||
+ ( (*id)->vendor == USB_ANY_ID ) ) &&
+ ( ( (*id)->product == product ) ||
+ ( (*id)->product == USB_ANY_ID ) ) &&
+ ( (*id)->class.class == class->class ) &&
+ ( (*id)->class.subclass == class->subclass ) &&
+ ( (*id)->class.protocol == class->protocol ) )
+ return driver;
+ }
+ }
+
+ /* Not found */
+ *id = NULL;
+ return NULL;
}
/**
@@ -1002,39 +1020,30 @@ static int usb_probe ( struct usb_function *func,
struct usb_device *usb = func->usb;
struct usb_driver *driver;
struct usb_device_id *id;
- unsigned int i;
int rc;
- /* Look for a matching driver */
- for_each_table_entry ( driver, USB_DRIVERS ) {
- for ( i = 0 ; i < driver->id_count ; i++ ) {
-
- /* Check for a matching ID */
- id = &driver->ids[i];
- if ( ! usb_device_id_matches ( func, id ) )
- continue;
-
- /* Probe driver */
- if ( ( rc = driver->probe ( func, config ) ) != 0 ) {
- DBGC ( usb, "USB %s failed to probe driver %s: "
- "%s\n", func->name, id->name,
- strerror ( rc ) );
- /* Continue trying other drivers */
- continue;
- }
+ /* Identify driver */
+ driver = usb_find_driver ( func->dev.desc.vendor, func->dev.desc.device,
+ &func->class, &id );
+ if ( ! driver ) {
+ DBGC ( usb, "USB %s %04x:%04x class %d:%d:%d has no driver\n",
+ func->name, func->dev.desc.vendor, func->dev.desc.device,
+ func->class.class, func->class.subclass,
+ func->class.protocol );
+ return -ENOENT;
+ }
- /* Record driver */
- func->driver = driver;
- func->dev.driver_name = id->name;
- return 0;
- }
+ /* Probe driver */
+ if ( ( rc = driver->probe ( func, config ) ) != 0 ) {
+ DBGC ( usb, "USB %s failed to probe driver %s: %s\n",
+ func->name, id->name, strerror ( rc ) );
+ return rc;
}
- /* No driver found */
- DBGC ( usb, "USB %s %04x:%04x class %d:%d:%d has no driver\n",
- func->name, func->dev.desc.vendor, func->dev.desc.device,
- func->class.class, func->class.subclass, func->class.protocol );
- return -ENOENT;
+ /* Record driver */
+ func->driver = driver;
+ func->dev.driver_name = id->name;
+ return 0;
}
/**