diff --git a/sys/arch/mips/adm5120/dev/ahci.c b/sys/arch/mips/adm5120/dev/ahci.c index 2b98e4ae221e..fed8d302a549 100644 --- a/sys/arch/mips/adm5120/dev/ahci.c +++ b/sys/arch/mips/adm5120/dev/ahci.c @@ -569,6 +569,8 @@ ahci_roothub_ctrl(struct usbd_bus *bus, usb_device_request_t *req, DPRINTF(D_TRACE, ("SLRCstart ")); + KASSERT(bus->ub_polling || mutex_owned(bus->ub_lock)); + len = UGETW(req->wLength); value = UGETW(req->wValue); index = UGETW(req->wIndex); @@ -729,22 +731,10 @@ ahci_roothub_ctrl(struct usbd_bus *bus, usb_device_request_t *req, static usbd_status ahci_root_intr_transfer(struct usbd_xfer *xfer) { - struct ahci_softc *sc = AHCI_XFER2SC(xfer); - usbd_status error; DPRINTF(D_TRACE, ("SLRItransfer ")); - /* Insert last in queue */ - mutex_enter(&sc->sc_lock); - error = usb_insert_transfer(xfer); - mutex_exit(&sc->sc_lock); - if (error) - return error; - - /* - * Pipe isn't running (otherwise error would be USBD_INPROG), - * start first. - */ + /* Pipe isn't running, start first. */ return ahci_root_intr_start(SIMPLEQ_FIRST(&xfer->ux_pipe->up_queue)); } @@ -755,13 +745,13 @@ ahci_root_intr_start(struct usbd_xfer *xfer) DPRINTF(D_TRACE, ("SLRIstart ")); - mutex_enter(&sc->sc_lock); + KASSERT(sc->sc_bus.ub_usepolling || mutex_owned(&sc->sc_lock); + KASSERT(sc->sc_intr_xfer == NULL); sc->sc_interval = MS_TO_TICKS(xfer->ux_pipe->up_endpoint->ue_edesc->bInterval); callout_schedule(&sc->sc_poll_handle, sc->sc_interval); sc->sc_intr_xfer = xfer; xfer->ux_status = USBD_IN_PROGRESS; - mutex_exit(&sc->sc_lock); return USBD_IN_PROGRESS; } @@ -827,17 +817,9 @@ ahci_root_intr_done(struct usbd_xfer *xfer) static usbd_status ahci_device_ctrl_transfer(struct usbd_xfer *xfer) { - struct ahci_softc *sc = AHCI_XFER2SC(xfer); - usbd_status error; DPRINTF(D_TRACE, ("C")); - mutex_enter(&sc->sc_lock); - error = usb_insert_transfer(xfer); - mutex_exit(&sc->sc_lock); - if (error) - return error; - return ahci_device_ctrl_start(SIMPLEQ_FIRST(&xfer->ux_pipe->up_queue)); } @@ -854,11 +836,11 @@ ahci_device_ctrl_start(struct usbd_xfer *xfer) struct ahci_softc *sc = AHCI_XFER2SC(xfer); int len, isread; + KASSERT(sc->sc_bus.ub_usepolling || mutex_owned(&sc->sc_lock); #if 0 struct ahci_pipe *apipe = (struct ahci_pipe *)xfer->ux_pipe; #endif - mutex_enter(&sc->sc_lock); /* printf("ctrl_start>>>\n"); */ #ifdef DIAGNOSTIC @@ -988,7 +970,6 @@ ahci_device_ctrl_start(struct usbd_xfer *xfer) /* printf("ctrl_start<<<\n"); */ usb_transfer_complete(xfer); - mutex_exit(&sc->sc_lock); usb_freemem(&reqdma); @@ -1017,28 +998,23 @@ ahci_device_ctrl_done(struct usbd_xfer *xfer) static usbd_status ahci_device_intr_transfer(struct usbd_xfer *xfer) { - struct ahci_softc *sc = AHCI_XFER2SC(xfer); - usbd_status error; DPRINTF(D_TRACE, ("INTRtrans ")); - mutex_enter(&sc->sc_lock); - error = usb_insert_transfer(xfer); - mutex_exit(&sc->sc_lock); - if (error) - return error; - return ahci_device_intr_start(SIMPLEQ_FIRST(&xfer->ux_pipe->up_queue)); } static usbd_status ahci_device_intr_start(struct usbd_xfer *xfer) { + struct ahci_softc *sc = AHCI_XFER2SC(xfer); struct usbd_pipe *pipe = xfer->ux_pipe; struct ahci_xfer *sx; DPRINTF(D_TRACE, ("INTRstart ")); + KASSERT(sc->sc_bus.ub_usepolling || mutex_owned(&sc->sc_lock); + sx = kmem_intr_alloc(sizeof(*sx), KM_NOSLEEP); if (sx == NULL) goto reterr; @@ -1161,17 +1137,9 @@ ahci_device_isoc_done(struct usbd_xfer *xfer) static usbd_status ahci_device_bulk_transfer(struct usbd_xfer *xfer) { - struct ahci_softc *sc = AHCI_XFER2SC(xfer); - usbd_status error; DPRINTF(D_TRACE, ("B")); - mutex_enter(&sc->sc_lock); - error = usb_insert_transfer(xfer); - mutex_exit(&sc->sc_lock); - if (error) - return error; - return ahci_device_bulk_start(SIMPLEQ_FIRST(&xfer->ux_pipe->up_queue)); } @@ -1192,6 +1160,8 @@ ahci_device_bulk_start(struct usbd_xfer *xfer) #define KSEG1ADDR(x) (0xa0000000 | (((uint32_t)x) & 0x1fffffff)) DPRINTF(D_TRACE, ("st ")); + KASSERT(sc->sc_bus.ub_usepolling || mutex_owned(&sc->sc_lock); + #ifdef DIAGNOSTIC if (xfer->ux_rqflags & URQ_REQUEST) { /* XXX panic */ @@ -1200,7 +1170,6 @@ ahci_device_bulk_start(struct usbd_xfer *xfer) } #endif - mutex_enter(&sc->sc_lock); level++; /* printf("bulk_start>>>\n"); */ @@ -1327,7 +1296,6 @@ ahci_device_bulk_start(struct usbd_xfer *xfer) isread ? BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE); usb_transfer_complete(xfer); - mutex_exit(&sc->sc_lock); return USBD_NORMAL_COMPLETION; } diff --git a/sys/dev/ic/sl811hs.c b/sys/dev/ic/sl811hs.c index e5773430ccaf..04a9de937d6c 100644 --- a/sys/dev/ic/sl811hs.c +++ b/sys/dev/ic/sl811hs.c @@ -839,32 +839,13 @@ usbd_status slhci_transfer(struct usbd_xfer *xfer) { SLHCIHIST_FUNC(); SLHCIHIST_CALLED(); - struct slhci_softc *sc = SLHCI_XFER2SC(xfer); usbd_status error; DLOG(D_TRACE, "transfer type %jd xfer %#jx spipe %#jx ", SLHCI_XFER_TYPE(xfer), (uintptr_t)xfer, (uintptr_t)xfer->ux_pipe, 0); - /* Insert last in queue */ - mutex_enter(&sc->sc_lock); - error = usb_insert_transfer(xfer); - mutex_exit(&sc->sc_lock); - if (error) { - if (error != USBD_IN_PROGRESS) - DLOG(D_ERR, "usb_insert_transfer returns %jd!", error, - 0,0,0); - return error; - } - - /* - * Pipe isn't running (otherwise error would be USBD_INPROG), - * so start it first. - */ - - /* - * Start will take the lock. - */ + /* Pipe isn't running, so start it first. */ error = xfer->ux_pipe->up_methods->upm_start(SIMPLEQ_FIRST(&xfer->ux_pipe->up_queue)); return error; @@ -882,7 +863,7 @@ slhci_start(struct usbd_xfer *xfer) usb_endpoint_descriptor_t *ed = pipe->up_endpoint->ue_edesc; unsigned int max_packet; - mutex_enter(&sc->sc_lock); + KASSERT(sc->sc_bus.ub_usepolling || mutex_owned(&sc->sc_lock)); max_packet = UGETW(ed->wMaxPacketSize); @@ -1004,8 +985,6 @@ slhci_start(struct usbd_xfer *xfer) slhci_start_entry(sc, spipe); - mutex_exit(&sc->sc_lock); - return USBD_IN_PROGRESS; } @@ -1027,13 +1006,13 @@ slhci_root_start(struct usbd_xfer *xfer) DLOG(D_TRACE, "transfer type %jd start", SLHCI_XFER_TYPE(xfer), 0, 0, 0); + KASSERT(sc->sc_bus.ub_usepolling || mutex_owned(&sc->sc_lock)); + KASSERT(spipe->ptype == PT_ROOT_INTR); - mutex_enter(&sc->sc_intr_lock); KASSERT(t->rootintr == NULL); t->rootintr = xfer; xfer->ux_status = USBD_IN_PROGRESS; - mutex_exit(&sc->sc_intr_lock); return USBD_IN_PROGRESS; } @@ -3216,6 +3195,8 @@ slhci_roothub_ctrl(struct usbd_bus *bus, usb_device_request_t *req, uint8_t type; int actlen = 0; + KASSERT(bus->ub_usepolling || mutex_owned(bus->ub_lock)); + len = UGETW(req->wLength); value = UGETW(req->wValue); index = UGETW(req->wIndex); diff --git a/sys/dev/usb/ehci.c b/sys/dev/usb/ehci.c index f6ff864d5155..a3737cbc106c 100644 --- a/sys/dev/usb/ehci.c +++ b/sys/dev/usb/ehci.c @@ -2369,6 +2369,8 @@ ehci_roothub_ctrl(struct usbd_bus *bus, usb_device_request_t *req, EHCIHIST_FUNC(); EHCIHIST_CALLED(); + KASSERT(bus->ub_usepolling || mutex_owned(bus->ub_lock)); + if (sc->sc_dying) return -1; @@ -2748,15 +2750,6 @@ ehci_disown(ehci_softc_t *sc, int index, int lowspeed) Static usbd_status ehci_root_intr_transfer(struct usbd_xfer *xfer) { - ehci_softc_t *sc = EHCI_XFER2SC(xfer); - usbd_status err; - - /* Insert last in queue. */ - mutex_enter(&sc->sc_lock); - err = usb_insert_transfer(xfer); - mutex_exit(&sc->sc_lock); - if (err) - return err; /* Pipe isn't running, start first */ return ehci_root_intr_start(SIMPLEQ_FIRST(&xfer->ux_pipe->up_queue)); @@ -2766,18 +2759,15 @@ Static usbd_status ehci_root_intr_start(struct usbd_xfer *xfer) { ehci_softc_t *sc = EHCI_XFER2SC(xfer); - const bool polling = sc->sc_bus.ub_usepolling; + + KASSERT(sc->sc_bus.ub_usepolling || mutex_owned(&sc->sc_lock)); if (sc->sc_dying) return USBD_IOERROR; - if (!polling) - mutex_enter(&sc->sc_lock); KASSERT(sc->sc_intrxfer == NULL); sc->sc_intrxfer = xfer; xfer->ux_status = USBD_IN_PROGRESS; - if (!polling) - mutex_exit(&sc->sc_lock); return USBD_IN_PROGRESS; } @@ -3397,14 +3387,10 @@ ehci_abortx(struct usbd_xfer *xfer) BUS_DMASYNC_PREREAD); } - /* - * Final step: Notify completion to waiting xfers. - */ dying: #ifdef DIAGNOSTIC exfer->ex_isdone = true; #endif - usb_transfer_complete(xfer); DPRINTFN(14, "end", 0, 0, 0, 0); KASSERT(mutex_owned(&sc->sc_lock)); @@ -3606,15 +3592,6 @@ ehci_device_ctrl_fini(struct usbd_xfer *xfer) Static usbd_status ehci_device_ctrl_transfer(struct usbd_xfer *xfer) { - ehci_softc_t *sc = EHCI_XFER2SC(xfer); - usbd_status err; - - /* Insert last in queue. */ - mutex_enter(&sc->sc_lock); - err = usb_insert_transfer(xfer); - mutex_exit(&sc->sc_lock); - if (err) - return err; /* Pipe isn't running, start first */ return ehci_device_ctrl_start(SIMPLEQ_FIRST(&xfer->ux_pipe->up_queue)); @@ -3629,10 +3606,10 @@ ehci_device_ctrl_start(struct usbd_xfer *xfer) ehci_softc_t *sc = EHCI_XFER2SC(xfer); ehci_soft_qtd_t *setup, *status, *next; ehci_soft_qh_t *sqh; - const bool polling = sc->sc_bus.ub_usepolling; EHCIHIST_FUNC(); EHCIHIST_CALLED(); + KASSERT(sc->sc_bus.ub_usepolling || mutex_owned(&sc->sc_lock)); KASSERT(xfer->ux_rqflags & URQ_REQUEST); if (sc->sc_dying) @@ -3751,16 +3728,11 @@ ehci_device_ctrl_start(struct usbd_xfer *xfer) DPRINTFN(5, "--- dump end ---", 0, 0, 0, 0); #endif - if (!polling) - mutex_enter(&sc->sc_lock); - /* Insert qTD in QH list - also does usb_syncmem(sqh) */ ehci_set_qh_qtd(sqh, setup); usbd_xfer_schedule_timeout(xfer); ehci_add_intr_list(sc, exfer); xfer->ux_status = USBD_IN_PROGRESS; - if (!polling) - mutex_exit(&sc->sc_lock); #if 0 #ifdef EHCI_DEBUG @@ -3886,15 +3858,6 @@ ehci_device_bulk_fini(struct usbd_xfer *xfer) Static usbd_status ehci_device_bulk_transfer(struct usbd_xfer *xfer) { - ehci_softc_t *sc = EHCI_XFER2SC(xfer); - usbd_status err; - - /* Insert last in queue. */ - mutex_enter(&sc->sc_lock); - err = usb_insert_transfer(xfer); - mutex_exit(&sc->sc_lock); - if (err) - return err; /* Pipe isn't running, start first */ return ehci_device_bulk_start(SIMPLEQ_FIRST(&xfer->ux_pipe->up_queue)); @@ -3909,13 +3872,14 @@ ehci_device_bulk_start(struct usbd_xfer *xfer) ehci_soft_qh_t *sqh; ehci_soft_qtd_t *end; int len, isread, endpt; - const bool polling = sc->sc_bus.ub_usepolling; EHCIHIST_FUNC(); EHCIHIST_CALLED(); DPRINTF("xfer=%#jx len=%jd flags=%jd", (uintptr_t)xfer, xfer->ux_length, xfer->ux_flags, 0); + KASSERT(sc->sc_bus.ub_usepolling || mutex_owned(&sc->sc_lock)); + if (sc->sc_dying) return USBD_IOERROR; @@ -3932,10 +3896,6 @@ ehci_device_bulk_start(struct usbd_xfer *xfer) exfer->ex_isdone = false; #endif - /* Take lock here to protect nexttoggle */ - if (!polling) - mutex_enter(&sc->sc_lock); - ehci_reset_sqtd_chain(sc, xfer, len, isread, &epipe->nexttoggle, &end); exfer->ex_sqtdend = end; @@ -3959,8 +3919,6 @@ ehci_device_bulk_start(struct usbd_xfer *xfer) usbd_xfer_schedule_timeout(xfer); ehci_add_intr_list(sc, exfer); xfer->ux_status = USBD_IN_PROGRESS; - if (!polling) - mutex_exit(&sc->sc_lock); #if 0 #ifdef EHCI_DEBUG @@ -4099,20 +4057,8 @@ ehci_device_intr_fini(struct usbd_xfer *xfer) Static usbd_status ehci_device_intr_transfer(struct usbd_xfer *xfer) { - ehci_softc_t *sc = EHCI_XFER2SC(xfer); - usbd_status err; - /* Insert last in queue. */ - mutex_enter(&sc->sc_lock); - err = usb_insert_transfer(xfer); - mutex_exit(&sc->sc_lock); - if (err) - return err; - - /* - * Pipe isn't running (otherwise err would be USBD_INPROG), - * so start it first. - */ + /* Pipe isn't running, so start it first. */ return ehci_device_intr_start(SIMPLEQ_FIRST(&xfer->ux_pipe->up_queue)); } @@ -4125,13 +4071,14 @@ ehci_device_intr_start(struct usbd_xfer *xfer) ehci_soft_qtd_t *end; ehci_soft_qh_t *sqh; int len, isread, endpt; - const bool polling = sc->sc_bus.ub_usepolling; EHCIHIST_FUNC(); EHCIHIST_CALLED(); DPRINTF("xfer=%#jx len=%jd flags=%jd", (uintptr_t)xfer, xfer->ux_length, xfer->ux_flags, 0); + KASSERT(sc->sc_bus.ub_usepolling || mutex_owned(&sc->sc_lock)); + if (sc->sc_dying) return USBD_IOERROR; @@ -4148,10 +4095,6 @@ ehci_device_intr_start(struct usbd_xfer *xfer) exfer->ex_isdone = false; #endif - /* Take lock to protect nexttoggle */ - if (!polling) - mutex_enter(&sc->sc_lock); - ehci_reset_sqtd_chain(sc, xfer, len, isread, &epipe->nexttoggle, &end); end->qtd.qtd_status |= htole32(EHCI_QTD_IOC); @@ -4175,8 +4118,6 @@ ehci_device_intr_start(struct usbd_xfer *xfer) usbd_xfer_schedule_timeout(xfer); ehci_add_intr_list(sc, exfer); xfer->ux_status = USBD_IN_PROGRESS; - if (!polling) - mutex_exit(&sc->sc_lock); #if 0 #ifdef EHCI_DEBUG @@ -4351,14 +4292,6 @@ Static usbd_status ehci_device_fs_isoc_transfer(struct usbd_xfer *xfer) { ehci_softc_t *sc = EHCI_XFER2SC(xfer); - usbd_status __diagused err; - - mutex_enter(&sc->sc_lock); - err = usb_insert_transfer(xfer); - mutex_exit(&sc->sc_lock); - - KASSERT(err == USBD_NORMAL_COMPLETION); - struct ehci_pipe *epipe = EHCI_XFER2EPIPE(xfer); struct usbd_device *dev = xfer->ux_pipe->up_dev; struct ehci_xfer *exfer = EHCI_XFER2EXFER(xfer); @@ -4376,6 +4309,8 @@ ehci_device_fs_isoc_transfer(struct usbd_xfer *xfer) DPRINTF("xfer %#jx len %jd flags %jd", (uintptr_t)xfer, xfer->ux_length, xfer->ux_flags, 0); + KASSERT(sc->sc_bus.ub_usepolling || mutex_owned(&sc->sc_lock)); + if (sc->sc_dying) return USBD_IOERROR; @@ -4509,8 +4444,6 @@ ehci_device_fs_isoc_transfer(struct usbd_xfer *xfer) * more than the period frame list. */ - mutex_enter(&sc->sc_lock); - /* Start inserting frames */ if (epipe->isoc.cur_xfers > 0) { frindex = epipe->isoc.next_frame; @@ -4573,7 +4506,6 @@ ehci_device_fs_isoc_transfer(struct usbd_xfer *xfer) ehci_add_intr_list(sc, exfer); xfer->ux_status = USBD_IN_PROGRESS; - mutex_exit(&sc->sc_lock); return USBD_IN_PROGRESS; } @@ -4724,14 +4656,6 @@ Static usbd_status ehci_device_isoc_transfer(struct usbd_xfer *xfer) { ehci_softc_t *sc = EHCI_XFER2SC(xfer); - usbd_status __diagused err; - - mutex_enter(&sc->sc_lock); - err = usb_insert_transfer(xfer); - mutex_exit(&sc->sc_lock); - - KASSERT(err == USBD_NORMAL_COMPLETION); - struct ehci_pipe *epipe = EHCI_XFER2EPIPE(xfer); struct ehci_xfer *exfer = EHCI_XFER2EXFER(xfer); ehci_soft_itd_t *itd, *prev; @@ -4749,6 +4673,8 @@ ehci_device_isoc_transfer(struct usbd_xfer *xfer) DPRINTF("xfer %#jx flags %jd", (uintptr_t)xfer, xfer->ux_flags, 0, 0); + KASSERT(sc->sc_bus.ub_usepolling || mutex_owned(&sc->sc_lock)); + if (sc->sc_dying) return USBD_IOERROR; @@ -4895,8 +4821,6 @@ ehci_device_isoc_transfer(struct usbd_xfer *xfer) * more than the period frame list. */ - mutex_enter(&sc->sc_lock); - /* Start inserting frames */ if (epipe->isoc.cur_xfers > 0) { frindex = epipe->isoc.next_frame; @@ -4964,7 +4888,6 @@ ehci_device_isoc_transfer(struct usbd_xfer *xfer) ehci_add_intr_list(sc, exfer); xfer->ux_status = USBD_IN_PROGRESS; - mutex_exit(&sc->sc_lock); return USBD_IN_PROGRESS; } diff --git a/sys/dev/usb/if_atu.c b/sys/dev/usb/if_atu.c index 85222d1dce28..6b0d464269a5 100644 --- a/sys/dev/usb/if_atu.c +++ b/sys/dev/usb/if_atu.c @@ -2223,7 +2223,6 @@ atu_stop(struct ifnet *ifp, int disable) struct atu_softc *sc = ifp->if_softc; struct ieee80211com *ic = &sc->sc_ic; struct atu_cdata *cd; - usbd_status err; int s; s = splnet(); @@ -2235,19 +2234,11 @@ atu_stop(struct ifnet *ifp, int disable) /* Stop transfers. */ if (sc->atu_ep[ATU_ENDPT_RX] != NULL) { - err = usbd_abort_pipe(sc->atu_ep[ATU_ENDPT_RX]); - if (err) { - DPRINTF(("%s: abort rx pipe failed: %s\n", - device_xname(sc->atu_dev), usbd_errstr(err))); - } + usbd_abort_pipe(sc->atu_ep[ATU_ENDPT_RX]); } if (sc->atu_ep[ATU_ENDPT_TX] != NULL) { - err = usbd_abort_pipe(sc->atu_ep[ATU_ENDPT_TX]); - if (err) { - DPRINTF(("%s: abort tx pipe failed: %s\n", - device_xname(sc->atu_dev), usbd_errstr(err))); - } + usbd_abort_pipe(sc->atu_ep[ATU_ENDPT_TX]); } /* Free RX/TX/MGMT list resources. */ @@ -2257,20 +2248,12 @@ atu_stop(struct ifnet *ifp, int disable) /* Close pipes */ if (sc->atu_ep[ATU_ENDPT_RX] != NULL) { - err = usbd_close_pipe(sc->atu_ep[ATU_ENDPT_RX]); - if (err) { - DPRINTF(("%s: close rx pipe failed: %s\n", - device_xname(sc->atu_dev), usbd_errstr(err))); - } + usbd_close_pipe(sc->atu_ep[ATU_ENDPT_RX]); sc->atu_ep[ATU_ENDPT_RX] = NULL; } if (sc->atu_ep[ATU_ENDPT_TX] != NULL) { - err = usbd_close_pipe(sc->atu_ep[ATU_ENDPT_TX]); - if (err) { - DPRINTF(("%s: close tx pipe failed: %s\n", - device_xname(sc->atu_dev), usbd_errstr(err))); - } + usbd_close_pipe(sc->atu_ep[ATU_ENDPT_TX]); sc->atu_ep[ATU_ENDPT_TX] = NULL; } diff --git a/sys/dev/usb/if_urtw.c b/sys/dev/usb/if_urtw.c index 162141c8072f..f08db3030887 100644 --- a/sys/dev/usb/if_urtw.c +++ b/sys/dev/usb/if_urtw.c @@ -829,24 +829,17 @@ urtw_close_pipes(struct urtw_softc *sc) usbd_status error = 0; if (sc->sc_rxpipe != NULL) { - error = usbd_close_pipe(sc->sc_rxpipe); - if (error != 0) - goto fail; + usbd_close_pipe(sc->sc_rxpipe); sc->sc_rxpipe = NULL; } if (sc->sc_txpipe_low != NULL) { - error = usbd_close_pipe(sc->sc_txpipe_low); - if (error != 0) - goto fail; + usbd_close_pipe(sc->sc_txpipe_low); sc->sc_txpipe_low = NULL; } if (sc->sc_txpipe_normal != NULL) { - error = usbd_close_pipe(sc->sc_txpipe_normal); - if (error != 0) - goto fail; + usbd_close_pipe(sc->sc_txpipe_normal); sc->sc_txpipe_normal = NULL; } -fail: return error; } diff --git a/sys/dev/usb/motg.c b/sys/dev/usb/motg.c index 63339b4f0d54..2faca383246c 100644 --- a/sys/dev/usb/motg.c +++ b/sys/dev/usb/motg.c @@ -806,6 +806,8 @@ motg_roothub_ctrl(struct usbd_bus *bus, usb_device_request_t *req, MOTGHIST_FUNC(); MOTGHIST_CALLED(); + KASSERT(bus->ub_usepolling || mutex_owned(bus->ub_lock)); + if (sc->sc_dying) return -1; @@ -1009,20 +1011,8 @@ motg_root_intr_abort(struct usbd_xfer *xfer) usbd_status motg_root_intr_transfer(struct usbd_xfer *xfer) { - struct motg_softc *sc = MOTG_XFER2SC(xfer); - usbd_status err; - - /* Insert last in queue. */ - mutex_enter(&sc->sc_lock); - err = usb_insert_transfer(xfer); - mutex_exit(&sc->sc_lock); - if (err) - return err; - /* - * Pipe isn't running (otherwise err would be USBD_INPROG), - * start first - */ + /* Pipe isn't running, start first */ return motg_root_intr_start(SIMPLEQ_FIRST(&xfer->ux_pipe->up_queue)); } @@ -1032,23 +1022,20 @@ motg_root_intr_start(struct usbd_xfer *xfer) { struct usbd_pipe *pipe = xfer->ux_pipe; struct motg_softc *sc = MOTG_PIPE2SC(pipe); - const bool polling = sc->sc_bus.ub_usepolling; MOTGHIST_FUNC(); MOTGHIST_CALLED(); DPRINTFN(MD_ROOT, "xfer=%#jx len=%jd flags=%jd", (uintptr_t)xfer, xfer->ux_length, xfer->ux_flags, 0); + KASSERT(sc->sc_bus.ub_usepolling || mutex_owned(&sc->sc_lock)); + if (sc->sc_dying) return USBD_IOERROR; - if (!polling) - mutex_enter(&sc->sc_lock); KASSERT(sc->sc_intr_xfer == NULL); sc->sc_intr_xfer = xfer; xfer->ux_status = USBD_IN_PROGRESS; - if (!polling) - mutex_exit(&sc->sc_lock); return USBD_IN_PROGRESS; } @@ -1279,21 +1266,8 @@ motg_setup_endpoint_rx(struct usbd_xfer *xfer) static usbd_status motg_device_ctrl_transfer(struct usbd_xfer *xfer) { - struct motg_softc *sc = MOTG_XFER2SC(xfer); - usbd_status err; - /* Insert last in queue. */ - mutex_enter(&sc->sc_lock); - err = usb_insert_transfer(xfer); - KASSERT(xfer->ux_status == USBD_NOT_STARTED); - mutex_exit(&sc->sc_lock); - if (err) - return err; - - /* - * Pipe isn't running (otherwise err would be USBD_INPROG), - * so start it first. - */ + /* Pipe isn't running, so start it first. */ return motg_device_ctrl_start(SIMPLEQ_FIRST(&xfer->ux_pipe->up_queue)); } @@ -1301,11 +1275,10 @@ static usbd_status motg_device_ctrl_start(struct usbd_xfer *xfer) { struct motg_softc *sc = MOTG_XFER2SC(xfer); - usbd_status err; - mutex_enter(&sc->sc_lock); - err = motg_device_ctrl_start1(sc); - mutex_exit(&sc->sc_lock); - return err; + + KASSERT(sc->sc_bus.ub_usepolling || mutex_owned(&sc->sc_lock)); + + return motg_device_ctrl_start1(sc); } static usbd_status @@ -1731,24 +1704,9 @@ motg_device_ctrl_done(struct usbd_xfer *xfer) static usbd_status motg_device_data_transfer(struct usbd_xfer *xfer) { - struct motg_softc *sc = MOTG_XFER2SC(xfer); - usbd_status err; - MOTGHIST_FUNC(); MOTGHIST_CALLED(); - /* Insert last in queue. */ - mutex_enter(&sc->sc_lock); - DPRINTF("xfer %#jx status %jd", (uintptr_t)xfer, xfer->ux_status, 0, 0); - err = usb_insert_transfer(xfer); - KASSERT(xfer->ux_status == USBD_NOT_STARTED); - mutex_exit(&sc->sc_lock); - if (err) - return err; - - /* - * Pipe isn't running (otherwise err would be USBD_INPROG), - * so start it first. - */ + /* Pipe isn't running, so start it first. */ return motg_device_data_start(SIMPLEQ_FIRST(&xfer->ux_pipe->up_queue)); } @@ -1757,15 +1715,14 @@ motg_device_data_start(struct usbd_xfer *xfer) { struct motg_softc *sc = MOTG_XFER2SC(xfer); struct motg_pipe *otgpipe = MOTG_PIPE2MPIPE(xfer->ux_pipe); - usbd_status err; MOTGHIST_FUNC(); MOTGHIST_CALLED(); - mutex_enter(&sc->sc_lock); DPRINTF("xfer %#jx status %jd", (uintptr_t)xfer, xfer->ux_status, 0, 0); - err = motg_device_data_start1(sc, otgpipe->hw_ep); - mutex_exit(&sc->sc_lock); - return err; + + KASSERT(sc->sc_bus.ub_usepolling || mutex_owned(&sc->sc_lock)); + + return motg_device_data_start1(sc, otgpipe->hw_ep); } static usbd_status @@ -2262,6 +2219,5 @@ motg_abortx(struct usbd_xfer *xfer) } } dying: - usb_transfer_complete(xfer); KASSERT(mutex_owned(&sc->sc_lock)); } diff --git a/sys/dev/usb/ohci.c b/sys/dev/usb/ohci.c index bd8ab4f33a27..938d5e085c9a 100644 --- a/sys/dev/usb/ohci.c +++ b/sys/dev/usb/ohci.c @@ -2409,12 +2409,7 @@ ohci_abortx(struct usbd_xfer *xfer) usb_syncmem(&sed->dma, sed->offs + offsetof(ohci_ed_t, ed_flags), sizeof(sed->ed.ed_flags), BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); - - /* - * Final step: Notify completion to waiting xfers. - */ dying: - usb_transfer_complete(xfer); DPRINTFN(14, "end", 0, 0, 0, 0); KASSERT(mutex_owned(&sc->sc_lock)); @@ -2436,6 +2431,8 @@ ohci_roothub_ctrl(struct usbd_bus *bus, usb_device_request_t *req, OHCIHIST_FUNC(); OHCIHIST_CALLED(); + KASSERT(bus->ub_usepolling || mutex_owned(bus->ub_lock)); + if (sc->sc_dying) return -1; @@ -2616,15 +2613,6 @@ ohci_roothub_ctrl(struct usbd_bus *bus, usb_device_request_t *req, Static usbd_status ohci_root_intr_transfer(struct usbd_xfer *xfer) { - ohci_softc_t *sc = OHCI_XFER2SC(xfer); - usbd_status err; - - /* Insert last in queue. */ - mutex_enter(&sc->sc_lock); - err = usb_insert_transfer(xfer); - mutex_exit(&sc->sc_lock); - if (err) - return err; /* Pipe isn't running, start first */ return ohci_root_intr_start(SIMPLEQ_FIRST(&xfer->ux_pipe->up_queue)); @@ -2634,18 +2622,15 @@ Static usbd_status ohci_root_intr_start(struct usbd_xfer *xfer) { ohci_softc_t *sc = OHCI_XFER2SC(xfer); - const bool polling = sc->sc_bus.ub_usepolling; + + KASSERT(sc->sc_bus.ub_usepolling || mutex_owned(&sc->sc_lock)); if (sc->sc_dying) return USBD_IOERROR; - if (!polling) - mutex_enter(&sc->sc_lock); KASSERT(sc->sc_intrxfer == NULL); sc->sc_intrxfer = xfer; xfer->ux_status = USBD_IN_PROGRESS; - if (!polling) - mutex_exit(&sc->sc_lock); return USBD_IN_PROGRESS; } @@ -2774,15 +2759,6 @@ ohci_device_ctrl_fini(struct usbd_xfer *xfer) Static usbd_status ohci_device_ctrl_transfer(struct usbd_xfer *xfer) { - ohci_softc_t *sc = OHCI_XFER2SC(xfer); - usbd_status err; - - /* Insert last in queue. */ - mutex_enter(&sc->sc_lock); - err = usb_insert_transfer(xfer); - mutex_exit(&sc->sc_lock); - if (err) - return err; /* Pipe isn't running, start first */ return ohci_device_ctrl_start(SIMPLEQ_FIRST(&xfer->ux_pipe->up_queue)); @@ -2800,10 +2776,11 @@ ohci_device_ctrl_start(struct usbd_xfer *xfer) ohci_soft_ed_t *sed; int isread; int len; - const bool polling = sc->sc_bus.ub_usepolling; OHCIHIST_FUNC(); OHCIHIST_CALLED(); + KASSERT(sc->sc_bus.ub_usepolling || mutex_owned(&sc->sc_lock)); + if (sc->sc_dying) return USBD_IOERROR; @@ -2818,10 +2795,6 @@ ohci_device_ctrl_start(struct usbd_xfer *xfer) req->bmRequestType, req->bRequest, UGETW(req->wValue), UGETW(req->wIndex)); - /* Need to take lock here for pipe->tail.td */ - if (!polling) - mutex_enter(&sc->sc_lock); - /* * Use the pipe "tail" TD as our first and loan our first TD to the * next transfer @@ -2956,8 +2929,6 @@ ohci_device_ctrl_start(struct usbd_xfer *xfer) DPRINTF("done", 0, 0, 0, 0); xfer->ux_status = USBD_IN_PROGRESS; - if (!polling) - mutex_exit(&sc->sc_lock); return USBD_IN_PROGRESS; } @@ -3062,15 +3033,6 @@ ohci_device_bulk_fini(struct usbd_xfer *xfer) Static usbd_status ohci_device_bulk_transfer(struct usbd_xfer *xfer) { - ohci_softc_t *sc = OHCI_XFER2SC(xfer); - usbd_status err; - - /* Insert last in queue. */ - mutex_enter(&sc->sc_lock); - err = usb_insert_transfer(xfer); - mutex_exit(&sc->sc_lock); - if (err) - return err; /* Pipe isn't running, start first */ return ohci_device_bulk_start(SIMPLEQ_FIRST(&xfer->ux_pipe->up_queue)); @@ -3086,10 +3048,11 @@ ohci_device_bulk_start(struct usbd_xfer *xfer) ohci_soft_td_t *data, *tail, *tdp; ohci_soft_ed_t *sed; int len, isread, endpt; - const bool polling = sc->sc_bus.ub_usepolling; OHCIHIST_FUNC(); OHCIHIST_CALLED(); + KASSERT(sc->sc_bus.ub_usepolling || mutex_owned(&sc->sc_lock)); + if (sc->sc_dying) return USBD_IOERROR; @@ -3104,9 +3067,6 @@ ohci_device_bulk_start(struct usbd_xfer *xfer) len, isread, xfer->ux_flags); DPRINTFN(4, "endpt=%jd", endpt, 0, 0, 0); - if (!polling) - mutex_enter(&sc->sc_lock); - /* * Use the pipe "tail" TD as our first and loan our first TD to the * next transfer @@ -3173,8 +3133,6 @@ ohci_device_bulk_start(struct usbd_xfer *xfer) OWRITE4(sc, OHCI_COMMAND_STATUS, OHCI_BLF); usbd_xfer_schedule_timeout(xfer); xfer->ux_status = USBD_IN_PROGRESS; - if (!polling) - mutex_exit(&sc->sc_lock); return USBD_IN_PROGRESS; } @@ -3270,15 +3228,6 @@ ohci_device_intr_fini(struct usbd_xfer *xfer) Static usbd_status ohci_device_intr_transfer(struct usbd_xfer *xfer) { - ohci_softc_t *sc = OHCI_XFER2SC(xfer); - usbd_status err; - - /* Insert last in queue. */ - mutex_enter(&sc->sc_lock); - err = usb_insert_transfer(xfer); - mutex_exit(&sc->sc_lock); - if (err) - return err; /* Pipe isn't running, start first */ return ohci_device_intr_start(SIMPLEQ_FIRST(&xfer->ux_pipe->up_queue)); @@ -3293,10 +3242,11 @@ ohci_device_intr_start(struct usbd_xfer *xfer) ohci_soft_ed_t *sed = opipe->sed; ohci_soft_td_t *data, *last, *tail; int len, isread, endpt; - const bool polling = sc->sc_bus.ub_usepolling; OHCIHIST_FUNC(); OHCIHIST_CALLED(); + KASSERT(sc->sc_bus.ub_usepolling || mutex_owned(&sc->sc_lock)); + if (sc->sc_dying) return USBD_IOERROR; @@ -3309,9 +3259,6 @@ ohci_device_intr_start(struct usbd_xfer *xfer) endpt = xfer->ux_pipe->up_endpoint->ue_edesc->bEndpointAddress; isread = UE_GET_DIR(endpt) == UE_DIR_IN; - if (!polling) - mutex_enter(&sc->sc_lock); - /* * Use the pipe "tail" TD as our first and loan our first TD to the * next transfer. @@ -3368,8 +3315,6 @@ ohci_device_intr_start(struct usbd_xfer *xfer) BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); xfer->ux_status = USBD_IN_PROGRESS; - if (!polling) - mutex_exit(&sc->sc_lock); return USBD_IN_PROGRESS; } @@ -3574,20 +3519,10 @@ ohci_device_isoc_fini(struct usbd_xfer *xfer) usbd_status ohci_device_isoc_transfer(struct usbd_xfer *xfer) { - ohci_softc_t *sc = OHCI_XFER2SC(xfer); - usbd_status __diagused err; - OHCIHIST_FUNC(); OHCIHIST_CALLED(); DPRINTFN(5, "xfer=%#jx", (uintptr_t)xfer, 0, 0, 0); - /* Put it on our queue, */ - mutex_enter(&sc->sc_lock); - err = usb_insert_transfer(xfer); - mutex_exit(&sc->sc_lock); - - KASSERT(err == USBD_NORMAL_COMPLETION); - /* insert into schedule, */ ohci_device_isoc_enter(xfer); @@ -3610,12 +3545,10 @@ ohci_device_isoc_enter(struct usbd_xfer *xfer) OHCIHIST_FUNC(); OHCIHIST_CALLED(); DPRINTFN(5, "xfer=%#jx", (uintptr_t)xfer, 0, 0, 0); - mutex_enter(&sc->sc_lock); + KASSERT(sc->sc_bus.ub_usepolling || mutex_owned(&sc->sc_lock)); - if (sc->sc_dying) { - mutex_exit(&sc->sc_lock); + if (sc->sc_dying) return; - } struct isoc *isoc = &opipe->isoc; @@ -3774,7 +3707,6 @@ ohci_device_isoc_enter(struct usbd_xfer *xfer) usb_syncmem(&sed->dma, sed->offs + offsetof(ohci_ed_t, ed_flags), sizeof(sed->ed.ed_flags), BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); - mutex_exit(&sc->sc_lock); } void diff --git a/sys/dev/usb/ualea.c b/sys/dev/usb/ualea.c index ede886968af4..d38722351672 100644 --- a/sys/dev/usb/ualea.c +++ b/sys/dev/usb/ualea.c @@ -161,14 +161,14 @@ ualea_detach(device_t self, int flags) /* Cancel pending xfer. */ if (sc->sc_pipe) - (void)usbd_abort_pipe(sc->sc_pipe); + usbd_abort_pipe(sc->sc_pipe); KASSERT(!sc->sc_inflight); /* All users have drained. Tear it all down. */ if (sc->sc_xfer) usbd_destroy_xfer(sc->sc_xfer); if (sc->sc_pipe) - (void)usbd_close_pipe(sc->sc_pipe); + usbd_close_pipe(sc->sc_pipe); mutex_destroy(&sc->sc_lock); return 0; diff --git a/sys/dev/usb/uhci.c b/sys/dev/usb/uhci.c index acf5e2e32c11..692a1ad92dd0 100644 --- a/sys/dev/usb/uhci.c +++ b/sys/dev/usb/uhci.c @@ -2258,20 +2258,8 @@ uhci_device_bulk_fini(struct usbd_xfer *xfer) usbd_status uhci_device_bulk_transfer(struct usbd_xfer *xfer) { - uhci_softc_t *sc = UHCI_XFER2SC(xfer); - usbd_status err; - - /* Insert last in queue. */ - mutex_enter(&sc->sc_lock); - err = usb_insert_transfer(xfer); - mutex_exit(&sc->sc_lock); - if (err) - return err; - /* - * Pipe isn't running (otherwise err would be USBD_INPROG), - * so start it first. - */ + /* Pipe isn't running, so start it first. */ return uhci_device_bulk_start(SIMPLEQ_FIRST(&xfer->ux_pipe->up_queue)); } @@ -2283,7 +2271,6 @@ uhci_device_bulk_start(struct usbd_xfer *xfer) uhci_softc_t *sc = UHCI_XFER2SC(xfer); uhci_soft_td_t *data, *dataend; uhci_soft_qh_t *sqh; - const bool polling = sc->sc_bus.ub_usepolling; int len; int endpt; int isread; @@ -2292,6 +2279,8 @@ uhci_device_bulk_start(struct usbd_xfer *xfer) DPRINTFN(3, "xfer=%#jx len=%jd flags=%jd", (uintptr_t)xfer, xfer->ux_length, xfer->ux_flags, 0); + KASSERT(sc->sc_bus.ub_usepolling || mutex_owned(&sc->sc_lock)); + if (sc->sc_dying) return USBD_IOERROR; @@ -2303,10 +2292,6 @@ uhci_device_bulk_start(struct usbd_xfer *xfer) isread = UE_GET_DIR(endpt) == UE_DIR_IN; sqh = upipe->bulk.sqh; - /* Take lock here to protect nexttoggle */ - if (!polling) - mutex_enter(&sc->sc_lock); - uhci_reset_std_chain(sc, xfer, len, isread, &upipe->nexttoggle, &dataend); @@ -2340,8 +2325,6 @@ uhci_device_bulk_start(struct usbd_xfer *xfer) uhci_add_intr_list(sc, ux); usbd_xfer_schedule_timeout(xfer); xfer->ux_status = USBD_IN_PROGRESS; - if (!polling) - mutex_exit(&sc->sc_lock); return USBD_IN_PROGRESS; } @@ -2414,15 +2397,10 @@ uhci_abortx(struct usbd_xfer *xfer) */ /* Hardware finishes in 1ms */ usb_delay_ms_locked(upipe->pipe.up_dev->ud_bus, 2, &sc->sc_lock); - - /* - * HC Step 3: Notify completion to waiting xfers. - */ dying: #ifdef DIAGNOSTIC ux->ux_isdone = true; #endif - usb_transfer_complete(xfer); DPRINTFN(14, "end", 0, 0, 0, 0); KASSERT(mutex_owned(&sc->sc_lock)); @@ -2495,20 +2473,8 @@ uhci_device_ctrl_fini(struct usbd_xfer *xfer) usbd_status uhci_device_ctrl_transfer(struct usbd_xfer *xfer) { - uhci_softc_t *sc = UHCI_XFER2SC(xfer); - usbd_status err; - /* Insert last in queue. */ - mutex_enter(&sc->sc_lock); - err = usb_insert_transfer(xfer); - mutex_exit(&sc->sc_lock); - if (err) - return err; - - /* - * Pipe isn't running (otherwise err would be USBD_INPROG), - * so start it first. - */ + /* Pipe isn't running, so start it first. */ return uhci_device_ctrl_start(SIMPLEQ_FIRST(&xfer->ux_pipe->up_queue)); } @@ -2524,12 +2490,13 @@ uhci_device_ctrl_start(struct usbd_xfer *xfer) int endpt = upipe->pipe.up_endpoint->ue_edesc->bEndpointAddress; uhci_soft_td_t *setup, *stat, *next, *dataend; uhci_soft_qh_t *sqh; - const bool polling = sc->sc_bus.ub_usepolling; int len; int isread; UHCIHIST_FUNC(); UHCIHIST_CALLED(); + KASSERT(sc->sc_bus.ub_usepolling || mutex_owned(&sc->sc_lock)); + if (sc->sc_dying) return USBD_IOERROR; @@ -2552,9 +2519,6 @@ uhci_device_ctrl_start(struct usbd_xfer *xfer) memcpy(KERNADDR(&upipe->ctrl.reqdma, 0), req, sizeof(*req)); usb_syncmem(&upipe->ctrl.reqdma, 0, sizeof(*req), BUS_DMASYNC_PREWRITE); - if (!polling) - mutex_enter(&sc->sc_lock); - /* Set up data transaction */ if (len != 0) { upipe->nexttoggle = 1; @@ -2652,8 +2616,6 @@ uhci_device_ctrl_start(struct usbd_xfer *xfer) #endif usbd_xfer_schedule_timeout(xfer); xfer->ux_status = USBD_IN_PROGRESS; - if (!polling) - mutex_exit(&sc->sc_lock); return USBD_IN_PROGRESS; } @@ -2701,20 +2663,8 @@ uhci_device_intr_fini(struct usbd_xfer *xfer) usbd_status uhci_device_intr_transfer(struct usbd_xfer *xfer) { - uhci_softc_t *sc = UHCI_XFER2SC(xfer); - usbd_status err; - - /* Insert last in queue. */ - mutex_enter(&sc->sc_lock); - err = usb_insert_transfer(xfer); - mutex_exit(&sc->sc_lock); - if (err) - return err; - /* - * Pipe isn't running (otherwise err would be USBD_INPROG), - * so start it first. - */ + /* Pipe isn't running, so start it first. */ return uhci_device_intr_start(SIMPLEQ_FIRST(&xfer->ux_pipe->up_queue)); } @@ -2726,18 +2676,19 @@ uhci_device_intr_start(struct usbd_xfer *xfer) uhci_softc_t *sc = UHCI_XFER2SC(xfer); uhci_soft_td_t *data, *dataend; uhci_soft_qh_t *sqh; - const bool polling = sc->sc_bus.ub_usepolling; int isread, endpt; int i; - if (sc->sc_dying) - return USBD_IOERROR; - UHCIHIST_FUNC(); UHCIHIST_CALLED(); DPRINTFN(3, "xfer=%#jx len=%jd flags=%jd", (uintptr_t)xfer, xfer->ux_length, xfer->ux_flags, 0); + KASSERT(sc->sc_bus.ub_usepolling || mutex_owned(&sc->sc_lock)); + + if (sc->sc_dying) + return USBD_IOERROR; + KASSERT(!(xfer->ux_rqflags & URQ_REQUEST)); KASSERT(xfer->ux_length <= xfer->ux_bufsize); @@ -2752,8 +2703,6 @@ uhci_device_intr_start(struct usbd_xfer *xfer) #endif /* Take lock to protect nexttoggle */ - if (!polling) - mutex_enter(&sc->sc_lock); uhci_reset_std_chain(sc, xfer, xfer->ux_length, isread, &upipe->nexttoggle, &dataend); @@ -2785,8 +2734,6 @@ uhci_device_intr_start(struct usbd_xfer *xfer) } uhci_add_intr_list(sc, ux); xfer->ux_status = USBD_IN_PROGRESS; - if (!polling) - mutex_exit(&sc->sc_lock); #ifdef UHCI_DEBUG if (uhcidebug >= 10) { @@ -2891,17 +2838,11 @@ usbd_status uhci_device_isoc_transfer(struct usbd_xfer *xfer) { uhci_softc_t *sc = UHCI_XFER2SC(xfer); - usbd_status err __diagused; UHCIHIST_FUNC(); UHCIHIST_CALLED(); DPRINTFN(5, "xfer=%#jx", (uintptr_t)xfer, 0, 0, 0); - /* Put it on our queue, */ - mutex_enter(&sc->sc_lock); - err = usb_insert_transfer(xfer); - mutex_exit(&sc->sc_lock); - - KASSERT(err == USBD_NORMAL_COMPLETION); + KASSERT(sc->sc_bus.ub_usepolling || mutex_owned(&sc->sc_lock)); /* insert into schedule, */ @@ -2936,7 +2877,6 @@ uhci_device_isoc_transfer(struct usbd_xfer *xfer) usb_syncmem(&xfer->ux_dmabuf, 0, xfer->ux_length, rd ? BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE); - mutex_enter(&sc->sc_lock); next = isoc->next; if (next == -1) { /* Not in use yet, schedule it a few frames ahead. */ @@ -2998,8 +2938,6 @@ uhci_device_isoc_transfer(struct usbd_xfer *xfer) #endif uhci_add_intr_list(sc, ux); - mutex_exit(&sc->sc_lock); - return USBD_IN_PROGRESS; } @@ -3651,6 +3589,8 @@ uhci_roothub_ctrl(struct usbd_bus *bus, usb_device_request_t *req, UHCIHIST_FUNC(); UHCIHIST_CALLED(); + KASSERT(bus->ub_usepolling || mutex_owned(bus->ub_lock)); + if (sc->sc_dying) return -1; @@ -3890,20 +3830,8 @@ uhci_root_intr_abort(struct usbd_xfer *xfer) usbd_status uhci_root_intr_transfer(struct usbd_xfer *xfer) { - uhci_softc_t *sc = UHCI_XFER2SC(xfer); - usbd_status err; - - /* Insert last in queue. */ - mutex_enter(&sc->sc_lock); - err = usb_insert_transfer(xfer); - mutex_exit(&sc->sc_lock); - if (err) - return err; - /* - * Pipe isn't running (otherwise err would be USBD_INPROG), - * start first - */ + /* Pipe isn't running, start first */ return uhci_root_intr_start(SIMPLEQ_FIRST(&xfer->ux_pipe->up_queue)); } @@ -3914,18 +3842,16 @@ uhci_root_intr_start(struct usbd_xfer *xfer) struct usbd_pipe *pipe = xfer->ux_pipe; uhci_softc_t *sc = UHCI_PIPE2SC(pipe); unsigned int ival; - const bool polling = sc->sc_bus.ub_usepolling; UHCIHIST_FUNC(); UHCIHIST_CALLED(); DPRINTF("xfer=%#jx len=%jd flags=%jd", (uintptr_t)xfer, xfer->ux_length, xfer->ux_flags, 0); + KASSERT(sc->sc_bus.ub_usepolling || mutex_owned(&sc->sc_lock)); + if (sc->sc_dying) return USBD_IOERROR; - if (!polling) - mutex_enter(&sc->sc_lock); - KASSERT(sc->sc_intr_xfer == NULL); /* XXX temporary variable needed to avoid gcc3 warning */ @@ -3935,9 +3861,6 @@ uhci_root_intr_start(struct usbd_xfer *xfer) sc->sc_intr_xfer = xfer; xfer->ux_status = USBD_IN_PROGRESS; - if (!polling) - mutex_exit(&sc->sc_lock); - return USBD_IN_PROGRESS; } diff --git a/sys/dev/usb/usb_mem.h b/sys/dev/usb/usb_mem.h index 5473c1b3b810..b93d694cfc3c 100644 --- a/sys/dev/usb/usb_mem.h +++ b/sys/dev/usb/usb_mem.h @@ -31,6 +31,16 @@ * POSSIBILITY OF SUCH DAMAGE. */ +#ifndef _DEV_USB_USB_MEM_H_ +#define _DEV_USB_USB_MEM_H_ + +#include + +#include +#include + +#include + typedef struct usb_dma_block { bus_dma_tag_t tag; bus_dmamap_t map; @@ -60,3 +70,5 @@ bus_addr_t usb_dmaaddr(usb_dma_t *, unsigned int); #define DMAADDR(dma, o) usb_dmaaddr((dma), (o)) #define KERNADDR(dma, o) \ ((void *)((char *)(dma)->udma_block->kaddr + (dma)->udma_offs + (o))) + +#endif /* _DEV_USB_USB_MEM_H_ */ diff --git a/sys/dev/usb/usbdi.c b/sys/dev/usb/usbdi.c index 02b1a41e9e08..93adb1d5752d 100644 --- a/sys/dev/usb/usbdi.c +++ b/sys/dev/usb/usbdi.c @@ -113,14 +113,14 @@ SDT_PROBE_DEFINE2(usb, device, xfer, done, "usbd_status"/*status*/); SDT_PROBE_DEFINE1(usb, device, xfer, destroy, "struct usbd_xfer *"/*xfer*/); -Static usbd_status usbd_ar_pipe(struct usbd_pipe *); +Static void usbd_ar_pipe(struct usbd_pipe *); Static void usbd_start_next(struct usbd_pipe *); Static usbd_status usbd_open_pipe_ival (struct usbd_interface *, uint8_t, uint8_t, struct usbd_pipe **, int); static void *usbd_alloc_buffer(struct usbd_xfer *, uint32_t); static void usbd_free_buffer(struct usbd_xfer *); static struct usbd_xfer *usbd_alloc_xfer(struct usbd_device *, unsigned int); -static usbd_status usbd_free_xfer(struct usbd_xfer *); +static void usbd_free_xfer(struct usbd_xfer *); static void usbd_request_async_cb(struct usbd_xfer *, void *, usbd_status); static void usbd_xfer_timeout(void *); static void usbd_xfer_timeout_task(void *); @@ -320,7 +320,7 @@ usbd_open_pipe_intr(struct usbd_interface *iface, uint8_t address, return err; } -usbd_status +void usbd_close_pipe(struct usbd_pipe *pipe) { USBHIST_FUNC(); USBHIST_CALLED(usbdebug); @@ -347,8 +347,6 @@ usbd_close_pipe(struct usbd_pipe *pipe) if (pipe->up_iface) usbd_iface_pipeunref(pipe->up_iface); kmem_free(pipe, pipe->up_dev->ud_bus->ub_pipesize); - - return USBD_NORMAL_COMPLETION; } usbd_status @@ -370,13 +368,6 @@ usbd_transfer(struct usbd_xfer *xfer) #endif xfer->ux_done = 0; - if (pipe->up_aborting) { - USBHIST_LOG(usbdebug, "<- done xfer %#jx, aborting", - (uintptr_t)xfer, 0, 0, 0); - SDT_PROBE2(usb, device, xfer, done, xfer, USBD_CANCELLED); - return USBD_CANCELLED; - } - KASSERT(xfer->ux_length == 0 || xfer->ux_buf != NULL); size = xfer->ux_length; @@ -404,11 +395,41 @@ usbd_transfer(struct usbd_xfer *xfer) } } + usbd_lock_pipe(pipe); + if (pipe->up_aborting) { + /* + * XXX For synchronous transfers this is fine. What to + * do for asynchronous transfers? The callback is + * never run, not even with status USBD_CANCELLED. + */ + usbd_unlock_pipe(pipe); + USBHIST_LOG(usbdebug, "<- done xfer %#jx, aborting", + (uintptr_t)xfer, 0, 0, 0); + SDT_PROBE2(usb, device, xfer, done, xfer, USBD_CANCELLED); + return USBD_CANCELLED; + } + /* xfer is not valid after the transfer method unless synchronous */ SDT_PROBE2(usb, device, pipe, transfer__start, pipe, xfer); - err = pipe->up_methods->upm_transfer(xfer); + do { +#ifdef DIAGNOSTIC + xfer->ux_state = XFER_ONQU; +#endif + SIMPLEQ_INSERT_TAIL(&pipe->up_queue, xfer, ux_next); + if (pipe->up_running && pipe->up_serialise) { + err = USBD_IN_PROGRESS; + } else { + pipe->up_running = 1; + err = USBD_NORMAL_COMPLETION; + } + if (err) + break; + err = pipe->up_methods->upm_transfer(xfer); + } while (0); SDT_PROBE3(usb, device, pipe, transfer__done, pipe, xfer, err); + usbd_unlock_pipe(pipe); + if (err != USBD_IN_PROGRESS && err) { /* * The transfer made it onto the pipe queue, but didn't get @@ -431,8 +452,8 @@ usbd_transfer(struct usbd_xfer *xfer) if (!(flags & USBD_SYNCHRONOUS)) { USBHIST_LOG(usbdebug, "<- done xfer %#jx, not sync (err %jd)", (uintptr_t)xfer, err, 0, 0); - if (err != USBD_IN_PROGRESS) /* XXX Possible? */ - SDT_PROBE2(usb, device, xfer, done, xfer, err); + KASSERTMSG(err != USBD_NORMAL_COMPLETION, + "asynchronous xfer %p completed synchronously", xfer); return err; } @@ -582,7 +603,7 @@ out: return xfer; } -static usbd_status +static void usbd_free_xfer(struct usbd_xfer *xfer) { USBHIST_FUNC(); @@ -602,7 +623,6 @@ usbd_free_xfer(struct usbd_xfer *xfer) cv_destroy(&xfer->ux_cv); xfer->ux_bus->ub_methods->ubm_freex(xfer->ux_bus, xfer); - return USBD_NORMAL_COMPLETION; } int @@ -761,23 +781,40 @@ usbd_interface2endpoint_descriptor(struct usbd_interface *iface, uint8_t index) /* Some drivers may wish to abort requests on the default pipe, * * but there is no mechanism for getting a handle on it. */ -usbd_status +void usbd_abort_default_pipe(struct usbd_device *device) { - return usbd_abort_pipe(device->ud_pipe0); + usbd_abort_pipe(device->ud_pipe0); } -usbd_status +void usbd_abort_pipe(struct usbd_pipe *pipe) { - usbd_status err; + + usbd_suspend_pipe(pipe); + usbd_resume_pipe(pipe); +} + +void +usbd_suspend_pipe(struct usbd_pipe *pipe) +{ KASSERT(pipe != NULL); usbd_lock_pipe(pipe); - err = usbd_ar_pipe(pipe); + usbd_ar_pipe(pipe); + usbd_unlock_pipe(pipe); +} + +void +usbd_resume_pipe(struct usbd_pipe *pipe) +{ + + usbd_lock_pipe(pipe); + KASSERT(pipe->up_aborting); + KASSERT(SIMPLEQ_EMPTY(&pipe->up_queue)); + pipe->up_aborting = 0; usbd_unlock_pipe(pipe); - return err; } usbd_status @@ -958,7 +995,7 @@ usbd_get_interface(struct usbd_interface *iface, uint8_t *aiface) /*** Internal routines ***/ /* Dequeue all pipe operations, called with bus lock held. */ -Static usbd_status +Static void usbd_ar_pipe(struct usbd_pipe *pipe) { struct usbd_xfer *xfer; @@ -1000,9 +1037,7 @@ usbd_ar_pipe(struct usbd_pipe *pipe) /* XXX only for non-0 usbd_clear_endpoint_stall(pipe); */ } } - pipe->up_aborting = 0; SDT_PROBE1(usb, device, pipe, abort__done, pipe); - return USBD_NORMAL_COMPLETION; } /* Called with USB lock held. */ @@ -1135,37 +1170,6 @@ usb_transfer_complete(struct usbd_xfer *xfer) usbd_start_next(pipe); } -/* Called with USB lock held. */ -usbd_status -usb_insert_transfer(struct usbd_xfer *xfer) -{ - struct usbd_pipe *pipe = xfer->ux_pipe; - usbd_status err; - - USBHIST_FUNC(); USBHIST_CALLARGS(usbdebug, - "xfer = %#jx pipe = %#jx running = %jd timeout = %jd", - (uintptr_t)xfer, (uintptr_t)pipe, - pipe->up_running, xfer->ux_timeout); - - KASSERT(mutex_owned(pipe->up_dev->ud_bus->ub_lock)); - KASSERTMSG(xfer->ux_state == XFER_BUSY, "xfer %p state is %x", xfer, - xfer->ux_state); - -#ifdef DIAGNOSTIC - xfer->ux_state = XFER_ONQU; -#endif - SIMPLEQ_INSERT_TAIL(&pipe->up_queue, xfer, ux_next); - if (pipe->up_running && pipe->up_serialise) - err = USBD_IN_PROGRESS; - else { - pipe->up_running = 1; - err = USBD_NORMAL_COMPLETION; - } - USBHIST_LOG(usbdebug, "<- done xfer %#jx, err %jd", (uintptr_t)xfer, - err, 0, 0); - return err; -} - /* Called with USB lock held. */ void usbd_start_next(struct usbd_pipe *pipe) @@ -1190,12 +1194,8 @@ usbd_start_next(struct usbd_pipe *pipe) if (xfer == NULL) { pipe->up_running = 0; } else { - if (!polling) - mutex_exit(pipe->up_dev->ud_bus->ub_lock); SDT_PROBE2(usb, device, pipe, start, pipe, xfer); err = pipe->up_methods->upm_start(xfer); - if (!polling) - mutex_enter(pipe->up_dev->ud_bus->ub_lock); if (err != USBD_IN_PROGRESS) { USBHIST_LOG(usbdebug, "error = %jd", err, 0, 0, 0); @@ -1531,11 +1531,13 @@ usbd_xfer_abort(struct usbd_xfer *xfer) usbd_xfer_cancel_timeout_async(xfer); /* - * We beat everyone else. Claim the status as cancelled and do - * the bus-specific dance to abort the hardware. + * We beat everyone else. Claim the status as cancelled, do + * the bus-specific dance to abort the hardware, and complete + * the xfer. */ xfer->ux_status = USBD_CANCELLED; bus->ub_methods->ubm_abortx(xfer); + usb_transfer_complete(xfer); } /* @@ -1615,11 +1617,13 @@ usbd_xfer_timeout_task(void *cookie) goto out; /* - * We beat everyone else. Claim the status as timed out and do - * the bus-specific dance to abort the hardware. + * We beat everyone else. Claim the status as timed out, do + * the bus-specific dance to abort the hardware, and complete + * the xfer. */ xfer->ux_status = USBD_TIMEOUT; bus->ub_methods->ubm_abortx(xfer); + usb_transfer_complete(xfer); out: /* All done -- release the lock. */ mutex_exit(bus->ub_lock); diff --git a/sys/dev/usb/usbdi.h b/sys/dev/usb/usbdi.h index 71d61eca5394..ef81dc466f9a 100644 --- a/sys/dev/usb/usbdi.h +++ b/sys/dev/usb/usbdi.h @@ -91,7 +91,7 @@ usbd_status usbd_open_pipe_intr(struct usbd_interface *, uint8_t, uint8_t, struct usbd_pipe **, void *, void *, uint32_t, usbd_callback, int); usbd_status usbd_open_pipe(struct usbd_interface *, uint8_t, uint8_t, struct usbd_pipe **); -usbd_status usbd_close_pipe(struct usbd_pipe *); +void usbd_close_pipe(struct usbd_pipe *); usbd_status usbd_transfer(struct usbd_xfer *); @@ -118,8 +118,11 @@ void usbd_get_xfer_status(struct usbd_xfer *, void **, usb_endpoint_descriptor_t *usbd_interface2endpoint_descriptor (struct usbd_interface *, uint8_t); -usbd_status usbd_abort_pipe(struct usbd_pipe *); -usbd_status usbd_abort_default_pipe(struct usbd_device *); +void usbd_abort_pipe(struct usbd_pipe *); +void usbd_abort_default_pipe(struct usbd_device *); + +void usbd_suspend_pipe(struct usbd_pipe *); +void usbd_resume_pipe(struct usbd_pipe *); usbd_status usbd_clear_endpoint_stall(struct usbd_pipe *); void usbd_clear_endpoint_stall_async(struct usbd_pipe *); diff --git a/sys/dev/usb/usbdivar.h b/sys/dev/usb/usbdivar.h index e993fc25b7a1..81e79ee77bbf 100644 --- a/sys/dev/usb/usbdivar.h +++ b/sys/dev/usb/usbdivar.h @@ -30,6 +30,9 @@ * POSSIBILITY OF SUCH DAMAGE. */ +#ifndef _DEV_USB_USBDIVAR_H_ +#define _DEV_USB_USBDIVAR_H_ + /* * Discussion about locking in the USB code: * @@ -41,18 +44,21 @@ * BUS METHOD LOCK NOTES * ----------------------- ------- ------------------------- * ubm_open - might want to take lock? - * ubm_softint x + * ubm_softint x may release/reacquire lock * ubm_dopoll - might want to take lock? * ubm_allocx - * ubm_freex - + * ubm_abortx x must not release/reacquire lock * ubm_getlock - Called at attach time * ubm_newdev - Will take lock - ubm_rhctrl + * ubm_rhctrl x * * PIPE METHOD LOCK NOTES * ----------------------- ------- ------------------------- - * upm_transfer - - * upm_start - might want to take lock? + * upm_init - + * upm_fini - + * upm_transfer x + * upm_start x * upm_abort x * upm_close x * upm_cleartoggle - @@ -64,7 +70,6 @@ * USB functions known to expect the lock taken include (this list is * probably not exhaustive): * usb_transfer_complete() - * usb_insert_transfer() * usb_start_next() * */ @@ -356,7 +361,6 @@ void usbd_iface_pipeunref(struct usbd_interface *); usbd_status usbd_fill_iface_data(struct usbd_device *, int, int); void usb_free_device(struct usbd_device *); -usbd_status usb_insert_transfer(struct usbd_xfer *); void usb_transfer_complete(struct usbd_xfer *); int usb_disconnect_port(struct usbd_port *, device_t, int); @@ -397,3 +401,5 @@ usb_addr2dindex(int addr) #define usbd_lock_pipe(p) mutex_enter((p)->up_dev->ud_bus->ub_lock) #define usbd_unlock_pipe(p) mutex_exit((p)->up_dev->ud_bus->ub_lock) + +#endif /* _DEV_USB_USBDIVAR_H_ */ diff --git a/sys/dev/usb/usbnet.c b/sys/dev/usb/usbnet.c index 1f57e11ea39e..50603bed02d8 100644 --- a/sys/dev/usb/usbnet.c +++ b/sys/dev/usb/usbnet.c @@ -779,10 +779,7 @@ usbnet_ep_close_pipes(struct usbnet * const un) for (size_t i = 0; i < __arraycount(unp->unp_ep); i++) { if (unp->unp_ep[i] == NULL) continue; - usbd_status err = usbd_close_pipe(unp->unp_ep[i]); - if (err) - aprint_error_dev(un->un_dev, "close pipe %zu: %s\n", i, - usbd_errstr(err)); + usbd_close_pipe(unp->unp_ep[i]); unp->unp_ep[i] = NULL; } } @@ -817,21 +814,16 @@ usbnet_ep_open_pipes(struct usbnet * const un) return USBD_NORMAL_COMPLETION; } -static usbd_status +static void usbnet_ep_stop_pipes(struct usbnet * const un) { struct usbnet_private * const unp = un->un_pri; - usbd_status err = USBD_NORMAL_COMPLETION; for (size_t i = 0; i < __arraycount(unp->unp_ep); i++) { if (unp->unp_ep[i] == NULL) continue; - usbd_status err2 = usbd_abort_pipe(unp->unp_ep[i]); - if (err == USBD_NORMAL_COMPLETION && err2) - err = err2; + usbd_abort_pipe(unp->unp_ep[i]); } - - return err; } static int @@ -1208,17 +1200,13 @@ usbnet_watchdog(struct ifnet *ifp) struct usbnet * const un = ifp->if_softc; struct usbnet_private * const unp = un->un_pri; struct usbnet_cdata * const cd = un_cdata(un); - usbd_status err; if_statinc(ifp, if_oerrors); device_printf(un->un_dev, "watchdog timeout\n"); if (cd->uncd_tx_cnt > 0) { DPRINTF("uncd_tx_cnt=%ju non zero, aborting pipe", 0, 0, 0, 0); - err = usbd_abort_pipe(unp->unp_ep[USBNET_ENDPT_TX]); - if (err) - device_printf(un->un_dev, "pipe abort failed: %s\n", - usbd_errstr(err)); + usbd_abort_pipe(unp->unp_ep[USBNET_ENDPT_TX]); if (cd->uncd_tx_cnt != 0) DPRINTF("uncd_tx_cnt now %ju", cd->uncd_tx_cnt, 0, 0, 0); } diff --git a/sys/dev/usb/usbroothub.c b/sys/dev/usb/usbroothub.c index c455f89abee4..8e2ceacdac5a 100644 --- a/sys/dev/usb/usbroothub.c +++ b/sys/dev/usb/usbroothub.c @@ -343,16 +343,6 @@ static const usb_hub_descriptor_t usbroothub_hubd = { usbd_status roothub_ctrl_transfer(struct usbd_xfer *xfer) { - struct usbd_pipe *pipe = xfer->ux_pipe; - struct usbd_bus *bus = pipe->up_dev->ud_bus; - usbd_status err; - - /* Insert last in queue. */ - mutex_enter(bus->ub_lock); - err = usb_insert_transfer(xfer); - mutex_exit(bus->ub_lock); - if (err) - return err; /* Pipe isn't running, start first */ return roothub_ctrl_start(SIMPLEQ_FIRST(&xfer->ux_pipe->up_queue)); @@ -371,6 +361,13 @@ roothub_ctrl_start(struct usbd_xfer *xfer) USBHIST_FUNC(); + /* + * XXX Should really assert pipe lock, in case ever have + * per-pipe locking instead of using the bus lock for all + * pipes. + */ + KASSERT(bus->ub_usepolling || mutex_owned(bus->ub_lock)); + KASSERT(xfer->ux_rqflags & URQ_REQUEST); req = &xfer->ux_request; @@ -564,9 +561,7 @@ roothub_ctrl_start(struct usbd_xfer *xfer) (uintptr_t)xfer, buflen, actlen, err); xfer->ux_status = err; - mutex_enter(bus->ub_lock); usb_transfer_complete(xfer); - mutex_exit(bus->ub_lock); return USBD_NORMAL_COMPLETION; } diff --git a/sys/dev/usb/utoppy.c b/sys/dev/usb/utoppy.c index a40352fedf90..b412542d5c3d 100644 --- a/sys/dev/usb/utoppy.c +++ b/sys/dev/usb/utoppy.c @@ -1365,7 +1365,6 @@ static int utoppyclose(dev_t dev, int flag, int mode, struct lwp *l) { struct utoppy_softc *sc; - usbd_status err; sc = device_lookup_private(&utoppy_cd, UTOPPYUNIT(dev)); @@ -1384,14 +1383,12 @@ utoppyclose(dev_t dev, int flag, int mode, struct lwp *l) (void) utoppy_cancel(sc); if (sc->sc_out_pipe != NULL) { - if ((err = usbd_abort_pipe(sc->sc_out_pipe)) != 0) - printf("usbd_abort_pipe(OUT) returned %d\n", err); + usbd_abort_pipe(sc->sc_out_pipe); sc->sc_out_pipe = NULL; } if (sc->sc_in_pipe != NULL) { - if ((err = usbd_abort_pipe(sc->sc_in_pipe)) != 0) - printf("usbd_abort_pipe(IN) returned %d\n", err); + usbd_abort_pipe(sc->sc_in_pipe); sc->sc_in_pipe = NULL; } diff --git a/sys/dev/usb/vhci.c b/sys/dev/usb/vhci.c index f5c46b9a774e..7d4254cc70b5 100644 --- a/sys/dev/usb/vhci.c +++ b/sys/dev/usb/vhci.c @@ -590,18 +590,9 @@ vhci_roothub_ctrl(struct usbd_bus *bus, usb_device_request_t *req, static usbd_status vhci_device_ctrl_transfer(struct usbd_xfer *xfer) { - vhci_softc_t *sc = xfer->ux_bus->ub_hcpriv; - usbd_status err; DPRINTF("%s: called\n", __func__); - /* Insert last in queue. */ - mutex_enter(&sc->sc_lock); - err = usb_insert_transfer(xfer); - mutex_exit(&sc->sc_lock); - if (err) - return err; - /* Pipe isn't running, start first */ return vhci_device_ctrl_start(SIMPLEQ_FIRST(&xfer->ux_pipe->up_queue)); } @@ -614,7 +605,6 @@ vhci_device_ctrl_start(struct usbd_xfer *xfer) struct usbd_device *dev = xfer->ux_pipe->up_dev; vhci_softc_t *sc = xfer->ux_bus->ub_hcpriv; vhci_port_t *port; - bool polling = sc->sc_bus.ub_usepolling; bool isread = (req->bmRequestType & UT_READ) != 0; uint8_t addr = UE_GET_ADDR(ed->bEndpointAddress); int portno, ret; @@ -627,14 +617,13 @@ vhci_device_ctrl_start(struct usbd_xfer *xfer) DPRINTF("%s: type=0x%02x, len=%d, isread=%d, portno=%d\n", __func__, req->bmRequestType, UGETW(req->wLength), isread, portno); + KASSERT(sc->sc_bus.ub_usepolling || mutex_owned(&sc->sc_lock)); + if (sc->sc_dying) return USBD_IOERROR; port = &sc->sc_port[portno]; - if (!polling) - mutex_enter(&sc->sc_lock); - mutex_enter(&port->lock); if (port->status & UPS_PORT_ENABLED) { xfer->ux_status = USBD_IN_PROGRESS; @@ -645,9 +634,6 @@ vhci_device_ctrl_start(struct usbd_xfer *xfer) } mutex_exit(&port->lock); - if (!polling) - mutex_exit(&sc->sc_lock); - return ret; } @@ -707,18 +693,9 @@ vhci_device_ctrl_done(struct usbd_xfer *xfer) static usbd_status vhci_root_intr_transfer(struct usbd_xfer *xfer) { - vhci_softc_t *sc = xfer->ux_bus->ub_hcpriv; - usbd_status err; DPRINTF("%s: called\n", __func__); - /* Insert last in queue. */ - mutex_enter(&sc->sc_lock); - err = usb_insert_transfer(xfer); - mutex_exit(&sc->sc_lock); - if (err) - return err; - /* Pipe isn't running, start first */ return vhci_root_intr_start(SIMPLEQ_FIRST(&xfer->ux_pipe->up_queue)); } @@ -727,20 +704,17 @@ static usbd_status vhci_root_intr_start(struct usbd_xfer *xfer) { vhci_softc_t *sc = xfer->ux_bus->ub_hcpriv; - const bool polling = sc->sc_bus.ub_usepolling; DPRINTF("%s: called, len=%zu\n", __func__, (size_t)xfer->ux_length); + KASSERT(sc->sc_bus.ub_usepolling || mutex_owned(&sc->sc_lock)); + if (sc->sc_dying) return USBD_IOERROR; - if (!polling) - mutex_enter(&sc->sc_lock); KASSERT(sc->sc_intrxfer == NULL); sc->sc_intrxfer = xfer; xfer->ux_status = USBD_IN_PROGRESS; - if (!polling) - mutex_exit(&sc->sc_lock); return USBD_IN_PROGRESS; } diff --git a/sys/dev/usb/xhci.c b/sys/dev/usb/xhci.c index 6c79c07ac6ec..efc6f7459eb2 100644 --- a/sys/dev/usb/xhci.c +++ b/sys/dev/usb/xhci.c @@ -2154,8 +2154,6 @@ xhci_abortx(struct usbd_xfer *xfer) xhci_pipe_restart(xfer->ux_pipe); - usb_transfer_complete(xfer); - DPRINTFN(14, "end", 0, 0, 0, 0); } @@ -2188,7 +2186,6 @@ xhci_pipe_async_task(void *cookie) struct xhci_slot * const xs = pipe->up_dev->ud_hcpriv; const u_int dci = xhci_ep_get_dci(pipe->up_endpoint->ue_edesc); struct xhci_ring * const tr = xs->xs_xr[dci]; - bool restart = false; XHCIHIST_FUNC(); XHCIHIST_CALLARGS("pipe %#jx slot %ju dci %ju", @@ -2229,31 +2226,18 @@ xhci_pipe_async_task(void *cookie) /* * If we halted our own queue because it stalled, mark it no - * longer halted and arrange to start it up again. + * longer halted and start issuing queued transfers again. */ if (tr->is_halted) { + struct usbd_xfer *xfer = SIMPLEQ_FIRST(&pipe->up_queue); + tr->is_halted = false; - if (!SIMPLEQ_EMPTY(&pipe->up_queue)) - restart = true; + if (xfer) + (*pipe->up_methods->upm_start)(xfer); } mutex_exit(&sc->sc_lock); - /* - * If the endpoint was stalled, start issuing queued transfers - * again. - */ - if (restart) { - /* - * XXX Shouldn't touch the queue unlocked -- upm_start - * should be called with the lock held instead. The - * pipe could be aborted at this point, and the xfer - * freed. - */ - struct usbd_xfer *xfer = SIMPLEQ_FIRST(&pipe->up_queue); - (*pipe->up_methods->upm_start)(xfer); - } - DPRINTFN(4, "ends", 0, 0, 0, 0); } @@ -3872,6 +3856,8 @@ xhci_roothub_ctrl(struct usbd_bus *bus, usb_device_request_t *req, XHCIHIST_FUNC(); + KASSERT(bus->ub_usepolling || mutex_owned(bus->ub_lock)); + if (sc->sc_dying) return -1; @@ -4129,18 +4115,8 @@ xhci_roothub_ctrl(struct usbd_bus *bus, usb_device_request_t *req, static usbd_status xhci_root_intr_transfer(struct usbd_xfer *xfer) { - struct xhci_softc * const sc = XHCI_XFER2SC(xfer); - usbd_status err; - XHCIHIST_FUNC(); XHCIHIST_CALLED(); - /* Insert last in queue. */ - mutex_enter(&sc->sc_lock); - err = usb_insert_transfer(xfer); - mutex_exit(&sc->sc_lock); - if (err) - return err; - /* Pipe isn't running, start first */ return xhci_root_intr_start(SIMPLEQ_FIRST(&xfer->ux_pipe->up_queue)); } @@ -4151,20 +4127,17 @@ xhci_root_intr_start(struct usbd_xfer *xfer) { struct xhci_softc * const sc = XHCI_XFER2SC(xfer); const size_t bn = XHCI_XFER2BUS(xfer) == &sc->sc_bus ? 0 : 1; - const bool polling = xhci_polling_p(sc); XHCIHIST_FUNC(); XHCIHIST_CALLED(); + KASSERT(xhci_polling_p(sc) || mutex_owned(&sc->sc_lock)); + if (sc->sc_dying) return USBD_IOERROR; - if (!polling) - mutex_enter(&sc->sc_lock); KASSERT(sc->sc_intrxfer[bn] == NULL); sc->sc_intrxfer[bn] = xfer; xfer->ux_status = USBD_IN_PROGRESS; - if (!polling) - mutex_exit(&sc->sc_lock); return USBD_IN_PROGRESS; } @@ -4233,18 +4206,8 @@ xhci_root_intr_done(struct usbd_xfer *xfer) static usbd_status xhci_device_ctrl_transfer(struct usbd_xfer *xfer) { - struct xhci_softc * const sc = XHCI_XFER2SC(xfer); - usbd_status err; - XHCIHIST_FUNC(); XHCIHIST_CALLED(); - /* Insert last in queue. */ - mutex_enter(&sc->sc_lock); - err = usb_insert_transfer(xfer); - mutex_exit(&sc->sc_lock); - if (err) - return err; - /* Pipe isn't running, start first */ return xhci_device_ctrl_start(SIMPLEQ_FIRST(&xfer->ux_pipe->up_queue)); } @@ -4272,14 +4235,14 @@ xhci_device_ctrl_start(struct usbd_xfer *xfer) req->bmRequestType | (req->bRequest << 8), UGETW(req->wValue), UGETW(req->wIndex), UGETW(req->wLength)); + KASSERT(polling || mutex_owned(&sc->sc_lock)); + /* we rely on the bottom bits for extra info */ KASSERTMSG(((uintptr_t)xfer & 0x3) == 0x0, "xfer %zx", (uintptr_t) xfer); KASSERT((xfer->ux_rqflags & URQ_REQUEST) != 0); - if (!polling) - mutex_enter(&sc->sc_lock); if (tr->is_halted) goto out; @@ -4337,8 +4300,6 @@ out: if (xfer->ux_status == USBD_NOT_STARTED) { */ } KASSERT(xfer->ux_status == USBD_IN_PROGRESS); - if (!polling) - mutex_exit(&sc->sc_lock); return USBD_IN_PROGRESS; } @@ -4378,18 +4339,8 @@ xhci_device_ctrl_close(struct usbd_pipe *pipe) static usbd_status xhci_device_isoc_transfer(struct usbd_xfer *xfer) { - struct xhci_softc * const sc = XHCI_XFER2SC(xfer); - usbd_status err; - XHCIHIST_FUNC(); XHCIHIST_CALLED(); - /* Insert last in queue. */ - mutex_enter(&sc->sc_lock); - err = usb_insert_transfer(xfer); - mutex_exit(&sc->sc_lock); - if (err) - return err; - return xhci_device_isoc_enter(xfer); } @@ -4420,6 +4371,8 @@ xhci_device_isoc_enter(struct usbd_xfer *xfer) XHCIHIST_CALLARGS("%#jx slot %ju dci %ju", (uintptr_t)xfer, xs->xs_idx, dci, 0); + KASSERT(polling || mutex_owned(&sc->sc_lock)); + if (sc->sc_dying) return USBD_IOERROR; @@ -4492,13 +4445,9 @@ xhci_device_isoc_enter(struct usbd_xfer *xfer) if (!polling) mutex_exit(&tr->xr_lock); - if (!polling) - mutex_enter(&sc->sc_lock); xfer->ux_status = USBD_IN_PROGRESS; xhci_db_write_4(sc, XHCI_DOORBELL(xs->xs_idx), dci); usbd_xfer_schedule_timeout(xfer); - if (!polling) - mutex_exit(&sc->sc_lock); return USBD_IN_PROGRESS; } @@ -4542,22 +4491,9 @@ xhci_device_isoc_done(struct usbd_xfer *xfer) static usbd_status xhci_device_bulk_transfer(struct usbd_xfer *xfer) { - struct xhci_softc * const sc = XHCI_XFER2SC(xfer); - usbd_status err; - XHCIHIST_FUNC(); XHCIHIST_CALLED(); - /* Insert last in queue. */ - mutex_enter(&sc->sc_lock); - err = usb_insert_transfer(xfer); - mutex_exit(&sc->sc_lock); - if (err) - return err; - - /* - * Pipe isn't running (otherwise err would be USBD_INPROG), - * so start it first. - */ + /* Pipe isn't running, so start it first. */ return xhci_device_bulk_start(SIMPLEQ_FIRST(&xfer->ux_pipe->up_queue)); } @@ -4581,13 +4517,13 @@ xhci_device_bulk_start(struct usbd_xfer *xfer) XHCIHIST_CALLARGS("%#jx slot %ju dci %ju", (uintptr_t)xfer, xs->xs_idx, dci, 0); + KASSERT(polling || mutex_owned(&sc->sc_lock)); + if (sc->sc_dying) return USBD_IOERROR; KASSERT((xfer->ux_rqflags & URQ_REQUEST) == 0); - if (!polling) - mutex_enter(&sc->sc_lock); if (tr->is_halted) goto out; @@ -4635,8 +4571,6 @@ out: if (xfer->ux_status == USBD_NOT_STARTED) { */ } KASSERT(xfer->ux_status == USBD_IN_PROGRESS); - if (!polling) - mutex_exit(&sc->sc_lock); return USBD_IN_PROGRESS; } @@ -4680,22 +4614,9 @@ xhci_device_bulk_close(struct usbd_pipe *pipe) static usbd_status xhci_device_intr_transfer(struct usbd_xfer *xfer) { - struct xhci_softc * const sc = XHCI_XFER2SC(xfer); - usbd_status err; - XHCIHIST_FUNC(); XHCIHIST_CALLED(); - /* Insert last in queue. */ - mutex_enter(&sc->sc_lock); - err = usb_insert_transfer(xfer); - mutex_exit(&sc->sc_lock); - if (err) - return err; - - /* - * Pipe isn't running (otherwise err would be USBD_INPROG), - * so start it first. - */ + /* Pipe isn't running, so start it first. */ return xhci_device_intr_start(SIMPLEQ_FIRST(&xfer->ux_pipe->up_queue)); } @@ -4719,11 +4640,11 @@ xhci_device_intr_start(struct usbd_xfer *xfer) XHCIHIST_CALLARGS("%#jx slot %ju dci %ju", (uintptr_t)xfer, xs->xs_idx, dci, 0); + KASSERT(polling || mutex_owned(&sc->sc_lock)); + if (sc->sc_dying) return USBD_IOERROR; - if (!polling) - mutex_enter(&sc->sc_lock); if (tr->is_halted) goto out; @@ -4761,8 +4682,6 @@ out: if (xfer->ux_status == USBD_NOT_STARTED) { */ } KASSERT(xfer->ux_status == USBD_IN_PROGRESS); - if (!polling) - mutex_exit(&sc->sc_lock); return USBD_IN_PROGRESS; } diff --git a/sys/dev/usb/xhcivar.h b/sys/dev/usb/xhcivar.h index 9893037be2e1..b253da58557f 100644 --- a/sys/dev/usb/xhcivar.h +++ b/sys/dev/usb/xhcivar.h @@ -29,8 +29,17 @@ #ifndef _DEV_USB_XHCIVAR_H_ #define _DEV_USB_XHCIVAR_H_ +#include + +#include +#include +#include +#include #include +#include +#include + #define XHCI_MAX_DCI 31 struct xhci_soft_trb { diff --git a/sys/external/bsd/dwc2/dwc2.c b/sys/external/bsd/dwc2/dwc2.c index e3e61a072b23..7bc817f0448e 100644 --- a/sys/external/bsd/dwc2/dwc2.c +++ b/sys/external/bsd/dwc2/dwc2.c @@ -515,7 +515,7 @@ dwc2_abortx(struct usbd_xfer *xfer) } /* - * HC Step 1: Handle the hardware. + * Handle the hardware. */ err = dwc2_hcd_urb_dequeue(hsotg, dxfer->urb); if (err) { @@ -524,11 +524,6 @@ dwc2_abortx(struct usbd_xfer *xfer) dying: mutex_spin_exit(&hsotg->lock); - - /* - * Final Step: Notify completion to waiting xfers. - */ - usb_transfer_complete(xfer); KASSERT(mutex_owned(&sc->sc_lock)); } @@ -614,18 +609,9 @@ dwc2_roothub_ctrl(struct usbd_bus *bus, usb_device_request_t *req, Static usbd_status dwc2_root_intr_transfer(struct usbd_xfer *xfer) { - struct dwc2_softc *sc = DWC2_XFER2SC(xfer); - usbd_status err; DPRINTF("\n"); - /* Insert last in queue. */ - mutex_enter(&sc->sc_lock); - err = usb_insert_transfer(xfer); - mutex_exit(&sc->sc_lock); - if (err) - return err; - /* Pipe isn't running, start first */ return dwc2_root_intr_start(SIMPLEQ_FIRST(&xfer->ux_pipe->up_queue)); } @@ -634,20 +620,17 @@ Static usbd_status dwc2_root_intr_start(struct usbd_xfer *xfer) { struct dwc2_softc *sc = DWC2_XFER2SC(xfer); - const bool polling = sc->sc_bus.ub_usepolling; DPRINTF("\n"); + KASSERT(sc->sc_bus.ub_usepolling || mutex_owned(&sc->sc_lock)); + if (sc->sc_dying) return USBD_IOERROR; - if (!polling) - mutex_enter(&sc->sc_lock); KASSERT(sc->sc_intrxfer == NULL); sc->sc_intrxfer = xfer; xfer->ux_status = USBD_IN_PROGRESS; - if (!polling) - mutex_exit(&sc->sc_lock); return USBD_IN_PROGRESS; } @@ -711,18 +694,9 @@ dwc2_root_intr_done(struct usbd_xfer *xfer) Static usbd_status dwc2_device_ctrl_transfer(struct usbd_xfer *xfer) { - struct dwc2_softc *sc = DWC2_XFER2SC(xfer); - usbd_status err; DPRINTF("\n"); - /* Insert last in queue. */ - mutex_enter(&sc->sc_lock); - err = usb_insert_transfer(xfer); - mutex_exit(&sc->sc_lock); - if (err) - return err; - /* Pipe isn't running, start first */ return dwc2_device_ctrl_start(SIMPLEQ_FIRST(&xfer->ux_pipe->up_queue)); } @@ -732,17 +706,13 @@ dwc2_device_ctrl_start(struct usbd_xfer *xfer) { struct dwc2_softc *sc = DWC2_XFER2SC(xfer); usbd_status err; - const bool polling = sc->sc_bus.ub_usepolling; DPRINTF("\n"); - if (!polling) - mutex_enter(&sc->sc_lock); + KASSERT(sc->sc_bus.ub_usepolling || mutex_owned(&sc->sc_lock)); + xfer->ux_status = USBD_IN_PROGRESS; err = dwc2_device_start(xfer); - if (!polling) - mutex_exit(&sc->sc_lock); - if (err) return err; @@ -783,22 +753,12 @@ dwc2_device_ctrl_done(struct usbd_xfer *xfer) Static usbd_status dwc2_device_bulk_transfer(struct usbd_xfer *xfer) { - struct dwc2_softc *sc = DWC2_XFER2SC(xfer); - usbd_status err; DPRINTF("xfer=%p\n", xfer); - /* Insert last in queue. */ - mutex_enter(&sc->sc_lock); - err = usb_insert_transfer(xfer); - - KASSERT(err == USBD_NORMAL_COMPLETION); - + KASSERT(xfer->ux_status == USBD_NOT_STARTED); xfer->ux_status = USBD_IN_PROGRESS; - err = dwc2_device_start(xfer); - mutex_exit(&sc->sc_lock); - - return err; + return dwc2_device_start(xfer); } Static void @@ -833,18 +793,9 @@ dwc2_device_bulk_done(struct usbd_xfer *xfer) Static usbd_status dwc2_device_intr_transfer(struct usbd_xfer *xfer) { - struct dwc2_softc *sc = DWC2_XFER2SC(xfer); - usbd_status err; DPRINTF("xfer=%p\n", xfer); - /* Insert last in queue. */ - mutex_enter(&sc->sc_lock); - err = usb_insert_transfer(xfer); - mutex_exit(&sc->sc_lock); - if (err) - return err; - /* Pipe isn't running, start first */ return dwc2_device_intr_start(SIMPLEQ_FIRST(&xfer->ux_pipe->up_queue)); } @@ -856,15 +807,11 @@ dwc2_device_intr_start(struct usbd_xfer *xfer) struct usbd_device *dev = dpipe->pipe.up_dev; struct dwc2_softc *sc = dev->ud_bus->ub_hcpriv; usbd_status err; - const bool polling = sc->sc_bus.ub_usepolling; - if (!polling) - mutex_enter(&sc->sc_lock); + KASSERT(sc->sc_bus.ub_usepolling || mutex_owned(&sc->sc_lock)); + xfer->ux_status = USBD_IN_PROGRESS; err = dwc2_device_start(xfer); - if (!polling) - mutex_exit(&sc->sc_lock); - if (err) return err; @@ -904,22 +851,12 @@ dwc2_device_intr_done(struct usbd_xfer *xfer) usbd_status dwc2_device_isoc_transfer(struct usbd_xfer *xfer) { - struct dwc2_softc *sc = DWC2_XFER2SC(xfer); - usbd_status err; DPRINTF("xfer=%p\n", xfer); - /* Insert last in queue. */ - mutex_enter(&sc->sc_lock); - err = usb_insert_transfer(xfer); - - KASSERT(err == USBD_NORMAL_COMPLETION); - + KASSERT(xfer->ux_status == USBD_NOT_STARTED); xfer->ux_status = USBD_IN_PROGRESS; - err = dwc2_device_start(xfer); - mutex_exit(&sc->sc_lock); - - return err; + return dwc2_device_start(xfer); } void @@ -973,6 +910,8 @@ dwc2_device_start(struct usbd_xfer *xfer) DPRINTFN(1, "xfer=%p pipe=%p\n", xfer, xfer->ux_pipe); + KASSERT(sc->sc_bus.ub_usepolling || mutex_owned(&sc->sc_lock)); + if (xfertype == UE_ISOCHRONOUS || xfertype == UE_INTERRUPT) { mutex_spin_enter(&hsotg->lock); @@ -1161,9 +1100,7 @@ dwc2_device_start(struct usbd_xfer *xfer) dwc2_hcd_get_ep_bandwidth(hsotg, dpipe), xfer); } - mutex_spin_exit(&hsotg->lock); -// mutex_exit(&sc->sc_lock); return USBD_IN_PROGRESS; diff --git a/sys/rump/dev/lib/libugenhc/ugenhc.c b/sys/rump/dev/lib/libugenhc/ugenhc.c index 003f1cc54453..a1fb16f3e02c 100644 --- a/sys/rump/dev/lib/libugenhc/ugenhc.c +++ b/sys/rump/dev/lib/libugenhc/ugenhc.c @@ -227,6 +227,8 @@ rumpusb_device_ctrl_start(struct usbd_xfer *xfer) int err = 0; int ru_error, mightfail = 0; + KASSERT(sc->sc_bus.ub_usepolling || mutex_owned(&sc->sc_lock)); + len = totlen = UGETW(req->wLength); if (len) buf = xfer->ux_buf; @@ -391,9 +393,7 @@ rumpusb_device_ctrl_start(struct usbd_xfer *xfer) ret: xfer->ux_status = err; - mutex_enter(&sc->sc_lock); usb_transfer_complete(xfer); - mutex_exit(&sc->sc_lock); return USBD_IN_PROGRESS; } @@ -401,14 +401,6 @@ rumpusb_device_ctrl_start(struct usbd_xfer *xfer) static usbd_status rumpusb_device_ctrl_transfer(struct usbd_xfer *xfer) { - struct ugenhc_softc *sc = UGENHC_XFER2SC(xfer); - usbd_status err; - - mutex_enter(&sc->sc_lock); - err = usb_insert_transfer(xfer); - mutex_exit(&sc->sc_lock); - if (err) - return err; return rumpusb_device_ctrl_start(SIMPLEQ_FIRST(&xfer->ux_pipe->up_queue)); } @@ -524,7 +516,8 @@ rumpusb_root_intr_start(struct usbd_xfer *xfer) struct ugenhc_softc *sc = UGENHC_XFER2SC(xfer); int error; - mutex_enter(&sc->sc_lock); + KASSERT(sc->sc_bus.ub_usepolling || mutex_owned(&sc->sc_lock)); + sc->sc_intrxfer = xfer; if (!sc->sc_rhintr) { error = kthread_create(PRI_NONE, 0, NULL, @@ -532,7 +525,6 @@ rumpusb_root_intr_start(struct usbd_xfer *xfer) if (error) xfer->ux_status = USBD_IOERROR; } - mutex_exit(&sc->sc_lock); return USBD_IN_PROGRESS; } @@ -540,14 +532,6 @@ rumpusb_root_intr_start(struct usbd_xfer *xfer) static usbd_status rumpusb_root_intr_transfer(struct usbd_xfer *xfer) { - struct ugenhc_softc *sc = UGENHC_XFER2SC(xfer); - usbd_status err; - - mutex_enter(&sc->sc_lock); - err = usb_insert_transfer(xfer); - mutex_exit(&sc->sc_lock); - if (err) - return err; return rumpusb_root_intr_start(SIMPLEQ_FIRST(&xfer->ux_pipe->up_queue)); } @@ -597,6 +581,8 @@ rumpusb_device_bulk_start(struct usbd_xfer *xfer) int xfererr = USBD_NORMAL_COMPLETION; int shortval, i; + KASSERT(sc->sc_bus.ub_usepolling || mutex_owned(&sc->sc_lock)); + ed = xfer->ux_pipe->up_endpoint->ue_edesc; endpt = ed->bEndpointAddress; isread = UE_GET_DIR(endpt) == UE_DIR_IN; @@ -683,9 +669,7 @@ rumpusb_device_bulk_start(struct usbd_xfer *xfer) if (done != len) panic("lazy bum"); xfer->ux_status = xfererr; - mutex_enter(&sc->sc_lock); usb_transfer_complete(xfer); - mutex_exit(&sc->sc_lock); return USBD_IN_PROGRESS; } @@ -698,9 +682,7 @@ doxfer_kth(void *arg) mutex_enter(&sc->sc_lock); do { struct usbd_xfer *xfer = SIMPLEQ_FIRST(&pipe->up_queue); - mutex_exit(&sc->sc_lock); rumpusb_device_bulk_start(xfer); - mutex_enter(&sc->sc_lock); } while (!SIMPLEQ_EMPTY(&pipe->up_queue)); mutex_exit(&sc->sc_lock); kthread_exit(0); @@ -709,8 +691,6 @@ doxfer_kth(void *arg) static usbd_status rumpusb_device_bulk_transfer(struct usbd_xfer *xfer) { - struct ugenhc_softc *sc = UGENHC_XFER2SC(xfer); - usbd_status err; if (!rump_threads) { /* XXX: lie about supporting async transfers */ @@ -720,20 +700,9 @@ rumpusb_device_bulk_transfer(struct usbd_xfer *xfer) return USBD_IN_PROGRESS; } - mutex_enter(&sc->sc_lock); - err = usb_insert_transfer(xfer); - mutex_exit(&sc->sc_lock); - if (err) - return err; - return rumpusb_device_bulk_start( SIMPLEQ_FIRST(&xfer->ux_pipe->up_queue)); } else { - mutex_enter(&sc->sc_lock); - err = usb_insert_transfer(xfer); - mutex_exit(&sc->sc_lock); - if (err) - return err; kthread_create(PRI_NONE, 0, NULL, doxfer_kth, xfer->ux_pipe, NULL, "rusbhcxf");