svn commit: r290331 - stable/10/sys/dev/usb/controller

Hans Petter Selasky hselasky at FreeBSD.org
Tue Nov 3 10:24:56 UTC 2015


Author: hselasky
Date: Tue Nov  3 10:24:54 2015
New Revision: 290331
URL: https://svnweb.freebsd.org/changeset/base/290331

Log:
  MFC r285914, r289029 and r289560:
  - Move the remainder of host controller capability registers reading from
    xhci_start_controller() to xhci_init(). These values don't change at run-
    time so there's no point of acquiring them on every USB_HW_POWER_RESUME
    instead of only once during initialization. In r276717, reading the first
    couple of registers in question already had been moved as a prerequisite
    for the changes in that revision.
  - Identify ASMedia ASM1042A controllers.
  - Use NULL instead of 0 for pointers.
  - Add quirks for USB 3.0 PCI devices.
  
  PR:		203650

Modified:
  stable/10/sys/dev/usb/controller/xhci.c
  stable/10/sys/dev/usb/controller/xhci_pci.c
Directory Properties:
  stable/10/   (props changed)

Modified: stable/10/sys/dev/usb/controller/xhci.c
==============================================================================
--- stable/10/sys/dev/usb/controller/xhci.c	Tue Nov  3 10:21:53 2015	(r290330)
+++ stable/10/sys/dev/usb/controller/xhci.c	Tue Nov  3 10:24:54 2015	(r290331)
@@ -380,54 +380,12 @@ xhci_start_controller(struct xhci_softc 
 		return (USB_ERR_IOERROR);
 	}
 
-	if (!(XREAD4(sc, oper, XHCI_PAGESIZE) & XHCI_PAGESIZE_4K)) {
-		device_printf(sc->sc_bus.parent, "Controller does "
-		    "not support 4K page size.\n");
-		return (USB_ERR_IOERROR);
-	}
-
-	temp = XREAD4(sc, capa, XHCI_HCSPARAMS1);
-
-	i = XHCI_HCS1_N_PORTS(temp);
-
-	if (i == 0) {
-		device_printf(sc->sc_bus.parent, "Invalid number "
-		    "of ports: %u\n", i);
-		return (USB_ERR_IOERROR);
-	}
-
-	sc->sc_noport = i;
-	sc->sc_noslot = XHCI_HCS1_DEVSLOT_MAX(temp);
-
-	if (sc->sc_noslot > XHCI_MAX_DEVICES)
-		sc->sc_noslot = XHCI_MAX_DEVICES;
-
 	/* set up number of device slots */
-
 	DPRINTF("CONFIG=0x%08x -> 0x%08x\n",
 	    XREAD4(sc, oper, XHCI_CONFIG), sc->sc_noslot);
 
 	XWRITE4(sc, oper, XHCI_CONFIG, sc->sc_noslot);
 
-	DPRINTF("Max slots: %u\n", sc->sc_noslot);
-
-	temp = XREAD4(sc, capa, XHCI_HCSPARAMS2);
-
-	sc->sc_noscratch = XHCI_HCS2_SPB_MAX(temp);
-
-	if (sc->sc_noscratch > XHCI_MAX_SCRATCHPADS) {
-		device_printf(sc->sc_bus.parent, "XHCI request "
-		    "too many scratchpads\n");
-		return (USB_ERR_NOMEM);
-	}
-
-	DPRINTF("Max scratch: %u\n", sc->sc_noscratch);
-
-	temp = XREAD4(sc, capa, XHCI_HCSPARAMS3);
-
-	sc->sc_exit_lat_max = XHCI_HCS3_U1_DEL(temp) +
-	    XHCI_HCS3_U2_DEL(temp) + 250 /* us */;
-
 	temp = XREAD4(sc, oper, XHCI_USBSTS);
 
 	/* clear interrupts */
@@ -459,29 +417,13 @@ xhci_start_controller(struct xhci_softc 
 	XWRITE4(sc, oper, XHCI_DCBAAP_LO, (uint32_t)addr);
 	XWRITE4(sc, oper, XHCI_DCBAAP_HI, (uint32_t)(addr >> 32));
 
-	/* Setup event table size */
-
-	temp = XREAD4(sc, capa, XHCI_HCSPARAMS2);
-
-	DPRINTF("HCS2=0x%08x\n", temp);
-
-	temp = XHCI_HCS2_ERST_MAX(temp);
-	temp = 1U << temp;
-	if (temp > XHCI_MAX_RSEG)
-		temp = XHCI_MAX_RSEG;
-
-	sc->sc_erst_max = temp;
-
+	/* set up event table size */
 	DPRINTF("ERSTSZ=0x%08x -> 0x%08x\n",
-	    XREAD4(sc, runt, XHCI_ERSTSZ(0)), temp);
+	    XREAD4(sc, runt, XHCI_ERSTSZ(0)), sc->sc_erst_max);
 
