Browse Source

[usb] Allow for wildcard USB class IDs

Make the class ID a property of the USB driver (rather than a property
of the USB device ID), and allow USB drivers to specify a wildcard ID
for any of the three component IDs (class, subclass, or protocol).

Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Michael Brown 9 years ago
parent
commit
668dc73d52

+ 15
- 10
src/drivers/bus/usb.c View File

985
 	unsigned int i;
985
 	unsigned int i;
986
 
986
 
987
 	/* Fill in vendor and product ID */
987
 	/* Fill in vendor and product ID */
988
+	memset ( desc, 0, sizeof ( *desc ) );
988
 	desc->vendor = le16_to_cpu ( usb->device.vendor );
989
 	desc->vendor = le16_to_cpu ( usb->device.vendor );
989
 	desc->product = le16_to_cpu ( usb->device.product );
990
 	desc->product = le16_to_cpu ( usb->device.product );
990
 
991
 
1023
 	interfaces[0] = first;
1024
 	interfaces[0] = first;
1024
 
1025
 
1025
 	/* Look for a CDC union descriptor, if applicable */
1026
 	/* Look for a CDC union descriptor, if applicable */
1026
-	if ( ( desc->class.class == USB_CLASS_CDC ) &&
1027
+	if ( ( desc->class.class.class == USB_CLASS_CDC ) &&
1027
 	     ( cdc_union = cdc_union_descriptor ( config, interface ) ) ) {
1028
 	     ( cdc_union = cdc_union_descriptor ( config, interface ) ) ) {
1028
 
1029
 
1029
 		/* Determine interface count */
1030
 		/* Determine interface count */
1096
 	for_each_table_entry ( driver, USB_DRIVERS ) {
1097
 	for_each_table_entry ( driver, USB_DRIVERS ) {
1097
 		for ( i = 0 ; i < driver->id_count ; i++ ) {
1098
 		for ( i = 0 ; i < driver->id_count ; i++ ) {
1098
 
1099
 
1099
-			/* Check for a matching ID */
1100
+			/* Ignore non-matching driver class */
1101
+			if ( ( driver->class.class.scalar ^ desc->class.scalar )
1102
+			     & driver->class.mask.scalar )
1103
+				continue;
1104
+
1105
+			/* Look for a matching ID */
1100
 			*id = &driver->ids[i];
1106
 			*id = &driver->ids[i];
1101
 			if ( ( ( (*id)->vendor == desc->vendor ) ||
1107
 			if ( ( ( (*id)->vendor == desc->vendor ) ||
1102
 			       ( (*id)->vendor == USB_ANY_ID ) ) &&
1108
 			       ( (*id)->vendor == USB_ANY_ID ) ) &&
1103
 			     ( ( (*id)->product == desc->product ) ||
1109
 			     ( ( (*id)->product == desc->product ) ||
1104
-			       ( (*id)->product == USB_ANY_ID ) ) &&
1105
-			     ( (*id)->class.class == desc->class.class ) &&
1106
-			     ( (*id)->class.subclass == desc->class.subclass )&&
1107
-			     ( (*id)->class.protocol == desc->class.protocol ) )
1110
+			       ( (*id)->product == USB_ANY_ID ) ) )
1108
 				return driver;
1111
 				return driver;
1109
 		}
1112
 		}
1110
 	}
1113
 	}
1178
 	if ( ! driver ) {
1181
 	if ( ! driver ) {
1179
 		DBGC ( usb, "USB %s %04x:%04x class %d:%d:%d has no driver\n",
1182
 		DBGC ( usb, "USB %s %04x:%04x class %d:%d:%d has no driver\n",
1180
 		       func->name, func->desc.vendor, func->desc.product,
1183
 		       func->name, func->desc.vendor, func->desc.product,
1181
-		       func->desc.class.class, func->desc.class.subclass,
1182
-		       func->desc.class.protocol );
1184
+		       func->desc.class.class.class,
1185
+		       func->desc.class.class.subclass,
1186
+		       func->desc.class.class.protocol );
1183
 		return -ENOENT;
1187
 		return -ENOENT;
1184
 	}
1188
 	}
1185
 
1189
 
1265
 			goto err_probe;
1269
 			goto err_probe;
1266
 		DBGC ( usb, "USB %s %04x:%04x class %d:%d:%d interfaces ",
1270
 		DBGC ( usb, "USB %s %04x:%04x class %d:%d:%d interfaces ",
1267
 		       func->name, func->desc.vendor, func->desc.product,
1271
 		       func->name, func->desc.vendor, func->desc.product,
1268
-		       func->desc.class.class, func->desc.class.subclass,
1269
-		       func->desc.class.protocol );
1272
+		       func->desc.class.class.class,
1273
+		       func->desc.class.class.subclass,
1274
+		       func->desc.class.class.protocol );
1270
 		for ( i = 0 ; i < func->desc.count ; i++ )
1275
 		for ( i = 0 ; i < func->desc.count ; i++ )
1271
 			DBGC ( usb, "%s%d", ( i ? "," : "" ),
1276
 			DBGC ( usb, "%s%d", ( i ? "," : "" ),
1272
 			       func->interface[i] );
1277
 			       func->interface[i] );

+ 1
- 0
src/drivers/net/dm96xx.c View File

666
 struct usb_driver dm96xx_driver __usb_driver = {
666
 struct usb_driver dm96xx_driver __usb_driver = {
667
 	.ids = dm96xx_ids,
667
 	.ids = dm96xx_ids,
668
 	.id_count = ( sizeof ( dm96xx_ids ) / sizeof ( dm96xx_ids[0] ) ),
668
 	.id_count = ( sizeof ( dm96xx_ids ) / sizeof ( dm96xx_ids[0] ) ),
669
+	.class = USB_CLASS_ID ( USB_ANY_ID, USB_ANY_ID, USB_ANY_ID ),
669
 	.score = USB_SCORE_NORMAL,
670
 	.score = USB_SCORE_NORMAL,
670
 	.probe = dm96xx_probe,
671
 	.probe = dm96xx_probe,
671
 	.remove = dm96xx_remove,
672
 	.remove = dm96xx_remove,

+ 1
- 5
src/drivers/net/ecm.c View File

503
 		.name = "cdc-ecm",
503
 		.name = "cdc-ecm",
504
 		.vendor = USB_ANY_ID,
504
 		.vendor = USB_ANY_ID,
505
 		.product = USB_ANY_ID,
505
 		.product = USB_ANY_ID,
506
-		.class = {
507
-			.class = USB_CLASS_CDC,
508
-			.subclass = USB_SUBCLASS_CDC_ECM,
509
-			.protocol = 0,
510
-		},
511
 	},
506
 	},
512
 };
507
 };
