mirror of https://github.com/ipxe/ipxe.git
[xhci] Undo PCH-specific quirk fixes when removing device
Restore the original values of XUSB2PR and USB3PSSEN, in case we are booting an OS with no support for xHCI. Suggested-by: Dan Ellis <Dan.Ellis@displaylink.com> Signed-off-by: Michael Brown <mcb30@ipxe.org>pull/34/head
parent
ff320404d5
commit
e905cdcce3
|
@ -3019,7 +3019,8 @@ static struct usb_host_operations xhci_operations = {
|
||||||
* @v xhci xHCI device
|
* @v xhci xHCI device
|
||||||
* @v pci PCI device
|
* @v pci PCI device
|
||||||
*/
|
*/
|
||||||
static void xhci_pch ( struct xhci_device *xhci, struct pci_device *pci ) {
|
static void xhci_pch_fix ( struct xhci_device *xhci, struct pci_device *pci ) {
|
||||||
|
struct xhci_pch *pch = &xhci->pch;
|
||||||
uint32_t xusb2pr;
|
uint32_t xusb2pr;
|
||||||
uint32_t xusb2prm;
|
uint32_t xusb2prm;
|
||||||
uint32_t usb3pssen;
|
uint32_t usb3pssen;
|
||||||
|
@ -3034,6 +3035,7 @@ static void xhci_pch ( struct xhci_device *xhci, struct pci_device *pci ) {
|
||||||
DBGC ( xhci, "XHCI %p enabling SuperSpeed on ports %08x\n",
|
DBGC ( xhci, "XHCI %p enabling SuperSpeed on ports %08x\n",
|
||||||
xhci, ( usb3prm & ~usb3pssen ) );
|
xhci, ( usb3prm & ~usb3pssen ) );
|
||||||
}
|
}
|
||||||
|
pch->usb3pssen = usb3pssen;
|
||||||
usb3pssen |= usb3prm;
|
usb3pssen |= usb3prm;
|
||||||
pci_write_config_dword ( pci, XHCI_PCH_USB3PSSEN, usb3pssen );
|
pci_write_config_dword ( pci, XHCI_PCH_USB3PSSEN, usb3pssen );
|
||||||
|
|
||||||
|
@ -3044,10 +3046,27 @@ static void xhci_pch ( struct xhci_device *xhci, struct pci_device *pci ) {
|
||||||
DBGC ( xhci, "XHCI %p routing ports %08x from EHCI to xHCI\n",
|
DBGC ( xhci, "XHCI %p routing ports %08x from EHCI to xHCI\n",
|
||||||
xhci, ( xusb2prm & ~xusb2pr ) );
|
xhci, ( xusb2prm & ~xusb2pr ) );
|
||||||
}
|
}
|
||||||
|
pch->xusb2pr = xusb2pr;
|
||||||
xusb2pr |= xusb2prm;
|
xusb2pr |= xusb2prm;
|
||||||
pci_write_config_dword ( pci, XHCI_PCH_XUSB2PR, xusb2pr );
|
pci_write_config_dword ( pci, XHCI_PCH_XUSB2PR, xusb2pr );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Undo Intel PCH-specific quirk fixes
|
||||||
|
*
|
||||||
|
* @v xhci xHCI device
|
||||||
|
* @v pci PCI device
|
||||||
|
*/
|
||||||
|
static void xhci_pch_undo ( struct xhci_device *xhci, struct pci_device *pci ) {
|
||||||
|
struct xhci_pch *pch = &xhci->pch;
|
||||||
|
|
||||||
|
/* Restore USB2 port routing to original state */
|
||||||
|
pci_write_config_dword ( pci, XHCI_PCH_XUSB2PR, pch->xusb2pr );
|
||||||
|
|
||||||
|
/* Restore SuperSpeed capability to original state */
|
||||||
|
pci_write_config_dword ( pci, XHCI_PCH_USB3PSSEN, pch->usb3pssen );
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Probe PCI device
|
* Probe PCI device
|
||||||
*
|
*
|
||||||
|
@ -3091,7 +3110,7 @@ static int xhci_probe ( struct pci_device *pci ) {
|
||||||
|
|
||||||
/* Fix Intel PCH-specific quirks, if applicable */
|
/* Fix Intel PCH-specific quirks, if applicable */
|
||||||
if ( pci->id->driver_data & XHCI_PCH )
|
if ( pci->id->driver_data & XHCI_PCH )
|
||||||
xhci_pch ( xhci, pci );
|
xhci_pch_fix ( xhci, pci );
|
||||||
|
|
||||||
/* Reset device */
|
/* Reset device */
|
||||||
if ( ( rc = xhci_reset ( xhci ) ) != 0 )
|
if ( ( rc = xhci_reset ( xhci ) ) != 0 )
|
||||||
|
@ -3126,6 +3145,8 @@ static int xhci_probe ( struct pci_device *pci ) {
|
||||||
err_alloc_bus:
|
err_alloc_bus:
|
||||||
xhci_reset ( xhci );
|
xhci_reset ( xhci );
|
||||||
err_reset:
|
err_reset:
|
||||||
|
if ( pci->id->driver_data & XHCI_PCH )
|
||||||
|
xhci_pch_undo ( xhci, pci );
|
||||||
xhci_legacy_release ( xhci );
|
xhci_legacy_release ( xhci );
|
||||||
err_legacy_claim:
|
err_legacy_claim:
|
||||||
iounmap ( xhci->regs );
|
iounmap ( xhci->regs );
|
||||||
|
@ -3147,6 +3168,8 @@ static void xhci_remove ( struct pci_device *pci ) {
|
||||||
unregister_usb_bus ( bus );
|
unregister_usb_bus ( bus );
|
||||||
free_usb_bus ( bus );
|
free_usb_bus ( bus );
|
||||||
xhci_reset ( xhci );
|
xhci_reset ( xhci );
|
||||||
|
if ( pci->id->driver_data & XHCI_PCH )
|
||||||
|
xhci_pch_undo ( xhci, pci );
|
||||||
xhci_legacy_release ( xhci );
|
xhci_legacy_release ( xhci );
|
||||||
iounmap ( xhci->regs );
|
iounmap ( xhci->regs );
|
||||||
free ( xhci );
|
free ( xhci );
|
||||||
|
|
|
@ -1004,6 +1004,29 @@ xhci_ring_consumed ( struct xhci_trb_ring *ring ) {
|
||||||
*/
|
*/
|
||||||
#define XHCI_PORT_RESET_MAX_WAIT_MS 500
|
#define XHCI_PORT_RESET_MAX_WAIT_MS 500
|
||||||
|
|
||||||
|
/** Intel PCH quirk */
|
||||||
|
struct xhci_pch {
|
||||||
|
/** USB2 port routing register original value */
|
||||||
|
uint32_t xusb2pr;
|
||||||
|
/** USB3 port SuperSpeed enable register original value */
|
||||||
|
uint32_t usb3pssen;
|
||||||
|
};
|
||||||
|
|
||||||
|
/** Intel PCH quirk flag */
|
||||||
|
#define XHCI_PCH 0x0001
|
||||||
|
|
||||||
|
/** Intel PCH USB2 port routing register */
|
||||||
|
#define XHCI_PCH_XUSB2PR 0xd0
|
||||||
|
|
||||||
|
/** Intel PCH USB2 port routing mask register */
|
||||||
|
#define XHCI_PCH_XUSB2PRM 0xd4
|
||||||
|
|
||||||
|
/** Intel PCH SuperSpeed enable register */
|
||||||
|
#define XHCI_PCH_USB3PSSEN 0xd8
|
||||||
|
|
||||||
|
/** Intel PCH USB3 port routing mask register */
|
||||||
|
#define XHCI_PCH_USB3PRM 0xdc
|
||||||
|
|
||||||
/** An xHCI device */
|
/** An xHCI device */
|
||||||
struct xhci_device {
|
struct xhci_device {
|
||||||
/** Registers */
|
/** Registers */
|
||||||
|
@ -1061,6 +1084,9 @@ struct xhci_device {
|
||||||
|
|
||||||
/** USB bus */
|
/** USB bus */
|
||||||
struct usb_bus *bus;
|
struct usb_bus *bus;
|
||||||
|
|
||||||
|
/** Intel PCH quirk */
|
||||||
|
struct xhci_pch pch;
|
||||||
};
|
};
|
||||||
|
|
||||||
/** An xHCI device slot */
|
/** An xHCI device slot */
|
||||||
|
@ -1103,19 +1129,4 @@ struct xhci_endpoint {
|
||||||
struct xhci_trb_ring ring;
|
struct xhci_trb_ring ring;
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Intel PCH quirk */
|
|
||||||
#define XHCI_PCH 0x0001
|
|
||||||
|
|
||||||
/** Intel PCH USB2 port routing register */
|
|
||||||
#define XHCI_PCH_XUSB2PR 0xd0
|
|
||||||
|
|
||||||
/** Intel PCH USB2 port routing mask register */
|
|
||||||
#define XHCI_PCH_XUSB2PRM 0xd4
|
|
||||||
|
|
||||||
/** Intel PCH USB3 port SuperSpeed enable register */
|
|
||||||
#define XHCI_PCH_USB3PSSEN 0xd8
|
|
||||||
|
|
||||||
/** Intel PCH USB3 port routing mask register */
|
|
||||||
#define XHCI_PCH_USB3PRM 0xdc
|
|
||||||
|
|
||||||
#endif /* _IPXE_XHCI_H */
|
#endif /* _IPXE_XHCI_H */
|
||||||
|
|
Loading…
Reference in New Issue