- Provide toggles to show debug messages. Set new sysctl variables
hw.midi.debug and hw.midi.seq.debug to 1 to enable debug log. - Make debug messages human-frendly. - Implement /dev/music. - Add a timer engine required by /dev/music. - Fix nonblocking I/O. - Fix the numbering of midi and synth devices.
This commit is contained in:
parent
233beff278
commit
995231304d
@ -503,6 +503,7 @@ dev/sound/midi/midi.c optional midi
|
||||
dev/sound/midi/midibuf.c optional midi
|
||||
dev/sound/midi/midisynth.c optional midi
|
||||
dev/sound/midi/sequencer.c optional seq midi
|
||||
dev/sound/midi/timer.c optional seq midi
|
||||
dev/sound/pci/als4000.c optional pcm pci
|
||||
dev/sound/pci/cmi.c optional pcm pci
|
||||
dev/sound/pci/cs4281.c optional pcm pci
|
||||
|
@ -548,7 +548,7 @@ emu_probe(device_t dev)
|
||||
device_set_desc(dev, "EMU8000 Wavetable Synth");
|
||||
bzero(scp, sizeof(*scp));
|
||||
|
||||
DEB(printf("emu%d: probing.\n", unit));
|
||||
MIDI_DEBUG(printf("emu%d: probing.\n", unit));
|
||||
|
||||
if (emu_allocres(scp, dev)) {
|
||||
emu_releaseres(scp, dev);
|
||||
@ -565,7 +565,7 @@ emu_probe(device_t dev)
|
||||
return (ENXIO);
|
||||
}
|
||||
|
||||
DEB(printf("emu%d: probed.\n", unit));
|
||||
MIDI_DEBUG(printf("emu%d: probed.\n", unit));
|
||||
|
||||
return (0);
|
||||
}
|
||||
@ -582,7 +582,7 @@ emu_attach(device_t dev)
|
||||
unit = device_get_unit(dev);
|
||||
scp = device_get_softc(dev);
|
||||
|
||||
DEB(printf("emu%d: attaching.\n", unit));
|
||||
MIDI_DEBUG(printf("emu%d: attaching.\n", unit));
|
||||
|
||||
if (emu_allocres(scp, dev)) {
|
||||
emu_releaseres(scp, dev);
|
||||
@ -731,7 +731,7 @@ emu_attach(device_t dev)
|
||||
|
||||
midiinit(devinfo, dev);
|
||||
|
||||
DEB(printf("emu%d: attached.\n", unit));
|
||||
MIDI_DEBUG(printf("emu%d: attached.\n", unit));
|
||||
|
||||
return (0);
|
||||
}
|
||||
@ -765,11 +765,11 @@ emu_ioctl(dev_t i_dev, u_long cmd, caddr_t arg, int mode, struct thread *td)
|
||||
|
||||
unit = MIDIUNIT(i_dev);
|
||||
|
||||
DEB(printf("emu%d: ioctlling, cmd 0x%x.\n", unit, (int)cmd));
|
||||
MIDI_DEBUG(printf("emu_ioctl: unit %d, cmd %s.\n", unit, midi_cmdname(cmd, cmdtab_midiioctl)));
|
||||
|
||||
devinfo = get_mididev_info(i_dev, &unit);
|
||||
if (devinfo == NULL) {
|
||||
DEB(printf("emu_ioctl: unit %d is not configured.\n", unit));
|
||||
MIDI_DEBUG(printf("emu_ioctl: unit %d is not configured.\n", unit));
|
||||
return (ENXIO);
|
||||
}
|
||||
scp = devinfo->softc;
|
||||
@ -793,7 +793,8 @@ emu_ioctl(dev_t i_dev, u_long cmd, caddr_t arg, int mode, struct thread *td)
|
||||
return (0);
|
||||
break;
|
||||
case SNDCTL_SYNTH_MEMAVL:
|
||||
return 0x7fffffff;
|
||||
*(int *)arg = 0x7fffffff;
|
||||
return (0);
|
||||
break;
|
||||
default:
|
||||
return (ENOSYS);
|
||||
@ -828,7 +829,7 @@ emu_readraw(mididev_info *md, u_char *buf, int len, int *lenr, int nonblock)
|
||||
unit = md->unit;
|
||||
scp = md->softc;
|
||||
if ((md->fflags & FREAD) == 0) {
|
||||
DEB(printf("emu_readraw: unit %d is not for reading.\n", unit));
|
||||
MIDI_DEBUG(printf("emu_readraw: unit %d is not for reading.\n", unit));
|
||||
return (EIO);
|
||||
}
|
||||
|
||||
@ -852,7 +853,7 @@ emu_writeraw(mididev_info *md, u_char *buf, int len, int *lenw, int nonblock)
|
||||
unit = md->unit;
|
||||
scp = md->softc;
|
||||
if ((md->fflags & FWRITE) == 0) {
|
||||
DEB(printf("emu_writeraw: unit %d is not for writing.\n", unit));
|
||||
MIDI_DEBUG(printf("emu_writeraw: unit %d is not for writing.\n", unit));
|
||||
return (EIO);
|
||||
}
|
||||
|
||||
|
@ -224,7 +224,7 @@ gusmidi_open(dev_t i_dev, int flags, int mode, struct thread *td)
|
||||
|
||||
devinfo = get_mididev_info(i_dev, &unit);
|
||||
if (devinfo == NULL) {
|
||||
DEB(printf("gusmidi_open: unit %d is not configured.\n", unit));
|
||||
MIDI_DEBUG(printf("gusmidi_open: unit %d is not configured.\n", unit));
|
||||
return (ENXIO);
|
||||
}
|
||||
scp = devinfo->softc;
|
||||
@ -252,9 +252,11 @@ gusmidi_ioctl(dev_t i_dev, u_long cmd, caddr_t arg, int mode, struct thread *td)
|
||||
|
||||
unit = MIDIUNIT(i_dev);
|
||||
|
||||
MIDI_DEBUG(printf("gusmidi_ioctl: unit %d, cmd %s.\n", unit, midi_cmdname(cmd, cmdtab_midiioctl)));
|
||||
|
||||
devinfo = get_mididev_info(i_dev, &unit);
|
||||
if (devinfo == NULL) {
|
||||
DEB(printf("gusmidi_ioctl: unit %d is not configured.\n", unit));
|
||||
MIDI_DEBUG(printf("gusmidi_ioctl: unit %d is not configured.\n", unit));
|
||||
return (ENXIO);
|
||||
}
|
||||
scp = devinfo->softc;
|
||||
@ -353,7 +355,7 @@ gusmidi_callback(void *di, int reason)
|
||||
mtx_assert(&d->flagqueue_mtx, MA_OWNED);
|
||||
|
||||
if (d == NULL) {
|
||||
DEB(printf("gusmidi_callback: device not configured.\n"));
|
||||
MIDI_DEBUG(printf("gusmidi_callback: device not configured.\n"));
|
||||
return (ENXIO);
|
||||
}
|
||||
|
||||
|
@ -249,7 +249,7 @@ mpu_probe2(device_t dev)
|
||||
if (scp->io == NULL)
|
||||
return (ENXIO);
|
||||
|
||||
DEB(printf("mpu%d: probing.\n", unit));
|
||||
MIDI_DEBUG(printf("mpu%d: probing.\n", unit));
|
||||
|
||||
/* Reset the interface. */
|
||||
if (mpu_resetmode(scp) != 0 || mpu_waitack(scp) != 0) {
|
||||
@ -320,7 +320,7 @@ no_irq:
|
||||
/* We have found the irq. */
|
||||
scp->irq_val = ffs(~irqp0 & irqp1) - 1;
|
||||
|
||||
DEB(printf("mpu%d: probed.\n", unit));
|
||||
MIDI_DEBUG(printf("mpu%d: probed.\n", unit));
|
||||
|
||||
return (0);
|
||||
}
|
||||
@ -356,7 +356,7 @@ mpu_attach(device_t dev)
|
||||
|
||||
scp = device_get_softc(dev);
|
||||
|
||||
DEB(printf("mpu: attaching.\n"));
|
||||
MIDI_DEBUG(printf("mpu: attaching.\n"));
|
||||
|
||||
mtx_init(&scp->mtx, "mpumid", MTX_DEF);
|
||||
|
||||
@ -387,7 +387,7 @@ mpu_attach(device_t dev)
|
||||
bus_setup_intr(dev, scp->irq, INTR_TYPE_AV, mpu_intr, scp,
|
||||
&scp->ih);
|
||||
|
||||
DEB(printf("mpu: attached.\n"));
|
||||
MIDI_DEBUG(printf("mpu: attached.\n"));
|
||||
|
||||
return (0);
|
||||
}
|
||||
@ -417,9 +417,11 @@ mpu_ioctl(dev_t i_dev, u_long cmd, caddr_t arg, int mode, struct thread *td)
|
||||
|
||||
unit = MIDIUNIT(i_dev);
|
||||
|
||||
MIDI_DEBUG(printf("mpu_ioctl: unit %d, cmd %s.\n", unit, midi_cmdname(cmd, cmdtab_midiioctl)));
|
||||
|
||||
devinfo = get_mididev_info(i_dev, &unit);
|
||||
if (devinfo == NULL) {
|
||||
DEB(printf("mpu_ioctl: unit %d is not configured.\n", unit));
|
||||
MIDI_DEBUG(printf("mpu_ioctl: unit %d is not configured.\n", unit));
|
||||
return (ENXIO);
|
||||
}
|
||||
scp = devinfo->softc;
|
||||
@ -497,7 +499,7 @@ mpu_callback(void *di, int reason)
|
||||
mtx_assert(&d->flagqueue_mtx, MA_OWNED);
|
||||
|
||||
if (d == NULL) {
|
||||
DEB(printf("mpu_callback: device not configured.\n"));
|
||||
MIDI_DEBUG(printf("mpu_callback: device not configured.\n"));
|
||||
return (ENXIO);
|
||||
}
|
||||
|
||||
|
@ -548,13 +548,13 @@ opl_probe(device_t dev)
|
||||
device_set_desc(dev, opl_op_desc.name);
|
||||
bzero(scp, sizeof(*scp));
|
||||
|
||||
DEB(printf("opl%d: probing.\n", unit));
|
||||
MIDI_DEBUG(printf("opl%d: probing.\n", unit));
|
||||
|
||||
scp->io_rid = 0;
|
||||
scp->io = bus_alloc_resource(dev, SYS_RES_IOPORT, &scp->io_rid, 0, ~0, 4, RF_ACTIVE);
|
||||
if (opl_allocres(scp, dev)) {
|
||||
/* We try the defaults in opl_defaultiobase. */
|
||||
DEB(printf("opl%d: port is omitted, trying the defaults.\n", unit));
|
||||
MIDI_DEBUG(printf("opl%d: port is omitted, trying the defaults.\n", unit));
|
||||
for (i = 0 ; i < sizeof(opl_defaultiobase) / sizeof(*opl_defaultiobase) ; i++) {
|
||||
scp->io_rid = 0;
|
||||
scp->io = bus_alloc_resource(dev, SYS_RES_IOPORT, &scp->io_rid, opl_defaultiobase[i], opl_defaultiobase[i] + 1, 4, RF_ACTIVE);
|
||||
@ -574,7 +574,7 @@ opl_probe(device_t dev)
|
||||
|
||||
/* We now have some kind of OPL. */
|
||||
|
||||
DEB(printf("opl%d: probed.\n", unit));
|
||||
MIDI_DEBUG(printf("opl%d: probed.\n", unit));
|
||||
|
||||
return (0);
|
||||
}
|
||||
@ -645,7 +645,7 @@ opl_attach(device_t dev)
|
||||
|
||||
scp = device_get_softc(dev);
|
||||
|
||||
DEB(printf("opl: attaching.\n"));
|
||||
MIDI_DEBUG(printf("opl: attaching.\n"));
|
||||
|
||||
/* Fill the softc for this unit. */
|
||||
scp->dev = dev;
|
||||
@ -751,8 +751,8 @@ opl_attach(device_t dev)
|
||||
|
||||
midiinit(devinfo, dev);
|
||||
|
||||
DEB(printf("opl: attached.\n"));
|
||||
DEB(printf("opl: the chip is OPL%d.\n", scp->model));
|
||||
MIDI_DEBUG(printf("opl: attached.\n"));
|
||||
MIDI_DEBUG(printf("opl: the chip is OPL%d.\n", scp->model));
|
||||
|
||||
return (0);
|
||||
}
|
||||
@ -772,11 +772,11 @@ opl_open(dev_t i_dev, int flags, int mode, struct thread *td)
|
||||
|
||||
unit = MIDIUNIT(i_dev);
|
||||
|
||||
DEB(printf("opl%d: opening.\n", unit));
|
||||
MIDI_DEBUG(printf("opl%d: opening.\n", unit));
|
||||
|
||||
devinfo = get_mididev_info(i_dev, &unit);
|
||||
if (devinfo == NULL) {
|
||||
DEB(printf("opl_open: unit %d is not configured.\n", unit));
|
||||
MIDI_DEBUG(printf("opl_open: unit %d is not configured.\n", unit));
|
||||
return (ENXIO);
|
||||
}
|
||||
scp = devinfo->softc;
|
||||
@ -799,7 +799,7 @@ opl_open(dev_t i_dev, int flags, int mode, struct thread *td)
|
||||
mtx_unlock(&scp->mtx);
|
||||
}
|
||||
|
||||
DEB(printf("opl%d: opened.\n", unit));
|
||||
MIDI_DEBUG(printf("opl%d: opened.\n", unit));
|
||||
|
||||
return (0);
|
||||
}
|
||||
@ -813,11 +813,11 @@ opl_close(dev_t i_dev, int flags, int mode, struct thread *td)
|
||||
|
||||
unit = MIDIUNIT(i_dev);
|
||||
|
||||
DEB(printf("opl%d: closing.\n", unit));
|
||||
MIDI_DEBUG(printf("opl%d: closing.\n", unit));
|
||||
|
||||
devinfo = get_mididev_info(i_dev, &unit);
|
||||
if (devinfo == NULL) {
|
||||
DEB(printf("opl_close: unit %d is not configured.\n", unit));
|
||||
MIDI_DEBUG(printf("opl_close: unit %d is not configured.\n", unit));
|
||||
return (ENXIO);
|
||||
}
|
||||
scp = devinfo->softc;
|
||||
@ -832,7 +832,7 @@ opl_close(dev_t i_dev, int flags, int mode, struct thread *td)
|
||||
/* Stop the OPL. */
|
||||
opl_reset(scp->devinfo);
|
||||
|
||||
DEB(printf("opl%d: closed.\n", unit));
|
||||
MIDI_DEBUG(printf("opl%d: closed.\n", unit));
|
||||
|
||||
return (0);
|
||||
}
|
||||
@ -845,15 +845,15 @@ opl_ioctl(dev_t i_dev, u_long cmd, caddr_t arg, int mode, struct thread *td)
|
||||
int unit;
|
||||
struct synth_info *synthinfo;
|
||||
struct midi_info *midiinfo;
|
||||
struct sbi_instrument ins;
|
||||
struct sbi_instrument *ins;
|
||||
|
||||
unit = MIDIUNIT(i_dev);
|
||||
|
||||
DEB(printf("opl%d: ioctlling, cmd 0x%x.\n", unit, (int)cmd));
|
||||
MIDI_DEBUG(printf("opl_ioctl: unit %d, cmd %s.\n", unit, midi_cmdname(cmd, cmdtab_midiioctl)));
|
||||
|
||||
devinfo = get_mididev_info(i_dev, &unit);
|
||||
if (devinfo == NULL) {
|
||||
DEB(printf("opl_ioctl: unit %d is not configured.\n", unit));
|
||||
MIDI_DEBUG(printf("opl_ioctl: unit %d is not configured.\n", unit));
|
||||
return (ENXIO);
|
||||
}
|
||||
scp = devinfo->softc;
|
||||
@ -880,19 +880,20 @@ opl_ioctl(dev_t i_dev, u_long cmd, caddr_t arg, int mode, struct thread *td)
|
||||
return (0);
|
||||
break;
|
||||
case SNDCTL_FM_LOAD_INSTR:
|
||||
bcopy(arg, &ins, sizeof(ins));
|
||||
if (ins.channel < 0 || ins.channel >= SBFM_MAXINSTR) {
|
||||
printf("opl_ioctl: Instrument number %d is not valid.\n", ins.channel);
|
||||
ins = (struct sbi_instrument *)arg;
|
||||
if (ins->channel < 0 || ins->channel >= SBFM_MAXINSTR) {
|
||||
printf("opl_ioctl: Instrument number %d is not valid.\n", ins->channel);
|
||||
return (EINVAL);
|
||||
}
|
||||
#if notyet
|
||||
pmgr_inform(scp, PM_E_PATCH_LOADED, inc.channel, 0, 0, 0);
|
||||
pmgr_inform(scp, PM_E_PATCH_LOADED, inc->channel, 0, 0, 0);
|
||||
#endif /* notyet */
|
||||
opl_storeinstr(scp, ins.channel, &ins);
|
||||
opl_storeinstr(scp, ins->channel, ins);
|
||||
return (0);
|
||||
break;
|
||||
case SNDCTL_SYNTH_MEMAVL:
|
||||
return 0x7fffffff;
|
||||
*(int *)arg = 0x7fffffff;
|
||||
return (0);
|
||||
break;
|
||||
case SNDCTL_FM_4OP_ENABLE:
|
||||
if (scp->model >= MODEL_OPL3)
|
||||
@ -918,14 +919,14 @@ opl_callback(void *d, int reason)
|
||||
mtx_assert(&devinfo->flagqueue_mtx, MA_OWNED);
|
||||
|
||||
if (devinfo == NULL) {
|
||||
DEB(printf("opl_callback: device not configured.\n"));
|
||||
MIDI_DEBUG(printf("opl_callback: device not configured.\n"));
|
||||
return (ENXIO);
|
||||
}
|
||||
|
||||
unit = devinfo->unit;
|
||||
scp = devinfo->softc;
|
||||
|
||||
DEB(printf("opl%d: callback, reason 0x%x.\n", unit, reason));
|
||||
MIDI_DEBUG(printf("opl%d: callback, reason 0x%x.\n", unit, reason));
|
||||
|
||||
switch (reason & MIDI_CB_REASON_MASK) {
|
||||
case MIDI_CB_START:
|
||||
@ -964,7 +965,7 @@ opl_readraw(mididev_info *md, u_char *buf, int len, int *lenr, int nonblock)
|
||||
unit = md->unit;
|
||||
scp = md->softc;
|
||||
if ((md->fflags & FREAD) == 0) {
|
||||
DEB(printf("opl_readraw: unit %d is not for reading.\n", unit));
|
||||
MIDI_DEBUG(printf("opl_readraw: unit %d is not for reading.\n", unit));
|
||||
return (EIO);
|
||||
}
|
||||
|
||||
@ -988,7 +989,7 @@ opl_writeraw(mididev_info *md, u_char *buf, int len, int *lenw, int nonblock)
|
||||
unit = md->unit;
|
||||
scp = md->softc;
|
||||
if ((md->fflags & FWRITE) == 0) {
|
||||
DEB(printf("opl_writeraw: unit %d is not for writing.\n", unit));
|
||||
MIDI_DEBUG(printf("opl_writeraw: unit %d is not for writing.\n", unit));
|
||||
return (EIO);
|
||||
}
|
||||
|
||||
@ -1010,7 +1011,7 @@ opl_killnote(mididev_info *md, int voice, int note, int vel)
|
||||
scp = md->softc;
|
||||
unit = md->unit;
|
||||
|
||||
DEB(printf("opl%d: killing a note, voice %d, note %d, vel %d.\n", unit, voice, note, vel));
|
||||
MIDI_DEBUG(printf("opl%d: killing a note, voice %d, note %d, vel %d.\n", unit, voice, note, vel));
|
||||
|
||||
if (voice < 0 || voice >= md->synth.alloc.max_voice)
|
||||
return (0);
|
||||
@ -1048,7 +1049,7 @@ opl_setinstr(mididev_info *md, int voice, int instr_no)
|
||||
scp = md->softc;
|
||||
unit = md->unit;
|
||||
|
||||
DEB(printf("opl%d: setting an instrument, voice %d, instr_no %d.\n", unit, voice, instr_no));
|
||||
MIDI_DEBUG(printf("opl%d: setting an instrument, voice %d, instr_no %d.\n", unit, voice, instr_no));
|
||||
|
||||
|
||||
if (voice < 0 || voice >= md->synth.alloc.max_voice || instr_no < 0 || instr_no >= SBFM_MAXINSTR)
|
||||
@ -1073,7 +1074,7 @@ opl_startnote(mididev_info *md, int voice, int note, int volume)
|
||||
scp = md->softc;
|
||||
unit = md->unit;
|
||||
|
||||
DEB(printf("opl%d: starting a note, voice %d, note %d, volume %d.\n", unit, voice, note, volume));
|
||||
MIDI_DEBUG(printf("opl%d: starting a note, voice %d, note %d, volume %d.\n", unit, voice, note, volume));
|
||||
|
||||
if (voice < 0 || voice >= md->synth.alloc.max_voice)
|
||||
return (0);
|
||||
@ -1192,7 +1193,7 @@ opl_reset(mididev_info *md)
|
||||
scp = md->softc;
|
||||
unit = md->unit;
|
||||
|
||||
DEB(printf("opl%d: resetting.\n", unit));
|
||||
MIDI_DEBUG(printf("opl%d: resetting.\n", unit));
|
||||
|
||||
mtx_lock(&md->synth.vc_mtx);
|
||||
mtx_lock(&scp->mtx);
|
||||
@ -1297,7 +1298,7 @@ opl_aftertouch(mididev_info *md, int voice, int press)
|
||||
scp = md->softc;
|
||||
unit = md->unit;
|
||||
|
||||
DEB(printf("opl%d: setting the aftertouch, voice %d, press %d.\n", unit, voice, press));
|
||||
MIDI_DEBUG(printf("opl%d: setting the aftertouch, voice %d, press %d.\n", unit, voice, press));
|
||||
|
||||
if (voice < 0 || voice >= md->synth.alloc.max_voice)
|
||||
return (0);
|
||||
@ -1356,7 +1357,7 @@ opl_bendpitch(sc_p scp, int voice, int value)
|
||||
md = scp->devinfo;
|
||||
unit = md->unit;
|
||||
|
||||
DEB(printf("opl%d: setting the pitch bend, voice %d, value %d.\n", unit, voice, value));
|
||||
MIDI_DEBUG(printf("opl%d: setting the pitch bend, voice %d, value %d.\n", unit, voice, value));
|
||||
|
||||
mtx_lock(&scp->mtx);
|
||||
|
||||
@ -1396,7 +1397,7 @@ opl_controller(mididev_info *md, int voice, int ctrlnum, int val)
|
||||
scp = md->softc;
|
||||
unit = md->unit;
|
||||
|
||||
DEB(printf("opl%d: setting the controller, voice %d, ctrlnum %d, val %d.\n", unit, voice, ctrlnum, val));
|
||||
MIDI_DEBUG(printf("opl%d: setting the controller, voice %d, ctrlnum %d, val %d.\n", unit, voice, ctrlnum, val));
|
||||
|
||||
if (voice < 0 || voice >= md->synth.alloc.max_voice)
|
||||
return (0);
|
||||
@ -1448,7 +1449,7 @@ opl_allocvoice(mididev_info *md, int chn, int note, struct voice_alloc_info *all
|
||||
|
||||
scp = md->softc;
|
||||
|
||||
DEB(printf("opl%d: allocating a voice, chn %d, note %d.\n", unit, chn, note));
|
||||
MIDI_DEBUG(printf("opl%d: allocating a voice, chn %d, note %d.\n", md->unit, chn, note));
|
||||
|
||||
best_time = 0x7fffffff;
|
||||
|
||||
@ -1515,7 +1516,7 @@ opl_setupvoice(mididev_info *md, int voice, int chn)
|
||||
|
||||
scp = md->softc;
|
||||
|
||||
DEB(printf("opl%d: setting up a voice, voice %d, chn %d.\n", unit, voice, chn));
|
||||
MIDI_DEBUG(printf("opl%d: setting up a voice, voice %d, chn %d.\n", md->unit, voice, chn));
|
||||
|
||||
mtx_lock(&md->synth.vc_mtx);
|
||||
|
||||
@ -1563,7 +1564,7 @@ opl_command(sc_p scp, int ch, int addr, u_int val)
|
||||
{
|
||||
int model;
|
||||
|
||||
DEB(printf("opl%d: sending a command, iobase 0x%x, addr 0x%x, val 0x%x.\n", unit, iobase, addr, val));
|
||||
MIDI_DEBUG(printf("opl%d: sending a command, addr 0x%x, val 0x%x.\n", scp->devinfo->unit, addr, val));
|
||||
|
||||
model = scp->model;
|
||||
|
||||
@ -1590,7 +1591,7 @@ opl_command(sc_p scp, int ch, int addr, u_int val)
|
||||
static int
|
||||
opl_status(sc_p scp)
|
||||
{
|
||||
DEB(printf("opl%d: reading the status.\n", unit));
|
||||
MIDI_DEBUG(printf("opl%d: reading the status.\n", scp->devinfo->unit));
|
||||
|
||||
return bus_space_read_1(rman_get_bustag(scp->io), rman_get_bushandle(scp->io), 0);
|
||||
}
|
||||
@ -1606,7 +1607,7 @@ opl_enter4opmode(sc_p scp)
|
||||
|
||||
devinfo = scp->devinfo;
|
||||
|
||||
DEB(printf("opl%d: entering 4 OP mode.\n", unit));
|
||||
MIDI_DEBUG(printf("opl%d: entering 4 OP mode.\n", devinfo->unit));
|
||||
|
||||
/* Connect all possible 4 OP voice operators. */
|
||||
mtx_lock(&devinfo->synth.vc_mtx);
|
||||
|
@ -172,7 +172,7 @@ uartsio_probe(device_t dev)
|
||||
if (scp->io == NULL)
|
||||
return (ENXIO);
|
||||
|
||||
DEB(printf("uartsio%d: probing.\n", unit));
|
||||
MIDI_DEBUG(printf("uartsio%d: probing.\n", unit));
|
||||
|
||||
/* Read the IER. The upper four bits should all be zero. */
|
||||
c = uartsio_readport(scp, com_ier);
|
||||
@ -190,7 +190,7 @@ uartsio_probe(device_t dev)
|
||||
|
||||
/* XXX Do we need a loopback test? */
|
||||
|
||||
DEB(printf("uartsio%d: probed.\n", unit));
|
||||
MIDI_DEBUG(printf("uartsio%d: probed.\n", unit));
|
||||
|
||||
return (0);
|
||||
}
|
||||
@ -203,7 +203,7 @@ uartsio_attach(device_t dev)
|
||||
|
||||
scp = device_get_softc(dev);
|
||||
|
||||
DEB(printf("uartsio: attaching.\n"));
|
||||
MIDI_DEBUG(printf("uartsio: attaching.\n"));
|
||||
|
||||
/* Allocate resources. */
|
||||
if (uartsio_allocres(scp, dev)) {
|
||||
@ -216,11 +216,11 @@ uartsio_attach(device_t dev)
|
||||
if ((uartsio_readport(scp, com_iir) & IIR_FIFO_MASK) == FIFO_RX_HIGH) {
|
||||
scp->has_fifo = 1;
|
||||
scp->tx_size = TX_FIFO_SIZE;
|
||||
DEB(printf("uartsio: uart is 16550A, tx size is %d bytes.\n", scp->tx_size));
|
||||
MIDI_DEBUG(printf("uartsio: uart is 16550A, tx size is %d bytes.\n", scp->tx_size));
|
||||
} else {
|
||||
scp->has_fifo = 0;
|
||||
scp->tx_size = 1;
|
||||
DEB(printf("uartsio: uart is not 16550A.\n"));
|
||||
MIDI_DEBUG(printf("uartsio: uart is not 16550A.\n"));
|
||||
}
|
||||
|
||||
/* Configure the uart. */
|
||||
@ -255,7 +255,7 @@ uartsio_attach(device_t dev)
|
||||
/* Now we can handle the interrupts. */
|
||||
bus_setup_intr(dev, scp->irq, INTR_TYPE_AV, uartsio_intr, scp, &scp->ih);
|
||||
|
||||
DEB(printf("uartsio: attached.\n"));
|
||||
MIDI_DEBUG(printf("uartsio: attached.\n"));
|
||||
|
||||
return (0);
|
||||
}
|
||||
@ -271,9 +271,11 @@ uartsio_ioctl(dev_t i_dev, u_long cmd, caddr_t arg, int mode, struct thread *td)
|
||||
|
||||
unit = MIDIUNIT(i_dev);
|
||||
|
||||
MIDI_DEBUG(printf("uartsio_ioctl: unit %d, cmd %s.\n", unit, midi_cmdname(cmd, cmdtab_midiioctl)));
|
||||
|
||||
devinfo = get_mididev_info(i_dev, &unit);
|
||||
if (devinfo == NULL) {
|
||||
DEB(printf("uartsio_ioctl: unit %d is not configured.\n", unit));
|
||||
MIDI_DEBUG(printf("uartsio_ioctl: unit %d is not configured.\n", unit));
|
||||
return (ENXIO);
|
||||
}
|
||||
scp = devinfo->softc;
|
||||
@ -331,7 +333,7 @@ uartsio_callback(void *di, int reason)
|
||||
mtx_assert(&d->flagqueue_mtx, MA_OWNED);
|
||||
|
||||
if (d == NULL) {
|
||||
DEB(printf("uartsio_callback: device not configured.\n"));
|
||||
MIDI_DEBUG(printf("uartsio_callback: device not configured.\n"));
|
||||
return (ENXIO);
|
||||
}
|
||||
|
||||
|
@ -89,16 +89,45 @@ static struct cdevsw midi_cdevsw = {
|
||||
* descriptors for active devices. also used as the public softc
|
||||
* of a device.
|
||||
*/
|
||||
static TAILQ_HEAD(,_mididev_info) midi_info;
|
||||
static int nmidi, nsynth;
|
||||
static TAILQ_HEAD(,_mididev_info) midi_info;
|
||||
static int nmidi, nsynth;
|
||||
/* Mutex to protect midi_info, nmidi and nsynth. */
|
||||
static struct mtx midiinfo_mtx;
|
||||
static int midiinfo_mtx_init;
|
||||
static struct mtx midiinfo_mtx;
|
||||
static int midiinfo_mtx_init;
|
||||
|
||||
/* These make the buffer for /dev/midistat */
|
||||
static int midistatbusy;
|
||||
static char midistatbuf[4096];
|
||||
static int midistatptr;
|
||||
static int midistatbusy;
|
||||
static char midistatbuf[4096];
|
||||
static int midistatptr;
|
||||
|
||||
SYSCTL_NODE(_hw, OID_AUTO, midi, CTLFLAG_RD, 0, "Midi driver");
|
||||
|
||||
int midi_debug;
|
||||
SYSCTL_INT(_hw_midi, OID_AUTO, debug, CTLFLAG_RW, &midi_debug, 0, "");
|
||||
|
||||
midi_cmdtab cmdtab_midiioctl[] = {
|
||||
{SNDCTL_MIDI_PRETIME, "SNDCTL_MIDI_PRETIME"},
|
||||
{SNDCTL_MIDI_MPUMODE, "SNDCTL_MIDI_MPUMODE"},
|
||||
{SNDCTL_MIDI_MPUCMD, "SNDCTL_MIDI_MPUCMD"},
|
||||
{SNDCTL_SYNTH_INFO, "SNDCTL_SYNTH_INFO"},
|
||||
{SNDCTL_MIDI_INFO, "SNDCTL_MIDI_INFO"},
|
||||
{SNDCTL_SYNTH_MEMAVL, "SNDCTL_SYNTH_MEMAVL"},
|
||||
{SNDCTL_FM_LOAD_INSTR, "SNDCTL_FM_LOAD_INSTR"},
|
||||
{SNDCTL_FM_4OP_ENABLE, "SNDCTL_FM_4OP_ENABLE"},
|
||||
{MIOSPASSTHRU, "MIOSPASSTHRU"},
|
||||
{MIOGPASSTHRU, "MIOGPASSTHRU"},
|
||||
{AIONWRITE, "AIONWRITE"},
|
||||
{AIOGSIZE, "AIOGSIZE"},
|
||||
{AIOSSIZE, "AIOSSIZE"},
|
||||
{AIOGFMT, "AIOGFMT"},
|
||||
{AIOSFMT, "AIOSFMT"},
|
||||
{AIOGMIX, "AIOGMIX"},
|
||||
{AIOSMIX, "AIOSMIX"},
|
||||
{AIOSTOP, "AIOSTOP"},
|
||||
{AIOSYNC, "AIOSYNC"},
|
||||
{AIOGCAP, "AIOGCAP"},
|
||||
{-1, NULL},
|
||||
};
|
||||
|
||||
/*
|
||||
* This is the generic init routine.
|
||||
@ -115,6 +144,8 @@ midiinit(mididev_info *d, device_t dev)
|
||||
* here the generic things.
|
||||
*/
|
||||
|
||||
MIDI_DEBUG(printf("midiinit: unit %d.\n", d->unit));
|
||||
|
||||
unit = d->unit;
|
||||
d->softc = device_get_softc(dev);
|
||||
d->dev = dev;
|
||||
@ -183,6 +214,58 @@ get_mididev_info_unit(int unit)
|
||||
return md;
|
||||
}
|
||||
|
||||
/*
|
||||
* a small utility function which, given a unit number, returns
|
||||
* a pointer to the associated mididev_info struct with MDT_MIDI.
|
||||
*/
|
||||
mididev_info *
|
||||
get_mididev_midi_unit(int unit)
|
||||
{
|
||||
mididev_info *md;
|
||||
|
||||
/* XXX */
|
||||
if (!midiinfo_mtx_init) {
|
||||
midiinfo_mtx_init = 1;
|
||||
mtx_init(&midiinfo_mtx, "midinf", MTX_DEF);
|
||||
TAILQ_INIT(&midi_info);
|
||||
}
|
||||
|
||||
mtx_lock(&midiinfo_mtx);
|
||||
TAILQ_FOREACH(md, &midi_info, md_link) {
|
||||
if (md->midiunit == unit)
|
||||
break;
|
||||
}
|
||||
mtx_unlock(&midiinfo_mtx);
|
||||
|
||||
return md;
|
||||
}
|
||||
|
||||
/*
|
||||
* a small utility function which, given a unit number, returns
|
||||
* a pointer to the associated mididev_info struct with MDT_SYNTH.
|
||||
*/
|
||||
mididev_info *
|
||||
get_mididev_synth_unit(int unit)
|
||||
{
|
||||
mididev_info *md;
|
||||
|
||||
/* XXX */
|
||||
if (!midiinfo_mtx_init) {
|
||||
midiinfo_mtx_init = 1;
|
||||
mtx_init(&midiinfo_mtx, "midinf", MTX_DEF);
|
||||
TAILQ_INIT(&midi_info);
|
||||
}
|
||||
|
||||
mtx_lock(&midiinfo_mtx);
|
||||
TAILQ_FOREACH(md, &midi_info, md_link) {
|
||||
if (md->synthunit == unit)
|
||||
break;
|
||||
}
|
||||
mtx_unlock(&midiinfo_mtx);
|
||||
|
||||
return md;
|
||||
}
|
||||
|
||||
/* Create a new midi device info structure. */
|
||||
/* TODO: lock md, then exit. */
|
||||
mididev_info *
|
||||
@ -213,12 +296,15 @@ create_mididev_info_unit(int type, mididev_info *mdinf, synthdev_info *syninf)
|
||||
|
||||
mtx_lock(&midiinfo_mtx);
|
||||
|
||||
/* XXX midi_info is still static. */
|
||||
switch (type) {
|
||||
case MDT_MIDI:
|
||||
mdnew->midiunit = nmidi;
|
||||
mdnew->synthunit = nmidi;
|
||||
nmidi++;
|
||||
break;
|
||||
case MDT_SYNTH:
|
||||
mdnew->midiunit = -1;
|
||||
mdnew->synthunit = nsynth;
|
||||
nsynth++;
|
||||
break;
|
||||
default:
|
||||
@ -233,6 +319,7 @@ create_mididev_info_unit(int type, mididev_info *mdinf, synthdev_info *syninf)
|
||||
panic("unsupported device type");
|
||||
return NULL;
|
||||
}
|
||||
mdnew->mdtype = type;
|
||||
|
||||
for (unit = 0 ; ; unit++) {
|
||||
TAILQ_FOREACH(md, &midi_info, md_link) {
|
||||
@ -259,6 +346,20 @@ mididev_info_number(void)
|
||||
return nmidi + nsynth;
|
||||
}
|
||||
|
||||
/* Return the number of configured midi devices. */
|
||||
int
|
||||
mididev_midi_number(void)
|
||||
{
|
||||
return nmidi;
|
||||
}
|
||||
|
||||
/* Return the number of configured synth devices. */
|
||||
int
|
||||
mididev_synth_number(void)
|
||||
{
|
||||
return nsynth;
|
||||
}
|
||||
|
||||
/*
|
||||
* here are the switches for the main functions. The switches do
|
||||
* all necessary checks on the device number to make sure
|
||||
@ -391,8 +492,7 @@ midi_open(dev_t i_dev, int flags, int mode, struct thread *td)
|
||||
dev = minor(i_dev);
|
||||
d = get_mididev_info(i_dev, &unit);
|
||||
|
||||
DEB(printf("open midi%d subdev %d flags 0x%08x mode 0x%08x\n",
|
||||
unit, dev & 0xf, flags, mode));
|
||||
MIDI_DEBUG(printf("midi_open: unit %d, flags 0x%x.\n", unit, flags));
|
||||
|
||||
if (d == NULL)
|
||||
return (ENXIO);
|
||||
@ -402,12 +502,14 @@ midi_open(dev_t i_dev, int flags, int mode, struct thread *td)
|
||||
device_busy(d->dev);
|
||||
if ((d->flags & MIDI_F_BUSY) != 0) {
|
||||
mtx_unlock(&d->flagqueue_mtx);
|
||||
DEB(printf("opl_open: unit %d is busy.\n", unit));
|
||||
printf("midi_open: unit %d is busy.\n", unit);
|
||||
return (EBUSY);
|
||||
}
|
||||
d->fflags = flags;
|
||||
d->flags |= MIDI_F_BUSY;
|
||||
d->flags &= ~(MIDI_F_READING | MIDI_F_WRITING);
|
||||
d->fflags = flags;
|
||||
if ((d->fflags & O_NONBLOCK) != 0)
|
||||
d->flags |= MIDI_F_NBIO;
|
||||
|
||||
/* Init the queue. */
|
||||
if ((flags & FREAD) != 0)
|
||||
@ -424,6 +526,16 @@ midi_open(dev_t i_dev, int flags, int mode, struct thread *td)
|
||||
else
|
||||
ret = d->open(i_dev, flags, mode, td);
|
||||
|
||||
mtx_lock(&d->flagqueue_mtx);
|
||||
|
||||
/* Begin recording if nonblocking. */
|
||||
if ((d->flags & (MIDI_F_READING | MIDI_F_NBIO)) == MIDI_F_NBIO && (d->fflags & FREAD) != 0)
|
||||
d->callback(d, MIDI_CB_START | MIDI_CB_RD);
|
||||
|
||||
mtx_unlock(&d->flagqueue_mtx);
|
||||
|
||||
MIDI_DEBUG(printf("midi_open: opened.\n"));
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
@ -436,7 +548,7 @@ midi_close(dev_t i_dev, int flags, int mode, struct thread *td)
|
||||
dev = minor(i_dev);
|
||||
d = get_mididev_info(i_dev, &unit);
|
||||
|
||||
DEB(printf("close midi%d subdev %d\n", unit, dev & 0xf));
|
||||
MIDI_DEBUG(printf("midi_close: unit %d.\n", unit));
|
||||
|
||||
if (d == NULL)
|
||||
return (ENXIO);
|
||||
@ -470,6 +582,8 @@ midi_close(dev_t i_dev, int flags, int mode, struct thread *td)
|
||||
else
|
||||
ret = d->close(i_dev, flags, mode, td);
|
||||
|
||||
MIDI_DEBUG(printf("midi_close: closed.\n"));
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
@ -483,7 +597,7 @@ midi_read(dev_t i_dev, struct uio * buf, int flag)
|
||||
dev = minor(i_dev);
|
||||
|
||||
d = get_mididev_info(i_dev, &unit);
|
||||
DEB(printf("read midi%d subdev %d flag 0x%08x\n", unit, dev & 0xf, flag));
|
||||
MIDI_DEBUG(printf("midi_read: unit %d, resid %d.\n", unit, buf->uio_resid));
|
||||
|
||||
if (d == NULL)
|
||||
return (ENXIO);
|
||||
@ -505,10 +619,13 @@ midi_read(dev_t i_dev, struct uio * buf, int flag)
|
||||
/* Have we got the data to read? */
|
||||
if ((d->flags & MIDI_F_NBIO) != 0 && d->midi_dbuf_in.rl == 0)
|
||||
ret = EAGAIN;
|
||||
else
|
||||
else {
|
||||
if ((d->flags & MIDI_F_NBIO) != 0 && len > d->midi_dbuf_in.rl)
|
||||
len = d->midi_dbuf_in.rl;
|
||||
ret = midibuf_seqread(&d->midi_dbuf_in, uiobuf, len, &lenr,
|
||||
d->callback, d, MIDI_CB_START | MIDI_CB_RD,
|
||||
&d->flagqueue_mtx);
|
||||
}
|
||||
|
||||
mtx_unlock(&d->flagqueue_mtx);
|
||||
|
||||
@ -517,6 +634,8 @@ midi_read(dev_t i_dev, struct uio * buf, int flag)
|
||||
|
||||
free(uiobuf, M_DEVBUF);
|
||||
|
||||
MIDI_DEBUG(printf("midi_read: ret %d, resid %d.\n", ret, buf->uio_resid));
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
@ -530,7 +649,7 @@ midi_write(dev_t i_dev, struct uio * buf, int flag)
|
||||
dev = minor(i_dev);
|
||||
d = get_mididev_info(i_dev, &unit);
|
||||
|
||||
DEB(printf("write midi%d subdev %d flag 0x%08x\n", unit, dev & 0xf, flag));
|
||||
MIDI_DEBUG(printf("midi_write: unit %d.\n", unit));
|
||||
|
||||
if (d == NULL)
|
||||
return (ENXIO);
|
||||
@ -593,6 +712,7 @@ midi_ioctl(dev_t i_dev, u_long cmd, caddr_t arg, int mode, struct thread *td)
|
||||
int ret = ENOSYS, dev, unit;
|
||||
mididev_info *d;
|
||||
struct snd_size *sndsize;
|
||||
snd_sync_parm *sp;
|
||||
|
||||
dev = minor(i_dev);
|
||||
d = get_mididev_info(i_dev, &unit);
|
||||
@ -610,6 +730,8 @@ midi_ioctl(dev_t i_dev, u_long cmd, caddr_t arg, int mode, struct thread *td)
|
||||
*/
|
||||
ret = 0;
|
||||
|
||||
MIDI_DEBUG(printf("midi_ioctl: unit %d, cmd %s.\n", unit, midi_cmdname(cmd, cmdtab_midiioctl)));
|
||||
|
||||
/*
|
||||
* all routines are called with int. blocked. Make sure that
|
||||
* ints are re-enabled when calling slow or blocking functions!
|
||||
@ -620,11 +742,15 @@ midi_ioctl(dev_t i_dev, u_long cmd, caddr_t arg, int mode, struct thread *td)
|
||||
* we start with the new ioctl interface.
|
||||
*/
|
||||
case AIONWRITE: /* how many bytes can write ? */
|
||||
mtx_lock(&d->flagqueue_mtx);
|
||||
*(int *)arg = d->midi_dbuf_out.fl;
|
||||
mtx_unlock(&d->flagqueue_mtx);
|
||||
MIDI_DEBUG(printf("midi_ioctl: fl %d.\n", *(int *)arg));
|
||||
break;
|
||||
|
||||
case AIOSSIZE: /* set the current blocksize */
|
||||
sndsize = (struct snd_size *)arg;
|
||||
MIDI_DEBUG(printf("midi_ioctl: play %d, rec %d.\n", sndsize->play_size, sndsize->rec_size));
|
||||
mtx_lock(&d->flagqueue_mtx);
|
||||
if (sndsize->play_size <= d->midi_dbuf_out.unit_size && sndsize->rec_size <= d->midi_dbuf_in.unit_size) {
|
||||
d->midi_dbuf_out.blocksize = d->midi_dbuf_out.unit_size;
|
||||
@ -661,6 +787,7 @@ midi_ioctl(dev_t i_dev, u_long cmd, caddr_t arg, int mode, struct thread *td)
|
||||
sndsize->play_size = d->midi_dbuf_out.blocksize;
|
||||
sndsize->rec_size = d->midi_dbuf_in.blocksize;
|
||||
mtx_unlock(&d->flagqueue_mtx);
|
||||
MIDI_DEBUG(printf("midi_ioctl: play %d, rec %d.\n", sndsize->play_size, sndsize->rec_size));
|
||||
|
||||
ret = 0;
|
||||
break;
|
||||
@ -672,40 +799,45 @@ midi_ioctl(dev_t i_dev, u_long cmd, caddr_t arg, int mode, struct thread *td)
|
||||
else if (*(int *)arg == AIOSYNC_CAPTURE)
|
||||
*(int *)arg = d->callback(d, MIDI_CB_STOP | MIDI_CB_RD);
|
||||
else {
|
||||
DEB(printf("AIOSTOP: bad channel 0x%x\n", *(int *)arg));
|
||||
MIDI_DEBUG(printf("midi_ioctl: bad channel 0x%x.\n", *(int *)arg));
|
||||
*(int *)arg = 0 ;
|
||||
}
|
||||
mtx_unlock(&d->flagqueue_mtx);
|
||||
break ;
|
||||
|
||||
case AIOSYNC:
|
||||
DEB(printf("AIOSYNC chan 0x%03lx pos %lu unimplemented\n",
|
||||
((snd_sync_parm *)arg)->chan,
|
||||
((snd_sync_parm *)arg)->pos));
|
||||
sp = (snd_sync_parm *)arg;
|
||||
MIDI_DEBUG(printf("midi_ioctl: unimplemented, chan 0x%03lx pos %lu.\n",
|
||||
sp->chan,
|
||||
sp->pos));
|
||||
break;
|
||||
/*
|
||||
* here follow the standard ioctls (filio.h etc.)
|
||||
*/
|
||||
case FIONREAD: /* get # bytes to read */
|
||||
mtx_lock(&d->flagqueue_mtx);
|
||||
*(int *)arg = d->midi_dbuf_in.rl;
|
||||
mtx_unlock(&d->flagqueue_mtx);
|
||||
MIDI_DEBUG(printf("midi_ioctl: rl %d.\n", *(int *)arg));
|
||||
break;
|
||||
|
||||
case FIOASYNC: /*set/clear async i/o */
|
||||
DEB( printf("FIOASYNC\n") ; )
|
||||
MIDI_DEBUG(printf("FIOASYNC\n"));
|
||||
break;
|
||||
|
||||
case FIONBIO: /* set/clear non-blocking i/o */
|
||||
mtx_lock(&d->flagqueue_mtx);
|
||||
if ( *(int *)arg == 0 )
|
||||
if (*(int *)arg == 0)
|
||||
d->flags &= ~MIDI_F_NBIO ;
|
||||
else
|
||||
d->flags |= MIDI_F_NBIO ;
|
||||
mtx_unlock(&d->flagqueue_mtx);
|
||||
MIDI_DEBUG(printf("midi_ioctl: arg %d.\n", *(int *)arg));
|
||||
break ;
|
||||
|
||||
case MIOSPASSTHRU: /* set/clear passthru */
|
||||
mtx_lock(&d->flagqueue_mtx);
|
||||
if ( *(int *)arg == 0 )
|
||||
if (*(int *)arg == 0)
|
||||
d->flags &= ~MIDI_F_PASSTHRU ;
|
||||
else
|
||||
d->flags |= MIDI_F_PASSTHRU ;
|
||||
@ -714,18 +846,22 @@ midi_ioctl(dev_t i_dev, u_long cmd, caddr_t arg, int mode, struct thread *td)
|
||||
midibuf_clear(&d->midi_dbuf_passthru);
|
||||
|
||||
mtx_unlock(&d->flagqueue_mtx);
|
||||
MIDI_DEBUG(printf("midi_ioctl: passthru %d.\n", *(int *)arg));
|
||||
|
||||
/* FALLTHROUGH */
|
||||
case MIOGPASSTHRU: /* get passthru */
|
||||
mtx_lock(&d->flagqueue_mtx);
|
||||
if ((d->flags & MIDI_F_PASSTHRU) != 0)
|
||||
(int *)arg = 1;
|
||||
*(int *)arg = 1;
|
||||
else
|
||||
(int *)arg = 0;
|
||||
break ;
|
||||
*(int *)arg = 0;
|
||||
mtx_unlock(&d->flagqueue_mtx);
|
||||
MIDI_DEBUG(printf("midi_ioctl: passthru %d.\n", *(int *)arg));
|
||||
break;
|
||||
|
||||
default:
|
||||
DEB(printf("default ioctl midi%d subdev %d fn 0x%08x fail\n",
|
||||
unit, dev & 0xf, cmd));
|
||||
MIDI_DEBUG(printf("midi_ioctl: default ioctl midi%d subdev %d fn 0x%08lx fail\n",
|
||||
unit, dev & 0xf, cmd));
|
||||
ret = EINVAL;
|
||||
break ;
|
||||
}
|
||||
@ -741,6 +877,8 @@ midi_poll(dev_t i_dev, int events, struct thread *td)
|
||||
dev = minor(i_dev);
|
||||
d = get_mididev_info(i_dev, &unit);
|
||||
|
||||
MIDI_DEBUG(printf("midi_poll: unit %d.\n", unit));
|
||||
|
||||
if (d == NULL)
|
||||
return (ENXIO);
|
||||
|
||||
@ -803,6 +941,8 @@ midi_sync(mididev_info *d)
|
||||
|
||||
mtx_assert(&d->flagqueue_mtx, MA_OWNED);
|
||||
|
||||
MIDI_DEBUG(printf("midi_sync: unit %d.\n", d->unit));
|
||||
|
||||
while (d->midi_dbuf_out.rl > 0) {
|
||||
if ((d->flags & MIDI_F_WRITING) == 0)
|
||||
d->callback(d, MIDI_CB_START | MIDI_CB_WR);
|
||||
@ -903,3 +1043,15 @@ midi_readstatus(char *buf, int *ptr, struct uio *uio)
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
char
|
||||
*midi_cmdname(int cmd, midi_cmdtab *tab)
|
||||
{
|
||||
while (tab->name != NULL) {
|
||||
if (cmd == tab->cmd)
|
||||
return (tab->name);
|
||||
tab++;
|
||||
}
|
||||
|
||||
return ("unknown");
|
||||
}
|
||||
|
@ -45,6 +45,7 @@
|
||||
#include <sys/fcntl.h>
|
||||
#include <sys/tty.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/sysctl.h>
|
||||
|
||||
#include <sys/kernel.h> /* for DATA_SET */
|
||||
|
||||
@ -98,14 +99,14 @@ struct _mididev_info {
|
||||
* the first part of the descriptor is filled up from a
|
||||
* template.
|
||||
*/
|
||||
char name[64];
|
||||
char name[64];
|
||||
|
||||
int type;
|
||||
int type;
|
||||
|
||||
d_open_t *open;
|
||||
d_close_t *close;
|
||||
d_ioctl_t *ioctl;
|
||||
midi_callback_t *callback;
|
||||
d_open_t *open;
|
||||
d_close_t *close;
|
||||
d_ioctl_t *ioctl;
|
||||
midi_callback_t *callback;
|
||||
|
||||
/*
|
||||
* combinations of the following flags are used as second argument in
|
||||
@ -137,20 +138,23 @@ struct _mididev_info {
|
||||
* not in the common structure.
|
||||
*/
|
||||
|
||||
int unit; /* unit number of the device */
|
||||
void *softc; /* softc for the device */
|
||||
device_t dev; /* device_t for the device */
|
||||
int unit; /* unit number of the device */
|
||||
int midiunit; /* unit number for midi devices */
|
||||
int synthunit; /* unit number for synth devices */
|
||||
int mdtype; /* MDT_MIDI or MDT_SYNTH */
|
||||
void *softc; /* softc for the device */
|
||||
device_t dev; /* device_t for the device */
|
||||
|
||||
int bd_id ; /* used to hold board-id info, eg. sb version,
|
||||
* mss codec type, etc. etc.
|
||||
*/
|
||||
int bd_id; /* used to hold board-id info, eg. sb version,
|
||||
* mss codec type, etc. etc.
|
||||
*/
|
||||
|
||||
struct mtx flagqueue_mtx; /* Mutex to protect flags and queues */
|
||||
struct mtx flagqueue_mtx; /* Mutex to protect flags and queues */
|
||||
|
||||
/* Queues */
|
||||
midi_dbuf midi_dbuf_in; /* midi input event/message queue */
|
||||
midi_dbuf midi_dbuf_out; /* midi output event/message queue */
|
||||
midi_dbuf midi_dbuf_passthru; /* midi passthru event/message queue */
|
||||
midi_dbuf midi_dbuf_in; /* midi input event/message queue */
|
||||
midi_dbuf midi_dbuf_out; /* midi output event/message queue */
|
||||
midi_dbuf midi_dbuf_passthru; /* midi passthru event/message queue */
|
||||
|
||||
/*
|
||||
* these parameters describe the operation of the board.
|
||||
@ -158,8 +162,8 @@ struct _mididev_info {
|
||||
*/
|
||||
|
||||
/* Flags */
|
||||
volatile u_long flags ; /* 32 bits, used for various purposes. */
|
||||
int fflags; /* file flag */
|
||||
volatile u_long flags; /* 32 bits, used for various purposes. */
|
||||
int fflags; /* file flag */
|
||||
|
||||
/*
|
||||
* we have separate flags for read and write, although in some
|
||||
@ -210,29 +214,29 @@ struct _mididev_info {
|
||||
*/
|
||||
#define MIDI_F_INIT 0x4000 /* changed parameters. need init */
|
||||
|
||||
int play_blocksize, rec_blocksize; /* blocksize for io and dma ops */
|
||||
int play_blocksize, rec_blocksize; /* blocksize for io and dma ops */
|
||||
|
||||
#define mwsel midi_dbuf_out.sel
|
||||
#define mrsel midi_dbuf_in.sel
|
||||
u_long interrupts; /* counter of interrupts */
|
||||
u_long magic;
|
||||
u_long nterrupts; /* counter of interrupts */
|
||||
u_long magic;
|
||||
#define MAGIC(unit) ( 0xa4d10de0 + unit )
|
||||
void *device_data ; /* just in case it is needed...*/
|
||||
void *device_data ; /* just in case it is needed...*/
|
||||
|
||||
midi_intr_t *intr; /* interrupt handler of the upper layer (ie sequencer) */
|
||||
midi_intr_t *intr; /* interrupt handler of the upper layer (ie sequencer) */
|
||||
void *intrarg; /* argument to interrupt handler */
|
||||
|
||||
/* The following is the interface from a midi sequencer to a midi device. */
|
||||
synthdev_info synth;
|
||||
synthdev_info synth;
|
||||
|
||||
/* This is the status message to display via /dev/midistat */
|
||||
char midistat[128];
|
||||
char midistat[128];
|
||||
|
||||
/* The tailq entry of the next midi device. */
|
||||
TAILQ_ENTRY(_mididev_info) md_link;
|
||||
TAILQ_ENTRY(_mididev_info) md_link;
|
||||
|
||||
/* The tailq entry of the next midi device opened by a sequencer. */
|
||||
TAILQ_ENTRY(_mididev_info) md_linkseq;
|
||||
TAILQ_ENTRY(_mididev_info) md_linkseq;
|
||||
} ;
|
||||
|
||||
/*
|
||||
@ -267,17 +271,7 @@ struct _mididev_info {
|
||||
*/
|
||||
#define MIDI_BUFFSIZE (1024) /* XXX */
|
||||
|
||||
/*
|
||||
* some macros for debugging purposes
|
||||
* DDB/DEB to enable/disable debugging stuff
|
||||
* BVDDB to enable debugging when bootverbose
|
||||
*/
|
||||
#define DDB(x) x /* XXX */
|
||||
#define BVDDB(x) if (bootverbose) x
|
||||
|
||||
#ifndef DEB
|
||||
#define DEB(x)
|
||||
#endif
|
||||
#ifdef _KERNEL
|
||||
|
||||
/* This is the generic midi drvier initializer. */
|
||||
int midiinit(mididev_info *d, device_t dev);
|
||||
@ -285,8 +279,12 @@ struct _mididev_info {
|
||||
/* This provides an access to the mididev_info. */
|
||||
mididev_info *get_mididev_info(dev_t i_dev, int *unit);
|
||||
mididev_info *get_mididev_info_unit(int unit);
|
||||
mididev_info *get_mididev_midi_unit(int unit);
|
||||
mididev_info *get_mididev_synth_unit(int unit);
|
||||
mididev_info *create_mididev_info_unit(int type, mididev_info *mdinf, synthdev_info *syninf);
|
||||
int mididev_info_number(void);
|
||||
int mididev_midi_number(void);
|
||||
int mididev_synth_number(void);
|
||||
#define MDT_MIDI (0)
|
||||
#define MDT_SYNTH (1)
|
||||
|
||||
@ -299,10 +297,32 @@ struct _mididev_info {
|
||||
d_poll_t midi_poll;
|
||||
|
||||
/* Common interrupt handler */
|
||||
void midi_intr(mididev_info *);
|
||||
void midi_intr(mididev_info *);
|
||||
|
||||
/* Sync output */
|
||||
int midi_sync(mididev_info *);
|
||||
int midi_sync(mididev_info *);
|
||||
|
||||
struct _midi_cmdtab {
|
||||
int cmd;
|
||||
char * name;
|
||||
};
|
||||
typedef struct _midi_cmdtab midi_cmdtab;
|
||||
|
||||
char *midi_cmdname(int cmd, midi_cmdtab *tab);
|
||||
|
||||
SYSCTL_DECL(_hw_midi);
|
||||
|
||||
extern int midi_debug;
|
||||
#define MIDI_DEBUG(x) \
|
||||
do { \
|
||||
if (midi_debug) { \
|
||||
(x); \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
extern midi_cmdtab cmdtab_midiioctl[];
|
||||
|
||||
#endif /* _KERNEL */
|
||||
|
||||
/*
|
||||
* Minor numbers for the midi driver.
|
||||
|
@ -125,11 +125,11 @@ midibuf_seqwrite(midi_dbuf *dbuf, u_char* data, int len, int *lenw, midi_callbac
|
||||
*lenw += lwrt;
|
||||
len -= lwrt;
|
||||
data += lwrt;
|
||||
|
||||
if (cb != NULL)
|
||||
(*cb)(d, reason);
|
||||
}
|
||||
|
||||
if (cb != NULL)
|
||||
(*cb)(d, reason);
|
||||
|
||||
/* Have we got still more data to write? */
|
||||
if (len > 0) {
|
||||
/* Sleep until we have enough space. */
|
||||
|
@ -437,7 +437,7 @@ synth_readraw(mididev_info *md, u_char *buf, int len, int *lenr, int nonblock)
|
||||
unit = md->unit;
|
||||
|
||||
if ((md->fflags & FREAD) == 0) {
|
||||
DEB(printf("synth_readraw: unit %d is not for reading.\n", unit));
|
||||
MIDI_DEBUG(printf("synth_readraw: unit %d is not for reading.\n", unit));
|
||||
return (EIO);
|
||||
}
|
||||
|
||||
@ -478,7 +478,7 @@ synth_writeraw(mididev_info *md, u_char *buf, int len, int *lenw, int nonblock)
|
||||
unit = md->unit;
|
||||
|
||||
if ((md->fflags & FWRITE) == 0) {
|
||||
DEB(printf("synth_writeraw: unit %d is not for writing.\n", unit));
|
||||
MIDI_DEBUG(printf("synth_writeraw: unit %d is not for writing.\n", unit));
|
||||
return (EIO);
|
||||
}
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -57,6 +57,8 @@
|
||||
#include <machine/clock.h> /* for DELAY */
|
||||
#include <sys/soundcard.h>
|
||||
|
||||
#include <dev/sound/midi/timer.h>
|
||||
|
||||
#define SEQ_CDEV_MAJOR MIDI_CDEV_MAJOR
|
||||
|
||||
/*
|
||||
@ -66,6 +68,13 @@
|
||||
#include <sys/poll.h>
|
||||
#define d_select_t d_poll_t
|
||||
|
||||
/* Return value from seq_playevent and timer event handers. */
|
||||
enum {
|
||||
MORE,
|
||||
TIMERARMED,
|
||||
QUEUEFULL
|
||||
};
|
||||
|
||||
typedef struct _seqdev_info seqdev_info;
|
||||
|
||||
/*
|
||||
@ -214,7 +223,7 @@ struct _seqdev_info {
|
||||
|
||||
/* The tailq entry of the next sequencer device. */
|
||||
TAILQ_ENTRY(_seqdev_info) sd_link;
|
||||
} ;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
@ -234,19 +243,30 @@ struct _seqdev_info {
|
||||
*/
|
||||
#define SEQ_BUFFSIZE (1024) /* XXX */
|
||||
|
||||
/*
|
||||
* some macros for debugging purposes
|
||||
* DDB/DEB to enable/disable debugging stuff
|
||||
* BVDDB to enable debugging when bootverbose
|
||||
*/
|
||||
#define DDB(x) x /* XXX */
|
||||
#define BVDDB(x) if (bootverbose) x
|
||||
|
||||
#ifndef DEB
|
||||
#define DEB(x)
|
||||
#endif
|
||||
|
||||
#define MIDI_DEV_SEQ 1 /* Sequencer output /dev/sequencer (FM
|
||||
synthesizer and MIDI output) */
|
||||
#define MIDI_DEV_MUSIC 8 /* Sequencer output /dev/music (FM
|
||||
synthesizer and MIDI output) */
|
||||
|
||||
#ifdef _KERNEL
|
||||
|
||||
extern midi_cmdtab cmdtab_seqioctl[];
|
||||
extern midi_cmdtab cmdtab_timer[];
|
||||
|
||||
void seq_timer(void *arg);
|
||||
int seq_copytoinput(void *arg, u_char *event, int len);
|
||||
|
||||
SYSCTL_DECL(_hw_midi_seq);
|
||||
|
||||
extern int seq_debug;
|
||||
#define SEQ_DEBUG(x) \
|
||||
do { \
|
||||
if (seq_debug) { \
|
||||
(x); \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
#endif /* _KERNEL */
|
||||
|
||||
|
||||
#endif /* _SEQUENCER_H_ */
|
||||
|
@ -224,9 +224,11 @@ csamidi_ioctl(dev_t i_dev, u_long cmd, caddr_t arg, int mode, struct thread *td)
|
||||
|
||||
unit = MIDIUNIT(i_dev);
|
||||
|
||||
MIDI_DEBUG(printf("csamidi_ioctl: unit %d, cmd %s.\n", unit, midi_cmdname(cmd, cmdtab_midiioctl)));
|
||||
|
||||
devinfo = get_mididev_info(i_dev, &unit);
|
||||
if (devinfo == NULL) {
|
||||
DEB(printf("csamidi_ioctl: unit %d is not configured.\n", unit));
|
||||
MIDI_DEBUG(printf("csamidi_ioctl: unit %d is not configured.\n", unit));
|
||||
return (ENXIO);
|
||||
}
|
||||
scp = devinfo->softc;
|
||||
@ -310,7 +312,7 @@ csamidi_callback(void *di, int reason)
|
||||
mtx_assert(&d->flagqueue_mtx, MA_OWNED);
|
||||
|
||||
if (d == NULL) {
|
||||
DEB(printf("csamidi_callback: device not configured.\n"));
|
||||
MIDI_DEBUG(printf("csamidi_callback: device not configured.\n"));
|
||||
return (ENXIO);
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user