mirror of https://github.com/ipxe/ipxe.git
[xhci] Assume an invalid PSI table if any invalid PSI value is observed
Invalid protocol speed ID tables appear to be increasingly common in the wild, to the point that it is infeasible to apply an explicit XHCI_BAD_PSIV flag for each offending PCI device ID. Fix by assuming an invalid PSI table as soon as any invalid value is reported by the hardware. Signed-off-by: Michael Brown <mcb30@ipxe.org>pull/68/head
parent
fbe8c52d0d
commit
c900751fa6
|
@ -801,23 +801,13 @@ static int xhci_port_speed ( struct xhci_device *xhci, unsigned int port,
|
|||
ports = readl ( xhci->cap + supported + XHCI_SUPPORTED_PORTS );
|
||||
psic = XHCI_SUPPORTED_PORTS_PSIC ( ports );
|
||||
|
||||
/* Use the default mappings if applicable */
|
||||
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;
|
||||
case XHCI_SPEED_HIGH : return USB_SPEED_HIGH;
|
||||
case XHCI_SPEED_SUPER : return USB_SPEED_SUPER;
|
||||
default:
|
||||
DBGC ( xhci, "XHCI %s-%d non-standard PSI value %d\n",
|
||||
xhci->name, port, psiv );
|
||||
return -ENOTSUP;
|
||||
}
|
||||
}
|
||||
/* Use protocol speed ID table unless device is known to be faulty */
|
||||
if ( ! ( xhci->quirks & XHCI_BAD_PSIV ) ) {
|
||||
|
||||
/* Iterate over PSI dwords looking for a match */
|
||||
for ( i = 0 ; i < psic ; i++ ) {
|
||||
psi = readl ( xhci->cap + supported + XHCI_SUPPORTED_PSI ( i ));
|
||||
psi = readl ( xhci->cap + supported +
|
||||
XHCI_SUPPORTED_PSI ( i ) );
|
||||
if ( psiv == XHCI_SUPPORTED_PSI_VALUE ( psi ) ) {
|
||||
mantissa = XHCI_SUPPORTED_PSI_MANTISSA ( psi );
|
||||
exponent = XHCI_SUPPORTED_PSI_EXPONENT ( psi );
|
||||
|
@ -826,9 +816,26 @@ static int xhci_port_speed ( struct xhci_device *xhci, unsigned int port,
|
|||
}
|
||||
}
|
||||
|
||||
DBGC ( xhci, "XHCI %s-%d spurious PSI value %d\n",
|
||||
/* Record device as faulty if no match is found */
|
||||
if ( psic != 0 ) {
|
||||
DBGC ( xhci, "XHCI %s-%d spurious PSI value %d: "
|
||||
"assuming PSI table is invalid\n",
|
||||
xhci->name, port, psiv );
|
||||
return -ENOENT;
|
||||
xhci->quirks |= XHCI_BAD_PSIV;
|
||||
}
|
||||
}
|
||||
|
||||
/* Use the default mappings */
|
||||
switch ( psiv ) {
|
||||
case XHCI_SPEED_LOW : return USB_SPEED_LOW;
|
||||
case XHCI_SPEED_FULL : return USB_SPEED_FULL;
|
||||
case XHCI_SPEED_HIGH : return USB_SPEED_HIGH;
|
||||
case XHCI_SPEED_SUPER : return USB_SPEED_SUPER;
|
||||
default:
|
||||
DBGC ( xhci, "XHCI %s-%d unrecognised PSI value %d\n",
|
||||
xhci->name, port, psiv );
|
||||
return -ENOTSUP;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in New Issue