Module Name:    src
Committed By:   pgoyette
Date:           Fri Jan  6 09:32:08 UTC 2017

Modified Files:
        src/sys/dev: spkr.c spkr_audio.c spkrvar.h
        src/sys/dev/isa: spkr_pcppi.c

Log Message:
Implement a common spkr_detach() function and call it from the
attachment-specific detach functions.  Returns EBUSY if the
device instance is busy, based on whether or not a sc->sc_inbuf
is allocated.  The buffer is malloc()d at spkropen time, and is
free()d in spkrclose().

Now we can actually implement the MODULE_CMD_FINI command and
unload the driver at will.

Addresses my PR kern/51785


To generate a diff of this commit:
cvs rdiff -u -r1.5 -r1.6 src/sys/dev/spkr.c src/sys/dev/spkrvar.h
cvs rdiff -u -r1.2 -r1.3 src/sys/dev/spkr_audio.c
cvs rdiff -u -r1.8 -r1.9 src/sys/dev/isa/spkr_pcppi.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/spkr.c
diff -u src/sys/dev/spkr.c:1.5 src/sys/dev/spkr.c:1.6
--- src/sys/dev/spkr.c:1.5	Thu Dec 15 06:55:55 2016
+++ src/sys/dev/spkr.c	Fri Jan  6 09:32:08 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: spkr.c,v 1.5 2016/12/15 06:55:55 pgoyette Exp $	*/
+/*	$NetBSD: spkr.c,v 1.6 2017/01/06 09:32:08 pgoyette Exp $	*/
 
 /*
  * Copyright (c) 1990 Eric S. Raymond (e...@snark.thyrsus.com)
@@ -43,7 +43,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: spkr.c,v 1.5 2016/12/15 06:55:55 pgoyette Exp $");
+__KERNEL_RCSID(0, "$NetBSD: spkr.c,v 1.6 2017/01/06 09:32:08 pgoyette Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -358,6 +358,9 @@ spkr_attach(device_t self, void (*tone)(
 {
 	struct spkr_softc *sc = device_private(self);
 
+#ifdef SPKRDEBUG
+	aprint_debug("%s: entering for unit %d\n", __func__, self->dv_unit);
+#endif /* SPKRDEBUG */
 	sc->sc_dev = self;
 	sc->sc_tone = tone;
 	sc->sc_rest = rest;
