|
@@ -972,22 +972,40 @@ static int usb_function ( struct usb_function *func,
|
972
|
972
|
}
|
973
|
973
|
|
974
|
974
|
/**
|
975
|
|
- * Check for a USB device ID match
|
|
975
|
+ * Find USB device driver
|
976
|
976
|
*
|
977
|
|
- * @v func USB function
|
978
|
|
- * @v id Device ID
|
979
|
|
- * @ret matches Device ID matches
|
980
|
|
- */
|
981
|
|
-static int
|
982
|
|
-usb_device_id_matches ( struct usb_function *func, struct usb_device_id *id ) {
|
983
|
|
-
|
984
|
|
- return ( ( ( id->vendor == func->dev.desc.vendor ) ||
|
985
|
|
- ( id->vendor == USB_ANY_ID ) ) &&
|
986
|
|
- ( ( id->product == func->dev.desc.device ) ||
|
987
|
|
- ( id->product == USB_ANY_ID ) ) &&
|
988
|
|
- ( id->class.class == func->class.class ) &&
|
989
|
|
- ( id->class.subclass == func->class.subclass ) &&
|
990
|
|
- ( id->class.protocol == func->class.protocol ) );
|
|
977
|
+ * @v vendor Vendor ID
|
|
978
|
+ * @v product Product ID
|
|
979
|
+ * @v class Class
|
|
980
|
+ * @ret id USB device ID, or NULL
|
|
981
|
+ * @ret driver USB device driver, or NULL
|
|
982
|
+ */
|
|
983
|
+struct usb_driver * usb_find_driver ( unsigned int vendor, unsigned int product,
|
|
984
|
+ struct usb_class *class,
|
|
985
|
+ struct usb_device_id **id ) {
|
|
986
|
+ struct usb_driver *driver;
|
|
987
|
+ unsigned int i;
|
|
988
|
+
|
|
989
|
+ /* Look for a matching driver */
|
|
990
|
+ for_each_table_entry ( driver, USB_DRIVERS ) {
|
|
991
|
+ for ( i = 0 ; i < driver->id_count ; i++ ) {
|
|
992
|
+
|
|
993
|
+ /* Check for a matching ID */
|
|
994
|
+ *id = &driver->ids[i];
|
|
995
|
+ if ( ( ( (*id)->vendor == vendor ) ||
|
|
996
|
+ ( (*id)->vendor == USB_ANY_ID ) ) &&
|
|
997
|
+ ( ( (*id)->product == product ) ||
|
|
998
|
+ ( (*id)->product == USB_ANY_ID ) ) &&
|
|
999
|
+ ( (*id)->class.class == class->class ) &&
|
|
1000
|
+ ( (*id)->class.subclass == class->subclass ) &&
|
|
1001
|
+ ( (*id)->class.protocol == class->protocol ) )
|
|
1002
|
+ return driver;
|
|
1003
|
+ }
|
|
1004
|
+ }
|
|
1005
|
+
|
|
1006
|
+ /* Not found */
|
|
1007
|
+ *id = NULL;
|
|
1008
|
+ return NULL;
|
991
|
1009
|
}
|
992
|
1010
|
|
993
|
1011
|
/**
|
|
@@ -1002,39 +1020,30 @@ static int usb_probe ( struct usb_function *func,
|
1002
|
1020
|
struct usb_device *usb = func->usb;
|
1003
|
1021
|
struct usb_driver *driver;
|
1004
|
1022
|
struct usb_device_id *id;
|
1005
|
|
- unsigned int i;
|
1006
|
1023
|
int rc;
|
1007
|
1024
|
|
1008
|
|
- /* Look for a matching driver */
|
1009
|
|
- for_each_table_entry ( driver, USB_DRIVERS ) {
|
1010
|
|
- for ( i = 0 ; i < driver->id_count ; i++ ) {
|
1011
|
|
-
|
1012
|
|
- /* Check for a matching ID */
|
1013
|
|
- id = &driver->ids[i];
|
1014
|
|
- if ( ! usb_device_id_matches ( func, id ) )
|
1015
|
|
- continue;
|
1016
|
|
-
|
1017
|
|
- /* Probe driver */
|
1018
|
|
- if ( ( rc = driver->probe ( func, config ) ) != 0 ) {
|
1019
|
|
- DBGC ( usb, "USB %s failed to probe driver %s: "
|
1020
|
|
- "%s\n", func->name, id->name,
|
1021
|
|
- strerror ( rc ) );
|
1022
|
|
- /* Continue trying other drivers */
|
1023
|
|
- continue;
|
1024
|
|
- }
|
|
1025
|
+ /* Identify driver */
|
|
1026
|
+ driver = usb_find_driver ( func->dev.desc.vendor, func->dev.desc.device,
|
|
1027
|
+ &func->class, &id );
|
|
1028
|
+ if ( ! driver ) {
|
|
1029
|
+ DBGC ( usb, "USB %s %04x:%04x class %d:%d:%d has no driver\n",
|
|
1030
|
+ func->name, func->dev.desc.vendor, func->dev.desc.device,
|
|
1031
|
+ func->class.class, func->class.subclass,
|
|
1032
|
+ func->class.protocol );
|
|
1033
|
+ return -ENOENT;
|
|
1034
|
+ }
|
1025
|
1035
|
|
1026
|
|
- /* Record driver */
|
1027
|
|
- func->driver = driver;
|
1028
|
|
- func->dev.driver_name = id->name;
|
1029
|
|
- return 0;
|
1030
|
|
- }
|
|
1036
|
+ /* Probe driver */
|
|
1037
|
+ if ( ( rc = driver->probe ( func, config ) ) != 0 ) {
|
|
1038
|
+ DBGC ( usb, "USB %s failed to probe driver %s: %s\n",
|
|
1039
|
+ func->name, id->name, strerror ( rc ) );
|
|
1040
|
+ return rc;
|
1031
|
1041
|
}
|
1032
|
1042
|
|
1033
|
|
- /* No driver found */
|
1034
|
|
- DBGC ( usb, "USB %s %04x:%04x class %d:%d:%d has no driver\n",
|
1035
|
|
- func->name, func->dev.desc.vendor, func->dev.desc.device,
|
1036
|
|
- func->class.class, func->class.subclass, func->class.protocol );
|
1037
|
|
- return -ENOENT;
|
|
1043
|
+ /* Record driver */
|
|
1044
|
+ func->driver = driver;
|
|
1045
|
+ func->dev.driver_name = id->name;
|
|
1046
|
+ return 0;
|
1038
|
1047
|
}
|
1039
|
1048
|
|
1040
|
1049
|
/**
|