Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/dev/usb ucycom(4): Defer uhidev_write_async to taskq.
details: https://anonhg.NetBSD.org/src/rev/d97b0146c98c
branches: trunk
changeset: 364539:d97b0146c98c
user: riastradh <riastradh%NetBSD.org@localhost>
date: Mon Mar 28 12:43:30 2022 +0000
description:
ucycom(4): Defer uhidev_write_async to taskq.
Can't submit USB transfers while holding tty_lock, a spin lock.
diffstat:
sys/dev/usb/ucycom.c | 34 ++++++++++++++++++++++++++++------
1 files changed, 28 insertions(+), 6 deletions(-)
diffs (106 lines):
diff -r f2e4ee427d15 -r d97b0146c98c sys/dev/usb/ucycom.c
--- a/sys/dev/usb/ucycom.c Mon Mar 28 12:43:22 2022 +0000
+++ b/sys/dev/usb/ucycom.c Mon Mar 28 12:43:30 2022 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: ucycom.c,v 1.53 2022/03/28 12:43:03 riastradh Exp $ */
+/* $NetBSD: ucycom.c,v 1.54 2022/03/28 12:43:30 riastradh Exp $ */
/*
* Copyright (c) 2005 The NetBSD Foundation, Inc.
@@ -38,7 +38,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ucycom.c,v 1.53 2022/03/28 12:43:03 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ucycom.c,v 1.54 2022/03/28 12:43:30 riastradh Exp $");
#ifdef _KERNEL_OPT
#include "opt_usb.h"
@@ -118,7 +118,9 @@
struct ucycom_softc {
struct uhidev sc_hdev;
+ struct usbd_device *sc_udev;
+ struct usb_task sc_task;
struct tty *sc_tty;
enum {
@@ -172,6 +174,7 @@
Static int ucycomparam(struct tty *, struct termios *);
Static void ucycomstart(struct tty *);
+Static void ucycomstarttask(void *);
Static void ucycomwritecb(struct usbd_xfer *, void *, usbd_status);
Static void ucycom_intr(struct uhidev *, void *, u_int);
Static int ucycom_configure(struct ucycom_softc *, uint32_t, uint8_t);
@@ -223,6 +226,7 @@
sc->sc_hdev.sc_intr = ucycom_intr;
sc->sc_hdev.sc_parent = uha->parent;
sc->sc_hdev.sc_report_id = uha->reportid;
+ sc->sc_udev = uha->uiaa->uiaa_device;
sc->sc_init_state = UCYCOM_INIT_NONE;
uhidev_get_report_desc(uha->parent, &desc, &size);
@@ -237,6 +241,9 @@
sc->sc_msr = sc->sc_mcr = 0;
+ /* not MP-safe */
+ usb_init_task(&sc->sc_task, ucycomstarttask, sc, 0);
+
/* set up tty */
sc->sc_tty = tty_alloc();
sc->sc_tty->t_sc = sc;
@@ -287,6 +294,8 @@
vdevgone(maj, mn | UCYCOMDIALOUT_MASK, mn | UCYCOMDIALOUT_MASK, VCHR);
vdevgone(maj, mn | UCYCOMCALLUNIT_MASK, mn | UCYCOMCALLUNIT_MASK, VCHR);
+ usb_rem_task_wait(sc->sc_udev, &sc->sc_task, USB_TASKQ_DRIVER, NULL);
+
/* Detach and free the tty. */
if (tp != NULL) {
DPRINTF(("ucycom_detach: tty_detach %p\n", tp));
@@ -482,6 +491,8 @@
u_char *data;
int cnt, len, s;
+ KASSERT(mutex_owned(&tty_lock));
+
if (sc->sc_dying)
return;
@@ -592,6 +603,19 @@
}
#endif
DPRINTFN(4,("ucycomstart: %d chars\n", len));
+ usb_add_task(sc->sc_udev, &sc->sc_task, USB_TASKQ_DRIVER);
+ return;
+
+out:
+ splx(s);
+}
+
+Static void
+ucycomstarttask(void *cookie)
+{
+ struct ucycom_softc *sc = cookie;
+ usbd_status err;
+
/* What can we do on error? */
err = uhidev_write_async(&sc->sc_hdev, sc->sc_obuf, sc->sc_olen, 0,
USBD_NO_TIMEOUT, ucycomwritecb, sc);
@@ -599,11 +623,9 @@
#ifdef UCYCOM_DEBUG
if (err != USBD_IN_PROGRESS)
DPRINTF(("ucycomstart: err=%s\n", usbd_errstr(err)));
+#else
+ __USE(err);
#endif
- return;
-
-out:
- splx(s);
}
Static void
Home |
Main Index |
Thread Index |
Old Index