summaryrefslogtreecommitdiff
path: root/sys/dev/usb
diff options
context:
space:
mode:
authorriastradh <riastradh@NetBSD.org>2022-03-28 12:42:54 +0000
committerriastradh <riastradh@NetBSD.org>2022-03-28 12:42:54 +0000
commita0bfea942da9867efd81224c080d06b7a0dbcab8 (patch)
tree1e242e780eaa6c355563018bba97c52c6e0c8349 /sys/dev/usb
parent772c15dffbd1abd4438c180b3bfb6961c50231ec (diff)
uhidev(9): Partially fix uhidev_write aborting.
In my previous change, I intended to make uhidev_stop abort any pending write -- but I forgot to initialize sc->sc_writereportid, so it never did anything. This changes the API and ABI of uhidev_write so it takes the struct uhidev pointer, rather than the struct uhidev_softc pointer; this way uhidev_write knows what the report id of the client is, so it can arrange to have uhidev_stop abort only this one. XXX Except it still doesn't actually work because we do this unlocked, ugh, so the write might complete before we abort anything. To be fixed some more in a later change. XXX kernel ABI change to uhidev_write signature, used by uhidev driver modules, requires bump
Diffstat (limited to 'sys/dev/usb')
-rw-r--r--sys/dev/usb/ucycom.c6
-rw-r--r--sys/dev/usb/uhid.c7
-rw-r--r--sys/dev/usb/uhidev.c14
-rw-r--r--sys/dev/usb/uhidev.h4
4 files changed, 18 insertions, 13 deletions
diff --git a/sys/dev/usb/ucycom.c b/sys/dev/usb/ucycom.c
index bb6046ae1a1..fde7d60e50d 100644
--- a/sys/dev/usb/ucycom.c
+++ b/sys/dev/usb/ucycom.c
@@ -1,4 +1,4 @@
-/* $NetBSD: ucycom.c,v 1.51 2020/03/14 02:35:33 christos Exp $ */
+/* $NetBSD: ucycom.c,v 1.52 2022/03/28 12:42:54 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.51 2020/03/14 02:35:33 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ucycom.c,v 1.52 2022/03/28 12:42:54 riastradh Exp $");
#ifdef _KERNEL_OPT
#include "opt_usb.h"
@@ -1105,7 +1105,7 @@ ucycom_set_status(struct ucycom_softc *sc)
memset(sc->sc_obuf, 0, sc->sc_olen);
sc->sc_obuf[0] = sc->sc_mcr;
- err = uhidev_write(sc->sc_hdev.sc_parent, sc->sc_obuf, sc->sc_olen);
+ err = uhidev_write(&sc->sc_hdev, sc->sc_obuf, sc->sc_olen);
if (err) {
DPRINTF(("ucycom_set_status: err=%d\n", err));
}
diff --git a/sys/dev/usb/uhid.c b/sys/dev/usb/uhid.c
index 839c14e78e1..02831eef8dd 100644
--- a/sys/dev/usb/uhid.c
+++ b/sys/dev/usb/uhid.c
@@ -1,4 +1,4 @@
-/* $NetBSD: uhid.c,v 1.120 2022/03/28 12:42:45 riastradh Exp $ */
+/* $NetBSD: uhid.c,v 1.121 2022/03/28 12:42:54 riastradh Exp $ */
/*
* Copyright (c) 1998, 2004, 2008, 2012 The NetBSD Foundation, Inc.
@@ -35,7 +35,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: uhid.c,v 1.120 2022/03/28 12:42:45 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: uhid.c,v 1.121 2022/03/28 12:42:54 riastradh Exp $");
#ifdef _KERNEL_OPT
#include "opt_compat_netbsd.h"
@@ -495,8 +495,7 @@ uhidwrite(dev_t dev, struct uio *uio, int flag)
#endif
if (!error) {
if (sc->sc_raw)
- err = uhidev_write(sc->sc_hdev.sc_parent, sc->sc_obuf,
- size);
+ err = uhidev_write(&sc->sc_hdev, sc->sc_obuf, size);
else
err = uhidev_set_report(&sc->sc_hdev,
UHID_OUTPUT_REPORT, sc->sc_obuf, size);
diff --git a/sys/dev/usb/uhidev.c b/sys/dev/usb/uhidev.c
index 29eb5e4f7a3..f217cd40128 100644
--- a/sys/dev/usb/uhidev.c
+++ b/sys/dev/usb/uhidev.c
@@ -1,4 +1,4 @@
-/* $NetBSD: uhidev.c,v 1.82 2022/02/09 18:09:48 jakllsch Exp $ */
+/* $NetBSD: uhidev.c,v 1.83 2022/03/28 12:42:54 riastradh Exp $ */
/*
* Copyright (c) 2001, 2012 The NetBSD Foundation, Inc.
@@ -35,7 +35,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: uhidev.c,v 1.82 2022/02/09 18:09:48 jakllsch Exp $");
+__KERNEL_RCSID(0, "$NetBSD: uhidev.c,v 1.83 2022/03/28 12:42:54 riastradh Exp $");
#ifdef _KERNEL_OPT
#include "opt_usb.h"
@@ -909,7 +909,7 @@ uhidev_stop(struct uhidev *scd)
abort = true;
mutex_exit(&sc->sc_lock);
- if (abort && sc->sc_opipe)
+ if (abort && sc->sc_opipe) /* XXX sc_opipe might go away */
usbd_abort_pipe(sc->sc_opipe);
}
@@ -969,8 +969,9 @@ uhidev_get_report(struct uhidev *scd, int type, void *data, int len)
}
usbd_status
-uhidev_write(struct uhidev_softc *sc, void *data, int len)
+uhidev_write(struct uhidev *scd, void *data, int len)
{
+ struct uhidev_softc *sc = scd->sc_parent;
usbd_status err;
DPRINTF(("uhidev_write: data=%p, len=%d\n", data, len));
@@ -993,6 +994,7 @@ uhidev_write(struct uhidev_softc *sc, void *data, int len)
}
}
sc->sc_writelock = curlwp;
+ sc->sc_writereportid = scd->sc_report_id;
mutex_exit(&sc->sc_lock);
#ifdef UHIDEV_DEBUG
@@ -1014,6 +1016,10 @@ uhidev_write(struct uhidev_softc *sc, void *data, int len)
KASSERT(sc->sc_refcnt);
KASSERTMSG(sc->sc_writelock == curlwp, "%s: migrated from %p to %p",
device_xname(sc->sc_dev), curlwp, sc->sc_writelock);
+ KASSERTMSG(sc->sc_writereportid == scd->sc_report_id,
+ "%s: changed write report ids from %d to %d",
+ device_xname(sc->sc_dev), scd->sc_report_id, sc->sc_writereportid);
+ sc->sc_writereportid = -1;
sc->sc_writelock = NULL;
cv_broadcast(&sc->sc_cv);
out: mutex_exit(&sc->sc_lock);
diff --git a/sys/dev/usb/uhidev.h b/sys/dev/usb/uhidev.h
index 83c0a357744..2c6b6ae1e40 100644
--- a/sys/dev/usb/uhidev.h
+++ b/sys/dev/usb/uhidev.h
@@ -1,4 +1,4 @@
-/* $NetBSD: uhidev.h,v 1.21 2020/11/29 22:54:51 riastradh Exp $ */
+/* $NetBSD: uhidev.h,v 1.22 2022/03/28 12:42:54 riastradh Exp $ */
/*
* Copyright (c) 2001 The NetBSD Foundation, Inc.
@@ -97,7 +97,7 @@ void uhidev_stop(struct uhidev *);
void uhidev_close(struct uhidev *);
usbd_status uhidev_set_report(struct uhidev *, int, void *, int);
usbd_status uhidev_get_report(struct uhidev *, int, void *, int);
-usbd_status uhidev_write(struct uhidev_softc *, void *, int);
+usbd_status uhidev_write(struct uhidev *, void *, int);
#define UHIDEV_OSIZE 64