mirror of https://github.com/ipxe/ipxe.git
[usb] Expose usb_find_driver()
Signed-off-by: Michael Brown <mcb30@ipxe.org>pull/41/head
parent
3376fa520b
commit
866e525814
|
@ -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 */
|
/* Probe driver */
|
||||||
if ( ( rc = driver->probe ( func, config ) ) != 0 ) {
|
if ( ( rc = driver->probe ( func, config ) ) != 0 ) {
|
||||||
DBGC ( usb, "USB %s failed to probe driver %s: "
|
DBGC ( usb, "USB %s failed to probe driver %s: %s\n",
|
||||||
"%s\n", func->name, id->name,
|
func->name, id->name, strerror ( rc ) );
|
||||||
strerror ( rc ) );
|
return rc;
|
||||||
/* Continue trying other drivers */
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Record driver */
|
/* Record driver */
|
||||||
func->driver = driver;
|
func->driver = driver;
|
||||||
func->dev.driver_name = id->name;
|
func->dev.driver_name = id->name;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
Loading…
Reference in New Issue