summaryrefslogtreecommitdiffstats
path: root/sound/oss/emu10k1/midi.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/oss/emu10k1/midi.c')
-rw-r--r--sound/oss/emu10k1/midi.c614
1 files changed, 0 insertions, 614 deletions
diff --git a/sound/oss/emu10k1/midi.c b/sound/oss/emu10k1/midi.c
deleted file mode 100644
index df1e990..0000000
--- a/sound/oss/emu10k1/midi.c
+++ /dev/null
@@ -1,614 +0,0 @@
-/*
- **********************************************************************
- * midi.c - /dev/midi interface for emu10k1 driver
- * Copyright 1999, 2000 Creative Labs, Inc.
- *
- **********************************************************************
- *
- * Date Author Summary of changes
- * ---- ------ ------------------
- * October 20, 1999 Bertrand Lee base code release
- *
- **********************************************************************
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public
- * License along with this program; if not, write to the Free
- * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,
- * USA.
- *
- **********************************************************************
- */
-
-#include <linux/module.h>
-#include <linux/poll.h>
-#include <linux/slab.h>
-#include <linux/sched.h>
-#include <linux/smp_lock.h>
-#include <asm/uaccess.h>
-
-#include "hwaccess.h"
-#include "cardmo.h"
-#include "cardmi.h"
-#include "midi.h"
-
-#ifdef EMU10K1_SEQUENCER
-#include "../sound_config.h"
-#endif
-
-static DEFINE_SPINLOCK(midi_spinlock);
-
-static void init_midi_hdr(struct midi_hdr *midihdr)
-{
- midihdr->bufferlength = MIDIIN_BUFLEN;
- midihdr->bytesrecorded = 0;
- midihdr->flags = 0;
-}
-
-static int midiin_add_buffer(struct emu10k1_mididevice *midi_dev, struct midi_hdr **midihdrptr)
-{
- struct midi_hdr *midihdr;
-
- if ((midihdr = kmalloc(sizeof(struct midi_hdr), GFP_KERNEL)) == NULL) {
- ERROR();
- return -EINVAL;
- }
-
- init_midi_hdr(midihdr);
-
- midihdr->data = kmalloc(MIDIIN_BUFLEN, GFP_KERNEL);
- if (!midihdr->data) {
- ERROR();
- kfree(midihdr);
- return -1;
- }
-
- if (emu10k1_mpuin_add_buffer(midi_dev->card->mpuin, midihdr) < 0) {
- ERROR();
- kfree(midihdr->data);
- kfree(midihdr);
- return -1;
- }
-
- *midihdrptr = midihdr;
- list_add_tail(&midihdr->list, &midi_dev->mid_hdrs);
-
- return 0;
-}
-
-static int emu10k1_midi_open(struct inode *inode, struct file *file)
-{
- int minor = iminor(inode);
- struct emu10k1_card *card = NULL;
- struct emu10k1_mididevice *midi_dev;
- struct list_head *entry;
-
- DPF(2, "emu10k1_midi_open()\n");
-
- /* Check for correct device to open */
- list_for_each(entry, &emu10k1_devs) {
- card = list_entry(entry, struct emu10k1_card, list);
-
- if (card->midi_dev == minor)
- goto match;
- }
-
- return -ENODEV;
-
-match:
-#ifdef EMU10K1_SEQUENCER
- if (card->seq_mididev) /* card is opened by sequencer */
- return -EBUSY;
-#endif
-
- /* Wait for device to become free */
- mutex_lock(&card->open_sem);
- while (card->open_mode & (file->f_mode << FMODE_MIDI_SHIFT)) {
- if (file->f_flags & O_NONBLOCK) {
- mutex_unlock(&card->open_sem);
- return -EBUSY;
- }
-
- mutex_unlock(&card->open_sem);
- interruptible_sleep_on(&card->open_wait);
-
- if (signal_pending(current)) {
- return -ERESTARTSYS;
- }
-
- mutex_lock(&card->open_sem);
- }
-
- if ((midi_dev = kmalloc(sizeof(*midi_dev), GFP_KERNEL)) == NULL)
- return -EINVAL;
-
- midi_dev->card = card;
- midi_dev->mistate = MIDIIN_STATE_STOPPED;
- init_waitqueue_head(&midi_dev->oWait);
- init_waitqueue_head(&midi_dev->iWait);
- midi_dev->ird = 0;
- midi_dev->iwr = 0;
- midi_dev->icnt = 0;
- INIT_LIST_HEAD(&midi_dev->mid_hdrs);
-
- if (file->f_mode & FMODE_READ) {
- struct midi_openinfo dsCardMidiOpenInfo;
- struct midi_hdr *midihdr1;
- struct midi_hdr *midihdr2;
-
- dsCardMidiOpenInfo.refdata = (unsigned long) midi_dev;
-
- if (emu10k1_mpuin_open(card, &dsCardMidiOpenInfo) < 0) {
- ERROR();
- kfree(midi_dev);
- return -ENODEV;
- }
-
- /* Add two buffers to receive sysex buffer */
- if (midiin_add_buffer(midi_dev, &midihdr1) < 0) {
- kfree(midi_dev);
- return -ENODEV;
- }
-
- if (midiin_add_buffer(midi_dev, &midihdr2) < 0) {
- list_del(&midihdr1->list);
- kfree(midihdr1->data);
- kfree(midihdr1);
- kfree(midi_dev);
- return -ENODEV;
- }
- }
-
- if (file->f_mode & FMODE_WRITE) {
- struct midi_openinfo dsCardMidiOpenInfo;
-
- dsCardMidiOpenInfo.refdata = (unsigned long) midi_dev;
-
- if (emu10k1_mpuout_open(card, &dsCardMidiOpenInfo) < 0) {
- ERROR();
- kfree(midi_dev);
- return -ENODEV;
- }
- }
-
- file->private_data = (void *) midi_dev;
-
- card->open_mode |= (file->f_mode << FMODE_MIDI_SHIFT) & (FMODE_MIDI_READ | FMODE_MIDI_WRITE);
-
- mutex_unlock(&card->open_sem);
-
- return nonseekable_open(inode, file);
-}
-
-static int emu10k1_midi_release(struct inode *inode, struct file *file)
-{
- struct emu10k1_mididevice *midi_dev = (struct emu10k1_mididevice *) file->private_data;
- struct emu10k1_card *card;
-
- lock_kernel();
-
- card = midi_dev->card;
- DPF(2, "emu10k1_midi_release()\n");
-
- if (file->f_mode & FMODE_WRITE) {
- if (!(file->f_flags & O_NONBLOCK)) {
-
- while (!signal_pending(current) && (card->mpuout->firstmidiq != NULL)) {
- DPF(4, "Cannot close - buffers not empty\n");
-
- interruptible_sleep_on(&midi_dev->oWait);
-
- }
- }
-
- emu10k1_mpuout_close(card);
- }
-
- if (file->f_mode & FMODE_READ) {
- struct midi_hdr *midihdr;
-
- if (midi_dev->mistate == MIDIIN_STATE_STARTED) {
- emu10k1_mpuin_stop(card);
- midi_dev->mistate = MIDIIN_STATE_STOPPED;
- }
-
- emu10k1_mpuin_reset(card);
- emu10k1_mpuin_close(card);
-
- while (!list_empty(&midi_dev->mid_hdrs)) {
- midihdr = list_entry(midi_dev->mid_hdrs.next, struct midi_hdr, list);
-
- list_del(midi_dev->mid_hdrs.next);
- kfree(midihdr->data);
- kfree(midihdr);
- }
- }
-
- kfree(midi_dev);
-
- mutex_lock(&card->open_sem);
- card->open_mode &= ~((file->f_mode << FMODE_MIDI_SHIFT) & (FMODE_MIDI_READ | FMODE_MIDI_WRITE));
- mutex_unlock(&card->open_sem);
- wake_up_interruptible(&card->open_wait);
-
- unlock_kernel();
-
- return 0;
-}
-
-static ssize_t emu10k1_midi_read(struct file *file, char __user *buffer, size_t count, loff_t * pos)
-{
- struct emu10k1_mididevice *midi_dev = (struct emu10k1_mididevice *) file->private_data;
- ssize_t ret = 0;
- u16 cnt;
- unsigned long flags;
-
- DPD(4, "emu10k1_midi_read(), count %#x\n", (u32) count);
-
- if (!access_ok(VERIFY_WRITE, buffer, count))
- return -EFAULT;
-
- if (midi_dev->mistate == MIDIIN_STATE_STOPPED) {
- if (emu10k1_mpuin_start(midi_dev->card) < 0) {
- ERROR();
- return -EINVAL;
- }
-
- midi_dev->mistate = MIDIIN_STATE_STARTED;
- }
-
- while (count > 0) {
- cnt = MIDIIN_BUFLEN - midi_dev->ird;
-
- spin_lock_irqsave(&midi_spinlock, flags);
-
- if (midi_dev->icnt < cnt)
- cnt = midi_dev->icnt;
-
- spin_unlock_irqrestore(&midi_spinlock, flags);
-
- if (cnt > count)
- cnt = count;
-
- if (cnt <= 0) {
- if (file->f_flags & O_NONBLOCK)
- return ret ? ret : -EAGAIN;
- DPF(2, " Go to sleep...\n");
-
- interruptible_sleep_on(&midi_dev->iWait);
-
- if (signal_pending(current))
- return ret ? ret : -ERESTARTSYS;
-
- continue;
- }
-
- if (copy_to_user(buffer, midi_dev->iBuf + midi_dev->ird, cnt)) {
- ERROR();
- return ret ? ret : -EFAULT;
- }
-
- midi_dev->ird += cnt;
- midi_dev->ird %= MIDIIN_BUFLEN;
-
- spin_lock_irqsave(&midi_spinlock, flags);
-
- midi_dev->icnt -= cnt;
-
- spin_unlock_irqrestore(&midi_spinlock, flags);
-
- count -= cnt;
- buffer += cnt;
- ret += cnt;
-
- if (midi_dev->icnt == 0)
- break;
- }
-
- return ret;
-}
-
-static ssize_t emu10k1_midi_write(struct file *file, const char __user *buffer, size_t count, loff_t * pos)
-{
- struct emu10k1_mididevice *midi_dev = (struct emu10k1_mididevice *) file->private_data;
- struct midi_hdr *midihdr;
- unsigned long flags;
-
- DPD(4, "emu10k1_midi_write(), count=%#x\n", (u32) count);
-
- if (!access_ok(VERIFY_READ, buffer, count))
- return -EFAULT;
-
- if ((midihdr = kmalloc(sizeof(struct midi_hdr), GFP_KERNEL)) == NULL)
- return -EINVAL;
-
- midihdr->bufferlength = count;
- midihdr->bytesrecorded = 0;
- midihdr->flags = 0;
-
- midihdr->data = kmalloc(count, GFP_KERNEL);
- if (!midihdr->data) {
- ERROR();
- kfree(midihdr);
- return -EINVAL;
- }
-
- if (copy_from_user(midihdr->data, buffer, count)) {
- kfree(midihdr->data);
- kfree(midihdr);
- return -EFAULT;
- }
-
- spin_lock_irqsave(&midi_spinlock, flags);
-
- if (emu10k1_mpuout_add_buffer(midi_dev->card, midihdr) < 0) {
- ERROR();
- kfree(midihdr->data);
- kfree(midihdr);
- spin_unlock_irqrestore(&midi_spinlock, flags);
- return -EINVAL;
- }
-
- spin_unlock_irqrestore(&midi_spinlock, flags);
-
- return count;
-}
-
-static unsigned int emu10k1_midi_poll(struct file *file, struct poll_table_struct *wait)
-{
- struct emu10k1_mididevice *midi_dev = (struct emu10k1_mididevice *) file->private_data;
- unsigned long flags;
- unsigned int mask = 0;
-
- DPF(4, "emu10k1_midi_poll() called\n");
-
- if (file->f_mode & FMODE_WRITE)
- poll_wait(file, &midi_dev->oWait, wait);
-
- if (file->f_mode & FMODE_READ)
- poll_wait(file, &midi_dev->iWait, wait);
-
- spin_lock_irqsave(&midi_spinlock, flags);
-
- if (file->f_mode & FMODE_WRITE)
- mask |= POLLOUT | POLLWRNORM;
-
- if (file->f_mode & FMODE_READ) {
- if (midi_dev->mistate == MIDIIN_STATE_STARTED)
- if (midi_dev->icnt > 0)
- mask |= POLLIN | POLLRDNORM;
- }
-
- spin_unlock_irqrestore(&midi_spinlock, flags);
-
- return mask;
-}
-
-int emu10k1_midi_callback(unsigned long msg, unsigned long refdata, unsigned long *pmsg)
-{
- struct emu10k1_mididevice *midi_dev = (struct emu10k1_mididevice *) refdata;
- struct midi_hdr *midihdr = NULL;
- unsigned long flags;
- int i;
-
- DPF(4, "emu10k1_midi_callback()\n");
-
- spin_lock_irqsave(&midi_spinlock, flags);
-
- switch (msg) {
- case ICARDMIDI_OUTLONGDATA:
- midihdr = (struct midi_hdr *) pmsg[2];
-
- kfree(midihdr->data);
- kfree(midihdr);
- wake_up_interruptible(&midi_dev->oWait);
-
- break;
-
- case ICARDMIDI_INLONGDATA:
- midihdr = (struct midi_hdr *) pmsg[2];
-
- for (i = 0; i < midihdr->bytesrecorded; i++) {
- midi_dev->iBuf[midi_dev->iwr++] = midihdr->data[i];
- midi_dev->iwr %= MIDIIN_BUFLEN;
- }
-
- midi_dev->icnt += midihdr->bytesrecorded;
-
- if (midi_dev->mistate == MIDIIN_STATE_STARTED) {
- init_midi_hdr(midihdr);
- emu10k1_mpuin_add_buffer(midi_dev->card->mpuin, midihdr);
- wake_up_interruptible(&midi_dev->iWait);
- }
- break;
-
- case ICARDMIDI_INDATA:
- {
- u8 *pBuf = (u8 *) & pmsg[1];
- u16 bytesvalid = pmsg[2];
-
- for (i = 0; i < bytesvalid; i++) {
- midi_dev->iBuf[midi_dev->iwr++] = pBuf[i];
- midi_dev->iwr %= MIDIIN_BUFLEN;
- }
-
- midi_dev->icnt += bytesvalid;
- }
-
- wake_up_interruptible(&midi_dev->iWait);
- break;
-
- default: /* Unknown message */
- spin_unlock_irqrestore(&midi_spinlock, flags);
- return -1;
- }
-
- spin_unlock_irqrestore(&midi_spinlock, flags);
-
- return 0;
-}
-
-/* MIDI file operations */
-const struct file_operations emu10k1_midi_fops = {
- .owner = THIS_MODULE,
- .read = emu10k1_midi_read,
- .write = emu10k1_midi_write,
- .poll = emu10k1_midi_poll,
- .open = emu10k1_midi_open,
- .release = emu10k1_midi_release,
-};
-
-
-#ifdef EMU10K1_SEQUENCER
-
-/* functions used for sequencer access */
-
-int emu10k1_seq_midi_open(int dev, int mode,
- void (*input) (int dev, unsigned char data),
- void (*output) (int dev))
-{
- struct emu10k1_card *card;
- struct midi_openinfo dsCardMidiOpenInfo;
- struct emu10k1_mididevice *midi_dev;
-
- if (midi_devs[dev] == NULL || midi_devs[dev]->devc == NULL)
- return -EINVAL;
-
- card = midi_devs[dev]->devc;
-
- if (card->open_mode) /* card is opened native */
- return -EBUSY;
-
- DPF(2, "emu10k1_seq_midi_open()\n");
-
- if ((midi_dev = kmalloc(sizeof(*midi_dev), GFP_KERNEL)) == NULL)
- return -EINVAL;
-
- midi_dev->card = card;
- midi_dev->mistate = MIDIIN_STATE_STOPPED;
- init_waitqueue_head(&midi_dev->oWait);
- init_waitqueue_head(&midi_dev->iWait);
- midi_dev->ird = 0;
- midi_dev->iwr = 0;
- midi_dev->icnt = 0;
- INIT_LIST_HEAD(&midi_dev->mid_hdrs);
-
- dsCardMidiOpenInfo.refdata = (unsigned long) midi_dev;
-
- if (emu10k1_mpuout_open(card, &dsCardMidiOpenInfo) < 0) {
- ERROR();
- return -ENODEV;
- }
-
- card->seq_mididev = midi_dev;
-
- return 0;
-}
-
-void emu10k1_seq_midi_close(int dev)
-{
- struct emu10k1_card *card;
-
- DPF(2, "emu10k1_seq_midi_close()\n");
- if (midi_devs[dev] == NULL || midi_devs[dev]->devc == NULL)
- return;
-
- card = midi_devs[dev]->devc;
- emu10k1_mpuout_close(card);
-
- kfree(card->seq_mididev);
- card->seq_mididev = NULL;
-}
-
-int emu10k1_seq_midi_out(int dev, unsigned char midi_byte)
-{
- struct emu10k1_card *card;
- struct midi_hdr *midihdr;
- unsigned long flags;
-
- if (midi_devs[dev] == NULL || midi_devs[dev]->devc == NULL)
- return -EINVAL;
-
- card = midi_devs[dev]->devc;
-
- if ((midihdr = kmalloc(sizeof(struct midi_hdr), GFP_KERNEL)) == NULL)
- return -EINVAL;
-
- midihdr->bufferlength = 1;
- midihdr->bytesrecorded = 0;
- midihdr->flags = 0;
-
- midihdr->data = kmalloc(1, GFP_KERNEL);
- if (!midihdr->data) {
- ERROR();
- kfree(midihdr);
- return -EINVAL;
- }
-
- *(midihdr->data) = midi_byte;
-
- spin_lock_irqsave(&midi_spinlock, flags);
-
- if (emu10k1_mpuout_add_buffer(card, midihdr) < 0) {
- ERROR();
- kfree(midihdr->data);
- kfree(midihdr);
- spin_unlock_irqrestore(&midi_spinlock, flags);
- return -EINVAL;
- }
-
- spin_unlock_irqrestore(&midi_spinlock, flags);
-
- return 1;
-}
-
-int emu10k1_seq_midi_start_read(int dev)
-{
- return 0;
-}
-
-int emu10k1_seq_midi_end_read(int dev)
-{
- return 0;
-}
-
-void emu10k1_seq_midi_kick(int dev)
-{
-}
-
-int emu10k1_seq_midi_buffer_status(int dev)
-{
- int count;
- struct midi_queue *queue;
- struct emu10k1_card *card;
-
- if (midi_devs[dev] == NULL || midi_devs[dev]->devc == NULL)
- return -EINVAL;
-
- count = 0;
-
- card = midi_devs[dev]->devc;
- queue = card->mpuout->firstmidiq;
-
- while (queue != NULL) {
- count++;
- if (queue == card->mpuout->lastmidiq)
- break;
-
- queue = queue->next;
- }
-
- return count;
-}
-
-#endif
-
OpenPOWER on IntegriCloud