more spkr rework.diff -r1.5 -r1.6 src/sys/dev/files.audio
(christos)
--- src/sys/dev/files.audio 2016/12/08 11:31:08 1.5
+++ src/sys/dev/files.audio 2016/12/09 04:32:39 1.6
@@ -1,14 +1,14 @@ | @@ -1,14 +1,14 @@ | |||
1 | # $NetBSD: files.audio,v 1.5 2016/12/08 11:31:08 nat Exp $ | 1 | # $NetBSD: files.audio,v 1.6 2016/12/09 04:32:39 christos Exp $ | |
2 | 2 | |||
3 | define audiobus { } | 3 | define audiobus { } | |
4 | define midibus { } | 4 | define midibus { } | |
5 | define midisyn | 5 | define midisyn | |
6 | 6 | |||
7 | # audio device attributes | 7 | # audio device attributes | |
8 | # | 8 | # | |
9 | define mulaw: auconv | 9 | define mulaw: auconv | |
10 | define auconv | 10 | define auconv | |
11 | define aurateconv | 11 | define aurateconv | |
12 | define auvolconv | 12 | define auvolconv | |
13 | 13 | |||
14 | # audio and midi devices, attaches to audio hardware driver | 14 | # audio and midi devices, attaches to audio hardware driver | |
@@ -23,14 +23,15 @@ attach spkr at audio with spkr_synth | @@ -23,14 +23,15 @@ attach spkr at audio with spkr_synth | |||
23 | # console bell via audio device | 23 | # console bell via audio device | |
24 | # | 24 | # | |
25 | define audiobell | 25 | define audiobell | |
26 | 26 | |||
27 | file dev/auconv.c auconv | 27 | file dev/auconv.c auconv | |
28 | file dev/audio.c audio needs-flag | 28 | file dev/audio.c audio needs-flag | |
29 | file dev/audiobell.c audiobell & vaudiospeaker needs-flag | 29 | file dev/audiobell.c audiobell & vaudiospeaker needs-flag | |
30 | file dev/aurateconv.c aurateconv needs-flag | 30 | file dev/aurateconv.c aurateconv needs-flag | |
31 | file dev/auvolconv.c auvolconv | 31 | file dev/auvolconv.c auvolconv | |
32 | file dev/midi.c midi needs-flag | 32 | file dev/midi.c midi needs-flag | |
33 | file dev/midictl.c midisyn | 33 | file dev/midictl.c midisyn | |
34 | file dev/midisyn.c midisyn | 34 | file dev/midisyn.c midisyn | |
35 | file dev/mulaw.c mulaw needs-flag | 35 | file dev/mulaw.c mulaw needs-flag | |
36 | file dev/spkr_synth.c spkr & vaudiospeaker needs-flag | 36 | file dev/spkr.c spkr needs-flag | |
37 | file dev/spkr_synth.c spkr_synth needs-flag |
/* $NetBSD: spkr.c,v 1.1 2016/12/09 04:32:39 christos Exp $ */
/*
* Copyright (c) 1990 Eric S. Raymond (esr@snark.thyrsus.com)
* Copyright (c) 1990 Andrew A. Chernov (ache@astral.msk.su)
* Copyright (c) 1990 Lennart Augustsson (lennart@augustsson.net)
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Eric S. Raymond
* 4. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/*
* spkr.c -- device driver for console speaker on 80386
*
* v1.1 by Eric S. Raymond (esr@snark.thyrsus.com) Feb 1990
* modified for 386bsd by Andrew A. Chernov <ache@astral.msk.su>
* 386bsd only clean version, all SYSV stuff removed
* use hz value from param.c
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: spkr.c,v 1.1 2016/12/09 04:32:39 christos Exp $");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/errno.h>
#include <sys/device.h>
#include <sys/malloc.h>
#include <sys/module.h>
#include <sys/uio.h>
#include <sys/proc.h>
#include <sys/ioctl.h>
#include <sys/conf.h>
#include <sys/bus.h>
#include <dev/spkrio.h>
dev_type_open(spkropen);
dev_type_close(spkrclose);
dev_type_write(spkrwrite);
dev_type_ioctl(spkrioctl);
const struct cdevsw spkr_cdevsw = {
.d_open = spkropen,
.d_close = spkrclose,
.d_read = noread,
.d_write = spkrwrite,
.d_ioctl = spkrioctl,
.d_stop = nostop,
.d_tty = notty,
.d_poll = nopoll,
.d_mmap = nommap,
.d_kqfilter = nokqfilter,
.d_discard = nodiscard,
.d_flag = D_OTHER
};
static void playinit(void);
static void playtone(int, int, int);
static void playstring(char *, int);
/**************** PLAY STRING INTERPRETER BEGINS HERE **********************
*
* Play string interpretation is modelled on IBM BASIC 2.0's PLAY statement;
* M[LNS] are missing and the ~ synonym and octave-tracking facility is added.
* Requires spkr_tone(), spkr_rest(). String play is not interruptible
* except possibly at physical block boundaries.
*/
#define dtoi(c) ((c) - '0')
static int octave; /* currently selected octave */
static int whole; /* whole-note time at current tempo, in ticks */
static int value; /* whole divisor for note time, quarter note = 1 */
static int fill; /* controls spacing of notes */
static bool octtrack; /* octave-tracking on? */
static bool octprefix; /* override current octave-tracking state? */
/*
* Magic number avoidance...
*/
#define SECS_PER_MIN 60 /* seconds per minute */
#define WHOLE_NOTE 4 /* quarter notes per whole note */
#define MIN_VALUE 64 /* the most we can divide a note by */
#define DFLT_VALUE 4 /* default value (quarter-note) */
#define FILLTIME 8 /* for articulation, break note in parts */
#define STACCATO 6 /* 6/8 = 3/4 of note is filled */
#define NORMAL 7 /* 7/8ths of note interval is filled */
#define LEGATO 8 /* all of note interval is filled */
#define DFLT_OCTAVE 4 /* default octave */
#define MIN_TEMPO 32 /* minimum tempo */
#define DFLT_TEMPO 120 /* default tempo */
#define MAX_TEMPO 255 /* max tempo */
#define NUM_MULT 3 /* numerator of dot multiplier */
#define DENOM_MULT 2 /* denominator of dot multiplier */
/* letter to half-tone: A B C D E F G */
static const int notetab[8] = {9, 11, 0, 2, 4, 5, 7};
/*
* This is the American Standard A440 Equal-Tempered scale with frequencies
* rounded to nearest integer. Thank Goddess for the good ol' CRC Handbook...
* our octave 0 is standard octave 2.
*/
#define OCTAVE_NOTES 12 /* semitones per octave */
static const int pitchtab[] =
{
/* C C# D D# E F F# G G# A A# B*/
/* 0 */ 65, 69, 73, 78, 82, 87, 93, 98, 103, 110, 117, 123,
/* 1 */ 131, 139, 147, 156, 165, 175, 185, 196, 208, 220, 233, 247,
/* 2 */ 262, 277, 294, 311, 330, 349, 370, 392, 415, 440, 466, 494,
/* 3 */ 523, 554, 587, 622, 659, 698, 740, 784, 831, 880, 932, 988,
/* 4 */ 1047, 1109, 1175, 1245, 1319, 1397, 1480, 1568, 1661, 1760, 1865, 1975,
/* 5 */ 2093, 2217, 2349, 2489, 2637, 2794, 2960, 3136, 3322, 3520, 3729, 3951,
/* 6 */ 4186, 4435, 4698, 4978, 5274, 5588, 5920, 6272, 6644, 7040, 7459, 7902,
};
#define NOCTAVES (int)(__arraycount(pitchtab) / OCTAVE_NOTES)
static void
playinit(void)
{
octave = DFLT_OCTAVE;
whole = (hz * SECS_PER_MIN * WHOLE_NOTE) / DFLT_TEMPO;
fill = NORMAL;
value = DFLT_VALUE;
octtrack = false;
octprefix = true; /* act as though there was an initial O(n) */
}
static void
playtone(int pitch, int val, int sustain)
/* play tone of proper duration for current rhythm signature */
{
int sound, silence, snum = 1, sdenom = 1;
/* this weirdness avoids floating-point arithmetic */
for (; sustain; sustain--)
{
snum *= NUM_MULT;
sdenom *= DENOM_MULT;
}
if (pitch == -1)
spkr_rest(whole * snum / (val * sdenom));
else
{
sound = (whole * snum) / (val * sdenom)
- (whole * (FILLTIME - fill)) / (val * FILLTIME);
silence = whole * (FILLTIME-fill) * snum / (FILLTIME * val * sdenom);
#ifdef SPKRDEBUG
printf("playtone: pitch %d for %d ticks, rest for %d ticks\n",
pitch, sound, silence);
#endif /* SPKRDEBUG */
spkr_tone(pitchtab[pitch], sound);
if (fill != LEGATO)
spkr_rest(silence);
}
}
static void
playstring(char *cp, int slen)
/* interpret and play an item from a notation string */
{
int pitch, lastpitch = OCTAVE_NOTES * DFLT_OCTAVE;
#define GETNUM(cp, v) for(v=0; slen > 0 && isdigit(cp[1]); ) \
{v = v * 10 + (*++cp - '0'); slen--;}
for (; slen--; cp++)
{
int sustain, timeval, tempo;
char c = toupper(*cp);
#ifdef SPKRDEBUG
printf("playstring: %c (%x)\n", c, c);
#endif /* SPKRDEBUG */
switch (c)
{
case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': case 'G':
/* compute pitch */
pitch = notetab[c - 'A'] + octave * OCTAVE_NOTES;
/* this may be followed by an accidental sign */
if (slen > 0 && (cp[1] == '#' || cp[1] == '+'))
{
++pitch;
++cp;
slen--;
}
else if (slen > 0 && cp[1] == '-')
{
--pitch;
++cp;
slen--;
}
/*
* If octave-tracking mode is on, and there has been no octave-
* setting prefix, find the version of the current letter note
* closest to the last regardless of octave.
*/
if (octtrack && !octprefix)
{
if (abs(pitch-lastpitch) > abs(pitch+OCTAVE_NOTES-lastpitch))
{
if (octave < NOCTAVES - 1) {
++octave;
pitch += OCTAVE_NOTES;
}
}
if (abs(pitch-lastpitch) > abs((pitch-OCTAVE_NOTES)-lastpitch))
{
if (octave > 0) {
--octave;
pitch -= OCTAVE_NOTES;
}
}
}
octprefix = false;
lastpitch = pitch;
/* ...which may in turn be followed by an override time value */
GETNUM(cp, timeval);
if (timeval <= 0 || timeval > MIN_VALUE)
timeval = value;
/* ...and/or sustain dots */
for (sustain = 0; slen > 0 && cp[1] == '.'; cp++)
{
slen--;
sustain++;
}
/* time to emit the actual tone */
playtone(pitch, timeval, sustain);
break;
case 'O':
if (slen > 0 && (cp[1] == 'N' || cp[1] == 'n'))
{
octprefix = octtrack = false;
++cp;
slen--;
}
else if (slen > 0 && (cp[1] == 'L' || cp[1] == 'l'))
{
octtrack = true;
++cp;
slen--;
}
else
{
GETNUM(cp, octave);
if (octave >= NOCTAVES)
octave = DFLT_OCTAVE;
octprefix = true;
}
break;
case '>':
if (octave < NOCTAVES - 1)
octave++;
octprefix = true;
break;
case '<':
if (octave > 0)
octave--;
octprefix = true;
break;
case 'N':
GETNUM(cp, pitch);
for (sustain = 0; slen > 0 && cp[1] == '.'; cp++)
{
slen--;
sustain++;
}
playtone(pitch - 1, value, sustain);
break;
case 'L':
GETNUM(cp, value);
if (value <= 0 || value > MIN_VALUE)
value = DFLT_VALUE;
break;
case 'P':
case '~':
/* this may be followed by an override time value */
GETNUM(cp, timeval);
if (timeval <= 0 || timeval > MIN_VALUE)
timeval = value;
for (sustain = 0; slen > 0 && cp[1] == '.'; cp++)
{
slen--;
sustain++;
}
playtone(-1, timeval, sustain);
break;
case 'T':
GETNUM(cp, tempo);
if (tempo < MIN_TEMPO || tempo > MAX_TEMPO)
tempo = DFLT_TEMPO;
whole = (hz * SECS_PER_MIN * WHOLE_NOTE) / tempo;
break;
case 'M':
if (slen > 0 && (cp[1] == 'N' || cp[1] == 'n'))
{
fill = NORMAL;
++cp;
slen--;
}
else if (slen > 0 && (cp[1] == 'L' || cp[1] == 'l'))
{
fill = LEGATO;
++cp;
slen--;
}
else if (slen > 0 && (cp[1] == 'S' || cp[1] == 's'))
{
fill = STACCATO;
++cp;
slen--;
}
break;
}
}
}
/******************* UNIX DRIVER HOOKS BEGIN HERE **************************
*
* This section implements driver hooks to run playstring() and the spkr_tone()
* and spkr_rest() functions defined above.
*/
static int spkr_active; /* exclusion flag */
int spkr_attached;
static void *spkr_inbuf;
int
spkr_probe(device_t parent, cfdata_t match, void *aux)
{
return (!spkr_attached);
}
int
spkropen(dev_t dev, int flags, int mode, struct lwp *l)
{
#ifdef SPKRDEBUG
printf("spkropen: entering with dev = %"PRIx64"\n", dev);
#endif /* SPKRDEBUG */
if (minor(dev) != 0 || !spkr_attached)
return(ENXIO);
else if (spkr_active)
return(EBUSY);
else
{
playinit();
spkr_inbuf = malloc(DEV_BSIZE, M_DEVBUF, M_WAITOK);
spkr_active = 1;
}
return(0);
}
int
spkrwrite(dev_t dev, struct uio *uio, int flags)
{
int n;
int error;
#ifdef SPKRDEBUG
printf("spkrwrite: entering with dev = %"PRIx64", count = %zu\n",
dev, uio->uio_resid);
#endif /* SPKRDEBUG */
if (minor(dev) != 0)
return(ENXIO);
else
{
n = min(DEV_BSIZE, uio->uio_resid);
error = uiomove(spkr_inbuf, n, uio);
if (!error)
playstring((char *)spkr_inbuf, n);
return(error);
}
}
int
spkrclose(dev_t dev, int flags, int mode, struct lwp *l)
{
#ifdef SPKRDEBUG
printf("spkrclose: entering with dev = %"PRIx64"\n", dev);
#endif /* SPKRDEBUG */
if (minor(dev) != 0)
return(ENXIO);
else
{
spkr_tone(0, 0);
free(spkr_inbuf, M_DEVBUF);
spkr_active = 0;
}
return(0);
}
int
spkrioctl(dev_t dev, u_long cmd, void *data, int flag, struct lwp *l)
{
#ifdef SPKRDEBUG
printf("spkrioctl: entering with dev = %"PRIx64", cmd = %lx\n", dev, cmd);
#endif /* SPKRDEBUG */
if (minor(dev) != 0)
return(ENXIO);
else if (cmd == SPKRTONE)
{
tone_t *tp = (tone_t *)data;
if (tp->frequency == 0)
spkr_rest(tp->duration);
else
spkr_tone(tp->frequency, tp->duration);
}
else if (cmd == SPKRTUNE)
{
tone_t *tp = (tone_t *)(*(void **)data);
tone_t ttp;
int error;
for (; ; tp++) {
error = copyin(tp, &ttp, sizeof(tone_t));
if (error)
return(error);
if (ttp.duration == 0)
break;
if (ttp.frequency == 0)
spkr_rest(ttp.duration);
else
spkr_tone(ttp.frequency, ttp.duration);
}
}
else
return(EINVAL);
return(0);
}
int
spkr__modcmd(modcmd_t cmd, void *arg)
{
#ifdef _MODULE
devmajor_t bmajor, cmajor;
#endif
int error = 0;
#ifdef _MODULE
switch(cmd) {
case MODULE_CMD_INIT:
bmajor = cmajor = -1;
error = devsw_attach(spkr_cd.cd_name, NULL, &bmajor,
&spkr_cdevsw, &cmajor);
if (error)
break;
error = config_init_component(cfdriver_ioconf_spkr,
cfattach_ioconf_spkr, cfdata_ioconf_spkr);
if (error) {
devsw_detach(NULL, &spkr_cdevsw);
}
break;
case MODULE_CMD_FINI:
if (spkr_active)
return EBUSY;
error = config_fini_component(cfdriver_ioconf_spkr,
cfattach_ioconf_spkr, cfdata_ioconf_spkr);
devsw_detach(NULL, &spkr_cdevsw);
break;
default:
error = ENOTTY;
break;
}
#endif
return error;
}
/* $NetBSD: spkrio.h,v 1.1 2016/12/09 04:32:39 christos Exp $ */
/*
* spkr.h -- interface definitions for speaker ioctl()
*/
#ifndef _DEV_ISA_SPKR_H_
#define _DEV_ISA_SPKR_H_
#include <sys/ioccom.h>
#define SPKRTONE _IOW('S', 1, tone_t) /* emit tone */
#define SPKRTUNE _IO('S', 2) /* emit tone sequence */
typedef struct {
int frequency; /* in hertz */
int duration; /* in 1/100ths of a second */
} tone_t;
void spkr_tone(u_int, u_int);
void spkr_rest(int);
int spkr__modcmd(modcmd_t, void *);
int spkr_probe(device_t, cfdata_t, void *);
extern int spkr_attached;
#endif
--- src/sys/dev/Attic/spkr_synth.c 2016/12/08 11:31:08 1.1
+++ src/sys/dev/Attic/spkr_synth.c 2016/12/09 04:32:39 1.2
@@ -1,14 +1,14 @@ | @@ -1,14 +1,14 @@ | |||
1 | /* $NetBSD: spkr_synth.c,v 1.1 2016/12/08 11:31:08 nat Exp $ */ | 1 | /* $NetBSD: spkr_synth.c,v 1.2 2016/12/09 04:32:39 christos Exp $ */ | |
2 | 2 | |||
3 | /*- | 3 | /*- | |
4 | * Copyright (c) 2016 Nathanial Sloss <nathanialsloss@yahoo.com.au> | 4 | * Copyright (c) 2016 Nathanial Sloss <nathanialsloss@yahoo.com.au> | |
5 | * All rights reserved. | 5 | * All rights reserved. | |
6 | * | 6 | * | |
7 | * Redistribution and use in source and binary forms, with or without | 7 | * Redistribution and use in source and binary forms, with or without | |
8 | * modification, are permitted provided that the following conditions | 8 | * modification, are permitted provided that the following conditions | |
9 | * are met: | 9 | * are met: | |
10 | * 1. Redistributions of source code must retain the above copyright | 10 | * 1. Redistributions of source code must retain the above copyright | |
11 | * notice, this list of conditions and the following disclaimer. | 11 | * notice, this list of conditions and the following disclaimer. | |
12 | * 2. Redistributions in binary form must reproduce the above copyright | 12 | * 2. Redistributions in binary form must reproduce the above copyright | |
13 | * notice, this list of conditions and the following disclaimer in the | 13 | * notice, this list of conditions and the following disclaimer in the | |
14 | * documentation and/or other materials provided with the distribution. | 14 | * documentation and/or other materials provided with the distribution. | |
@@ -16,29 +16,28 @@ | @@ -16,29 +16,28 @@ | |||
16 | * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS | 16 | * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS | |
17 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED | 17 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED | |
18 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | 18 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | |
19 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS | 19 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS | |
20 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | 20 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | |
21 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | 21 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |
22 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | 22 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |
23 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | 23 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | |
24 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | 24 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |
25 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | 25 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |
26 | * POSSIBILITY OF SUCH DAMAGE. | 26 | * POSSIBILITY OF SUCH DAMAGE. | |
27 | */ | 27 | */ | |
28 | 28 | |||
29 | #ifdef VAUDIOSPEAKER | |||
30 | #include <sys/cdefs.h> | 29 | #include <sys/cdefs.h> | |
31 | __KERNEL_RCSID(0, "$NetBSD: spkr_synth.c,v 1.1 2016/12/08 11:31:08 nat Exp $"); | 30 | __KERNEL_RCSID(0, "$NetBSD: spkr_synth.c,v 1.2 2016/12/09 04:32:39 christos Exp $"); | |
32 | 31 | |||
33 | #include <sys/param.h> | 32 | #include <sys/param.h> | |
34 | #include <sys/systm.h> | 33 | #include <sys/systm.h> | |
35 | #include <sys/kernel.h> | 34 | #include <sys/kernel.h> | |
36 | #include <sys/errno.h> | 35 | #include <sys/errno.h> | |
37 | #include <sys/device.h> | 36 | #include <sys/device.h> | |
38 | #include <sys/malloc.h> | 37 | #include <sys/malloc.h> | |
39 | #include <sys/module.h> | 38 | #include <sys/module.h> | |
40 | #include <sys/uio.h> | 39 | #include <sys/uio.h> | |
41 | #include <sys/proc.h> | 40 | #include <sys/proc.h> | |
42 | #include <sys/ioctl.h> | 41 | #include <sys/ioctl.h> | |
43 | #include <sys/conf.h> | 42 | #include <sys/conf.h> | |
44 | #include <sys/condvar.h> | 43 | #include <sys/condvar.h> | |
@@ -52,86 +51,89 @@ struct vbell_args { | @@ -52,86 +51,89 @@ struct vbell_args { | |||
52 | device_t *cookie; | 51 | device_t *cookie; | |
53 | u_int pitch; | 52 | u_int pitch; | |
54 | u_int period; | 53 | u_int period; | |
55 | u_int volume; | 54 | u_int volume; | |
56 | bool dying; | 55 | bool dying; | |
57 | }; | 56 | }; | |
58 | 57 | |||
59 | void bell_thread(void *); | 58 | void bell_thread(void *); | |
60 | static int beep_sysctl_device(SYSCTLFN_PROTO); | 59 | static int beep_sysctl_device(SYSCTLFN_PROTO); | |
61 | 60 | |||
62 | #include <dev/audiobellvar.h> | 61 | #include <dev/audiobellvar.h> | |
63 | 62 | |||
64 | #include <dev/spkrvar.h> | 63 | #include <dev/spkrvar.h> | |
65 | #include <dev/isa/spkrio.h> | 64 | #include <dev/spkrio.h> | |
66 | 65 | |||
67 | #include "isa/spkr.c" | 66 | static void spkrattach(device_t, device_t, void *); | |
68 | 67 | static int spkrdetach(device_t, int); | ||
69 | int spkrprobe(device_t, cfdata_t, void *); | |||
70 | void spkrattach(device_t, device_t, void *); | |||
71 | int spkrdetach(device_t, int); | |||
72 | device_t speakerattach_mi(device_t); | 68 | device_t speakerattach_mi(device_t); | |
73 | 69 | |||
74 | #include "ioconf.h" | 70 | #include "ioconf.h" | |
75 | 71 | |||
76 | MODULE(MODULE_CLASS_DRIVER, spkr, NULL /* "audio" */); | 72 | MODULE(MODULE_CLASS_DRIVER, spkr, NULL /* "audio" */); | |
77 | 73 | |||
74 | static int | |||
75 | spkr_modcmd(modcmd_t cmd, void *arg) | |||
76 | { | |||
77 | return spkr__modcmd(cmd, arg); | |||
78 | } | |||
79 | ||||
78 | #ifdef _MODULE | 80 | #ifdef _MODULE | |
79 | #include "ioconf.c" | 81 | #include "ioconf.c" | |
80 | #endif | 82 | #endif | |
81 | 83 | |||
82 | 84 | |||
83 | CFATTACH_DECL3_NEW(spkr_synth, 0, | 85 | CFATTACH_DECL3_NEW(spkr_synth, 0, | |
84 | spkrprobe, spkrattach, spkrdetach, NULL, NULL, NULL, DVF_DETACH_SHUTDOWN); | 86 | spkr_probe, spkrattach, spkrdetach, NULL, NULL, NULL, DVF_DETACH_SHUTDOWN); | |
85 | 87 | |||
86 | extern struct cfdriver audio_cd; | 88 | extern struct cfdriver audio_cd; | |
87 | 89 | |||
88 | static struct sysctllog *spkr_sc_log; /* sysctl log */ | 90 | static struct sysctllog *spkr_sc_log; /* sysctl log */ | |
89 | static int beep_index = 0; | 91 | static int beep_index = 0; | |
90 | 92 | |||
91 | struct vbell_args sc_bell_args; | 93 | struct vbell_args sc_bell_args; | |
92 | lwp_t *sc_bellthread; | 94 | lwp_t *sc_bellthread; | |
93 | kmutex_t sc_bellock; | 95 | kmutex_t sc_bellock; | |
94 | kcondvar_t sc_bellcv; | 96 | kcondvar_t sc_bellcv; | |
95 | 97 | |||
96 | struct spkr_attach_args { | 98 | struct spkr_attach_args { | |
97 | device_t dev; | 99 | device_t dev; | |
98 | }; | 100 | }; | |
99 | 101 | |||
100 | static void | 102 | void | |
101 | tone(u_int xhz, u_int ticks) | 103 | spkr_tone(u_int xhz, u_int ticks) | |
102 | { | 104 | { | |
103 | audiobell(beep_index, xhz, ticks * (1000 / hz), 80, 0); | 105 | audiobell(beep_index, xhz, ticks * (1000 / hz), 80, 0); | |
104 | } | 106 | } | |
105 | 107 | |||
106 | static void | 108 | void | |
107 | rest(int ticks) | 109 | spkr_rest(int ticks) | |
108 | { | 110 | { | |
109 | #ifdef SPKRDEBUG | 111 | #ifdef SPKRDEBUG | |
110 | printf("rest: %d\n", ticks); | 112 | printf("%s: %d\n", __func__, ticks); | |
111 | #endif /* SPKRDEBUG */ | 113 | #endif /* SPKRDEBUG */ | |
112 | if (ticks > 0) | 114 | if (ticks > 0) | |
113 | audiobell(beep_index, 0, ticks * (1000 / hz), 80, 0); | 115 | audiobell(beep_index, 0, ticks * (1000 / hz), 80, 0); | |
114 | } | 116 | } | |
115 | 117 | |||
116 | device_t | 118 | device_t | |
117 | speakerattach_mi(device_t dev) | 119 | speakerattach_mi(device_t dev) | |
118 | { | 120 | { | |
119 | struct spkr_attach_args sa; | 121 | struct spkr_attach_args sa; | |
120 | sa.dev = dev; | 122 | sa.dev = dev; | |
121 | return config_found(dev, &sa, NULL); | 123 | return config_found(dev, &sa, NULL); | |
122 | } | 124 | } | |
123 | 125 | |||
124 | void | 126 | static void | |
125 | spkrattach(device_t parent, device_t self, void *aux) | 127 | spkrattach(device_t parent, device_t self, void *aux) | |
126 | { | 128 | { | |
127 | const struct sysctlnode *node; | 129 | const struct sysctlnode *node; | |
128 | 130 | |||
129 | printf("\n"); | 131 | printf("\n"); | |
130 | beep_index = 0; | 132 | beep_index = 0; | |
131 | spkr_attached = 1; | 133 | spkr_attached = 1; | |
132 | 134 | |||
133 | if (!pmf_device_register(self, NULL, NULL)) | 135 | if (!pmf_device_register(self, NULL, NULL)) | |
134 | aprint_error_dev(self, "couldn't establish power handler\n"); | 136 | aprint_error_dev(self, "couldn't establish power handler\n"); | |
135 | mutex_init(&sc_bellock, MUTEX_DEFAULT, IPL_SCHED); | 137 | mutex_init(&sc_bellock, MUTEX_DEFAULT, IPL_SCHED); | |
136 | cv_init(&sc_bellcv, "bellcv"); | 138 | cv_init(&sc_bellcv, "bellcv"); | |
137 | 139 | |||
@@ -150,27 +152,27 @@ spkrattach(device_t parent, device_t sel | @@ -150,27 +152,27 @@ spkrattach(device_t parent, device_t sel | |||
150 | CTLFLAG_READWRITE, | 152 | CTLFLAG_READWRITE, | |
151 | CTLTYPE_INT, "device", | 153 | CTLTYPE_INT, "device", | |
152 | SYSCTL_DESCR("default device"), | 154 | SYSCTL_DESCR("default device"), | |
153 | beep_sysctl_device, 0, | 155 | beep_sysctl_device, 0, | |
154 | NULL, 0, | 156 | NULL, 0, | |
155 | CTL_HW, node->sysctl_num, | 157 | CTL_HW, node->sysctl_num, | |
156 | CTL_CREATE, CTL_EOL); | 158 | CTL_CREATE, CTL_EOL); | |
157 | } | 159 | } | |
158 | 160 | |||
159 | kthread_create(PRI_BIO, KTHREAD_MPSAFE | KTHREAD_MUSTJOIN, NULL, | 161 | kthread_create(PRI_BIO, KTHREAD_MPSAFE | KTHREAD_MUSTJOIN, NULL, | |
160 | bell_thread, &sc_bell_args, &sc_bellthread, "vbell"); | 162 | bell_thread, &sc_bell_args, &sc_bellthread, "vbell"); | |
161 | } | 163 | } | |
162 | 164 | |||
163 | int | 165 | static int | |
164 | spkrdetach(device_t self, int flags) | 166 | spkrdetach(device_t self, int flags) | |
165 | { | 167 | { | |
166 | 168 | |||
167 | pmf_device_deregister(self); | 169 | pmf_device_deregister(self); | |
168 | 170 | |||
169 | mutex_enter(&sc_bellock); | 171 | mutex_enter(&sc_bellock); | |
170 | sc_bell_args.dying = true; | 172 | sc_bell_args.dying = true; | |
171 | 173 | |||
172 | cv_broadcast(&sc_bellcv); | 174 | cv_broadcast(&sc_bellcv); | |
173 | mutex_exit(&sc_bellock); | 175 | mutex_exit(&sc_bellock); | |
174 | 176 | |||
175 | kthread_join(sc_bellthread); | 177 | kthread_join(sc_bellthread); | |
176 | cv_destroy(&sc_bellcv); | 178 | cv_destroy(&sc_bellcv); | |
@@ -240,16 +242,13 @@ beep_sysctl_device(SYSCTLFN_ARGS) | @@ -240,16 +242,13 @@ beep_sysctl_device(SYSCTLFN_ARGS) | |||
240 | error = sysctl_lookup(SYSCTLFN_CALL(&node)); | 242 | error = sysctl_lookup(SYSCTLFN_CALL(&node)); | |
241 | if (error || newp == NULL) | 243 | if (error || newp == NULL) | |
242 | return error; | 244 | return error; | |
243 | 245 | |||
244 | 246 | |||
245 | if (t < -1 || (t != -1 && (ac = device_lookup_private(&audio_cd, t)) == | 247 | if (t < -1 || (t != -1 && (ac = device_lookup_private(&audio_cd, t)) == | |
246 | NULL)) | 248 | NULL)) | |
247 | return EINVAL; | 249 | return EINVAL; | |
248 | 250 | |||
249 | beep_index = t; | 251 | beep_index = t; | |
250 | 252 | |||
251 | return error; | 253 | return error; | |
252 | } | 254 | } | |
253 | ||||
254 | #endif /* VAUDIOSPEAKER */ | |||
255 | /* spkr.c ends here */ |
--- src/sys/dev/isa/files.isa 2016/12/09 02:22:34 1.166
+++ src/sys/dev/isa/files.isa 2016/12/09 04:32:39 1.167
@@ -1,14 +1,14 @@ | @@ -1,14 +1,14 @@ | |||
1 | # $NetBSD: files.isa,v 1.166 2016/12/09 02:22:34 christos Exp $ | 1 | # $NetBSD: files.isa,v 1.167 2016/12/09 04:32:39 christos Exp $ | |
2 | # | 2 | # | |
3 | # Config file and device description for machine-independent ISA code. | 3 | # Config file and device description for machine-independent ISA code. | |
4 | # Included by ports that need it. Requires that the SCSI files be | 4 | # Included by ports that need it. Requires that the SCSI files be | |
5 | # defined first. | 5 | # defined first. | |
6 | 6 | |||
7 | # ports should specify appropriate major numbers for the following | 7 | # ports should specify appropriate major numbers for the following | |
8 | # devices: | 8 | # devices: | |
9 | # mcd, wd, wt | 9 | # mcd, wd, wt | |
10 | 10 | |||
11 | device isa {[port = -1], [size = 0], | 11 | device isa {[port = -1], [size = 0], | |
12 | [iomem = -1], [iosiz = 0], | 12 | [iomem = -1], [iosiz = 0], | |
13 | [irq = -1], [drq = -1], [drq2 = -1]} | 13 | [irq = -1], [drq = -1], [drq2 = -1]} | |
14 | attach isa at isabus | 14 | attach isa at isabus | |
@@ -425,27 +425,26 @@ attach rt at isa | @@ -425,27 +425,26 @@ attach rt at isa | |||
425 | file dev/isa/radiotrack.c rt | 425 | file dev/isa/radiotrack.c rt | |
426 | 426 | |||
427 | # AIMS Lab Radiotrack II FM Radio Card | 427 | # AIMS Lab Radiotrack II FM Radio Card | |
428 | device rtii: radiodev, tea5757 | 428 | device rtii: radiodev, tea5757 | |
429 | attach rtii at isa | 429 | attach rtii at isa | |
430 | file dev/isa/radiotrack2.c rtii | 430 | file dev/isa/radiotrack2.c rtii | |
431 | 431 | |||
432 | # PC PPI (speaker interface) | 432 | # PC PPI (speaker interface) | |
433 | device pcppi {} | 433 | device pcppi {} | |
434 | attach pcppi at isa | 434 | attach pcppi at isa | |
435 | file dev/isa/pcppi.c pcppi needs-flag | 435 | file dev/isa/pcppi.c pcppi needs-flag | |
436 | 436 | |||
437 | attach spkr at pcppi with spkr_pcppi | 437 | attach spkr at pcppi with spkr_pcppi | |
438 | file dev/isa/spkr.c spkr needs-flag | |||
439 | file dev/isa/spkr_pcppi.c spkr_pcppi | 438 | file dev/isa/spkr_pcppi.c spkr_pcppi | |
440 | 439 | |||
441 | attach midi at pcppi with midi_pcppi: midisyn | 440 | attach midi at pcppi with midi_pcppi: midisyn | |
442 | file dev/isa/midi_pcppi.c midi_pcppi | 441 | file dev/isa/midi_pcppi.c midi_pcppi | |
443 | 442 | |||
444 | # AT Timer (TIMER 1) | 443 | # AT Timer (TIMER 1) | |
445 | attach attimer at isa with attimer_isa | 444 | attach attimer at isa with attimer_isa | |
446 | file dev/isa/attimer_isa.c attimer_isa | 445 | file dev/isa/attimer_isa.c attimer_isa | |
447 | 446 | |||
448 | # | 447 | # | |
449 | # Environmental monitors | 448 | # Environmental monitors | |
450 | # | 449 | # | |
451 | 450 |
--- src/sys/dev/isa/spkr_pcppi.c 2016/12/09 02:22:34 1.1
+++ src/sys/dev/isa/spkr_pcppi.c 2016/12/09 04:32:39 1.2
@@ -1,14 +1,14 @@ | @@ -1,14 +1,14 @@ | |||
1 | /* $NetBSD: spkr_pcppi.c,v 1.1 2016/12/09 02:22:34 christos Exp $ */ | 1 | /* $NetBSD: spkr_pcppi.c,v 1.2 2016/12/09 04:32:39 christos Exp $ */ | |
2 | 2 | |||
3 | /* | 3 | /* | |
4 | * Copyright (c) 1990 Eric S. Raymond (esr@snark.thyrsus.com) | 4 | * Copyright (c) 1990 Eric S. Raymond (esr@snark.thyrsus.com) | |
5 | * Copyright (c) 1990 Andrew A. Chernov (ache@astral.msk.su) | 5 | * Copyright (c) 1990 Andrew A. Chernov (ache@astral.msk.su) | |
6 | * Copyright (c) 1990 Lennart Augustsson (lennart@augustsson.net) | 6 | * Copyright (c) 1990 Lennart Augustsson (lennart@augustsson.net) | |
7 | * All rights reserved. | 7 | * All rights reserved. | |
8 | * | 8 | * | |
9 | * Redistribution and use in source and binary forms, with or without | 9 | * Redistribution and use in source and binary forms, with or without | |
10 | * modification, are permitted provided that the following conditions | 10 | * modification, are permitted provided that the following conditions | |
11 | * are met: | 11 | * are met: | |
12 | * 1. Redistributions of source code must retain the above copyright | 12 | * 1. Redistributions of source code must retain the above copyright | |
13 | * notice, this list of conditions and the following disclaimer. | 13 | * notice, this list of conditions and the following disclaimer. | |
14 | * 2. Redistributions in binary form must reproduce the above copyright | 14 | * 2. Redistributions in binary form must reproduce the above copyright | |
@@ -33,59 +33,65 @@ | @@ -33,59 +33,65 @@ | |||
33 | * POSSIBILITY OF SUCH DAMAGE. | 33 | * POSSIBILITY OF SUCH DAMAGE. | |
34 | */ | 34 | */ | |
35 | 35 | |||
36 | /* | 36 | /* | |
37 | * spkr.c -- device driver for console speaker on 80386 | 37 | * spkr.c -- device driver for console speaker on 80386 | |
38 | * | 38 | * | |
39 | * v1.1 by Eric S. Raymond (esr@snark.thyrsus.com) Feb 1990 | 39 | * v1.1 by Eric S. Raymond (esr@snark.thyrsus.com) Feb 1990 | |
40 | * modified for 386bsd by Andrew A. Chernov <ache@astral.msk.su> | 40 | * modified for 386bsd by Andrew A. Chernov <ache@astral.msk.su> | |
41 | * 386bsd only clean version, all SYSV stuff removed | 41 | * 386bsd only clean version, all SYSV stuff removed | |
42 | * use hz value from param.c | 42 | * use hz value from param.c | |
43 | */ | 43 | */ | |
44 | 44 | |||
45 | #include <sys/cdefs.h> | 45 | #include <sys/cdefs.h> | |
46 | __KERNEL_RCSID(0, "$NetBSD: spkr_pcppi.c,v 1.1 2016/12/09 02:22:34 christos Exp $"); | 46 | __KERNEL_RCSID(0, "$NetBSD: spkr_pcppi.c,v 1.2 2016/12/09 04:32:39 christos Exp $"); | |
47 | 47 | |||
48 | #include <sys/param.h> | 48 | #include <sys/param.h> | |
49 | #include <sys/systm.h> | 49 | #include <sys/systm.h> | |
50 | #include <sys/kernel.h> | 50 | #include <sys/kernel.h> | |
51 | #include <sys/errno.h> | 51 | #include <sys/errno.h> | |
52 | #include <sys/device.h> | 52 | #include <sys/device.h> | |
53 | #include <sys/malloc.h> | 53 | #include <sys/malloc.h> | |
54 | #include <sys/module.h> | 54 | #include <sys/module.h> | |
55 | #include <sys/uio.h> | 55 | #include <sys/uio.h> | |
56 | #include <sys/proc.h> | 56 | #include <sys/proc.h> | |
57 | #include <sys/ioctl.h> | 57 | #include <sys/ioctl.h> | |
58 | #include <sys/conf.h> | 58 | #include <sys/conf.h> | |
59 | 59 | |||
60 | #include <sys/bus.h> | 60 | #include <sys/bus.h> | |
61 | 61 | |||
62 | #include <dev/isa/pcppivar.h> | 62 | #include <dev/isa/pcppivar.h> | |
63 | 63 | |||
64 | #include <dev/isa/spkrio.h> | 64 | #include <dev/spkrio.h> | |
65 | 65 | |||
66 | void spkrattach(device_t, device_t, void *); | 66 | extern int spkr_attached; | |
67 | int spkrdetach(device_t, int); | 67 | static void spkrattach(device_t, device_t, void *); | |
68 | int spkrprobe(device_t, cfdata_t, void *); | 68 | static int spkrdetach(device_t, int); | |
69 | 69 | |||
70 | #include "ioconf.h" | 70 | #include "ioconf.h" | |
71 | 71 | |||
72 | MODULE(MODULE_CLASS_DRIVER, spkr, NULL /* "pcppi" */); | 72 | MODULE(MODULE_CLASS_DRIVER, spkr, NULL /* "pcppi" */); | |
73 | 73 | |||
74 | static int | |||
75 | spkr_modcmd(modcmd_t cmd, void *arg) | |||
76 | { | |||
77 | return spkr__modcmd(cmd, arg); | |||
78 | } | |||
79 | ||||
74 | #ifdef _MODULE | 80 | #ifdef _MODULE | |
75 | #include "ioconf.c" | 81 | #include "ioconf.c" | |
76 | #endif | 82 | #endif | |
77 | 83 | |||
78 | CFATTACH_DECL_NEW(spkr_pcppi, 0, spkrprobe, spkrattach, spkrdetach, NULL); | 84 | CFATTACH_DECL_NEW(spkr_pcppi, 0, spkr_probe, spkrattach, spkrdetach, NULL); | |
79 | 85 | |||
80 | static pcppi_tag_t ppicookie; | 86 | static pcppi_tag_t ppicookie; | |
81 | 87 | |||
82 | #define SPKRPRI (PZERO - 1) | 88 | #define SPKRPRI (PZERO - 1) | |
83 | 89 | |||
84 | void | 90 | void | |
85 | spkr_tone(u_int xhz, u_int ticks) | 91 | spkr_tone(u_int xhz, u_int ticks) | |
86 | /* emit tone of frequency hz for given number of ticks */ | 92 | /* emit tone of frequency hz for given number of ticks */ | |
87 | { | 93 | { | |
88 | pcppi_bell(ppicookie, xhz, ticks, PCPPI_BELL_SLEEP); | 94 | pcppi_bell(ppicookie, xhz, ticks, PCPPI_BELL_SLEEP); | |
89 | } | 95 | } | |
90 | 96 | |||
91 | void | 97 | void | |
@@ -94,86 +100,34 @@ spkr_rest(int ticks) | @@ -94,86 +100,34 @@ spkr_rest(int ticks) | |||
94 | { | 100 | { | |
95 | /* | 101 | /* | |
96 | * Set timeout to endrest function, then give up the timeslice. | 102 | * Set timeout to endrest function, then give up the timeslice. | |
97 | * This is so other processes can execute while the rest is being | 103 | * This is so other processes can execute while the rest is being | |
98 | * waited out. | 104 | * waited out. | |
99 | */ | 105 | */ | |
100 | #ifdef SPKRDEBUG | 106 | #ifdef SPKRDEBUG | |
101 | printf("%s: %d\n", __func__, ticks); | 107 | printf("%s: %d\n", __func__, ticks); | |
102 | #endif /* SPKRDEBUG */ | 108 | #endif /* SPKRDEBUG */ | |
103 | if (ticks > 0) | 109 | if (ticks > 0) | |
104 | tsleep(spkr_rest, SPKRPRI | PCATCH, "rest", ticks); | 110 | tsleep(spkr_rest, SPKRPRI | PCATCH, "rest", ticks); | |
105 | } | 111 | } | |
106 | 112 | |||
107 | extern int spkr_active; /* exclusion flag */ | 113 | static void | |
108 | extern const struct cdevsw spkr_cdevsw; | |||
109 | ||||
110 | int spkr_attached = 0; | |||
111 | ||||
112 | int | |||
113 | spkrprobe(device_t parent, cfdata_t match, void *aux) | |||
114 | { | |||
115 | return (!spkr_attached); | |||
116 | } | |||
117 | ||||
118 | void | |||
119 | spkrattach(device_t parent, device_t self, void *aux) | 114 | spkrattach(device_t parent, device_t self, void *aux) | |
120 | { | 115 | { | |
121 | aprint_naive("\n"); | 116 | aprint_naive("\n"); | |
122 | aprint_normal("\n"); | 117 | aprint_normal("\n"); | |
123 | ppicookie = ((struct pcppi_attach_args *)aux)->pa_cookie; | 118 | ppicookie = ((struct pcppi_attach_args *)aux)->pa_cookie; | |
124 | spkr_attached = 1; | 119 | spkr_attached = 1; | |
125 | if (!pmf_device_register(self, NULL, NULL)) | 120 | if (!pmf_device_register(self, NULL, NULL)) | |
126 | aprint_error_dev(self, "couldn't establish power handler\n"); | 121 | aprint_error_dev(self, "couldn't establish power handler\n"); | |
127 | } | 122 | } | |
128 | 123 | |||
129 | int | 124 | static int | |
130 | spkrdetach(device_t self, int flags) | 125 | spkrdetach(device_t self, int flags) | |
131 | { | 126 | { | |
132 | 127 | |||
133 | pmf_device_deregister(self); | 128 | pmf_device_deregister(self); | |
134 | spkr_attached = 0; | 129 | spkr_attached = 0; | |
135 | ppicookie = NULL; | 130 | ppicookie = NULL; | |
136 | 131 | |||
137 | return 0; | 132 | return 0; | |
138 | } | 133 | } | |
139 | ||||
140 | ||||
141 | static int | |||
142 | spkr_modcmd(modcmd_t cmd, void *arg) | |||
143 | { | |||
144 | #ifdef _MODULE | |||
145 | devmajor_t bmajor, cmajor; | |||
146 | #endif | |||
147 | int error = 0; | |||
148 | ||||
149 | #ifdef _MODULE | |||
150 | switch(cmd) { | |||
151 | case MODULE_CMD_INIT: | |||
152 | bmajor = cmajor = -1; | |||
153 | error = devsw_attach(spkr_cd.cd_name, NULL, &bmajor, | |||
154 | &spkr_cdevsw, &cmajor); | |||
155 | if (error) | |||
156 | break; | |||
157 | ||||
158 | error = config_init_component(cfdriver_ioconf_spkr, | |||
159 | cfattach_ioconf_spkr, cfdata_ioconf_spkr); | |||
160 | if (error) { | |||
161 | devsw_detach(NULL, &spkr_cdevsw); | |||
162 | } | |||
163 | break; | |||
164 | ||||
165 | case MODULE_CMD_FINI: | |||
166 | if (spkr_active) | |||
167 | return EBUSY; | |||
168 | error = config_fini_component(cfdriver_ioconf_spkr, | |||
169 | cfattach_ioconf_spkr, cfdata_ioconf_spkr); | |||
170 | devsw_detach(NULL, &spkr_cdevsw); | |||
171 | break; | |||
172 | default: | |||
173 | error = ENOTTY; | |||
174 | break; | |||
175 | } | |||
176 | #endif | |||
177 | ||||
178 | return error; | |||
179 | } |