-	XWRITE4(sc, runt, XHCI_ERSTSZ(0), XHCI_ERSTS_SET(temp));
+	XWRITE4(sc, runt, XHCI_ERSTSZ(0), XHCI_ERSTS_SET(sc->sc_erst_max));
 
-	/* Check if we should use the default IMOD value */
-	if (sc->sc_imod_default == 0)
-		sc->sc_imod_default = XHCI_IMOD_DEFAULT;
-
-	/* Setup interrupt rate */
+	/* set up interrupt rate */
 	XWRITE4(sc, runt, XHCI_IMOD(0), sc->sc_imod_default);
 
 	usbd_get_page(&sc->sc_hw.root_pc, 0, &buf_res);
@@ -508,8 +450,7 @@ xhci_start_controller(struct xhci_softc 
 	XWRITE4(sc, runt, XHCI_ERSTBA_LO(0), (uint32_t)addr);
 	XWRITE4(sc, runt, XHCI_ERSTBA_HI(0), (uint32_t)(addr >> 32));
 
-	/* Setup interrupter registers */
-
+	/* set up interrupter registers */
 	temp = XREAD4(sc, runt, XHCI_IMAN(0));
 	temp |= XHCI_IMAN_INTR_ENA;
 	XWRITE4(sc, runt, XHCI_IMAN(0), temp);
@@ -620,6 +561,12 @@ xhci_init(struct xhci_softc *sc, device_
 
 	DPRINTF("xHCI version = 0x%04x\n", XREAD2(sc, capa, XHCI_HCIVERSION));
 
+	if (!(XREAD4(sc, oper, XHCI_PAGESIZE) & XHCI_PAGESIZE_4K)) {
+		device_printf(sc->sc_bus.parent, "Controller does "
+		    "not support 4K page size.\n");
+		return (ENXIO);
+	}
+
 	temp = XREAD4(sc, capa, XHCI_HCSPARAMS0);
 
 	DPRINTF("HCS0 = 0x%08x\n", temp);
@@ -638,6 +585,55 @@ xhci_init(struct xhci_softc *sc, device_
 	device_printf(self, "%d bytes context size, %d-bit DMA\n",
 	    sc->sc_ctx_is_64_byte ? 64 : 32, (int)sc->sc_bus.dma_bits);
 
+	temp = XREAD4(sc, capa, XHCI_HCSPARAMS1);
+
+	/* get number of device slots */
+	sc->sc_noport = XHCI_HCS1_N_PORTS(temp);
+
+	if (sc->sc_noport == 0) {
+		device_printf(sc->sc_bus.parent, "Invalid number "
+		    "of ports: %u\n", sc->sc_noport);
+		return (ENXIO);
+	}
+
+	sc->sc_noport = sc->sc_noport;
+	sc->sc_noslot = XHCI_HCS1_DEVSLOT_MAX(temp);
+
+	DPRINTF("Max slots: %u\n", sc->sc_noslot);
+
+	if (sc->sc_noslot > XHCI_MAX_DEVICES)
+		sc->sc_noslot = XHCI_MAX_DEVICES;
+
+	temp = XREAD4(sc, capa, XHCI_HCSPARAMS2);
+
+	DPRINTF("HCS2=0x%08x\n", temp);
+
+	/* get number of scratchpads */
+	sc->sc_noscratch = XHCI_HCS2_SPB_MAX(temp);
+
+	if (sc->sc_noscratch > XHCI_MAX_SCRATCHPADS) {
+		device_printf(sc->sc_bus.parent, "XHCI request "
+		    "too many scratchpads\n");
+		return (ENOMEM);
+	}
+
+	DPRINTF("Max scratch: %u\n", sc->sc_noscratch);
+
+	/* get event table size */
+	sc->sc_erst_max = 1U << XHCI_HCS2_ERST_MAX(temp);
+	if (sc->sc_erst_max > XHCI_MAX_RSEG)
+		sc->sc_erst_max = XHCI_MAX_RSEG;
+
+	temp = XREAD4(sc, capa, XHCI_HCSPARAMS3);
+
+	/* get maximum exit latency */
+	sc->sc_exit_lat_max = XHCI_HCS3_U1_DEL(temp) +
+	    XHCI_HCS3_U2_DEL(temp) + 250 /* us */;
+
+	/* Check if we should use the default IMOD value. */
+	if (sc->sc_imod_default == 0)
+		sc->sc_imod_default = XHCI_IMOD_DEFAULT;
+
 	/* get all DMA memory */
 	if (usb_bus_mem_alloc_all(&sc->sc_bus,
 	    USB_GET_DMA_TAG(self), &xhci_iterate_hw_softc)) {

Modified: stable/10/sys/dev/usb/controller/xhci_pci.c
==============================================================================
--- stable/10/sys/dev/usb/controller/xhci_pci.c	Tue Nov  3 10:21:53 2015	(r290330)
+++ stable/10/sys/dev/usb/controller/xhci_pci.c	Tue Nov  3 10:24:54 2015	(r290331)
@@ -86,10 +86,9 @@ static driver_t xhci_driver = {
 
 static devclass_t xhci_devclass;
 
-DRIVER_MODULE(xhci, pci, xhci_driver, xhci_devclass, 0, 0);
+DRIVER_MODULE(xhci, pci, xhci_driver, xhci_devclass, NULL, NULL);
 MODULE_DEPEND(xhci, usb, 1, 1, 1);
 
-
 static const char *
 xhci_pci_match(device_t self)
 {
@@ -104,6 +103,8 @@ xhci_pci_match(device_t self)
 
 	case 0x10421b21:
 		return ("ASMedia ASM1042 USB 3.0 controller");
+	case 0x11421b21:
+		return ("ASMedia ASM1042A USB 3.0 controller");
 
 	case 0x0f358086:
 		return ("Intel BayTrail USB 3.0 controller");
@@ -114,6 +115,8 @@ xhci_pci_match(device_t self)
 		return ("Intel Lynx Point USB 3.0 controller");
 	case 0x8cb18086:
 		return ("Intel Wildcat Point USB 3.0 controller");
+	case 0x9cb18086:
+		return ("Broadwell Integrated PCH-LP chipset USB 3.0 controller");
 
 	case 0xa01b177d:
 		return ("Cavium ThunderX USB 3.0 controller");
@@ -200,17 +203,31 @@ xhci_pci_attach(device_t self)
 	sc->sc_io_hdl = rman_get_bushandle(sc->sc_io_res);
 	sc->sc_io_size = rman_get_size(sc->sc_io_res);
 
-	/* check for USB 3.0 controllers which don't support 64-bit DMA */
 	switch (pci_get_devid(self)) {
 	case 0x01941033:	/* NEC uPD720200 USB 3.0 controller */
+	case 0x00141912:	/* NEC uPD720201 USB 3.0 controller */
+		/* Don't use 64-bit DMA on these controllers. */
 		usedma32 = 1;
 		break;
 	case 0x10001b73:	/* FL1000G */
 		/* Fresco Logic host doesn't support MSI. */
 		usemsi = 0;
 		break;
+	case 0x0f358086:	/* BayTrail */
+	case 0x9c318086:	/* Panther Point */
+	case 0x1e318086:	/* Panther Point */
+	case 0x8c318086:	/* Lynx Point */
+	case 0x8cb18086:	/* Wildcat Point */
+	case 0x9cb18086:	/* Broadwell Mobile Integrated */
+		/*
+		 * On Intel chipsets, reroute ports from EHCI to XHCI
+		 * controller and use a different IMOD value.
+		 */
+		sc->sc_port_route = &xhci_pci_port_route;
+		sc->sc_imod_default = XHCI_IMOD_DEFAULT_LP;
+		break;
 	}
-	
+
 	if (xhci_init(sc, self, usedma32)) {
 		device_printf(self, "Could not initialize softc\n");
 		bus_release_resource(self, SYS_RES_MEMORY, PCI_XHCI_CBMEM,
@@ -269,20 +286,6 @@ xhci_pci_attach(device_t self)
 			goto error;
 	}
 
-	/* On Intel chipsets reroute ports from EHCI to XHCI controller. */
-	switch (pci_get_devid(self)) {
-	case 0x0f358086:	/* BayTrail */
-	case 0x9c318086:	/* Panther Point */
-	case 0x1e318086:	/* Panther Point */
-	case 0x8c318086:	/* Lynx Point */
-	case 0x8cb18086:	/* Wildcat Point */
-		sc->sc_port_route = &xhci_pci_port_route;
-		sc->sc_imod_default = XHCI_IMOD_DEFAULT_LP;
-		break;
-	default:
-		break;
-	}
-
 	xhci_pci_take_controller(self);
 
 	err = xhci_halt_controller(sc);


More information about the svn-src-all mailing list