513
 
508
 
515
 struct usb_driver ecm_driver __usb_driver = {
510
 struct usb_driver ecm_driver __usb_driver = {
516
 	.ids = ecm_ids,
511
 	.ids = ecm_ids,
517
 	.id_count = ( sizeof ( ecm_ids ) / sizeof ( ecm_ids[0] ) ),
512
 	.id_count = ( sizeof ( ecm_ids ) / sizeof ( ecm_ids[0] ) ),
513
+	.class = USB_CLASS_ID ( USB_CLASS_CDC, USB_SUBCLASS_CDC_ECM, 0 ),
518
 	.score = USB_SCORE_NORMAL,
514
 	.score = USB_SCORE_NORMAL,
519
 	.probe = ecm_probe,
515
 	.probe = ecm_probe,
520
 	.remove = ecm_remove,
516
 	.remove = ecm_remove,

+ 1
- 5
src/drivers/net/ncm.c View File

655
 		.name = "cdc-ncm",
655
 		.name = "cdc-ncm",
656
 		.vendor = USB_ANY_ID,
656
 		.vendor = USB_ANY_ID,
657
 		.product = USB_ANY_ID,
657
 		.product = USB_ANY_ID,
658
-		.class = {
659
-			.class = USB_CLASS_CDC,
660
-			.subclass = USB_SUBCLASS_CDC_NCM,
661
-			.protocol = 0,
662
-		},
663
 	},
658
 	},
