diff options
| author | pgoyette <pgoyette@NetBSD.org> | 2017-01-06 09:32:08 +0000 |
|---|---|---|
| committer | pgoyette <pgoyette@NetBSD.org> | 2017-01-06 09:32:08 +0000 |
| commit | bccce848e50e23364a2bd85bcf5c4e447ac1fc27 (patch) | |
| tree | 32ff9dd9f043b0b8faa4150f1109c44147a35d8d /sys/dev | |
| parent | 9dda8d65f690864a32d372f5c13a0ef115661ad1 (diff) | |
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
Diffstat (limited to 'sys/dev')
| -rw-r--r-- | sys/dev/isa/spkr_pcppi.c | 8 | ||||
| -rw-r--r-- | sys/dev/spkr.c | 44 | ||||
| -rw-r--r-- | sys/dev/spkr_audio.c | 9 | ||||
| -rw-r--r-- | sys/dev/spkrvar.h | 4 |
4 files changed, 47 insertions, 18 deletions
diff --git a/sys/dev/isa/spkr_pcppi.c b/sys/dev/isa/spkr_pcppi.c index 27322f351bd..39e3c3ed8b3 100644 --- a/sys/dev/isa/spkr_pcppi.c +++ b/sys/dev/isa/spkr_pcppi.c @@ -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 (esr@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); diff --git a/sys/dev/spkr.c b/sys/dev/spkr.c index 5a1b7dc647c..bed93eaea0e 100644 --- a/sys/dev/spkr.c +++ b/sys/dev/spkr.c @@ -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 (esr@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)(device_t, u_int, u_int), { 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)(device_t, u_int, u_int), } 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, struct lwp *l) 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, int flags) 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, struct lwp *l) 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 *data, int flag, struct lwp *l) 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; diff --git a/sys/dev/spkr_audio.c b/sys/dev/spkr_audio.c index 58b7c70ff7c..3266360bbc6 100644 --- a/sys/dev/spkr_audio.c +++ b/sys/dev/spkr_audio.c @@ -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 <nathanialsloss@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 flags) cv_destroy(&sc->sc_bellcv); mutex_destroy(&sc->sc_bellock); - return 0; } diff --git a/sys/dev/spkrvar.h b/sys/dev/spkrvar.h index ae977a47772..7a20bab0cdf 100644 --- a/sys/dev/spkrvar.h +++ b/sys/dev/spkrvar.h @@ -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 */ |
