CVS commit: src/sys/dev/pci

2022-03-28 Thread Shoichi YAMAGUCHI
Module Name:src
Committed By:   yamaguchi
Date:   Tue Mar 29 01:57:51 UTC 2022

Modified Files:
src/sys/dev/pci: if_vioif.c

Log Message:
vioif(4): Added a comment about stopping packet processing


To generate a diff of this commit:
cvs rdiff -u -r1.75 -r1.76 src/sys/dev/pci/if_vioif.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/dev/pci/if_vioif.c
diff -u src/sys/dev/pci/if_vioif.c:1.75 src/sys/dev/pci/if_vioif.c:1.76
--- src/sys/dev/pci/if_vioif.c:1.75	Thu Mar 24 08:02:21 2022
+++ src/sys/dev/pci/if_vioif.c	Tue Mar 29 01:57:51 2022
@@ -1,4 +1,4 @@
-/*	$NetBSD: if_vioif.c,v 1.75 2022/03/24 08:02:21 yamaguchi Exp $	*/
+/*	$NetBSD: if_vioif.c,v 1.76 2022/03/29 01:57:51 yamaguchi Exp $	*/
 
 /*
  * Copyright (c) 2020 The NetBSD Foundation, Inc.
@@ -27,7 +27,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: if_vioif.c,v 1.75 2022/03/24 08:02:21 yamaguchi Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_vioif.c,v 1.76 2022/03/29 01:57:51 yamaguchi Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_net_mpsafe.h"
@@ -1211,6 +1211,34 @@ vioif_init(struct ifnet *ifp)
 }
 
 static void
+vioif_stop_rendezvous(struct vioif_softc *sc)
+{
+	struct vioif_txqueue *txq;
+	struct vioif_rxqueue *rxq;
+	int i;
+
+	/*
+	 * stop all packet processing:
+	 * 1. acquire a lock for queue to wait
+	 *for finish of interrupt handler
+	 * 2. stop workqueue for packet processing
+	 */
+
+	for (i =0; i < sc->sc_act_nvq_pairs; i++) {
+		txq = >sc_txq[i];
+		rxq = >sc_rxq[i];
+
+		mutex_enter(rxq->rxq_lock);
+		mutex_exit(rxq->rxq_lock);
+		vioif_work_wait(sc->sc_txrx_workqueue, >rxq_work);
+
+		mutex_enter(txq->txq_lock);
+		mutex_exit(txq->txq_lock);
+		vioif_work_wait(sc->sc_txrx_workqueue, >txq_work);
+	}
+}
+
+static void
 vioif_stop(struct ifnet *ifp, int disable)
 {
 	struct vioif_softc *sc = ifp->if_softc;
@@ -1243,19 +1271,7 @@ vioif_stop(struct ifnet *ifp, int disabl
 	/* only way to stop I/O and DMA is resetting... */
 	virtio_reset(vsc);
 
-	/* rendezvous for finish of handlers */
-	for (i = 0; i < sc->sc_act_nvq_pairs; i++) {
-		txq = >sc_txq[i];
-		rxq = >sc_rxq[i];
-
-		mutex_enter(rxq->rxq_lock);
-		mutex_exit(rxq->rxq_lock);
-		vioif_work_wait(sc->sc_txrx_workqueue, >rxq_work);
-
-		mutex_enter(txq->txq_lock);
-		mutex_exit(txq->txq_lock);
-		vioif_work_wait(sc->sc_txrx_workqueue, >txq_work);
-	}
+	vioif_stop_rendezvous(sc);
 
 	for (i = 0; i < sc->sc_act_nvq_pairs; i++) {
 		vioif_rx_queue_clear(>sc_rxq[i]);



CVS commit: src/sys/dev/pci

2022-03-28 Thread Shoichi YAMAGUCHI
Module Name:src
Committed By:   yamaguchi
Date:   Tue Mar 29 01:57:51 UTC 2022

Modified Files:
src/sys/dev/pci: if_vioif.c

Log Message:
vioif(4): Added a comment about stopping packet processing


To generate a diff of this commit:
cvs rdiff -u -r1.75 -r1.76 src/sys/dev/pci/if_vioif.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.



Re: null-terminated vs. nul-terminated

2022-03-28 Thread David H. Gutteridge

On 2022-03-26 11:57, Roland Illig wrote:

The term "null-terminated string" is quite common when talking about C.
In contrast, the word "nul" in "nul-terminated" always reminds me of
the character abbreviation in ASCII, which has a narrower scope than C.
I prefer to keep "null-terminated" here.


Hi all,

While I don't really want to prolong this debate, as the committer who
triggered this discussion, I felt I should respond, in part to explain
why I made my choice (which I reverted, though I don't agree "null-
terminated" is more correct). TL;DR: there is no consistency here in
NetBSD's code base in man pages or comments in source code, and no
applicable style guide I know of, but "NUL-terminated" is the most
common form found. It seems there was also an attempt at standardization
in man pages made in 2005-2006, settling on "nul-terminated".

I was taught (several decades ago) that the short form for the null
byte or null character was NUL in ANSI C parlance (not just ASCII), and
that "null-terminated" was incorrect as it's ambiguous. If someone were
to say "null-byte-terminated", "null-character-terminated", or for the
other context "null-pointer-terminated", that would be fine.
"NUL-terminated" was the unambiguous contraction. (As others have
pointed out, a cleverer way to avoid this debate would be to use
entirely different terms.)

The most common form found in man pages at present installed in NetBSD
-current is actually "NUL-terminated", by a significant margin. That's
in part because many of those are from third-party projects, e.g.,
OpenBSD and OpenSSL, which standardized on that form. The next most
common is "null-terminated", then (following slightly behind) "nul-
terminated", then (much less commonly) "NULL-terminated" (which seems
quite incorrect to me). I didn't look as closely at comments, but a
similar pattern emerged, with "NUL-terminated" the most common under
/usr/include, for example (in part due to the origins of some upstream
code). (It's not my intent here to quote or debate exact statistics, so
I haven't provided any. I'm sharing my perception of practice, rightly
or wrongly.)

"nul-terminated" and "null-terminated" seemed more common in man pages
that originated from historical BSD sources, so, lacking any style
guide, I inferred the lowercase "nul" was more "correct" as "BSD style"
(excepting modern OpenBSD), even though that looks a bit odd to me. I
then examined where "nul-terminated" came from, and found these bulk
commits, which imply a standard.

date: 2005-01-02 18:38:04 +;  author: wiz;
Mark up NULL, and replace null by nul where appropriate.

date: 2006-10-16 08:48:45 +;  author: wiz;
nul/null/NULL cleanup:
when talking about characters/bytes, use "nul" and "nul-terminate"
when talking about pointers, use "null pointer" or ".Dv NULL"

So that seemed to me the established style.

Regards,

Dave


CVS commit: src/distrib/sets/lists

2022-03-28 Thread Christos Zoulas
Module Name:src
Committed By:   christos
Date:   Mon Mar 28 20:52:17 UTC 2022

Modified Files:
src/distrib/sets/lists/debug: mi
src/distrib/sets/lists/tests: mi

Log Message:
Add t_link


To generate a diff of this commit:
cvs rdiff -u -r1.373 -r1.374 src/distrib/sets/lists/debug/mi
cvs rdiff -u -r1.1188 -r1.1189 src/distrib/sets/lists/tests/mi

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/distrib/sets/lists/debug/mi
diff -u src/distrib/sets/lists/debug/mi:1.373 src/distrib/sets/lists/debug/mi:1.374
--- src/distrib/sets/lists/debug/mi:1.373	Wed Feb 23 22:35:33 2022
+++ src/distrib/sets/lists/debug/mi	Mon Mar 28 16:52:17 2022
@@ -1,4 +1,4 @@
-# $NetBSD: mi,v 1.373 2022/02/24 03:35:33 mrg Exp $
+# $NetBSD: mi,v 1.374 2022/03/28 20:52:17 christos Exp $
 ./etc/mtree/set.debug   comp-sys-root
 ./usr/lib	comp-sys-usr		compatdir
 ./usr/lib/i18n/libBIG5_g.a			comp-c-debuglib		debuglib,compatfile
@@ -1712,6 +1712,7 @@
 ./usr/libdata/debug/usr/tests/fs/union/t_pr.debug			tests-fs-debug		debug,atf,rump
 ./usr/libdata/debug/usr/tests/fs/vfs/t_full.debug			tests-fs-debug		debug,atf,rump
 ./usr/libdata/debug/usr/tests/fs/vfs/t_io.debug			tests-fs-debug		debug,atf,rump
+./usr/libdata/debug/usr/tests/fs/vfs/t_link.debug			tests-fs-debug		debug,atf,rump
 ./usr/libdata/debug/usr/tests/fs/vfs/t_mtime_otrunc.debug		tests-fs-debug		debug,atf,rump
 ./usr/libdata/debug/usr/tests/fs/vfs/t_mtime_write.debug		tests-fs-debug		debug,atf,rump
 ./usr/libdata/debug/usr/tests/fs/vfs/t_renamerace.debug			tests-fs-debug		debug,atf,rump

Index: src/distrib/sets/lists/tests/mi
diff -u src/distrib/sets/lists/tests/mi:1.1188 src/distrib/sets/lists/tests/mi:1.1189
--- src/distrib/sets/lists/tests/mi:1.1188	Sat Feb 12 08:17:57 2022
+++ src/distrib/sets/lists/tests/mi	Mon Mar 28 16:52:17 2022
@@ -1,4 +1,4 @@
-# $NetBSD: mi,v 1.1188 2022/02/12 13:17:57 rillig Exp $
+# $NetBSD: mi,v 1.1189 2022/03/28 20:52:17 christos Exp $
 #
 # Note: don't delete entries from here - mark them as "obsolete" instead.
 #
@@ -1598,6 +1598,7 @@
 ./usr/tests/fs/vfs/Kyuafiletests-fs-tests		atf,rump,kyua
 ./usr/tests/fs/vfs/t_fulltests-fs-tests		atf,rump
 ./usr/tests/fs/vfs/t_io	tests-fs-tests		atf,rump
+./usr/tests/fs/vfs/t_linktests-fs-tests		atf,rump
 ./usr/tests/fs/vfs/t_mtime_otrunc			tests-fs-tests		atf,rump
 ./usr/tests/fs/vfs/t_mtime_write			tests-fs-tests		atf,rump
 ./usr/tests/fs/vfs/t_renameracetests-fs-tests		atf,rump



CVS commit: src/distrib/sets/lists

2022-03-28 Thread Christos Zoulas
Module Name:src
Committed By:   christos
Date:   Mon Mar 28 20:52:17 UTC 2022

Modified Files:
src/distrib/sets/lists/debug: mi
src/distrib/sets/lists/tests: mi

Log Message:
Add t_link


To generate a diff of this commit:
cvs rdiff -u -r1.373 -r1.374 src/distrib/sets/lists/debug/mi
cvs rdiff -u -r1.1188 -r1.1189 src/distrib/sets/lists/tests/mi

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.



CVS commit: src/tests/fs/vfs

2022-03-28 Thread Christos Zoulas
Module Name:src
Committed By:   christos
Date:   Mon Mar 28 20:51:04 UTC 2022

Modified Files:
src/tests/fs/vfs: Makefile
Added Files:
src/tests/fs/vfs: t_link.c

Log Message:
Add a test for hardlink sysctl limiting.


To generate a diff of this commit:
cvs rdiff -u -r1.27 -r1.28 src/tests/fs/vfs/Makefile
cvs rdiff -u -r0 -r1.1 src/tests/fs/vfs/t_link.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/tests/fs/vfs/Makefile
diff -u src/tests/fs/vfs/Makefile:1.27 src/tests/fs/vfs/Makefile:1.28
--- src/tests/fs/vfs/Makefile:1.27	Mon Mar  2 06:09:13 2020
+++ src/tests/fs/vfs/Makefile	Mon Mar 28 16:51:04 2022
@@ -1,4 +1,4 @@
-#	$NetBSD: Makefile,v 1.27 2020/03/02 11:09:13 christos Exp $
+#	$NetBSD: Makefile,v 1.28 2022/03/28 20:51:04 christos Exp $
 #
 
 .include 
@@ -6,6 +6,7 @@
 TESTSDIR=	${TESTSBASE}/fs/vfs
 WARNS=		4
 
+TESTS_C+=	t_link
 TESTS_C+=	t_full
 TESTS_C+=	t_io
 TESTS_C+=	t_renamerace
@@ -19,6 +20,12 @@ TESTS_C+=	t_mtime_write
 TESTS_C+=	t_vfsops
 TESTS_C+=	t_vnops
 
+
+.PATH: ${NETBSDSRCDIR}/lib/libc/gen
+CPPFLAGS.sysctlbyname.c += -DRUMP_ACTION
+CPPFLAGS.sysctlgetmibinfo.c += -DRUMP_ACTION
+SRCS.t_link+= sysctlbyname.c sysctlgetmibinfo.c t_link.c
+
 LDADD+=-lrumpnet_shmif -lrumpnet -lrumpnet_net -lrumpnet_netinet# TCP/IP
 LDADD+=-lrumpfs_nfs		# NFS
 LDADD+=-lrumpfs_ext2fs		# ext2fs

Added files:

Index: src/tests/fs/vfs/t_link.c
diff -u /dev/null src/tests/fs/vfs/t_link.c:1.1
--- /dev/null	Mon Mar 28 16:51:05 2022
+++ src/tests/fs/vfs/t_link.c	Mon Mar 28 16:51:04 2022
@@ -0,0 +1,150 @@
+/*	$NetBSD: t_link.c,v 1.1 2022/03/28 20:51:04 christos Exp $	*/
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *notice, this list of conditions and the following disclaimer in the
+ *documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+
+#include "../common/h_fsmacros.h"
+#include "h_macros.h"
+
+#define USES_OWNER			 \
+	if (FSTYPE_MSDOS(tc))		 \
+	atf_tc_skip("owner not supported by file system")
+
+
+static void
+hardlink(const atf_tc_t *tc, const char *mp, uid_t u1, uid_t u2,
+bool sysctl, bool allowed)
+{
+	const char name[] = "foo";
+	const char link[] = "bar";
+	int one = 1, fd;
+
+	USES_OWNER;
+
+	FSTEST_ENTER();
+
+	if (sysctl) {
+		if (sysctlbyname(
+		"security.models.extensions.hardlink_check_uid",
+		NULL, 0, , sizeof(one)) == -1)
+			atf_tc_fail_errno("sysctlbyname");
+	}
+
+	rump_pub_lwproc_rfork(RUMP_RFCFDG);
+	if (rump_sys_chmod(".", 0777) == -1)
+		atf_tc_fail_errno("chmod");
+	if (rump_sys_setuid(u1) == -1)
+		atf_tc_fail_errno("setuid");
+if ((fd = rump_sys_open(name, O_RDWR|O_CREAT, 0666)) == -1)
+		atf_tc_fail_errno("open");
+	if (rump_sys_close(fd) == -1)
+		atf_tc_fail_errno("close");
+	rump_pub_lwproc_releaselwp();
+
+	rump_pub_lwproc_rfork(RUMP_RFCFDG);
+	if (rump_sys_setuid(u2) == -1)
+		atf_tc_fail_errno("setuid");
+if (rump_sys_link(name, link) == -1) {
+		if (allowed)
+			atf_tc_fail_errno("link");
+	} else {
+		if (!allowed)
+			atf_tc_fail("failed to disallow hard link");
+	}
+	rump_pub_lwproc_releaselwp();
+
+	FSTEST_EXIT();
+}
+
+
+static void
+hardlink_sameuser(const atf_tc_t *tc, const char *mp)
+{
+	hardlink(tc, mp, 1, 1, false, true);
+}
+
+static void
+hardlink_sameuser_sysctl(const atf_tc_t *tc, const char *mp)
+{
+	hardlink(tc, mp, 1, 1, true, true);
+}
+
+static void
+hardlink_otheruser(const atf_tc_t *tc, const char *mp)
+{
+	hardlink(tc, mp, 1, 2, false, true);
+}
+
+static void
+hardlink_otheruser_sysctl(const atf_tc_t *tc, const char *mp)
+{
+	hardlink(tc, 

CVS commit: src/tests/fs/vfs

2022-03-28 Thread Christos Zoulas
Module Name:src
Committed By:   christos
Date:   Mon Mar 28 20:51:04 UTC 2022

Modified Files:
src/tests/fs/vfs: Makefile
Added Files:
src/tests/fs/vfs: t_link.c

Log Message:
Add a test for hardlink sysctl limiting.


To generate a diff of this commit:
cvs rdiff -u -r1.27 -r1.28 src/tests/fs/vfs/Makefile
cvs rdiff -u -r0 -r1.1 src/tests/fs/vfs/t_link.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.



CVS commit: src/sys/rump/librump/rumpkern

2022-03-28 Thread Christos Zoulas
Module Name:src
Committed By:   christos
Date:   Mon Mar 28 20:49:52 UTC 2022

Modified Files:
src/sys/rump/librump/rumpkern: Makefile.rumpkern

Log Message:
include the extensions secmodel


To generate a diff of this commit:
cvs rdiff -u -r1.187 -r1.188 src/sys/rump/librump/rumpkern/Makefile.rumpkern

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.



CVS commit: src/sys/rump/librump/rumpkern

2022-03-28 Thread Christos Zoulas
Module Name:src
Committed By:   christos
Date:   Mon Mar 28 20:49:52 UTC 2022

Modified Files:
src/sys/rump/librump/rumpkern: Makefile.rumpkern

Log Message:
include the extensions secmodel


To generate a diff of this commit:
cvs rdiff -u -r1.187 -r1.188 src/sys/rump/librump/rumpkern/Makefile.rumpkern

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/rump/librump/rumpkern/Makefile.rumpkern
diff -u src/sys/rump/librump/rumpkern/Makefile.rumpkern:1.187 src/sys/rump/librump/rumpkern/Makefile.rumpkern:1.188
--- src/sys/rump/librump/rumpkern/Makefile.rumpkern:1.187	Thu Aug 27 10:11:57 2020
+++ src/sys/rump/librump/rumpkern/Makefile.rumpkern	Mon Mar 28 16:49:52 2022
@@ -1,4 +1,4 @@
-#	$NetBSD: Makefile.rumpkern,v 1.187 2020/08/27 14:11:57 riastradh Exp $
+#	$NetBSD: Makefile.rumpkern,v 1.188 2022/03/28 20:49:52 christos Exp $
 #
 
 IOCONFDIR:=	${.PARSEDIR}
@@ -20,6 +20,7 @@ MAN=		rump.3 rump_lwproc.3
 	${RUMPTOP}/../crypto/cprng_fast\
 	${RUMPTOP}/../crypto/nist_hash_drbg			\
 	${RUMPTOP}/../secmodel	\
+	${RUMPTOP}/../secmodel/extensions			\
 	${RUMPTOP}/../secmodel/suser\
 	${RUMPTOP}/../compat/common
 
@@ -145,6 +146,7 @@ SRCS+=	uvm_page_array.c uvm_page_status.
 # 4.4BSD secmodel.  selection is hardcoded for now
 SRCS+=	secmodel.c
 SRCS+=	secmodel_suser.c
+SRCS+=	secmodel_extensions.c
 
 # the funny bit.  this doesn't really belong here, but helps with the
 # needs of kern_descrip.c.  And since it's a fully dynamic interface,



CVS commit: src/sys/rump/librump/rumpkern

2022-03-28 Thread Christos Zoulas
Module Name:src
Committed By:   christos
Date:   Mon Mar 28 20:49:32 UTC 2022

Modified Files:
src/sys/rump/librump/rumpkern: rump.c

Log Message:
no need to include suser; it gets autoloaded as a module.


To generate a diff of this commit:
cvs rdiff -u -r1.354 -r1.355 src/sys/rump/librump/rumpkern/rump.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.



CVS commit: src/sys/rump/librump/rumpkern

2022-03-28 Thread Christos Zoulas
Module Name:src
Committed By:   christos
Date:   Mon Mar 28 20:49:32 UTC 2022

Modified Files:
src/sys/rump/librump/rumpkern: rump.c

Log Message:
no need to include suser; it gets autoloaded as a module.


To generate a diff of this commit:
cvs rdiff -u -r1.354 -r1.355 src/sys/rump/librump/rumpkern/rump.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/rump/librump/rumpkern/rump.c
diff -u src/sys/rump/librump/rumpkern/rump.c:1.354 src/sys/rump/librump/rumpkern/rump.c:1.355
--- src/sys/rump/librump/rumpkern/rump.c:1.354	Mon Mar 28 08:38:59 2022
+++ src/sys/rump/librump/rumpkern/rump.c	Mon Mar 28 16:49:32 2022
@@ -1,4 +1,4 @@
-/*	$NetBSD: rump.c,v 1.354 2022/03/28 12:38:59 riastradh Exp $	*/
+/*	$NetBSD: rump.c,v 1.355 2022/03/28 20:49:32 christos Exp $	*/
 
 /*
  * Copyright (c) 2007-2011 Antti Kantee.  All Rights Reserved.
@@ -26,7 +26,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: rump.c,v 1.354 2022/03/28 12:38:59 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: rump.c,v 1.355 2022/03/28 20:49:32 christos Exp $");
 
 #include 
 #define ELFSIZE ARCH_ELFSIZE
@@ -85,8 +85,6 @@ __KERNEL_RCSID(0, "$NetBSD: rump.c,v 1.3
 
 #include 
 
-#include 
-
 #include 
 
 #include 



CVS commit: src/games/cgram

2022-03-28 Thread Roland Illig
Module Name:src
Committed By:   rillig
Date:   Mon Mar 28 20:00:29 UTC 2022

Modified Files:
src/games/cgram: cgram.c

Log Message:
cgram: define a word as a sequence of letters, not non-whitespace

Pressing Tab or Shift+Tab now advances to the next letter that could be
substituted, it no longer stops at punctuation or digits.  Since only
letters are scrambled, these are most interesting to be edited.


To generate a diff of this commit:
cvs rdiff -u -r1.26 -r1.27 src/games/cgram/cgram.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/games/cgram/cgram.c
diff -u src/games/cgram/cgram.c:1.26 src/games/cgram/cgram.c:1.27
--- src/games/cgram/cgram.c:1.26	Fri Oct 29 11:45:39 2021
+++ src/games/cgram/cgram.c	Mon Mar 28 20:00:29 2022
@@ -1,4 +1,4 @@
-/* $NetBSD: cgram.c,v 1.26 2021/10/29 11:45:39 nia Exp $ */
+/* $NetBSD: cgram.c,v 1.27 2022/03/28 20:00:29 rillig Exp $ */
 
 /*-
  * Copyright (c) 2013, 2021 The NetBSD Foundation, Inc.
@@ -31,7 +31,7 @@
 
 #include 
 #if defined(__RCSID) && !defined(lint)
-__RCSID("$NetBSD: cgram.c,v 1.26 2021/10/29 11:45:39 nia Exp $");
+__RCSID("$NetBSD: cgram.c,v 1.27 2022/03/28 20:00:29 rillig Exp $");
 #endif
 
 #include 
@@ -48,12 +48,6 @@ __RCSID("$NetBSD: cgram.c,v 1.26 2021/10
 
 
 static bool
-ch_isspace(char ch)
-{
-	return isspace((unsigned char)ch) != 0;
-}
-
-static bool
 ch_islower(char ch)
 {
 	return ch >= 'a' && ch <= 'z';
@@ -451,20 +445,20 @@ go_right(void)
 static void
 go_to_prev_word(void)
 {
-	while (can_go_left() && ch_isspace(char_left_of_cursor()))
+	while (can_go_left() && !ch_isalpha(char_left_of_cursor()))
 		go_left();
 
-	while (can_go_left() && !ch_isspace(char_left_of_cursor()))
+	while (can_go_left() && ch_isalpha(char_left_of_cursor()))
 		go_left();
 }
 
 static void
 go_to_next_word(void)
 {
-	while (can_go_right() && !ch_isspace(char_at_cursor()))
+	while (can_go_right() && ch_isalpha(char_at_cursor()))
 		go_right();
 
-	while (can_go_right() && ch_isspace(char_at_cursor()))
+	while (can_go_right() && !ch_isalpha(char_at_cursor()))
 		go_right();
 }
 



CVS commit: src/games/cgram

2022-03-28 Thread Roland Illig
Module Name:src
Committed By:   rillig
Date:   Mon Mar 28 20:00:29 UTC 2022

Modified Files:
src/games/cgram: cgram.c

Log Message:
cgram: define a word as a sequence of letters, not non-whitespace

Pressing Tab or Shift+Tab now advances to the next letter that could be
substituted, it no longer stops at punctuation or digits.  Since only
letters are scrambled, these are most interesting to be edited.


To generate a diff of this commit:
cvs rdiff -u -r1.26 -r1.27 src/games/cgram/cgram.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.



CVS commit: src/sys/arch/arm/cortex

2022-03-28 Thread Taylor R Campbell
Module Name:src
Committed By:   riastradh
Date:   Mon Mar 28 19:59:36 UTC 2022

Modified Files:
src/sys/arch/arm/cortex: gicv3.c

Log Message:
arm/cortex: Use container_of, not bespoke offsetof arithmetic.


To generate a diff of this commit:
cvs rdiff -u -r1.49 -r1.50 src/sys/arch/arm/cortex/gicv3.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/arch/arm/cortex/gicv3.c
diff -u src/sys/arch/arm/cortex/gicv3.c:1.49 src/sys/arch/arm/cortex/gicv3.c:1.50
--- src/sys/arch/arm/cortex/gicv3.c:1.49	Sat Oct  2 20:52:09 2021
+++ src/sys/arch/arm/cortex/gicv3.c	Mon Mar 28 19:59:35 2022
@@ -1,4 +1,4 @@
-/* $NetBSD: gicv3.c,v 1.49 2021/10/02 20:52:09 skrll Exp $ */
+/* $NetBSD: gicv3.c,v 1.50 2022/03/28 19:59:35 riastradh Exp $ */
 
 /*-
  * Copyright (c) 2018 Jared McNeill 
@@ -32,7 +32,7 @@
 #define	_INTR_PRIVATE
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: gicv3.c,v 1.49 2021/10/02 20:52:09 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: gicv3.c,v 1.50 2022/03/28 19:59:35 riastradh Exp $");
 
 #include 
 #include 
@@ -58,9 +58,9 @@ __KERNEL_RCSID(0, "$NetBSD: gicv3.c,v 1.
 #endif
 
 #define	PICTOSOFTC(pic)	\
-	((void *)((uintptr_t)(pic) - offsetof(struct gicv3_softc, sc_pic)))
+	container_of(pic, struct gicv3_softc, sc_pic)
 #define	LPITOSOFTC(lpi) \
-	((void *)((uintptr_t)(lpi) - offsetof(struct gicv3_softc, sc_lpi)))
+	container_of(lpi, struct gicv3_softc, sc_lpi)
 
 #define	IPL_TO_PRIORITY(sc, ipl)	(((0xff - (ipl)) << (sc)->sc_priority_shift) & 0xff)
 #define	IPL_TO_PMR(sc, ipl)		(((0xff - (ipl)) << (sc)->sc_pmr_shift) & 0xff)



CVS commit: src/sys/arch/arm/cortex

2022-03-28 Thread Taylor R Campbell
Module Name:src
Committed By:   riastradh
Date:   Mon Mar 28 19:59:36 UTC 2022

Modified Files:
src/sys/arch/arm/cortex: gicv3.c

Log Message:
arm/cortex: Use container_of, not bespoke offsetof arithmetic.


To generate a diff of this commit:
cvs rdiff -u -r1.49 -r1.50 src/sys/arch/arm/cortex/gicv3.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.



CVS commit: src/sys/arch/arm/apple

2022-03-28 Thread Taylor R Campbell
Module Name:src
Committed By:   riastradh
Date:   Mon Mar 28 19:59:26 UTC 2022

Modified Files:
src/sys/arch/arm/apple: apple_intc.c

Log Message:
arm/apple: Use container_of, not bespoke offsetof arithmetic.

Better type-safety this way.


To generate a diff of this commit:
cvs rdiff -u -r1.6 -r1.7 src/sys/arch/arm/apple/apple_intc.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.



CVS commit: src/sys/arch/arm/apple

2022-03-28 Thread Taylor R Campbell
Module Name:src
Committed By:   riastradh
Date:   Mon Mar 28 19:59:26 UTC 2022

Modified Files:
src/sys/arch/arm/apple: apple_intc.c

Log Message:
arm/apple: Use container_of, not bespoke offsetof arithmetic.

Better type-safety this way.


To generate a diff of this commit:
cvs rdiff -u -r1.6 -r1.7 src/sys/arch/arm/apple/apple_intc.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/arch/arm/apple/apple_intc.c
diff -u src/sys/arch/arm/apple/apple_intc.c:1.6 src/sys/arch/arm/apple/apple_intc.c:1.7
--- src/sys/arch/arm/apple/apple_intc.c:1.6	Fri Nov 26 19:39:58 2021
+++ src/sys/arch/arm/apple/apple_intc.c	Mon Mar 28 19:59:26 2022
@@ -1,4 +1,4 @@
-/* $NetBSD: apple_intc.c,v 1.6 2021/11/26 19:39:58 skrll Exp $ */
+/* $NetBSD: apple_intc.c,v 1.7 2022/03/28 19:59:26 riastradh Exp $ */
 
 /*-
  * Copyright (c) 2021 Jared McNeill 
@@ -32,7 +32,7 @@
 #define	_INTR_PRIVATE
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: apple_intc.c,v 1.6 2021/11/26 19:39:58 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: apple_intc.c,v 1.7 2022/03/28 19:59:26 riastradh Exp $");
 
 #include 
 #include 
@@ -112,10 +112,8 @@ struct apple_intc_softc {
 
 static struct apple_intc_softc *intc_softc;
 
-#define	PICTOSOFTC(pic)	\
-	((void *)((uintptr_t)(pic) - offsetof(struct apple_intc_softc, sc_pic)))
-#define	PICTOPERCPU(pic) \
-	((void *)((uintptr_t)(pic) - offsetof(struct apple_intc_percpu, pc_pic)))
+#define	PICTOSOFTC(pic) container_of(pic, struct apple_intc_softc, sc_pic)
+#define	PICTOPERCPU(pic) container_of(pic, struct apple_intc_percpu, pc_pic)
 
 #define AIC_READ(sc, reg) \
 	bus_space_read_4((sc)->sc_bst, (sc)->sc_bsh, (reg))



CVS commit: src/sys/secmodel/extensions

2022-03-28 Thread Roland Illig
Module Name:src
Committed By:   rillig
Date:   Mon Mar 28 19:08:43 UTC 2022

Modified Files:
src/sys/secmodel/extensions: secmodel_extensions.c

Log Message:
secmodel: fix grammar in description of hardlink_check_gid


To generate a diff of this commit:
cvs rdiff -u -r1.13 -r1.14 src/sys/secmodel/extensions/secmodel_extensions.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/secmodel/extensions/secmodel_extensions.c
diff -u src/sys/secmodel/extensions/secmodel_extensions.c:1.13 src/sys/secmodel/extensions/secmodel_extensions.c:1.14
--- src/sys/secmodel/extensions/secmodel_extensions.c:1.13	Sun Mar 27 16:28:35 2022
+++ src/sys/secmodel/extensions/secmodel_extensions.c	Mon Mar 28 19:08:43 2022
@@ -1,4 +1,4 @@
-/* $NetBSD: secmodel_extensions.c,v 1.13 2022/03/27 16:28:35 christos Exp $ */
+/* $NetBSD: secmodel_extensions.c,v 1.14 2022/03/28 19:08:43 rillig Exp $ */
 /*-
  * Copyright (c) 2011 Elad Efrat 
  * All rights reserved.
@@ -27,7 +27,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: secmodel_extensions.c,v 1.13 2022/03/27 16:28:35 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: secmodel_extensions.c,v 1.14 2022/03/28 19:08:43 rillig Exp $");
 
 #include 
 #include 
@@ -167,7 +167,7 @@ SYSCTL_SETUP(sysctl_security_extensions_
 		   CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
 		   CTLTYPE_INT, "hardlink_check_gid",
 		   SYSCTL_DESCR("Whether unprivileged users can hardlink "\
-			"to files they that they are not in their " \
+			"to files that are not in their " \
 			"group membership"),
 		   sysctl_extensions_user_handler, 0,
 		   _check_gid, 0,



CVS commit: src/sys/secmodel/extensions

2022-03-28 Thread Roland Illig
Module Name:src
Committed By:   rillig
Date:   Mon Mar 28 19:08:43 UTC 2022

Modified Files:
src/sys/secmodel/extensions: secmodel_extensions.c

Log Message:
secmodel: fix grammar in description of hardlink_check_gid


To generate a diff of this commit:
cvs rdiff -u -r1.13 -r1.14 src/sys/secmodel/extensions/secmodel_extensions.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.



CVS commit: src/sys/dev/raidframe

2022-03-28 Thread Thomas Klausner
Module Name:src
Committed By:   wiz
Date:   Mon Mar 28 13:07:14 UTC 2022

Modified Files:
src/sys/dev/raidframe: rf_netbsdkintf.c

Log Message:
Restore another historic RCS Id.


To generate a diff of this commit:
cvs rdiff -u -r1.404 -r1.405 src/sys/dev/raidframe/rf_netbsdkintf.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/dev/raidframe/rf_netbsdkintf.c
diff -u src/sys/dev/raidframe/rf_netbsdkintf.c:1.404 src/sys/dev/raidframe/rf_netbsdkintf.c:1.405
--- src/sys/dev/raidframe/rf_netbsdkintf.c:1.404	Mon Mar 28 12:33:21 2022
+++ src/sys/dev/raidframe/rf_netbsdkintf.c	Mon Mar 28 13:07:14 2022
@@ -1,4 +1,4 @@
-/*	$NetBSD: rf_netbsdkintf.c,v 1.404 2022/03/28 12:33:21 riastradh Exp $	*/
+/*	$NetBSD: rf_netbsdkintf.c,v 1.405 2022/03/28 13:07:14 wiz Exp $	*/
 
 /*-
  * Copyright (c) 1996, 1997, 1998, 2008-2011 The NetBSD Foundation, Inc.
@@ -62,7 +62,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * from: Utah $Hdr$
+ * from: Utah $Hdr: cd.c 1.6 90/11/28$
  *
  *  @(#)cd.c8.2 (Berkeley) 11/16/93
  */
@@ -101,7 +101,7 @@
  ***/
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: rf_netbsdkintf.c,v 1.404 2022/03/28 12:33:21 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: rf_netbsdkintf.c,v 1.405 2022/03/28 13:07:14 wiz Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_raid_autoconfig.h"



CVS commit: src/sys/dev/raidframe

2022-03-28 Thread Thomas Klausner
Module Name:src
Committed By:   wiz
Date:   Mon Mar 28 13:07:14 UTC 2022

Modified Files:
src/sys/dev/raidframe: rf_netbsdkintf.c

Log Message:
Restore another historic RCS Id.


To generate a diff of this commit:
cvs rdiff -u -r1.404 -r1.405 src/sys/dev/raidframe/rf_netbsdkintf.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.



CVS commit: src/sys/arch/sandpoint/conf

2022-03-28 Thread Martin Husemann
Module Name:src
Committed By:   martin
Date:   Mon Mar 28 12:48:44 UTC 2022

Modified Files:
src/sys/arch/sandpoint/conf: INSTALL

Log Message:
Provide a bit more space for the ramdisk image (which recently did grow)


To generate a diff of this commit:
cvs rdiff -u -r1.9 -r1.10 src/sys/arch/sandpoint/conf/INSTALL

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/arch/sandpoint/conf/INSTALL
diff -u src/sys/arch/sandpoint/conf/INSTALL:1.9 src/sys/arch/sandpoint/conf/INSTALL:1.10
--- src/sys/arch/sandpoint/conf/INSTALL:1.9	Sun Aug 10 17:58:51 2014
+++ src/sys/arch/sandpoint/conf/INSTALL	Mon Mar 28 12:48:44 2022
@@ -1,4 +1,4 @@
-#	$NetBSD: INSTALL,v 1.9 2014/08/10 17:58:51 joerg Exp $
+#	$NetBSD: INSTALL,v 1.10 2022/03/28 12:48:44 martin Exp $
 #
 # GENERIC install kernel for SandPoint NAS
 #
@@ -7,7 +7,7 @@ include "arch/sandpoint/conf/GENERIC"
 
 options 	MEMORY_DISK_HOOKS
 options 	MEMORY_DISK_IS_ROOT		# Force root on RAM disk
-options 	MEMORY_DISK_ROOT_SIZE=4600	# 2300KB
+options 	MEMORY_DISK_ROOT_SIZE=4800	# 2400KB
 options 	MEMORY_DISK_RBFLAGS=RB_SINGLE	# boot in single-user mode
 
 pseudo-device	md		



CVS commit: src/sys/arch/sandpoint/conf

2022-03-28 Thread Martin Husemann
Module Name:src
Committed By:   martin
Date:   Mon Mar 28 12:48:44 UTC 2022

Modified Files:
src/sys/arch/sandpoint/conf: INSTALL

Log Message:
Provide a bit more space for the ramdisk image (which recently did grow)


To generate a diff of this commit:
cvs rdiff -u -r1.9 -r1.10 src/sys/arch/sandpoint/conf/INSTALL

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.



CVS commit: src/sys/dev

2022-03-28 Thread Taylor R Campbell
Module Name:src
Committed By:   riastradh
Date:   Mon Mar 28 12:48:35 UTC 2022

Modified Files:
src/sys/dev: ccd.c

Log Message:
sys/dev/ccd.c: Restore historic RCS id.

This got munged accidentally by `git cvsexportcommit -k' -- taking
that option out of my commitbomb script!


To generate a diff of this commit:
cvs rdiff -u -r1.188 -r1.189 src/sys/dev/ccd.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/dev/ccd.c
diff -u src/sys/dev/ccd.c:1.188 src/sys/dev/ccd.c:1.189
--- src/sys/dev/ccd.c:1.188	Mon Mar 28 12:33:20 2022
+++ src/sys/dev/ccd.c	Mon Mar 28 12:48:35 2022
@@ -1,4 +1,4 @@
-/*	$NetBSD: ccd.c,v 1.188 2022/03/28 12:33:20 riastradh Exp $	*/
+/*	$NetBSD: ccd.c,v 1.189 2022/03/28 12:48:35 riastradh Exp $	*/
 
 /*-
  * Copyright (c) 1996, 1997, 1998, 1999, 2007, 2009 The NetBSD Foundation, Inc.
@@ -62,7 +62,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * from: Utah $Hdr$
+ * from: Utah $Hdr: cd.c 1.6 90/11/28$
  *
  *	@(#)cd.c	8.2 (Berkeley) 11/16/93
  */
@@ -88,7 +88,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: ccd.c,v 1.188 2022/03/28 12:33:20 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ccd.c,v 1.189 2022/03/28 12:48:35 riastradh Exp $");
 
 #include 
 #include 



CVS commit: src/sys/dev

2022-03-28 Thread Taylor R Campbell
Module Name:src
Committed By:   riastradh
Date:   Mon Mar 28 12:48:35 UTC 2022

Modified Files:
src/sys/dev: ccd.c

Log Message:
sys/dev/ccd.c: Restore historic RCS id.

This got munged accidentally by `git cvsexportcommit -k' -- taking
that option out of my commitbomb script!


To generate a diff of this commit:
cvs rdiff -u -r1.188 -r1.189 src/sys/dev/ccd.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.



CVS commit: src/sys/dev/usb

2022-03-28 Thread Taylor R Campbell
Module Name:src
Committed By:   riastradh
Date:   Mon Mar 28 12:45:04 UTC 2022

Modified Files:
src/sys/dev/usb: uatp.c

Log Message:
uatp(4): Use usbd_get/set_report for Geyser 3/4 reset.


To generate a diff of this commit:
cvs rdiff -u -r1.30 -r1.31 src/sys/dev/usb/uatp.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/dev/usb/uatp.c
diff -u src/sys/dev/usb/uatp.c:1.30 src/sys/dev/usb/uatp.c:1.31
--- src/sys/dev/usb/uatp.c:1.30	Mon Mar 28 12:44:54 2022
+++ src/sys/dev/usb/uatp.c	Mon Mar 28 12:45:04 2022
@@ -1,4 +1,4 @@
-/*	$NetBSD: uatp.c,v 1.30 2022/03/28 12:44:54 riastradh Exp $	*/
+/*	$NetBSD: uatp.c,v 1.31 2022/03/28 12:45:04 riastradh Exp $	*/
 
 /*-
  * Copyright (c) 2011-2014 The NetBSD Foundation, Inc.
@@ -146,7 +146,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: uatp.c,v 1.30 2022/03/28 12:44:54 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: uatp.c,v 1.31 2022/03/28 12:45:04 riastradh Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_usb.h"
@@ -489,6 +489,7 @@ struct uatp_softc {
 	device_t sc_dev;
 	struct uhidev *sc_hdev;		/* uhidev(9) parent.  */
 	struct usbd_device *sc_udev;	/* USB device.  */
+	struct usbd_interface *sc_iface0; /* Geyser 3/4 reset interface.  */
 	device_t sc_wsmousedev;		/* Attached wsmouse device.  */
 	const struct uatp_parameters *sc_parameters;
 	struct uatp_knobs sc_knobs;
@@ -1295,19 +1296,12 @@ uatp_ioctl(void *v, unsigned long cmd, v
 static void
 geyser34_enable_raw_mode(struct uatp_softc *sc)
 {
-	struct usbd_device *udev = sc->sc_udev;
-	usb_device_request_t req;
-	usbd_status status;
 	uint8_t report[GEYSER34_MODE_PACKET_SIZE];
-
-	req.bmRequestType = UT_READ_CLASS_INTERFACE;
-	req.bRequest = UR_GET_REPORT;
-	USETW2(req.wValue, UHID_FEATURE_REPORT, GEYSER34_MODE_REPORT_ID);
-	USETW(req.wIndex, GEYSER34_MODE_INTERFACE);
-	USETW(req.wLength, GEYSER34_MODE_PACKET_SIZE);
+	usbd_status status;
 
 	DPRINTF(sc, UATP_DEBUG_RESET, ("get feature report\n"));
-	status = usbd_do_request(udev, , report);
+	status = usbd_get_report(sc->sc_iface0, UHID_FEATURE_REPORT,
+	GEYSER34_MODE_REPORT_ID, report, sizeof(report));
 	if (status != USBD_NORMAL_COMPLETION) {
 		aprint_error_dev(uatp_dev(sc),
 		"error reading feature report: %s\n", usbd_errstr(status));
@@ -1333,14 +1327,9 @@ geyser34_enable_raw_mode(struct uatp_sof
 
 	report[0] = GEYSER34_RAW_MODE;
 
-	req.bmRequestType = UT_WRITE_CLASS_INTERFACE;
-	req.bRequest = UR_SET_REPORT;
-	USETW2(req.wValue, UHID_FEATURE_REPORT, GEYSER34_MODE_REPORT_ID);
-	USETW(req.wIndex, GEYSER34_MODE_INTERFACE);
-	USETW(req.wLength, GEYSER34_MODE_PACKET_SIZE);
-
 	DPRINTF(sc, UATP_DEBUG_RESET, ("set feature report\n"));
-	status = usbd_do_request(udev, , report);
+	status = usbd_set_report(sc->sc_iface0, UHID_FEATURE_REPORT,
+	GEYSER34_MODE_REPORT_ID, report, sizeof(report));
 	if (status != USBD_NORMAL_COMPLETION) {
 		aprint_error_dev(uatp_dev(sc),
 		"error writing feature report: %s\n", usbd_errstr(status));
@@ -1356,8 +1345,11 @@ geyser34_enable_raw_mode(struct uatp_sof
 static void
 geyser34_initialize(struct uatp_softc *sc)
 {
+	usbd_status err __diagused;
 
 	DPRINTF(sc, UATP_DEBUG_MISC, ("initializing\n"));
+	err = usbd_device2interface_handle(sc->sc_udev, 0, >sc_iface0);
+	KASSERT(err == 0);	/* always an interface 0 if attached */
 	geyser34_enable_raw_mode(sc);
 	usb_init_task(>sc_reset_task, _reset_task, sc, 0);
 }



CVS commit: src/sys/dev/usb

2022-03-28 Thread Taylor R Campbell
Module Name:src
Committed By:   riastradh
Date:   Mon Mar 28 12:45:04 UTC 2022

Modified Files:
src/sys/dev/usb: uatp.c

Log Message:
uatp(4): Use usbd_get/set_report for Geyser 3/4 reset.


To generate a diff of this commit:
cvs rdiff -u -r1.30 -r1.31 src/sys/dev/usb/uatp.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.



CVS commit: src/sys/dev/usb

2022-03-28 Thread Taylor R Campbell
Module Name:src
Committed By:   riastradh
Date:   Mon Mar 28 12:44:55 UTC 2022

Modified Files:
src/sys/dev/usb: uatp.c

Log Message:
uatp(4): Fix detach logic.

Let wsmouse child decide whether it's in use or close if mandatory.
If config_detach_children succeeds, this must no longer be open and
we can commit to freeing everything.


To generate a diff of this commit:
cvs rdiff -u -r1.29 -r1.30 src/sys/dev/usb/uatp.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/dev/usb/uatp.c
diff -u src/sys/dev/usb/uatp.c:1.29 src/sys/dev/usb/uatp.c:1.30
--- src/sys/dev/usb/uatp.c:1.29	Mon Mar 28 12:44:17 2022
+++ src/sys/dev/usb/uatp.c	Mon Mar 28 12:44:54 2022
@@ -1,4 +1,4 @@
-/*	$NetBSD: uatp.c,v 1.29 2022/03/28 12:44:17 riastradh Exp $	*/
+/*	$NetBSD: uatp.c,v 1.30 2022/03/28 12:44:54 riastradh Exp $	*/
 
 /*-
  * Copyright (c) 2011-2014 The NetBSD Foundation, Inc.
@@ -146,7 +146,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: uatp.c,v 1.29 2022/03/28 12:44:17 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: uatp.c,v 1.30 2022/03/28 12:44:54 riastradh Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_usb.h"
@@ -298,7 +298,7 @@ static void uatp_disable(void *);
 static int uatp_ioctl(void *, unsigned long, void *, int, struct lwp *);
 static void geyser34_enable_raw_mode(struct uatp_softc *);
 static void geyser34_initialize(struct uatp_softc *);
-static int geyser34_finalize(struct uatp_softc *);
+static void geyser34_finalize(struct uatp_softc *);
 static void geyser34_deferred_reset(struct uatp_softc *);
 static void geyser34_reset_task(void *);
 static void uatp_intr(void *, void *, unsigned int);
@@ -553,8 +553,8 @@ struct uatp_parameters {
 	/* Device-specific initialization routine.  May be null.  */
 	void (*initialize)(struct uatp_softc *);
 
-	/* Device-specific finalization routine.  May be null.  May fail.  */
-	int (*finalize)(struct uatp_softc *);
+	/* Device-specific finalization routine.  May be null.  */
+	void (*finalize)(struct uatp_softc *);
 
 	/* Tests whether this is a base sample.  Second argument is
 	 * input_size bytes long.  */
@@ -1182,19 +1182,18 @@ static int
 uatp_detach(device_t self, int flags)
 {
 	struct uatp_softc *sc = device_private(self);
+	int error;
 
 	DPRINTF(sc, UATP_DEBUG_MISC, ("detaching with flags %d\n", flags));
 
-if (sc->sc_status & UATP_ENABLED) {
-		aprint_error_dev(uatp_dev(sc), "can't detach while enabled\n");
-		return EBUSY;
-}
+	error = config_detach_children(self, flags);
+	if (error)
+		return error;
 
-	if (sc->sc_parameters->finalize) {
-		int error = sc->sc_parameters->finalize(sc);
-		if (error != 0)
-			return error;
-	}
+	KASSERT((sc->sc_status & UATP_ENABLED) == 0);
+
+	if (sc->sc_parameters->finalize)
+		sc->sc_parameters->finalize(sc);
 
 	pmf_device_deregister(self);
 
@@ -1203,7 +1202,7 @@ uatp_detach(device_t self, int flags)
 
 	tap_finalize(sc);
 
-	return config_detach_children(self, flags);
+	return 0;
 }
 
 static int
@@ -1363,15 +1362,13 @@ geyser34_initialize(struct uatp_softc *s
 	usb_init_task(>sc_reset_task, _reset_task, sc, 0);
 }
 
-static int
+static void
 geyser34_finalize(struct uatp_softc *sc)
 {
 
 	DPRINTF(sc, UATP_DEBUG_MISC, ("finalizing\n"));
 	usb_rem_task_wait(sc->sc_udev, >sc_reset_task, USB_TASKQ_DRIVER,
 	NULL);
-
-	return 0;
 }
 
 static void



CVS commit: src/sys/dev/usb

2022-03-28 Thread Taylor R Campbell
Module Name:src
Committed By:   riastradh
Date:   Mon Mar 28 12:44:55 UTC 2022

Modified Files:
src/sys/dev/usb: uatp.c

Log Message:
uatp(4): Fix detach logic.

Let wsmouse child decide whether it's in use or close if mandatory.
If config_detach_children succeeds, this must no longer be open and
we can commit to freeing everything.


To generate a diff of this commit:
cvs rdiff -u -r1.29 -r1.30 src/sys/dev/usb/uatp.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.



CVS commit: src/sys/dev/usb

2022-03-28 Thread Taylor R Campbell
Module Name:src
Committed By:   riastradh
Date:   Mon Mar 28 12:44:45 UTC 2022

Modified Files:
src/sys/dev/usb: uhidev.c

Log Message:
uhidev(9): Assert uhidev is open when writing.

(Maybe we could have uhidevs that are output-only, in which case a
driver could, in principle, want to issue writes without getting any
input report interrupts.  But we can cross that bridge when we come
to it.)


To generate a diff of this commit:
cvs rdiff -u -r1.92 -r1.93 src/sys/dev/usb/uhidev.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/dev/usb/uhidev.c
diff -u src/sys/dev/usb/uhidev.c:1.92 src/sys/dev/usb/uhidev.c:1.93
--- src/sys/dev/usb/uhidev.c:1.92	Mon Mar 28 12:44:37 2022
+++ src/sys/dev/usb/uhidev.c	Mon Mar 28 12:44:45 2022
@@ -1,4 +1,4 @@
-/*	$NetBSD: uhidev.c,v 1.92 2022/03/28 12:44:37 riastradh Exp $	*/
+/*	$NetBSD: uhidev.c,v 1.93 2022/03/28 12:44:45 riastradh Exp $	*/
 
 /*
  * Copyright (c) 2001, 2012 The NetBSD Foundation, Inc.
@@ -35,7 +35,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: uhidev.c,v 1.92 2022/03/28 12:44:37 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: uhidev.c,v 1.93 2022/03/28 12:44:45 riastradh Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_usb.h"
@@ -1083,6 +1083,7 @@ uhidev_write(struct uhidev *scd, void *d
 
 	mutex_enter(>sc_lock);
 	KASSERT(sc->sc_refcnt);
+	KASSERT(scd->sc_state & UHIDEV_OPEN);
 	for (;;) {
 		if (scd->sc_state & UHIDEV_STOPPED) {
 			err = USBD_CANCELLED;
@@ -1116,6 +1117,7 @@ uhidev_write(struct uhidev *scd, void *d
 
 	mutex_enter(>sc_lock);
 	KASSERT(sc->sc_refcnt);
+	KASSERT(scd->sc_state & UHIDEV_OPEN);
 	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,
@@ -1168,6 +1170,7 @@ uhidev_write_async(struct uhidev *scd, v
 
 	mutex_enter(>sc_lock);
 	KASSERT(sc->sc_refcnt);
+	KASSERT(scd->sc_state & UHIDEV_OPEN);
 	if (scd->sc_state & UHIDEV_STOPPED) {
 		err = USBD_CANCELLED;
 		goto out;



CVS commit: src/sys/dev/usb

2022-03-28 Thread Taylor R Campbell
Module Name:src
Committed By:   riastradh
Date:   Mon Mar 28 12:44:45 UTC 2022

Modified Files:
src/sys/dev/usb: uhidev.c

Log Message:
uhidev(9): Assert uhidev is open when writing.

(Maybe we could have uhidevs that are output-only, in which case a
driver could, in principle, want to issue writes without getting any
input report interrupts.  But we can cross that bridge when we come
to it.)


To generate a diff of this commit:
cvs rdiff -u -r1.92 -r1.93 src/sys/dev/usb/uhidev.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.



CVS commit: src/sys/dev/usb

2022-03-28 Thread Taylor R Campbell
Module Name:src
Committed By:   riastradh
Date:   Mon Mar 28 12:44:37 UTC 2022

Modified Files:
src/sys/dev/usb: uhidev.c uhidev.h

Log Message:
uhidev(9): Define UHIDEV_MAXREPID = 255.

Report ids are limited by the HID spec to a single byte.

- Clamp max report id in report descriptor to this.

- Prune dead refcnt-overflow error branches.  Assert instead.


To generate a diff of this commit:
cvs rdiff -u -r1.91 -r1.92 src/sys/dev/usb/uhidev.c
cvs rdiff -u -r1.26 -r1.27 src/sys/dev/usb/uhidev.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/dev/usb/uhidev.c
diff -u src/sys/dev/usb/uhidev.c:1.91 src/sys/dev/usb/uhidev.c:1.92
--- src/sys/dev/usb/uhidev.c:1.91	Mon Mar 28 12:44:28 2022
+++ src/sys/dev/usb/uhidev.c	Mon Mar 28 12:44:37 2022
@@ -1,4 +1,4 @@
-/*	$NetBSD: uhidev.c,v 1.91 2022/03/28 12:44:28 riastradh Exp $	*/
+/*	$NetBSD: uhidev.c,v 1.92 2022/03/28 12:44:37 riastradh Exp $	*/
 
 /*
  * Copyright (c) 2001, 2012 The NetBSD Foundation, Inc.
@@ -35,7 +35,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: uhidev.c,v 1.91 2022/03/28 12:44:28 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: uhidev.c,v 1.92 2022/03/28 12:44:37 riastradh Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_usb.h"
@@ -458,7 +458,7 @@ uhidev_maxrepid(void *buf, int len)
 		if ((int)h.report_ID > maxid)
 			maxid = h.report_ID;
 	hid_end_parse(d);
-	return maxid;
+	return MIN(maxid, UHIDEV_MAXREPID);
 }
 
 static int
@@ -671,11 +671,11 @@ uhidev_open_pipes(struct uhidev_softc *s
 
 	/*
 	 * If the pipes are already open, just increment the reference
-	 * count, or fail if it would overflow.
+	 * count.  The reference count is limited by the number of
+	 * report ids, so this can't overflow.
 	 */
 	if (sc->sc_refcnt) {
-		if (sc->sc_refcnt == INT_MAX)
-			return EBUSY;
+		KASSERT(sc->sc_refcnt < UHIDEV_MAXREPID);
 		sc->sc_refcnt++;
 		return 0;
 	}
@@ -700,12 +700,9 @@ uhidev_open_pipes(struct uhidev_softc *s
 	if (error)
 		goto out;
 	if (sc->sc_refcnt) {
-		if (sc->sc_refcnt == INT_MAX) {
-			error = EBUSY;
-		} else {
-			sc->sc_refcnt++;
-			error = 0;
-		}
+		KASSERT(sc->sc_refcnt < UHIDEV_MAXREPID);
+		sc->sc_refcnt++;
+		error = 0;
 		goto out0;
 	}
 	mutex_exit(>sc_lock);

Index: src/sys/dev/usb/uhidev.h
diff -u src/sys/dev/usb/uhidev.h:1.26 src/sys/dev/usb/uhidev.h:1.27
--- src/sys/dev/usb/uhidev.h:1.26	Mon Mar 28 12:44:17 2022
+++ src/sys/dev/usb/uhidev.h	Mon Mar 28 12:44:37 2022
@@ -1,4 +1,4 @@
-/*	$NetBSD: uhidev.h,v 1.26 2022/03/28 12:44:17 riastradh Exp $	*/
+/*	$NetBSD: uhidev.h,v 1.27 2022/03/28 12:44:37 riastradh Exp $	*/
 
 /*
  * Copyright (c) 2001 The NetBSD Foundation, Inc.
@@ -54,5 +54,6 @@ usbd_status uhidev_write_async(struct uh
 usbd_callback, void *);
 
 #define	UHIDEV_OSIZE	64
+#define	UHIDEV_MAXREPID	255
 
 #endif	/* _DEV_USB_UHIDEV_H_ */



CVS commit: src/sys/dev/usb

2022-03-28 Thread Taylor R Campbell
Module Name:src
Committed By:   riastradh
Date:   Mon Mar 28 12:44:37 UTC 2022

Modified Files:
src/sys/dev/usb: uhidev.c uhidev.h

Log Message:
uhidev(9): Define UHIDEV_MAXREPID = 255.

Report ids are limited by the HID spec to a single byte.

- Clamp max report id in report descriptor to this.

- Prune dead refcnt-overflow error branches.  Assert instead.


To generate a diff of this commit:
cvs rdiff -u -r1.91 -r1.92 src/sys/dev/usb/uhidev.c
cvs rdiff -u -r1.26 -r1.27 src/sys/dev/usb/uhidev.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.



CVS commit: src/sys/dev/usb

2022-03-28 Thread Taylor R Campbell
Module Name:src
Committed By:   riastradh
Date:   Mon Mar 28 12:44:28 UTC 2022

Modified Files:
src/sys/dev/usb: uhidev.c

Log Message:
uhidev(9): Omit needless sc_dying.


To generate a diff of this commit:
cvs rdiff -u -r1.90 -r1.91 src/sys/dev/usb/uhidev.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/dev/usb/uhidev.c
diff -u src/sys/dev/usb/uhidev.c:1.90 src/sys/dev/usb/uhidev.c:1.91
--- src/sys/dev/usb/uhidev.c:1.90	Mon Mar 28 12:44:17 2022
+++ src/sys/dev/usb/uhidev.c	Mon Mar 28 12:44:28 2022
@@ -1,4 +1,4 @@
-/*	$NetBSD: uhidev.c,v 1.90 2022/03/28 12:44:17 riastradh Exp $	*/
+/*	$NetBSD: uhidev.c,v 1.91 2022/03/28 12:44:28 riastradh Exp $	*/
 
 /*
  * Copyright (c) 2001, 2012 The NetBSD Foundation, Inc.
@@ -35,7 +35,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: uhidev.c,v 1.90 2022/03/28 12:44:17 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: uhidev.c,v 1.91 2022/03/28 12:44:28 riastradh Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_usb.h"
@@ -110,7 +110,6 @@ struct uhidev_softc {
 	int sc_refcnt;
 	int sc_writereportid;
 	int sc_stopreportid;
-	u_char sc_dying;
 
 	/*
 	 * - Read under sc_lock, provided sc_refcnt > 0.
@@ -146,10 +145,9 @@ static int uhidev_match(device_t, cfdata
 static void uhidev_attach(device_t, device_t, void *);
 static void uhidev_childdet(device_t, device_t);
 static int uhidev_detach(device_t, int);
-static int uhidev_activate(device_t, enum devact);
 
 CFATTACH_DECL2_NEW(uhidev, sizeof(struct uhidev_softc), uhidev_match,
-uhidev_attach, uhidev_detach, uhidev_activate, NULL, uhidev_childdet);
+uhidev_attach, uhidev_detach, NULL, NULL, uhidev_childdet);
 
 static int
 uhidev_match(device_t parent, cfdata_t match, void *aux)
@@ -203,7 +201,6 @@ uhidev_attach(device_t parent, device_t 
 	sc->sc_refcnt = 0;
 	sc->sc_writereportid = -1;
 	sc->sc_stopreportid = -1;
-	sc->sc_dying = false;
 
 	id = usbd_get_interface_descriptor(iface);
 
@@ -244,7 +241,6 @@ uhidev_attach(device_t parent, device_t 
 		if (ed == NULL) {
 			aprint_error_dev(self,
 			"could not read endpoint descriptor\n");
-			sc->sc_dying = 1;
 			return;
 		}
 
@@ -275,7 +271,6 @@ uhidev_attach(device_t parent, device_t 
 	 */
 	if (sc->sc_iep_addr == -1) {
 		aprint_error_dev(self, "no input interrupt endpoint\n");
-		sc->sc_dying = 1;
 		return;
 	}
 
@@ -336,7 +331,6 @@ uhidev_attach(device_t parent, device_t 
 	}
 	if (err) {
 		aprint_error_dev(self, "no report descriptor\n");
-		sc->sc_dying = 1;
 		return;
 	}
 
@@ -479,20 +473,6 @@ uhidevprint(void *aux, const char *pnp)
 	return UNCONF;
 }
 
-static int
-uhidev_activate(device_t self, enum devact act)
-{
-	struct uhidev_softc *sc = device_private(self);
-
-	switch (act) {
-	case DVACT_DEACTIVATE:
-		sc->sc_dying = 1;
-		return 0;
-	default:
-		return EOPNOTSUPP;
-	}
-}
-
 static void
 uhidev_childdet(device_t self, device_t child)
 {
@@ -523,26 +503,17 @@ uhidev_detach(device_t self, int flags)
 
 	DPRINTF(("uhidev_detach: sc=%p flags=%d\n", sc, flags));
 
-	/* Notify that we are going away.  */
-	mutex_enter(>sc_lock);
-	sc->sc_dying = 1;
-	cv_broadcast(>sc_cv);
-	mutex_exit(>sc_lock);
-
 	/*
 	 * Try to detach all our children.  If anything fails, bail.
 	 * Failure can happen if this is from drvctl -d; of course, if
 	 * this is a USB device being yanked, flags will have
 	 * DETACH_FORCE and the children will not have the option of
-	 * refusing detachment.
+	 * refusing detachment.  If they do detach, the pipes can no
+	 * longer be in use.
 	 */
 	rv = config_detach_children(self, flags);
-	if (rv) {
-		mutex_enter(>sc_lock);
-		sc->sc_dying = 0;
-		mutex_exit(>sc_lock);
+	if (rv)
 		return rv;
-	}
 
 	KASSERTMSG(sc->sc_refcnt == 0,
 	"%s: %d refs remain", device_xname(sc->sc_dev), sc->sc_refcnt);
@@ -650,8 +621,6 @@ uhidev_config_enter(struct uhidev_softc 
 	KASSERT(mutex_owned(>sc_lock));
 
 	for (;;) {
-		if (sc->sc_dying)
-			return ENXIO;
 		if (sc->sc_configlock == NULL)
 			break;
 		error = cv_wait_sig(>sc_cv, >sc_lock);
@@ -700,10 +669,6 @@ uhidev_open_pipes(struct uhidev_softc *s
 
 	KASSERT(mutex_owned(>sc_lock));
 
-	/* If the device is dying, refuse.  */
-	if (sc->sc_dying)
-		return ENXIO;
-
 	/*
 	 * If the pipes are already open, just increment the reference
 	 * count, or fail if it would overflow.
@@ -1122,10 +1087,6 @@ uhidev_write(struct uhidev *scd, void *d
 	mutex_enter(>sc_lock);
 	KASSERT(sc->sc_refcnt);
 	for (;;) {
-		if (sc->sc_dying) {
-			err = USBD_IOERROR;
-			goto out;
-		}
 		if (scd->sc_state & UHIDEV_STOPPED) {
 			err = USBD_CANCELLED;
 			goto out;
@@ -1210,10 +1171,6 @@ uhidev_write_async(struct uhidev *scd, v
 
 	mutex_enter(>sc_lock);
 	KASSERT(sc->sc_refcnt);
-	if (sc->sc_dying) {
-		err = USBD_IOERROR;
-		goto out;
-	}
 	if (scd->sc_state & UHIDEV_STOPPED) {
 		err = USBD_CANCELLED;
 		goto out;



CVS commit: src/sys/dev/usb

2022-03-28 Thread Taylor R Campbell
Module Name:src
Committed By:   riastradh
Date:   Mon Mar 28 12:44:28 UTC 2022

Modified Files:
src/sys/dev/usb: uhidev.c

Log Message:
uhidev(9): Omit needless sc_dying.


To generate a diff of this commit:
cvs rdiff -u -r1.90 -r1.91 src/sys/dev/usb/uhidev.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.



CVS commit: src/sys/dev/usb

2022-03-28 Thread Taylor R Campbell
Module Name:src
Committed By:   riastradh
Date:   Mon Mar 28 12:44:17 UTC 2022

Modified Files:
src/sys/dev/usb: uatp.c ucycom.c uhid.c uhidev.c uhidev.h ukbd.c ums.c
uthum.c uts.c

Log Message:
uhidev(9): Make uhidev state opaque.

This makes the API simpler and clearer and gives us more latitude to
fix bugs in the state management without breaking the ABI.

XXX kernel ABI change to signature of uhidev_get_report_desc and
uhidev_open, and to struct uhidev_attach_arg, requires bump for
uhidev driver modules


To generate a diff of this commit:
cvs rdiff -u -r1.28 -r1.29 src/sys/dev/usb/uatp.c
cvs rdiff -u -r1.54 -r1.55 src/sys/dev/usb/ucycom.c
cvs rdiff -u -r1.122 -r1.123 src/sys/dev/usb/uhid.c
cvs rdiff -u -r1.89 -r1.90 src/sys/dev/usb/uhidev.c
cvs rdiff -u -r1.25 -r1.26 src/sys/dev/usb/uhidev.h
cvs rdiff -u -r1.158 -r1.159 src/sys/dev/usb/ukbd.c
cvs rdiff -u -r1.102 -r1.103 src/sys/dev/usb/ums.c
cvs rdiff -u -r1.22 -r1.23 src/sys/dev/usb/uthum.c
cvs rdiff -u -r1.14 -r1.15 src/sys/dev/usb/uts.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/dev/usb/uatp.c
diff -u src/sys/dev/usb/uatp.c:1.28 src/sys/dev/usb/uatp.c:1.29
--- src/sys/dev/usb/uatp.c:1.28	Mon Mar 28 12:43:12 2022
+++ src/sys/dev/usb/uatp.c	Mon Mar 28 12:44:17 2022
@@ -1,4 +1,4 @@
-/*	$NetBSD: uatp.c,v 1.28 2022/03/28 12:43:12 riastradh Exp $	*/
+/*	$NetBSD: uatp.c,v 1.29 2022/03/28 12:44:17 riastradh Exp $	*/
 
 /*-
  * Copyright (c) 2011-2014 The NetBSD Foundation, Inc.
@@ -146,7 +146,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: uatp.c,v 1.28 2022/03/28 12:43:12 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: uatp.c,v 1.29 2022/03/28 12:44:17 riastradh Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_usb.h"
@@ -301,7 +301,7 @@ static void geyser34_initialize(struct u
 static int geyser34_finalize(struct uatp_softc *);
 static void geyser34_deferred_reset(struct uatp_softc *);
 static void geyser34_reset_task(void *);
-static void uatp_intr(struct uhidev *, void *, unsigned int);
+static void uatp_intr(void *, void *, unsigned int);
 static bool base_sample_softc_flag(const struct uatp_softc *, const uint8_t *);
 static bool base_sample_input_flag(const struct uatp_softc *, const uint8_t *);
 static void read_sample_1(uint8_t *, uint8_t *, const uint8_t *);
@@ -486,7 +486,8 @@ static const struct uatp_knobs default_k
 };
 
 struct uatp_softc {
-	struct uhidev sc_hdev;		/* uhidev(9) parent.  */
+	device_t sc_dev;
+	struct uhidev *sc_hdev;		/* uhidev(9) parent.  */
 	struct usbd_device *sc_udev;	/* USB device.  */
 	device_t sc_wsmousedev;		/* Attached wsmouse device.  */
 	const struct uatp_parameters *sc_parameters;
@@ -691,7 +692,7 @@ find_uatp_descriptor(const struct uhidev
 static device_t
 uatp_dev(const struct uatp_softc *sc)
 {
-	return sc->sc_hdev.sc_dev;
+	return sc->sc_dev;
 }
 
 static uint8_t *
@@ -931,12 +932,8 @@ uatp_attach(device_t parent, device_t se
 	int report_size, input_size;
 	struct wsmousedev_attach_args a;
 
-	/* Set up uhidev state.  (Why doesn't uhidev do most of this?)  */
-	sc->sc_hdev.sc_dev = self;
-	sc->sc_hdev.sc_intr = uatp_intr;
-	sc->sc_hdev.sc_parent = uha->parent;
-	sc->sc_hdev.sc_report_id = uha->reportid;
-
+	sc->sc_dev = self;
+	sc->sc_hdev = uha->parent;
 	sc->sc_udev = uha->uiaa->uiaa_device;
 
 	/* Identify ourselves to dmesg.  */
@@ -948,7 +945,7 @@ uatp_attach(device_t parent, device_t se
 	"vendor 0x%04x, product 0x%04x, report id %d\n",
 	(unsigned int)uha->uiaa->uiaa_vendor,
 	(unsigned int)uha->uiaa->uiaa_product,
-	(int)uha->reportid);
+	uha->reportid);
 
 	uhidev_get_report_desc(uha->parent, _descriptor, _size);
 	input_size = hid_report_size(report_descriptor, report_size, hid_input,
@@ -1251,8 +1248,8 @@ uatp_enable(void *v)
 	tap_enable(sc);
 	uatp_clear_position(sc);
 
-	DPRINTF(sc, UATP_DEBUG_MISC, ("uhidev_open(%p)\n", >sc_hdev));
-	return uhidev_open(>sc_hdev);
+	DPRINTF(sc, UATP_DEBUG_MISC, ("uhidev_open(%p)\n", sc->sc_hdev));
+	return uhidev_open(sc->sc_hdev, _intr, sc);
 }
 
 static void
@@ -1270,8 +1267,8 @@ uatp_disable(void *v)
 	tap_disable(sc);
 	sc->sc_status &=~ UATP_ENABLED;
 
-	DPRINTF(sc, UATP_DEBUG_MISC, ("uhidev_close(%p)\n", >sc_hdev));
-	uhidev_close(>sc_hdev);
+	DPRINTF(sc, UATP_DEBUG_MISC, ("uhidev_close(%p)\n", sc->sc_hdev));
+	uhidev_close(sc->sc_hdev);
 }
 
 static int
@@ -1399,15 +1396,15 @@ geyser34_reset_task(void *arg)
 /* Interrupt handler */
 
 static void
-uatp_intr(struct uhidev *addr, void *ibuf, unsigned int len)
+uatp_intr(void *cookie, void *ibuf, unsigned int len)
 {
-	struct uatp_softc *sc = (struct uatp_softc *)addr;
+	struct uatp_softc *sc = cookie;
 	uint8_t *input;
 	int dx, dy, dz, dw;
 	uint32_t buttons;
 
 	DPRINTF(sc, UATP_DEBUG_INTR, ("softc %p, ibuf %p, len %u\n",
-	addr, ibuf, len));
+	sc, ibuf, len));
 
 	/*
 	 * Some devices break packets up into chunks, so we accumulate

Index: 

CVS commit: src/sys/dev/usb

2022-03-28 Thread Taylor R Campbell
Module Name:src
Committed By:   riastradh
Date:   Mon Mar 28 12:44:17 UTC 2022

Modified Files:
src/sys/dev/usb: uatp.c ucycom.c uhid.c uhidev.c uhidev.h ukbd.c ums.c
uthum.c uts.c

Log Message:
uhidev(9): Make uhidev state opaque.

This makes the API simpler and clearer and gives us more latitude to
fix bugs in the state management without breaking the ABI.

XXX kernel ABI change to signature of uhidev_get_report_desc and
uhidev_open, and to struct uhidev_attach_arg, requires bump for
uhidev driver modules


To generate a diff of this commit:
cvs rdiff -u -r1.28 -r1.29 src/sys/dev/usb/uatp.c
cvs rdiff -u -r1.54 -r1.55 src/sys/dev/usb/ucycom.c
cvs rdiff -u -r1.122 -r1.123 src/sys/dev/usb/uhid.c
cvs rdiff -u -r1.89 -r1.90 src/sys/dev/usb/uhidev.c
cvs rdiff -u -r1.25 -r1.26 src/sys/dev/usb/uhidev.h
cvs rdiff -u -r1.158 -r1.159 src/sys/dev/usb/ukbd.c
cvs rdiff -u -r1.102 -r1.103 src/sys/dev/usb/ums.c
cvs rdiff -u -r1.22 -r1.23 src/sys/dev/usb/uthum.c
cvs rdiff -u -r1.14 -r1.15 src/sys/dev/usb/uts.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.



CVS commit: src/sys/dev/usb

2022-03-28 Thread Taylor R Campbell
Module Name:src
Committed By:   riastradh
Date:   Mon Mar 28 12:44:06 UTC 2022

Modified Files:
src/sys/dev/usb: uhidev.c

Log Message:
uhidev(9): Fix race between uhidev_close and uhidev_intr.

uhidev_intr currently relies on the kernel lock to serialize access
to struct uhidev::sc_state, but if the driver's sc_intr function
sleeps (which it may do, even though this runs is softint context --
it may sleep on an adaptive lock), uhidev_close might return while
the driver's sc_intr function is still in flight.

This avoids that race, and makes progress toward MP-safe uhidev.


To generate a diff of this commit:
cvs rdiff -u -r1.88 -r1.89 src/sys/dev/usb/uhidev.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/dev/usb/uhidev.c
diff -u src/sys/dev/usb/uhidev.c:1.88 src/sys/dev/usb/uhidev.c:1.89
--- src/sys/dev/usb/uhidev.c:1.88	Mon Mar 28 12:43:58 2022
+++ src/sys/dev/usb/uhidev.c	Mon Mar 28 12:44:06 2022
@@ -1,4 +1,4 @@
-/*	$NetBSD: uhidev.c,v 1.88 2022/03/28 12:43:58 riastradh Exp $	*/
+/*	$NetBSD: uhidev.c,v 1.89 2022/03/28 12:44:06 riastradh Exp $	*/
 
 /*
  * Copyright (c) 2001, 2012 The NetBSD Foundation, Inc.
@@ -35,7 +35,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: uhidev.c,v 1.88 2022/03/28 12:43:58 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: uhidev.c,v 1.89 2022/03/28 12:44:06 riastradh Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_usb.h"
@@ -44,6 +44,7 @@ __KERNEL_RCSID(0, "$NetBSD: uhidev.c,v 1
 #include 
 #include 
 
+#include 
 #include 
 #include 
 #include 
@@ -53,6 +54,7 @@ __KERNEL_RCSID(0, "$NetBSD: uhidev.c,v 1
 #include 
 #include 
 #include 
+#include 
 
 #include 
 #include 
@@ -622,7 +624,7 @@ uhidev_intr(struct usbd_xfer *xfer, void
 	scd = device_private(cdev);
 	DPRINTFN(5,("uhidev_intr: rep=%d, scd=%p state=%#x\n",
 		rep, scd, scd ? scd->sc_state : 0));
-	if (!(scd->sc_state & UHIDEV_OPEN))
+	if (!(atomic_load_acquire(>sc_state) & UHIDEV_OPEN))
 		return;
 #ifdef UHIDEV_DEBUG
 	if (scd->sc_in_rep_size != cc) {
@@ -921,7 +923,7 @@ uhidev_open(struct uhidev *scd)
 		error = EBUSY;
 		goto out;
 	}
-	scd->sc_state |= UHIDEV_OPEN;
+	atomic_store_release(>sc_state, scd->sc_state | UHIDEV_OPEN);
 
 	/* Open the pipes which are shared by all report ids.  */
 	error = uhidev_open_pipes(sc);
@@ -935,7 +937,8 @@ out:	if (error) {
 		KASSERTMSG(scd->sc_state & UHIDEV_OPEN,
 		"%s: report id %d: closed while opening",
 		device_xname(sc->sc_dev), scd->sc_report_id);
-		scd->sc_state &= ~UHIDEV_OPEN;
+		atomic_store_relaxed(>sc_state,
+		scd->sc_state & ~UHIDEV_OPEN);
 	}
 	mutex_exit(>sc_lock);
 	return error;
@@ -962,7 +965,7 @@ uhidev_stop(struct uhidev *scd)
 	mutex_enter(>sc_lock);
 
 	/* Prevent further writes on this report from starting.  */
-	scd->sc_state |= UHIDEV_STOPPED;
+	atomic_store_relaxed(>sc_state, scd->sc_state | UHIDEV_STOPPED);
 
 	/* If there's no output pipe at all, nothing to do.  */
 	if (sc->sc_opipe == NULL)
@@ -1052,9 +1055,21 @@ uhidev_close(struct uhidev *scd)
 	KASSERT(scd->sc_state & UHIDEV_OPEN);
 	uhidev_close_pipes(sc);
 	KASSERT(scd->sc_state & UHIDEV_OPEN);
-	scd->sc_state &= ~(UHIDEV_OPEN | UHIDEV_STOPPED);
+	atomic_store_relaxed(>sc_state,
+	scd->sc_state & ~(UHIDEV_OPEN | UHIDEV_STOPPED));
 
+	/*
+	 * Make sure the next uhidev_intr (which runs in softint, like
+	 * XC_HIGHPRI) notices that UHIDEV_OPEN is cleared, and wait
+	 * for any current one to finish, in case the pipe is still
+	 * open for other report ids.
+	 *
+	 * We must drop the lock while doing this, because
+	 * uhidev_write_callback takes the lock in softint context and
+	 * it could deadlock with the xcall softint.
+	 */
 	mutex_exit(>sc_lock);
+	xc_barrier(XC_HIGHPRI);
 }
 
 usbd_status



CVS commit: src/sys/dev/usb

2022-03-28 Thread Taylor R Campbell
Module Name:src
Committed By:   riastradh
Date:   Mon Mar 28 12:44:06 UTC 2022

Modified Files:
src/sys/dev/usb: uhidev.c

Log Message:
uhidev(9): Fix race between uhidev_close and uhidev_intr.

uhidev_intr currently relies on the kernel lock to serialize access
to struct uhidev::sc_state, but if the driver's sc_intr function
sleeps (which it may do, even though this runs is softint context --
it may sleep on an adaptive lock), uhidev_close might return while
the driver's sc_intr function is still in flight.

This avoids that race, and makes progress toward MP-safe uhidev.


To generate a diff of this commit:
cvs rdiff -u -r1.88 -r1.89 src/sys/dev/usb/uhidev.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.



CVS commit: src/sys/dev/usb

2022-03-28 Thread Taylor R Campbell
Module Name:src
Committed By:   riastradh
Date:   Mon Mar 28 12:43:58 UTC 2022

Modified Files:
src/sys/dev/usb: uhidev.c

Log Message:
uhidev(9): Refactor error branch to use one label.

No functional change intended.


To generate a diff of this commit:
cvs rdiff -u -r1.87 -r1.88 src/sys/dev/usb/uhidev.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/dev/usb/uhidev.c
diff -u src/sys/dev/usb/uhidev.c:1.87 src/sys/dev/usb/uhidev.c:1.88
--- src/sys/dev/usb/uhidev.c:1.87	Mon Mar 28 12:43:48 2022
+++ src/sys/dev/usb/uhidev.c	Mon Mar 28 12:43:58 2022
@@ -1,4 +1,4 @@
-/*	$NetBSD: uhidev.c,v 1.87 2022/03/28 12:43:48 riastradh Exp $	*/
+/*	$NetBSD: uhidev.c,v 1.88 2022/03/28 12:43:58 riastradh Exp $	*/
 
 /*
  * Copyright (c) 2001, 2012 The NetBSD Foundation, Inc.
@@ -35,7 +35,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: uhidev.c,v 1.87 2022/03/28 12:43:48 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: uhidev.c,v 1.88 2022/03/28 12:43:58 riastradh Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_usb.h"
@@ -919,27 +919,25 @@ uhidev_open(struct uhidev *scd)
 	/* Mark the report id open.  This is an exclusive lock.  */
 	if (scd->sc_state & UHIDEV_OPEN) {
 		error = EBUSY;
-		goto fail0;
+		goto out;
 	}
 	scd->sc_state |= UHIDEV_OPEN;
 
 	/* Open the pipes which are shared by all report ids.  */
 	error = uhidev_open_pipes(sc);
 	if (error)
-		goto fail1;
-
-	mutex_exit(>sc_lock);
+		goto out;
 
 	/* Success!  */
-	return 0;
+	error = 0;
 
-fail2: __unused
-	uhidev_close_pipes(sc);
-fail1:	KASSERTMSG(scd->sc_state & UHIDEV_OPEN,
-	"%s: report id %d: closed while opening",
-	device_xname(sc->sc_dev), scd->sc_report_id);
-	scd->sc_state &= ~UHIDEV_OPEN;
-fail0:	mutex_exit(>sc_lock);
+out:	if (error) {
+		KASSERTMSG(scd->sc_state & UHIDEV_OPEN,
+		"%s: report id %d: closed while opening",
+		device_xname(sc->sc_dev), scd->sc_report_id);
+		scd->sc_state &= ~UHIDEV_OPEN;
+	}
+	mutex_exit(>sc_lock);
 	return error;
 }
 



CVS commit: src/sys/dev/usb

2022-03-28 Thread Taylor R Campbell
Module Name:src
Committed By:   riastradh
Date:   Mon Mar 28 12:43:58 UTC 2022

Modified Files:
src/sys/dev/usb: uhidev.c

Log Message:
uhidev(9): Refactor error branch to use one label.

No functional change intended.


To generate a diff of this commit:
cvs rdiff -u -r1.87 -r1.88 src/sys/dev/usb/uhidev.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.



CVS commit: src/sys/dev/usb

2022-03-28 Thread Taylor R Campbell
Module Name:src
Committed By:   riastradh
Date:   Mon Mar 28 12:43:48 UTC 2022

Modified Files:
src/sys/dev/usb: uhidev.c

Log Message:
uhidev(9): Make some private functions static and fix comment.

No functional change.


To generate a diff of this commit:
cvs rdiff -u -r1.86 -r1.87 src/sys/dev/usb/uhidev.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/dev/usb/uhidev.c
diff -u src/sys/dev/usb/uhidev.c:1.86 src/sys/dev/usb/uhidev.c:1.87
--- src/sys/dev/usb/uhidev.c:1.86	Mon Mar 28 12:43:39 2022
+++ src/sys/dev/usb/uhidev.c	Mon Mar 28 12:43:48 2022
@@ -1,4 +1,4 @@
-/*	$NetBSD: uhidev.c,v 1.86 2022/03/28 12:43:39 riastradh Exp $	*/
+/*	$NetBSD: uhidev.c,v 1.87 2022/03/28 12:43:48 riastradh Exp $	*/
 
 /*
  * Copyright (c) 2001, 2012 The NetBSD Foundation, Inc.
@@ -35,7 +35,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: uhidev.c,v 1.86 2022/03/28 12:43:39 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: uhidev.c,v 1.87 2022/03/28 12:43:48 riastradh Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_usb.h"
@@ -124,10 +124,10 @@ int	uhidevdebug = 0;
 #define DPRINTFN(n,x)
 #endif
 
-Static void uhidev_intr(struct usbd_xfer *, void *, usbd_status);
+static void uhidev_intr(struct usbd_xfer *, void *, usbd_status);
 
-Static int uhidev_maxrepid(void *, int);
-Static int uhidevprint(void *, const char *);
+static int uhidev_maxrepid(void *, int);
+static int uhidevprint(void *, const char *);
 
 static int uhidev_match(device_t, cfdata_t, void *);
 static void uhidev_attach(device_t, device_t, void *);
@@ -444,7 +444,7 @@ uhidev_attach(device_t parent, device_t 
 	return;
 }
 
-int
+static int
 uhidev_maxrepid(void *buf, int len)
 {
 	struct hid_data *d;
@@ -460,7 +460,7 @@ uhidev_maxrepid(void *buf, int len)
 	return maxid;
 }
 
-int
+static int
 uhidevprint(void *aux, const char *pnp)
 {
 	struct uhidev_attach_arg *uha = aux;
@@ -573,7 +573,7 @@ uhidev_detach(device_t self, int flags)
 	return rv;
 }
 
-void
+static void
 uhidev_intr(struct usbd_xfer *xfer, void *addr, usbd_status status)
 {
 	struct uhidev_softc *sc = addr;
@@ -731,8 +731,8 @@ uhidev_open_pipes(struct uhidev_softc *s
 		return 0;
 
 	/*
-	 * Lock the configuration and release sc_lock we may sleep to
-	 * allocate.  If someone else got in first, we're done;
+	 * Lock the configuration and release sc_lock -- we may sleep
+	 * to allocate.  If someone else got in first, we're done;
 	 * otherwise open the pipes.
 	 */
 	error = uhidev_config_enter(sc);



CVS commit: src/sys/dev/usb

2022-03-28 Thread Taylor R Campbell
Module Name:src
Committed By:   riastradh
Date:   Mon Mar 28 12:43:48 UTC 2022

Modified Files:
src/sys/dev/usb: uhidev.c

Log Message:
uhidev(9): Make some private functions static and fix comment.

No functional change.


To generate a diff of this commit:
cvs rdiff -u -r1.86 -r1.87 src/sys/dev/usb/uhidev.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.



CVS commit: src/sys/dev/usb

2022-03-28 Thread Taylor R Campbell
Module Name:src
Committed By:   riastradh
Date:   Mon Mar 28 12:43:39 UTC 2022

Modified Files:
src/sys/dev/usb: uhidev.c uhidev.h

Log Message:
uhidev(9): Make uhidev_stop work reliably.


To generate a diff of this commit:
cvs rdiff -u -r1.85 -r1.86 src/sys/dev/usb/uhidev.c
cvs rdiff -u -r1.24 -r1.25 src/sys/dev/usb/uhidev.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/dev/usb/uhidev.c
diff -u src/sys/dev/usb/uhidev.c:1.85 src/sys/dev/usb/uhidev.c:1.86
--- src/sys/dev/usb/uhidev.c:1.85	Mon Mar 28 12:43:22 2022
+++ src/sys/dev/usb/uhidev.c	Mon Mar 28 12:43:39 2022
@@ -1,4 +1,4 @@
-/*	$NetBSD: uhidev.c,v 1.85 2022/03/28 12:43:22 riastradh Exp $	*/
+/*	$NetBSD: uhidev.c,v 1.86 2022/03/28 12:43:39 riastradh Exp $	*/
 
 /*
  * Copyright (c) 2001, 2012 The NetBSD Foundation, Inc.
@@ -35,7 +35,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: uhidev.c,v 1.85 2022/03/28 12:43:22 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: uhidev.c,v 1.86 2022/03/28 12:43:39 riastradh Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_usb.h"
@@ -96,6 +96,7 @@ struct uhidev_softc {
 	struct lwp *sc_configlock;
 	int sc_refcnt;
 	int sc_writereportid;
+	int sc_stopreportid;
 	u_char sc_dying;
 
 	/*
@@ -187,6 +188,10 @@ uhidev_attach(device_t parent, device_t 
 	cv_init(>sc_cv, "uhidev");
 	sc->sc_writelock = NULL;
 	sc->sc_configlock = NULL;
+	sc->sc_refcnt = 0;
+	sc->sc_writereportid = -1;
+	sc->sc_stopreportid = -1;
+	sc->sc_dying = false;
 
 	id = usbd_get_interface_descriptor(iface);
 
@@ -938,21 +943,72 @@ fail0:	mutex_exit(>sc_lock);
 	return error;
 }
 
+/*
+ * uhidev_stop(scd)
+ *
+ *	Make all current and future output reports or xfers by scd to
+ *	the output pipe to fail.  Caller must then ensure no more will
+ *	be submitted and then call uhidev_close.
+ *
+ *	Side effect: If uhidev_write was in progress for this scd,
+ *	blocks all other uhidev_writes until uhidev_close on this scd.
+ *
+ *	May sleep but only for a short duration to wait for USB
+ *	transfer completion callbacks to run.
+ */
 void
 uhidev_stop(struct uhidev *scd)
 {
 	struct uhidev_softc *sc = scd->sc_parent;
-	bool abort = false;
 
 	mutex_enter(>sc_lock);
-	if (sc->sc_writereportid == scd->sc_report_id)
-		abort = true;
+
+	/* Prevent further writes on this report from starting.  */
+	scd->sc_state |= UHIDEV_STOPPED;
+
+	/* If there's no output pipe at all, nothing to do.  */
+	if (sc->sc_opipe == NULL)
+		goto out;
+
+	/*
+	 * If there's no write on this report in progress, nothing to
+	 * do -- any subsequent attempts will be prevented by
+	 * UHIDEV_STOPPED.
+	 */
+	if (sc->sc_writereportid != scd->sc_report_id)
+		goto out;
+
+	/*
+	 * Caller must wait for uhidev_open to succeed before calling
+	 * uhidev_write, and must wait for all uhidev_writes to return
+	 * before calling uhidev_close, so neither on can be in flight
+	 * right now.
+	 *
+	 * Suspend the pipe, but hold up uhidev_write from any report
+	 * until we confirm this one has finished.  We will resume the
+	 * pipe only after all uhidev_writes on this report have
+	 * finished -- when the caller calls uhidev_close.
+	 */
+	KASSERTMSG(sc->sc_stopreportid == -1, "%d", sc->sc_stopreportid);
+	sc->sc_stopreportid = scd->sc_report_id;
 	mutex_exit(>sc_lock);
 
-	if (abort && sc->sc_opipe) /* XXX sc_opipe might go away */
-		usbd_abort_pipe(sc->sc_opipe);
+	usbd_suspend_pipe(sc->sc_opipe);
+
+	mutex_enter(>sc_lock);
+	KASSERT(sc->sc_stopreportid == scd->sc_report_id);
+	sc->sc_stopreportid = scd->sc_report_id;
+	cv_broadcast(>sc_cv);
+out:	mutex_exit(>sc_lock);
 }
 
+/*
+ * uhidev_close(scd)
+ *
+ *	Close a uhidev previously opened with uhidev_open.  If writes
+ *	had been stopped with uhidev_stop, allow writes at other report
+ *	ids again.
+ */
 void
 uhidev_close(struct uhidev *scd)
 {
@@ -970,11 +1026,35 @@ uhidev_close(struct uhidev *scd)
 	KASSERTMSG(scd->sc_state & UHIDEV_OPEN,
 	"%s: report id %d: unpaired close",
 	device_xname(sc->sc_dev), scd->sc_report_id);
+
+	/*
+	 * If the caller had issued uhidev_stop to interrupt a write
+	 * for this report, then resume the pipe now that no further
+	 * uhidev_write on the same report is possible, and wake anyone
+	 * trying to write on other reports.
+	 */
+	if (sc->sc_stopreportid == scd->sc_report_id) {
+		KASSERT(scd->sc_state & UHIDEV_STOPPED);
+		mutex_exit(>sc_lock);
+
+		usbd_resume_pipe(sc->sc_opipe);
+
+		mutex_enter(>sc_lock);
+		KASSERT(sc->sc_stopreportid == scd->sc_report_id);
+		KASSERT(scd->sc_state & UHIDEV_STOPPED);
+		sc->sc_stopreportid = -1;
+		cv_broadcast(>sc_cv);
+	}
+
+	/*
+	 * Close our reference to the pipes, and mark our report as no
+	 * longer open.  If it was stopped, clear that too -- drivers
+	 * are forbidden from issuing writes after uhidev_close anyway.
+	 */
+	KASSERT(scd->sc_state & UHIDEV_OPEN);
 	uhidev_close_pipes(sc);
-	KASSERTMSG(scd->sc_state & UHIDEV_OPEN,
-	"%s: 

CVS commit: src/sys/dev/usb

2022-03-28 Thread Taylor R Campbell
Module Name:src
Committed By:   riastradh
Date:   Mon Mar 28 12:43:39 UTC 2022

Modified Files:
src/sys/dev/usb: uhidev.c uhidev.h

Log Message:
uhidev(9): Make uhidev_stop work reliably.


To generate a diff of this commit:
cvs rdiff -u -r1.85 -r1.86 src/sys/dev/usb/uhidev.c
cvs rdiff -u -r1.24 -r1.25 src/sys/dev/usb/uhidev.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.



CVS commit: src/sys/dev/usb

2022-03-28 Thread Taylor R Campbell
Module Name:src
Committed By:   riastradh
Date:   Mon Mar 28 12:43:30 UTC 2022

Modified Files:
src/sys/dev/usb: ucycom.c

Log Message:
ucycom(4): Defer uhidev_write_async to taskq.

Can't submit USB transfers while holding tty_lock, a spin lock.


To generate a diff of this commit:
cvs rdiff -u -r1.53 -r1.54 src/sys/dev/usb/ucycom.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/dev/usb/ucycom.c
diff -u src/sys/dev/usb/ucycom.c:1.53 src/sys/dev/usb/ucycom.c:1.54
--- src/sys/dev/usb/ucycom.c:1.53	Mon Mar 28 12:43:03 2022
+++ src/sys/dev/usb/ucycom.c	Mon Mar 28 12:43:30 2022
@@ -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 
-__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 @@ int	ucycomdebug = 20;
 
 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 @@ const struct cdevsw ucycom_cdevsw = {
 
 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 @@ ucycom_attach(device_t parent, device_t 
 	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, , );
@@ -237,6 +241,9 @@ ucycom_attach(device_t parent, device_t 
 
 	sc->sc_msr = sc->sc_mcr = 0;
 
+	/* not MP-safe */
+	usb_init_task(>sc_task, ucycomstarttask, sc, 0);
+
 	/* set up tty */
 	sc->sc_tty = tty_alloc();
 	sc->sc_tty->t_sc = sc;
@@ -287,6 +294,8 @@ ucycom_detach(device_t self, int flags)
 	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_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 @@ ucycomstart(struct tty *tp)
 	u_char *data;
 	int cnt, len, s;
 
+	KASSERT(mutex_owned(_lock));
+
 	if (sc->sc_dying)
 		return;
 
@@ -592,6 +603,19 @@ ucycomstart(struct tty *tp)
 	}
 #endif
 	DPRINTFN(4,("ucycomstart: %d chars\n", len));
+	usb_add_task(sc->sc_udev, >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_hdev, sc->sc_obuf, sc->sc_olen, 0,
 	USBD_NO_TIMEOUT, ucycomwritecb, sc);
@@ -599,11 +623,9 @@ ucycomstart(struct tty *tp)
 #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



CVS commit: src/sys/dev/usb

2022-03-28 Thread Taylor R Campbell
Module Name:src
Committed By:   riastradh
Date:   Mon Mar 28 12:43:30 UTC 2022

Modified Files:
src/sys/dev/usb: ucycom.c

Log Message:
ucycom(4): Defer uhidev_write_async to taskq.

Can't submit USB transfers while holding tty_lock, a spin lock.


To generate a diff of this commit:
cvs rdiff -u -r1.53 -r1.54 src/sys/dev/usb/ucycom.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.



CVS commit: src/sys/dev/usb

2022-03-28 Thread Taylor R Campbell
Module Name:src
Committed By:   riastradh
Date:   Mon Mar 28 12:43:22 UTC 2022

Modified Files:
src/sys/dev/usb: uhidev.c uhidev.h

Log Message:
uhidev(9): Move struct uhidev_softc into uhidev.c.

No longer part of any ABI for uhidev modules.


To generate a diff of this commit:
cvs rdiff -u -r1.84 -r1.85 src/sys/dev/usb/uhidev.c
cvs rdiff -u -r1.23 -r1.24 src/sys/dev/usb/uhidev.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/dev/usb/uhidev.c
diff -u src/sys/dev/usb/uhidev.c:1.84 src/sys/dev/usb/uhidev.c:1.85
--- src/sys/dev/usb/uhidev.c:1.84	Mon Mar 28 12:43:03 2022
+++ src/sys/dev/usb/uhidev.c	Mon Mar 28 12:43:22 2022
@@ -1,4 +1,4 @@
-/*	$NetBSD: uhidev.c,v 1.84 2022/03/28 12:43:03 riastradh Exp $	*/
+/*	$NetBSD: uhidev.c,v 1.85 2022/03/28 12:43:22 riastradh Exp $	*/
 
 /*
  * Copyright (c) 2001, 2012 The NetBSD Foundation, Inc.
@@ -35,7 +35,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: uhidev.c,v 1.84 2022/03/28 12:43:03 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: uhidev.c,v 1.85 2022/03/28 12:43:22 riastradh Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_usb.h"
@@ -74,6 +74,46 @@ __KERNEL_RCSID(0, "$NetBSD: uhidev.c,v 1
 
 #include "locators.h"
 
+struct uhidev_softc {
+	device_t sc_dev;		/* base device */
+	struct usbd_device *sc_udev;
+	struct usbd_interface *sc_iface;	/* interface */
+	int sc_iep_addr;
+	int sc_oep_addr;
+	u_int sc_isize;
+
+	int sc_repdesc_size;
+	void *sc_repdesc;
+
+	u_int sc_nrepid;
+	device_t *sc_subdevs;
+
+	kmutex_t sc_lock;
+	kcondvar_t sc_cv;
+
+	/* Read/written under sc_lock.  */
+	struct lwp *sc_writelock;
+	struct lwp *sc_configlock;
+	int sc_refcnt;
+	int sc_writereportid;
+	u_char sc_dying;
+
+	/*
+	 * - Read under sc_lock, provided sc_refcnt > 0.
+	 * - Written under sc_configlock only when transitioning to and
+	 *   from sc_refcnt = 0.
+	 */
+	u_char *sc_ibuf;
+	struct usbd_pipe *sc_ipipe;	/* input interrupt pipe */
+	struct usbd_pipe *sc_opipe;	/* output interrupt pipe */
+	struct usbd_xfer *sc_oxfer;	/* write request */
+	usbd_callback sc_writecallback;	/* async write request callback */
+	void *sc_writecookie;
+
+	u_int sc_flags;
+#define UHIDEV_F_XB1	0x0001	/* Xbox 1 controller */
+};
+
 #ifdef UHIDEV_DEBUG
 #define DPRINTF(x)	if (uhidevdebug) printf x
 #define DPRINTFN(n,x)	if (uhidevdebug>(n)) printf x

Index: src/sys/dev/usb/uhidev.h
diff -u src/sys/dev/usb/uhidev.h:1.23 src/sys/dev/usb/uhidev.h:1.24
--- src/sys/dev/usb/uhidev.h:1.23	Mon Mar 28 12:43:03 2022
+++ src/sys/dev/usb/uhidev.h	Mon Mar 28 12:43:22 2022
@@ -1,4 +1,4 @@
-/*	$NetBSD: uhidev.h,v 1.23 2022/03/28 12:43:03 riastradh Exp $	*/
+/*	$NetBSD: uhidev.h,v 1.24 2022/03/28 12:43:22 riastradh Exp $	*/
 
 /*
  * Copyright (c) 2001 The NetBSD Foundation, Inc.
@@ -35,46 +35,6 @@
 
 #include 
 
-struct uhidev_softc {
-	device_t sc_dev;		/* base device */
-	struct usbd_device *sc_udev;
-	struct usbd_interface *sc_iface;	/* interface */
-	int sc_iep_addr;
-	int sc_oep_addr;
-	u_int sc_isize;
-
-	int sc_repdesc_size;
-	void *sc_repdesc;
-
-	u_int sc_nrepid;
-	device_t *sc_subdevs;
-
-	kmutex_t sc_lock;
-	kcondvar_t sc_cv;
-
-	/* Read/written under sc_lock.  */
-	struct lwp *sc_writelock;
-	struct lwp *sc_configlock;
-	int sc_refcnt;
-	int sc_writereportid;
-	u_char sc_dying;
-
-	/*
-	 * - Read under sc_lock, provided sc_refcnt > 0.
-	 * - Written under sc_configlock only when transitioning to and
-	 *   from sc_refcnt = 0.
-	 */
-	u_char *sc_ibuf;
-	struct usbd_pipe *sc_ipipe;	/* input interrupt pipe */
-	struct usbd_pipe *sc_opipe;	/* output interrupt pipe */
-	struct usbd_xfer *sc_oxfer;	/* write request */
-	usbd_callback sc_writecallback;	/* async write request callback */
-	void *sc_writecookie;
-
-	u_int sc_flags;
-#define UHIDEV_F_XB1	0x0001	/* Xbox 1 controller */
-};
-
 struct uhidev {
 	device_t sc_dev;		/* base device */
 	struct uhidev_softc *sc_parent;



CVS commit: src/sys/dev/usb

2022-03-28 Thread Taylor R Campbell
Module Name:src
Committed By:   riastradh
Date:   Mon Mar 28 12:43:22 UTC 2022

Modified Files:
src/sys/dev/usb: uhidev.c uhidev.h

Log Message:
uhidev(9): Move struct uhidev_softc into uhidev.c.

No longer part of any ABI for uhidev modules.


To generate a diff of this commit:
cvs rdiff -u -r1.84 -r1.85 src/sys/dev/usb/uhidev.c
cvs rdiff -u -r1.23 -r1.24 src/sys/dev/usb/uhidev.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.



CVS commit: src/sys

2022-03-28 Thread Taylor R Campbell
Module Name:src
Committed By:   riastradh
Date:   Mon Mar 28 12:43:12 UTC 2022

Modified Files:
src/sys/arch/macppc/dev: pbms.c
src/sys/dev/usb: uatp.c uhid.c ukbd.c ums.c uthum.c

Log Message:
uhidev(9): Get the device and interface through attach args.

This way uhidev drivers don't need access to uhidev_softc itself for
it.


To generate a diff of this commit:
cvs rdiff -u -r1.19 -r1.20 src/sys/arch/macppc/dev/pbms.c
cvs rdiff -u -r1.27 -r1.28 src/sys/dev/usb/uatp.c
cvs rdiff -u -r1.121 -r1.122 src/sys/dev/usb/uhid.c
cvs rdiff -u -r1.157 -r1.158 src/sys/dev/usb/ukbd.c
cvs rdiff -u -r1.101 -r1.102 src/sys/dev/usb/ums.c
cvs rdiff -u -r1.21 -r1.22 src/sys/dev/usb/uthum.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/arch/macppc/dev/pbms.c
diff -u src/sys/arch/macppc/dev/pbms.c:1.19 src/sys/arch/macppc/dev/pbms.c:1.20
--- src/sys/arch/macppc/dev/pbms.c:1.19	Sat Aug  7 16:18:57 2021
+++ src/sys/arch/macppc/dev/pbms.c	Mon Mar 28 12:43:12 2022
@@ -1,4 +1,4 @@
-/* $Id: pbms.c,v 1.19 2021/08/07 16:18:57 thorpej Exp $ */
+/* $Id: pbms.c,v 1.20 2022/03/28 12:43:12 riastradh Exp $ */
 
 /*
  * Copyright (c) 2005, Johan Wallén
@@ -307,7 +307,8 @@ pbms_match(device_t parent, cfdata_t mat
 	 * we expect. 
 	 */
 	if (uha->uiaa->uiaa_proto == UIPROTO_MOUSE &&
-	(udd = usbd_get_device_descriptor(uha->parent->sc_udev)) != NULL) {
+	((udd = usbd_get_device_descriptor(uha->uiaa->uiaa_device))
+		!= NULL)) {
 		vendor = UGETW(udd->idVendor);
 		product = UGETW(udd->idProduct);
 		for (i = 0; i < PBMS_NUM_DEVICES; i++) {
@@ -329,6 +330,7 @@ pbms_attach(device_t parent, device_t se
 	struct uhidev_attach_arg *uha = aux;
 	struct pbms_dev *pd;
 	struct pbms_softc *sc = device_private(self);
+	struct usbd_device *udev;
 	usb_device_descriptor_t *udd;
 	int i;
 	uint16_t vendor, product;
@@ -341,7 +343,8 @@ pbms_attach(device_t parent, device_t se
 	sc->sc_datalen = PBMS_DATA_LEN;
 
 	/* Fill in device-specific parameters. */
-	if ((udd = usbd_get_device_descriptor(uha->parent->sc_udev)) != NULL) {
+	udev = uha->uiaa->uiaa_udevice;
+	if ((udd = usbd_get_device_descriptor(udev)) != NULL) {
 		product = UGETW(udd->idProduct);
 		vendor = UGETW(udd->idVendor);
 		for (i = 0; i < PBMS_NUM_DEVICES; i++) {

Index: src/sys/dev/usb/uatp.c
diff -u src/sys/dev/usb/uatp.c:1.27 src/sys/dev/usb/uatp.c:1.28
--- src/sys/dev/usb/uatp.c:1.27	Sat Aug  7 16:19:17 2021
+++ src/sys/dev/usb/uatp.c	Mon Mar 28 12:43:12 2022
@@ -1,4 +1,4 @@
-/*	$NetBSD: uatp.c,v 1.27 2021/08/07 16:19:17 thorpej Exp $	*/
+/*	$NetBSD: uatp.c,v 1.28 2022/03/28 12:43:12 riastradh Exp $	*/
 
 /*-
  * Copyright (c) 2011-2014 The NetBSD Foundation, Inc.
@@ -146,7 +146,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: uatp.c,v 1.27 2021/08/07 16:19:17 thorpej Exp $");
+__KERNEL_RCSID(0, "$NetBSD: uatp.c,v 1.28 2022/03/28 12:43:12 riastradh Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_usb.h"
@@ -486,7 +486,8 @@ static const struct uatp_knobs default_k
 };
 
 struct uatp_softc {
-	struct uhidev sc_hdev;		/* USB parent.  */
+	struct uhidev sc_hdev;		/* uhidev(9) parent.  */
+	struct usbd_device *sc_udev;	/* USB device.  */
 	device_t sc_wsmousedev;		/* Attached wsmouse device.  */
 	const struct uatp_parameters *sc_parameters;
 	struct uatp_knobs sc_knobs;
@@ -936,6 +937,8 @@ uatp_attach(device_t parent, device_t se
 	sc->sc_hdev.sc_parent = uha->parent;
 	sc->sc_hdev.sc_report_id = uha->reportid;
 
+	sc->sc_udev = uha->uiaa->uiaa_device;
+
 	/* Identify ourselves to dmesg.  */
 	uatp_descriptor = find_uatp_descriptor(uha);
 	KASSERT(uatp_descriptor != NULL);
@@ -1296,7 +1299,7 @@ uatp_ioctl(void *v, unsigned long cmd, v
 static void
 geyser34_enable_raw_mode(struct uatp_softc *sc)
 {
-	struct usbd_device *udev = sc->sc_hdev.sc_parent->sc_udev;
+	struct usbd_device *udev = sc->sc_udev;
 	usb_device_request_t req;
 	usbd_status status;
 	uint8_t report[GEYSER34_MODE_PACKET_SIZE];
@@ -1368,8 +1371,8 @@ geyser34_finalize(struct uatp_softc *sc)
 {
 
 	DPRINTF(sc, UATP_DEBUG_MISC, ("finalizing\n"));
-	usb_rem_task_wait(sc->sc_hdev.sc_parent->sc_udev, >sc_reset_task,
-	USB_TASKQ_DRIVER, NULL);
+	usb_rem_task_wait(sc->sc_udev, >sc_reset_task, USB_TASKQ_DRIVER,
+	NULL);
 
 	return 0;
 }
@@ -1379,8 +1382,7 @@ geyser34_deferred_reset(struct uatp_soft
 {
 
 	DPRINTF(sc, UATP_DEBUG_RESET, ("deferring reset\n"));
-	usb_add_task(sc->sc_hdev.sc_parent->sc_udev, >sc_reset_task,
-	USB_TASKQ_DRIVER);
+	usb_add_task(sc->sc_udev, >sc_reset_task, USB_TASKQ_DRIVER);
 }
 
 static void

Index: src/sys/dev/usb/uhid.c
diff -u src/sys/dev/usb/uhid.c:1.121 src/sys/dev/usb/uhid.c:1.122
--- src/sys/dev/usb/uhid.c:1.121	Mon Mar 28 12:42:54 2022
+++ src/sys/dev/usb/uhid.c	Mon Mar 28 12:43:12 2022
@@ -1,4 +1,4 @@
-/*	$NetBSD: uhid.c,v 1.121 2022/03/28 12:42:54 riastradh Exp $	*/
+/*	$NetBSD: uhid.c,v 1.122 2022/03/28 12:43:12 riastradh Exp $	*/
 
 /*
  * Copyright 

CVS commit: src/sys

2022-03-28 Thread Taylor R Campbell
Module Name:src
Committed By:   riastradh
Date:   Mon Mar 28 12:43:12 UTC 2022

Modified Files:
src/sys/arch/macppc/dev: pbms.c
src/sys/dev/usb: uatp.c uhid.c ukbd.c ums.c uthum.c

Log Message:
uhidev(9): Get the device and interface through attach args.

This way uhidev drivers don't need access to uhidev_softc itself for
it.


To generate a diff of this commit:
cvs rdiff -u -r1.19 -r1.20 src/sys/arch/macppc/dev/pbms.c
cvs rdiff -u -r1.27 -r1.28 src/sys/dev/usb/uatp.c
cvs rdiff -u -r1.121 -r1.122 src/sys/dev/usb/uhid.c
cvs rdiff -u -r1.157 -r1.158 src/sys/dev/usb/ukbd.c
cvs rdiff -u -r1.101 -r1.102 src/sys/dev/usb/ums.c
cvs rdiff -u -r1.21 -r1.22 src/sys/dev/usb/uthum.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.



CVS commit: src/sys/dev/usb

2022-03-28 Thread Taylor R Campbell
Module Name:src
Committed By:   riastradh
Date:   Mon Mar 28 12:43:03 UTC 2022

Modified Files:
src/sys/dev/usb: ucycom.c uhidev.c uhidev.h

Log Message:
uhidev(9): New uhidev_write_async.

Like uhidev_write but issues the transfer asynchronously with a
callback.

Use it in ucycom(4).

Also, clear endpoint stalls asynchronously -- can't do them
synchronously in xfer callbacks which run at softint and therefore
can't wait in cv_wait as usbd_do_request does.


To generate a diff of this commit:
cvs rdiff -u -r1.52 -r1.53 src/sys/dev/usb/ucycom.c
cvs rdiff -u -r1.83 -r1.84 src/sys/dev/usb/uhidev.c
cvs rdiff -u -r1.22 -r1.23 src/sys/dev/usb/uhidev.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/dev/usb/ucycom.c
diff -u src/sys/dev/usb/ucycom.c:1.52 src/sys/dev/usb/ucycom.c:1.53
--- src/sys/dev/usb/ucycom.c:1.52	Mon Mar 28 12:42:54 2022
+++ src/sys/dev/usb/ucycom.c	Mon Mar 28 12:43:03 2022
@@ -1,4 +1,4 @@
-/*	$NetBSD: ucycom.c,v 1.52 2022/03/28 12:42:54 riastradh Exp $	*/
+/*	$NetBSD: ucycom.c,v 1.53 2022/03/28 12:43:03 riastradh Exp $	*/
 
 /*
  * Copyright (c) 2005 The NetBSD Foundation, Inc.
@@ -38,7 +38,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: ucycom.c,v 1.52 2022/03/28 12:42:54 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ucycom.c,v 1.53 2022/03/28 12:43:03 riastradh Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_usb.h"
@@ -592,11 +592,9 @@ ucycomstart(struct tty *tp)
 	}
 #endif
 	DPRINTFN(4,("ucycomstart: %d chars\n", len));
-	usbd_setup_xfer(sc->sc_hdev.sc_parent->sc_oxfer, sc, sc->sc_obuf,
-	sc->sc_olen, 0, USBD_NO_TIMEOUT, ucycomwritecb);
-
 	/* What can we do on error? */
-	err = usbd_transfer(sc->sc_hdev.sc_parent->sc_oxfer);
+	err = uhidev_write_async(>sc_hdev, sc->sc_obuf, sc->sc_olen, 0,
+	USBD_NO_TIMEOUT, ucycomwritecb, sc);
 
 #ifdef UCYCOM_DEBUG
 	if (err != USBD_IN_PROGRESS)
@@ -621,7 +619,6 @@ ucycomwritecb(struct usbd_xfer *xfer, vo
 
 	if (status) {
 		DPRINTF(("ucycomwritecb: status=%d\n", status));
-		usbd_clear_endpoint_stall(sc->sc_hdev.sc_parent->sc_opipe);
 		/* XXX we should restart after some delay. */
 		goto error;
 	}

Index: src/sys/dev/usb/uhidev.c
diff -u src/sys/dev/usb/uhidev.c:1.83 src/sys/dev/usb/uhidev.c:1.84
--- src/sys/dev/usb/uhidev.c:1.83	Mon Mar 28 12:42:54 2022
+++ src/sys/dev/usb/uhidev.c	Mon Mar 28 12:43:03 2022
@@ -1,4 +1,4 @@
-/*	$NetBSD: uhidev.c,v 1.83 2022/03/28 12:42:54 riastradh Exp $	*/
+/*	$NetBSD: uhidev.c,v 1.84 2022/03/28 12:43:03 riastradh Exp $	*/
 
 /*
  * Copyright (c) 2001, 2012 The NetBSD Foundation, Inc.
@@ -35,7 +35,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: uhidev.c,v 1.83 2022/03/28 12:42:54 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: uhidev.c,v 1.84 2022/03/28 12:43:03 riastradh Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_usb.h"
@@ -1025,3 +1025,74 @@ uhidev_write(struct uhidev *scd, void *d
 out:	mutex_exit(>sc_lock);
 	return err;
 }
+
+static void
+uhidev_write_callback(struct usbd_xfer *xfer, void *cookie, usbd_status err)
+{
+	struct uhidev_softc *sc = cookie;
+	usbd_callback writecallback;
+	void *writecookie;
+
+	if (err) {
+		if (err != USBD_CANCELLED)
+			usbd_clear_endpoint_stall_async(sc->sc_opipe);
+	}
+
+	mutex_enter(>sc_lock);
+	KASSERT(sc->sc_writelock == (void *)1);
+	writecallback = sc->sc_writecallback;
+	writecookie = sc->sc_writecookie;
+	sc->sc_writereportid = -1;
+	sc->sc_writelock = NULL;
+	sc->sc_writecallback = NULL;
+	sc->sc_writecookie = NULL;
+	cv_broadcast(>sc_cv);
+	mutex_exit(>sc_lock);
+
+	(*writecallback)(xfer, writecookie, err);
+}
+
+usbd_status
+uhidev_write_async(struct uhidev *scd, void *data, int len, int flags,
+int timo, usbd_callback writecallback, void *writecookie)
+{
+	struct uhidev_softc *sc = scd->sc_parent;
+	usbd_status err;
+
+	DPRINTF(("%s: data=%p, len=%d\n", __func__, data, len));
+
+	if (sc->sc_opipe == NULL)
+		return USBD_INVAL;
+
+	mutex_enter(>sc_lock);
+	KASSERT(sc->sc_refcnt);
+	if (sc->sc_dying) {
+		err = USBD_IOERROR;
+		goto out;
+	}
+	if (sc->sc_writelock != NULL) {
+		err = USBD_IN_USE;
+		goto out;
+	}
+	sc->sc_writelock = (void *)1; /* XXX no lwp to attribute async xfer */
+	sc->sc_writereportid = scd->sc_report_id;
+	sc->sc_writecallback = writecallback;
+	sc->sc_writecookie = writecookie;
+	usbd_setup_xfer(sc->sc_oxfer, sc, data, len, flags, timo,
+	uhidev_write_callback);
+	err = usbd_transfer(sc->sc_oxfer);
+	switch (err) {
+	case USBD_IN_PROGRESS:
+		break;
+	case USBD_NORMAL_COMPLETION:
+		panic("unexpected normal completion of async xfer under lock");
+	default:		/* error */
+		sc->sc_writelock = NULL;
+		sc->sc_writereportid = -1;
+		sc->sc_writecallback = NULL;
+		sc->sc_writecookie = NULL;
+		cv_broadcast(>sc_cv);
+	}
+out:	mutex_exit(>sc_lock);
+	return err;
+}

Index: src/sys/dev/usb/uhidev.h
diff -u src/sys/dev/usb/uhidev.h:1.22 src/sys/dev/usb/uhidev.h:1.23
--- src/sys/dev/usb/uhidev.h:1.22	Mon Mar 

CVS commit: src/sys/dev/usb

2022-03-28 Thread Taylor R Campbell
Module Name:src
Committed By:   riastradh
Date:   Mon Mar 28 12:43:03 UTC 2022

Modified Files:
src/sys/dev/usb: ucycom.c uhidev.c uhidev.h

Log Message:
uhidev(9): New uhidev_write_async.

Like uhidev_write but issues the transfer asynchronously with a
callback.

Use it in ucycom(4).

Also, clear endpoint stalls asynchronously -- can't do them
synchronously in xfer callbacks which run at softint and therefore
can't wait in cv_wait as usbd_do_request does.


To generate a diff of this commit:
cvs rdiff -u -r1.52 -r1.53 src/sys/dev/usb/ucycom.c
cvs rdiff -u -r1.83 -r1.84 src/sys/dev/usb/uhidev.c
cvs rdiff -u -r1.22 -r1.23 src/sys/dev/usb/uhidev.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.



CVS commit: src/sys/dev/usb

2022-03-28 Thread Taylor R Campbell
Module Name:src
Committed By:   riastradh
Date:   Mon Mar 28 12:42:54 UTC 2022

Modified Files:
src/sys/dev/usb: ucycom.c uhid.c uhidev.c uhidev.h

Log Message:
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


To generate a diff of this commit:
cvs rdiff -u -r1.51 -r1.52 src/sys/dev/usb/ucycom.c
cvs rdiff -u -r1.120 -r1.121 src/sys/dev/usb/uhid.c
cvs rdiff -u -r1.82 -r1.83 src/sys/dev/usb/uhidev.c
cvs rdiff -u -r1.21 -r1.22 src/sys/dev/usb/uhidev.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/dev/usb/ucycom.c
diff -u src/sys/dev/usb/ucycom.c:1.51 src/sys/dev/usb/ucycom.c:1.52
--- src/sys/dev/usb/ucycom.c:1.51	Sat Mar 14 02:35:33 2020
+++ src/sys/dev/usb/ucycom.c	Mon Mar 28 12:42:54 2022
@@ -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 
-__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 *s
 	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_hdev, sc->sc_obuf, sc->sc_olen);
 	if (err) {
 		DPRINTF(("ucycom_set_status: err=%d\n", err));
 	}

Index: src/sys/dev/usb/uhid.c
diff -u src/sys/dev/usb/uhid.c:1.120 src/sys/dev/usb/uhid.c:1.121
--- src/sys/dev/usb/uhid.c:1.120	Mon Mar 28 12:42:45 2022
+++ src/sys/dev/usb/uhid.c	Mon Mar 28 12:42:54 2022
@@ -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 
-__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, in
 #endif
 	if (!error) {
 		if (sc->sc_raw)
-			err = uhidev_write(sc->sc_hdev.sc_parent, sc->sc_obuf,
-			size);
+			err = uhidev_write(>sc_hdev, sc->sc_obuf, size);
 		else
 			err = uhidev_set_report(>sc_hdev,
 			UHID_OUTPUT_REPORT, sc->sc_obuf, size);

Index: src/sys/dev/usb/uhidev.c
diff -u src/sys/dev/usb/uhidev.c:1.82 src/sys/dev/usb/uhidev.c:1.83
--- src/sys/dev/usb/uhidev.c:1.82	Wed Feb  9 18:09:48 2022
+++ src/sys/dev/usb/uhidev.c	Mon Mar 28 12:42:54 2022
@@ -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 
-__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_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, in
 }
 
 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, vo
 		}
 	}
 	sc->sc_writelock = curlwp;
+	sc->sc_writereportid = scd->sc_report_id;
 	mutex_exit(>sc_lock);
 
 #ifdef UHIDEV_DEBUG
@@ -1014,6 +1016,10 @@ uhidev_write(struct uhidev_softc *sc, vo
 	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: 

CVS commit: src/sys/dev/usb

2022-03-28 Thread Taylor R Campbell
Module Name:src
Committed By:   riastradh
Date:   Mon Mar 28 12:42:54 UTC 2022

Modified Files:
src/sys/dev/usb: ucycom.c uhid.c uhidev.c uhidev.h

Log Message:
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


To generate a diff of this commit:
cvs rdiff -u -r1.51 -r1.52 src/sys/dev/usb/ucycom.c
cvs rdiff -u -r1.120 -r1.121 src/sys/dev/usb/uhid.c
cvs rdiff -u -r1.82 -r1.83 src/sys/dev/usb/uhidev.c
cvs rdiff -u -r1.21 -r1.22 src/sys/dev/usb/uhidev.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.



CVS commit: src/sys/dev/usb

2022-03-28 Thread Taylor R Campbell
Module Name:src
Committed By:   riastradh
Date:   Mon Mar 28 12:42:45 UTC 2022

Modified Files:
src/sys/dev/usb: uhid.c

Log Message:
uhid(4): Use d_cfdriver/devtounit/cancel to avoid open/detach races.

- Split uhidclose into separate uhidcancel and uhidclose parts.
  uhidcancel interrupts pending I/O operations (open, read, write,
  ioctl, ); uhidclose doesn't run until all I/O operations are
  done.

- Handle case where, owing to revoke(2), uhidcancel/uhidclose run
  concurrently with a uhidopen that hasn't yet noticed that there
  isn't actually a device.

- Handle case where, owing to revoke(2), uhidread might be cancelled
  by mere revoke, not by detach, so it has to wake up when the device
  is closing, not (just) when dying (but dying will lead to closing
  so no need to check for dying).

- Omit needless reference-counting goo.  vdevgone takes care of this
  for us by cancelling all I/O operations with uhidcancel, waiting
  for I/O operations to drain, closing the device, and waiting until
  it is closed if that is already happening concurrently.

- Name the closed/changing/open states rather than using 0/1/2.

- Omit needless sc_dying.


To generate a diff of this commit:
cvs rdiff -u -r1.119 -r1.120 src/sys/dev/usb/uhid.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.



CVS commit: src/sys/dev/usb

2022-03-28 Thread Taylor R Campbell
Module Name:src
Committed By:   riastradh
Date:   Mon Mar 28 12:42:45 UTC 2022

Modified Files:
src/sys/dev/usb: uhid.c

Log Message:
uhid(4): Use d_cfdriver/devtounit/cancel to avoid open/detach races.

- Split uhidclose into separate uhidcancel and uhidclose parts.
  uhidcancel interrupts pending I/O operations (open, read, write,
  ioctl, ); uhidclose doesn't run until all I/O operations are
  done.

- Handle case where, owing to revoke(2), uhidcancel/uhidclose run
  concurrently with a uhidopen that hasn't yet noticed that there
  isn't actually a device.

- Handle case where, owing to revoke(2), uhidread might be cancelled
  by mere revoke, not by detach, so it has to wake up when the device
  is closing, not (just) when dying (but dying will lead to closing
  so no need to check for dying).

- Omit needless reference-counting goo.  vdevgone takes care of this
  for us by cancelling all I/O operations with uhidcancel, waiting
  for I/O operations to drain, closing the device, and waiting until
  it is closed if that is already happening concurrently.

- Name the closed/changing/open states rather than using 0/1/2.

- Omit needless sc_dying.


To generate a diff of this commit:
cvs rdiff -u -r1.119 -r1.120 src/sys/dev/usb/uhid.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/dev/usb/uhid.c
diff -u src/sys/dev/usb/uhid.c:1.119 src/sys/dev/usb/uhid.c:1.120
--- src/sys/dev/usb/uhid.c:1.119	Sun Sep 26 15:07:17 2021
+++ src/sys/dev/usb/uhid.c	Mon Mar 28 12:42:45 2022
@@ -1,4 +1,4 @@
-/*	$NetBSD: uhid.c,v 1.119 2021/09/26 15:07:17 thorpej Exp $	*/
+/*	$NetBSD: uhid.c,v 1.120 2022/03/28 12:42:45 riastradh Exp $	*/
 
 /*
  * Copyright (c) 1998, 2004, 2008, 2012 The NetBSD Foundation, Inc.
@@ -35,7 +35,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: uhid.c,v 1.119 2021/09/26 15:07:17 thorpej Exp $");
+__KERNEL_RCSID(0, "$NetBSD: uhid.c,v 1.120 2022/03/28 12:42:45 riastradh Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_compat_netbsd.h"
@@ -89,7 +89,6 @@ struct uhid_softc {
 
 	kmutex_t sc_lock;
 	kcondvar_t sc_cv;
-	kcondvar_t sc_detach_cv;
 
 	int sc_isize;
 	int sc_osize;
@@ -104,10 +103,13 @@ struct uhid_softc {
 	volatile uint32_t sc_state;	/* driver state */
 #define UHID_IMMED	0x02	/* return read data immediately */
 
-	int sc_refcnt;
 	int sc_raw;
-	u_char sc_open;
-	u_char sc_dying;
+	enum {
+		UHID_CLOSED,
+		UHID_OPENING,
+		UHID_OPEN,
+	} sc_open;
+	bool sc_closing;
 };
 
 #define	UHIDUNIT(dev)	(minor(dev))
@@ -115,6 +117,7 @@ struct uhid_softc {
 #define	UHID_BSIZE	1020	/* buffer size */
 
 static dev_type_open(uhidopen);
+static dev_type_cancel(uhidcancel);
 static dev_type_close(uhidclose);
 static dev_type_read(uhidread);
 static dev_type_write(uhidwrite);
@@ -124,6 +127,7 @@ static dev_type_kqfilter(uhidkqfilter);
 
 const struct cdevsw uhid_cdevsw = {
 	.d_open = uhidopen,
+	.d_cancel = uhidcancel,
 	.d_close = uhidclose,
 	.d_read = uhidread,
 	.d_write = uhidwrite,
@@ -134,22 +138,19 @@ const struct cdevsw uhid_cdevsw = {
 	.d_mmap = nommap,
 	.d_kqfilter = uhidkqfilter,
 	.d_discard = nodiscard,
+	.d_cfdriver = _cd,
+	.d_devtounit = dev_minor_unit,
 	.d_flag = D_OTHER
 };
 
-Static void uhid_intr(struct uhidev *, void *, u_int);
-
-Static int uhid_do_read(struct uhid_softc *, struct uio *, int);
-Static int uhid_do_write(struct uhid_softc *, struct uio *, int);
-Static int uhid_do_ioctl(struct uhid_softc*, u_long, void *, int, struct lwp *);
+static void uhid_intr(struct uhidev *, void *, u_int);
 
 static int	uhid_match(device_t, cfdata_t, void *);
 static void	uhid_attach(device_t, device_t, void *);
 static int	uhid_detach(device_t, int);
-static int	uhid_activate(device_t, enum devact);
 
 CFATTACH_DECL_NEW(uhid, sizeof(struct uhid_softc), uhid_match, uhid_attach,
-uhid_detach, uhid_activate);
+uhid_detach, NULL);
 
 static int
 uhid_match(device_t parent, cfdata_t match, void *aux)
@@ -194,7 +195,6 @@ uhid_attach(device_t parent, device_t se
 
 	mutex_init(>sc_lock, MUTEX_DEFAULT, IPL_SOFTUSB);
 	cv_init(>sc_cv, "uhidrea");
-	cv_init(>sc_detach_cv, "uhiddet");
 
 	if (!pmf_device_register(self, NULL, NULL))
 		aprint_error_dev(self, "couldn't establish power handler\n");
@@ -203,20 +203,6 @@ uhid_attach(device_t parent, device_t se
 }
 
 static int
-uhid_activate(device_t self, enum devact act)
-{
-	struct uhid_softc *sc = device_private(self);
-
-	switch (act) {
-	case DVACT_DEACTIVATE:
-		sc->sc_dying = 1;
-		return 0;
-	default:
-		return EOPNOTSUPP;
-	}
-}
-
-static int
 uhid_detach(device_t self, int flags)
 {
 	struct uhid_softc *sc = device_private(self);
@@ -224,24 +210,6 @@ uhid_detach(device_t self, int flags)
 
 	DPRINTF(("uhid_detach: sc=%p flags=%d\n", sc, flags));
 
-	/* Prevent new I/O operations, and interrupt any pending reads.  */
-	mutex_enter(>sc_lock);
-	sc->sc_dying = 1;
-	cv_broadcast(>sc_cv);
-	mutex_exit(>sc_lock);
-
-	/* Interrupt 

CVS commit: src/sys/dev/usb

2022-03-28 Thread Taylor R Campbell
Module Name:src
Committed By:   riastradh
Date:   Mon Mar 28 12:42:37 UTC 2022

Modified Files:
src/sys/dev/usb: ucom.c

Log Message:
ucom(4): Rework open/close/attach/detach logic.

- Defer sleep after hangup until open.

  No need to make close hang; we just need to make sure some time has
  passed before we next try to open.

  This changes the wchan for the sleep.  Oh well.

- Use .d_cfdriver/devtounit/cancel to resolve races between attach,
  detach, open, close, and revoke.

- Use a separate .sc_closing flag instead of a UCOM_CLOSING state.
  ucomcancel/ucomclose owns this flag, and it may be set in any state
  (except UCOM_DEAD).  UCOM_OPENING remains owned by ucomopen, which
  might be interrupted by cancel/close.

- Rework error branches in ucomopen.  Much simpler this way.

- Nix unnecessary reference counting.


To generate a diff of this commit:
cvs rdiff -u -r1.129 -r1.130 src/sys/dev/usb/ucom.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/dev/usb/ucom.c
diff -u src/sys/dev/usb/ucom.c:1.129 src/sys/dev/usb/ucom.c:1.130
--- src/sys/dev/usb/ucom.c:1.129	Thu Jun 24 08:20:42 2021
+++ src/sys/dev/usb/ucom.c	Mon Mar 28 12:42:37 2022
@@ -1,4 +1,4 @@
-/*	$NetBSD: ucom.c,v 1.129 2021/06/24 08:20:42 riastradh Exp $	*/
+/*	$NetBSD: ucom.c,v 1.130 2022/03/28 12:42:37 riastradh Exp $	*/
 
 /*
  * Copyright (c) 1998, 2000 The NetBSD Foundation, Inc.
@@ -34,7 +34,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: ucom.c,v 1.129 2021/06/24 08:20:42 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ucom.c,v 1.130 2022/03/28 12:42:37 riastradh Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_usb.h"
@@ -180,11 +180,10 @@ struct ucom_softc {
 	UCOM_DEAD,
 	UCOM_ATTACHED,
 	UCOM_OPENING,
-	UCOM_CLOSING,
 	UCOM_OPEN
 	}			sc_state;
-	int			sc_refcnt;
-	bool			sc_dying;	/* disconnecting */
+	bool			sc_closing;	/* software is closing */
+	bool			sc_dying;	/* hardware is gone */
 
 	struct pps_state	sc_pps_state;	/* pps state */
 
@@ -192,10 +191,12 @@ struct ucom_softc {
 
 	kmutex_t		sc_lock;
 	kcondvar_t		sc_statecv;
-	kcondvar_t		sc_detachcv;
+
+	struct timeval		sc_hup_time;
 };
 
 dev_type_open(ucomopen);
+dev_type_cancel(ucomcancel);
 dev_type_close(ucomclose);
 dev_type_read(ucomread);
 dev_type_write(ucomwrite);
@@ -206,6 +207,7 @@ dev_type_poll(ucompoll);
 
 const struct cdevsw ucom_cdevsw = {
 	.d_open = ucomopen,
+	.d_cancel = ucomcancel,
 	.d_close = ucomclose,
 	.d_read = ucomread,
 	.d_write = ucomwrite,
@@ -216,16 +218,16 @@ const struct cdevsw ucom_cdevsw = {
 	.d_mmap = nommap,
 	.d_kqfilter = ttykqfilter,
 	.d_discard = nodiscard,
+	.d_cfdriver = _cd,
+	.d_devtounit = dev_minor_unit,
 	.d_flag = D_TTY | D_MPSAFE
 };
 
-static void	ucom_cleanup(struct ucom_softc *);
+static void	ucom_cleanup(struct ucom_softc *, int);
 static int	ucomparam(struct tty *, struct termios *);
 static int	ucomhwiflow(struct tty *, int);
 static void	ucomstart(struct tty *);
 static void	ucom_shutdown(struct ucom_softc *);
-static int	ucom_do_ioctl(struct ucom_softc *, u_long, void *,
-			  int, struct lwp *);
 static void	ucom_dtr(struct ucom_softc *, int);
 static void	ucom_rts(struct ucom_softc *, int);
 static void	ucom_break(struct ucom_softc *, int);
@@ -288,14 +290,13 @@ ucom_attach(device_t parent, device_t se
 	sc->sc_mcr = 0;
 	sc->sc_tx_stopped = 0;
 	sc->sc_swflags = 0;
-	sc->sc_refcnt = 0;
+	sc->sc_closing = false;
 	sc->sc_dying = false;
 	sc->sc_state = UCOM_DEAD;
 
 	sc->sc_si = softint_establish(SOFTINT_USB, ucom_softintr, sc);
 	mutex_init(>sc_lock, MUTEX_DEFAULT, IPL_SOFTUSB);
 	cv_init(>sc_statecv, "ucomstate");
-	cv_init(>sc_detachcv, "ucomdtch");
 
 	SIMPLEQ_INIT(>sc_ibuff_empty);
 	SIMPLEQ_INIT(>sc_ibuff_full);
@@ -366,7 +367,6 @@ ucom_attach(device_t parent, device_t se
 		aprint_error_dev(self, "couldn't establish power handler\n");
 
 	sc->sc_state = UCOM_ATTACHED;
-
 	return;
 
 fail_2:
@@ -375,8 +375,8 @@ fail_2:
 		if (ub->ub_xfer)
 			usbd_destroy_xfer(ub->ub_xfer);
 	}
-
 	usbd_close_pipe(sc->sc_bulkout_pipe);
+	sc->sc_bulkout_pipe = NULL;
 
 fail_1:
 	for (ub = >sc_ibuff[0]; ub != >sc_ibuff[UCOM_IN_BUFFS];
@@ -385,11 +385,10 @@ fail_1:
 			usbd_destroy_xfer(ub->ub_xfer);
 	}
 	usbd_close_pipe(sc->sc_bulkin_pipe);
+	sc->sc_bulkin_pipe = NULL;
 
 fail_0:
 	aprint_error_dev(self, "attach failed, error=%d\n", error);
-
-	return;
 }
 
 int
@@ -406,49 +405,21 @@ ucom_detach(device_t self, int flags)
 	(uintptr_t)tp, 0);
 	DPRINTF("... pipe=%jd,%jd", sc->sc_bulkin_no, sc->sc_bulkout_no, 0, 0);
 
+	/* Prevent new opens from hanging.  */
 	mutex_enter(>sc_lock);
 	sc->sc_dying = true;
 	mutex_exit(>sc_lock);
 
 	pmf_device_deregister(self);
 
-	if (sc->sc_bulkin_pipe != NULL) {
-		usbd_abort_pipe(sc->sc_bulkin_pipe);
-	}
-	if (sc->sc_bulkout_pipe != NULL) {
-		usbd_abort_pipe(sc->sc_bulkout_pipe);
-	}
-
-	mutex_enter(>sc_lock);
-
-	/* wait for open/close to 

CVS commit: src/sys/dev/usb

2022-03-28 Thread Taylor R Campbell
Module Name:src
Committed By:   riastradh
Date:   Mon Mar 28 12:42:37 UTC 2022

Modified Files:
src/sys/dev/usb: ucom.c

Log Message:
ucom(4): Rework open/close/attach/detach logic.

- Defer sleep after hangup until open.

  No need to make close hang; we just need to make sure some time has
  passed before we next try to open.

  This changes the wchan for the sleep.  Oh well.

- Use .d_cfdriver/devtounit/cancel to resolve races between attach,
  detach, open, close, and revoke.

- Use a separate .sc_closing flag instead of a UCOM_CLOSING state.
  ucomcancel/ucomclose owns this flag, and it may be set in any state
  (except UCOM_DEAD).  UCOM_OPENING remains owned by ucomopen, which
  might be interrupted by cancel/close.

- Rework error branches in ucomopen.  Much simpler this way.

- Nix unnecessary reference counting.


To generate a diff of this commit:
cvs rdiff -u -r1.129 -r1.130 src/sys/dev/usb/ucom.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.



CVS commit: src/sys/kern

2022-03-28 Thread Taylor R Campbell
Module Name:src
Committed By:   riastradh
Date:   Mon Mar 28 12:41:17 UTC 2022

Modified Files:
src/sys/kern: subr_devsw.c

Log Message:
subr_devsw.c: KNF and style nits.

No functional change intended.


To generate a diff of this commit:
cvs rdiff -u -r1.44 -r1.45 src/sys/kern/subr_devsw.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/kern/subr_devsw.c
diff -u src/sys/kern/subr_devsw.c:1.44 src/sys/kern/subr_devsw.c:1.45
--- src/sys/kern/subr_devsw.c:1.44	Mon Mar 28 12:39:10 2022
+++ src/sys/kern/subr_devsw.c	Mon Mar 28 12:41:17 2022
@@ -1,4 +1,4 @@
-/*	$NetBSD: subr_devsw.c,v 1.44 2022/03/28 12:39:10 riastradh Exp $	*/
+/*	$NetBSD: subr_devsw.c,v 1.45 2022/03/28 12:41:17 riastradh Exp $	*/
 
 /*-
  * Copyright (c) 2001, 2002, 2007, 2008 The NetBSD Foundation, Inc.
@@ -28,7 +28,7 @@
  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  * POSSIBILITY OF SUCH DAMAGE.
  */
- 
+
 /*
  * Overview
  *
@@ -69,7 +69,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: subr_devsw.c,v 1.44 2022/03/28 12:39:10 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: subr_devsw.c,v 1.45 2022/03/28 12:41:17 riastradh Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_dtrace.h"
@@ -146,11 +146,11 @@ devsw_attach(const char *devname,
 	int error, i;
 
 	if (devname == NULL || cdev == NULL)
-		return (EINVAL);
+		return EINVAL;
 
 	mutex_enter(_lock);
 
-	for (i = 0 ; i < max_devsw_convs ; i++) {
+	for (i = 0; i < max_devsw_convs; i++) {
 		conv = _conv[i];
 		if (conv->d_name == NULL || strcmp(devname, conv->d_name) != 0)
 			continue;
@@ -162,17 +162,17 @@ devsw_attach(const char *devname,
 
 		if (*bmajor != conv->d_bmajor || *cmajor != conv->d_cmajor) {
 			error = EINVAL;
-			goto fail;
+			goto out;
 		}
 		if ((*bmajor >= 0 && bdev == NULL) || *cmajor < 0) {
 			error = EINVAL;
-			goto fail;
+			goto out;
 		}
 
 		if ((*bmajor >= 0 && bdevsw[*bmajor] != NULL) ||
 		cdevsw[*cmajor] != NULL) {
 			error = EEXIST;
-			goto fail;
+			goto out;
 		}
 		break;
 	}
@@ -182,12 +182,12 @@ devsw_attach(const char *devname,
 	 * need to flail around trying to unwind.
 	 */
 	error = bdevsw_attach(bdev, bmajor);
-	if (error != 0) 
-		goto fail;
+	if (error != 0)
+		goto out;
 	error = cdevsw_attach(cdev, cmajor);
 	if (error != 0) {
 		devsw_detach_locked(bdev, NULL);
-		goto fail;
+		goto out;
 	}
 
 	/*
@@ -195,9 +195,9 @@ devsw_attach(const char *devname,
 	 * empty slot or extend the table.
 	 */
 	if (i == max_devsw_convs)
-		goto fail;
+		goto out;
 
-	for (i = 0 ; i < max_devsw_convs ; i++) {
+	for (i = 0; i < max_devsw_convs; i++) {
 		if (devsw_conv[i].d_name == NULL)
 			break;
 	}
@@ -212,7 +212,7 @@ devsw_attach(const char *devname,
 		if (newptr == NULL) {
 			devsw_detach_locked(bdev, cdev);
 			error = ENOMEM;
-			goto fail;
+			goto out;
 		}
 		newptr[old_convs].d_name = NULL;
 		newptr[old_convs].d_bmajor = -1;
@@ -228,18 +228,16 @@ devsw_attach(const char *devname,
 	if (name == NULL) {
 		devsw_detach_locked(bdev, cdev);
 		error = ENOMEM;
-		goto fail;
+		goto out;
 	}
 
 	devsw_conv[i].d_name = name;
 	devsw_conv[i].d_bmajor = *bmajor;
 	devsw_conv[i].d_cmajor = *cmajor;
-
-	mutex_exit(_lock);
-	return (0);
- fail:
+	error = 0;
+out:
 	mutex_exit(_lock);
-	return (error);
+	return error;
 }
 
 static int
@@ -254,13 +252,13 @@ bdevsw_attach(const struct bdevsw *devsw
 	KASSERT(mutex_owned(_lock));
 
 	if (devsw == NULL)
-		return (0);
+		return 0;
 
 	if (*devmajor < 0) {
-		for (bmajor = sys_bdevsws ; bmajor < max_bdevsws ; bmajor++) {
+		for (bmajor = sys_bdevsws; bmajor < max_bdevsws; bmajor++) {
 			if (bdevsw[bmajor] != NULL)
 continue;
-			for (i = 0 ; i < max_devsw_convs ; i++) {
+			for (i = 0; i < max_devsw_convs; i++) {
 if (devsw_conv[i].d_bmajor == bmajor)
 	break;
 			}
@@ -272,8 +270,8 @@ bdevsw_attach(const struct bdevsw *devsw
 	}
 
 	if (*devmajor >= MAXDEVSW) {
-		printf("%s: block majors exhausted", __func__);
-		return (ENOMEM);
+		printf("%s: block majors exhausted\n", __func__);
+		return ENOMEM;
 	}
 
 	if (bdevswref == NULL) {
@@ -296,7 +294,7 @@ bdevsw_attach(const struct bdevsw *devsw
 	}
 
 	if (bdevsw[*devmajor] != NULL)
-		return (EEXIST);
+		return EEXIST;
 
 	KASSERT(bdevswref[*devmajor].dr_lc == NULL);
 	lc = kmem_zalloc(sizeof(*lc), KM_SLEEP);
@@ -305,7 +303,7 @@ bdevsw_attach(const struct bdevsw *devsw
 
 	atomic_store_release([*devmajor], devsw);
 
-	return (0);
+	return 0;
 }
 
 static int
@@ -320,10 +318,10 @@ cdevsw_attach(const struct cdevsw *devsw
 	KASSERT(mutex_owned(_lock));
 
 	if (*devmajor < 0) {
-		for (cmajor = sys_cdevsws ; cmajor < max_cdevsws ; cmajor++) {
+		for (cmajor = sys_cdevsws; cmajor < max_cdevsws; cmajor++) {
 			if (cdevsw[cmajor] != NULL)
 continue;
-			for (i = 0 ; i < max_devsw_convs ; i++) {
+			for (i = 0; i < max_devsw_convs; i++) {
 if (devsw_conv[i].d_cmajor == cmajor)
 	

CVS commit: src/sys/kern

2022-03-28 Thread Taylor R Campbell
Module Name:src
Committed By:   riastradh
Date:   Mon Mar 28 12:41:17 UTC 2022

Modified Files:
src/sys/kern: subr_devsw.c

Log Message:
subr_devsw.c: KNF and style nits.

No functional change intended.


To generate a diff of this commit:
cvs rdiff -u -r1.44 -r1.45 src/sys/kern/subr_devsw.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.



CVS commit: src/sys/dev/audio

2022-03-28 Thread Taylor R Campbell
Module Name:src
Committed By:   riastradh
Date:   Mon Mar 28 12:39:57 UTC 2022

Modified Files:
src/sys/dev/audio: audio.c

Log Message:
audio(4): Use d_cfdriver/devtounit to avoid open/detach races.


To generate a diff of this commit:
cvs rdiff -u -r1.120 -r1.121 src/sys/dev/audio/audio.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/dev/audio/audio.c
diff -u src/sys/dev/audio/audio.c:1.120 src/sys/dev/audio/audio.c:1.121
--- src/sys/dev/audio/audio.c:1.120	Sat Mar 26 06:49:27 2022
+++ src/sys/dev/audio/audio.c	Mon Mar 28 12:39:57 2022
@@ -1,4 +1,4 @@
-/*	$NetBSD: audio.c,v 1.120 2022/03/26 06:49:27 isaki Exp $	*/
+/*	$NetBSD: audio.c,v 1.121 2022/03/28 12:39:57 riastradh Exp $	*/
 
 /*-
  * Copyright (c) 2008 The NetBSD Foundation, Inc.
@@ -181,7 +181,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: audio.c,v 1.120 2022/03/26 06:49:27 isaki Exp $");
+__KERNEL_RCSID(0, "$NetBSD: audio.c,v 1.121 2022/03/28 12:39:57 riastradh Exp $");
 
 #ifdef _KERNEL_OPT
 #include "audio.h"
@@ -567,7 +567,6 @@ static int audio_exlock_mutex_enter(stru
 static void audio_exlock_mutex_exit(struct audio_softc *);
 static int audio_exlock_enter(struct audio_softc *);
 static void audio_exlock_exit(struct audio_softc *);
-static void audio_sc_acquire_foropen(struct audio_softc *, struct psref *);
 static struct audio_softc *audio_sc_acquire_fromfile(audio_file_t *,
 	struct psref *);
 static void audio_sc_release(struct audio_softc *, struct psref *);
@@ -766,6 +765,13 @@ audio_volume_to_outer(u_int v)
 static dev_type_open(audioopen);
 /* XXXMRG use more dev_type_xxx */
 
+static int
+audiounit(dev_t dev)
+{
+
+	return AUDIOUNIT(dev);
+}
+
 const struct cdevsw audio_cdevsw = {
 	.d_open = audioopen,
 	.d_close = noclose,
@@ -778,6 +784,8 @@ const struct cdevsw audio_cdevsw = {
 	.d_mmap = nommap,
 	.d_kqfilter = nokqfilter,
 	.d_discard = nodiscard,
+	.d_cfdriver = _cd,
+	.d_devtounit = audiounit,
 	.d_flag = D_OTHER | D_MPSAFE
 };
 
@@ -1590,31 +1598,6 @@ audio_exlock_exit(struct audio_softc *sc
 }
 
 /*
- * Increment reference counter for this sc.
- * This is intended to be used for open.
- */
-void
-audio_sc_acquire_foropen(struct audio_softc *sc, struct psref *refp)
-{
-	int s;
-
-	/* Block audiodetach while we acquire a reference */
-	s = pserialize_read_enter();
-
-	/*
-	 * We don't examine sc_dying here.  However, all open methods
-	 * call audio_exlock_enter() right after this, so we can examine
-	 * sc_dying in it.
-	 */
-
-	/* Acquire a reference */
-	psref_acquire(refp, >sc_psref, audio_psref_class);
-
-	/* Now sc won't go away until we drop the reference count */
-	pserialize_read_exit(s);
-}
-
-/*
  * Get sc from file, and increment reference counter for this sc.
  * This is intended to be used for methods other than open.
  * If successful, returns sc.  Otherwise returns NULL.
@@ -1732,21 +1715,20 @@ static int
 audioopen(dev_t dev, int flags, int ifmt, struct lwp *l)
 {
 	struct audio_softc *sc;
-	struct psref sc_ref;
-	int bound;
 	int error;
 
-	/* Find the device */
+	/*
+	 * Find the device.  Because we wired the cdevsw to the audio
+	 * autoconf instance, the system ensures it will not go away
+	 * until after we return.
+	 */
 	sc = device_lookup_private(_cd, AUDIOUNIT(dev));
 	if (sc == NULL || sc->hw_if == NULL)
 		return ENXIO;
 
-	bound = curlwp_bind();
-	audio_sc_acquire_foropen(sc, _ref);
-
 	error = audio_exlock_enter(sc);
 	if (error)
-		goto done;
+		return error;
 
 	device_active(sc->sc_dev, DVA_SYSTEM);
 	switch (AUDIODEV(dev)) {
@@ -1766,9 +1748,6 @@ audioopen(dev_t dev, int flags, int ifmt
 	}
 	audio_exlock_exit(sc);
 
-done:
-	audio_sc_release(sc, _ref);
-	curlwp_bindx(bound);
 	return error;
 }
 
@@ -2150,30 +2129,42 @@ done:
 int
 audiobellopen(dev_t dev, audio_file_t **filep)
 {
+	device_t audiodev = NULL;
 	struct audio_softc *sc;
-	struct psref sc_ref;
-	int bound;
+	bool exlock = false;
 	int error;
 
-	/* Find the device */
-	sc = device_lookup_private(_cd, AUDIOUNIT(dev));
-	if (sc == NULL || sc->hw_if == NULL)
-		return ENXIO;
+	/*
+	 * Find the autoconf instance and make sure it doesn't go away
+	 * while we are opening it.
+	 */
+	audiodev = device_lookup_acquire(_cd, AUDIOUNIT(dev));
+	if (audiodev == NULL) {
+		error = ENXIO;
+		goto out;
+	}
 
-	bound = curlwp_bind();
-	audio_sc_acquire_foropen(sc, _ref);
+	/* If attach failed, it's hopeless -- give up.  */
+	sc = device_private(audiodev);
+	if (sc->hw_if == NULL) {
+		error = ENXIO;
+		goto out;
+	}
 
+	/* Take the exclusive configuration lock.  */
 	error = audio_exlock_enter(sc);
 	if (error)
-		goto done;
+		goto out;
+	exlock = true;
 
+	/* Open the audio device.  */
 	device_active(sc->sc_dev, DVA_SYSTEM);
 	error = audio_open(dev, sc, FWRITE, 0, curlwp, filep);
 
-	audio_exlock_exit(sc);
-done:
-	audio_sc_release(sc, _ref);
-	curlwp_bindx(bound);
+out:	if (exlock)
+		audio_exlock_exit(sc);
+	if 

CVS commit: src/sys/dev/audio

2022-03-28 Thread Taylor R Campbell
Module Name:src
Committed By:   riastradh
Date:   Mon Mar 28 12:39:57 UTC 2022

Modified Files:
src/sys/dev/audio: audio.c

Log Message:
audio(4): Use d_cfdriver/devtounit to avoid open/detach races.


To generate a diff of this commit:
cvs rdiff -u -r1.120 -r1.121 src/sys/dev/audio/audio.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.



CVS commit: src/sys/dev/scsipi

2022-03-28 Thread Taylor R Campbell
Module Name:src
Committed By:   riastradh
Date:   Mon Mar 28 12:39:47 UTC 2022

Modified Files:
src/sys/dev/scsipi: sd.c

Log Message:
sd(4): Use d_cfdriver/devtounit to avoid open/detach races.


To generate a diff of this commit:
cvs rdiff -u -r1.333 -r1.334 src/sys/dev/scsipi/sd.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/dev/scsipi/sd.c
diff -u src/sys/dev/scsipi/sd.c:1.333 src/sys/dev/scsipi/sd.c:1.334
--- src/sys/dev/scsipi/sd.c:1.333	Thu Jan 27 18:44:49 2022
+++ src/sys/dev/scsipi/sd.c	Mon Mar 28 12:39:46 2022
@@ -1,4 +1,4 @@
-/*	$NetBSD: sd.c,v 1.333 2022/01/27 18:44:49 jakllsch Exp $	*/
+/*	$NetBSD: sd.c,v 1.334 2022/03/28 12:39:46 riastradh Exp $	*/
 
 /*-
  * Copyright (c) 1998, 2003, 2004 The NetBSD Foundation, Inc.
@@ -47,7 +47,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: sd.c,v 1.333 2022/01/27 18:44:49 jakllsch Exp $");
+__KERNEL_RCSID(0, "$NetBSD: sd.c,v 1.334 2022/03/28 12:39:46 riastradh Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_scsi.h"
@@ -167,6 +167,8 @@ const struct bdevsw sd_bdevsw = {
 	.d_dump = sddump,
 	.d_psize = sdsize,
 	.d_discard = nodiscard,
+	.d_cfdriver = _cd,
+	.d_devtounit = disklabel_dev_unit,
 	.d_flag = D_DISK | D_MPSAFE
 };
 
@@ -182,6 +184,8 @@ const struct cdevsw sd_cdevsw = {
 	.d_mmap = nommap,
 	.d_kqfilter = nokqfilter,
 	.d_discard = nodiscard,
+	.d_cfdriver = _cd,
+	.d_devtounit = disklabel_dev_unit,
 	.d_flag = D_DISK | D_MPSAFE
 };
 



CVS commit: src/sys/dev/scsipi

2022-03-28 Thread Taylor R Campbell
Module Name:src
Committed By:   riastradh
Date:   Mon Mar 28 12:39:47 UTC 2022

Modified Files:
src/sys/dev/scsipi: sd.c

Log Message:
sd(4): Use d_cfdriver/devtounit to avoid open/detach races.


To generate a diff of this commit:
cvs rdiff -u -r1.333 -r1.334 src/sys/dev/scsipi/sd.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.



CVS commit: src/sys/dev/ata

2022-03-28 Thread Taylor R Campbell
Module Name:src
Committed By:   riastradh
Date:   Mon Mar 28 12:39:37 UTC 2022

Modified Files:
src/sys/dev/ata: wd.c

Log Message:
wd(4): Use d_cfdriver/devtounit to avoid open/detach races.


To generate a diff of this commit:
cvs rdiff -u -r1.466 -r1.467 src/sys/dev/ata/wd.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/dev/ata/wd.c
diff -u src/sys/dev/ata/wd.c:1.466 src/sys/dev/ata/wd.c:1.467
--- src/sys/dev/ata/wd.c:1.466	Tue Dec 28 13:27:32 2021
+++ src/sys/dev/ata/wd.c	Mon Mar 28 12:39:37 2022
@@ -1,4 +1,4 @@
-/*	$NetBSD: wd.c,v 1.466 2021/12/28 13:27:32 riastradh Exp $ */
+/*	$NetBSD: wd.c,v 1.467 2022/03/28 12:39:37 riastradh Exp $ */
 
 /*
  * Copyright (c) 1998, 2001 Manuel Bouyer.  All rights reserved.
@@ -54,7 +54,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: wd.c,v 1.466 2021/12/28 13:27:32 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: wd.c,v 1.467 2022/03/28 12:39:37 riastradh Exp $");
 
 #include "opt_ata.h"
 #include "opt_wd.h"
@@ -152,6 +152,8 @@ const struct bdevsw wd_bdevsw = {
 	.d_dump = wddump,
 	.d_psize = wdsize,
 	.d_discard = wddiscard,
+	.d_cfdriver = _cd,
+	.d_devtounit = disklabel_dev_unit,
 	.d_flag = D_DISK
 };
 
@@ -167,6 +169,8 @@ const struct cdevsw wd_cdevsw = {
 	.d_mmap = nommap,
 	.d_kqfilter = nokqfilter,
 	.d_discard = wddiscard,
+	.d_cfdriver = _cd,
+	.d_devtounit = disklabel_dev_unit,
 	.d_flag = D_DISK
 };
 



CVS commit: src/sys/dev/ata

2022-03-28 Thread Taylor R Campbell
Module Name:src
Committed By:   riastradh
Date:   Mon Mar 28 12:39:37 UTC 2022

Modified Files:
src/sys/dev/ata: wd.c

Log Message:
wd(4): Use d_cfdriver/devtounit to avoid open/detach races.


To generate a diff of this commit:
cvs rdiff -u -r1.466 -r1.467 src/sys/dev/ata/wd.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.



CVS commit: src/sys

2022-03-28 Thread Taylor R Campbell
Module Name:src
Committed By:   riastradh
Date:   Mon Mar 28 12:39:29 UTC 2022

Modified Files:
src/sys/kern: tty.c
src/sys/sys: tty.h

Log Message:
tty(9): New ttycancel function.

This causes any current and future ttyopens to fail until ttyclose.

This is necessary for revoke to work reliably for device detach like
ucom(4) removable USB devices.  A tty driver for a removable device
needs some way to interrupt a pending .d_open so it returns promptly.
But ttyclose only interrupts ttyopen if it's already sleeping; it
won't cause a concurrent .d_open call which _will call_ but _hasn't
yet called_ ttyopen to avoid sleeping.  Using ttycancel in the tty
driver's .d_cancel makes this work.


To generate a diff of this commit:
cvs rdiff -u -r1.299 -r1.300 src/sys/kern/tty.c
cvs rdiff -u -r1.95 -r1.96 src/sys/sys/tty.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/kern/tty.c
diff -u src/sys/kern/tty.c:1.299 src/sys/kern/tty.c:1.300
--- src/sys/kern/tty.c:1.299	Sun Dec  5 07:44:53 2021
+++ src/sys/kern/tty.c	Mon Mar 28 12:39:28 2022
@@ -1,4 +1,4 @@
-/*	$NetBSD: tty.c,v 1.299 2021/12/05 07:44:53 msaitoh Exp $	*/
+/*	$NetBSD: tty.c,v 1.300 2022/03/28 12:39:28 riastradh Exp $	*/
 
 /*-
  * Copyright (c) 2008, 2020 The NetBSD Foundation, Inc.
@@ -63,7 +63,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: tty.c,v 1.299 2021/12/05 07:44:53 msaitoh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: tty.c,v 1.300 2022/03/28 12:39:28 riastradh Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_compat_netbsd.h"
@@ -420,6 +420,21 @@ ttylopen(dev_t device, struct tty *tp)
 }
 
 /*
+ * Interrupt any pending I/O and make it fail.  Used before close to
+ * interrupt pending open/read/write/ and make it fail promptly.
+ */
+void
+ttycancel(struct tty *tp)
+{
+
+	mutex_spin_enter(_lock);
+	tp->t_state |= TS_CANCEL;
+	cv_broadcast(>t_outcv);
+	cv_broadcast(>t_rawcv);
+	mutex_spin_exit(_lock);
+}
+
+/*
  * Handle close() on a tty line: flush and set to initial state,
  * bumping generation number so that pending read/write calls
  * can detect recycling of the tty.
@@ -2750,7 +2765,9 @@ ttysleep(struct tty *tp, kcondvar_t *cv,
 	KASSERT(mutex_owned(_lock));
 
 	gen = tp->t_gen;
-	if (cv == NULL)
+	if (ISSET(tp->t_state, TS_CANCEL))
+		error = ERESTART;
+	else if (cv == NULL)
 		error = kpause("ttypause", catch_p, timo, _lock);
 	else if (catch_p)
 		error = cv_timedwait_sig(cv, _lock, timo);

Index: src/sys/sys/tty.h
diff -u src/sys/sys/tty.h:1.95 src/sys/sys/tty.h:1.96
--- src/sys/sys/tty.h:1.95	Sun Jan 27 02:08:50 2019
+++ src/sys/sys/tty.h	Mon Mar 28 12:39:28 2022
@@ -1,4 +1,4 @@
-/*	$NetBSD: tty.h,v 1.95 2019/01/27 02:08:50 pgoyette Exp $	*/
+/*	$NetBSD: tty.h,v 1.96 2022/03/28 12:39:28 riastradh Exp $	*/
 
 /*-
  * Copyright (c) 2008 The NetBSD Foundation, Inc.
@@ -207,6 +207,8 @@ struct tty {
 #define	TS_KERN_ONLY	0x1		/* Device is accessible by kernel
 	 * only, deny all userland access */
 
+#define	TS_CANCEL	0x2		/* I/O cancelled pending close. */
+
 /* Character type information. */
 #define	ORDINARY	0
 #define	CONTROL		1
@@ -281,6 +283,7 @@ void	 ttwakeup(struct tty *);
 int	 ttwrite(struct tty *, struct uio *, int);
 void	 ttychars(struct tty *);
 int	 ttycheckoutq(struct tty *, int);
+void	 ttycancel(struct tty *);
 int	 ttyclose(struct tty *);
 void	 ttyflush(struct tty *, int);
 void	 ttygetinfo(struct tty *, int, char *, size_t);



CVS commit: src/sys

2022-03-28 Thread Taylor R Campbell
Module Name:src
Committed By:   riastradh
Date:   Mon Mar 28 12:39:29 UTC 2022

Modified Files:
src/sys/kern: tty.c
src/sys/sys: tty.h

Log Message:
tty(9): New ttycancel function.

This causes any current and future ttyopens to fail until ttyclose.

This is necessary for revoke to work reliably for device detach like
ucom(4) removable USB devices.  A tty driver for a removable device
needs some way to interrupt a pending .d_open so it returns promptly.
But ttyclose only interrupts ttyopen if it's already sleeping; it
won't cause a concurrent .d_open call which _will call_ but _hasn't
yet called_ ttyopen to avoid sleeping.  Using ttycancel in the tty
driver's .d_cancel makes this work.


To generate a diff of this commit:
cvs rdiff -u -r1.299 -r1.300 src/sys/kern/tty.c
cvs rdiff -u -r1.95 -r1.96 src/sys/sys/tty.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.



CVS commit: src/sys

2022-03-28 Thread Taylor R Campbell
Module Name:src
Committed By:   riastradh
Date:   Mon Mar 28 12:39:18 UTC 2022

Modified Files:
src/sys/sys: conf.h
src/sys/uvm: uvm_device.c

Log Message:
driver(9): New types dev_*_t for device driver devsw operations.

These will serve to replace the archaic and kludgey dev_type_* macros
which should've been typedefs all along.


To generate a diff of this commit:
cvs rdiff -u -r1.160 -r1.161 src/sys/sys/conf.h
cvs rdiff -u -r1.72 -r1.73 src/sys/uvm/uvm_device.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/sys/conf.h
diff -u src/sys/sys/conf.h:1.160 src/sys/sys/conf.h:1.161
--- src/sys/sys/conf.h:1.160	Mon Mar 28 12:39:10 2022
+++ src/sys/sys/conf.h	Mon Mar 28 12:39:18 2022
@@ -1,4 +1,4 @@
-/*	$NetBSD: conf.h,v 1.160 2022/03/28 12:39:10 riastradh Exp $	*/
+/*	$NetBSD: conf.h,v 1.161 2022/03/28 12:39:18 riastradh Exp $	*/
 
 /*-
  * Copyright (c) 1990, 1993
@@ -116,22 +116,37 @@ const struct cdevsw *cdevsw_lookup(dev_t
 devmajor_t bdevsw_lookup_major(const struct bdevsw *);
 devmajor_t cdevsw_lookup_major(const struct cdevsw *);
 
-#define	dev_type_open(n)	int n (dev_t, int, int, struct lwp *)
-#define	dev_type_cancel(n)	int n (dev_t, int, int, struct lwp *)
-#define	dev_type_close(n)	int n (dev_t, int, int, struct lwp *)
-#define	dev_type_read(n)	int n (dev_t, struct uio *, int)
-#define	dev_type_write(n)	int n (dev_t, struct uio *, int)
-#define	dev_type_ioctl(n) \
-		int n (dev_t, u_long, void *, int, struct lwp *)
-#define	dev_type_stop(n)	void n (struct tty *, int)
-#define	dev_type_tty(n)		struct tty * n (dev_t)
-#define	dev_type_poll(n)	int n (dev_t, int, struct lwp *)
-#define	dev_type_mmap(n)	paddr_t n (dev_t, off_t, int)
-#define	dev_type_strategy(n)	void n (struct buf *)
-#define	dev_type_dump(n)	int n (dev_t, daddr_t, void *, size_t)
-#define	dev_type_size(n)	int n (dev_t)
-#define	dev_type_kqfilter(n)	int n (dev_t, struct knote *)
-#define dev_type_discard(n)	int n (dev_t, off_t, off_t)
+typedef int dev_open_t(dev_t, int, int, struct lwp *);
+typedef int dev_cancel_t(dev_t, int, int, struct lwp *);
+typedef int dev_close_t(dev_t, int, int, struct lwp *);
+typedef int dev_read_t(dev_t, struct uio *, int);
+typedef int dev_write_t(dev_t, struct uio *, int);
+typedef int dev_ioctl_t(dev_t, u_long, void *, int, struct lwp *);
+typedef void dev_stop_t(struct tty *, int);
+typedef struct tty *dev_tty_t(dev_t);
+typedef int dev_poll_t(dev_t, int, struct lwp *);
+typedef paddr_t dev_mmap_t(dev_t, off_t, int);
+typedef void dev_strategy_t(struct buf *);
+typedef int dev_dump_t(dev_t, daddr_t, void *, size_t);
+typedef int dev_size_t(dev_t);
+typedef int dev_kqfilter_t(dev_t, struct knote *);
+typedef int dev_discard_t(dev_t, off_t, off_t);
+
+#define	dev_type_open(n)	dev_open_t n
+#define	dev_type_cancel(n)	dev_cancel_t n
+#define	dev_type_close(n)	dev_close_t n
+#define	dev_type_read(n)	dev_read_t n
+#define	dev_type_write(n)	dev_write_t n
+#define	dev_type_ioctl(n)	dev_ioctl_t n
+#define	dev_type_stop(n)	dev_stop_t n
+#define	dev_type_tty(n)		dev_tty_t n
+#define	dev_type_poll(n)	dev_poll_t n
+#define	dev_type_mmap(n)	dev_mmap_t n
+#define	dev_type_strategy(n)	dev_strategy_t n
+#define	dev_type_dump(n)	dev_dump_t n
+#define	dev_type_size(n)	dev_size_t n
+#define	dev_type_kqfilter(n)	dev_kqfilter_t n
+#define dev_type_discard(n)	dev_discard_t n
 
 int devenodev(dev_t, ...);
 int deveopnotsupp(dev_t, ...);
@@ -140,30 +155,30 @@ int ttyenodev(struct tty *, ...);
 void ttyvenodev(struct tty *, ...);
 void ttyvnullop(struct tty *, ...);
 
-#define	noopen		((dev_type_open((*)))devenodev)
-#define	noclose		((dev_type_close((*)))devenodev)
-#define	noread		((dev_type_read((*)))devenodev)
-#define	nowrite		((dev_type_write((*)))devenodev)
-#define	noioctl		((dev_type_ioctl((*)))devenodev)
-#define	nostop		((dev_type_stop((*)))ttyvenodev)
+#define	noopen		((dev_open_t *)devenodev)
+#define	noclose		((dev_close_t *)devenodev)
+#define	noread		((dev_read_t *)devenodev)
+#define	nowrite		((dev_write_t *)devenodev)
+#define	noioctl		((dev_ioctl_t *)devenodev)
+#define	nostop		((dev_stop_t *)ttyvenodev)
 #define	notty		NULL
 #define	nopoll		seltrue
 paddr_t	nommap(dev_t, off_t, int);
-#define	nodump		((dev_type_dump((*)))devenodev)
+#define	nodump		((dev_dump_t *)devenodev)
 #define	nosize		NULL
 #define	nokqfilter	seltrue_kqfilter
-#define	nodiscard	((dev_type_discard((*)))devenodev)
+#define	nodiscard	((dev_discard_t *)devenodev)
 
-#define	nullopen	((dev_type_open((*)))devnullop)
-#define	nullclose	((dev_type_close((*)))devnullop)
-#define	nullread	((dev_type_read((*)))devnullop)
-#define	nullwrite	((dev_type_write((*)))devnullop)
-#define	nullioctl	((dev_type_ioctl((*)))devnullop)
-#define	nullstop	((dev_type_stop((*)))ttyvnullop)
-#define	nullpoll	((dev_type_poll((*)))devnullop)
-#define	nulldump	((dev_type_dump((*)))devnullop)
-#define	nullkqfilter	

CVS commit: src/sys

2022-03-28 Thread Taylor R Campbell
Module Name:src
Committed By:   riastradh
Date:   Mon Mar 28 12:39:18 UTC 2022

Modified Files:
src/sys/sys: conf.h
src/sys/uvm: uvm_device.c

Log Message:
driver(9): New types dev_*_t for device driver devsw operations.

These will serve to replace the archaic and kludgey dev_type_* macros
which should've been typedefs all along.


To generate a diff of this commit:
cvs rdiff -u -r1.160 -r1.161 src/sys/sys/conf.h
cvs rdiff -u -r1.72 -r1.73 src/sys/uvm/uvm_device.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.



CVS commit: src/sys

2022-03-28 Thread Taylor R Campbell
Module Name:src
Committed By:   riastradh
Date:   Mon Mar 28 12:39:10 UTC 2022

Modified Files:
src/sys/kern: subr_devsw.c
src/sys/miscfs/specfs: spec_vnops.c
src/sys/sys: conf.h

Log Message:
driver(9): New devsw d_cancel op to interrupt I/O before close.

If specified, when revoking a device node or closing its last open
node, specfs will:

1. Call d_cancel, which should return promptly without blocking.
2. Wait for all concurrent d_read/write/ioctl/ to drain.
3. Call d_close.

Otherwise, specfs will:

1. Call d_close.
2. Wait for all concurrent d_read/write/ioctl/ to drain.

This fallback is problematic because often parts of d_close rely on
concurrent devsw operations to have completed already, so it is up to
each driver to have its own mechanism for waiting, and the extra step
in (2) is almost redundant.  But it is still important to ensure that
devsw operations are not active by the time a module tries to invoke
devsw_detach, because only d_open is protected against that.

The signature of d_cancel matches d_close, mostly so we don't raise
questions about `why is this different?'; the lwp argument is not
useful but we should remove it from open/cancel/close all at the same
time.

The only way d_cancel should fail, if it does at all, is with ENODEV,
meaning the driver doesn't support cancelling outstanding I/O, and
will take responsibility for that in d_close.  I would make it return
void and only have bdev_cancel and cdev_cancel possibly return ENODEV
so specfs can detect whether a driver supports it, but this would
break the pattern around devsw operation types.

Drivers are allowed to omit it from struct bdevsw, struct cdevsw --
if so, it is as if they used a function that just returns ENODEV.

XXX kernel ABI change to struct bdevsw/cdevsw requires bump


To generate a diff of this commit:
cvs rdiff -u -r1.43 -r1.44 src/sys/kern/subr_devsw.c
cvs rdiff -u -r1.209 -r1.210 src/sys/miscfs/specfs/spec_vnops.c
cvs rdiff -u -r1.159 -r1.160 src/sys/sys/conf.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/kern/subr_devsw.c
diff -u src/sys/kern/subr_devsw.c:1.43 src/sys/kern/subr_devsw.c:1.44
--- src/sys/kern/subr_devsw.c:1.43	Mon Mar 28 12:38:33 2022
+++ src/sys/kern/subr_devsw.c	Mon Mar 28 12:39:10 2022
@@ -1,4 +1,4 @@
-/*	$NetBSD: subr_devsw.c,v 1.43 2022/03/28 12:38:33 riastradh Exp $	*/
+/*	$NetBSD: subr_devsw.c,v 1.44 2022/03/28 12:39:10 riastradh Exp $	*/
 
 /*-
  * Copyright (c) 2001, 2002, 2007, 2008 The NetBSD Foundation, Inc.
@@ -69,7 +69,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: subr_devsw.c,v 1.43 2022/03/28 12:38:33 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: subr_devsw.c,v 1.44 2022/03/28 12:39:10 riastradh Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_dtrace.h"
@@ -934,6 +934,24 @@ bdev_open(dev_t dev, int flag, int devty
 }
 
 int
+bdev_cancel(dev_t dev, int flag, int devtype, struct lwp *l)
+{
+	const struct bdevsw *d;
+	int rv, mpflag;
+
+	if ((d = bdevsw_lookup(dev)) == NULL)
+		return ENXIO;
+	if (d->d_cancel == NULL)
+		return ENODEV;
+
+	DEV_LOCK(d);
+	rv = (*d->d_cancel)(dev, flag, devtype, l);
+	DEV_UNLOCK(d);
+
+	return rv;
+}
+
+int
 bdev_close(dev_t dev, int flag, int devtype, lwp_t *l)
 {
 	const struct bdevsw *d;
@@ -1129,6 +1147,24 @@ cdev_open(dev_t dev, int flag, int devty
 }
 
 int
+cdev_cancel(dev_t dev, int flag, int devtype, struct lwp *l)
+{
+	const struct cdevsw *d;
+	int rv, mpflag;
+
+	if ((d = cdevsw_lookup(dev)) == NULL)
+		return ENXIO;
+	if (d->d_cancel == NULL)
+		return ENODEV;
+
+	DEV_LOCK(d);
+	rv = (*d->d_cancel)(dev, flag, devtype, l);
+	DEV_UNLOCK(d);
+
+	return rv;
+}
+
+int
 cdev_close(dev_t dev, int flag, int devtype, lwp_t *l)
 {
 	const struct cdevsw *d;

Index: src/sys/miscfs/specfs/spec_vnops.c
diff -u src/sys/miscfs/specfs/spec_vnops.c:1.209 src/sys/miscfs/specfs/spec_vnops.c:1.210
--- src/sys/miscfs/specfs/spec_vnops.c:1.209	Mon Mar 28 12:37:56 2022
+++ src/sys/miscfs/specfs/spec_vnops.c	Mon Mar 28 12:39:10 2022
@@ -1,4 +1,4 @@
-/*	$NetBSD: spec_vnops.c,v 1.209 2022/03/28 12:37:56 riastradh Exp $	*/
+/*	$NetBSD: spec_vnops.c,v 1.210 2022/03/28 12:39:10 riastradh Exp $	*/
 
 /*-
  * Copyright (c) 2008 The NetBSD Foundation, Inc.
@@ -58,7 +58,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: spec_vnops.c,v 1.209 2022/03/28 12:37:56 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: spec_vnops.c,v 1.210 2022/03/28 12:39:10 riastradh Exp $");
 
 #include 
 #include 
@@ -1688,6 +1688,22 @@ spec_close(void *v)
 	if (!(flags & FNONBLOCK))
 		VOP_UNLOCK(vp);
 
+	/*
+	 * If we can cancel all outstanding I/O, then wait for it to
+	 * drain before we call .d_close.  Drivers that split up
+	 * .d_cancel and .d_close this way need not have any internal
+	 * mechanism for waiting in .d_close for I/O to drain.
+	 */
+	if (vp->v_type == VBLK)
+		error = bdev_cancel(dev, flags, mode, curlwp);
+	else
+		error = 

CVS commit: src/sys

2022-03-28 Thread Taylor R Campbell
Module Name:src
Committed By:   riastradh
Date:   Mon Mar 28 12:39:10 UTC 2022

Modified Files:
src/sys/kern: subr_devsw.c
src/sys/miscfs/specfs: spec_vnops.c
src/sys/sys: conf.h

Log Message:
driver(9): New devsw d_cancel op to interrupt I/O before close.

If specified, when revoking a device node or closing its last open
node, specfs will:

1. Call d_cancel, which should return promptly without blocking.
2. Wait for all concurrent d_read/write/ioctl/ to drain.
3. Call d_close.

Otherwise, specfs will:

1. Call d_close.
2. Wait for all concurrent d_read/write/ioctl/ to drain.

This fallback is problematic because often parts of d_close rely on
concurrent devsw operations to have completed already, so it is up to
each driver to have its own mechanism for waiting, and the extra step
in (2) is almost redundant.  But it is still important to ensure that
devsw operations are not active by the time a module tries to invoke
devsw_detach, because only d_open is protected against that.

The signature of d_cancel matches d_close, mostly so we don't raise
questions about `why is this different?'; the lwp argument is not
useful but we should remove it from open/cancel/close all at the same
time.

The only way d_cancel should fail, if it does at all, is with ENODEV,
meaning the driver doesn't support cancelling outstanding I/O, and
will take responsibility for that in d_close.  I would make it return
void and only have bdev_cancel and cdev_cancel possibly return ENODEV
so specfs can detect whether a driver supports it, but this would
break the pattern around devsw operation types.

Drivers are allowed to omit it from struct bdevsw, struct cdevsw --
if so, it is as if they used a function that just returns ENODEV.

XXX kernel ABI change to struct bdevsw/cdevsw requires bump


To generate a diff of this commit:
cvs rdiff -u -r1.43 -r1.44 src/sys/kern/subr_devsw.c
cvs rdiff -u -r1.209 -r1.210 src/sys/miscfs/specfs/spec_vnops.c
cvs rdiff -u -r1.159 -r1.160 src/sys/sys/conf.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.



CVS commit: src/sys

2022-03-28 Thread Taylor R Campbell
Module Name:src
Committed By:   riastradh
Date:   Mon Mar 28 12:38:59 UTC 2022

Modified Files:
src/sys/arch/amiga/amiga: autoconf.c
src/sys/arch/amiga/dev: grf_cc.c grf_cl.c grf_cv.c grf_cv3d.c grf_et.c
grf_rh.c grf_rt.c grf_ul.c
src/sys/arch/amigappc/amigappc: autoconf.c
src/sys/arch/arm/iomd: iomdiic.c
src/sys/arch/atari/atari: autoconf.c
src/sys/arch/atari/dev: ite_cc.c ite_et.c
src/sys/arch/dreamcast/dev/maple: maple.c
src/sys/arch/mips/mips: cpu_subr.c
src/sys/ddb: db_autoconf.c
src/sys/dev/sbus: esp_sbus.c
src/sys/dev/wscons: wsmux.c
src/sys/kern: kern_pmf.c subr_autoconf.c subr_device.c
src/sys/rump/librump/rumpkern: rump.c
src/sys/sys: device.h
Added Files:
src/sys/sys: device_impl.h

Log Message:
sys: Split struct device into a private device_impl.h.

Include this only inside autoconf itself, and a few files that abuse
autoconf in ways I can't confidently make easy fixes for.

XXX kernel ABI change requires bump -- no more use of struct device
internals allowed, previously done by some drivers


To generate a diff of this commit:
cvs rdiff -u -r1.120 -r1.121 src/sys/arch/amiga/amiga/autoconf.c
cvs rdiff -u -r1.43 -r1.44 src/sys/arch/amiga/dev/grf_cc.c
cvs rdiff -u -r1.54 -r1.55 src/sys/arch/amiga/dev/grf_cl.c
cvs rdiff -u -r1.63 -r1.64 src/sys/arch/amiga/dev/grf_cv.c
cvs rdiff -u -r1.38 -r1.39 src/sys/arch/amiga/dev/grf_cv3d.c
cvs rdiff -u -r1.39 -r1.40 src/sys/arch/amiga/dev/grf_et.c
cvs rdiff -u -r1.60 -r1.61 src/sys/arch/amiga/dev/grf_rh.c \
src/sys/arch/amiga/dev/grf_rt.c
cvs rdiff -u -r1.53 -r1.54 src/sys/arch/amiga/dev/grf_ul.c
cvs rdiff -u -r1.9 -r1.10 src/sys/arch/amigappc/amigappc/autoconf.c
cvs rdiff -u -r1.11 -r1.12 src/sys/arch/arm/iomd/iomdiic.c
cvs rdiff -u -r1.71 -r1.72 src/sys/arch/atari/atari/autoconf.c
cvs rdiff -u -r1.43 -r1.44 src/sys/arch/atari/dev/ite_cc.c
cvs rdiff -u -r1.34 -r1.35 src/sys/arch/atari/dev/ite_et.c
cvs rdiff -u -r1.55 -r1.56 src/sys/arch/dreamcast/dev/maple/maple.c
cvs rdiff -u -r1.60 -r1.61 src/sys/arch/mips/mips/cpu_subr.c
cvs rdiff -u -r1.2 -r1.3 src/sys/ddb/db_autoconf.c
cvs rdiff -u -r1.56 -r1.57 src/sys/dev/sbus/esp_sbus.c
cvs rdiff -u -r1.65 -r1.66 src/sys/dev/wscons/wsmux.c
cvs rdiff -u -r1.47 -r1.48 src/sys/kern/kern_pmf.c
cvs rdiff -u -r1.300 -r1.301 src/sys/kern/subr_autoconf.c
cvs rdiff -u -r1.12 -r1.13 src/sys/kern/subr_device.c
cvs rdiff -u -r1.353 -r1.354 src/sys/rump/librump/rumpkern/rump.c
cvs rdiff -u -r1.181 -r1.182 src/sys/sys/device.h
cvs rdiff -u -r0 -r1.1 src/sys/sys/device_impl.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/arch/amiga/amiga/autoconf.c
diff -u src/sys/arch/amiga/amiga/autoconf.c:1.120 src/sys/arch/amiga/amiga/autoconf.c:1.121
--- src/sys/arch/amiga/amiga/autoconf.c:1.120	Sat Aug  7 16:18:41 2021
+++ src/sys/arch/amiga/amiga/autoconf.c	Mon Mar 28 12:38:57 2022
@@ -1,4 +1,4 @@
-/*	$NetBSD: autoconf.c,v 1.120 2021/08/07 16:18:41 thorpej Exp $	*/
+/*	$NetBSD: autoconf.c,v 1.121 2022/03/28 12:38:57 riastradh Exp $	*/
 
 /*
  * Copyright (c) 1994 Christian E. Hopps
@@ -31,7 +31,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: autoconf.c,v 1.120 2021/08/07 16:18:41 thorpej Exp $");
+__KERNEL_RCSID(0, "$NetBSD: autoconf.c,v 1.121 2022/03/28 12:38:57 riastradh Exp $");
 
 #include 
 #include 
@@ -39,6 +39,7 @@ __KERNEL_RCSID(0, "$NetBSD: autoconf.c,v
 #include 
 #include 
 #include 
+#include 	/* XXX autoconf abuse */
 #include 
 #include 
 #include 

Index: src/sys/arch/amiga/dev/grf_cc.c
diff -u src/sys/arch/amiga/dev/grf_cc.c:1.43 src/sys/arch/amiga/dev/grf_cc.c:1.44
--- src/sys/arch/amiga/dev/grf_cc.c:1.43	Sat Aug  7 16:18:41 2021
+++ src/sys/arch/amiga/dev/grf_cc.c	Mon Mar 28 12:38:57 2022
@@ -1,4 +1,4 @@
-/*	$NetBSD: grf_cc.c,v 1.43 2021/08/07 16:18:41 thorpej Exp $ */
+/*	$NetBSD: grf_cc.c,v 1.44 2022/03/28 12:38:57 riastradh Exp $ */
 
 /*
  * Copyright (c) 1994 Christian E. Hopps
@@ -31,7 +31,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: grf_cc.c,v 1.43 2021/08/07 16:18:41 thorpej Exp $");
+__KERNEL_RCSID(0, "$NetBSD: grf_cc.c,v 1.44 2022/03/28 12:38:57 riastradh Exp $");
 
 #include "grfcc.h"
 #include "ite.h"
@@ -47,6 +47,7 @@ __KERNEL_RCSID(0, "$NetBSD: grf_cc.c,v 1
 #include 
 #include 
 #include 
+#include 	/* XXX autoconf abuse */
 #include 
 #include 
 #include 

Index: src/sys/arch/amiga/dev/grf_cl.c
diff -u src/sys/arch/amiga/dev/grf_cl.c:1.54 src/sys/arch/amiga/dev/grf_cl.c:1.55
--- src/sys/arch/amiga/dev/grf_cl.c:1.54	Sun Dec 26 16:08:19 2021
+++ src/sys/arch/amiga/dev/grf_cl.c	Mon Mar 28 12:38:57 2022
@@ -1,4 +1,4 @@
-/*	$NetBSD: grf_cl.c,v 1.54 2021/12/26 16:08:19 andvar Exp $ */
+/*	$NetBSD: grf_cl.c,v 1.55 2022/03/28 12:38:57 riastradh Exp $ */
 
 /*
  * Copyright (c) 1997 Klaus Burkert
@@ -36,7 +36,7 @@
 #include "opt_amigacons.h"
 
 #include 

CVS commit: src/sys

2022-03-28 Thread Taylor R Campbell
Module Name:src
Committed By:   riastradh
Date:   Mon Mar 28 12:38:59 UTC 2022

Modified Files:
src/sys/arch/amiga/amiga: autoconf.c
src/sys/arch/amiga/dev: grf_cc.c grf_cl.c grf_cv.c grf_cv3d.c grf_et.c
grf_rh.c grf_rt.c grf_ul.c
src/sys/arch/amigappc/amigappc: autoconf.c
src/sys/arch/arm/iomd: iomdiic.c
src/sys/arch/atari/atari: autoconf.c
src/sys/arch/atari/dev: ite_cc.c ite_et.c
src/sys/arch/dreamcast/dev/maple: maple.c
src/sys/arch/mips/mips: cpu_subr.c
src/sys/ddb: db_autoconf.c
src/sys/dev/sbus: esp_sbus.c
src/sys/dev/wscons: wsmux.c
src/sys/kern: kern_pmf.c subr_autoconf.c subr_device.c
src/sys/rump/librump/rumpkern: rump.c
src/sys/sys: device.h
Added Files:
src/sys/sys: device_impl.h

Log Message:
sys: Split struct device into a private device_impl.h.

Include this only inside autoconf itself, and a few files that abuse
autoconf in ways I can't confidently make easy fixes for.

XXX kernel ABI change requires bump -- no more use of struct device
internals allowed, previously done by some drivers


To generate a diff of this commit:
cvs rdiff -u -r1.120 -r1.121 src/sys/arch/amiga/amiga/autoconf.c
cvs rdiff -u -r1.43 -r1.44 src/sys/arch/amiga/dev/grf_cc.c
cvs rdiff -u -r1.54 -r1.55 src/sys/arch/amiga/dev/grf_cl.c
cvs rdiff -u -r1.63 -r1.64 src/sys/arch/amiga/dev/grf_cv.c
cvs rdiff -u -r1.38 -r1.39 src/sys/arch/amiga/dev/grf_cv3d.c
cvs rdiff -u -r1.39 -r1.40 src/sys/arch/amiga/dev/grf_et.c
cvs rdiff -u -r1.60 -r1.61 src/sys/arch/amiga/dev/grf_rh.c \
src/sys/arch/amiga/dev/grf_rt.c
cvs rdiff -u -r1.53 -r1.54 src/sys/arch/amiga/dev/grf_ul.c
cvs rdiff -u -r1.9 -r1.10 src/sys/arch/amigappc/amigappc/autoconf.c
cvs rdiff -u -r1.11 -r1.12 src/sys/arch/arm/iomd/iomdiic.c
cvs rdiff -u -r1.71 -r1.72 src/sys/arch/atari/atari/autoconf.c
cvs rdiff -u -r1.43 -r1.44 src/sys/arch/atari/dev/ite_cc.c
cvs rdiff -u -r1.34 -r1.35 src/sys/arch/atari/dev/ite_et.c
cvs rdiff -u -r1.55 -r1.56 src/sys/arch/dreamcast/dev/maple/maple.c
cvs rdiff -u -r1.60 -r1.61 src/sys/arch/mips/mips/cpu_subr.c
cvs rdiff -u -r1.2 -r1.3 src/sys/ddb/db_autoconf.c
cvs rdiff -u -r1.56 -r1.57 src/sys/dev/sbus/esp_sbus.c
cvs rdiff -u -r1.65 -r1.66 src/sys/dev/wscons/wsmux.c
cvs rdiff -u -r1.47 -r1.48 src/sys/kern/kern_pmf.c
cvs rdiff -u -r1.300 -r1.301 src/sys/kern/subr_autoconf.c
cvs rdiff -u -r1.12 -r1.13 src/sys/kern/subr_device.c
cvs rdiff -u -r1.353 -r1.354 src/sys/rump/librump/rumpkern/rump.c
cvs rdiff -u -r1.181 -r1.182 src/sys/sys/device.h
cvs rdiff -u -r0 -r1.1 src/sys/sys/device_impl.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.



CVS commit: src/sys

2022-03-28 Thread Taylor R Campbell
Module Name:src
Committed By:   riastradh
Date:   Mon Mar 28 12:38:34 UTC 2022

Modified Files:
src/sys/kern: subr_devsw.c vfs_subr.c
src/sys/sys: conf.h

Log Message:
driver(9): Make vdevgone call config_detach_commit if appropriate.

Make sure to do this before spec_node_lookup_by_dev -- that might wait
for a concurrent revoke to complete, which in turn might wait for a
concurrent open to complete, which in turn might be waiting for the
device to commit to detaching.


To generate a diff of this commit:
cvs rdiff -u -r1.42 -r1.43 src/sys/kern/subr_devsw.c
cvs rdiff -u -r1.492 -r1.493 src/sys/kern/vfs_subr.c
cvs rdiff -u -r1.158 -r1.159 src/sys/sys/conf.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/kern/subr_devsw.c
diff -u src/sys/kern/subr_devsw.c:1.42 src/sys/kern/subr_devsw.c:1.43
--- src/sys/kern/subr_devsw.c:1.42	Mon Mar 28 12:34:08 2022
+++ src/sys/kern/subr_devsw.c	Mon Mar 28 12:38:33 2022
@@ -1,4 +1,4 @@
-/*	$NetBSD: subr_devsw.c,v 1.42 2022/03/28 12:34:08 riastradh Exp $	*/
+/*	$NetBSD: subr_devsw.c,v 1.43 2022/03/28 12:38:33 riastradh Exp $	*/
 
 /*-
  * Copyright (c) 2001, 2002, 2007, 2008 The NetBSD Foundation, Inc.
@@ -69,7 +69,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: subr_devsw.c,v 1.42 2022/03/28 12:34:08 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: subr_devsw.c,v 1.43 2022/03/28 12:38:33 riastradh Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_dtrace.h"
@@ -1068,6 +1068,24 @@ bdev_discard(dev_t dev, off_t pos, off_t
 	return rv;
 }
 
+void
+bdev_detached(dev_t dev)
+{
+	const struct bdevsw *d;
+	device_t dv;
+	int unit;
+
+	if ((d = bdevsw_lookup(dev)) == NULL)
+		return;
+	if (d->d_devtounit == NULL)
+		return;
+	if ((unit = (*d->d_devtounit)(dev)) == -1)
+		return;
+	if ((dv = device_lookup(d->d_cfdriver, unit)) == NULL)
+		return;
+	config_detach_commit(dv);
+}
+
 int
 cdev_open(dev_t dev, int flag, int devtype, lwp_t *l)
 {
@@ -1288,6 +1306,24 @@ cdev_type(dev_t dev)
 	return d->d_flag & D_TYPEMASK;
 }
 
+void
+cdev_detached(dev_t dev)
+{
+	const struct cdevsw *d;
+	device_t dv;
+	int unit;
+
+	if ((d = cdevsw_lookup(dev)) == NULL)
+		return;
+	if (d->d_devtounit == NULL)
+		return;
+	if ((unit = (*d->d_devtounit)(dev)) == -1)
+		return;
+	if ((dv = device_lookup(d->d_cfdriver, unit)) == NULL)
+		return;
+	config_detach_commit(dv);
+}
+
 /*
  * nommap(dev, off, prot)
  *

Index: src/sys/kern/vfs_subr.c
diff -u src/sys/kern/vfs_subr.c:1.492 src/sys/kern/vfs_subr.c:1.493
--- src/sys/kern/vfs_subr.c:1.492	Mon Mar 28 12:37:46 2022
+++ src/sys/kern/vfs_subr.c	Mon Mar 28 12:38:33 2022
@@ -1,4 +1,4 @@
-/*	$NetBSD: vfs_subr.c,v 1.492 2022/03/28 12:37:46 riastradh Exp $	*/
+/*	$NetBSD: vfs_subr.c,v 1.493 2022/03/28 12:38:33 riastradh Exp $	*/
 
 /*-
  * Copyright (c) 1997, 1998, 2004, 2005, 2007, 2008, 2019, 2020
@@ -69,7 +69,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: vfs_subr.c,v 1.492 2022/03/28 12:37:46 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: vfs_subr.c,v 1.493 2022/03/28 12:38:33 riastradh Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_ddb.h"
@@ -512,6 +512,20 @@ vdevgone(int maj, int minl, int minh, en
 	for (mn = minl; mn <= minh; mn++) {
 		dev = makedev(maj, mn);
 		/*
+		 * Notify anyone trying to get at this device that it
+		 * has been detached, and then revoke it.
+		 */
+		switch (type) {
+		case VBLK:
+			bdev_detached(dev);
+			break;
+		case VCHR:
+			cdev_detached(dev);
+			break;
+		default:
+			panic("invalid specnode type: %d", type);
+		}
+		/*
 		 * Passing 0 as flags, instead of VDEAD_NOWAIT, means
 		 * spec_node_lookup_by_dev will wait for vnodes it
 		 * finds concurrently being revoked before returning.

Index: src/sys/sys/conf.h
diff -u src/sys/sys/conf.h:1.158 src/sys/sys/conf.h:1.159
--- src/sys/sys/conf.h:1.158	Mon Mar 28 12:34:17 2022
+++ src/sys/sys/conf.h	Mon Mar 28 12:38:33 2022
@@ -1,4 +1,4 @@
-/*	$NetBSD: conf.h,v 1.158 2022/03/28 12:34:17 riastradh Exp $	*/
+/*	$NetBSD: conf.h,v 1.159 2022/03/28 12:38:33 riastradh Exp $	*/
 
 /*-
  * Copyright (c) 1990, 1993
@@ -172,6 +172,8 @@ dev_type_dump(bdev_dump);
 dev_type_size(bdev_size);
 dev_type_discard(bdev_discard);
 
+void	bdev_detached(dev_t);
+
 dev_type_open(cdev_open);
 dev_type_close(cdev_close);
 dev_type_read(cdev_read);
@@ -184,6 +186,8 @@ dev_type_mmap(cdev_mmap);
 dev_type_kqfilter(cdev_kqfilter);
 dev_type_discard(cdev_discard);
 
+void	cdev_detached(dev_t);
+
 int	cdev_type(dev_t);
 int	cdev_flags(dev_t);
 int	bdev_type(dev_t);



CVS commit: src/sys

2022-03-28 Thread Taylor R Campbell
Module Name:src
Committed By:   riastradh
Date:   Mon Mar 28 12:38:34 UTC 2022

Modified Files:
src/sys/kern: subr_devsw.c vfs_subr.c
src/sys/sys: conf.h

Log Message:
driver(9): Make vdevgone call config_detach_commit if appropriate.

Make sure to do this before spec_node_lookup_by_dev -- that might wait
for a concurrent revoke to complete, which in turn might wait for a
concurrent open to complete, which in turn might be waiting for the
device to commit to detaching.


To generate a diff of this commit:
cvs rdiff -u -r1.42 -r1.43 src/sys/kern/subr_devsw.c
cvs rdiff -u -r1.492 -r1.493 src/sys/kern/vfs_subr.c
cvs rdiff -u -r1.158 -r1.159 src/sys/sys/conf.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.



CVS commit: src/sys/kern

2022-03-28 Thread Taylor R Campbell
Module Name:src
Committed By:   riastradh
Date:   Mon Mar 28 12:38:25 UTC 2022

Modified Files:
src/sys/kern: subr_autoconf.c

Log Message:
autoconf(9): Disentangle slightly circuitous config_detach logic.

No functional change intended.


To generate a diff of this commit:
cvs rdiff -u -r1.299 -r1.300 src/sys/kern/subr_autoconf.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/kern/subr_autoconf.c
diff -u src/sys/kern/subr_autoconf.c:1.299 src/sys/kern/subr_autoconf.c:1.300
--- src/sys/kern/subr_autoconf.c:1.299	Mon Mar 28 12:38:15 2022
+++ src/sys/kern/subr_autoconf.c	Mon Mar 28 12:38:24 2022
@@ -1,4 +1,4 @@
-/* $NetBSD: subr_autoconf.c,v 1.299 2022/03/28 12:38:15 riastradh Exp $ */
+/* $NetBSD: subr_autoconf.c,v 1.300 2022/03/28 12:38:24 riastradh Exp $ */
 
 /*
  * Copyright (c) 1996, 2000 Christopher G. Demetriou
@@ -77,7 +77,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: subr_autoconf.c,v 1.299 2022/03/28 12:38:15 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: subr_autoconf.c,v 1.300 2022/03/28 12:38:24 riastradh Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_ddb.h"
@@ -2023,6 +2023,11 @@ config_detach(device_t dev, int flags)
 	alldevs_nwrite++;
 	mutex_exit(_lock);
 
+	/*
+	 * Call the driver's .ca_detach function, unless it has none or
+	 * we are skipping it because it's unforced shutdown time and
+	 * the driver didn't ask to detach on shutdown.
+	 */
 	if (!detachall &&
 	(flags & (DETACH_SHUTDOWN|DETACH_FORCE)) == DETACH_SHUTDOWN &&
 	(dev->dv_flags & DVF_DETACH_SHUTDOWN) == 0) {
@@ -2035,25 +2040,20 @@ config_detach(device_t dev, int flags)
 	/*
 	 * If it was not possible to detach the device, then we either
 	 * panic() (for the forced but failed case), or return an error.
-	 *
-	 * If it was possible to detach the device, ensure that the
-	 * device is deactivated.
 	 */
-	if (rv == 0) {
-		config_detach_commit(dev);
-		dev->dv_flags &= ~DVF_ACTIVE; /* XXXSMP */
-	} else if ((flags & DETACH_FORCE) == 0) {
+	if (rv) {
 		/*
-		 * Detach failed -- likely EBUSY.  Driver must not have
-		 * called config_detach_commit.
+		 * Detach failed -- likely EOPNOTSUPP or EBUSY.  Driver
+		 * must not have called config_detach_commit.
 		 */
 		KASSERTMSG(!dev->dv_detached,
 		"%s committed to detaching and then backed out",
 		device_xname(dev));
+		if (flags & DETACH_FORCE) {
+			panic("config_detach: forced detach of %s failed (%d)",
+			device_xname(dev), rv);
+		}
 		goto out;
-	} else {
-		panic("config_detach: forced detach of %s failed (%d)",
-		device_xname(dev), rv);
 	}
 
 	/*
@@ -2061,6 +2061,19 @@ config_detach(device_t dev, int flags)
 	 */
 
 	/*
+	 * If .ca_detach didn't commit to detach, then do that for it.
+	 * This wakes any pending device_lookup_acquire calls so they
+	 * will fail.
+	 */
+	config_detach_commit(dev);
+
+	/*
+	 * If it was possible to detach the device, ensure that the
+	 * device is deactivated.
+	 */
+	dev->dv_flags &= ~DVF_ACTIVE; /* XXXSMP */
+
+	/*
 	 * Wait for all device_lookup_acquire references -- mostly, for
 	 * all attempts to open the device -- to drain.  It is the
 	 * responsibility of .ca_detach to ensure anything with open



CVS commit: src/sys/kern

2022-03-28 Thread Taylor R Campbell
Module Name:src
Committed By:   riastradh
Date:   Mon Mar 28 12:38:25 UTC 2022

Modified Files:
src/sys/kern: subr_autoconf.c

Log Message:
autoconf(9): Disentangle slightly circuitous config_detach logic.

No functional change intended.


To generate a diff of this commit:
cvs rdiff -u -r1.299 -r1.300 src/sys/kern/subr_autoconf.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.



CVS commit: src/sys

2022-03-28 Thread Taylor R Campbell
Module Name:src
Committed By:   riastradh
Date:   Mon Mar 28 12:38:15 UTC 2022

Modified Files:
src/sys/kern: subr_autoconf.c
src/sys/sys: device.h

Log Message:
autoconf(9): New function config_detach_commit.

When a driver's .ca_detach function has committed to detaching -- it
definitely won't back out with EBUSY, for instance -- it can call
this to wake all pending calls to device_lookup_acquire and make them
fail immediately.

This is necessary to break a deadlock if the device_lookup_acquire
calls happen inside I/O operations which the driver's .ca_detach
function waits for the completion of -- without config_detach_commit,
I/O operations would be stuck in device_lookup_acquire waiting for
.ca_detach and .ca_detach would be stuck waiting for I/O operations
to return.

Most drivers won't need to call this: for autoconf drivers used the
traditional way by devsw for userland device nodes, the .ca_detach
routine uses vdevgone, and we will arrange to make vdevgone call
config_detach_commit automagically in such drivers anyway.

XXX kernel ABI change to struct device requires bump -- later change
will make struct device opaque to ABI, but we're not there yet


To generate a diff of this commit:
cvs rdiff -u -r1.298 -r1.299 src/sys/kern/subr_autoconf.c
cvs rdiff -u -r1.180 -r1.181 src/sys/sys/device.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/kern/subr_autoconf.c
diff -u src/sys/kern/subr_autoconf.c:1.298 src/sys/kern/subr_autoconf.c:1.299
--- src/sys/kern/subr_autoconf.c:1.298	Mon Mar 28 12:33:41 2022
+++ src/sys/kern/subr_autoconf.c	Mon Mar 28 12:38:15 2022
@@ -1,4 +1,4 @@
-/* $NetBSD: subr_autoconf.c,v 1.298 2022/03/28 12:33:41 riastradh Exp $ */
+/* $NetBSD: subr_autoconf.c,v 1.299 2022/03/28 12:38:15 riastradh Exp $ */
 
 /*
  * Copyright (c) 1996, 2000 Christopher G. Demetriou
@@ -77,7 +77,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: subr_autoconf.c,v 1.298 2022/03/28 12:33:41 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: subr_autoconf.c,v 1.299 2022/03/28 12:38:15 riastradh Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_ddb.h"
@@ -2039,10 +2039,17 @@ config_detach(device_t dev, int flags)
 	 * If it was possible to detach the device, ensure that the
 	 * device is deactivated.
 	 */
-	if (rv == 0)
-		dev->dv_flags &= ~DVF_ACTIVE;
-	else if ((flags & DETACH_FORCE) == 0) {
-		/* Detach failed -- likely EBUSY.  */
+	if (rv == 0) {
+		config_detach_commit(dev);
+		dev->dv_flags &= ~DVF_ACTIVE; /* XXXSMP */
+	} else if ((flags & DETACH_FORCE) == 0) {
+		/*
+		 * Detach failed -- likely EBUSY.  Driver must not have
+		 * called config_detach_commit.
+		 */
+		KASSERTMSG(!dev->dv_detached,
+		"%s committed to detaching and then backed out",
+		device_xname(dev));
 		goto out;
 	} else {
 		panic("config_detach: forced detach of %s failed (%d)",
@@ -2059,7 +2066,8 @@ config_detach(device_t dev, int flags)
 	 * responsibility of .ca_detach to ensure anything with open
 	 * references will be interrupted and release them promptly,
 	 * not block indefinitely.  All new attempts to acquire
-	 * references will block until dv_detaching clears.
+	 * references will fail, as config_detach_commit has arranged
+	 * by now.
 	 */
 	mutex_enter(_misc_lock);
 	localcount_drain(dev->dv_localcount,
@@ -2133,6 +2141,30 @@ out:
 	return rv;
 }
 
+/*
+ * config_detach_commit(dev)
+ *
+ *	Issued by a driver's .ca_detach routine to notify anyone
+ *	waiting in device_lookup_acquire that the driver is committed
+ *	to detaching the device, which allows device_lookup_acquire to
+ *	wake up and fail immediately.
+ *
+ *	Safe to call multiple times -- idempotent.  Must be called
+ *	during config_detach_enter/exit.  Safe to use with
+ *	device_lookup because the device is not actually removed from
+ *	the table until after config_detach_exit.
+ */
+void
+config_detach_commit(device_t dev)
+{
+
+	mutex_enter(_misc_lock);
+	KASSERT(dev->dv_detaching == curlwp);
+	dev->dv_detached = true;
+	cv_broadcast(_misc_cv);
+	mutex_exit(_misc_lock);
+}
+
 int
 config_detach_children(device_t parent, int flags)
 {
@@ -2640,7 +2672,8 @@ device_lookup_acquire(cfdriver_t cd, int
 	mutex_enter(_lock);
 retry:	if (unit < 0 || unit >= cd->cd_ndevs ||
 	(dv = cd->cd_devs[unit]) == NULL ||
-	dv->dv_del_gen != 0) {
+	dv->dv_del_gen != 0 ||
+	dv->dv_detached) {
 		dv = NULL;
 	} else {
 		/*

Index: src/sys/sys/device.h
diff -u src/sys/sys/device.h:1.180 src/sys/sys/device.h:1.181
--- src/sys/sys/device.h:1.180	Mon Mar 28 12:33:41 2022
+++ src/sys/sys/device.h	Mon Mar 28 12:38:15 2022
@@ -1,4 +1,4 @@
-/* $NetBSD: device.h,v 1.180 2022/03/28 12:33:41 riastradh Exp $ */
+/* $NetBSD: device.h,v 1.181 2022/03/28 12:38:15 riastradh Exp $ */
 
 /*
  * Copyright (c) 2021 The NetBSD Foundation, Inc.
@@ -281,6 +281,7 @@ struct device {
 
 	struct lwp	*dv_attaching;	/* thread not yet finished in attach 

CVS commit: src/sys

2022-03-28 Thread Taylor R Campbell
Module Name:src
Committed By:   riastradh
Date:   Mon Mar 28 12:38:15 UTC 2022

Modified Files:
src/sys/kern: subr_autoconf.c
src/sys/sys: device.h

Log Message:
autoconf(9): New function config_detach_commit.

When a driver's .ca_detach function has committed to detaching -- it
definitely won't back out with EBUSY, for instance -- it can call
this to wake all pending calls to device_lookup_acquire and make them
fail immediately.

This is necessary to break a deadlock if the device_lookup_acquire
calls happen inside I/O operations which the driver's .ca_detach
function waits for the completion of -- without config_detach_commit,
I/O operations would be stuck in device_lookup_acquire waiting for
.ca_detach and .ca_detach would be stuck waiting for I/O operations
to return.

Most drivers won't need to call this: for autoconf drivers used the
traditional way by devsw for userland device nodes, the .ca_detach
routine uses vdevgone, and we will arrange to make vdevgone call
config_detach_commit automagically in such drivers anyway.

XXX kernel ABI change to struct device requires bump -- later change
will make struct device opaque to ABI, but we're not there yet


To generate a diff of this commit:
cvs rdiff -u -r1.298 -r1.299 src/sys/kern/subr_autoconf.c
cvs rdiff -u -r1.180 -r1.181 src/sys/sys/device.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.



CVS commit: src/sys/miscfs/specfs

2022-03-28 Thread Taylor R Campbell
Module Name:src
Committed By:   riastradh
Date:   Mon Mar 28 12:38:04 UTC 2022

Modified Files:
src/sys/miscfs/specfs: specdev.h

Log Message:
specfs: Reorder struct specnode members to save padding.

Shrinks from 40 bytes to 32 bytes on LP64 systems this way.


To generate a diff of this commit:
cvs rdiff -u -r1.51 -r1.52 src/sys/miscfs/specfs/specdev.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/miscfs/specfs/specdev.h
diff -u src/sys/miscfs/specfs/specdev.h:1.51 src/sys/miscfs/specfs/specdev.h:1.52
--- src/sys/miscfs/specfs/specdev.h:1.51	Mon Mar 28 12:37:46 2022
+++ src/sys/miscfs/specfs/specdev.h	Mon Mar 28 12:38:04 2022
@@ -1,4 +1,4 @@
-/*	$NetBSD: specdev.h,v 1.51 2022/03/28 12:37:46 riastradh Exp $	*/
+/*	$NetBSD: specdev.h,v 1.52 2022/03/28 12:38:04 riastradh Exp $	*/
 
 /*-
  * Copyright (c) 2008 The NetBSD Foundation, Inc.
@@ -66,8 +66,8 @@
 typedef struct specnode {
 	vnode_t		*sn_next;
 	struct specdev	*sn_dev;
-	u_int		sn_opencnt;	/* # of opens, share of sd_opencnt */
 	dev_t		sn_rdev;
+	u_int		sn_opencnt;	/* # of opens, share of sd_opencnt */
 	bool		sn_gone;
 } specnode_t;
 



CVS commit: src/sys/miscfs/specfs

2022-03-28 Thread Taylor R Campbell
Module Name:src
Committed By:   riastradh
Date:   Mon Mar 28 12:38:04 UTC 2022

Modified Files:
src/sys/miscfs/specfs: specdev.h

Log Message:
specfs: Reorder struct specnode members to save padding.

Shrinks from 40 bytes to 32 bytes on LP64 systems this way.


To generate a diff of this commit:
cvs rdiff -u -r1.51 -r1.52 src/sys/miscfs/specfs/specdev.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.



CVS commit: src/sys

2022-03-28 Thread Taylor R Campbell
Module Name:src
Committed By:   riastradh
Date:   Mon Mar 28 12:37:56 UTC 2022

Modified Files:
src/sys/kern: vfs_vnode.c
src/sys/miscfs/specfs: spec_vnops.c

Log Message:
specfs: Remove specnode from hash table in spec_node_revoke.

Previously, it was possible for spec_node_lookup_by_dev to handle a
speconde that a concurrent spec_node_destroy is about to remove from
the hash table and then free, as soon as spec_node_lookup_by_dev
releases device_lock.

Now, the ordering is:

1. Remove specnode from hash table in spec_node_revoke.  At this
   point, no _new_ vnode references are possible (other than possibly
   one acquired by vcache_vget under v_interlock), but there may be
   existing ones.

2. Mark vnode reclaimed so vcache_vget will fail.

3. The last vrele (or equivalent logic in vcache_vget) will then free
   the specnode in spec_node_destroy.

This way, _if_ a thread in spec_node_lookup_by_dev finds a specnode
in the hash table under device_lock/v_interlock, _then_ it will not
be freed until the thread completes vcache_vget.

This change requires calling spec_node_revoke unconditionally for
device special nodes, not just for active ones.  Might introduce
slightly more contention on device_lock but not much because we
already have to take it in this path anyway a little later in
spec_node_destroy.


To generate a diff of this commit:
cvs rdiff -u -r1.140 -r1.141 src/sys/kern/vfs_vnode.c
cvs rdiff -u -r1.208 -r1.209 src/sys/miscfs/specfs/spec_vnops.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/kern/vfs_vnode.c
diff -u src/sys/kern/vfs_vnode.c:1.140 src/sys/kern/vfs_vnode.c:1.141
--- src/sys/kern/vfs_vnode.c:1.140	Mon Mar 28 12:37:46 2022
+++ src/sys/kern/vfs_vnode.c	Mon Mar 28 12:37:56 2022
@@ -1,4 +1,4 @@
-/*	$NetBSD: vfs_vnode.c,v 1.140 2022/03/28 12:37:46 riastradh Exp $	*/
+/*	$NetBSD: vfs_vnode.c,v 1.141 2022/03/28 12:37:56 riastradh Exp $	*/
 
 /*-
  * Copyright (c) 1997-2011, 2019, 2020 The NetBSD Foundation, Inc.
@@ -148,7 +148,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: vfs_vnode.c,v 1.140 2022/03/28 12:37:46 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: vfs_vnode.c,v 1.141 2022/03/28 12:37:56 riastradh Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_pax.h"
@@ -1811,14 +1811,13 @@ vcache_reclaim(vnode_t *vp)
 	uint32_t hash;
 	uint8_t temp_buf[64], *temp_key;
 	size_t temp_key_len;
-	bool recycle, active;
+	bool recycle;
 	int error;
 
 	KASSERT(VOP_ISLOCKED(vp) == LK_EXCLUSIVE);
 	KASSERT(mutex_owned(vp->v_interlock));
 	KASSERT(vrefcnt(vp) != 0);
 
-	active = (vrefcnt(vp) > 1);
 	temp_key_len = vip->vi_key.vk_key_len;
 	/*
 	 * Prevent the vnode from being recycled or brought into use
@@ -1861,8 +1860,6 @@ vcache_reclaim(vnode_t *vp)
 
 	/*
 	 * Clean out any cached data associated with the vnode.
-	 * If purging an active vnode, it must be closed and
-	 * deactivated before being reclaimed.
 	 */
 	error = vinvalbuf(vp, V_SAVE, NOCRED, l, 0, 0);
 	if (error != 0) {
@@ -1872,7 +1869,7 @@ vcache_reclaim(vnode_t *vp)
 	}
 	KASSERTMSG((error == 0), "vinvalbuf failed: %d", error);
 	KASSERT((vp->v_iflag & VI_ONWORKLST) == 0);
-	if (active && (vp->v_type == VBLK || vp->v_type == VCHR)) {
+	if (vp->v_type == VBLK || vp->v_type == VCHR) {
 		 spec_node_revoke(vp);
 	}
 

Index: src/sys/miscfs/specfs/spec_vnops.c
diff -u src/sys/miscfs/specfs/spec_vnops.c:1.208 src/sys/miscfs/specfs/spec_vnops.c:1.209
--- src/sys/miscfs/specfs/spec_vnops.c:1.208	Mon Mar 28 12:37:46 2022
+++ src/sys/miscfs/specfs/spec_vnops.c	Mon Mar 28 12:37:56 2022
@@ -1,4 +1,4 @@
-/*	$NetBSD: spec_vnops.c,v 1.208 2022/03/28 12:37:46 riastradh Exp $	*/
+/*	$NetBSD: spec_vnops.c,v 1.209 2022/03/28 12:37:56 riastradh Exp $	*/
 
 /*-
  * Copyright (c) 2008 The NetBSD Foundation, Inc.
@@ -58,7 +58,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: spec_vnops.c,v 1.208 2022/03/28 12:37:46 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: spec_vnops.c,v 1.209 2022/03/28 12:37:56 riastradh Exp $");
 
 #include 
 #include 
@@ -591,6 +591,7 @@ spec_node_revoke(vnode_t *vp)
 {
 	specnode_t *sn;
 	specdev_t *sd;
+	struct vnode **vpp;
 
 	KASSERT(VOP_ISLOCKED(vp) == LK_EXCLUSIVE);
 
@@ -603,10 +604,10 @@ spec_node_revoke(vnode_t *vp)
 
 	mutex_enter(_lock);
 	KASSERT(sn->sn_opencnt <= sd->sd_opencnt);
+	sn->sn_gone = true;
 	if (sn->sn_opencnt != 0) {
 		sd->sd_opencnt -= (sn->sn_opencnt - 1);
 		sn->sn_opencnt = 1;
-		sn->sn_gone = true;
 		mutex_exit(_lock);
 
 		VOP_CLOSE(vp, FNONBLOCK, NOCRED);
@@ -624,6 +625,22 @@ spec_node_revoke(vnode_t *vp)
 	 */
 	while (sd->sd_closing)
 		cv_wait(_iocv, _lock);
+
+	/*
+	 * Remove from the hash so lookups stop returning this
+	 * specnode.  We will dissociate it from the specdev -- and
+	 * possibly free the specdev -- in spec_node_destroy.
+	 */
+	KASSERT(sn->sn_gone);
+	KASSERT(sn->sn_opencnt == 0);
+	for (vpp = _hash[SPECHASH(vp->v_rdev)];;
+	 vpp = 

CVS commit: src/sys

2022-03-28 Thread Taylor R Campbell
Module Name:src
Committed By:   riastradh
Date:   Mon Mar 28 12:37:56 UTC 2022

Modified Files:
src/sys/kern: vfs_vnode.c
src/sys/miscfs/specfs: spec_vnops.c

Log Message:
specfs: Remove specnode from hash table in spec_node_revoke.

Previously, it was possible for spec_node_lookup_by_dev to handle a
speconde that a concurrent spec_node_destroy is about to remove from
the hash table and then free, as soon as spec_node_lookup_by_dev
releases device_lock.

Now, the ordering is:

1. Remove specnode from hash table in spec_node_revoke.  At this
   point, no _new_ vnode references are possible (other than possibly
   one acquired by vcache_vget under v_interlock), but there may be
   existing ones.

2. Mark vnode reclaimed so vcache_vget will fail.

3. The last vrele (or equivalent logic in vcache_vget) will then free
   the specnode in spec_node_destroy.

This way, _if_ a thread in spec_node_lookup_by_dev finds a specnode
in the hash table under device_lock/v_interlock, _then_ it will not
be freed until the thread completes vcache_vget.

This change requires calling spec_node_revoke unconditionally for
device special nodes, not just for active ones.  Might introduce
slightly more contention on device_lock but not much because we
already have to take it in this path anyway a little later in
spec_node_destroy.


To generate a diff of this commit:
cvs rdiff -u -r1.140 -r1.141 src/sys/kern/vfs_vnode.c
cvs rdiff -u -r1.208 -r1.209 src/sys/miscfs/specfs/spec_vnops.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.



CVS commit: src/sys

2022-03-28 Thread Taylor R Campbell
Module Name:src
Committed By:   riastradh
Date:   Mon Mar 28 12:37:46 UTC 2022

Modified Files:
src/sys/coda: coda_vfsops.c
src/sys/kern: vfs_mount.c vfs_subr.c vfs_vnode.c
src/sys/miscfs/specfs: spec_vnops.c specdev.h

Log Message:
specfs: Let spec_node_lookup_by_dev wait for reclaim to finish.

vdevgone relies on this to ensure that if there is a concurrent
revoke in progress, it will wait for that revoke to finish -- that
way, it can guarantee all I/O operations have completed and the
device is closed.


To generate a diff of this commit:
cvs rdiff -u -r1.89 -r1.90 src/sys/coda/coda_vfsops.c
cvs rdiff -u -r1.91 -r1.92 src/sys/kern/vfs_mount.c
cvs rdiff -u -r1.491 -r1.492 src/sys/kern/vfs_subr.c
cvs rdiff -u -r1.139 -r1.140 src/sys/kern/vfs_vnode.c
cvs rdiff -u -r1.207 -r1.208 src/sys/miscfs/specfs/spec_vnops.c
cvs rdiff -u -r1.50 -r1.51 src/sys/miscfs/specfs/specdev.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/coda/coda_vfsops.c
diff -u src/sys/coda/coda_vfsops.c:1.89 src/sys/coda/coda_vfsops.c:1.90
--- src/sys/coda/coda_vfsops.c:1.89	Fri Nov 20 10:08:47 2020
+++ src/sys/coda/coda_vfsops.c	Mon Mar 28 12:37:46 2022
@@ -1,4 +1,4 @@
-/*	$NetBSD: coda_vfsops.c,v 1.89 2020/11/20 10:08:47 hannken Exp $	*/
+/*	$NetBSD: coda_vfsops.c,v 1.90 2022/03/28 12:37:46 riastradh Exp $	*/
 
 /*
  *
@@ -45,7 +45,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: coda_vfsops.c,v 1.89 2020/11/20 10:08:47 hannken Exp $");
+__KERNEL_RCSID(0, "$NetBSD: coda_vfsops.c,v 1.90 2022/03/28 12:37:46 riastradh Exp $");
 
 #include 
 #include 
@@ -636,7 +636,7 @@ struct mount *devtomp(dev_t dev)
 struct mount *mp;
 struct vnode *vp;
 
-if (spec_node_lookup_by_dev(VBLK, dev, ) == 0) {
+if (spec_node_lookup_by_dev(VBLK, dev, VDEAD_NOWAIT, ) == 0) {
 	mp = spec_node_getmountedfs(vp);
 	vrele(vp);
 } else {

Index: src/sys/kern/vfs_mount.c
diff -u src/sys/kern/vfs_mount.c:1.91 src/sys/kern/vfs_mount.c:1.92
--- src/sys/kern/vfs_mount.c:1.91	Thu Mar 24 12:59:56 2022
+++ src/sys/kern/vfs_mount.c	Mon Mar 28 12:37:46 2022
@@ -1,4 +1,4 @@
-/*	$NetBSD: vfs_mount.c,v 1.91 2022/03/24 12:59:56 riastradh Exp $	*/
+/*	$NetBSD: vfs_mount.c,v 1.92 2022/03/28 12:37:46 riastradh Exp $	*/
 
 /*-
  * Copyright (c) 1997-2020 The NetBSD Foundation, Inc.
@@ -67,7 +67,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: vfs_mount.c,v 1.91 2022/03/24 12:59:56 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: vfs_mount.c,v 1.92 2022/03/28 12:37:46 riastradh Exp $");
 
 #include 
 #include 
@@ -1376,7 +1376,8 @@ vfs_mountedon(vnode_t *vp)
 		return ENOTBLK;
 	if (spec_node_getmountedfs(vp) != NULL)
 		return EBUSY;
-	if (spec_node_lookup_by_dev(vp->v_type, vp->v_rdev, ) == 0) {
+	if (spec_node_lookup_by_dev(vp->v_type, vp->v_rdev, VDEAD_NOWAIT, )
+	== 0) {
 		if (spec_node_getmountedfs(vq) != NULL)
 			error = EBUSY;
 		vrele(vq);

Index: src/sys/kern/vfs_subr.c
diff -u src/sys/kern/vfs_subr.c:1.491 src/sys/kern/vfs_subr.c:1.492
--- src/sys/kern/vfs_subr.c:1.491	Sat Oct 16 07:12:01 2021
+++ src/sys/kern/vfs_subr.c	Mon Mar 28 12:37:46 2022
@@ -1,4 +1,4 @@
-/*	$NetBSD: vfs_subr.c,v 1.491 2021/10/16 07:12:01 simonb Exp $	*/
+/*	$NetBSD: vfs_subr.c,v 1.492 2022/03/28 12:37:46 riastradh Exp $	*/
 
 /*-
  * Copyright (c) 1997, 1998, 2004, 2005, 2007, 2008, 2019, 2020
@@ -69,7 +69,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: vfs_subr.c,v 1.491 2021/10/16 07:12:01 simonb Exp $");
+__KERNEL_RCSID(0, "$NetBSD: vfs_subr.c,v 1.492 2022/03/28 12:37:46 riastradh Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_ddb.h"
@@ -495,7 +495,7 @@ int
 vfinddev(dev_t dev, enum vtype type, vnode_t **vpp)
 {
 
-	return (spec_node_lookup_by_dev(type, dev, vpp) == 0);
+	return (spec_node_lookup_by_dev(type, dev, VDEAD_NOWAIT, vpp) == 0);
 }
 
 /*
@@ -511,7 +511,12 @@ vdevgone(int maj, int minl, int minh, en
 
 	for (mn = minl; mn <= minh; mn++) {
 		dev = makedev(maj, mn);
-		while (spec_node_lookup_by_dev(type, dev, ) == 0) {
+		/*
+		 * Passing 0 as flags, instead of VDEAD_NOWAIT, means
+		 * spec_node_lookup_by_dev will wait for vnodes it
+		 * finds concurrently being revoked before returning.
+		 */
+		while (spec_node_lookup_by_dev(type, dev, 0, ) == 0) {
 			VOP_REVOKE(vp, REVOKEALL);
 			vrele(vp);
 		}

Index: src/sys/kern/vfs_vnode.c
diff -u src/sys/kern/vfs_vnode.c:1.139 src/sys/kern/vfs_vnode.c:1.140
--- src/sys/kern/vfs_vnode.c:1.139	Sat Mar 19 13:53:32 2022
+++ src/sys/kern/vfs_vnode.c	Mon Mar 28 12:37:46 2022
@@ -1,4 +1,4 @@
-/*	$NetBSD: vfs_vnode.c,v 1.139 2022/03/19 13:53:32 hannken Exp $	*/
+/*	$NetBSD: vfs_vnode.c,v 1.140 2022/03/28 12:37:46 riastradh Exp $	*/
 
 /*-
  * Copyright (c) 1997-2011, 2019, 2020 The NetBSD Foundation, Inc.
@@ -148,7 +148,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: vfs_vnode.c,v 1.139 2022/03/19 13:53:32 hannken Exp $");
+__KERNEL_RCSID(0, "$NetBSD: vfs_vnode.c,v 1.140 

CVS commit: src/sys

2022-03-28 Thread Taylor R Campbell
Module Name:src
Committed By:   riastradh
Date:   Mon Mar 28 12:37:46 UTC 2022

Modified Files:
src/sys/coda: coda_vfsops.c
src/sys/kern: vfs_mount.c vfs_subr.c vfs_vnode.c
src/sys/miscfs/specfs: spec_vnops.c specdev.h

Log Message:
specfs: Let spec_node_lookup_by_dev wait for reclaim to finish.

vdevgone relies on this to ensure that if there is a concurrent
revoke in progress, it will wait for that revoke to finish -- that
way, it can guarantee all I/O operations have completed and the
device is closed.


To generate a diff of this commit:
cvs rdiff -u -r1.89 -r1.90 src/sys/coda/coda_vfsops.c
cvs rdiff -u -r1.91 -r1.92 src/sys/kern/vfs_mount.c
cvs rdiff -u -r1.491 -r1.492 src/sys/kern/vfs_subr.c
cvs rdiff -u -r1.139 -r1.140 src/sys/kern/vfs_vnode.c
cvs rdiff -u -r1.207 -r1.208 src/sys/miscfs/specfs/spec_vnops.c
cvs rdiff -u -r1.50 -r1.51 src/sys/miscfs/specfs/specdev.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.



CVS commit: src/sys/miscfs/specfs

2022-03-28 Thread Taylor R Campbell
Module Name:src
Committed By:   riastradh
Date:   Mon Mar 28 12:37:35 UTC 2022

Modified Files:
src/sys/miscfs/specfs: spec_vnops.c

Log Message:
specfs: Assert opencnt is nonzero before decrementing.


To generate a diff of this commit:
cvs rdiff -u -r1.206 -r1.207 src/sys/miscfs/specfs/spec_vnops.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/miscfs/specfs/spec_vnops.c
diff -u src/sys/miscfs/specfs/spec_vnops.c:1.206 src/sys/miscfs/specfs/spec_vnops.c:1.207
--- src/sys/miscfs/specfs/spec_vnops.c:1.206	Mon Mar 28 12:37:26 2022
+++ src/sys/miscfs/specfs/spec_vnops.c	Mon Mar 28 12:37:35 2022
@@ -1,4 +1,4 @@
-/*	$NetBSD: spec_vnops.c,v 1.206 2022/03/28 12:37:26 riastradh Exp $	*/
+/*	$NetBSD: spec_vnops.c,v 1.207 2022/03/28 12:37:35 riastradh Exp $	*/
 
 /*-
  * Copyright (c) 2008 The NetBSD Foundation, Inc.
@@ -58,7 +58,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: spec_vnops.c,v 1.206 2022/03/28 12:37:26 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: spec_vnops.c,v 1.207 2022/03/28 12:37:35 riastradh Exp $");
 
 #include 
 #include 
@@ -944,6 +944,8 @@ spec_open(void *v)
 		KASSERT(sn->sn_opencnt == 1);
 		needclose = true;
 	} else {
+		KASSERT(sd->sd_opencnt);
+		KASSERT(sn->sn_opencnt);
 		sd->sd_opencnt--;
 		sn->sn_opencnt--;
 		if (vp->v_type == VBLK)
@@ -1643,6 +1645,8 @@ spec_close(void *v)
 	 * between open and close can use fd_clone.
 	 */
 	mutex_enter(_lock);
+	KASSERT(sn->sn_opencnt);
+	KASSERT(sd->sd_opencnt);
 	sn->sn_opencnt--;
 	count = --sd->sd_opencnt;
 	if (vp->v_type == VBLK) {



CVS commit: src/sys/miscfs/specfs

2022-03-28 Thread Taylor R Campbell
Module Name:src
Committed By:   riastradh
Date:   Mon Mar 28 12:37:35 UTC 2022

Modified Files:
src/sys/miscfs/specfs: spec_vnops.c

Log Message:
specfs: Assert opencnt is nonzero before decrementing.


To generate a diff of this commit:
cvs rdiff -u -r1.206 -r1.207 src/sys/miscfs/specfs/spec_vnops.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.



CVS commit: src/sys/miscfs/specfs

2022-03-28 Thread Taylor R Campbell
Module Name:src
Committed By:   riastradh
Date:   Mon Mar 28 12:37:27 UTC 2022

Modified Files:
src/sys/miscfs/specfs: spec_vnops.c

Log Message:
specfs: Take an I/O reference across bdev/cdev_open.

- Revoke is used to invalidate all prior access control checks when
  device permissions are changing, so it must wait for .d_open to exit
  so any new access must go through new access control checks.

- Revoke is used by vdevgone in xyz_detach to wait until all use of
  the driver's data structures have completed before xyz_detach frees
  them.

So we need to make sure spec_close waits for .d_open too.


To generate a diff of this commit:
cvs rdiff -u -r1.205 -r1.206 src/sys/miscfs/specfs/spec_vnops.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/miscfs/specfs/spec_vnops.c
diff -u src/sys/miscfs/specfs/spec_vnops.c:1.205 src/sys/miscfs/specfs/spec_vnops.c:1.206
--- src/sys/miscfs/specfs/spec_vnops.c:1.205	Mon Mar 28 12:37:18 2022
+++ src/sys/miscfs/specfs/spec_vnops.c	Mon Mar 28 12:37:26 2022
@@ -1,4 +1,4 @@
-/*	$NetBSD: spec_vnops.c,v 1.205 2022/03/28 12:37:18 riastradh Exp $	*/
+/*	$NetBSD: spec_vnops.c,v 1.206 2022/03/28 12:37:26 riastradh Exp $	*/
 
 /*-
  * Copyright (c) 2008 The NetBSD Foundation, Inc.
@@ -58,7 +58,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: spec_vnops.c,v 1.205 2022/03/28 12:37:18 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: spec_vnops.c,v 1.206 2022/03/28 12:37:26 riastradh Exp $");
 
 #include 
 #include 
@@ -694,10 +694,10 @@ spec_open(void *v)
 	} */ *ap = v;
 	struct lwp *l = curlwp;
 	struct vnode *vp = ap->a_vp;
-	dev_t dev;
+	dev_t dev, dev1;
 	int error;
 	enum kauth_device_req req;
-	specnode_t *sn;
+	specnode_t *sn, *sn1;
 	specdev_t *sd;
 	spec_ioctl_t ioctl;
 	u_int gen = 0;
@@ -805,18 +805,34 @@ spec_open(void *v)
 	}
 
 	/*
-	 * Open the device.  If .d_open returns ENXIO (device not
-	 * configured), the driver may not be loaded, so try
-	 * autoloading a module and then try .d_open again if anything
-	 * got loaded.
-	 *
 	 * Because opening the device may block indefinitely, e.g. when
 	 * opening a tty, and loading a module may cross into many
 	 * other subsystems, we must not hold the vnode lock while
 	 * calling .d_open, so release it now and reacquire it when
 	 * done.
+	 *
+	 * Take an I/O reference so that any concurrent spec_close via
+	 * spec_node_revoke will wait for us to finish calling .d_open.
+	 * The vnode can't be dead at this point because we have it
+	 * locked.  Note that if revoked, the driver must interrupt
+	 * .d_open before spec_close starts waiting for I/O to drain so
+	 * this doesn't deadlock.
 	 */
 	VOP_UNLOCK(vp);
+	error = spec_io_enter(vp, , );
+	if (error) {
+		vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
+		return error;
+	}
+	KASSERT(sn1 == sn);
+	KASSERT(dev1 == dev);
+
+	/*
+	 * Open the device.  If .d_open returns ENXIO (device not
+	 * configured), the driver may not be loaded, so try
+	 * autoloading a module and then try .d_open again if anything
+	 * got loaded.
+	 */
 	switch (vp->v_type) {
 	case VCHR:
 		do {
@@ -871,7 +887,16 @@ spec_open(void *v)
 	default:
 		__unreachable();
 	}
+
+	/*
+	 * Release the I/O reference now that we have called .d_open,
+	 * and reacquire the vnode lock.  At this point, the device may
+	 * have been revoked, so we must tread carefully.  However, sn
+	 * and sd remain valid pointers until we drop our reference.
+	 */
+	spec_io_exit(vp, sn);
 	vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
+	KASSERT(vp->v_specnode == sn);
 
 	/*
 	 * If it has been revoked since we released the vnode lock and



CVS commit: src/sys/miscfs/specfs

2022-03-28 Thread Taylor R Campbell
Module Name:src
Committed By:   riastradh
Date:   Mon Mar 28 12:37:27 UTC 2022

Modified Files:
src/sys/miscfs/specfs: spec_vnops.c

Log Message:
specfs: Take an I/O reference across bdev/cdev_open.

- Revoke is used to invalidate all prior access control checks when
  device permissions are changing, so it must wait for .d_open to exit
  so any new access must go through new access control checks.

- Revoke is used by vdevgone in xyz_detach to wait until all use of
  the driver's data structures have completed before xyz_detach frees
  them.

So we need to make sure spec_close waits for .d_open too.


To generate a diff of this commit:
cvs rdiff -u -r1.205 -r1.206 src/sys/miscfs/specfs/spec_vnops.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.



CVS commit: src/sys/miscfs/specfs

2022-03-28 Thread Taylor R Campbell
Module Name:src
Committed By:   riastradh
Date:   Mon Mar 28 12:37:18 UTC 2022

Modified Files:
src/sys/miscfs/specfs: spec_vnops.c

Log Message:
specfs: Wait for last close in spec_node_revoke.

Otherwise, revoke -- and vdevgone, in the detach path of removable
devices -- may complete while I/O operations are still running
concurrently.


To generate a diff of this commit:
cvs rdiff -u -r1.204 -r1.205 src/sys/miscfs/specfs/spec_vnops.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/miscfs/specfs/spec_vnops.c
diff -u src/sys/miscfs/specfs/spec_vnops.c:1.204 src/sys/miscfs/specfs/spec_vnops.c:1.205
--- src/sys/miscfs/specfs/spec_vnops.c:1.204	Mon Mar 28 12:37:09 2022
+++ src/sys/miscfs/specfs/spec_vnops.c	Mon Mar 28 12:37:18 2022
@@ -1,4 +1,4 @@
-/*	$NetBSD: spec_vnops.c,v 1.204 2022/03/28 12:37:09 riastradh Exp $	*/
+/*	$NetBSD: spec_vnops.c,v 1.205 2022/03/28 12:37:18 riastradh Exp $	*/
 
 /*-
  * Copyright (c) 2008 The NetBSD Foundation, Inc.
@@ -58,7 +58,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: spec_vnops.c,v 1.204 2022/03/28 12:37:09 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: spec_vnops.c,v 1.205 2022/03/28 12:37:18 riastradh Exp $");
 
 #include 
 #include 
@@ -597,6 +597,16 @@ spec_node_revoke(vnode_t *vp)
 		mutex_enter(_lock);
 		KASSERT(sn->sn_opencnt == 0);
 	}
+
+	/*
+	 * We may have revoked the vnode in this thread while another
+	 * thread was in the middle of spec_close, in the window when
+	 * spec_close releases the vnode lock to call .d_close for the
+	 * last close.  In that case, wait for the concurrent
+	 * spec_close to complete.
+	 */
+	while (sd->sd_closing)
+		cv_wait(_iocv, _lock);
 	mutex_exit(_lock);
 }
 



CVS commit: src/sys/miscfs/specfs

2022-03-28 Thread Taylor R Campbell
Module Name:src
Committed By:   riastradh
Date:   Mon Mar 28 12:37:18 UTC 2022

Modified Files:
src/sys/miscfs/specfs: spec_vnops.c

Log Message:
specfs: Wait for last close in spec_node_revoke.

Otherwise, revoke -- and vdevgone, in the detach path of removable
devices -- may complete while I/O operations are still running
concurrently.


To generate a diff of this commit:
cvs rdiff -u -r1.204 -r1.205 src/sys/miscfs/specfs/spec_vnops.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.



CVS commit: src/sys/miscfs/specfs

2022-03-28 Thread Taylor R Campbell
Module Name:src
Committed By:   riastradh
Date:   Mon Mar 28 12:37:09 UTC 2022

Modified Files:
src/sys/miscfs/specfs: spec_vnops.c specdev.h

Log Message:
specfs: Prevent new opens while close is waiting to drain.

Otherwise, bdev/cdev_close could have cancelled all _existing_ opens,
and waited for them to complete (and freed resources used by them) --
but a new one could start, and hang (e.g., a tty), at the same time
spec_close tries to drain all pending I/O operations, one of which
(the new open) is now hanging indefinitely.

Preventing the new open from even starting until bdev/cdev_close is
finished and all I/O operations have drained avoids this deadlock.


To generate a diff of this commit:
cvs rdiff -u -r1.203 -r1.204 src/sys/miscfs/specfs/spec_vnops.c
cvs rdiff -u -r1.49 -r1.50 src/sys/miscfs/specfs/specdev.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/miscfs/specfs/spec_vnops.c
diff -u src/sys/miscfs/specfs/spec_vnops.c:1.203 src/sys/miscfs/specfs/spec_vnops.c:1.204
--- src/sys/miscfs/specfs/spec_vnops.c:1.203	Mon Mar 28 12:37:01 2022
+++ src/sys/miscfs/specfs/spec_vnops.c	Mon Mar 28 12:37:09 2022
@@ -1,4 +1,4 @@
-/*	$NetBSD: spec_vnops.c,v 1.203 2022/03/28 12:37:01 riastradh Exp $	*/
+/*	$NetBSD: spec_vnops.c,v 1.204 2022/03/28 12:37:09 riastradh Exp $	*/
 
 /*-
  * Copyright (c) 2008 The NetBSD Foundation, Inc.
@@ -58,7 +58,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: spec_vnops.c,v 1.203 2022/03/28 12:37:01 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: spec_vnops.c,v 1.204 2022/03/28 12:37:09 riastradh Exp $");
 
 #include 
 #include 
@@ -397,6 +397,7 @@ spec_node_init(vnode_t *vp, dev_t rdev)
 		sd->sd_bdevvp = NULL;
 		sd->sd_iocnt = 0;
 		sd->sd_opened = false;
+		sd->sd_closing = false;
 		sn->sn_dev = sd;
 		sd = NULL;
 	} else {
@@ -734,8 +735,17 @@ spec_open(void *v)
 	case VCHR:
 		/*
 		 * Character devices can accept opens from multiple
-		 * vnodes.
+		 * vnodes.  But first, wait for any close to finish.
+		 * Wait under the vnode lock so we don't have to worry
+		 * about the vnode being revoked while we wait.
 		 */
+		while (sd->sd_closing) {
+			error = cv_wait_sig(_iocv, _lock);
+			if (error)
+break;
+		}
+		if (error)
+			break;
 		sd->sd_opencnt++;
 		sn->sn_opencnt++;
 		break;
@@ -1605,8 +1615,10 @@ spec_close(void *v)
 		count + 1);
 		sd->sd_bdevvp = NULL;
 	}
-	if (count == 0)
+	if (count == 0) {
 		sd->sd_opened = false;
+		sd->sd_closing = true;
+	}
 	mutex_exit(_lock);
 
 	if (count != 0)
@@ -1631,6 +1643,18 @@ spec_close(void *v)
 	 */
 	spec_io_drain(sd);
 
+	/*
+	 * Wake any spec_open calls waiting for close to finish -- do
+	 * this before reacquiring the vnode lock, because spec_open
+	 * holds the vnode lock while waiting, so doing this after
+	 * reacquiring the lock would deadlock.
+	 */
+	mutex_enter(_lock);
+	KASSERT(sd->sd_closing);
+	sd->sd_closing = false;
+	cv_broadcast(_iocv);
+	mutex_exit(_lock);
+
 	if (!(flags & FNONBLOCK))
 		vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
 

Index: src/sys/miscfs/specfs/specdev.h
diff -u src/sys/miscfs/specfs/specdev.h:1.49 src/sys/miscfs/specfs/specdev.h:1.50
--- src/sys/miscfs/specfs/specdev.h:1.49	Mon Mar 28 12:36:51 2022
+++ src/sys/miscfs/specfs/specdev.h	Mon Mar 28 12:37:09 2022
@@ -1,4 +1,4 @@
-/*	$NetBSD: specdev.h,v 1.49 2022/03/28 12:36:51 riastradh Exp $	*/
+/*	$NetBSD: specdev.h,v 1.50 2022/03/28 12:37:09 riastradh Exp $	*/
 
 /*-
  * Copyright (c) 2008 The NetBSD Foundation, Inc.
@@ -80,6 +80,7 @@ typedef struct specdev {
 	dev_t		sd_rdev;
 	volatile u_int	sd_iocnt;	/* # bdev/cdev_* operations active */
 	bool		sd_opened;	/* true if successfully opened */
+	bool		sd_closing;	/* true when bdev/cdev_close ongoing */
 } specdev_t;
 
 /*



CVS commit: src/sys/miscfs/specfs

2022-03-28 Thread Taylor R Campbell
Module Name:src
Committed By:   riastradh
Date:   Mon Mar 28 12:37:09 UTC 2022

Modified Files:
src/sys/miscfs/specfs: spec_vnops.c specdev.h

Log Message:
specfs: Prevent new opens while close is waiting to drain.

Otherwise, bdev/cdev_close could have cancelled all _existing_ opens,
and waited for them to complete (and freed resources used by them) --
but a new one could start, and hang (e.g., a tty), at the same time
spec_close tries to drain all pending I/O operations, one of which
(the new open) is now hanging indefinitely.

Preventing the new open from even starting until bdev/cdev_close is
finished and all I/O operations have drained avoids this deadlock.


To generate a diff of this commit:
cvs rdiff -u -r1.203 -r1.204 src/sys/miscfs/specfs/spec_vnops.c
cvs rdiff -u -r1.49 -r1.50 src/sys/miscfs/specfs/specdev.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.



CVS commit: src/sys/miscfs/specfs

2022-03-28 Thread Taylor R Campbell
Module Name:src
Committed By:   riastradh
Date:   Mon Mar 28 12:37:01 UTC 2022

Modified Files:
src/sys/miscfs/specfs: spec_vnops.c

Log Message:
specfs: Take an I/O reference in spec_node_setmountedfs.

This is not quite correct.  We _should_ require the caller to hold a
vnode lock around spec_node_getmountedfs, and an exclusive vnode lock
around spec_node_setmountedfs, so that it is only necessary to check
whether revoke has already happened, not hold an I/O reference.

Unfortunately, various callers in various file systems don't follow
this sensible rule.  So let's at least make sure the vnode can't be
revoked in spec_node_setmountedfs, while we're in bdev_ioctl, and
leave a comment explaining what the sorry state of affairs is and how
to fix it later.


To generate a diff of this commit:
cvs rdiff -u -r1.202 -r1.203 src/sys/miscfs/specfs/spec_vnops.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/miscfs/specfs/spec_vnops.c
diff -u src/sys/miscfs/specfs/spec_vnops.c:1.202 src/sys/miscfs/specfs/spec_vnops.c:1.203
--- src/sys/miscfs/specfs/spec_vnops.c:1.202	Mon Mar 28 12:36:51 2022
+++ src/sys/miscfs/specfs/spec_vnops.c	Mon Mar 28 12:37:01 2022
@@ -1,4 +1,4 @@
-/*	$NetBSD: spec_vnops.c,v 1.202 2022/03/28 12:36:51 riastradh Exp $	*/
+/*	$NetBSD: spec_vnops.c,v 1.203 2022/03/28 12:37:01 riastradh Exp $	*/
 
 /*-
  * Copyright (c) 2008 The NetBSD Foundation, Inc.
@@ -58,7 +58,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: spec_vnops.c,v 1.202 2022/03/28 12:36:51 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: spec_vnops.c,v 1.203 2022/03/28 12:37:01 riastradh Exp $");
 
 #include 
 #include 
@@ -498,6 +498,11 @@ spec_node_lookup_by_mount(struct mount *
 
 /*
  * Get the file system mounted on this block device.
+ *
+ * XXX Caller should hold the vnode lock -- shared or exclusive -- so
+ * that this can't changed, and the vnode can't be revoked while we
+ * examine it.  But not all callers do, and they're scattered through a
+ * lot of file systems, so we can't assert this yet.
  */
 struct mount *
 spec_node_getmountedfs(vnode_t *devvp)
@@ -512,23 +517,51 @@ spec_node_getmountedfs(vnode_t *devvp)
 
 /*
  * Set the file system mounted on this block device.
+ *
+ * XXX Caller should hold the vnode lock exclusively so this can't be
+ * changed or assumed by spec_node_getmountedfs while we change it, and
+ * the vnode can't be revoked while we handle it.  But not all callers
+ * do, and they're scattered through a lot of file systems, so we can't
+ * assert this yet.  Instead, for now, we'll take an I/O reference so
+ * at least the ioctl doesn't race with revoke/detach.
+ *
+ * If you do change this to assert an exclusive vnode lock, you must
+ * also do vdead_check before trying bdev_ioctl, because the vnode may
+ * have been revoked by the time the caller locked it, and this is
+ * _not_ a vop -- calls to spec_node_setmountedfs don't go through
+ * v_op, so revoking the vnode doesn't prevent further calls.
+ *
+ * XXX Caller should additionally have the vnode open, at least if mp
+ * is nonnull, but I'm not sure all callers do that -- need to audit.
+ * Currently udf closes the vnode before clearing the mount.
  */
 void
 spec_node_setmountedfs(vnode_t *devvp, struct mount *mp)
 {
 	struct dkwedge_info dkw;
+	struct specnode *sn;
+	dev_t dev;
+	int error;
 
 	KASSERT(devvp->v_type == VBLK);
-	KASSERT(devvp->v_specnode->sn_dev->sd_mountpoint == NULL || mp == NULL);
-	devvp->v_specnode->sn_dev->sd_mountpoint = mp;
-	if (mp == NULL)
-		return;
 
-	if (bdev_ioctl(devvp->v_rdev, DIOCGWEDGEINFO, , FREAD, curlwp) != 0)
+	error = spec_io_enter(devvp, , );
+	if (error)
 		return;
 
+	KASSERT(sn->sn_dev->sd_mountpoint == NULL || mp == NULL);
+	sn->sn_dev->sd_mountpoint = mp;
+	if (mp == NULL)
+		goto out;
+
+	error = bdev_ioctl(dev, DIOCGWEDGEINFO, , FREAD, curlwp);
+	if (error)
+		goto out;
+
 	strlcpy(mp->mnt_stat.f_mntfromlabel, dkw.dkw_wname,
 	sizeof(mp->mnt_stat.f_mntfromlabel));
+
+out:	spec_io_exit(devvp, sn);
 }
 
 /*



CVS commit: src/sys/miscfs/specfs

2022-03-28 Thread Taylor R Campbell
Module Name:src
Committed By:   riastradh
Date:   Mon Mar 28 12:37:01 UTC 2022

Modified Files:
src/sys/miscfs/specfs: spec_vnops.c

Log Message:
specfs: Take an I/O reference in spec_node_setmountedfs.

This is not quite correct.  We _should_ require the caller to hold a
vnode lock around spec_node_getmountedfs, and an exclusive vnode lock
around spec_node_setmountedfs, so that it is only necessary to check
whether revoke has already happened, not hold an I/O reference.

Unfortunately, various callers in various file systems don't follow
this sensible rule.  So let's at least make sure the vnode can't be
revoked in spec_node_setmountedfs, while we're in bdev_ioctl, and
leave a comment explaining what the sorry state of affairs is and how
to fix it later.


To generate a diff of this commit:
cvs rdiff -u -r1.202 -r1.203 src/sys/miscfs/specfs/spec_vnops.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.



CVS commit: src/sys/miscfs/specfs

2022-03-28 Thread Taylor R Campbell
Module Name:src
Committed By:   riastradh
Date:   Mon Mar 28 12:36:51 UTC 2022

Modified Files:
src/sys/miscfs/specfs: spec_vnops.c specdev.h

Log Message:
specfs: Drain all I/O operations after last .d_close call.

New kind of I/O reference on specdevs, sd_iocnt.  This could be done
with psref instead; I chose a reference count instead for now because
we already have to take a per-object lock anyway, v_interlock, for
vdead_check, so another atomic is not likely to hurt much more.  We
can always change the mechanism inside spec_io_enter/exit/drain later
on.

Make sure every access to vp->v_rdev or vp->v_specnode and every call
to a devsw operation is protected either:

- by the vnode lock (with vdead_check if we unlocked/relocked),
- by positive sd_opencnt,
- by spec_io_enter/exit, or
- by sd_opencnt management in open/close.


To generate a diff of this commit:
cvs rdiff -u -r1.201 -r1.202 src/sys/miscfs/specfs/spec_vnops.c
cvs rdiff -u -r1.48 -r1.49 src/sys/miscfs/specfs/specdev.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/miscfs/specfs/spec_vnops.c
diff -u src/sys/miscfs/specfs/spec_vnops.c:1.201 src/sys/miscfs/specfs/spec_vnops.c:1.202
--- src/sys/miscfs/specfs/spec_vnops.c:1.201	Mon Mar 28 12:36:42 2022
+++ src/sys/miscfs/specfs/spec_vnops.c	Mon Mar 28 12:36:51 2022
@@ -1,4 +1,4 @@
-/*	$NetBSD: spec_vnops.c,v 1.201 2022/03/28 12:36:42 riastradh Exp $	*/
+/*	$NetBSD: spec_vnops.c,v 1.202 2022/03/28 12:36:51 riastradh Exp $	*/
 
 /*-
  * Copyright (c) 2008 The NetBSD Foundation, Inc.
@@ -58,7 +58,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: spec_vnops.c,v 1.201 2022/03/28 12:36:42 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: spec_vnops.c,v 1.202 2022/03/28 12:36:51 riastradh Exp $");
 
 #include 
 #include 
@@ -81,6 +81,7 @@ __KERNEL_RCSID(0, "$NetBSD: spec_vnops.c
 #include 
 #include 
 #include 
+#include 
 
 #include 
 #include 
@@ -173,6 +174,7 @@ const struct vnodeopv_desc spec_vnodeop_
 	{ _vnodeop_p, spec_vnodeop_entries };
 
 static kauth_listener_t rawio_listener;
+static struct kcondvar specfs_iocv;
 
 /* Returns true if vnode is /dev/mem or /dev/kmem. */
 bool
@@ -218,6 +220,141 @@ spec_init(void)
 
 	rawio_listener = kauth_listen_scope(KAUTH_SCOPE_DEVICE,
 	rawio_listener_cb, NULL);
+	cv_init(_iocv, "specio");
+}
+
+/*
+ * spec_io_enter(vp, , )
+ *
+ *	Enter an operation that may not hold vp's vnode lock or an
+ *	fstrans on vp's mount.  Until spec_io_exit, the vnode will not
+ *	be revoked.
+ *
+ *	On success, set sn to the specnode pointer and dev to the dev_t
+ *	number and return zero.  Caller must later call spec_io_exit
+ *	when done.
+ *
+ *	On failure, return ENXIO -- the device has been revoked and no
+ *	longer exists.
+ */
+static int
+spec_io_enter(struct vnode *vp, struct specnode **snp, dev_t *devp)
+{
+	dev_t dev;
+	struct specnode *sn;
+	unsigned iocnt;
+	int error = 0;
+
+	mutex_enter(vp->v_interlock);
+
+	/*
+	 * Extract all the info we need from the vnode, unless the
+	 * vnode has already been reclaimed.  This can happen if the
+	 * underlying device has been removed and all the device nodes
+	 * for it have been revoked.  The caller may not hold a vnode
+	 * lock or fstrans to prevent this from happening before it has
+	 * had an opportunity to notice the vnode is dead.
+	 */
+	if (vdead_check(vp, VDEAD_NOWAIT) != 0 ||
+	(sn = vp->v_specnode) == NULL ||
+	(dev = vp->v_rdev) == NODEV) {
+		error = ENXIO;
+		goto out;
+	}
+
+	/*
+	 * Notify spec_close that we are doing an I/O operation which
+	 * may not be not bracketed by fstrans(9) and thus is not
+	 * blocked by vfs suspension.
+	 *
+	 * We could hold this reference with psref(9) instead, but we
+	 * already have to take the interlock for vdead_check, so
+	 * there's not much more cost here to another atomic operation.
+	 */
+	do {
+		iocnt = atomic_load_relaxed(>sn_dev->sd_iocnt);
+		if (__predict_false(iocnt == UINT_MAX)) {
+			/*
+			 * The I/O count is limited by the number of
+			 * LWPs (which will never overflow this) --
+			 * unless one driver uses another driver via
+			 * specfs, which is rather unusual, but which
+			 * could happen via pud(4) userspace drivers.
+			 * We could use a 64-bit count, but can't use
+			 * atomics for that on all platforms.
+			 * (Probably better to switch to psref or
+			 * localcount instead.)
+			 */
+			error = EBUSY;
+			goto out;
+		}
+	} while (atomic_cas_uint(>sn_dev->sd_iocnt, iocnt, iocnt + 1)
+	!= iocnt);
+
+	/* Success!  */
+	*snp = sn;
+	*devp = dev;
+	error = 0;
+
+out:	mutex_exit(vp->v_interlock);
+	return error;
+}
+
+/*
+ * spec_io_exit(vp, sn)
+ *
+ *	Exit an operation entered with a successful spec_io_enter --
+ *	allow concurrent spec_node_revoke to proceed.  The argument sn
+ *	must match the struct specnode pointer returned by spec_io_exit
+ *	for vp.
+ */
+static void
+spec_io_exit(struct vnode *vp, struct 

CVS commit: src/sys/miscfs/specfs

2022-03-28 Thread Taylor R Campbell
Module Name:src
Committed By:   riastradh
Date:   Mon Mar 28 12:36:51 UTC 2022

Modified Files:
src/sys/miscfs/specfs: spec_vnops.c specdev.h

Log Message:
specfs: Drain all I/O operations after last .d_close call.

New kind of I/O reference on specdevs, sd_iocnt.  This could be done
with psref instead; I chose a reference count instead for now because
we already have to take a per-object lock anyway, v_interlock, for
vdead_check, so another atomic is not likely to hurt much more.  We
can always change the mechanism inside spec_io_enter/exit/drain later
on.

Make sure every access to vp->v_rdev or vp->v_specnode and every call
to a devsw operation is protected either:

- by the vnode lock (with vdead_check if we unlocked/relocked),
- by positive sd_opencnt,
- by spec_io_enter/exit, or
- by sd_opencnt management in open/close.


To generate a diff of this commit:
cvs rdiff -u -r1.201 -r1.202 src/sys/miscfs/specfs/spec_vnops.c
cvs rdiff -u -r1.48 -r1.49 src/sys/miscfs/specfs/specdev.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.



CVS commit: src/sys/miscfs/specfs

2022-03-28 Thread Taylor R Campbell
Module Name:src
Committed By:   riastradh
Date:   Mon Mar 28 12:36:42 UTC 2022

Modified Files:
src/sys/miscfs/specfs: spec_vnops.c specdev.h

Log Message:
specfs: Resolve a race between close and a failing reopen.


To generate a diff of this commit:
cvs rdiff -u -r1.200 -r1.201 src/sys/miscfs/specfs/spec_vnops.c
cvs rdiff -u -r1.47 -r1.48 src/sys/miscfs/specfs/specdev.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/miscfs/specfs/spec_vnops.c
diff -u src/sys/miscfs/specfs/spec_vnops.c:1.200 src/sys/miscfs/specfs/spec_vnops.c:1.201
--- src/sys/miscfs/specfs/spec_vnops.c:1.200	Mon Mar 28 12:36:26 2022
+++ src/sys/miscfs/specfs/spec_vnops.c	Mon Mar 28 12:36:42 2022
@@ -1,4 +1,4 @@
-/*	$NetBSD: spec_vnops.c,v 1.200 2022/03/28 12:36:26 riastradh Exp $	*/
+/*	$NetBSD: spec_vnops.c,v 1.201 2022/03/28 12:36:42 riastradh Exp $	*/
 
 /*-
  * Copyright (c) 2008 The NetBSD Foundation, Inc.
@@ -58,7 +58,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: spec_vnops.c,v 1.200 2022/03/28 12:36:26 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: spec_vnops.c,v 1.201 2022/03/28 12:36:42 riastradh Exp $");
 
 #include 
 #include 
@@ -258,6 +258,7 @@ spec_node_init(vnode_t *vp, dev_t rdev)
 		sd->sd_refcnt = 1;
 		sd->sd_opencnt = 0;
 		sd->sd_bdevvp = NULL;
+		sd->sd_opened = false;
 		sn->sn_dev = sd;
 		sd = NULL;
 	} else {
@@ -518,6 +519,7 @@ spec_open(void *v)
 	spec_ioctl_t ioctl;
 	u_int gen;
 	const char *name;
+	bool needclose = false;
 	struct partinfo pi;
 	
 	l = curlwp;
@@ -688,12 +690,9 @@ spec_open(void *v)
 	 * must fail with EBADF.
 	 *
 	 * Otherwise, if opening it failed, back out and release the
-	 * open reference.
-	 *
-	 * XXX This is wrong -- we might release the last open
-	 * reference here, but we don't close the device.  If only this
-	 * thread's call to open failed, that's fine, but we might
-	 * have:
+	 * open reference.  If it was ever successfully opened and we
+	 * got the last reference this way, it's now our job to close
+	 * it.  This might happen in the following scenario:
 	 *
 	 *	Thread 1		Thread 2
 	 *	VOP_OPEN
@@ -710,21 +709,54 @@ spec_open(void *v)
 	 *	  release vnode lock
 	 *  acquire vnode lock
 	 *  --sd_opencnt == 0
-	 *  but no .d_close (***)
+	 *
+	 * We can't resolve this by making spec_close wait for .d_open
+	 * to complete before examining sd_opencnt, because .d_open can
+	 * hang indefinitely, e.g. for a tty.
 	 */
 	mutex_enter(_lock);
 	if (sn->sn_gone) {
 		if (error == 0)
 			error = EBADF;
-	} else if (error != 0) {
+	} else if (error == 0) {
+		sd->sd_opened = true;
+	} else if (sd->sd_opencnt == 1 && sd->sd_opened) {
+		/*
+		 * We're the last reference to a _previous_ open even
+		 * though this one failed, so we have to close it.
+		 * Don't decrement the reference count here --
+		 * spec_close will do that.
+		 */
+		KASSERT(sn->sn_opencnt == 1);
+		needclose = true;
+	} else {
 		sd->sd_opencnt--;
 		sn->sn_opencnt--;
 		if (vp->v_type == VBLK)
 			sd->sd_bdevvp = NULL;
-
 	}
 	mutex_exit(_lock);
 
+	/*
+	 * If this open failed, but the device was previously opened,
+	 * and another thread concurrently closed the vnode while we
+	 * were in the middle of reopening it, the other thread will
+	 * see sd_opencnt > 0 and thus decide not to call .d_close --
+	 * it is now our responsibility to do so.
+	 *
+	 * XXX The flags passed to VOP_CLOSE here are wrong, but
+	 * drivers can't rely on FREAD|FWRITE anyway -- e.g., consider
+	 * a device opened by thread 0 with O_READ, then opened by
+	 * thread 1 with O_WRITE, then closed by thread 0, and finally
+	 * closed by thread 1; the last .d_close call will have FWRITE
+	 * but not FREAD.  We should just eliminate the FREAD/FWRITE
+	 * parameter to .d_close altogether.
+	 */
+	if (needclose) {
+		KASSERT(error);
+		VOP_CLOSE(vp, FNONBLOCK, NOCRED);
+	}
+
 	/* If anything went wrong, we're done.  */
 	if (error)
 		return error;
@@ -1341,6 +1373,25 @@ spec_close(void *v)
 	 * device.  For block devices, the open reference count must be
 	 * 1 at this point.  If the device's open reference count goes
 	 * to zero, we're the last one out so get the lights.
+	 *
+	 * We may find --sd->sd_opencnt gives zero, and yet
+	 * sd->sd_opened is false.  This happens if the vnode is
+	 * revoked at the same time as it is being opened, which can
+	 * happen when opening a tty blocks indefinitely.  In that
+	 * case, we still must call close -- it is the job of close to
+	 * interrupt the open.  Either way, the device will be no
+	 * longer opened, so we have to clear sd->sd_opened; subsequent
+	 * opens will have responsibility for issuing close.
+	 *
+	 * This has the side effect that the sequence of opens might
+	 * happen out of order -- we might end up doing open, open,
+	 * close, close, instead of open, close, open, close.  This is
+	 * unavoidable with the current devsw API, where open is
+	 

  1   2   >