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.
This commit is contained in:
mrg 2018-09-16 20:21:56 +00:00
parent 06bbe38b6d
commit b627726203
7 changed files with 141 additions and 76 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: ehci.c,v 1.263 2018/09/16 09:25:47 skrll Exp $ */
/* $NetBSD: ehci.c,v 1.264 2018/09/16 20:21:56 mrg 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.263 2018/09/16 09:25:47 skrll Exp $");
__KERNEL_RCSID(0, "$NetBSD: ehci.c,v 1.264 2018/09/16 20:21:56 mrg Exp $");
#include "ohci.h"
#include "uhci.h"
@ -2637,13 +2637,16 @@ Static usbd_status
ehci_root_intr_start(struct usbd_xfer *xfer)
{
ehci_softc_t *sc = EHCI_XFER2SC(xfer);
const bool polling = sc->sc_bus.ub_usepolling;
if (sc->sc_dying)
return USBD_IOERROR;
mutex_enter(&sc->sc_lock);
if (!polling)
mutex_enter(&sc->sc_lock);
sc->sc_intrxfer = xfer;
mutex_exit(&sc->sc_lock);
if (!polling)
mutex_exit(&sc->sc_lock);
return USBD_IN_PROGRESS;
}
@ -3538,6 +3541,7 @@ ehci_device_ctrl_start(struct usbd_xfer *xfer)
ehci_softc_t *sc = EHCI_XFER2SC(xfer);
ehci_soft_qtd_t *setup, *status, *next;
ehci_soft_qh_t *sqh;
const bool polling = sc->sc_bus.ub_usepolling;
EHCIHIST_FUNC(); EHCIHIST_CALLED();
@ -3657,7 +3661,8 @@ ehci_device_ctrl_start(struct usbd_xfer *xfer)
DPRINTFN(5, "--- dump end ---", 0, 0, 0, 0);
#endif
mutex_enter(&sc->sc_lock);
if (!polling)
mutex_enter(&sc->sc_lock);
/* Insert qTD in QH list - also does usb_syncmem(sqh) */
ehci_set_qh_qtd(sqh, setup);
@ -3667,7 +3672,8 @@ ehci_device_ctrl_start(struct usbd_xfer *xfer)
}
ehci_add_intr_list(sc, exfer);
xfer->ux_status = USBD_IN_PROGRESS;
mutex_exit(&sc->sc_lock);
if (!polling)
mutex_exit(&sc->sc_lock);
#if 0
#ifdef EHCI_DEBUG
@ -3814,6 +3820,7 @@ ehci_device_bulk_start(struct usbd_xfer *xfer)
ehci_soft_qh_t *sqh;
ehci_soft_qtd_t *end;
int len, isread, endpt;
const bool polling = sc->sc_bus.ub_usepolling;
EHCIHIST_FUNC(); EHCIHIST_CALLED();
@ -3837,7 +3844,8 @@ ehci_device_bulk_start(struct usbd_xfer *xfer)
#endif
/* Take lock here to protect nexttoggle */
mutex_enter(&sc->sc_lock);
if (!polling)
mutex_enter(&sc->sc_lock);
ehci_reset_sqtd_chain(sc, xfer, len, isread, &epipe->nexttoggle, &end);
@ -3864,7 +3872,8 @@ ehci_device_bulk_start(struct usbd_xfer *xfer)
}
ehci_add_intr_list(sc, exfer);
xfer->ux_status = USBD_IN_PROGRESS;
mutex_exit(&sc->sc_lock);
if (!polling)
mutex_exit(&sc->sc_lock);
#if 0
#ifdef EHCI_DEBUG
@ -4029,6 +4038,7 @@ ehci_device_intr_start(struct usbd_xfer *xfer)
ehci_soft_qtd_t *end;
ehci_soft_qh_t *sqh;
int len, isread, endpt;
const bool polling = sc->sc_bus.ub_usepolling;
EHCIHIST_FUNC(); EHCIHIST_CALLED();
@ -4052,7 +4062,8 @@ ehci_device_intr_start(struct usbd_xfer *xfer)
#endif
/* Take lock to protect nexttoggle */
mutex_enter(&sc->sc_lock);
if (!polling)
mutex_enter(&sc->sc_lock);
ehci_reset_sqtd_chain(sc, xfer, len, isread, &epipe->nexttoggle, &end);
@ -4079,7 +4090,8 @@ ehci_device_intr_start(struct usbd_xfer *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

View File

@ -1,4 +1,4 @@
/* $NetBSD: ohci.c,v 1.286 2018/09/16 10:29:39 mrg Exp $ */
/* $NetBSD: ohci.c,v 1.287 2018/09/16 20:21:56 mrg 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.286 2018/09/16 10:29:39 mrg Exp $");
__KERNEL_RCSID(0, "$NetBSD: ohci.c,v 1.287 2018/09/16 20:21:56 mrg Exp $");
#ifdef _KERNEL_OPT
#include "opt_usb.h"
@ -2591,14 +2591,17 @@ Static usbd_status
ohci_root_intr_start(struct usbd_xfer *xfer)
{
ohci_softc_t *sc = OHCI_XFER2SC(xfer);
const bool polling = sc->sc_bus.ub_usepolling;
if (sc->sc_dying)
return USBD_IOERROR;
mutex_enter(&sc->sc_lock);
if (!polling)
mutex_enter(&sc->sc_lock);
KASSERT(sc->sc_intrxfer == NULL);
sc->sc_intrxfer = xfer;
mutex_exit(&sc->sc_lock);
if (!polling)
mutex_exit(&sc->sc_lock);
return USBD_IN_PROGRESS;
}
@ -2732,6 +2735,7 @@ ohci_device_ctrl_start(struct usbd_xfer *xfer)
ohci_soft_ed_t *sed;
int isread;
int len;
const bool polling = sc->sc_bus.ub_usepolling;
OHCIHIST_FUNC(); OHCIHIST_CALLED();
@ -2750,7 +2754,8 @@ ohci_device_ctrl_start(struct usbd_xfer *xfer)
UGETW(req->wIndex));
/* Need to take lock here for pipe->tail.td */
mutex_enter(&sc->sc_lock);
if (!polling)
mutex_enter(&sc->sc_lock);
/*
* Use the pipe "tail" TD as our first and loan our first TD to the
@ -2866,7 +2871,7 @@ ohci_device_ctrl_start(struct usbd_xfer *xfer)
sizeof(sed->ed.ed_tailp),
BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
OWRITE4(sc, OHCI_COMMAND_STATUS, OHCI_CLF);
if (xfer->ux_timeout && !sc->sc_bus.ub_usepolling) {
if (xfer->ux_timeout && !polling) {
callout_reset(&xfer->ux_callout, mstohz(xfer->ux_timeout),
ohci_timeout, xfer);
}
@ -2874,7 +2879,8 @@ ohci_device_ctrl_start(struct usbd_xfer *xfer)
DPRINTF("done", 0, 0, 0, 0);
xfer->ux_status = USBD_IN_PROGRESS;
mutex_exit(&sc->sc_lock);
if (!polling)
mutex_exit(&sc->sc_lock);
return USBD_IN_PROGRESS;
}
@ -3001,6 +3007,7 @@ ohci_device_bulk_start(struct usbd_xfer *xfer)
ohci_soft_td_t *data, *tail, *tdp;
ohci_soft_ed_t *sed;
int len, isread, endpt;
const bool polling = sc->sc_bus.ub_usepolling;
OHCIHIST_FUNC(); OHCIHIST_CALLED();
@ -3018,7 +3025,8 @@ ohci_device_bulk_start(struct usbd_xfer *xfer)
len, isread, xfer->ux_flags);
DPRINTFN(4, "endpt=%jd", endpt, 0, 0, 0);
mutex_enter(&sc->sc_lock);
if (!polling)
mutex_enter(&sc->sc_lock);
/*
* Use the pipe "tail" TD as our first and loan our first TD to the
@ -3084,7 +3092,8 @@ ohci_device_bulk_start(struct usbd_xfer *xfer)
}
xfer->ux_status = USBD_IN_PROGRESS;
mutex_exit(&sc->sc_lock);
if (!polling)
mutex_exit(&sc->sc_lock);
return USBD_IN_PROGRESS;
}
@ -3203,6 +3212,7 @@ ohci_device_intr_start(struct usbd_xfer *xfer)
ohci_soft_ed_t *sed = opipe->sed;
ohci_soft_td_t *data, *last, *tail;
int len, isread, endpt;
const bool polling = sc->sc_bus.ub_usepolling;
OHCIHIST_FUNC(); OHCIHIST_CALLED();
@ -3218,7 +3228,8 @@ ohci_device_intr_start(struct usbd_xfer *xfer)
endpt = xfer->ux_pipe->up_endpoint->ue_edesc->bEndpointAddress;
isread = UE_GET_DIR(endpt) == UE_DIR_IN;
mutex_enter(&sc->sc_lock);
if (!polling)
mutex_enter(&sc->sc_lock);
/*
* Use the pipe "tail" TD as our first and loan our first TD to the
@ -3270,7 +3281,8 @@ ohci_device_intr_start(struct usbd_xfer *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;
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: uhci.c,v 1.283 2018/09/03 16:29:34 riastradh Exp $ */
/* $NetBSD: uhci.c,v 1.284 2018/09/16 20:21:56 mrg 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.283 2018/09/03 16:29:34 riastradh Exp $");
__KERNEL_RCSID(0, "$NetBSD: uhci.c,v 1.284 2018/09/16 20:21:56 mrg Exp $");
#ifdef _KERNEL_OPT
#include "opt_usb.h"
@ -1555,7 +1555,7 @@ uhci_idone(struct uhci_xfer *ux, ux_completeq_t *cqp)
struct uhci_pipe *upipe = UHCI_PIPE2UPIPE(xfer->ux_pipe);
uhci_soft_td_t *std;
uint32_t status = 0, nstatus;
bool polling __diagused = sc->sc_bus.ub_usepolling;
const bool polling __diagused = sc->sc_bus.ub_usepolling;
int actlen;
KASSERT(polling || mutex_owned(&sc->sc_lock));
@ -2257,6 +2257,7 @@ uhci_device_bulk_start(struct usbd_xfer *xfer)
uhci_softc_t *sc = UHCI_XFER2SC(xfer);
uhci_soft_td_t *data, *dataend;
uhci_soft_qh_t *sqh;
const bool polling = sc->sc_bus.ub_usepolling;
int len;
int endpt;
int isread;
@ -2277,7 +2278,8 @@ uhci_device_bulk_start(struct usbd_xfer *xfer)
sqh = upipe->bulk.sqh;
/* Take lock here to protect nexttoggle */
mutex_enter(&sc->sc_lock);
if (!polling)
mutex_enter(&sc->sc_lock);
uhci_reset_std_chain(sc, xfer, len, isread, &upipe->nexttoggle,
&dataend);
@ -2311,12 +2313,13 @@ uhci_device_bulk_start(struct usbd_xfer *xfer)
uhci_add_bulk(sc, sqh);
uhci_add_intr_list(sc, ux);
if (xfer->ux_timeout && !sc->sc_bus.ub_usepolling) {
if (xfer->ux_timeout && !polling) {
callout_reset(&xfer->ux_callout, mstohz(xfer->ux_timeout),
uhci_timeout, xfer);
}
xfer->ux_status = USBD_IN_PROGRESS;
mutex_exit(&sc->sc_lock);
if (!polling)
mutex_exit(&sc->sc_lock);
return USBD_IN_PROGRESS;
}
@ -2541,6 +2544,7 @@ uhci_device_ctrl_start(struct usbd_xfer *xfer)
int endpt = upipe->pipe.up_endpoint->ue_edesc->bEndpointAddress;
uhci_soft_td_t *setup, *stat, *next, *dataend;
uhci_soft_qh_t *sqh;
const bool polling = sc->sc_bus.ub_usepolling;
int len;
int isread;
@ -2568,7 +2572,8 @@ uhci_device_ctrl_start(struct usbd_xfer *xfer)
memcpy(KERNADDR(&upipe->ctrl.reqdma, 0), req, sizeof(*req));
usb_syncmem(&upipe->ctrl.reqdma, 0, sizeof(*req), BUS_DMASYNC_PREWRITE);
mutex_enter(&sc->sc_lock);
if (!polling)
mutex_enter(&sc->sc_lock);
/* Set up data transaction */
if (len != 0) {
@ -2665,12 +2670,13 @@ uhci_device_ctrl_start(struct usbd_xfer *xfer)
DPRINTF("--- dump end ---", 0, 0, 0, 0);
}
#endif
if (xfer->ux_timeout && !sc->sc_bus.ub_usepolling) {
if (xfer->ux_timeout && !polling) {
callout_reset(&xfer->ux_callout, mstohz(xfer->ux_timeout),
uhci_timeout, xfer);
}
xfer->ux_status = USBD_IN_PROGRESS;
mutex_exit(&sc->sc_lock);
if (!polling)
mutex_exit(&sc->sc_lock);
return USBD_IN_PROGRESS;
}
@ -2743,6 +2749,7 @@ uhci_device_intr_start(struct usbd_xfer *xfer)
uhci_softc_t *sc = UHCI_XFER2SC(xfer);
uhci_soft_td_t *data, *dataend;
uhci_soft_qh_t *sqh;
const bool polling = sc->sc_bus.ub_usepolling;
int isread, endpt;
int i;
@ -2768,7 +2775,7 @@ uhci_device_intr_start(struct usbd_xfer *xfer)
#endif
/* Take lock to protect nexttoggle */
if (!sc->sc_bus.ub_usepolling)
if (!polling)
mutex_enter(&sc->sc_lock);
uhci_reset_std_chain(sc, xfer, xfer->ux_length, isread,
&upipe->nexttoggle, &dataend);
@ -2801,7 +2808,7 @@ uhci_device_intr_start(struct usbd_xfer *xfer)
}
uhci_add_intr_list(sc, ux);
xfer->ux_status = USBD_IN_PROGRESS;
if (!sc->sc_bus.ub_usepolling)
if (!polling)
mutex_exit(&sc->sc_lock);
#ifdef UHCI_DEBUG

