diff options
| author | riastradh <riastradh@NetBSD.org> | 2021-06-13 14:48:10 +0000 |
|---|---|---|
| committer | riastradh <riastradh@NetBSD.org> | 2021-06-13 14:48:10 +0000 |
| commit | 80dbb9305f86bc06b5d7b574492b8569a7422ce0 (patch) | |
| tree | 53b25e5162b6e361d9de53655ab17f75af7ba8d9 /sys/dev | |
| parent | 861fb2a61e6fb22d04beb514d90c95a1edbb72b7 (diff) | |
usb(4): Bus exploration is single-threaded -- assert it so.
New usb_in_event_thread(dev) returns true if dev is a USB device --
that is, a device with a usbN ancestor -- and the current thread is
the USB event thread.
(Kinda kludgey to pass around the device_t instead of, say, struct
usbd_bus, but I don't see a good way to get to the usbN device_t or
struct usb_softc from there.)
Diffstat (limited to 'sys/dev')
| -rw-r--r-- | sys/dev/usb/uhub.c | 12 | ||||
| -rw-r--r-- | sys/dev/usb/usb.c | 26 | ||||
| -rw-r--r-- | sys/dev/usb/usb_subr.c | 15 | ||||
| -rw-r--r-- | sys/dev/usb/usbdi.h | 4 |
4 files changed, 42 insertions, 15 deletions
diff --git a/sys/dev/usb/uhub.c b/sys/dev/usb/uhub.c index 6f0ac8c0998..628a6b1816d 100644 --- a/sys/dev/usb/uhub.c +++ b/sys/dev/usb/uhub.c @@ -1,4 +1,4 @@ -/* $NetBSD: uhub.c,v 1.152 2021/06/13 14:46:07 riastradh Exp $ */ +/* $NetBSD: uhub.c,v 1.153 2021/06/13 14:48:10 riastradh 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.152 2021/06/13 14:46:07 riastradh Exp $"); +__KERNEL_RCSID(0, "$NetBSD: uhub.c,v 1.153 2021/06/13 14:48:10 riastradh Exp $"); #ifdef _KERNEL_OPT #include "opt_usb.h" @@ -269,10 +269,12 @@ uhub_attach(device_t parent, device_t self, void *aux) usb_endpoint_descriptor_t *ed; struct usbd_tt *tts = NULL; - config_pending_incr(self); - UHUBHIST_FUNC(); UHUBHIST_CALLED(); + KASSERT(usb_in_event_thread(parent)); + + config_pending_incr(self); + sc->sc_dev = self; sc->sc_hub = dev; sc->sc_proto = uaa->uaa_proto; @@ -498,7 +500,7 @@ uhub_explore(struct usbd_device *dev) device_unit(sc->sc_dev), (uintptr_t)dev, dev->ud_addr, dev->ud_speed); - KASSERT(KERNEL_LOCKED_P()); + KASSERT(usb_in_event_thread(sc->sc_dev)); if (!sc->sc_running) return USBD_NOT_STARTED; diff --git a/sys/dev/usb/usb.c b/sys/dev/usb/usb.c index 368d72fc9f3..8be68ad747b 100644 --- a/sys/dev/usb/usb.c +++ b/sys/dev/usb/usb.c @@ -1,4 +1,4 @@ -/* $NetBSD: usb.c,v 1.195 2021/06/12 12:13:10 riastradh Exp $ */ +/* $NetBSD: usb.c,v 1.196 2021/06/13 14:48:10 riastradh 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.195 2021/06/12 12:13:10 riastradh Exp $"); +__KERNEL_RCSID(0, "$NetBSD: usb.c,v 1.196 2021/06/13 14:48:10 riastradh Exp $"); #ifdef _KERNEL_OPT #include "opt_usb.h" @@ -142,6 +142,7 @@ struct usb_softc { struct usbd_port sc_port; /* dummy port for root hub */ struct lwp *sc_event_thread; + struct lwp *sc_attach_thread; char sc_dying; bool sc_pmf_registered; @@ -483,8 +484,10 @@ usb_doattach(device_t self) ue->u.ue_ctrlr.ue_bus = device_unit(self); usb_add_event(USB_EVENT_CTRLR_ATTACH, ue); + sc->sc_attach_thread = curlwp; err = usbd_new_device(self, sc->sc_bus, 0, speed, 0, &sc->sc_port); + sc->sc_attach_thread = NULL; if (!err) { dev = sc->sc_port.up_dev; if (dev->ud_hub == NULL) { @@ -529,6 +532,25 @@ usb_create_event_thread(device_t self) } } +bool +usb_in_event_thread(device_t dev) +{ + struct usb_softc *sc; + + if (cold) + return true; + + for (; dev; dev = device_parent(dev)) { + if (device_is_a(dev, "usb")) + break; + } + if (dev == NULL) + return false; + sc = device_private(dev); + + return curlwp == sc->sc_event_thread || curlwp == sc->sc_attach_thread; +} + /* * Add a task to be performed by the task thread. This function can be * called from any context and the task will be executed in a process diff --git a/sys/dev/usb/usb_subr.c b/sys/dev/usb/usb_subr.c index 4d1eec36d18..1e14cc7d3a6 100644 --- a/sys/dev/usb/usb_subr.c +++ b/sys/dev/usb/usb_subr.c @@ -1,4 +1,4 @@ -/* $NetBSD: usb_subr.c,v 1.264 2021/06/13 09:12:24 mlelstv Exp $ */ +/* $NetBSD: usb_subr.c,v 1.265 2021/06/13 14:48:10 riastradh 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.264 2021/06/13 09:12:24 mlelstv Exp $"); +__KERNEL_RCSID(0, "$NetBSD: usb_subr.c,v 1.265 2021/06/13 14:48:10 riastradh Exp $"); #ifdef _KERNEL_OPT #include "opt_compat_netbsd.h" @@ -1097,6 +1097,8 @@ usbd_attachwholedevice(device_t parent, struct usbd_device *dev, int port, device_t dv; int dlocs[USBDEVIFCF_NLOCS]; + KASSERT(usb_in_event_thread(parent)); + uaa.uaa_device = dev; uaa.uaa_usegeneric = usegeneric; uaa.uaa_port = port; @@ -1147,8 +1149,7 @@ usbd_attachinterfaces(device_t parent, struct usbd_device *dev, int i, j, loc; device_t dv; - /* Needed for access to dev->ud_subdevs. */ - KASSERT(KERNEL_LOCKED_P()); + KASSERT(usb_in_event_thread(parent)); nifaces = dev->ud_cdesc->bNumInterface; ifaces = kmem_zalloc(nifaces * sizeof(*ifaces), KM_SLEEP); @@ -1240,7 +1241,7 @@ usbd_probe_and_attach(device_t parent, struct usbd_device *dev, int confi, nifaces; usbd_status err; - KASSERT(KERNEL_LOCKED_P()); + KASSERT(usb_in_event_thread(parent)); /* First try with device specific drivers. */ err = usbd_attachwholedevice(parent, dev, port, 0); @@ -1310,7 +1311,7 @@ usbd_reattach_device(device_t parent, struct usbd_device *dev, USBHIST_CALLARGS(usbdebug, "uhub%jd port=%jd", device_unit(parent), port, 0, 0); - KASSERT(KERNEL_LOCKED_P()); + KASSERT(usb_in_event_thread(parent)); if (locators != NULL) { loc = locators[USBIFIFCF_PORT]; @@ -1370,7 +1371,7 @@ usbd_new_device(device_t parent, struct usbd_bus *bus, int depth, int speed, int i; int p; - KASSERT(KERNEL_LOCKED_P()); + KASSERT(usb_in_event_thread(parent)); if (bus->ub_methods->ubm_newdev != NULL) return (bus->ub_methods->ubm_newdev)(parent, bus, depth, speed, diff --git a/sys/dev/usb/usbdi.h b/sys/dev/usb/usbdi.h index 4322d75bffd..71d61eca539 100644 --- a/sys/dev/usb/usbdi.h +++ b/sys/dev/usb/usbdi.h @@ -1,4 +1,4 @@ -/* $NetBSD: usbdi.h,v 1.102 2020/02/16 09:40:35 maxv Exp $ */ +/* $NetBSD: usbdi.h,v 1.103 2021/06/13 14:48:10 riastradh Exp $ */ /* $FreeBSD: src/sys/dev/usb/usbdi.h,v 1.18 1999/11/17 22:33:49 n_hibma Exp $ */ /* @@ -222,6 +222,8 @@ bool usb_rem_task_wait(struct usbd_device *, struct usb_task *, int, bool usb_task_pending(struct usbd_device *, struct usb_task *); #define usb_init_task(t, f, a, fl) ((t)->fun = (f), (t)->arg = (a), (t)->queue = USB_NUM_TASKQS, (t)->flags = (fl)) +bool usb_in_event_thread(device_t); + struct usb_devno { uint16_t ud_vendor; uint16_t ud_product; |
