|  | @@ -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 |  
 |