david/ipxe
Archived
1
0

[usb] Expose usb_find_driver()

Signed-off-by: Michael Brown <mcb30@ipxe.org>
This commit is contained in:
Michael Brown 2015-09-05 15:53:56 +01:00
parent 3376fa520b
commit 866e525814
2 changed files with 56 additions and 42 deletions

View File

@ -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 vendor Vendor ID
* @v id Device ID * @v product Product ID
* @ret matches Device ID matches * @v class Class
* @ret id USB device ID, or NULL
* @ret driver USB device driver, or NULL
*/ */
static int struct usb_driver * usb_find_driver ( unsigned int vendor, unsigned int product,
usb_device_id_matches ( struct usb_function *func, struct usb_device_id *id ) { struct usb_class *class,
struct usb_device_id **id ) {
struct usb_driver *driver;
unsigned int i;
return ( ( ( id->vendor == func->dev.desc.vendor ) || /* Look for a matching driver */
( id->vendor == USB_ANY_ID ) ) && for_each_table_entry ( driver, USB_DRIVERS ) {
( ( id->product == func->dev.desc.device ) || for ( i = 0 ; i < driver->id_count ; i++ ) {
( id->product == USB_ANY_ID ) ) &&
( id->class.class == func->class.class ) && /* Check for a matching ID */
( id->class.subclass == func->class.subclass ) && *id = &driver->ids[i];
( id->class.protocol == func->class.protocol ) ); 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_device *usb = func->usb;
struct usb_driver *driver; struct usb_driver *driver;
struct usb_device_id *id; struct usb_device_id *id;
unsigned int i;
int rc; int rc;
/* Look for a matching driver */ /* Identify driver */
for_each_table_entry ( driver, USB_DRIVERS ) { driver = usb_find_driver ( func->dev.desc.vendor, func->dev.desc.device,
for ( i = 0 ; i < driver->id_count ; i++ ) { &func->class, &id );
if ( ! driver ) {
/* Check for a matching ID */ DBGC ( usb, "USB %s %04x:%04x class %d:%d:%d has no driver\n",
id = &driver->ids[i]; func->name, func->dev.desc.vendor, func->dev.desc.device,
if ( ! usb_device_id_matches ( func, id ) ) func->class.class, func->class.subclass,
continue; func->class.protocol );
return -ENOENT;
/* 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;
}
/* Record driver */
func->driver = driver;
func->dev.driver_name = id->name;
return 0;
}
} }
/* No driver found */ /* Probe driver */
DBGC ( usb, "USB %s %04x:%04x class %d:%d:%d has no driver\n", if ( ( rc = driver->probe ( func, config ) ) != 0 ) {
func->name, func->dev.desc.vendor, func->dev.desc.device, DBGC ( usb, "USB %s failed to probe driver %s: %s\n",
func->class.class, func->class.subclass, func->class.protocol ); func->name, id->name, strerror ( rc ) );
return -ENOENT; return rc;
}
/* Record driver */
func->driver = driver;
func->dev.driver_name = id->name;
return 0;
} }
/** /**

View File

@ -1316,4 +1316,9 @@ struct usb_driver {
/** Declare a USB driver */ /** Declare a USB driver */
#define __usb_driver __table_entry ( USB_DRIVERS, 01 ) #define __usb_driver __table_entry ( USB_DRIVERS, 01 )
extern struct usb_driver * usb_find_driver ( unsigned int vendor,
unsigned int product,
struct usb_class *class,
struct usb_device_id **id );
#endif /* _IPXE_USB_H */ #endif /* _IPXE_USB_H */