664
 };
659
 };
665
 
660
 
667
 struct usb_driver ncm_driver __usb_driver = {
662
 struct usb_driver ncm_driver __usb_driver = {
668
 	.ids = ncm_ids,
663
 	.ids = ncm_ids,
669
 	.id_count = ( sizeof ( ncm_ids ) / sizeof ( ncm_ids[0] ) ),
664
 	.id_count = ( sizeof ( ncm_ids ) / sizeof ( ncm_ids[0] ) ),
665
+	.class = USB_CLASS_ID ( USB_CLASS_CDC, USB_SUBCLASS_CDC_NCM, 0 ),
670
 	.score = USB_SCORE_NORMAL,
666
 	.score = USB_SCORE_NORMAL,
671
 	.probe = ncm_probe,
667
 	.probe = ncm_probe,
672
 	.remove = ncm_remove,
668
 	.remove = ncm_remove,

+ 1
- 2
src/drivers/net/smsc75xx.c View File

1038
 		.name = "smsc7500",
1038
 		.name = "smsc7500",
1039
 		.vendor = 0x0424,
1039
 		.vendor = 0x0424,
1040
 		.product = 0x7500,
1040
 		.product = 0x7500,
1041
-		.class = { 0xff, 0x00, 0xff },
1042
 	},
1041
 	},
1043
 	{
1042
 	{
1044
 		.name = "smsc7505",
1043
 		.name = "smsc7505",
1045
 		.vendor = 0x0424,
1044
 		.vendor = 0x0424,
1046
 		.product = 0x7505,
1045
 		.product = 0x7505,
1047
-		.class = { 0xff, 0x00, 0xff },
1048
 	},
1046
 	},
1049
 };
1047
 };
1050
 
1048
 
1052
 struct usb_driver smsc75xx_driver __usb_driver = {
1050
 struct usb_driver smsc75xx_driver __usb_driver = {
1053
 	.ids = smsc75xx_ids,
1051
 	.ids = smsc75xx_ids,
1054
 	.id_count = ( sizeof ( smsc75xx_ids ) / sizeof ( smsc75xx_ids[0] ) ),
1052
 	.id_count = ( sizeof ( smsc75xx_ids ) / sizeof ( smsc75xx_ids[0] ) ),
1053
+	.class = USB_CLASS_ID ( 0xff, 0x00, 0xff ),
1055
 	.score = USB_SCORE_NORMAL,
1054
 	.score = USB_SCORE_NORMAL,
1056
 	.probe = smsc75xx_probe,
1055
 	.probe = smsc75xx_probe,
1057
 	.remove = smsc75xx_remove,
1056
 	.remove = smsc75xx_remove,

+ 2
- 16
src/drivers/usb/usbhub.c View File

517
 /** USB hub device IDs */
517
 /** USB hub device IDs */
518
 static struct usb_device_id hub_ids[] = {
518
 static struct usb_device_id hub_ids[] = {
519
 	{
519
 	{
520
-		.name = "hub-1",
520
+		.name = "hub",
521
 		.vendor = USB_ANY_ID,
521
 		.vendor = USB_ANY_ID,
522
 		.product = USB_ANY_ID,
522
 		.product = USB_ANY_ID,
523
-		.class = {
524
-			.class = USB_CLASS_HUB,
525
-			.subclass = 0,
526
-			.protocol = 0,
527
-		},
528
-	},
529
-	{
530
-		.name = "hub-2",
531
-		.vendor = USB_ANY_ID,
532
-		.product = USB_ANY_ID,
533
-		.class = {
534
-			.class = USB_CLASS_HUB,
535
-			.subclass = 0,
536
-			.protocol = 1,
537
-		},
538
 	},
523
 	},
539
 };
524
 };
540
 
525
 
542
 struct usb_driver usb_hub_driver __usb_driver = {
527
 struct usb_driver usb_hub_driver __usb_driver = {
543
 	.ids = hub_ids,
528
 	.ids = hub_ids,
544
 	.id_count = ( sizeof ( hub_ids ) / sizeof ( hub_ids[0] ) ),
529
 	.id_count = ( sizeof ( hub_ids ) / sizeof ( hub_ids[0] ) ),
530
+	.class = USB_CLASS_ID ( USB_CLASS_HUB, 0, USB_ANY_ID ),
545
 	.score = USB_SCORE_NORMAL,
531
 	.score = USB_SCORE_NORMAL,
546
 	.probe = hub_probe,
532
 	.probe = hub_probe,
547
 	.remove = hub_remove,
533
 	.remove = hub_remove,

+ 4
- 3
src/drivers/usb/usbio.c View File

1316
 		       "%s\n", efi_handle_name ( handle ), strerror ( rc ) );
1316
 		       "%s\n", efi_handle_name ( handle ), strerror ( rc ) );
1317
 		goto err_get_device_descriptor;
1317
 		goto err_get_device_descriptor;
1318
 	}
1318
 	}