View File

@ -1,4 +1,4 @@
/* $NetBSD: usb.c,v 1.171 2018/08/02 06:09:04 riastradh Exp $ */
/* $NetBSD: usb.c,v 1.172 2018/09/16 20:21:56 mrg 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.171 2018/08/02 06:09:04 riastradh Exp $");
__KERNEL_RCSID(0, "$NetBSD: usb.c,v 1.172 2018/09/16 20:21:56 mrg Exp $");
#ifdef _KERNEL_OPT
#include "opt_usb.h"
@ -375,6 +375,10 @@ usb_doattach(device_t self)
sc->sc_dying = 1;
}
/*
* Drop this reference after the first set of attachments in the
* event thread.
*/
config_pending_incr(self);
if (!pmf_device_register(self, NULL, NULL))
@ -529,6 +533,7 @@ void
usb_event_thread(void *arg)
{
struct usb_softc *sc = arg;
struct usbd_bus *bus = sc->sc_bus;
USBHIST_FUNC(); USBHIST_CALLED(usbdebug);
@ -540,30 +545,37 @@ usb_event_thread(void *arg)
* know how to synchronize the creation of the threads so it
* will work.
*/
usb_delay_ms(sc->sc_bus, 500);
usb_delay_ms(bus, 500);
/* Make sure first discover does something. */
mutex_enter(sc->sc_bus->ub_lock);
mutex_enter(bus->ub_lock);
sc->sc_bus->ub_needsexplore = 1;
usb_discover(sc);
mutex_exit(sc->sc_bus->ub_lock);
config_pending_decr(sc->sc_bus->ub_usbctl);
mutex_exit(bus->ub_lock);
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);
@ -997,25 +1009,28 @@ usbkqfilter(dev_t dev, struct knote *kn)
Static void
usb_discover(struct usb_softc *sc)
{
struct usbd_bus *bus = sc->sc_bus;
USBHIST_FUNC(); USBHIST_CALLED(usbdebug);
KASSERT(mutex_owned(sc->sc_bus->ub_lock));
KASSERT(mutex_owned(bus->ub_lock));
if (usb_noexplore > 1)
return;
/*
* We need mutual exclusion while traversing the device tree,
* but this is guaranteed since this function is only called
* from the event thread for the controller.
*
* Also, we now have sc_bus->ub_lock held.
* Also, we now have bus->ub_lock held, and in combination
* with ub_exploring, avoids interferring with polling.
*/
while (sc->sc_bus->ub_needsexplore && !sc->sc_dying) {
sc->sc_bus->ub_needsexplore = 0;
while (bus->ub_needsexplore && !sc->sc_dying) {
bus->ub_needsexplore = 0;
mutex_exit(sc->sc_bus->ub_lock);
sc->sc_bus->ub_roothub->ud_hub->uh_explore(sc->sc_bus->ub_roothub);
mutex_enter(sc->sc_bus->ub_lock);
bus->ub_roothub->ud_hub->uh_explore(bus->ub_roothub);
mutex_enter(bus->ub_lock);
}
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: usbdi.c,v 1.177 2018/08/09 06:26:47 mrg Exp $ */
/* $NetBSD: usbdi.c,v 1.178 2018/09/16 20:21:56 mrg 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.177 2018/08/09 06:26:47 mrg Exp $");
__KERNEL_RCSID(0, "$NetBSD: usbdi.c,v 1.178 2018/09/16 20:21:56 mrg Exp $");
#ifdef _KERNEL_OPT
#include "opt_usb.h"
@ -964,19 +964,19 @@ usb_transfer_complete(struct usbd_xfer *xfer)
(uintptr_t)xfer, (uintptr_t)xfer->ux_callback, xfer->ux_status, 0);
if (xfer->ux_callback) {
if (!polling)
if (!polling) {
mutex_exit(pipe->up_dev->ud_bus->ub_lock);
if (!(pipe->up_flags & USBD_MPSAFE))
KERNEL_LOCK(1, curlwp);
if (!(pipe->up_flags & USBD_MPSAFE))
KERNEL_LOCK(1, curlwp);
}
xfer->ux_callback(xfer, xfer->ux_priv, xfer->ux_status);
if (!(pipe->up_flags & USBD_MPSAFE))
KERNEL_UNLOCK_ONE(curlwp);
if (!polling)
if (!polling) {
if (!(pipe->up_flags & USBD_MPSAFE))
KERNEL_UNLOCK_ONE(curlwp);
mutex_enter(pipe->up_dev->ud_bus->ub_lock);
}
}
if (sync && !polling) {
@ -1175,7 +1175,8 @@ usbd_dopoll(struct usbd_interface *iface)
}
/*
* XXX use this more??? ub_usepolling it touched manually all over
* This is for keyboard driver as well, which only operates in polling
* mode from the ask root, etc., prompt and from DDB.
*/
void
usbd_set_polling(struct usbd_device *dev, int on)

View File

@ -1,4 +1,4 @@
/* $NetBSD: xhci.c,v 1.98 2018/09/03 16:29:34 riastradh Exp $ */
/* $NetBSD: xhci.c,v 1.99 2018/09/16 20:21:56 mrg Exp $ */
/*
* Copyright (c) 2013 Jonathan A. Kollasch
@ -34,7 +34,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: xhci.c,v 1.98 2018/09/03 16:29:34 riastradh Exp $");
__KERNEL_RCSID(0, "$NetBSD: xhci.c,v 1.99 2018/09/16 20:21:56 mrg Exp $");
#ifdef _KERNEL_OPT
#include "opt_usb.h"
@ -3705,15 +3705,18 @@ xhci_root_intr_start(struct usbd_xfer *xfer)
{
struct xhci_softc * const sc = XHCI_XFER2SC(xfer);
const size_t bn = XHCI_XFER2BUS(xfer) == &sc->sc_bus ? 0 : 1;
const bool polling = sc->sc_bus.ub_usepolling;
XHCIHIST_FUNC(); XHCIHIST_CALLED();
if (sc->sc_dying)
return USBD_IOERROR;
mutex_enter(&sc->sc_lock);
if (!polling)
mutex_enter(&sc->sc_lock);
sc->sc_intrxfer[bn] = xfer;
mutex_exit(&sc->sc_lock);
if (!polling)
mutex_exit(&sc->sc_lock);
return USBD_IN_PROGRESS;
}
@ -3791,6 +3794,7 @@ xhci_device_ctrl_start(struct usbd_xfer *xfer)
uint32_t status;
uint32_t control;
u_int i;
const bool polling = sc->sc_bus.ub_usepolling;
XHCIHIST_FUNC(); XHCIHIST_CALLED();
DPRINTFN(12, "req: %04jx %04jx %04jx %04jx",
@ -3837,9 +3841,11 @@ xhci_device_ctrl_start(struct usbd_xfer *xfer)
xhci_trb_put(&xx->xx_trb[i++], parameter, status, control);
xfer->ux_status = USBD_IN_PROGRESS;
mutex_enter(&tr->xr_lock);
if (!polling)
mutex_enter(&tr->xr_lock);
xhci_ring_put(sc, tr, xfer, xx->xx_trb, i);
mutex_exit(&tr->xr_lock);
if (!polling)
mutex_exit(&tr->xr_lock);
xhci_db_write_4(sc, XHCI_DOORBELL(xs->xs_idx), dci);
@ -3922,6 +3928,7 @@ xhci_device_bulk_start(struct usbd_xfer *xfer)
uint32_t status;
uint32_t control;
u_int i = 0;
const bool polling = sc->sc_bus.ub_usepolling;
XHCIHIST_FUNC(); XHCIHIST_CALLED();
@ -3955,9 +3962,11 @@ xhci_device_bulk_start(struct usbd_xfer *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);

View File

@ -1,4 +1,4 @@
/* $NetBSD: dwc2.c,v 1.54 2018/08/28 08:17:10 skrll Exp $ */
/* $NetBSD: dwc2.c,v 1.55 2018/09/16 20:21:56 mrg Exp $ */
/*-
* Copyright (c) 2013 The NetBSD Foundation, Inc.
@ -30,7 +30,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: dwc2.c,v 1.54 2018/08/28 08:17:10 skrll Exp $");
__KERNEL_RCSID(0, "$NetBSD: dwc2.c,v 1.55 2018/09/16 20:21:56 mrg Exp $");
#include "opt_usb.h"
@ -625,16 +625,19 @@ Static usbd_status
dwc2_root_intr_start(struct usbd_xfer *xfer)
{
struct dwc2_softc *sc = DWC2_XFER2SC(xfer);
const bool polling = sc->sc_bus.ub_usepolling;
DPRINTF("\n");
if (sc->sc_dying)
return USBD_IOERROR;
mutex_enter(&sc->sc_lock);
if (!polling)
mutex_enter(&sc->sc_lock);
KASSERT(sc->sc_intrxfer == NULL);
sc->sc_intrxfer = xfer;
mutex_exit(&sc->sc_lock);
if (!polling)
mutex_exit(&sc->sc_lock);
return USBD_IN_PROGRESS;
}
@ -702,13 +705,16 @@ dwc2_device_ctrl_start(struct usbd_xfer *xfer)
{
struct dwc2_softc *sc = DWC2_XFER2SC(xfer);
usbd_status err;
const bool polling = sc->sc_bus.ub_usepolling;
DPRINTF("\n");
mutex_enter(&sc->sc_lock);
if (!polling)
mutex_enter(&sc->sc_lock);
xfer->ux_status = USBD_IN_PROGRESS;
err = dwc2_device_start(xfer);
mutex_exit(&sc->sc_lock);
if (!polling)
mutex_exit(&sc->sc_lock);
if (err)
return err;
@ -822,11 +828,14 @@ dwc2_device_intr_start(struct usbd_xfer *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;