david/ipxe
david
/
ipxe
Archived
1
0
Fork 0

[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>
This commit is contained in:
Michael Brown 2015-06-18 15:09:57 +01:00
parent 323bf186fb
commit be3517c4ab
2 changed files with 9 additions and 3 deletions

View File

@ -743,6 +743,8 @@ static unsigned int xhci_port_protocol ( struct xhci_device *xhci,
xhci_speed_name ( psi ) );
}
}
if ( xhci->quirks & XHCI_BAD_PSIV )
DBGC2 ( xhci, " (ignored)" );
DBGC2 ( xhci, "\n" );
}
@ -800,7 +802,7 @@ static int xhci_port_speed ( struct xhci_device *xhci, unsigned int port,
psic = XHCI_SUPPORTED_PORTS_PSIC ( ports );
/* Use the default mappings if applicable */
if ( ! psic ) {
if ( ( psic == 0 ) || ( xhci->quirks & XHCI_BAD_PSIV ) ) {
switch ( psiv ) {
case XHCI_SPEED_LOW : return USB_SPEED_LOW;
case XHCI_SPEED_FULL : return USB_SPEED_FULL;
@ -857,14 +859,14 @@ static int xhci_port_psiv ( struct xhci_device *xhci, unsigned int port,
psic = XHCI_SUPPORTED_PORTS_PSIC ( ports );
/* Use the default mappings if applicable */
if ( ! psic ) {
if ( ( psic == 0 ) || ( xhci->quirks & XHCI_BAD_PSIV ) ) {
switch ( speed ) {
case USB_SPEED_LOW : return XHCI_SPEED_LOW;
case USB_SPEED_FULL : return XHCI_SPEED_FULL;
case USB_SPEED_HIGH : return XHCI_SPEED_HIGH;
case USB_SPEED_SUPER : return XHCI_SPEED_SUPER;
default:
DBGC ( xhci, "XHCI %s-%d non-standad speed %d\n",
DBGC ( xhci, "XHCI %s-%d non-standard speed %d\n",
xhci->name, port, speed );
return -ENOTSUP;
}
@ -3286,6 +3288,7 @@ static void xhci_remove ( struct pci_device *pci ) {
/** XHCI PCI device IDs */
static struct pci_device_id xhci_ids[] = {
PCI_ROM ( 0x8086, 0x9d2f, "xhci-skylake", "xHCI (Skylake)", ( XHCI_PCH | XHCI_BAD_PSIV ) ),
PCI_ROM ( 0x8086, 0xffff, "xhci-pch", "xHCI (Intel PCH)", XHCI_PCH ),
PCI_ROM ( 0xffff, 0xffff, "xhci", "xHCI", 0 ),
};

View File

@ -1032,6 +1032,9 @@ struct xhci_pch {
/** Intel PCH USB3 port routing mask register */
#define XHCI_PCH_USB3PRM 0xdc
/** Invalid protocol speed ID values quirk */
#define XHCI_BAD_PSIV 0x0002
/** An xHCI device */
struct xhci_device {
/** Registers */