Browse Source

[xhci] Ignore invalid protocol speed ID values on Intel Skylake platforms

Some Intel Skylake platforms (observed on a prototype Lenovo ThinkPad)
report the list of available USB3 protocol speed ID values as {1,2,3}
but then report a port's speed using ID value 4.

The value 4 happens to be the default value for SuperSpeed (when no
protocol speed ID value list is explicitly defined), and the hardware
seems to function correctly if we simply ignore its protocol speed ID
table and assume that it uses the default values.

Fix by adding a "broken PSI values" quirk for this controller.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Michael Brown 10 years ago
parent
commit
be3517c4ab
2 changed files with 9 additions and 3 deletions
  1. 6
    3
      src/drivers/usb/xhci.c
  2. 3
    0
      src/drivers/usb/xhci.h

+ 6
- 3
src/drivers/usb/xhci.c View File

743
 					xhci_speed_name ( psi ) );
743
 					xhci_speed_name ( psi ) );
744
 			}
744
 			}
745
 		}
745
 		}
746
+		if ( xhci->quirks & XHCI_BAD_PSIV )
747
+			DBGC2 ( xhci, " (ignored)" );
746
 		DBGC2 ( xhci, "\n" );
748
 		DBGC2 ( xhci, "\n" );
747
 	}
749
 	}
748
 
750
 
800
 	psic = XHCI_SUPPORTED_PORTS_PSIC ( ports );
802
 	psic = XHCI_SUPPORTED_PORTS_PSIC ( ports );
801
 
803
 
802
 	/* Use the default mappings if applicable */
804
 	/* Use the default mappings if applicable */
803
-	if ( ! psic ) {
805
+	if ( ( psic == 0 ) || ( xhci->quirks & XHCI_BAD_PSIV ) ) {
804
 		switch ( psiv ) {
806
 		switch ( psiv ) {
805
 		case XHCI_SPEED_LOW :	return USB_SPEED_LOW;
807
 		case XHCI_SPEED_LOW :	return USB_SPEED_LOW;
806
 		case XHCI_SPEED_FULL :	return USB_SPEED_FULL;
808
 		case XHCI_SPEED_FULL :	return USB_SPEED_FULL;
857
 	psic = XHCI_SUPPORTED_PORTS_PSIC ( ports );
859
 	psic = XHCI_SUPPORTED_PORTS_PSIC ( ports );
858
 
860
 
859
 	/* Use the default mappings if applicable */
861
 	/* Use the default mappings if applicable */
860
-	if ( ! psic ) {
862
+	if ( ( psic == 0 ) || ( xhci->quirks & XHCI_BAD_PSIV ) ) {
861
 		switch ( speed ) {
863
 		switch ( speed ) {
862
 		case USB_SPEED_LOW :	return XHCI_SPEED_LOW;
864
 		case USB_SPEED_LOW :	return XHCI_SPEED_LOW;
863
 		case USB_SPEED_FULL :	return XHCI_SPEED_FULL;
865
 		case USB_SPEED_FULL :	return XHCI_SPEED_FULL;
864
 		case USB_SPEED_HIGH :	return XHCI_SPEED_HIGH;
866
 		case USB_SPEED_HIGH :	return XHCI_SPEED_HIGH;
865
 		case USB_SPEED_SUPER :	return XHCI_SPEED_SUPER;
867
 		case USB_SPEED_SUPER :	return XHCI_SPEED_SUPER;
866
 		default:
868
 		default:
867
-			DBGC ( xhci, "XHCI %s-%d non-standad speed %d\n",
869
+			DBGC ( xhci, "XHCI %s-%d non-standard speed %d\n",
868
 			       xhci->name, port, speed );
870
 			       xhci->name, port, speed );
869
 			return -ENOTSUP;
871
 			return -ENOTSUP;
870
 		}
872
 		}
3286
 
3288
 
3287
 /** XHCI PCI device IDs */
3289
 /** XHCI PCI device IDs */
3288
 static struct pci_device_id xhci_ids[] = {
3290
 static struct pci_device_id xhci_ids[] = {
3291
+	PCI_ROM ( 0x8086, 0x9d2f, "xhci-skylake", "xHCI (Skylake)", ( XHCI_PCH | XHCI_BAD_PSIV ) ),
3289
 	PCI_ROM ( 0x8086, 0xffff, "xhci-pch", "xHCI (Intel PCH)", XHCI_PCH ),
3292
 	PCI_ROM ( 0x8086, 0xffff, "xhci-pch", "xHCI (Intel PCH)", XHCI_PCH ),
3290
 	PCI_ROM ( 0xffff, 0xffff, "xhci", "xHCI", 0 ),
3293
 	PCI_ROM ( 0xffff, 0xffff, "xhci", "xHCI", 0 ),
3291
 };
3294
 };

+ 3
- 0
src/drivers/usb/xhci.h View File

1032
 /** Intel PCH USB3 port routing mask register */
1032
 /** Intel PCH USB3 port routing mask register */
1033
 #define XHCI_PCH_USB3PRM 0xdc
1033
 #define XHCI_PCH_USB3PRM 0xdc
1034
 
1034
 
1035
+/** Invalid protocol speed ID values quirk */
1036
+#define XHCI_BAD_PSIV 0x0002
1037
+
1035
 /** An xHCI device */
1038
 /** An xHCI device */
1036
 struct xhci_device {
1039
 struct xhci_device {
1037
 	/** Registers */
1040
 	/** Registers */

Loading…
Cancel
Save