瀏覽代碼

[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>
tags/v1.20.1
Michael Brown 10 年之前
父節點
當前提交
e905cdcce3
共有 2 個檔案被更改,包括 51 行新增17 行删除
  1. 25
    2
      src/drivers/usb/xhci.c
  2. 26
    15
      src/drivers/usb/xhci.h

+ 25
- 2
src/drivers/usb/xhci.c 查看文件

3019
  * @v xhci		xHCI device
3019
  * @v xhci		xHCI device
3020
  * @v pci		PCI device
3020
  * @v pci		PCI device
3021
  */
3021
  */
3022
-static void xhci_pch ( struct xhci_device *xhci, struct pci_device *pci ) {
3022
+static void xhci_pch_fix ( struct xhci_device *xhci, struct pci_device *pci ) {
3023
+	struct xhci_pch *pch = &xhci->pch;
3023
 	uint32_t xusb2pr;
3024
 	uint32_t xusb2pr;
3024
 	uint32_t xusb2prm;
3025
 	uint32_t xusb2prm;
3025
 	uint32_t usb3pssen;
3026
 	uint32_t usb3pssen;
3034
 		DBGC ( xhci, "XHCI %p enabling SuperSpeed on ports %08x\n",
3035
 		DBGC ( xhci, "XHCI %p enabling SuperSpeed on ports %08x\n",
3035
 		       xhci, ( usb3prm & ~usb3pssen ) );
3036
 		       xhci, ( usb3prm & ~usb3pssen ) );
3036
 	}
3037
 	}
3038
+	pch->usb3pssen = usb3pssen;
3037
 	usb3pssen |= usb3prm;
3039
 	usb3pssen |= usb3prm;
3038
 	pci_write_config_dword ( pci, XHCI_PCH_USB3PSSEN, usb3pssen );
3040
 	pci_write_config_dword ( pci, XHCI_PCH_USB3PSSEN, usb3pssen );
3039
 
3041
 
3044
 		DBGC ( xhci, "XHCI %p routing ports %08x from EHCI to xHCI\n",
3046
 		DBGC ( xhci, "XHCI %p routing ports %08x from EHCI to xHCI\n",
3045
 		       xhci, ( xusb2prm & ~xusb2pr ) );
3047
 		       xhci, ( xusb2prm & ~xusb2pr ) );
3046
 	}
3048
 	}
3049
+	pch->xusb2pr = xusb2pr;
3047
 	xusb2pr |= xusb2prm;
3050
 	xusb2pr |= xusb2prm;
3048
 	pci_write_config_dword ( pci, XHCI_PCH_XUSB2PR, xusb2pr );
3051
 	pci_write_config_dword ( pci, XHCI_PCH_XUSB2PR, xusb2pr );
3049
 }
3052
 }
3050
 
3053
 
3054
+/**
3055
+ * Undo Intel PCH-specific quirk fixes
3056
+ *
3057
+ * @v xhci		xHCI device
3058
+ * @v pci		PCI device
3059
+ */
3060
+static void xhci_pch_undo ( struct xhci_device *xhci, struct pci_device *pci ) {
3061
+	struct xhci_pch *pch = &xhci->pch;
3062
+
3063
+	/* Restore USB2 port routing to original state */
3064
+	pci_write_config_dword ( pci, XHCI_PCH_XUSB2PR, pch->xusb2pr );
3065
+
3066
+	/* Restore SuperSpeed capability to original state */
3067
+	pci_write_config_dword ( pci, XHCI_PCH_USB3PSSEN, pch->usb3pssen );
3068
+}
3069
+
3051
 /**
3070
 /**
3052
  * Probe PCI device
3071
  * Probe PCI device
3053
  *
3072
  *
3091
 
3110
 
3092
 	/* Fix Intel PCH-specific quirks, if applicable */
3111
 	/* Fix Intel PCH-specific quirks, if applicable */
3093
 	if ( pci->id->driver_data & XHCI_PCH )
3112
 	if ( pci->id->driver_data & XHCI_PCH )
3094
-		xhci_pch ( xhci, pci );
3113
+		xhci_pch_fix ( xhci, pci );
3095
 
3114
 
3096
 	/* Reset device */
3115
 	/* Reset device */
3097
 	if ( ( rc = xhci_reset ( xhci ) ) != 0 )
