Page MenuHomeFreeBSD

D54634.id169446.diff
No OneTemporary

D54634.id169446.diff

diff --git a/sys/dev/speaker/spkr.c b/sys/dev/speaker/spkr.c
--- a/sys/dev/speaker/spkr.c
+++ b/sys/dev/speaker/spkr.c
@@ -14,6 +14,7 @@
#include <sys/conf.h>
#include <sys/ctype.h>
#include <sys/malloc.h>
+#include <sys/sx.h>
#include <machine/clock.h>
#include <dev/speaker/speaker.h>
@@ -24,7 +25,6 @@
static struct cdevsw spkr_cdevsw = {
.d_version = D_VERSION,
- .d_flags = D_NEEDGIANT,
.d_open = spkropen,
.d_close = spkrclose,
.d_write = spkrwrite,
@@ -392,51 +392,58 @@
static bool spkr_active = false; /* exclusion flag */
static char *spkr_inbuf; /* incoming buf */
+static struct sx spkr_lock;
static int
spkropen(struct cdev *dev, int flags, int fmt, struct thread *td)
{
+ int error;
+
#ifdef DEBUG
(void) printf("spkropen: entering with dev = %s\n", devtoname(dev));
#endif /* DEBUG */
- if (spkr_active)
- return(EBUSY);
- else {
+ error = 0;
+ sx_xlock(&spkr_lock);
+ if (spkr_active) {
+ error = EBUSY;
+ } else {
#ifdef DEBUG
(void) printf("spkropen: about to perform play initialization\n");
#endif /* DEBUG */
playinit();
spkr_inbuf = malloc(DEV_BSIZE, M_SPKR, M_WAITOK);
spkr_active = true;
- return(0);
- }
+ }
+ sx_xunlock(&spkr_lock);
+ return (error);
}
static int
spkrwrite(struct cdev *dev, struct uio *uio, int ioflag)
{
+ unsigned n;
+ char *cp;
+ int error;
+
#ifdef DEBUG
printf("spkrwrite: entering with dev = %s, count = %zd\n",
devtoname(dev), uio->uio_resid);
#endif /* DEBUG */
if (uio->uio_resid > (DEV_BSIZE - 1)) /* prevent system crashes */
- return(E2BIG);
- else {
- unsigned n;
- char *cp;
- int error;
-
- n = uio->uio_resid;
- cp = spkr_inbuf;
- error = uiomove(cp, n, uio);
- if (!error) {
- cp[n] = '\0';
- playstring(cp, n);
- }
- return(error);
+ return(E2BIG);
+
+ sx_xlock(&spkr_lock);
+ n = uio->uio_resid;
+ cp = spkr_inbuf;
+ error = uiomove(cp, n, uio);
+ if (!error) {
+ cp[n] = '\0';
+ playstring(cp, n);
}
+ sx_xunlock(&spkr_lock);
+ return (error);
}
static int
@@ -446,10 +453,12 @@
(void) printf("spkrclose: entering with dev = %s\n", devtoname(dev));
#endif /* DEBUG */
+ sx_xlock(&spkr_lock);
wakeup(&endtone);
wakeup(&endrest);
free(spkr_inbuf, M_SPKR);
spkr_active = false;
+ sx_xunlock(&spkr_lock);
return(0);
}
@@ -457,28 +466,30 @@
spkrioctl(struct cdev *dev, unsigned long cmd, caddr_t cmdarg, int flags,
struct thread *td)
{
+ tone_t *tp, ttp;
+ int error;
+
#ifdef DEBUG
(void) printf("spkrioctl: entering with dev = %s, cmd = %lx\n",
devtoname(dev), cmd);
#endif /* DEBUG */
+ error = 0;
+ sx_xlock(&spkr_lock);
if (cmd == SPKRTONE) {
- tone_t *tp = (tone_t *)cmdarg;
+ tp = (tone_t *)cmdarg;
if (tp->frequency == 0)
rest(tp->duration);
else
tone(tp->frequency, tp->duration);
- return 0;
} else if (cmd == SPKRTUNE) {
- tone_t *tp = (tone_t *)(*(caddr_t *)cmdarg);
- tone_t ttp;
- int error;
+ tp = (tone_t *)(*(caddr_t *)cmdarg);
for (; ; tp++) {
error = copyin(tp, &ttp, sizeof(tone_t));
if (error)
- return(error);
+ break;
if (ttp.duration == 0)
break;
@@ -488,9 +499,11 @@
else
tone(ttp.frequency, ttp.duration);
}
- return(0);
+ } else {
+ error = EINVAL;
}
- return(EINVAL);
+ sx_xunlock(&spkr_lock);
+ return (error);
}
static struct cdev *speaker_dev;
@@ -504,13 +517,15 @@
int error = 0;
switch(type) {
- case MOD_LOAD:
+ case MOD_LOAD:
+ sx_init(&spkr_lock, "speaker");
speaker_dev = make_dev(&spkr_cdevsw, 0,
UID_ROOT, GID_WHEEL, 0600, "speaker");
break;
case MOD_SHUTDOWN:
case MOD_UNLOAD:
destroy_dev(speaker_dev);
+ sx_destroy(&spkr_lock);
break;
default:
error = EOPNOTSUPP;
diff --git a/sys/x86/isa/clock.c b/sys/x86/isa/clock.c
--- a/sys/x86/isa/clock.c
+++ b/sys/x86/isa/clock.c
@@ -163,8 +163,11 @@
mode = TIMER_SEL2 | TIMER_SQWAVE | TIMER_16BIT;
- if (timer2_state != RELEASED)
+ mtx_lock_spin(&clock_lock);
+ if (timer2_state != RELEASED) {
+ mtx_unlock_spin(&clock_lock);
return (-1);
+ }
timer2_state = ACQUIRED;
/*
@@ -175,6 +178,7 @@
* careful with it as with timer0.
*/
outb(TIMER_MODE, TIMER_SEL2 | (mode & 0x3f));
+ mtx_unlock_spin(&clock_lock);
ppi_spkr_on(); /* enable counter2 output to speaker */
return (0);
@@ -184,10 +188,14 @@
timer_spkr_release(void)
{
- if (timer2_state != ACQUIRED)
+ mtx_lock_spin(&clock_lock);
+ if (timer2_state != ACQUIRED) {
+ mtx_unlock_spin(&clock_lock);
return (-1);
+ }
timer2_state = RELEASED;
outb(TIMER_MODE, TIMER_SEL2 | TIMER_SQWAVE | TIMER_16BIT);
+ mtx_unlock_spin(&clock_lock);
ppi_spkr_off(); /* disable counter2 output to speaker */
return (0);

File Metadata

Mime Type
text/plain
Expires
Wed, Apr 8, 9:23 PM (1 h, 36 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
31115980
Default Alt Text
D54634.id169446.diff (4 KB)

Event Timeline