Index: kern/kern_subr.c =================================================================== RCS file: /cvsroot/src/sys/kern/kern_subr.c,v retrieving revision 1.219 diff -p -u -r1.219 kern_subr.c --- kern/kern_subr.c 14 Nov 2017 14:14:29 -0000 1.219 +++ kern/kern_subr.c 16 Sep 2018 11:58:03 -0000 @@ -171,6 +171,9 @@ char *bootspec; !device_is_a((dv), "dk") && \ !device_is_a((dv), "flash")) +/* XXX USB keyboards */ +#include "usb.h" + void setroot(device_t bootdv, int bootpartition) { @@ -261,6 +264,19 @@ setroot(device_t bootdv, int bootpartiti if (boothowto & RB_ASKNAME) { device_t defdumpdv; +#if NUSB > 0 +#ifndef USB_ASKNAME_PAUSE_SECONDS +#define USB_ASKNAME_PAUSE_SECONDS 5 +#endif + /* + * XXX Until USB keybaord attachment is properly handled by + * config_pending handling, hack around it for now. + */ + printf("pausing for %u seconds for USB keyboards...", + USB_ASKNAME_PAUSE_SECONDS); + kpause("askroot", true, USB_ASKNAME_PAUSE_SECONDS * hz, NULL); + printf("\n"); +#endif for (;;) { printf("root device"); if (bootdv != NULL) { Index: external/bsd/dwc2/dwc2.c =================================================================== RCS file: /cvsroot/src/sys/external/bsd/dwc2/dwc2.c,v retrieving revision 1.54 diff -p -u -r1.54 dwc2.c --- external/bsd/dwc2/dwc2.c 28 Aug 2018 08:17:10 -0000 1.54 +++ external/bsd/dwc2/dwc2.c 16 Sep 2018 11:58:03 -0000 @@ -625,16 +625,19 @@ 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"); if (sc->sc_dying) return USBD_IOERROR; - mutex_enter(&sc->sc_lock); + if (!polling) + mutex_enter(&sc->sc_lock); KASSERT(sc->sc_intrxfer == NULL); sc->sc_intrxfer = xfer; - mutex_exit(&sc->sc_lock); + if (!polling) + mutex_exit(&sc->sc_lock); return USBD_IN_PROGRESS; } @@ -702,13 +705,16 @@ dwc2_device_ctrl_start(struct usbd_xfer { struct dwc2_softc *sc = DWC2_XFER2SC(xfer); usbd_status err; + const bool polling = sc->sc_bus.ub_usepolling; DPRINTF("\n"); - mutex_enter(&sc->sc_lock); + if (!polling) + mutex_enter(&sc->sc_lock); xfer->ux_status = USBD_IN_PROGRESS; err = dwc2_device_start(xfer); - mutex_exit(&sc->sc_lock); + if (!polling) + mutex_exit(&sc->sc_lock); if (err) return err; @@ -822,11 +828,14 @@ dwc2_device_intr_start(struct usbd_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; - mutex_enter(&sc->sc_lock); + if (!polling) + mutex_enter(&sc->sc_lock); xfer->ux_status = USBD_IN_PROGRESS; err = dwc2_device_start(xfer); - mutex_exit(&sc->sc_lock); + if (!polling) + mutex_exit(&sc->sc_lock); if (err) return err; Index: dev/usb/ehci.c =================================================================== RCS file: /cvsroot/src/sys/dev/usb/ehci.c,v retrieving revision 1.263 diff -p -u -r1.263 ehci.c --- dev/usb/ehci.c 16 Sep 2018 09:25:47 -0000 1.263 +++ dev/usb/ehci.c 16 Sep 2018 11:58:03 -0000 @@ -2637,13 +2637,16 @@ 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; if (sc->sc_dying) return USBD_IOERROR; - mutex_enter(&sc->sc_lock); + if (!polling) + mutex_enter(&sc->sc_lock); sc->sc_intrxfer = xfer; - mutex_exit(&sc->sc_lock); + if (!polling) + mutex_exit(&sc->sc_lock); return USBD_IN_PROGRESS; } @@ -3538,6 +3541,7 @@ ehci_device_ctrl_start(struct usbd_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(); @@ -3657,7 +3661,8 @@ ehci_device_ctrl_start(struct usbd_xfer DPRINTFN(5, "--- dump end ---", 0, 0, 0, 0); #endif - mutex_enter(&sc->sc_lock); + if (!polling) + mutex_enter(&sc->sc_lock); /* Insert qTD in QH list - also does usb_syncmem(sqh) */ ehci_set_qh_qtd(sqh, setup); @@ -3667,7 +3672,8 @@ ehci_device_ctrl_start(struct usbd_xfer } ehci_add_intr_list(sc, exfer); xfer->ux_status = USBD_IN_PROGRESS; - mutex_exit(&sc->sc_lock); + if (!polling) + mutex_exit(&sc->sc_lock); #if 0 #ifdef EHCI_DEBUG @@ -3814,6 +3820,7 @@ ehci_device_bulk_start(struct usbd_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(); @@ -3837,7 +3844,8 @@ ehci_device_bulk_start(struct usbd_xfer #endif /* Take lock here to protect nexttoggle */ - mutex_enter(&sc->sc_lock); + if (!polling) + mutex_enter(&sc->sc_lock); ehci_reset_sqtd_chain(sc, xfer, len, isread, &epipe->nexttoggle, &end); @@ -3864,7 +3872,8 @@ ehci_device_bulk_start(struct usbd_xfer } ehci_add_intr_list(sc, exfer); xfer->ux_status = USBD_IN_PROGRESS; - mutex_exit(&sc->sc_lock); + if (!polling) + mutex_exit(&sc->sc_lock); #if 0 #ifdef EHCI_DEBUG @@ -4029,6 +4038,7 @@ ehci_device_intr_start(struct usbd_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(); @@ -4052,7 +4062,8 @@ ehci_device_intr_start(struct usbd_xfer #endif /* Take lock to protect nexttoggle */ - mutex_enter(&sc->sc_lock); + if (!polling) + mutex_enter(&sc->sc_lock); ehci_reset_sqtd_chain(sc, xfer, len, isread, &epipe->nexttoggle, &end); @@ -4079,7 +4090,8 @@ ehci_device_intr_start(struct usbd_xfer } ehci_add_intr_list(sc, exfer); xfer->ux_status = USBD_IN_PROGRESS; - mutex_exit(&sc->sc_lock); + if (!polling) + mutex_exit(&sc->sc_lock); #if 0 #ifdef EHCI_DEBUG Index: dev/usb/ohci.c =================================================================== RCS file: /cvsroot/src/sys/dev/usb/ohci.c,v retrieving revision 1.286 diff -p -u -r1.286 ohci.c --- dev/usb/ohci.c 16 Sep 2018 10:29:39 -0000 1.286 +++ dev/usb/ohci.c 16 Sep 2018 11:58:03 -0000 @@ -2591,14 +2591,17 @@ 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; if (sc->sc_dying) return USBD_IOERROR; - mutex_enter(&sc->sc_lock); + if (!polling) + mutex_enter(&sc->sc_lock); KASSERT(sc->sc_intrxfer == NULL); sc->sc_intrxfer = xfer; - mutex_exit(&sc->sc_lock); + if (!polling) + mutex_exit(&sc->sc_lock); return USBD_IN_PROGRESS; } @@ -2732,6 +2735,7 @@ ohci_device_ctrl_start(struct usbd_xfer ohci_soft_ed_t *sed; int isread; int len; + const bool polling = sc->sc_bus.ub_usepolling; OHCIHIST_FUNC(); OHCIHIST_CALLED(); @@ -2750,7 +2754,8 @@ ohci_device_ctrl_start(struct usbd_xfer UGETW(req->wIndex)); /* Need to take lock here for pipe->tail.td */ - mutex_enter(&sc->sc_lock); + if (!polling) + mutex_enter(&sc->sc_lock); /* * Use the pipe "tail" TD as our first and loan our first TD to the @@ -2866,7 +2871,7 @@ ohci_device_ctrl_start(struct usbd_xfer sizeof(sed->ed.ed_tailp), BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); OWRITE4(sc, OHCI_COMMAND_STATUS, OHCI_CLF); - if (xfer->ux_timeout && !sc->sc_bus.ub_usepolling) { + if (xfer->ux_timeout && !polling) { callout_reset(&xfer->ux_callout, mstohz(xfer->ux_timeout), ohci_timeout, xfer); } @@ -2874,7 +2879,8 @@ ohci_device_ctrl_start(struct usbd_xfer DPRINTF("done", 0, 0, 0, 0); xfer->ux_status = USBD_IN_PROGRESS; - mutex_exit(&sc->sc_lock); + if (!polling) + mutex_exit(&sc->sc_lock); return USBD_IN_PROGRESS; } @@ -3001,6 +3007,7 @@ ohci_device_bulk_start(struct usbd_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(); @@ -3018,7 +3025,8 @@ ohci_device_bulk_start(struct usbd_xfer len, isread, xfer->ux_flags); DPRINTFN(4, "endpt=%jd", endpt, 0, 0, 0); - mutex_enter(&sc->sc_lock); + if (!polling) + mutex_enter(&sc->sc_lock); /* * Use the pipe "tail" TD as our first and loan our first TD to the @@ -3084,7 +3092,8 @@ ohci_device_bulk_start(struct usbd_xfer } xfer->ux_status = USBD_IN_PROGRESS; - mutex_exit(&sc->sc_lock); + if (!polling) + mutex_exit(&sc->sc_lock); return USBD_IN_PROGRESS; } @@ -3203,6 +3212,7 @@ ohci_device_intr_start(struct usbd_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(); @@ -3218,7 +3228,8 @@ ohci_device_intr_start(struct usbd_xfer endpt = xfer->ux_pipe->up_endpoint->ue_edesc->bEndpointAddress; isread = UE_GET_DIR(endpt) == UE_DIR_IN; - mutex_enter(&sc->sc_lock); + if (!polling) + mutex_enter(&sc->sc_lock); /* * Use the pipe "tail" TD as our first and loan our first TD to the @@ -3270,7 +3281,8 @@ ohci_device_intr_start(struct usbd_xfer BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); xfer->ux_status = USBD_IN_PROGRESS; - mutex_exit(&sc->sc_lock); + if (!polling) + mutex_exit(&sc->sc_lock); return USBD_IN_PROGRESS; } Index: dev/usb/uhci.c =================================================================== RCS file: /cvsroot/src/sys/dev/usb/uhci.c,v retrieving revision 1.283 diff -p -u -r1.283 uhci.c --- dev/usb/uhci.c 3 Sep 2018 16:29:34 -0000 1.283 +++ dev/usb/uhci.c 16 Sep 2018 11:58:03 -0000 @@ -1555,7 +1555,7 @@ uhci_idone(struct uhci_xfer *ux, ux_comp struct uhci_pipe *upipe = UHCI_PIPE2UPIPE(xfer->ux_pipe); uhci_soft_td_t *std; uint32_t status = 0, nstatus; - bool polling __diagused = sc->sc_bus.ub_usepolling; + const bool polling __diagused = sc->sc_bus.ub_usepolling; int actlen; KASSERT(polling || mutex_owned(&sc->sc_lock)); @@ -2257,6 +2257,7 @@ uhci_device_bulk_start(struct usbd_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; @@ -2277,7 +2278,8 @@ uhci_device_bulk_start(struct usbd_xfer sqh = upipe->bulk.sqh; /* Take lock here to protect nexttoggle */ - mutex_enter(&sc->sc_lock); + if (!polling) + mutex_enter(&sc->sc_lock); uhci_reset_std_chain(sc, xfer, len, isread, &upipe->nexttoggle, &dataend); @@ -2311,12 +2313,13 @@ uhci_device_bulk_start(struct usbd_xfer uhci_add_bulk(sc, sqh); uhci_add_intr_list(sc, ux); - if (xfer->ux_timeout && !sc->sc_bus.ub_usepolling) { + if (xfer->ux_timeout && !polling) { callout_reset(&xfer->ux_callout, mstohz(xfer->ux_timeout), uhci_timeout, xfer); } xfer->ux_status = USBD_IN_PROGRESS; - mutex_exit(&sc->sc_lock); + if (!polling) + mutex_exit(&sc->sc_lock); return USBD_IN_PROGRESS; } @@ -2541,6 +2544,7 @@ uhci_device_ctrl_start(struct usbd_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; @@ -2568,7 +2572,8 @@ uhci_device_ctrl_start(struct usbd_xfer memcpy(KERNADDR(&upipe->ctrl.reqdma, 0), req, sizeof(*req)); usb_syncmem(&upipe->ctrl.reqdma, 0, sizeof(*req), BUS_DMASYNC_PREWRITE); - mutex_enter(&sc->sc_lock); + if (!polling) + mutex_enter(&sc->sc_lock); /* Set up data transaction */ if (len != 0) { @@ -2665,12 +2670,13 @@ uhci_device_ctrl_start(struct usbd_xfer DPRINTF("--- dump end ---", 0, 0, 0, 0); } #endif - if (xfer->ux_timeout && !sc->sc_bus.ub_usepolling) { + if (xfer->ux_timeout && !polling) { callout_reset(&xfer->ux_callout, mstohz(xfer->ux_timeout), uhci_timeout, xfer); } xfer->ux_status = USBD_IN_PROGRESS; - mutex_exit(&sc->sc_lock); + if (!polling) + mutex_exit(&sc->sc_lock); return USBD_IN_PROGRESS; } @@ -2743,6 +2749,7 @@ uhci_device_intr_start(struct usbd_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; @@ -2768,7 +2775,7 @@ uhci_device_intr_start(struct usbd_xfer #endif /* Take lock to protect nexttoggle */ - if (!sc->sc_bus.ub_usepolling) + if (!polling) mutex_enter(&sc->sc_lock); uhci_reset_std_chain(sc, xfer, xfer->ux_length, isread, &upipe->nexttoggle, &dataend); @@ -2801,7 +2808,7 @@ uhci_device_intr_start(struct usbd_xfer } uhci_add_intr_list(sc, ux); xfer->ux_status = USBD_IN_PROGRESS; - if (!sc->sc_bus.ub_usepolling) + if (!polling) mutex_exit(&sc->sc_lock); #ifdef UHCI_DEBUG Index: dev/usb/usb.c =================================================================== RCS file: /cvsroot/src/sys/dev/usb/usb.c,v retrieving revision 1.171 diff -p -u -r1.171 usb.c --- dev/usb/usb.c 2 Aug 2018 06:09:04 -0000 1.171 +++ dev/usb/usb.c 16 Sep 2018 11:58:03 -0000 @@ -375,6 +375,10 @@ usb_doattach(device_t self) sc->sc_dying = 1; } + /* + * Drop this reference after the first set of attachments in the + * event thread. + */ config_pending_incr(self); if (!pmf_device_register(self, NULL, NULL)) @@ -529,6 +533,7 @@ void usb_event_thread(void *arg) { struct usb_softc *sc = arg; + struct usbd_bus *bus = sc->sc_bus; USBHIST_FUNC(); USBHIST_CALLED(usbdebug); @@ -540,30 +545,37 @@ usb_event_thread(void *arg) * know how to synchronize the creation of the threads so it * will work. */ - usb_delay_ms(sc->sc_bus, 500); + usb_delay_ms(bus, 500); /* Make sure first discover does something. */ - mutex_enter(sc->sc_bus->ub_lock); + mutex_enter(bus->ub_lock); sc->sc_bus->ub_needsexplore = 1; usb_discover(sc); - mutex_exit(sc->sc_bus->ub_lock); - config_pending_decr(sc->sc_bus->ub_usbctl); + mutex_exit(bus->ub_lock); + + /* Drop the config_pending reference from attach. */ + config_pending_decr(bus->ub_usbctl); - mutex_enter(sc->sc_bus->ub_lock); + mutex_enter(bus->ub_lock); while (!sc->sc_dying) { +#if 0 /* not yet */ + while (sc->sc_bus->ub_usepolling) + kpause("usbpoll", true, hz, bus->ub_lock); +#endif + if (usb_noexplore < 2) usb_discover(sc); - cv_timedwait(&sc->sc_bus->ub_needsexplore_cv, - sc->sc_bus->ub_lock, usb_noexplore ? 0 : hz * 60); + cv_timedwait(&bus->ub_needsexplore_cv, + bus->ub_lock, usb_noexplore ? 0 : hz * 60); DPRINTFN(2, "sc %#jx woke up", (uintptr_t)sc, 0, 0, 0); } sc->sc_event_thread = NULL; /* In case parent is waiting for us to exit. */ - cv_signal(&sc->sc_bus->ub_needsexplore_cv); - mutex_exit(sc->sc_bus->ub_lock); + cv_signal(&bus->ub_needsexplore_cv); + mutex_exit(bus->ub_lock); DPRINTF("sc %#jx exit", (uintptr_t)sc, 0, 0, 0); kthread_exit(0); @@ -997,25 +1009,28 @@ usbkqfilter(dev_t dev, struct knote *kn) Static void usb_discover(struct usb_softc *sc) { + struct usbd_bus *bus = sc->sc_bus; USBHIST_FUNC(); USBHIST_CALLED(usbdebug); - KASSERT(mutex_owned(sc->sc_bus->ub_lock)); + KASSERT(mutex_owned(bus->ub_lock)); if (usb_noexplore > 1) return; + /* * We need mutual exclusion while traversing the device tree, * but this is guaranteed since this function is only called * from the event thread for the controller. * - * Also, we now have sc_bus->ub_lock held. + * Also, we now have bus->ub_lock held, and in combination + * with ub_exploring, avoids interferring with polling. */ - while (sc->sc_bus->ub_needsexplore && !sc->sc_dying) { - sc->sc_bus->ub_needsexplore = 0; + while (bus->ub_needsexplore && !sc->sc_dying) { + bus->ub_needsexplore = 0; mutex_exit(sc->sc_bus->ub_lock); - sc->sc_bus->ub_roothub->ud_hub->uh_explore(sc->sc_bus->ub_roothub); - mutex_enter(sc->sc_bus->ub_lock); + bus->ub_roothub->ud_hub->uh_explore(bus->ub_roothub); + mutex_enter(bus->ub_lock); } } Index: dev/usb/usbdi.c =================================================================== RCS file: /cvsroot/src/sys/dev/usb/usbdi.c,v retrieving revision 1.177 diff -p -u -r1.177 usbdi.c --- dev/usb/usbdi.c 9 Aug 2018 06:26:47 -0000 1.177 +++ dev/usb/usbdi.c 16 Sep 2018 11:58:03 -0000 @@ -964,19 +964,19 @@ usb_transfer_complete(struct usbd_xfer * (uintptr_t)xfer, (uintptr_t)xfer->ux_callback, xfer->ux_status, 0); if (xfer->ux_callback) { - if (!polling) + if (!polling) { mutex_exit(pipe->up_dev->ud_bus->ub_lock); - - if (!(pipe->up_flags & USBD_MPSAFE)) - KERNEL_LOCK(1, curlwp); + if (!(pipe->up_flags & USBD_MPSAFE)) + KERNEL_LOCK(1, curlwp); + } xfer->ux_callback(xfer, xfer->ux_priv, xfer->ux_status); - if (!(pipe->up_flags & USBD_MPSAFE)) - KERNEL_UNLOCK_ONE(curlwp); - - if (!polling) + if (!polling) { + if (!(pipe->up_flags & USBD_MPSAFE)) + KERNEL_UNLOCK_ONE(curlwp); mutex_enter(pipe->up_dev->ud_bus->ub_lock); + } } if (sync && !polling) { @@ -1175,7 +1175,8 @@ usbd_dopoll(struct usbd_interface *iface } /* - * XXX use this more??? ub_usepolling it touched manually all over + * This is for keyboard driver as well, which only operates in polling + * mode from the ask root, etc., prompt and from DDB. */ void usbd_set_polling(struct usbd_device *dev, int on) Index: dev/usb/xhci.c =================================================================== RCS file: /cvsroot/src/sys/dev/usb/xhci.c,v retrieving revision 1.98 diff -p -u -r1.98 xhci.c --- dev/usb/xhci.c 3 Sep 2018 16:29:34 -0000 1.98 +++ dev/usb/xhci.c 16 Sep 2018 11:58:03 -0000 @@ -3705,15 +3705,18 @@ xhci_root_intr_start(struct usbd_xfer *x { struct xhci_softc * const sc = XHCI_XFER2SC(xfer); const size_t bn = XHCI_XFER2BUS(xfer) == &sc->sc_bus ? 0 : 1; + const bool polling = sc->sc_bus.ub_usepolling; XHCIHIST_FUNC(); XHCIHIST_CALLED(); if (sc->sc_dying) return USBD_IOERROR; - mutex_enter(&sc->sc_lock); + if (!polling) + mutex_enter(&sc->sc_lock); sc->sc_intrxfer[bn] = xfer; - mutex_exit(&sc->sc_lock); + if (!polling) + mutex_exit(&sc->sc_lock); return USBD_IN_PROGRESS; } @@ -3791,6 +3794,7 @@ xhci_device_ctrl_start(struct usbd_xfer uint32_t status; uint32_t control; u_int i; + const bool polling = sc->sc_bus.ub_usepolling; XHCIHIST_FUNC(); XHCIHIST_CALLED(); DPRINTFN(12, "req: %04jx %04jx %04jx %04jx", @@ -3837,9 +3841,11 @@ xhci_device_ctrl_start(struct usbd_xfer xhci_trb_put(&xx->xx_trb[i++], parameter, status, control); xfer->ux_status = USBD_IN_PROGRESS; - mutex_enter(&tr->xr_lock); + if (!polling) + mutex_enter(&tr->xr_lock); xhci_ring_put(sc, tr, xfer, xx->xx_trb, i); - mutex_exit(&tr->xr_lock); + if (!polling) + mutex_exit(&tr->xr_lock); xhci_db_write_4(sc, XHCI_DOORBELL(xs->xs_idx), dci); @@ -3922,6 +3928,7 @@ xhci_device_bulk_start(struct usbd_xfer uint32_t status; uint32_t control; u_int i = 0; + const bool polling = sc->sc_bus.ub_usepolling; XHCIHIST_FUNC(); XHCIHIST_CALLED(); @@ -3955,9 +3962,11 @@ xhci_device_bulk_start(struct usbd_xfer xhci_trb_put(&xx->xx_trb[i++], parameter, status, control); xfer->ux_status = USBD_IN_PROGRESS; - mutex_enter(&tr->xr_lock); + if (!polling) + mutex_enter(&tr->xr_lock); xhci_ring_put(sc, tr, xfer, xx->xx_trb, i); - mutex_exit(&tr->xr_lock); + if (!polling) + mutex_exit(&tr->xr_lock); xhci_db_write_4(sc, XHCI_DOORBELL(xs->xs_idx), dci);