mirror of https://github.com/ipxe/ipxe.git
[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>pull/36/head
parent
323bf186fb
commit
be3517c4ab
|
@ -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 ),
|
||||
};
|
||||
|
|
|
@ -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 */
|
||||
|
|
Loading…
Reference in New Issue