3116
 	if ( ( rc = xhci_reset ( xhci ) ) != 0 )
3126
  err_alloc_bus:
3145
  err_alloc_bus:
3127
 	xhci_reset ( xhci );
3146
 	xhci_reset ( xhci );
3128
  err_reset:
3147
  err_reset:
3148
+	if ( pci->id->driver_data & XHCI_PCH )
3149
+		xhci_pch_undo ( xhci, pci );
3129
 	xhci_legacy_release ( xhci );
3150
 	xhci_legacy_release ( xhci );
3130
  err_legacy_claim:
3151
  err_legacy_claim:
3131
 	iounmap ( xhci->regs );
3152
 	iounmap ( xhci->regs );
3147
 	unregister_usb_bus ( bus );
3168
 	unregister_usb_bus ( bus );
3148
 	free_usb_bus ( bus );
3169
 	free_usb_bus ( bus );
3149
 	xhci_reset ( xhci );
3170
 	xhci_reset ( xhci );
3171
+	if ( pci->id->driver_data & XHCI_PCH )
3172
+		xhci_pch_undo ( xhci, pci );
3150
 	xhci_legacy_release ( xhci );
3173
 	xhci_legacy_release ( xhci );
3151
 	iounmap ( xhci->regs );
3174
 	iounmap ( xhci->regs );
3152
 	free ( xhci );
3175
 	free ( xhci );

+ 26
- 15
src/drivers/usb/xhci.h 查看文件

1004
  */
1004
  */
1005
 #define XHCI_PORT_RESET_MAX_WAIT_MS 500
1005
 #define XHCI_PORT_RESET_MAX_WAIT_MS 500
1006
 
1006
 
1007
+/** Intel PCH quirk */
1008
+struct xhci_pch {
1009
+	/** USB2 port routing register original value */
1010
+	uint32_t xusb2pr;
1011
+	/** USB3 port SuperSpeed enable register original value */
1012
+	uint32_t usb3pssen;
1013
+};
1014
+
1015
+/** Intel PCH quirk flag */
1016
+#define XHCI_PCH 0x0001
1017
+
1018
+/** Intel PCH USB2 port routing register */
1019
+#define XHCI_PCH_XUSB2PR 0xd0
1020
+
1021
+/** Intel PCH USB2 port routing mask register */
1022
+#define XHCI_PCH_XUSB2PRM 0xd4
1023
+
1024
+/** Intel PCH SuperSpeed enable register */
1025
+#define XHCI_PCH_USB3PSSEN 0xd8
1026
+
1027
+/** Intel PCH USB3 port routing mask register */
1028
+#define XHCI_PCH_USB3PRM 0xdc
1029
+
1007
 /** An xHCI device */
1030
 /** An xHCI device */
1008
 struct xhci_device {
1031
 struct xhci_device {
1009
 	/** Registers */
1032
 	/** Registers */
1061
 
1084
 
1062
 	/** USB bus */
1085
 	/** USB bus */
1063
 	struct usb_bus *bus;
1086
 	struct usb_bus *bus;
1087
+
1088
+	/** Intel PCH quirk */
1089
+	struct xhci_pch pch;
1064
 };
1090
 };
1065
 
1091
 
1066
 /** An xHCI device slot */
1092
 /** An xHCI device slot */
1103
 	struct xhci_trb_ring ring;
1129
 	struct xhci_trb_ring ring;
1104
 };
1130
 };
1105
 
1131
 
1106
-/** Intel PCH quirk */
1107
-#define XHCI_PCH 0x0001
1108
-
1109
-/** Intel PCH USB2 port routing register */
1110
-#define XHCI_PCH_XUSB2PR 0xd0
1111
-
1112
-/** Intel PCH USB2 port routing mask register */
1113
-#define XHCI_PCH_XUSB2PRM 0xd4
1114
-
1115
-/** Intel PCH USB3 port SuperSpeed enable register */
1116
-#define XHCI_PCH_USB3PSSEN 0xd8
1117
-
1118
-/** Intel PCH USB3 port routing mask register */
1119
-#define XHCI_PCH_USB3PRM 0xdc
1120
-
1121
 #endif /* _IPXE_XHCI_H */
1132
 #endif /* _IPXE_XHCI_H */

Loading…
取消
儲存