Module Name: src Committed By: riastradh Date: Thu Mar 3 06:12:11 UTC 2022
Modified Files: src/sys/arch/mips/adm5120/dev: ahci.c src/sys/dev/ic: sl811hs.c src/sys/dev/usb: ehci.c motg.c ohci.c uhci.c usbdi.c usbdivar.h usbroothub.c vhci.c xhci.c src/sys/external/bsd/dwc2: dwc2.c src/sys/rump/dev/lib/libugenhc: ugenhc.c Log Message: usb: Hold pipe lock across upm_transfer and upm_start. This simplifies the code and fixes races with abort. Access to the pipe's queue is now done exclusively while the pipe is locked. To generate a diff of this commit: cvs rdiff -u -r1.29 -r1.30 src/sys/arch/mips/adm5120/dev/ahci.c cvs rdiff -u -r1.109 -r1.110 src/sys/dev/ic/sl811hs.c cvs rdiff -u -r1.304 -r1.305 src/sys/dev/usb/ehci.c cvs rdiff -u -r1.39 -r1.40 src/sys/dev/usb/motg.c cvs rdiff -u -r1.320 -r1.321 src/sys/dev/usb/ohci.c cvs rdiff -u -r1.310 -r1.311 src/sys/dev/usb/uhci.c cvs rdiff -u -r1.230 -r1.231 src/sys/dev/usb/usbdi.c cvs rdiff -u -r1.133 -r1.134 src/sys/dev/usb/usbdivar.h cvs rdiff -u -r1.12 -r1.13 src/sys/dev/usb/usbroothub.c cvs rdiff -u -r1.24 -r1.25 src/sys/dev/usb/vhci.c cvs rdiff -u -r1.157 -r1.158 src/sys/dev/usb/xhci.c cvs rdiff -u -r1.79 -r1.80 src/sys/external/bsd/dwc2/dwc2.c cvs rdiff -u -r1.30 -r1.31 src/sys/rump/dev/lib/libugenhc/ugenhc.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/arch/mips/adm5120/dev/ahci.c diff -u src/sys/arch/mips/adm5120/dev/ahci.c:1.29 src/sys/arch/mips/adm5120/dev/ahci.c:1.30 --- src/sys/arch/mips/adm5120/dev/ahci.c:1.29 Thu Mar 3 06:04:31 2022 +++ src/sys/arch/mips/adm5120/dev/ahci.c Thu Mar 3 06:12:11 2022 @@ -1,4 +1,4 @@ -/* $NetBSD: ahci.c,v 1.29 2022/03/03 06:04:31 riastradh Exp $ */ +/* $NetBSD: ahci.c,v 1.30 2022/03/03 06:12:11 riastradh Exp $ */ /*- * Copyright (c) 2007 Ruslan Ermilov and Vsevolod Lobko. @@ -64,7 +64,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: ahci.c,v 1.29 2022/03/03 06:04:31 riastradh Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ahci.c,v 1.30 2022/03/03 06:12:11 riastradh Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -569,6 +569,8 @@ ahci_roothub_ctrl(struct usbd_bus *bus, 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); @@ -743,13 +745,13 @@ ahci_root_intr_start(struct usbd_xfer *x 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; } @@ -834,11 +836,11 @@ ahci_device_ctrl_start(struct usbd_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 @@ -968,7 +970,6 @@ ahci_device_ctrl_start(struct usbd_xfer /* printf("ctrl_start<<<\n"); */ usb_transfer_complete(xfer); - mutex_exit(&sc->sc_lock); usb_freemem(&reqdma); @@ -1006,11 +1007,14 @@ ahci_device_intr_transfer(struct usbd_xf 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; @@ -1156,6 +1160,8 @@ ahci_device_bulk_start(struct usbd_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 */ @@ -1164,7 +1170,6 @@ ahci_device_bulk_start(struct usbd_xfer } #endif - mutex_enter(&sc->sc_lock); level++; /* printf("bulk_start>>>\n"); */ @@ -1291,7 +1296,6 @@ ahci_device_bulk_start(struct usbd_xfer isread ? BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE); usb_transfer_complete(xfer); - mutex_exit(&sc->sc_lock); return USBD_NORMAL_COMPLETION; } Index: src/sys/dev/ic/sl811hs.c diff -u src/sys/dev/ic/sl811hs.c:1.109 src/sys/dev/ic/sl811hs.c:1.110 --- src/sys/dev/ic/sl811hs.c:1.109 Thu Mar 3 06:04:31 2022 +++ src/sys/dev/ic/sl811hs.c Thu Mar 3 06:12:11 2022 @@ -1,4 +1,4 @@ -/* $NetBSD: sl811hs.c,v 1.109 2022/03/03 06:04:31 riastradh Exp $ */ +/* $NetBSD: sl811hs.c,v 1.110 2022/03/03 06:12:11 riastradh Exp $ */ /* * Not (c) 2007 Matthew Orgass @@ -68,7 +68,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: sl811hs.c,v 1.109 2022/03/03 06:04:31 riastradh Exp $"); +__KERNEL_RCSID(0, "$NetBSD: sl811hs.c,v 1.110 2022/03/03 06:12:11 riastradh Exp $"); #ifdef _KERNEL_OPT #include "opt_slhci.h" @@ -846,10 +846,6 @@ slhci_transfer(struct usbd_xfer *xfer) 0); /* Pipe isn't running, so start it first. */ - - /* - * Start will take the lock. - */ error = xfer->ux_pipe->up_methods->upm_start(SIMPLEQ_FIRST(&xfer->ux_pipe->up_queue)); return error; @@ -867,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); @@ -989,8 +985,6 @@ slhci_start(struct usbd_xfer *xfer) slhci_start_entry(sc, spipe); - mutex_exit(&sc->sc_lock); - return USBD_IN_PROGRESS; } @@ -1012,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; } @@ -3201,6 +3195,8 @@ slhci_roothub_ctrl(struct usbd_bus *bus, 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); Index: src/sys/dev/usb/ehci.c diff -u src/sys/dev/usb/ehci.c:1.304 src/sys/dev/usb/ehci.c:1.305 --- src/sys/dev/usb/ehci.c:1.304 Thu Mar 3 06:08:50 2022 +++ src/sys/dev/usb/ehci.c Thu Mar 3 06:12:11 2022 @@ -1,4 +1,4 @@ -/* $NetBSD: ehci.c,v 1.304 2022/03/03 06:08:50 riastradh Exp $ */ +/* $NetBSD: ehci.c,v 1.305 2022/03/03 06:12:11 riastradh Exp $ */ /* * Copyright (c) 2004-2012,2016,2020 The NetBSD Foundation, Inc. @@ -54,7 +54,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: ehci.c,v 1.304 2022/03/03 06:08:50 riastradh Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ehci.c,v 1.305 2022/03/03 06:12:11 riastradh Exp $"); #include "ohci.h" #include "uhci.h" @@ -2369,6 +2369,8 @@ ehci_roothub_ctrl(struct usbd_bus *bus, EHCIHIST_FUNC(); EHCIHIST_CALLED(); + KASSERT(bus->ub_usepolling || mutex_owned(bus->ub_lock)); + if (sc->sc_dying) return -1; @@ -2757,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; } @@ -3607,10 +3606,10 @@ 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(); + KASSERT(sc->sc_bus.ub_usepolling || mutex_owned(&sc->sc_lock)); KASSERT(xfer->ux_rqflags & URQ_REQUEST); if (sc->sc_dying) @@ -3729,16 +3728,11 @@ ehci_device_ctrl_start(struct usbd_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 @@ -3878,13 +3872,14 @@ 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(); 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; @@ -3901,10 +3896,6 @@ ehci_device_bulk_start(struct usbd_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; @@ -3928,8 +3919,6 @@ ehci_device_bulk_start(struct usbd_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 @@ -4082,13 +4071,14 @@ 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(); 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; @@ -4105,10 +4095,6 @@ ehci_device_intr_start(struct usbd_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); @@ -4132,8 +4118,6 @@ ehci_device_intr_start(struct usbd_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 @@ -4325,6 +4309,8 @@ ehci_device_fs_isoc_transfer(struct usbd 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; @@ -4458,8 +4444,6 @@ ehci_device_fs_isoc_transfer(struct usbd * 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; @@ -4522,7 +4506,6 @@ ehci_device_fs_isoc_transfer(struct usbd ehci_add_intr_list(sc, exfer); xfer->ux_status = USBD_IN_PROGRESS; - mutex_exit(&sc->sc_lock); return USBD_IN_PROGRESS; } @@ -4690,6 +4673,8 @@ ehci_device_isoc_transfer(struct usbd_xf 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; @@ -4836,8 +4821,6 @@ ehci_device_isoc_transfer(struct usbd_xf * 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; @@ -4905,7 +4888,6 @@ ehci_device_isoc_transfer(struct usbd_xf ehci_add_intr_list(sc, exfer); xfer->ux_status = USBD_IN_PROGRESS; - mutex_exit(&sc->sc_lock); return USBD_IN_PROGRESS; } Index: src/sys/dev/usb/motg.c diff -u src/sys/dev/usb/motg.c:1.39 src/sys/dev/usb/motg.c:1.40 --- src/sys/dev/usb/motg.c:1.39 Thu Mar 3 06:08:50 2022 +++ src/sys/dev/usb/motg.c Thu Mar 3 06:12:11 2022 @@ -1,4 +1,4 @@ -/* $NetBSD: motg.c,v 1.39 2022/03/03 06:08:50 riastradh Exp $ */ +/* $NetBSD: motg.c,v 1.40 2022/03/03 06:12:11 riastradh Exp $ */ /* * Copyright (c) 1998, 2004, 2011, 2012, 2014 The NetBSD Foundation, Inc. @@ -40,7 +40,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: motg.c,v 1.39 2022/03/03 06:08:50 riastradh Exp $"); +__KERNEL_RCSID(0, "$NetBSD: motg.c,v 1.40 2022/03/03 06:12:11 riastradh Exp $"); #ifdef _KERNEL_OPT #include "opt_usb.h" @@ -806,6 +806,8 @@ motg_roothub_ctrl(struct usbd_bus *bus, MOTGHIST_FUNC(); MOTGHIST_CALLED(); + KASSERT(bus->ub_usepolling || mutex_owned(bus->ub_lock)); + if (sc->sc_dying) return -1; @@ -1020,23 +1022,20 @@ motg_root_intr_start(struct usbd_xfer *x { 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; } @@ -1276,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 @@ -1717,15 +1715,14 @@ motg_device_data_start(struct usbd_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 Index: src/sys/dev/usb/ohci.c diff -u src/sys/dev/usb/ohci.c:1.320 src/sys/dev/usb/ohci.c:1.321 --- src/sys/dev/usb/ohci.c:1.320 Thu Mar 3 06:08:50 2022 +++ src/sys/dev/usb/ohci.c Thu Mar 3 06:12:11 2022 @@ -1,4 +1,4 @@ -/* $NetBSD: ohci.c,v 1.320 2022/03/03 06:08:50 riastradh Exp $ */ +/* $NetBSD: ohci.c,v 1.321 2022/03/03 06:12:11 riastradh Exp $ */ /* * Copyright (c) 1998, 2004, 2005, 2012, 2016, 2020 The NetBSD Foundation, Inc. @@ -42,7 +42,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: ohci.c,v 1.320 2022/03/03 06:08:50 riastradh Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ohci.c,v 1.321 2022/03/03 06:12:11 riastradh Exp $"); #ifdef _KERNEL_OPT #include "opt_usb.h" @@ -2431,6 +2431,8 @@ ohci_roothub_ctrl(struct usbd_bus *bus, OHCIHIST_FUNC(); OHCIHIST_CALLED(); + KASSERT(bus->ub_usepolling || mutex_owned(bus->ub_lock)); + if (sc->sc_dying) return -1; @@ -2620,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; } @@ -2777,10 +2776,11 @@ 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(); + KASSERT(sc->sc_bus.ub_usepolling || mutex_owned(&sc->sc_lock)); + if (sc->sc_dying) return USBD_IOERROR; @@ -2795,10 +2795,6 @@ ohci_device_ctrl_start(struct usbd_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 @@ -2933,8 +2929,6 @@ ohci_device_ctrl_start(struct usbd_xfer DPRINTF("done", 0, 0, 0, 0); xfer->ux_status = USBD_IN_PROGRESS; - if (!polling) - mutex_exit(&sc->sc_lock); return USBD_IN_PROGRESS; } @@ -3054,10 +3048,11 @@ 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(); + KASSERT(sc->sc_bus.ub_usepolling || mutex_owned(&sc->sc_lock)); + if (sc->sc_dying) return USBD_IOERROR; @@ -3072,9 +3067,6 @@ ohci_device_bulk_start(struct usbd_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 @@ -3141,8 +3133,6 @@ ohci_device_bulk_start(struct usbd_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; } @@ -3252,10 +3242,11 @@ 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(); + KASSERT(sc->sc_bus.ub_usepolling || mutex_owned(&sc->sc_lock)); + if (sc->sc_dying) return USBD_IOERROR; @@ -3268,9 +3259,6 @@ ohci_device_intr_start(struct usbd_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. @@ -3327,8 +3315,6 @@ ohci_device_intr_start(struct usbd_xfer BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); xfer->ux_status = USBD_IN_PROGRESS; - if (!polling) - mutex_exit(&sc->sc_lock); return USBD_IN_PROGRESS; } @@ -3559,12 +3545,10 @@ ohci_device_isoc_enter(struct usbd_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; @@ -3723,7 +3707,6 @@ ohci_device_isoc_enter(struct usbd_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 Index: src/sys/dev/usb/uhci.c diff -u src/sys/dev/usb/uhci.c:1.310 src/sys/dev/usb/uhci.c:1.311 --- src/sys/dev/usb/uhci.c:1.310 Thu Mar 3 06:08:50 2022 +++ src/sys/dev/usb/uhci.c Thu Mar 3 06:12:11 2022 @@ -1,4 +1,4 @@ -/* $NetBSD: uhci.c,v 1.310 2022/03/03 06:08:50 riastradh Exp $ */ +/* $NetBSD: uhci.c,v 1.311 2022/03/03 06:12:11 riastradh Exp $ */ /* * Copyright (c) 1998, 2004, 2011, 2012, 2016, 2020 The NetBSD Foundation, Inc. @@ -42,7 +42,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: uhci.c,v 1.310 2022/03/03 06:08:50 riastradh Exp $"); +__KERNEL_RCSID(0, "$NetBSD: uhci.c,v 1.311 2022/03/03 06:12:11 riastradh Exp $"); #ifdef _KERNEL_OPT #include "opt_usb.h" @@ -2271,7 +2271,6 @@ 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; @@ -2280,6 +2279,8 @@ uhci_device_bulk_start(struct usbd_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; @@ -2291,10 +2292,6 @@ uhci_device_bulk_start(struct usbd_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); @@ -2328,8 +2325,6 @@ uhci_device_bulk_start(struct usbd_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; } @@ -2495,12 +2490,13 @@ 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; UHCIHIST_FUNC(); UHCIHIST_CALLED(); + KASSERT(sc->sc_bus.ub_usepolling || mutex_owned(&sc->sc_lock)); + if (sc->sc_dying) return USBD_IOERROR; @@ -2523,9 +2519,6 @@ 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); - if (!polling) - mutex_enter(&sc->sc_lock); - /* Set up data transaction */ if (len != 0) { upipe->nexttoggle = 1; @@ -2623,8 +2616,6 @@ uhci_device_ctrl_start(struct usbd_xfer #endif usbd_xfer_schedule_timeout(xfer); xfer->ux_status = USBD_IN_PROGRESS; - if (!polling) - mutex_exit(&sc->sc_lock); return USBD_IN_PROGRESS; } @@ -2685,18 +2676,19 @@ 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; - 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); @@ -2711,8 +2703,6 @@ uhci_device_intr_start(struct usbd_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); @@ -2744,8 +2734,6 @@ uhci_device_intr_start(struct usbd_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) { @@ -2854,6 +2842,8 @@ uhci_device_isoc_transfer(struct usbd_xf UHCIHIST_FUNC(); UHCIHIST_CALLED(); DPRINTFN(5, "xfer=%#jx", (uintptr_t)xfer, 0, 0, 0); + KASSERT(sc->sc_bus.ub_usepolling || mutex_owned(&sc->sc_lock)); + /* insert into schedule, */ struct uhci_pipe *upipe = UHCI_PIPE2UPIPE(xfer->ux_pipe); @@ -2887,7 +2877,6 @@ uhci_device_isoc_transfer(struct usbd_xf 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. */ @@ -2949,8 +2938,6 @@ uhci_device_isoc_transfer(struct usbd_xf #endif uhci_add_intr_list(sc, ux); - mutex_exit(&sc->sc_lock); - return USBD_IN_PROGRESS; } @@ -3602,6 +3589,8 @@ uhci_roothub_ctrl(struct usbd_bus *bus, UHCIHIST_FUNC(); UHCIHIST_CALLED(); + KASSERT(bus->ub_usepolling || mutex_owned(bus->ub_lock)); + if (sc->sc_dying) return -1; @@ -3853,18 +3842,16 @@ uhci_root_intr_start(struct usbd_xfer *x 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 */ @@ -3874,9 +3861,6 @@ uhci_root_intr_start(struct usbd_xfer *x sc->sc_intr_xfer = xfer; xfer->ux_status = USBD_IN_PROGRESS; - if (!polling) - mutex_exit(&sc->sc_lock); - return USBD_IN_PROGRESS; } Index: src/sys/dev/usb/usbdi.c diff -u src/sys/dev/usb/usbdi.c:1.230 src/sys/dev/usb/usbdi.c:1.231 --- src/sys/dev/usb/usbdi.c:1.230 Thu Mar 3 06:09:57 2022 +++ src/sys/dev/usb/usbdi.c Thu Mar 3 06:12:11 2022 @@ -1,4 +1,4 @@ -/* $NetBSD: usbdi.c,v 1.230 2022/03/03 06:09:57 riastradh Exp $ */ +/* $NetBSD: usbdi.c,v 1.231 2022/03/03 06:12:11 riastradh 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.230 2022/03/03 06:09:57 riastradh Exp $"); +__KERNEL_RCSID(0, "$NetBSD: usbdi.c,v 1.231 2022/03/03 06:12:11 riastradh Exp $"); #ifdef _KERNEL_OPT #include "opt_usb.h" @@ -422,13 +422,14 @@ usbd_transfer(struct usbd_xfer *xfer) pipe->up_running = 1; err = USBD_NORMAL_COMPLETION; } - usbd_unlock_pipe(pipe); 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 @@ -1190,12 +1191,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); Index: src/sys/dev/usb/usbdivar.h diff -u src/sys/dev/usb/usbdivar.h:1.133 src/sys/dev/usb/usbdivar.h:1.134 --- src/sys/dev/usb/usbdivar.h:1.133 Thu Mar 3 06:09:20 2022 +++ src/sys/dev/usb/usbdivar.h Thu Mar 3 06:12:11 2022 @@ -1,4 +1,4 @@ -/* $NetBSD: usbdivar.h,v 1.133 2022/03/03 06:09:20 riastradh Exp $ */ +/* $NetBSD: usbdivar.h,v 1.134 2022/03/03 06:12:11 riastradh Exp $ */ /* * Copyright (c) 1998, 2012 The NetBSD Foundation, Inc. @@ -51,14 +51,14 @@ * 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_init - * upm_fini - - * upm_transfer - - * upm_start - might want to take lock? + * upm_transfer x + * upm_start x * upm_abort x * upm_close x * upm_cleartoggle - Index: src/sys/dev/usb/usbroothub.c diff -u src/sys/dev/usb/usbroothub.c:1.12 src/sys/dev/usb/usbroothub.c:1.13 --- src/sys/dev/usb/usbroothub.c:1.12 Thu Mar 3 06:04:31 2022 +++ src/sys/dev/usb/usbroothub.c Thu Mar 3 06:12:11 2022 @@ -1,4 +1,4 @@ -/* $NetBSD: usbroothub.c,v 1.12 2022/03/03 06:04:31 riastradh Exp $ */ +/* $NetBSD: usbroothub.c,v 1.13 2022/03/03 06:12:11 riastradh Exp $ */ /*- * Copyright (c) 1998, 2004, 2011, 2012 The NetBSD Foundation, Inc. @@ -58,7 +58,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: usbroothub.c,v 1.12 2022/03/03 06:04:31 riastradh Exp $"); +__KERNEL_RCSID(0, "$NetBSD: usbroothub.c,v 1.13 2022/03/03 06:12:11 riastradh Exp $"); #include <sys/param.h> #include <sys/systm.h> /* for ostype */ @@ -361,6 +361,13 @@ roothub_ctrl_start(struct usbd_xfer *xfe 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; @@ -554,9 +561,7 @@ roothub_ctrl_start(struct usbd_xfer *xfe (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; } Index: src/sys/dev/usb/vhci.c diff -u src/sys/dev/usb/vhci.c:1.24 src/sys/dev/usb/vhci.c:1.25 --- src/sys/dev/usb/vhci.c:1.24 Thu Mar 3 06:04:31 2022 +++ src/sys/dev/usb/vhci.c Thu Mar 3 06:12:11 2022 @@ -1,4 +1,4 @@ -/* $NetBSD: vhci.c,v 1.24 2022/03/03 06:04:31 riastradh Exp $ */ +/* $NetBSD: vhci.c,v 1.25 2022/03/03 06:12:11 riastradh Exp $ */ /* * Copyright (c) 2019-2020 The NetBSD Foundation, Inc. @@ -30,7 +30,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: vhci.c,v 1.24 2022/03/03 06:04:31 riastradh Exp $"); +__KERNEL_RCSID(0, "$NetBSD: vhci.c,v 1.25 2022/03/03 06:12:11 riastradh Exp $"); #ifdef _KERNEL_OPT #include "opt_usb.h" @@ -605,7 +605,6 @@ vhci_device_ctrl_start(struct usbd_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; @@ -618,14 +617,13 @@ vhci_device_ctrl_start(struct usbd_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; @@ -636,9 +634,6 @@ vhci_device_ctrl_start(struct usbd_xfer } mutex_exit(&port->lock); - if (!polling) - mutex_exit(&sc->sc_lock); - return ret; } @@ -709,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; } Index: src/sys/dev/usb/xhci.c diff -u src/sys/dev/usb/xhci.c:1.157 src/sys/dev/usb/xhci.c:1.158 --- src/sys/dev/usb/xhci.c:1.157 Thu Mar 3 06:08:50 2022 +++ src/sys/dev/usb/xhci.c Thu Mar 3 06:12:11 2022 @@ -1,4 +1,4 @@ -/* $NetBSD: xhci.c,v 1.157 2022/03/03 06:08:50 riastradh Exp $ */ +/* $NetBSD: xhci.c,v 1.158 2022/03/03 06:12:11 riastradh Exp $ */ /* * Copyright (c) 2013 Jonathan A. Kollasch @@ -34,7 +34,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: xhci.c,v 1.157 2022/03/03 06:08:50 riastradh Exp $"); +__KERNEL_RCSID(0, "$NetBSD: xhci.c,v 1.158 2022/03/03 06:12:11 riastradh Exp $"); #ifdef _KERNEL_OPT #include "opt_usb.h" @@ -2186,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", @@ -2227,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); } @@ -3870,6 +3856,8 @@ xhci_roothub_ctrl(struct usbd_bus *bus, XHCIHIST_FUNC(); + KASSERT(bus->ub_usepolling || mutex_owned(bus->ub_lock)); + if (sc->sc_dying) return -1; @@ -4139,20 +4127,17 @@ 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 = 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; } @@ -4250,14 +4235,14 @@ xhci_device_ctrl_start(struct usbd_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; @@ -4315,8 +4300,6 @@ out: if (xfer->ux_status == USBD_NOT_STA */ } KASSERT(xfer->ux_status == USBD_IN_PROGRESS); - if (!polling) - mutex_exit(&sc->sc_lock); return USBD_IN_PROGRESS; } @@ -4388,6 +4371,8 @@ xhci_device_isoc_enter(struct usbd_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; @@ -4460,13 +4445,9 @@ xhci_device_isoc_enter(struct usbd_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; } @@ -4536,13 +4517,13 @@ xhci_device_bulk_start(struct usbd_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; @@ -4590,8 +4571,6 @@ out: if (xfer->ux_status == USBD_NOT_STA */ } KASSERT(xfer->ux_status == USBD_IN_PROGRESS); - if (!polling) - mutex_exit(&sc->sc_lock); return USBD_IN_PROGRESS; } @@ -4661,11 +4640,11 @@ xhci_device_intr_start(struct usbd_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; @@ -4703,8 +4682,6 @@ out: if (xfer->ux_status == USBD_NOT_STA */ } KASSERT(xfer->ux_status == USBD_IN_PROGRESS); - if (!polling) - mutex_exit(&sc->sc_lock); return USBD_IN_PROGRESS; } Index: src/sys/external/bsd/dwc2/dwc2.c diff -u src/sys/external/bsd/dwc2/dwc2.c:1.79 src/sys/external/bsd/dwc2/dwc2.c:1.80 --- src/sys/external/bsd/dwc2/dwc2.c:1.79 Thu Mar 3 06:08:50 2022 +++ src/sys/external/bsd/dwc2/dwc2.c Thu Mar 3 06:12:11 2022 @@ -1,4 +1,4 @@ -/* $NetBSD: dwc2.c,v 1.79 2022/03/03 06:08:50 riastradh Exp $ */ +/* $NetBSD: dwc2.c,v 1.80 2022/03/03 06:12:11 riastradh Exp $ */ /*- * Copyright (c) 2013 The NetBSD Foundation, Inc. @@ -30,7 +30,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: dwc2.c,v 1.79 2022/03/03 06:08:50 riastradh Exp $"); +__KERNEL_RCSID(0, "$NetBSD: dwc2.c,v 1.80 2022/03/03 06:12:11 riastradh Exp $"); #include "opt_usb.h" @@ -620,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; } @@ -709,17 +706,13 @@ 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"); - 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; @@ -760,18 +753,12 @@ dwc2_device_ctrl_done(struct usbd_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); - mutex_enter(&sc->sc_lock); 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 @@ -820,15 +807,11 @@ 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; - 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; @@ -868,18 +851,12 @@ dwc2_device_intr_done(struct usbd_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); - mutex_enter(&sc->sc_lock); 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 @@ -933,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); @@ -1121,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; Index: src/sys/rump/dev/lib/libugenhc/ugenhc.c diff -u src/sys/rump/dev/lib/libugenhc/ugenhc.c:1.30 src/sys/rump/dev/lib/libugenhc/ugenhc.c:1.31 --- src/sys/rump/dev/lib/libugenhc/ugenhc.c:1.30 Thu Mar 3 06:04:31 2022 +++ src/sys/rump/dev/lib/libugenhc/ugenhc.c Thu Mar 3 06:12:11 2022 @@ -1,4 +1,4 @@ -/* $NetBSD: ugenhc.c,v 1.30 2022/03/03 06:04:31 riastradh Exp $ */ +/* $NetBSD: ugenhc.c,v 1.31 2022/03/03 06:12:11 riastradh Exp $ */ /* * Copyright (c) 2009, 2010 Antti Kantee. All Rights Reserved. @@ -61,7 +61,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: ugenhc.c,v 1.30 2022/03/03 06:04:31 riastradh Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ugenhc.c,v 1.31 2022/03/03 06:12:11 riastradh Exp $"); #include <sys/param.h> #include <sys/bus.h> @@ -227,6 +227,8 @@ rumpusb_device_ctrl_start(struct usbd_xf 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_xf ret: xfer->ux_status = err; - mutex_enter(&sc->sc_lock); usb_transfer_complete(xfer); - mutex_exit(&sc->sc_lock); return USBD_IN_PROGRESS; } @@ -516,7 +516,8 @@ rumpusb_root_intr_start(struct usbd_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, @@ -524,7 +525,6 @@ rumpusb_root_intr_start(struct usbd_xfer if (error) xfer->ux_status = USBD_IOERROR; } - mutex_exit(&sc->sc_lock); return USBD_IN_PROGRESS; } @@ -581,6 +581,8 @@ rumpusb_device_bulk_start(struct usbd_xf 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; @@ -667,9 +669,7 @@ rumpusb_device_bulk_start(struct usbd_xf 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; } @@ -682,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);