NetBSD-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

port-mac68k/60694: mac68k: obio(4) has no rescan callback, so obio drivers cannot be modules



>Number:         60694
>Category:       port-mac68k
>Synopsis:       mac68k: obio(4) has no rescan callback, so obio drivers cannot be modules
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    port-mac68k-maintainer
>State:          open
>Class:          change-request
>Submitter-Id:   net
>Arrival-Date:   Tue Sep 08 10:30:01 +0000 2026
>Originator:     Ray Tran
>Release:        11.0
>Organization:
Diamond Creek Digital
>Environment:
Hardware: Apple Macintosh Centris 650 (68040 at 25 MHz, 68 MB RAM, 512 KB
VRAM, DAFB internal video on an Apple 14" Color Display, SONIC ethernet, internal SCSI disk), running NetBSD 11.0 with a kernel
built from the 11.0 sources plus this series.  Kernel identification of
the current build (uname -v):

NetBSD 11.0 (Q650WSMUX) #22: Mon Sep  7 10:03:36 UTC 2026
>Description:
obio, the bus every on-board mac68k device hangs off, has no rescan
callback.  "drvctl -r obio0" answers "Operation not supported by
device", and a driver for an obio child that is loaded with modload(8)
after autoconfiguration has finished appears in modstat(8) and simply
never attaches to anything.  The only way to get an obio driver into a
running kernel is to build it in, which on a 25 MHz 68040 means a kernel
rebuild and a reboot per iteration instead of a 40-second module reload.

This adds the rescan.  The bus tags are kept in an obio softc because
obio_rescan() has no aux argument to take them from; obio_attach() saves
them from the mainbus_attach_args it already receives, and the rescan
offers the same attach args to config_search() that attach did.

config_search_internal() skips cfdata already in FSTATE_FOUND, so an
attached device is not offered twice.  A wildcard entry ("foo* at obio?")
is FSTATE_STAR and IS offered again on every rescan, so an obio driver
whose match function does not inspect real hardware must refuse a second
instance itself - obio_match() already guards itself that way and is the
pattern to copy.
>How-To-Repeat:
Build any obio child driver as a module, boot a kernel without it,
modload it, and run "drvctl -r obio0".  Before: EOPNOTSUPP, and the
device never appears.  After: it attaches.
>Fix:
Applies to sys/arch/mac68k/obio/obio.c.  Found while developing an
out-of-tree SWIM floppy driver, and used since for the out-of-tree
display drivers this port's development relies on, all loaded by
modload(8) on a Centris 650 running NetBSD 11.0.  The same patch applies
to -current (11.99.8) and the resulting kernel boots under qemu -M q800.


Applies with "patch -p1" from the top of usr/src; verified with -F0
(no fuzz) against NetBSD-current 11.99.8 (20260830003849Z) and 11.0.

--- a/sys/arch/mac68k/obio/obio.c
+++ b/sys/arch/mac68k/obio/obio.c
@@ -46,9 +46,19 @@
 static void	obio_attach(device_t, device_t, void *);
 static int	obio_print(void *, const char *);
 static int	obio_search(device_t, cfdata_t, const int *, void *);
+static int	obio_rescan(device_t, const char *, const int *);
 
-CFATTACH_DECL_NEW(obio, 0,
-    obio_match, obio_attach, NULL, NULL);
+/*
+ * The bus tags are needed again by obio_rescan(), which has no aux
+ * argument to take them from, so keep them.
+ */
+struct obio_softc {
+	bus_space_tag_t	sc_bst;
+	bus_dma_tag_t	sc_dmat;
+};
+
+CFATTACH_DECL3_NEW(obio, sizeof(struct obio_softc),
+    obio_match, obio_attach, NULL, NULL, obio_rescan, NULL, 0);
 
 static int
 obio_match(device_t parent, cfdata_t cf, void *aux)
@@ -66,6 +76,12 @@
 static void
 obio_attach(device_t parent, device_t self, void *aux)
 {
+	struct obio_softc *sc = device_private(self);
+	struct mainbus_attach_args *mba = aux;
+
+	sc->sc_bst = mba->mba_bst;
+	sc->sc_dmat = mba->mba_dmat;
+
 	printf("\n");
 
 	/* Search for and attach children. */
@@ -73,6 +89,37 @@
 	    CFARGS(.search = obio_search));
 }
 
+static int
+obio_rescan(device_t self, const char *ifattr, const int *locators)
+{
+	struct obio_softc *sc = device_private(self);
+	struct mainbus_attach_args mba;
+
+	if (!ifattr_match(ifattr, "obio"))
+		return 0;
+
+	mba.mba_bst = sc->sc_bst;
+	mba.mba_dmat = sc->sc_dmat;
+
+	config_search(self, &mba,
+	    CFARGS(.search = obio_search));
+
+	return 0;
+}
+
 int
 obio_print(void *args, const char *name)
 {




Home | Main Index | Thread Index | Old Index