convert a lockless + spltty() combo to a IPL_VM mutex and cv.
hopefully this will avoid the beep-didn't-stop problem i had recently that i was able to fix by calling wakeup() on pcppi's softc from ddb.
This commit is contained in:
parent
5517207853
commit
dad44dc109
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: pcppi.c,v 1.35 2009/04/17 20:46:37 dyoung Exp $ */
|
||||
/* $NetBSD: pcppi.c,v 1.36 2011/05/03 04:27:13 mrg Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1996 Carnegie-Mellon University.
|
||||
@ -28,7 +28,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: pcppi.c,v 1.35 2009/04/17 20:46:37 dyoung Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: pcppi.c,v 1.36 2011/05/03 04:27:13 mrg Exp $");
|
||||
|
||||
#include "attimer.h"
|
||||
|
||||
@ -39,8 +39,9 @@ __KERNEL_RCSID(0, "$NetBSD: pcppi.c,v 1.35 2009/04/17 20:46:37 dyoung Exp $");
|
||||
#include <sys/proc.h>
|
||||
#include <sys/device.h>
|
||||
#include <sys/errno.h>
|
||||
|
||||
#include <sys/bus.h>
|
||||
#include <sys/mutex.h>
|
||||
#include <sys/condvar.h>
|
||||
|
||||
#include <dev/ic/attimervar.h>
|
||||
|
||||
@ -199,6 +200,10 @@ pcppi_detach(device_t self, int flags)
|
||||
callout_stop(&sc->sc_bell_ch);
|
||||
callout_destroy(&sc->sc_bell_ch);
|
||||
bus_space_unmap(sc->sc_iot, sc->sc_ppi_ioh, sc->sc_size);
|
||||
|
||||
mutex_destroy(&sc->sc_lock);
|
||||
cv_destroy(&sc->sc_stop_cv);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -212,6 +217,9 @@ pcppi_attach(struct pcppi_softc *sc)
|
||||
|
||||
sc->sc_bellactive = sc->sc_bellpitch = sc->sc_slp = 0;
|
||||
|
||||
mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_VM);
|
||||
cv_init(&sc->sc_stop_cv, "bell");
|
||||
|
||||
#if NPCKBD > 0
|
||||
/* Provide a beeper for the PC Keyboard, if there isn't one already. */
|
||||
pckbd_hookup_bell(pcppi_pckbd_bell, sc);
|
||||
@ -266,21 +274,20 @@ void
|
||||
pcppi_bell(pcppi_tag_t self, int pitch, int period, int slp)
|
||||
{
|
||||
struct pcppi_softc *sc = self;
|
||||
int s;
|
||||
|
||||
s = spltty(); /* ??? */
|
||||
mutex_enter(&sc->sc_lock);
|
||||
if (sc->sc_bellactive) {
|
||||
if (sc->sc_timeout) {
|
||||
sc->sc_timeout = 0;
|
||||
callout_stop(&sc->sc_bell_ch);
|
||||
}
|
||||
if (sc->sc_slp)
|
||||
wakeup(pcppi_bell_stop);
|
||||
cv_broadcast(&sc->sc_stop_cv);
|
||||
}
|
||||
if (pitch == 0 || period == 0) {
|
||||
pcppi_bell_stop(sc);
|
||||
sc->sc_bellpitch = 0;
|
||||
splx(s);
|
||||
mutex_exit(&sc->sc_lock);
|
||||
return;
|
||||
}
|
||||
if (!sc->sc_bellactive || sc->sc_bellpitch != pitch) {
|
||||
@ -304,20 +311,19 @@ pcppi_bell(pcppi_tag_t self, int pitch, int period, int slp)
|
||||
callout_reset(&sc->sc_bell_ch, period, pcppi_bell_stop, sc);
|
||||
if (slp & PCPPI_BELL_SLEEP) {
|
||||
sc->sc_slp = 1;
|
||||
tsleep(pcppi_bell_stop, PCPPIPRI | PCATCH, "bell", 0);
|
||||
cv_wait_sig(&sc->sc_stop_cv, &sc->sc_lock);
|
||||
sc->sc_slp = 0;
|
||||
}
|
||||
}
|
||||
splx(s);
|
||||
mutex_exit(&sc->sc_lock);
|
||||
}
|
||||
|
||||
static void
|
||||
pcppi_bell_stop(void *arg)
|
||||
{
|
||||
struct pcppi_softc *sc = arg;
|
||||
int s;
|
||||
|
||||
s = spltty(); /* ??? */
|
||||
mutex_enter(&sc->sc_lock);
|
||||
sc->sc_timeout = 0;
|
||||
|
||||
/* disable bell */
|
||||
@ -326,8 +332,8 @@ pcppi_bell_stop(void *arg)
|
||||
& ~PIT_SPKR);
|
||||
sc->sc_bellactive = 0;
|
||||
if (sc->sc_slp)
|
||||
wakeup(pcppi_bell_stop);
|
||||
splx(s);
|
||||
cv_broadcast(&sc->sc_stop_cv);
|
||||
mutex_exit(&sc->sc_lock);
|
||||
}
|
||||
|
||||
#if NPCKBD > 0
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: pcppivar.h,v 1.9 2008/03/04 16:35:19 cube Exp $ */
|
||||
/* $NetBSD: pcppivar.h,v 1.10 2011/05/03 04:27:13 mrg Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1996 Carnegie-Mellon University.
|
||||
@ -37,18 +37,21 @@ struct pcppi_attach_args {
|
||||
};
|
||||
|
||||
struct pcppi_softc {
|
||||
device_t sc_dv;
|
||||
device_t sc_dv;
|
||||
|
||||
bus_space_tag_t sc_iot;
|
||||
bus_space_handle_t sc_ppi_ioh;
|
||||
bus_size_t sc_size;
|
||||
device_t sc_timer;
|
||||
bus_space_tag_t sc_iot;
|
||||
bus_space_handle_t sc_ppi_ioh;
|
||||
bus_size_t sc_size;
|
||||
device_t sc_timer;
|
||||
|
||||
struct callout sc_bell_ch;
|
||||
struct callout sc_bell_ch;
|
||||
|
||||
int sc_bellactive, sc_bellpitch;
|
||||
int sc_slp;
|
||||
int sc_timeout;
|
||||
int sc_bellactive, sc_bellpitch;
|
||||
int sc_slp;
|
||||
int sc_timeout;
|
||||
|
||||
kmutex_t sc_lock;
|
||||
kcondvar_t sc_stop_cv;
|
||||
};
|
||||
|
||||
void pcppi_attach(struct pcppi_softc *);
|
||||
|
Loading…
Reference in New Issue
Block a user