Index: share/man/man4/usb.4 =================================================================== RCS file: /cvsroot/src/share/man/man4/usb.4,v retrieving revision 1.105 diff -p -u -r1.105 usb.4 --- share/man/man4/usb.4 21 Jan 2017 20:30:29 -0000 1.105 +++ share/man/man4/usb.4 25 Sep 2018 03:19:52 -0000 @@ -43,10 +43,10 @@ .Cd "slhci* at pcmcia? function ?" .Cd "uhci* at cardbus? function ?" .Cd "uhci* at pci? dev ? function ?" -.Cd "usb* at ehci? flags X" -.Cd "usb* at ohci? flags X" -.Cd "usb* at uhci? flags X" -.Cd "usb* at slhci? flags X" +.Cd "usb* at ehci?" +.Cd "usb* at ohci?" +.Cd "usb* at uhci?" +.Cd "usb* at slhci?" .Cd "uhub* at usb?" .Cd "uhub* at uhub? port ? configuration ? interface ? vendor ? product ? release ?" .Cd "XX* at uhub? port ? configuration ? interface ? vendor ? product ? release ?" @@ -92,26 +92,6 @@ hubs and must always be present since th .Tn USB system. .Pp -The -.Va flags -argument to the -.Va usb -device affects the order in which the device detection happens -during cold boot. -Normally, only the USB host controller and the -.Va usb -device are detected during the autoconfiguration when the -machine is booted. -The rest of the devices are detected once -the system becomes functional and the kernel thread for the -.Va usb -device is started. -Sometimes it is desirable to have a device detected early in the -boot process, e.g., the console keyboard. -To achieve this use a -.Va flags -value of 1. -.Pp .Nx supports the following machine-independent .Tn USB Index: sys/ddb/db_command.c =================================================================== RCS file: /cvsroot/src/sys/ddb/db_command.c,v retrieving revision 1.148.8.4 diff -p -u -r1.148.8.4 db_command.c --- sys/ddb/db_command.c 23 Sep 2018 17:28:25 -0000 1.148.8.4 +++ sys/ddb/db_command.c 25 Sep 2018 03:19:52 -0000 @@ -90,10 +90,10 @@ __KERNEL_RCSID(0, "$NetBSD: db_command.c #include #include #include - -/*include queue macros*/ #include +#include + #include #include @@ -541,7 +541,14 @@ db_unregister_tbl(uint8_t type,const str return ENOENT; } -/* This function is called from machine trap code. */ +#ifndef _KERNEL +#define cnpollc(c) __nothing +#endif + +/* + * This function is called via db_trap() or directly from + * machine trap code. + */ void db_command_loop(void) { @@ -578,7 +585,9 @@ db_command_loop(void) if (db_print_position() != 0) db_printf("\n"); db_output_line = 0; + cnpollc(1); (void) db_read_line(); + cnpollc(0); db_command(&db_last_command); } Index: sys/ddb/db_output.c =================================================================== RCS file: /cvsroot/src/sys/ddb/db_output.c,v retrieving revision 1.33 diff -p -u -r1.33 db_output.c --- sys/ddb/db_output.c 1 Sep 2012 01:13:51 -0000 1.33 +++ sys/ddb/db_output.c 25 Sep 2018 03:19:52 -0000 @@ -111,7 +111,7 @@ db_more(void) for (p = "--db_more--"; *p; p++) cnputc(*p); - switch(cngetc()) { + switch (cngetc()) { case ' ': db_output_line = 0; break; Index: sys/dev/pci/xhci_pci.c =================================================================== RCS file: /cvsroot/src/sys/dev/pci/xhci_pci.c,v retrieving revision 1.8 diff -p -u -r1.8 xhci_pci.c --- sys/dev/pci/xhci_pci.c 19 Jan 2017 16:05:00 -0000 1.8 +++ sys/dev/pci/xhci_pci.c 25 Sep 2018 03:19:52 -0000 @@ -138,6 +138,7 @@ xhci_pci_attach(device_t parent, device_ printf("%s: csr: %08x\n", __func__, csr); #endif if ((csr & PCI_COMMAND_MEM_ENABLE) == 0) { + sc->sc_ios = 0; aprint_error_dev(self, "memory access is disabled\n"); return; } @@ -155,6 +156,7 @@ xhci_pci_attach(device_t parent, device_ } break; default: + sc->sc_ios = 0; aprint_error_dev(self, "BAR not 64 or 32-bit MMIO\n"); return; } Index: sys/dev/usb/ehci.c =================================================================== RCS file: /cvsroot/src/sys/dev/usb/ehci.c,v retrieving revision 1.254.8.4 diff -p -u -r1.254.8.4 ehci.c --- sys/dev/usb/ehci.c 25 Aug 2018 11:29:52 -0000 1.254.8.4 +++ sys/dev/usb/ehci.c 25 Sep 2018 03:19:52 -0000 @@ -2650,13 +2650,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; } @@ -3551,6 +3554,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(); @@ -3670,7 +3674,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); @@ -3680,7 +3685,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 @@ -3827,6 +3833,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(); @@ -3850,7 +3857,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); @@ -3877,7 +3885,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 @@ -4042,6 +4051,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(); @@ -4065,7 +4075,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); @@ -4092,7 +4103,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: sys/dev/usb/ohci.c =================================================================== RCS file: /cvsroot/src/sys/dev/usb/ohci.c,v retrieving revision 1.273.6.3 diff -p -u -r1.273.6.3 ohci.c --- sys/dev/usb/ohci.c 25 Aug 2018 11:29:52 -0000 1.273.6.3 +++ sys/dev/usb/ohci.c 25 Sep 2018 03:19:52 -0000 @@ -2607,14 +2607,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; } @@ -2750,6 +2753,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(); @@ -2768,7 +2772,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 @@ -2884,7 +2889,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); } @@ -2892,7 +2897,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; } @@ -3019,6 +3025,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(); @@ -3036,7 +3043,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 @@ -3102,7 +3110,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; } @@ -3221,6 +3230,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(); @@ -3236,7 +3246,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 @@ -3288,7 +3299,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: sys/dev/usb/uhci.c =================================================================== RCS file: /cvsroot/src/sys/dev/usb/uhci.c,v retrieving revision 1.275.2.4 diff -p -u -r1.275.2.4 uhci.c --- sys/dev/usb/uhci.c 25 Aug 2018 11:29:52 -0000 1.275.2.4 +++ sys/dev/usb/uhci.c 25 Sep 2018 03:19:52 -0000 @@ -2256,6 +2256,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; @@ -2276,7 +2277,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); @@ -2310,12 +2312,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; } @@ -2540,6 +2543,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; @@ -2567,7 +2571,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) { @@ -2664,12 +2669,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; } @@ -2742,6 +2748,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; @@ -2767,7 +2774,8 @@ uhci_device_intr_start(struct usbd_xfer #endif /* Take lock to protect nexttoggle */ - mutex_enter(&sc->sc_lock); + if (!polling) + mutex_enter(&sc->sc_lock); uhci_reset_std_chain(sc, xfer, xfer->ux_length, isread, &upipe->nexttoggle, &dataend); @@ -2799,7 +2807,8 @@ uhci_device_intr_start(struct usbd_xfer } uhci_add_intr_list(sc, ux); xfer->ux_status = USBD_IN_PROGRESS; - mutex_exit(&sc->sc_lock); + if (!polling) + mutex_exit(&sc->sc_lock); #ifdef UHCI_DEBUG if (uhcidebug >= 10) { Index: sys/dev/usb/uhcivar.h =================================================================== RCS file: /cvsroot/src/sys/dev/usb/uhcivar.h,v retrieving revision 1.53.10.1 diff -p -u -r1.53.10.1 uhcivar.h --- sys/dev/usb/uhcivar.h 25 Aug 2018 11:29:52 -0000 1.53.10.1 +++ sys/dev/usb/uhcivar.h 25 Sep 2018 03:19:52 -0000 @@ -170,8 +170,8 @@ typedef struct uhci_softc { pool_cache_t sc_xferpool; /* free xfer pool */ - uint8_t sc_saved_sof; uint16_t sc_saved_frnum; + uint8_t sc_saved_sof; char sc_isreset; char sc_suspend; Index: sys/dev/usb/uhub.c =================================================================== RCS file: /cvsroot/src/sys/dev/usb/uhub.c,v retrieving revision 1.136.2.1 diff -p -u -r1.136.2.1 uhub.c --- sys/dev/usb/uhub.c 2 Nov 2017 21:29:52 -0000 1.136.2.1 +++ sys/dev/usb/uhub.c 25 Sep 2018 03:19:52 -0000 @@ -113,9 +113,9 @@ struct uhub_softc { uint8_t *sc_statuspend; uint8_t *sc_status; size_t sc_statuslen; - int sc_explorepending; - - u_char sc_running; + bool sc_explorepending; + bool sc_first_explore; + bool sc_running; }; #define UHUB_IS_HIGH_SPEED(sc) \ @@ -262,6 +262,8 @@ uhub_attach(device_t parent, device_t se usb_endpoint_descriptor_t *ed; struct usbd_tt *tts = NULL; + config_pending_incr(self); + UHUBHIST_FUNC(); UHUBHIST_CALLED(); sc->sc_dev = self; @@ -283,14 +285,14 @@ uhub_attach(device_t parent, device_t se if (err) { DPRINTF("configuration failed, sc %#jx error %jd", (uintptr_t)sc, err, 0, 0); - return; + goto bad2; } if (dev->ud_depth > USB_HUB_MAX_DEPTH) { aprint_error_dev(self, "hub depth (%d) exceeded, hub ignored\n", USB_HUB_MAX_DEPTH); - return; + goto bad2; } /* Get hub descriptor. */ @@ -300,7 +302,7 @@ uhub_attach(device_t parent, device_t se if (err) { DPRINTF("getting hub descriptor failed, uhub%jd error %jd", device_unit(self), err, 0, 0); - return; + goto bad2; } for (nremov = 0, port = 1; port <= nports; port++) @@ -364,7 +366,7 @@ uhub_attach(device_t parent, device_t se /* force initial scan */ memset(sc->sc_status, 0xff, sc->sc_statuslen); - sc->sc_explorepending = 1; + sc->sc_explorepending = true; err = usbd_open_pipe_intr(iface, ed->bEndpointAddress, USBD_SHORT_XFER_OK|USBD_MPSAFE, &sc->sc_ipipe, sc, @@ -449,8 +451,8 @@ uhub_attach(device_t parent, device_t se usbd_delay_ms(dev, pwrdly); /* The usual exploration will finish the setup. */ - - sc->sc_running = 1; + sc->sc_running = true; + sc->sc_first_explore = true; if (!pmf_device_register(self, NULL, NULL)) aprint_error_dev(self, "couldn't establish power handler\n"); @@ -468,7 +470,8 @@ uhub_attach(device_t parent, device_t se kmem_free(hub, sizeof(*hub) + (nports-1) * sizeof(struct usbd_port)); dev->ud_hub = NULL; - return; + bad2: + config_pending_decr(self); } usbd_status @@ -777,7 +780,7 @@ uhub_explore(struct usbd_device *dev) } } mutex_enter(&sc->sc_lock); - sc->sc_explorepending = 0; + sc->sc_explorepending = false; for (int i = 0; i < sc->sc_statuslen; i++) { if (sc->sc_statuspend[i] != 0) { memcpy(sc->sc_status, sc->sc_statuspend, @@ -788,6 +791,10 @@ uhub_explore(struct usbd_device *dev) } } mutex_exit(&sc->sc_lock); + if (sc->sc_first_explore) { + config_pending_decr(sc->sc_dev); + sc->sc_first_explore = false; + } return USBD_NORMAL_COMPLETION; } @@ -942,7 +949,7 @@ uhub_intr(struct usbd_xfer *xfer, void * } if (!sc->sc_explorepending) { - sc->sc_explorepending = 1; + sc->sc_explorepending = true; memcpy(sc->sc_status, sc->sc_statuspend, sc->sc_statuslen); Index: sys/dev/usb/usb.c =================================================================== RCS file: /cvsroot/src/sys/dev/usb/usb.c,v retrieving revision 1.165.6.3 diff -p -u -r1.165.6.3 usb.c --- sys/dev/usb/usb.c 8 Aug 2018 10:28:35 -0000 1.165.6.3 +++ sys/dev/usb/usb.c 25 Sep 2018 03:19:52 -0000 @@ -138,6 +138,7 @@ struct usb_softc { struct lwp *sc_event_thread; char sc_dying; + bool sc_pmf_registered; }; struct usb_taskq { @@ -189,6 +190,7 @@ Static int usb_nevents = 0; Static struct selinfo usb_selevent; Static kmutex_t usb_event_lock; Static kcondvar_t usb_event_cv; +/* XXX this is gross and broken */ Static proc_t *usb_async_proc; /* process that wants USB SIGIO */ Static void *usb_async_sih; Static int usb_dev_open = 0; @@ -239,6 +241,9 @@ usb_attach(device_t parent, device_t sel sc->sc_bus = aux; usbrev = sc->sc_bus->ub_revision; + cv_init(&sc->sc_bus->ub_needsexplore_cv, "usbevt"); + sc->sc_pmf_registered = false; + aprint_naive("\n"); aprint_normal(": USB revision %s", usbrev_str[usbrev]); switch (usbrev) { @@ -306,6 +311,11 @@ usb_once_init(void) * end up using them in usb_doattach(). */ } + + KASSERT(usb_async_sih == NULL); + usb_async_sih = softint_establish(SOFTINT_CLOCK | SOFTINT_MPSAFE, + usb_async_intr, NULL); + return 0; } @@ -338,8 +348,6 @@ usb_doattach(device_t self) panic("usb_doattach"); } - cv_init(&sc->sc_bus->ub_needsexplore_cv, "usbevt"); - ue = usb_alloc_event(); ue->u.ue_ctrlr.ue_bus = device_unit(self); usb_add_event(USB_EVENT_CTRLR_ATTACH, ue); @@ -356,28 +364,22 @@ usb_doattach(device_t self) } sc->sc_bus->ub_roothub = dev; usb_create_event_thread(self); -#if 1 - /* - * Turning this code off will delay attachment of USB devices - * until the USB event thread is running, which means that - * the keyboard will not work until after cold boot. - */ - if (cold && (device_cfdata(self)->cf_flags & 1)) - dev->ud_hub->uh_explore(sc->sc_bus->ub_roothub); -#endif } else { aprint_error("%s: root hub problem, error=%s\n", device_xname(self), usbd_errstr(err)); 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)) aprint_error_dev(self, "couldn't establish power handler\n"); - - usb_async_sih = softint_establish(SOFTINT_CLOCK | SOFTINT_MPSAFE, - usb_async_intr, NULL); + else + sc->sc_pmf_registered = true; return; } @@ -525,6 +527,7 @@ void usb_event_thread(void *arg) { struct usb_softc *sc = arg; + struct usbd_bus *bus = sc->sc_bus; USBHIST_FUNC(); USBHIST_CALLED(usbdebug); @@ -536,30 +539,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); - mutex_enter(sc->sc_bus->ub_lock); + /* Drop the config_pending reference from attach. */ + config_pending_decr(bus->ub_usbctl); + + 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); @@ -989,25 +999,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); } } @@ -1156,6 +1169,10 @@ usb_schedsoftintr(struct usbd_bus *bus) DPRINTFN(10, "polling=%jd", bus->ub_usepolling, 0, 0, 0); + /* In case the bus never finished setting up. */ + if (__predict_false(bus->ub_soft == NULL)) + return; + if (bus->ub_usepolling) { bus->ub_methods->ubm_softint(bus); } else { @@ -1208,7 +1225,8 @@ usb_detach(device_t self, int flags) (rc = usb_disconnect_port(&sc->sc_port, self, flags)) != 0) return rc; - pmf_device_deregister(self); + if (sc->sc_pmf_registered) + pmf_device_deregister(self); /* Kill off event thread. */ sc->sc_dying = 1; while (sc->sc_event_thread != NULL) { Index: sys/dev/usb/usb_subr.c =================================================================== RCS file: /cvsroot/src/sys/dev/usb/usb_subr.c,v retrieving revision 1.220.2.4 diff -p -u -r1.220.2.4 usb_subr.c --- sys/dev/usb/usb_subr.c 26 Aug 2018 08:05:16 -0000 1.220.2.4 +++ sys/dev/usb/usb_subr.c 25 Sep 2018 03:19:52 -0000 @@ -907,6 +907,7 @@ usbd_attachwholedevice(device_t parent, dlocs[USBDEVIFCF_INTERFACE] = -1; KERNEL_LOCK(1, curlwp); + config_pending_incr(parent); dv = config_found_sm_loc(parent, "usbdevif", dlocs, &uaa, usbd_print, config_stdsubmatch); KERNEL_UNLOCK_ONE(curlwp); @@ -917,6 +918,7 @@ usbd_attachwholedevice(device_t parent, dev->ud_nifaces_claimed = 1; /* XXX */ usbd_serialnumber(dv, dev); } + config_pending_decr(parent); return USBD_NORMAL_COMPLETION; } Index: sys/dev/usb/usbdi.c =================================================================== RCS file: /cvsroot/src/sys/dev/usb/usbdi.c,v retrieving revision 1.173.2.2 diff -p -u -r1.173.2.2 usbdi.c --- sys/dev/usb/usbdi.c 25 Aug 2018 11:29:52 -0000 1.173.2.2 +++ sys/dev/usb/usbdi.c 25 Sep 2018 03:19:52 -0000 @@ -963,19 +963,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) { @@ -1143,7 +1143,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: sys/dev/usb/xhci.c =================================================================== RCS file: /cvsroot/src/sys/dev/usb/xhci.c,v retrieving revision 1.72.2.7 diff -p -u -r1.72.2.7 xhci.c --- sys/dev/usb/xhci.c 25 Aug 2018 11:29:52 -0000 1.72.2.7 +++ sys/dev/usb/xhci.c 25 Sep 2018 03:19:52 -0000 @@ -3711,15 +3711,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; } @@ -3800,6 +3803,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", @@ -3846,9 +3850,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); @@ -3931,6 +3937,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(); @@ -3964,9 +3971,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); Index: sys/external/bsd/dwc2/dwc2.c =================================================================== RCS file: /cvsroot/src/sys/external/bsd/dwc2/dwc2.c,v retrieving revision 1.46.2.2 diff -p -u -r1.46.2.2 dwc2.c --- sys/external/bsd/dwc2/dwc2.c 25 Aug 2018 11:29:52 -0000 1.46.2.2 +++ sys/external/bsd/dwc2/dwc2.c 25 Sep 2018 03:19:53 -0000 @@ -630,16 +630,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; } @@ -709,13 +712,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; @@ -829,11 +835,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: sys/kern/subr_userconf.c =================================================================== RCS file: /cvsroot/src/sys/kern/subr_userconf.c,v retrieving revision 1.26 diff -p -u -r1.26 subr_userconf.c --- sys/kern/subr_userconf.c 23 Dec 2013 15:34:16 -0000 1.26 +++ sys/kern/subr_userconf.c 25 Sep 2018 03:19:53 -0000 @@ -103,7 +103,9 @@ userconf_more(void) if (userconf_cnt != -1) { if (userconf_cnt == userconf_lines) { printf("-- more --"); + cnpollc(1); c = cngetc(); + cnpollc(0); userconf_cnt = 0; printf("\r \r"); } @@ -391,7 +393,9 @@ userconf_change(int devno) while (c != 'y' && c != 'Y' && c != 'n' && c != 'N') { printf("change (y/n) ?"); + cnpollc(1); c = cngetc(); + cnpollc(0); printf("\n"); }