1319
+	memset ( &desc, 0, sizeof ( desc ) );
1319
 	desc.vendor = device.IdVendor;
1320
 	desc.vendor = device.IdVendor;
1320
 	desc.product = device.IdProduct;
1321
 	desc.product = device.IdProduct;
1321
 
1322
 
1327
 		       "%s\n", efi_handle_name ( handle ), strerror ( rc ) );
1328
 		       "%s\n", efi_handle_name ( handle ), strerror ( rc ) );
1328
 		goto err_get_interface_descriptor;
1329
 		goto err_get_interface_descriptor;
1329
 	}
1330
 	}
1330
-	desc.class.class = interface.InterfaceClass;
1331
-	desc.class.subclass = interface.InterfaceSubClass;
1332
-	desc.class.protocol = interface.InterfaceProtocol;
1331
+	desc.class.class.class = interface.InterfaceClass;
1332
+	desc.class.class.subclass = interface.InterfaceSubClass;
1333
+	desc.class.class.protocol = interface.InterfaceProtocol;
1333
 
1334
 
1334
 	/* Look for a driver for this interface */
1335
 	/* Look for a driver for this interface */
1335
 	driver = usb_find_driver ( &desc, &id );
1336
 	driver = usb_find_driver ( &desc, &id );

+ 2
- 5
src/drivers/usb/usbkbd.c View File

437
 		.name = "kbd",
437
 		.name = "kbd",
438
 		.vendor = USB_ANY_ID,
438
 		.vendor = USB_ANY_ID,
439
 		.product = USB_ANY_ID,
439
 		.product = USB_ANY_ID,
440
-		.class = {
441
-			.class = USB_CLASS_HID,
442
-			.subclass = USB_SUBCLASS_HID_BOOT,
443
-			.protocol = USBKBD_PROTOCOL,
444
-		},
445
 	},
440
 	},
446
 };
441
 };
447
 
442
 