@@ -365,6 +368,22 @@ spkr_attach(device_t self, void (*tone)(
 }
 
 int
+spkr_detach(device_t self, int flags)
+{
+	struct spkr_softc *sc = device_private(self);
+
+#ifdef SPKRDEBUG
+	aprint_debug("%s: entering for unit %d\n", __func__, self->dv_unit);
+#endif /* SPKRDEBUG */
+	if (sc == NULL)
+		return ENXIO;
+	if (sc->sc_inbuf != NULL)
+		return EBUSY;
+
+	return 0;
+}
+
+int
 spkropen(dev_t dev, int	flags, int mode, struct lwp *l)
 {
 #ifdef SPKRDEBUG
@@ -374,7 +393,7 @@ spkropen(dev_t dev, int	flags, int mode,
 
 	if (sc == NULL)
 		return ENXIO;
-	if (sc->sc_inbuf)
+	if (sc->sc_inbuf != NULL)
 		return EBUSY;
 
 	sc->sc_inbuf = malloc(DEV_BSIZE, M_DEVBUF, M_WAITOK);
@@ -393,7 +412,7 @@ spkrwrite(dev_t dev, struct uio *uio, in
 
 	if (sc == NULL)
 		return ENXIO;
-	if (!sc->sc_inbuf)
+	if (sc->sc_inbuf == NULL)
 		return EINVAL;
 
 	size_t n = min(DEV_BSIZE, uio->uio_resid);
@@ -414,7 +433,7 @@ spkrclose(dev_t dev, int flags, int mode
 
 	if (sc == NULL)
 		return ENXIO;
-	if (!sc->sc_inbuf)
+	if (sc->sc_inbuf == NULL)
 		return EINVAL;
 
 	sc->sc_tone(sc->sc_dev, 0, 0);
@@ -448,7 +467,7 @@ spkrioctl(dev_t dev, u_long cmd, void *d
 
 	if (sc == NULL)
 		return ENXIO;
-	if (!sc->sc_inbuf)
+	if (sc->sc_inbuf == NULL)
 		return EINVAL;
 
 	switch (cmd) {
@@ -493,20 +512,21 @@ spkr_modcmd(modcmd_t cmd, void *arg)
 			break;
 
 		error = config_init_component(cfdriver_ioconf_spkr,
-			cfattach_ioconf_spkr, cfdata_ioconf_spkr);
+		    cfattach_ioconf_spkr, cfdata_ioconf_spkr);
 		if (error) {
 			devsw_detach(NULL, &spkr_cdevsw);
 		}
 		break;
 
 	case MODULE_CMD_FINI:
-		return EBUSY;
-#ifdef notyet
-		error = config_fini_component(cfdriver_ioconf_spkr,
-			cfattach_ioconf_spkr, cfdata_ioconf_spkr);
 		devsw_detach(NULL, &spkr_cdevsw);
+		error = config_fini_component(cfdriver_ioconf_spkr,
+		    cfattach_ioconf_spkr, cfdata_ioconf_spkr);
+		if (error)
+			devsw_attach(spkr_cd.cd_name, NULL, &bmajor,
+			    &spkr_cdevsw, &cmajor);
 		break;
-#endif
+
 	default:
 		error = ENOTTY;
 		break;
Index: src/sys/dev/spkrvar.h
diff -u src/sys/dev/spkrvar.h:1.5 src/sys/dev/spkrvar.h:1.6
--- src/sys/dev/spkrvar.h:1.5	Thu Dec 15 06:48:14 2016
+++ src/sys/dev/spkrvar.h	Fri Jan  6 09:32:08 2017
@@ -1,4 +1,4 @@
-/* $NetBSD: spkrvar.h,v 1.5 2016/12/15 06:48:14 pgoyette Exp $ */
+/* $NetBSD: spkrvar.h,v 1.6 2017/01/06 09:32:08 pgoyette Exp $ */
 
 #ifndef _SYS_DEV_SPKRVAR_H
 #define _SYS_DEV_SPKRVAR_H
@@ -23,4 +23,6 @@ struct spkr_softc {
 void spkr_attach(device_t,
     void (*)(device_t, u_int, u_int), void (*)(device_t, int));
 
+int spkr_detach(device_t, int);
+
 #endif /* _SYS_DEV_SPKRVAR_H */

Index: src/sys/dev/spkr_audio.c
diff -u src/sys/dev/spkr_audio.c:1.2 src/sys/dev/spkr_audio.c:1.3
--- src/sys/dev/spkr_audio.c:1.2	Thu Dec 15 06:48:14 2016
+++ src/sys/dev/spkr_audio.c	Fri Jan  6 09:32:08 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: spkr_audio.c,v 1.2 2016/12/15 06:48:14 pgoyette Exp $	*/
+/*	$NetBSD: spkr_audio.c,v 1.3 2017/01/06 09:32:08 pgoyette Exp $	*/
 
 /*-
  * Copyright (c) 2016 Nathanial Sloss <nathanialsl...@yahoo.com.au>
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: spkr_audio.c,v 1.2 2016/12/15 06:48:14 pgoyette Exp $");
+__KERNEL_RCSID(0, "$NetBSD: spkr_audio.c,v 1.3 2017/01/06 09:32:08 pgoyette Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -148,6 +148,10 @@ static int
 spkr_audio_detach(device_t self, int flags)
 {
 	struct spkr_audio_softc *sc = device_private(self);
+	int error;
+
+	if ((error = spkr_detach(self, flags)) != 0)
+		return error;
 
 	pmf_device_deregister(self);
 
@@ -161,7 +165,6 @@ spkr_audio_detach(device_t self, int fla
 	cv_destroy(&sc->sc_bellcv);
 	mutex_destroy(&sc->sc_bellock);
 
-
 	return 0;
 }
 

Index: src/sys/dev/isa/spkr_pcppi.c
diff -u src/sys/dev/isa/spkr_pcppi.c:1.8 src/sys/dev/isa/spkr_pcppi.c:1.9
--- src/sys/dev/isa/spkr_pcppi.c:1.8	Thu Dec 15 06:48:14 2016
+++ src/sys/dev/isa/spkr_pcppi.c	Fri Jan  6 09:32:08 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: spkr_pcppi.c,v 1.8 2016/12/15 06:48:14 pgoyette Exp $	*/
+/*	$NetBSD: spkr_pcppi.c,v 1.9 2017/01/06 09:32:08 pgoyette Exp $	*/
 
 /*
  * Copyright (c) 1990 Eric S. Raymond (e...@snark.thyrsus.com)
@@ -43,7 +43,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: spkr_pcppi.c,v 1.8 2016/12/15 06:48:14 pgoyette Exp $");
+__KERNEL_RCSID(0, "$NetBSD: spkr_pcppi.c,v 1.9 2017/01/06 09:32:08 pgoyette Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -129,6 +129,10 @@ static int
 spkr_pcppi_detach(device_t self, int flags)
 {
 	struct spkr_pcppi_softc *sc = device_private(self);
+	int error;
+
+	if ((error = spkr_detach(self, flags)) != 0)
+		return error;
 
 	sc->sc_pcppicookie = NULL;
 	pmf_device_deregister(self);

Reply via email to