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

MFC after:	3 days
This commit is contained in:
Marius Strobl 2015-07-27 15:26:50 +00:00
parent 891c57d8a9
commit 43bc87c459
2 changed files with 77 additions and 82 deletions

View File

@ -375,54 +375,12 @@ xhci_start_controller(struct xhci_softc *sc)
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 */
@ -454,29 +412,13 @@ xhci_start_controller(struct xhci_softc *sc)
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);
@ -503,8 +445,7 @@ xhci_start_controller(struct xhci_softc *sc)
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);
@ -615,6 +556,12 @@ xhci_init(struct xhci_softc *sc, device_t self, uint8_t dma32)
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);
@ -633,6 +580,55 @@ xhci_init(struct xhci_softc *sc, device_t self, uint8_t dma32)
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)) {

View File

@ -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)
{
@ -101,6 +100,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 Intel BayTrail USB 3.0 controller");
@ -193,16 +194,28 @@ 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 */
/* Don't use 64-bit DMA on these controllers. */
usedma32 = 1;
break;
case 0x0f358086: /* BayTrail */
case 0x9c318086: /* Panther Point */
case 0x1e318086: /* Panther Point */
case 0x8c318086: /* Lynx Point */
case 0x8cb18086: /* Wildcat Point */
/*
* 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;
/* FALLTHROUGH */
default:
usedma32 = 0;
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,
@ -261,20 +274,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);