449
 struct usb_driver usbkbd_driver __usb_driver = {
444
 struct usb_driver usbkbd_driver __usb_driver = {
450
 	.ids = usbkbd_ids,
445
 	.ids = usbkbd_ids,
451
 	.id_count = ( sizeof ( usbkbd_ids ) / sizeof ( usbkbd_ids[0] ) ),
446
 	.id_count = ( sizeof ( usbkbd_ids ) / sizeof ( usbkbd_ids[0] ) ),
447
+	.class = USB_CLASS_ID ( USB_CLASS_HID, USB_SUBCLASS_HID_BOOT,
448
+				USBKBD_PROTOCOL ),
452
 	.score = USB_SCORE_NORMAL,
449
 	.score = USB_SCORE_NORMAL,
453
 	.probe = usbkbd_probe,
450
 	.probe = usbkbd_probe,
454
 	.remove = usbkbd_remove,
451
 	.remove = usbkbd_remove,

+ 42
- 3
src/include/ipxe/usb.h View File

615
 extern int usb_refill ( struct usb_endpoint *ep );
615
 extern int usb_refill ( struct usb_endpoint *ep );
616
 extern void usb_flush ( struct usb_endpoint *ep );
616
 extern void usb_flush ( struct usb_endpoint *ep );
617
 
617
 
618
+/** A USB class descriptor */
619
+union usb_class_descriptor {
620
+	/** Class */
621
+	struct usb_class class;
622
+	/** Scalar value */
623
+	uint32_t scalar;
624
+};
625
+
618
 /**
626
 /**
619
  * A USB function descriptor
627
  * A USB function descriptor
620
  *
628
  *
627
 	/** Product ID */
635
 	/** Product ID */
628
 	uint16_t product;
636
 	uint16_t product;
629
 	/** Class */
637
 	/** Class */
630
-	struct usb_class class;
638
+	union usb_class_descriptor class;
631
 	/** Number of interfaces */
639
 	/** Number of interfaces */
632
 	unsigned int count;
640
 	unsigned int count;
633
 };
641
 };
1298
 	uint16_t vendor;
1306
 	uint16_t vendor;
1299
 	/** Product ID */
1307
 	/** Product ID */
1300
 	uint16_t product;
1308
 	uint16_t product;
1301
-	/** Class */
1302
-	struct usb_class class;
1303
 };
1309
 };
1304
 
1310
 
1305
 /** Match-anything ID */
1311
 /** Match-anything ID */
1306
 #define USB_ANY_ID 0xffff
1312
 #define USB_ANY_ID 0xffff
1307
 
1313
 
1314
+/** A USB class ID */
1315
+struct usb_class_id {
1316
+	/** Class */
1317
+	union usb_class_descriptor class;
1318
+	/** Class mask */
1319
+	union usb_class_descriptor mask;
1320
+};
1321
+
1322
+/** Construct USB class ID
1323
+ *
1324
+ * @v base		Base class code (or USB_ANY_ID)
1325
+ * @v subclass		Subclass code (or USB_ANY_ID)
1326
+ * @v protocol		Protocol code (or USB_ANY_ID)
1327
+ */
1328
+#define USB_CLASS_ID( base, subclass, protocol ) {			\
1329
+	.class = {							\
1330
+		.class = {						\
1331
+			( (base) & 0xff ),				\
1332
+			( (subclass) & 0xff ),				\
1333
+			( (protocol) & 0xff ),				\
1334
+		},							\
1335
+	},								\
1336
+	.mask = {							\
1337
+		.class = {						\
1338
+			( ( (base) == USB_ANY_ID ) ? 0x00 : 0xff ),	\
1339
+			( ( (subclass) == USB_ANY_ID ) ? 0x00 : 0xff ),	\
1340
+			( ( (protocol) == USB_ANY_ID ) ? 0x00 : 0xff ),	\
1341
+		},							\
1342
+		},							\
1343
+	}
1344
+
1308
 /** A USB driver */
1345
 /** A USB driver */
1309
 struct usb_driver {
1346
 struct usb_driver {
1310
 	/** USB ID table */
1347
 	/** USB ID table */
1311
 	struct usb_device_id *ids;
1348
 	struct usb_device_id *ids;
1312
 	/** Number of entries in ID table */
1349
 	/** Number of entries in ID table */
1313
 	unsigned int id_count;
1350
 	unsigned int id_count;
1351
+	/** Class ID */
1352
+	struct usb_class_id class;
1314
 	/** Driver score
1353
 	/** Driver score
1315
 	 *
1354
 	 *
1316
 	 * This is used to determine the preferred configuration for a
1355
 	 * This is used to determine the preferred configuration for a

Loading…
Cancel
Save