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:
parent
06bbe38b6d
commit
b627726203
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue