Module Name: src Committed By: martin Date: Thu Sep 27 14:52:27 UTC 2018
Modified Files: src/share/man/man4 [netbsd-8]: usb.4 src/sys/ddb [netbsd-8]: db_command.c db_output.c src/sys/dev/pci [netbsd-8]: xhci_pci.c src/sys/dev/usb [netbsd-8]: ehci.c ohci.c uhci.c uhcivar.h uhub.c usb.c usb_subr.c usbdi.c xhci.c src/sys/external/bsd/dwc2 [netbsd-8]: dwc2.c src/sys/kern [netbsd-8]: subr_userconf.c Log Message: Pull up following revision(s) (requested by mrg in ticket #1037): sys/dev/usb/uhub.c: revision 1.139 sys/external/bsd/dwc2/dwc2.c: revision 1.55 sys/ddb/db_output.c: revision 1.34 sys/ddb/db_command.c: revision 1.160 sys/dev/usb/ehci.c: revision 1.264 sys/dev/usb/xhci.c: revision 1.99 sys/dev/usb/ehci.c: revision 1.265 sys/kern/subr_userconf.c: revision 1.27 sys/dev/usb/ehcivar.h: revision 1.46 sys/dev/usb/ohci.c: revision 1.287 sys/dev/usb/uhci.c: revision 1.284 sys/dev/usb/usbdi.c: revision 1.178 sys/dev/usb/usb.c: revision 1.172 sys/dev/pci/xhci_pci.c: revision 1.14 sys/dev/usb/usb.c: revision 1.173 sys/dev/usb/usb.c: revision 1.174 share/man/man4/usb.4: revision 1.110 sys/ddb/db_command.c: revision 1.159 sys/dev/usb/usb_subr.c: revision 1.227 sys/dev/usb/uhcivar.h: revision 1.56 (all via patch) consolidate the handling of polling across HC drivers, and generic USB: - don't take mutexes if polling - normalise the code across all drivers - add some not yet code to block discovery to/from polling - minor CSE - adjust comment for usbd_set_polling() to reality now i properly understand what it is used for and why. this, with a hack to make RB_ASKNAME to wait 5 seconds allows boot -a work with USB keyboards. there are still multiple issues remaining: - discovery and polling need to be mutually exclusive - attachment of ukbd and wskbd is not handled by config_pending, and the 5 second delay isn't going to always be enough. call cnpollc(1) and cnpollc(0) around cngetc(). (christos has a good idea to add a function that does all 3, and we should switch all the callers in this sequence to use it (and fix the MD ones missing it still). not all can, as eg, line-grabbing functions can use cngetsn(), which only calls cnpollc() twice.) When this file is used when not building the kernel (eg: /usr/sbin/crash) make cnpollc() go away. reorder some struct members to remove holes. add config_pending usage to uhub and general USB device attachment. - call config_pending_incr() and config_pending_decr() around attaching devices against "usbdevif" attribute. uhub: - convert sc_explorepending and sc_running to bool. add new sc_first_explore. - call config_pending_incr() at the start of uhub_attach(). dropped in uhub_explore(), if this is the first explore. implement a gross hack to fix "boot -a" on systems with usb keyboards on systems with ehci handover to uhci (and maybe ohci), and fix a similar problem for "boot -s". there is effort to ensure that all devices attached via USB are probed before RB_ASKNAME or RB_SINGLE attempts to ask any questions on the console, and largely this works, often by chance, today, for USB disks and root. i've recently pushed this more into uhub and general USB device attachment as well, and kept a config_pending reference across the first explore of a bus. these fix many issues with directly attached hubs. however, on systems where devices connected to ehci ports are handed over to a companion uhci or ohci port, it may not be the first, or even second, bus explore that finds the device finally before attachment, and at this point all config_pending references are dropped. there is no direct communication between drivers, the potentials are looked up but their device_t is only used for generic things like the name, so informing the correct companion to expect a device and deal with the config_pending references is not possible without some fairly ugly layer violations or multi-level callbacks (eg, we have "ehci0", and usually an the relevant companion, eg, "uhci2", but it is the uhub that uhci2 has attached that will deal with the device attachment.) with the above fixes to generic USB code, the disown happens during the first explore. the hack works by, at this point, checking if (a) root is not mounted, (b) single user or ask name are set, and (c) if the hack as not been triggered already. if all 3 conditions are true, then a config_pending_incr() is called and a callback is triggered for (default) 5 seconds to call config_pending_decr(). ehci detach pauses waiting for this callback if scheduled. this allows enough time for the uhub and the ukbd/wskbd to attach before the RK_ASKROOT prompts appear. testing shows it takes between 1.5 and 2 seconds for the keyboard to appear after the disown occurs. Index: dev/usb/ehcivar.c - new sc_compcallout, sc_compcallout, sc_complock, and a state for th handover hack. Index: dev/usb/ehci.c ehci_init(): - use aprint_normal_dev() instead of manual device_xname(). - initialise sc_compcallout, sc_compcallout, sc_complock, and sc_comp_state. ehci_detach(): - if there are companion controllers, tear own the above, including waiting if there is a callback scheduled. ehci_disown_callback(): - new callout to call config_pending_decr() in the the future. schedule this ca ehci_disown_sched_callback(): - if booting to single user or asking names, call config_pending_incr() and schedule the callout above, default 5 second delay. ehci_disown(): - if disowning a port call ehci_disown_sched_callback(). deal with partial attach failures in usb_attach vs usb_detach aka PR 53598. - make sure xhci's sc->sc_ios is NULL if failure happens. - rearrange usb_attach() / usb_doattach() to make it simpler to clean up. - move usb_async_intr softint into usb_once_init(). previously, each USB controller would start a new one, and leave the old one leaked. - handle controller interrupts without a bus attached remove usb(4)'s "flags 1" code. it has been dead for a while, as it runs during the interrupts part of configuration now, and all the devices try attach as early as possible, including any root or boot required disk or keyboard device, which is what this flag was for. To generate a diff of this commit: cvs rdiff -u -r1.105 -r1.105.4.1 src/share/man/man4/usb.4 cvs rdiff -u -r1.148.8.4 -r1.148.8.5 src/sys/ddb/db_command.c cvs rdiff -u -r1.33 -r1.33.32.1 src/sys/ddb/db_output.c cvs rdiff -u -r1.8 -r1.8.6.1 src/sys/dev/pci/xhci_pci.c cvs rdiff -u -r1.254.8.4 -r1.254.8.5 src/sys/dev/usb/ehci.c cvs rdiff -u -r1.273.6.3 -r1.273.6.4 src/sys/dev/usb/ohci.c cvs rdiff -u -r1.275.2.4 -r1.275.2.5 src/sys/dev/usb/uhci.c cvs rdiff -u -r1.53.10.1 -r1.53.10.2 src/sys/dev/usb/uhcivar.h cvs rdiff -u -r1.136.2.1 -r1.136.2.2 src/sys/dev/usb/uhub.c cvs rdiff -u -r1.165.6.3 -r1.165.6.4 src/sys/dev/usb/usb.c cvs rdiff -u -r1.220.2.4 -r1.220.2.5 src/sys/dev/usb/usb_subr.c cvs rdiff -u -r1.173.2.2 -r1.173.2.3 src/sys/dev/usb/usbdi.c cvs rdiff -u -r1.72.2.7 -r1.72.2.8 src/sys/dev/usb/xhci.c cvs rdiff -u -r1.46.2.2 -r1.46.2.3 src/sys/external/bsd/dwc2/dwc2.c cvs rdiff -u -r1.26 -r1.26.22.1 src/sys/kern/subr_userconf.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/share/man/man4/usb.4 diff -u src/share/man/man4/usb.4:1.105 src/share/man/man4/usb.4:1.105.4.1 --- src/share/man/man4/usb.4:1.105 Sat Jan 21 20:30:29 2017 +++ src/share/man/man4/usb.4 Thu Sep 27 14:52:27 2018 @@ -1,4 +1,4 @@ -.\" $NetBSD: usb.4,v 1.105 2017/01/21 20:30:29 jdolecek Exp $ +.\" $NetBSD: usb.4,v 1.105.4.1 2018/09/27 14:52:27 martin Exp $ .\" .\" Copyright (c) 1999-2014 The NetBSD Foundation, Inc. .\" All rights reserved. @@ -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: src/sys/ddb/db_command.c diff -u src/sys/ddb/db_command.c:1.148.8.4 src/sys/ddb/db_command.c:1.148.8.5 --- src/sys/ddb/db_command.c:1.148.8.4 Sun Sep 23 17:28:25 2018 +++ src/sys/ddb/db_command.c Thu Sep 27 14:52:26 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: db_command.c,v 1.148.8.4 2018/09/23 17:28:25 martin Exp $ */ +/* $NetBSD: db_command.c,v 1.148.8.5 2018/09/27 14:52:26 martin Exp $ */ /* * Copyright (c) 1996, 1997, 1998, 1999, 2002, 2009 The NetBSD Foundation, Inc. @@ -60,7 +60,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: db_command.c,v 1.148.8.4 2018/09/23 17:28:25 martin Exp $"); +__KERNEL_RCSID(0, "$NetBSD: db_command.c,v 1.148.8.5 2018/09/27 14:52:26 martin Exp $"); #ifdef _KERNEL_OPT #include "opt_aio.h" @@ -90,10 +90,10 @@ __KERNEL_RCSID(0, "$NetBSD: db_command.c #include <sys/module.h> #include <sys/kernhist.h> #include <sys/socketvar.h> - -/*include queue macros*/ #include <sys/queue.h> +#include <dev/cons.h> + #include <ddb/ddb.h> #include <uvm/uvm_extern.h> @@ -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: src/sys/ddb/db_output.c diff -u src/sys/ddb/db_output.c:1.33 src/sys/ddb/db_output.c:1.33.32.1 --- src/sys/ddb/db_output.c:1.33 Sat Sep 1 01:13:51 2012 +++ src/sys/ddb/db_output.c Thu Sep 27 14:52:26 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: db_output.c,v 1.33 2012/09/01 01:13:51 matt Exp $ */ +/* $NetBSD: db_output.c,v 1.33.32.1 2018/09/27 14:52:26 martin Exp $ */ /* * Mach Operating System @@ -35,7 +35,7 @@ #endif #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: db_output.c,v 1.33 2012/09/01 01:13:51 matt Exp $"); +__KERNEL_RCSID(0, "$NetBSD: db_output.c,v 1.33.32.1 2018/09/27 14:52:26 martin Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -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: src/sys/dev/pci/xhci_pci.c diff -u src/sys/dev/pci/xhci_pci.c:1.8 src/sys/dev/pci/xhci_pci.c:1.8.6.1 --- src/sys/dev/pci/xhci_pci.c:1.8 Thu Jan 19 16:05:00 2017 +++ src/sys/dev/pci/xhci_pci.c Thu Sep 27 14:52:27 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: xhci_pci.c,v 1.8 2017/01/19 16:05:00 skrll Exp $ */ +/* $NetBSD: xhci_pci.c,v 1.8.6.1 2018/09/27 14:52:27 martin Exp $ */ /* OpenBSD: xhci_pci.c,v 1.4 2014/07/12 17:38:51 yuo Exp */ /* @@ -32,7 +32,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: xhci_pci.c,v 1.8 2017/01/19 16:05:00 skrll Exp $"); +__KERNEL_RCSID(0, "$NetBSD: xhci_pci.c,v 1.8.6.1 2018/09/27 14:52:27 martin Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -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: src/sys/dev/usb/ehci.c diff -u src/sys/dev/usb/ehci.c:1.254.8.4 src/sys/dev/usb/ehci.c:1.254.8.5 --- src/sys/dev/usb/ehci.c:1.254.8.4 Sat Aug 25 11:29:52 2018 +++ src/sys/dev/usb/ehci.c Thu Sep 27 14:52:26 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: ehci.c,v 1.254.8.4 2018/08/25 11:29:52 martin Exp $ */ +/* $NetBSD: ehci.c,v 1.254.8.5 2018/09/27 14:52:26 martin Exp $ */ /* * Copyright (c) 2004-2012 The NetBSD Foundation, Inc. @@ -53,7 +53,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: ehci.c,v 1.254.8.4 2018/08/25 11:29:52 martin Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ehci.c,v 1.254.8.5 2018/09/27 14:52:26 martin Exp $"); #include "ohci.h" #include "uhci.h" @@ -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: src/sys/dev/usb/ohci.c diff -u src/sys/dev/usb/ohci.c:1.273.6.3 src/sys/dev/usb/ohci.c:1.273.6.4 --- src/sys/dev/usb/ohci.c:1.273.6.3 Sat Aug 25 11:29:52 2018 +++ src/sys/dev/usb/ohci.c Thu Sep 27 14:52:26 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: ohci.c,v 1.273.6.3 2018/08/25 11:29:52 martin Exp $ */ +/* $NetBSD: ohci.c,v 1.273.6.4 2018/09/27 14:52:26 martin Exp $ */ /* * Copyright (c) 1998, 2004, 2005, 2012 The NetBSD Foundation, Inc. @@ -41,7 +41,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: ohci.c,v 1.273.6.3 2018/08/25 11:29:52 martin Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ohci.c,v 1.273.6.4 2018/09/27 14:52:26 martin Exp $"); #ifdef _KERNEL_OPT #include "opt_usb.h" @@ -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: src/sys/dev/usb/uhci.c diff -u src/sys/dev/usb/uhci.c:1.275.2.4 src/sys/dev/usb/uhci.c:1.275.2.5 --- src/sys/dev/usb/uhci.c:1.275.2.4 Sat Aug 25 11:29:52 2018 +++ src/sys/dev/usb/uhci.c Thu Sep 27 14:52:26 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: uhci.c,v 1.275.2.4 2018/08/25 11:29:52 martin Exp $ */ +/* $NetBSD: uhci.c,v 1.275.2.5 2018/09/27 14:52:26 martin Exp $ */ /* * Copyright (c) 1998, 2004, 2011, 2012 The NetBSD Foundation, Inc. @@ -42,7 +42,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: uhci.c,v 1.275.2.4 2018/08/25 11:29:52 martin Exp $"); +__KERNEL_RCSID(0, "$NetBSD: uhci.c,v 1.275.2.5 2018/09/27 14:52:26 martin Exp $"); #ifdef _KERNEL_OPT #include "opt_usb.h" @@ -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: src/sys/dev/usb/uhcivar.h diff -u src/sys/dev/usb/uhcivar.h:1.53.10.1 src/sys/dev/usb/uhcivar.h:1.53.10.2 --- src/sys/dev/usb/uhcivar.h:1.53.10.1 Sat Aug 25 11:29:52 2018 +++ src/sys/dev/usb/uhcivar.h Thu Sep 27 14:52:26 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: uhcivar.h,v 1.53.10.1 2018/08/25 11:29:52 martin Exp $ */ +/* $NetBSD: uhcivar.h,v 1.53.10.2 2018/09/27 14:52:26 martin Exp $ */ /* * Copyright (c) 1998 The NetBSD Foundation, Inc. @@ -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: src/sys/dev/usb/uhub.c diff -u src/sys/dev/usb/uhub.c:1.136.2.1 src/sys/dev/usb/uhub.c:1.136.2.2 --- src/sys/dev/usb/uhub.c:1.136.2.1 Thu Nov 2 21:29:52 2017 +++ src/sys/dev/usb/uhub.c Thu Sep 27 14:52:26 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: uhub.c,v 1.136.2.1 2017/11/02 21:29:52 snj Exp $ */ +/* $NetBSD: uhub.c,v 1.136.2.2 2018/09/27 14:52:26 martin Exp $ */ /* $FreeBSD: src/sys/dev/usb/uhub.c,v 1.18 1999/11/17 22:33:43 n_hibma Exp $ */ /* $OpenBSD: uhub.c,v 1.86 2015/06/29 18:27:40 mpi Exp $ */ @@ -37,7 +37,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: uhub.c,v 1.136.2.1 2017/11/02 21:29:52 snj Exp $"); +__KERNEL_RCSID(0, "$NetBSD: uhub.c,v 1.136.2.2 2018/09/27 14:52:26 martin Exp $"); #ifdef _KERNEL_OPT #include "opt_usb.h" @@ -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: src/sys/dev/usb/usb.c diff -u src/sys/dev/usb/usb.c:1.165.6.3 src/sys/dev/usb/usb.c:1.165.6.4 --- src/sys/dev/usb/usb.c:1.165.6.3 Wed Aug 8 10:28:35 2018 +++ src/sys/dev/usb/usb.c Thu Sep 27 14:52:26 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: usb.c,v 1.165.6.3 2018/08/08 10:28:35 martin Exp $ */ +/* $NetBSD: usb.c,v 1.165.6.4 2018/09/27 14:52:26 martin Exp $ */ /* * Copyright (c) 1998, 2002, 2008, 2012 The NetBSD Foundation, Inc. @@ -37,7 +37,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: usb.c,v 1.165.6.3 2018/08/08 10:28:35 martin Exp $"); +__KERNEL_RCSID(0, "$NetBSD: usb.c,v 1.165.6.4 2018/09/27 14:52:26 martin Exp $"); #ifdef _KERNEL_OPT #include "opt_usb.h" @@ -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: src/sys/dev/usb/usb_subr.c diff -u src/sys/dev/usb/usb_subr.c:1.220.2.4 src/sys/dev/usb/usb_subr.c:1.220.2.5 --- src/sys/dev/usb/usb_subr.c:1.220.2.4 Sun Aug 26 08:05:16 2018 +++ src/sys/dev/usb/usb_subr.c Thu Sep 27 14:52:26 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: usb_subr.c,v 1.220.2.4 2018/08/26 08:05:16 martin Exp $ */ +/* $NetBSD: usb_subr.c,v 1.220.2.5 2018/09/27 14:52:26 martin Exp $ */ /* $FreeBSD: src/sys/dev/usb/usb_subr.c,v 1.18 1999/11/17 22:33:47 n_hibma Exp $ */ /* @@ -32,7 +32,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: usb_subr.c,v 1.220.2.4 2018/08/26 08:05:16 martin Exp $"); +__KERNEL_RCSID(0, "$NetBSD: usb_subr.c,v 1.220.2.5 2018/09/27 14:52:26 martin Exp $"); #ifdef _KERNEL_OPT #include "opt_compat_netbsd.h" @@ -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: src/sys/dev/usb/usbdi.c diff -u src/sys/dev/usb/usbdi.c:1.173.2.2 src/sys/dev/usb/usbdi.c:1.173.2.3 --- src/sys/dev/usb/usbdi.c:1.173.2.2 Sat Aug 25 11:29:52 2018 +++ src/sys/dev/usb/usbdi.c Thu Sep 27 14:52:26 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: usbdi.c,v 1.173.2.2 2018/08/25 11:29:52 martin Exp $ */ +/* $NetBSD: usbdi.c,v 1.173.2.3 2018/09/27 14:52:26 martin Exp $ */ /* * Copyright (c) 1998, 2012, 2015 The NetBSD Foundation, Inc. @@ -32,7 +32,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: usbdi.c,v 1.173.2.2 2018/08/25 11:29:52 martin Exp $"); +__KERNEL_RCSID(0, "$NetBSD: usbdi.c,v 1.173.2.3 2018/09/27 14:52:26 martin Exp $"); #ifdef _KERNEL_OPT #include "opt_usb.h" @@ -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: src/sys/dev/usb/xhci.c diff -u src/sys/dev/usb/xhci.c:1.72.2.7 src/sys/dev/usb/xhci.c:1.72.2.8 --- src/sys/dev/usb/xhci.c:1.72.2.7 Sat Aug 25 11:29:52 2018 +++ src/sys/dev/usb/xhci.c Thu Sep 27 14:52:26 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: xhci.c,v 1.72.2.7 2018/08/25 11:29:52 martin Exp $ */ +/* $NetBSD: xhci.c,v 1.72.2.8 2018/09/27 14:52:26 martin Exp $ */ /* * Copyright (c) 2013 Jonathan A. Kollasch @@ -34,7 +34,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: xhci.c,v 1.72.2.7 2018/08/25 11:29:52 martin Exp $"); +__KERNEL_RCSID(0, "$NetBSD: xhci.c,v 1.72.2.8 2018/09/27 14:52:26 martin Exp $"); #ifdef _KERNEL_OPT #include "opt_usb.h" @@ -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: src/sys/external/bsd/dwc2/dwc2.c diff -u src/sys/external/bsd/dwc2/dwc2.c:1.46.2.2 src/sys/external/bsd/dwc2/dwc2.c:1.46.2.3 --- src/sys/external/bsd/dwc2/dwc2.c:1.46.2.2 Sat Aug 25 11:29:52 2018 +++ src/sys/external/bsd/dwc2/dwc2.c Thu Sep 27 14:52:26 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: dwc2.c,v 1.46.2.2 2018/08/25 11:29:52 martin Exp $ */ +/* $NetBSD: dwc2.c,v 1.46.2.3 2018/09/27 14:52:26 martin Exp $ */ /*- * Copyright (c) 2013 The NetBSD Foundation, Inc. @@ -30,7 +30,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: dwc2.c,v 1.46.2.2 2018/08/25 11:29:52 martin Exp $"); +__KERNEL_RCSID(0, "$NetBSD: dwc2.c,v 1.46.2.3 2018/09/27 14:52:26 martin Exp $"); #include "opt_usb.h" @@ -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: src/sys/kern/subr_userconf.c diff -u src/sys/kern/subr_userconf.c:1.26 src/sys/kern/subr_userconf.c:1.26.22.1 --- src/sys/kern/subr_userconf.c:1.26 Mon Dec 23 15:34:16 2013 +++ src/sys/kern/subr_userconf.c Thu Sep 27 14:52:26 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: subr_userconf.c,v 1.26 2013/12/23 15:34:16 skrll Exp $ */ +/* $NetBSD: subr_userconf.c,v 1.26.22.1 2018/09/27 14:52:26 martin Exp $ */ /* * Copyright (c) 1996 Mats O Jansson <m...@stacken.kth.se> @@ -29,7 +29,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: subr_userconf.c,v 1.26 2013/12/23 15:34:16 skrll Exp $"); +__KERNEL_RCSID(0, "$NetBSD: subr_userconf.c,v 1.26.22.1 2018/09/27 14:52:26 martin Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -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"); }