|
@@ -3013,6 +3013,41 @@ static struct usb_host_operations xhci_operations = {
|
3013
|
3013
|
},
|
3014
|
3014
|
};
|
3015
|
3015
|
|
|
3016
|
+/**
|
|
3017
|
+ * Fix Intel PCH-specific quirks
|
|
3018
|
+ *
|
|
3019
|
+ * @v xhci xHCI device
|
|
3020
|
+ * @v pci PCI device
|
|
3021
|
+ */
|
|
3022
|
+static void xhci_pch ( struct xhci_device *xhci, struct pci_device *pci ) {
|
|
3023
|
+ uint32_t xusb2pr;
|
|
3024
|
+ uint32_t xusb2prm;
|
|
3025
|
+ uint32_t usb3pssen;
|
|
3026
|
+ uint32_t usb3prm;
|
|
3027
|
+
|
|
3028
|
+ /* Enable SuperSpeed capability. Do this before rerouting
|
|
3029
|
+ * USB2 ports, so that USB3 devices connect at SuperSpeed.
|
|
3030
|
+ */
|
|
3031
|
+ pci_read_config_dword ( pci, XHCI_PCH_USB3PSSEN, &usb3pssen );
|
|
3032
|
+ pci_read_config_dword ( pci, XHCI_PCH_USB3PRM, &usb3prm );
|
|
3033
|
+ if ( usb3prm & ~usb3pssen ) {
|
|
3034
|
+ DBGC ( xhci, "XHCI %p enabling SuperSpeed on ports %08x\n",
|
|
3035
|
+ xhci, ( usb3prm & ~usb3pssen ) );
|
|
3036
|
+ }
|
|
3037
|
+ usb3pssen |= usb3prm;
|
|
3038
|
+ pci_write_config_dword ( pci, XHCI_PCH_USB3PSSEN, usb3pssen );
|
|
3039
|
+
|
|
3040
|
+ /* Route USB2 ports from EHCI to xHCI */
|
|
3041
|
+ pci_read_config_dword ( pci, XHCI_PCH_XUSB2PR, &xusb2pr );
|
|
3042
|
+ pci_read_config_dword ( pci, XHCI_PCH_XUSB2PRM, &xusb2prm );
|
|
3043
|
+ if ( xusb2prm & ~xusb2pr ) {
|
|
3044
|
+ DBGC ( xhci, "XHCI %p routing ports %08x from EHCI to xHCI\n",
|
|
3045
|
+ xhci, ( xusb2prm & ~xusb2pr ) );
|
|
3046
|
+ }
|
|
3047
|
+ xusb2pr |= xusb2prm;
|
|
3048
|
+ pci_write_config_dword ( pci, XHCI_PCH_XUSB2PR, xusb2pr );
|
|
3049
|
+}
|
|
3050
|
+
|
3016
|
3051
|
/**
|
3017
|
3052
|
* Probe PCI device
|
3018
|
3053
|
*
|
|
@@ -3054,6 +3089,10 @@ static int xhci_probe ( struct pci_device *pci ) {
|
3054
|
3089
|
if ( ( rc = xhci_legacy_claim ( xhci ) ) != 0 )
|
3055
|
3090
|
goto err_legacy_claim;
|
3056
|
3091
|
|
|
3092
|
+ /* Fix Intel PCH-specific quirks, if applicable */
|
|
3093
|
+ if ( pci->id->driver_data & XHCI_PCH )
|
|
3094
|
+ xhci_pch ( xhci, pci );
|
|
3095
|
+
|
3057
|
3096
|
/* Reset device */
|
3058
|
3097
|
if ( ( rc = xhci_reset ( xhci ) ) != 0 )
|
3059
|
3098
|
goto err_reset;
|
|
@@ -3115,6 +3154,7 @@ static void xhci_remove ( struct pci_device *pci ) {
|
3115
|
3154
|
|
3116
|
3155
|
/** XHCI PCI device IDs */
|
3117
|
3156
|
static struct pci_device_id xhci_ids[] = {
|
|
3157
|
+ PCI_ROM ( 0x8086, 0xffff, "xhci-pch", "xHCI (Intel PCH)", XHCI_PCH ),
|
3118
|
3158
|
PCI_ROM ( 0xffff, 0xffff, "xhci", "xHCI", 0 ),
|
3119
|
3159
|
};
|
3120
|
3160
|
|