diff options
author | Michael Brown | 2015-09-05 16:53:56 +0200 |
---|---|---|
committer | Michael Brown | 2015-09-06 22:51:38 +0200 |
commit | 866e52581451238e840be214a34648da2958dafd (patch) | |
tree | fda435e25eab8c09de591ab5e394215dad2e0aef /src/drivers/bus | |
parent | [efi] Implement the EFI_PXE_BASE_CODE_PROTOCOL (diff) | |
download | ipxe-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.c | 95 |
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; } /** |