diff options
Diffstat (limited to 'sys/dev/usb/uhci.c')
-rw-r--r-- | sys/dev/usb/uhci.c | 139 |
1 files changed, 69 insertions, 70 deletions
diff --git a/sys/dev/usb/uhci.c b/sys/dev/usb/uhci.c index afe28a6..4c3e77d 100644 --- a/sys/dev/usb/uhci.c +++ b/sys/dev/usb/uhci.c @@ -154,7 +154,7 @@ struct uhci_pipe { } u; }; -/* +/* * The uhci_intr_info free list can be global since they contain * no dma specific data. The other free lists do. */ @@ -170,10 +170,10 @@ Static void uhci_free_sqh(uhci_softc_t *, uhci_soft_qh_t *); Static uhci_intr_info_t *uhci_alloc_intr_info(uhci_softc_t *); Static void uhci_free_intr_info(uhci_intr_info_t *ii); -Static void uhci_free_std_chain(uhci_softc_t *, +Static void uhci_free_std_chain(uhci_softc_t *, uhci_soft_td_t *, uhci_soft_td_t *); Static usbd_status uhci_alloc_std_chain(struct uhci_pipe *, - uhci_softc_t *, int, int, u_int16_t, usb_dma_t *, + uhci_softc_t *, int, int, u_int16_t, usb_dma_t *, uhci_soft_td_t **, uhci_soft_td_t **); Static void uhci_timo(void *); Static void uhci_waitintr(uhci_softc_t *, usbd_xfer_handle); @@ -243,13 +243,13 @@ Static void uhci_root_intr_done(usbd_xfer_handle); Static usbd_status uhci_open(usbd_pipe_handle); Static void uhci_poll(struct usbd_bus *); -Static void uhci_softintr __P((struct usbd_bus *)); +Static void uhci_softintr(struct usbd_bus *); Static usbd_status uhci_device_request(usbd_xfer_handle xfer); Static void uhci_add_intr(uhci_softc_t *, int, uhci_soft_qh_t *); Static void uhci_remove_intr(uhci_softc_t *, int, uhci_soft_qh_t *); -Static usbd_status uhci_device_setintr(uhci_softc_t *sc, +Static usbd_status uhci_device_setintr(uhci_softc_t *sc, struct uhci_pipe *pipe, int ival); Static void uhci_device_clear_toggle(usbd_pipe_handle pipe); @@ -296,7 +296,7 @@ struct usbd_bus_methods uhci_bus_methods = { uhci_freex, }; -struct usbd_pipe_methods uhci_root_ctrl_methods = { +struct usbd_pipe_methods uhci_root_ctrl_methods = { uhci_root_ctrl_transfer, uhci_root_ctrl_start, uhci_root_ctrl_abort, @@ -305,7 +305,7 @@ struct usbd_pipe_methods uhci_root_ctrl_methods = { uhci_root_ctrl_done, }; -struct usbd_pipe_methods uhci_root_intr_methods = { +struct usbd_pipe_methods uhci_root_intr_methods = { uhci_root_intr_transfer, uhci_root_intr_start, uhci_root_intr_abort, @@ -356,7 +356,7 @@ uhci_find_prev_qh(uhci_soft_qh_t *pqh, uhci_soft_qh_t *sqh) DPRINTFN(15,("uhci_find_prev_qh: pqh=%p sqh=%p\n", pqh, sqh)); for (; pqh->hlink != sqh; pqh = pqh->hlink) { -#if defined(DIAGNOSTIC) || defined(UHCI_DEBUG) +#if defined(DIAGNOSTIC) || defined(UHCI_DEBUG) if (le32toh(pqh->qh.qh_hlink) & UHCI_PTR_T) { printf("uhci_find_prev_qh: QH not found\n"); return (NULL); @@ -397,7 +397,7 @@ uhci_init(uhci_softc_t *sc) uhci_busreset(sc); /* Allocate and initialize real frame array. */ - err = usb_allocmem(&sc->sc_bus, + err = usb_allocmem(&sc->sc_bus, UHCI_FRAMELIST_COUNT * sizeof(uhci_physaddr_t), UHCI_FRAMELIST_ALIGN, &sc->sc_dma); if (err) @@ -406,7 +406,7 @@ uhci_init(uhci_softc_t *sc) UWRITE2(sc, UHCI_FRNUM, 0); /* set frame number to 0 */ UWRITE4(sc, UHCI_FLBASEADDR, DMAADDR(&sc->sc_dma, 0)); /* set frame list*/ - /* + /* * Allocate a TD, inactive, that hangs from the last QH. * This is to avoid a bug in the PIIX that makes it run berserk * otherwise. @@ -419,7 +419,7 @@ uhci_init(uhci_softc_t *sc) std->td.td_status = htole32(0); /* inactive */ std->td.td_token = htole32(0); std->td.td_buffer = htole32(0); - + /* Allocate the dummy QH marking the end and used for looping the QHs.*/ lsqh = uhci_alloc_sqh(sc); if (lsqh == NULL) @@ -449,7 +449,7 @@ uhci_init(uhci_softc_t *sc) chsqh->elink = NULL; chsqh->qh.qh_elink = htole32(UHCI_PTR_T); sc->sc_hctl_start = sc->sc_hctl_end = chsqh; - + /* Allocate dummy QH where control traffic will be queued. */ clsqh = uhci_alloc_sqh(sc); if (clsqh == NULL) @@ -460,7 +460,7 @@ uhci_init(uhci_softc_t *sc) clsqh->qh.qh_elink = htole32(UHCI_PTR_T); sc->sc_lctl_start = sc->sc_lctl_end = clsqh; - /* + /* * Make all (virtual) frame list pointers point to the interrupt * queue heads and the interrupt queue heads at the control * queue head and point the physical frame list to the virtual. @@ -483,8 +483,8 @@ uhci_init(uhci_softc_t *sc) sc->sc_vframes[i].etd = std; sc->sc_vframes[i].hqh = sqh; sc->sc_vframes[i].eqh = sqh; - for (j = i; - j < UHCI_FRAMELIST_COUNT; + for (j = i; + j < UHCI_FRAMELIST_COUNT; j += UHCI_VFRAMELIST_COUNT) sc->sc_pframes[j] = htole32(std->physaddr); } @@ -504,7 +504,7 @@ uhci_init(uhci_softc_t *sc) #endif DPRINTFN(1,("uhci_init: enabling\n")); - UWRITE2(sc, UHCI_INTR, UHCI_INTR_TOCRCIE | UHCI_INTR_RIE | + UWRITE2(sc, UHCI_INTR, UHCI_INTR_TOCRCIE | UHCI_INTR_RIE | UHCI_INTR_IOCE | UHCI_INTR_SPIE); /* enable interrupts */ UHCICMD(sc, UHCI_CMD_MAXP); /* Assume 64 byte packets at frame end */ @@ -540,7 +540,7 @@ uhci_detach(struct uhci_softc *sc, int flags) if (sc->sc_child != NULL) rv = config_detach(sc->sc_child, flags); - + if (rv != 0) return (rv); @@ -556,7 +556,7 @@ uhci_detach(struct uhci_softc *sc, int flags) break; SIMPLEQ_REMOVE_HEAD(&sc->sc_free_xfers, xfer, next); free(xfer, M_USB); - } + } /* XXX free other data structures XXX */ @@ -630,7 +630,7 @@ uhci_power(int why, void *v) s = splusb(); cmd = UREAD2(sc, UHCI_CMD); - DPRINTF(("uhci_power: sc=%p, why=%d (was %d), cmd=0x%x\n", + DPRINTF(("uhci_power: sc=%p, why=%d (was %d), cmd=0x%x\n", sc, why, sc->sc_suspend, cmd)); if (why != PWR_RESUME) { @@ -639,7 +639,7 @@ uhci_power(int why, void *v) uhci_dumpregs(sc); #endif if (sc->sc_has_timo != NULL) - usb_untimeout(uhci_timo, sc->sc_has_timo, + usb_untimeout(uhci_timo, sc->sc_has_timo, sc->sc_has_timo->timo_handle); sc->sc_bus.use_polling++; uhci_run(sc, 0); /* stop the controller */ @@ -671,13 +671,13 @@ uhci_power(int why, void *v) UHCICMD(sc, cmd | UHCI_CMD_FGR); /* force global resume */ usb_delay_ms(&sc->sc_bus, USB_RESUME_DELAY); UHCICMD(sc, cmd & ~UHCI_CMD_EGSM); /* back to normal */ - UWRITE2(sc, UHCI_INTR, UHCI_INTR_TOCRCIE | UHCI_INTR_RIE | + UWRITE2(sc, UHCI_INTR, UHCI_INTR_TOCRCIE | UHCI_INTR_RIE | UHCI_INTR_IOCE | UHCI_INTR_SPIE); /* re-enable intrs */ uhci_run(sc, 1); /* and start traffic again */ usb_delay_ms(&sc->sc_bus, USB_RESUME_RECOVERY); sc->sc_bus.use_polling--; if (sc->sc_has_timo != NULL) - usb_timeout(uhci_timo, sc->sc_has_timo, + usb_timeout(uhci_timo, sc->sc_has_timo, sc->sc_ival, sc->sc_has_timo->timo_handle); #ifdef UHCI_DEBUG if (uhcidebug > 2) @@ -923,7 +923,7 @@ uhci_add_loop(uhci_softc_t *sc) { if (++sc->sc_loops == 1) { DPRINTFN(5,("uhci_start_loop: add\n")); /* Note, we don't loop back the soft pointer. */ - sc->sc_last_qh->qh.qh_hlink = + sc->sc_last_qh->qh.qh_hlink = htole32(sc->sc_hctl_start->physaddr | UHCI_PTR_QH); } } @@ -998,9 +998,9 @@ void uhci_add_ls_ctrl(uhci_softc_t *sc, uhci_soft_qh_t *sqh) { uhci_soft_qh_t *eqh; - + SPLUSBCHECK; - + DPRINTFN(10, ("uhci_add_ls_ctrl: sqh=%p\n", sqh)); eqh = sc->sc_lctl_end; sqh->hlink = eqh->hlink; @@ -1015,9 +1015,9 @@ void uhci_remove_ls_ctrl(uhci_softc_t *sc, uhci_soft_qh_t *sqh) { uhci_soft_qh_t *pqh; - + SPLUSBCHECK; - + DPRINTFN(10, ("uhci_remove_ls_ctrl: sqh=%p\n", sqh)); /* See comment in uhci_remove_hs_ctrl() */ if (!(sqh->qh.qh_elink & htole32(UHCI_PTR_T))) { @@ -1129,12 +1129,12 @@ uhci_intr(void *arg) } if (status & UHCI_STS_HCPE) { ack |= UHCI_STS_HCPE; - printf("%s: host controller process error\n", + printf("%s: host controller process error\n", USBDEVNAME(sc->sc_bus.bdev)); } if (status & UHCI_STS_HCH) { /* no acknowledge needed */ - printf("%s: host controller halted\n", + printf("%s: host controller halted\n", USBDEVNAME(sc->sc_bus.bdev)); sc->sc_dying = 1; } @@ -1156,8 +1156,7 @@ uhci_intr(void *arg) } void -uhci_softintr(bus) - struct usbd_bus *bus; +uhci_softintr(struct usbd_bus *bus) { uhci_softc_t *sc = (uhci_softc_t *)bus; uhci_intr_info_t *ii; @@ -1206,7 +1205,7 @@ uhci_check_intr(uhci_softc_t *sc, uhci_intr_info_t *ii) return; } #endif - /* + /* * If the last TD is still active we need to check whether there * is a an error somewhere in the middle, or whether there was a * short packet (SPD and not ACTIVE). @@ -1223,7 +1222,7 @@ uhci_check_intr(uhci_softc_t *sc, uhci_intr_info_t *ii) goto done; /* We want short packets, and it is short: it's done */ if ((status & UHCI_TD_SPD) && - UHCI_TD_GET_ACTLEN(status) < + UHCI_TD_GET_ACTLEN(status) < UHCI_TD_GET_MAXLEN(le32toh(std->td.td_token))) goto done; } @@ -1327,7 +1326,7 @@ uhci_idone(uhci_intr_info_t *ii) upipe->nexttoggle = UHCI_TD_GET_DT(le32toh(std->td.td_token)); status &= UHCI_TD_ERROR; - DPRINTFN(10, ("uhci_check_intr: actlen=%d, status=0x%x\n", + DPRINTFN(10, ("uhci_check_intr: actlen=%d, status=0x%x\n", actlen, status)); xfer->actlen = actlen; if (status != 0) { @@ -1408,7 +1407,7 @@ uhci_waitintr(uhci_softc_t *sc, usbd_xfer_handle xfer) /* Timeout */ DPRINTF(("uhci_waitintr: timeout\n")); for (ii = LIST_FIRST(&sc->sc_intrhead); - ii != NULL && ii->xfer != xfer; + ii != NULL && ii->xfer != xfer; ii = LIST_NEXT(ii, list)) ; #ifdef DIAGNOSTIC @@ -1434,11 +1433,11 @@ uhci_reset(uhci_softc_t *sc) UHCICMD(sc, UHCI_CMD_HCRESET); /* The reset bit goes low when the controller is done. */ - for (n = 0; n < UHCI_RESET_TIMEOUT && + for (n = 0; n < UHCI_RESET_TIMEOUT && (UREAD2(sc, UHCI_CMD) & UHCI_CMD_HCRESET); n++) usb_delay_ms(&sc->sc_bus, 1); if (n >= UHCI_RESET_TIMEOUT) - printf("%s: controller did not reset\n", + printf("%s: controller did not reset\n", USBDEVNAME(sc->sc_bus.bdev)); } @@ -1587,7 +1586,7 @@ uhci_alloc_std_chain(struct uhci_pipe *upipe, uhci_softc_t *sc, int len, int endpt = upipe->pipe.endpoint->edesc->bEndpointAddress; DPRINTFN(8, ("uhci_alloc_std_chain: addr=%d endpt=%d len=%d ls=%d " - "flags=0x%x\n", addr, UE_GET_ADDR(endpt), len, + "flags=0x%x\n", addr, UE_GET_ADDR(endpt), len, upipe->pipe.device->lowspeed, flags)); maxp = UGETW(upipe->pipe.endpoint->edesc->wMaxPacketSize); if (maxp == 0) { @@ -1634,14 +1633,14 @@ uhci_alloc_std_chain(struct uhci_pipe *upipe, uhci_softc_t *sc, int len, *ep = p; } else l = maxp; - p->td.td_token = + p->td.td_token = htole32(rd ? UHCI_TD_IN (l, endpt, addr, tog) : UHCI_TD_OUT(l, endpt, addr, tog)); p->td.td_buffer = htole32(DMAADDR(dma, i * maxp)); tog ^= 1; } *sp = lastp; - DPRINTFN(10, ("uhci_alloc_std_chain: nexttog=%d\n", + DPRINTFN(10, ("uhci_alloc_std_chain: nexttog=%d\n", upipe->nexttoggle)); return (USBD_NORMAL_COMPLETION); } @@ -1668,7 +1667,7 @@ uhci_device_bulk_transfer(usbd_xfer_handle xfer) if (err) return (err); - /* + /* * Pipe isn't running (otherwise err would be USBD_INPROG), * so start it first. */ @@ -1843,7 +1842,7 @@ uhci_device_ctrl_transfer(usbd_xfer_handle xfer) if (err) return (err); - /* + /* * Pipe isn't running (otherwise err would be USBD_INPROG), * so start it first. */ @@ -1883,7 +1882,7 @@ uhci_device_intr_transfer(usbd_xfer_handle xfer) if (err) return (err); - /* + /* * Pipe isn't running (otherwise err would be USBD_INPROG), * so start it first. */ @@ -1942,7 +1941,7 @@ uhci_device_intr_start(usbd_xfer_handle xfer) ii->isdone = 0; #endif - DPRINTFN(10,("uhci_device_intr_transfer: qhs[0]=%p\n", + DPRINTFN(10,("uhci_device_intr_transfer: qhs[0]=%p\n", upipe->u.intr.qhs[0])); for (i = 0; i < upipe->u.intr.npoll; i++) { sqh = upipe->u.intr.qhs[i]; @@ -2006,11 +2005,11 @@ uhci_device_intr_close(usbd_pipe_handle pipe) npoll = upipe->u.intr.npoll; uhci_lock_frames(sc); for (i = 0; i < npoll; i++) - uhci_remove_intr(sc, upipe->u.intr.qhs[i]->pos, + uhci_remove_intr(sc, upipe->u.intr.qhs[i]->pos, upipe->u.intr.qhs[i]); uhci_unlock_frames(sc); - /* + /* * We now have to wait for any activity on the physical * descriptors to stop. */ @@ -2086,9 +2085,9 @@ uhci_device_request(usbd_xfer_handle xfer) stat->link.std = NULL; stat->td.td_link = htole32(UHCI_PTR_T); - stat->td.td_status = htole32(UHCI_TD_SET_ERRCNT(3) | ls | + stat->td.td_status = htole32(UHCI_TD_SET_ERRCNT(3) | ls | UHCI_TD_ACTIVE | UHCI_TD_IOC); - stat->td.td_token = + stat->td.td_token = htole32(isread ? UHCI_TD_OUT(0, endpt, addr, 1) : UHCI_TD_IN (0, endpt, addr, 1)); stat->td.td_buffer = htole32(0); @@ -2142,7 +2141,7 @@ uhci_device_request(usbd_xfer_handle xfer) uhci_dump_qh(sxqh); for (xqh = sxqh; xqh != NULL; - xqh = (maxqh++ == 5 || xqh->hlink == sxqh || + xqh = (maxqh++ == 5 || xqh->hlink == sxqh || xqh->hlink == xqh ? NULL : xqh->hlink)) { uhci_dump_qh(xqh); } @@ -2193,7 +2192,7 @@ uhci_device_isoc_enter(usbd_xfer_handle xfer) usbd_device_handle dev = upipe->pipe.device; uhci_softc_t *sc = (uhci_softc_t *)dev->bus; struct iso *iso = &upipe->u.iso; - uhci_soft_td_t *std; + uhci_soft_td_t *std; u_int32_t buf, len, status; int s, i, next, nframes; @@ -2289,7 +2288,7 @@ uhci_device_isoc_start(usbd_xfer_handle xfer) #endif s = splusb(); - + /* Set up interrupt info. */ ii->xfer = xfer; ii->stdstart = end; @@ -2303,7 +2302,7 @@ uhci_device_isoc_start(usbd_xfer_handle xfer) ii->isdone = 0; #endif LIST_INSERT_HEAD(&sc->sc_intrhead, ii, list); - + splx(s); return (USBD_IN_PROGRESS); @@ -2603,7 +2602,7 @@ uhci_remove_intr(uhci_softc_t *sc, int n, uhci_soft_qh_t *sqh) } for (pqh = vf->hqh; pqh->hlink != sqh; pqh = pqh->hlink) -#if defined(DIAGNOSTIC) || defined(UHCI_DEBUG) +#if defined(DIAGNOSTIC) || defined(UHCI_DEBUG) if (le32toh(pqh->qh.qh_hlink) & UHCI_PTR_T) { DPRINTF(("uhci_remove_intr: QH not found\n")); return; @@ -2638,10 +2637,10 @@ uhci_device_setintr(uhci_softc_t *sc, struct uhci_pipe *upipe, int ival) DPRINTFN(2, ("uhci_setintr: ival=%d npoll=%d\n", ival, npoll)); upipe->u.intr.npoll = npoll; - upipe->u.intr.qhs = + upipe->u.intr.qhs = malloc(npoll * sizeof(uhci_soft_qh_t *), M_USBHC, M_WAITOK); - /* + /* * Figure out which offset in the schedule that has most * bandwidth left over. */ @@ -2673,7 +2672,7 @@ uhci_device_setintr(uhci_softc_t *sc, struct uhci_pipe *upipe, int ival) uhci_lock_frames(sc); /* Enter QHs into the controller data structures. */ for(i = 0; i < npoll; i++) - uhci_add_intr(sc, upipe->u.intr.qhs[i]->pos, + uhci_add_intr(sc, upipe->u.intr.qhs[i]->pos, upipe->u.intr.qhs[i]); uhci_unlock_frames(sc); @@ -2692,7 +2691,7 @@ uhci_open(usbd_pipe_handle pipe) int ival; DPRINTFN(1, ("uhci_open: pipe=%p, addr=%d, endpt=%d (%d)\n", - pipe, pipe->device->address, + pipe, pipe->device->address, ed->bEndpointAddress, sc->sc_addr)); if (pipe->device->address == sc->sc_addr) { switch (ed->bEndpointAddress) { @@ -2726,8 +2725,8 @@ uhci_open(usbd_pipe_handle pipe) uhci_free_std(sc, upipe->u.ctl.setup); goto bad; } - err = usb_allocmem(&sc->sc_bus, - sizeof(usb_device_request_t), + err = usb_allocmem(&sc->sc_bus, + sizeof(usb_device_request_t), 0, &upipe->u.ctl.reqdma); if (err) { uhci_free_sqh(sc, upipe->u.ctl.sqh); @@ -2850,7 +2849,7 @@ uhci_root_ctrl_transfer(usbd_xfer_handle xfer) if (err) return (err); - /* + /* * Pipe isn't running (otherwise err would be USBD_INPROG), * so start it first. */ @@ -2877,7 +2876,7 @@ uhci_root_ctrl_start(usbd_xfer_handle xfer) #endif req = &xfer->request; - DPRINTFN(2,("uhci_root_ctrl_control type=0x%02x request=%02x\n", + DPRINTFN(2,("uhci_root_ctrl_control type=0x%02x request=%02x\n", req->bmRequestType, req->bRequest)); len = UGETW(req->wLength); @@ -2892,7 +2891,7 @@ uhci_root_ctrl_start(usbd_xfer_handle xfer) case C(UR_CLEAR_FEATURE, UT_WRITE_DEVICE): case C(UR_CLEAR_FEATURE, UT_WRITE_INTERFACE): case C(UR_CLEAR_FEATURE, UT_WRITE_ENDPOINT): - /* + /* * DEVICE_REMOTE_WAKEUP and ENDPOINT_HALT are no-ops * for the integrated root hub. */ @@ -3060,7 +3059,7 @@ uhci_root_ctrl_start(usbd_xfer_handle xfer) goto ret; } if (len > 0) { - *(u_int8_t *)buf = + *(u_int8_t *)buf = (UREAD2(sc, port) & UHCI_PORTSC_LS) >> UHCI_PORTSC_LS_SHIFT; totlen = 1; @@ -3100,19 +3099,19 @@ uhci_root_ctrl_start(usbd_xfer_handle xfer) status = change = 0; if (x & UHCI_PORTSC_CCS) status |= UPS_CURRENT_CONNECT_STATUS; - if (x & UHCI_PORTSC_CSC) + if (x & UHCI_PORTSC_CSC) change |= UPS_C_CONNECT_STATUS; - if (x & UHCI_PORTSC_PE) + if (x & UHCI_PORTSC_PE) status |= UPS_PORT_ENABLED; - if (x & UHCI_PORTSC_POEDC) + if (x & UHCI_PORTSC_POEDC) change |= UPS_C_PORT_ENABLED; - if (x & UHCI_PORTSC_OCI) + if (x & UHCI_PORTSC_OCI) status |= UPS_OVERCURRENT_INDICATOR; - if (x & UHCI_PORTSC_OCIC) + if (x & UHCI_PORTSC_OCIC) change |= UPS_C_OVERCURRENT_INDICATOR; - if (x & UHCI_PORTSC_SUSP) + if (x & UHCI_PORTSC_SUSP) status |= UPS_SUSPEND; - if (x & UHCI_PORTSC_LSDA) + if (x & UHCI_PORTSC_LSDA) status |= UPS_LOW_SPEED; status |= UPS_PORT_POWER; if (sc->sc_isreset) |