]> pilppa.org Git - linux-2.6-omap-h63xx.git/blob - sound/oss/emu10k1/midi.c
Merge master.kernel.org:/pub/scm/linux/kernel/git/wim/linux-2.6-watchdog
[linux-2.6-omap-h63xx.git] / sound / oss / emu10k1 / midi.c
1 /*
2  **********************************************************************
3  *     midi.c - /dev/midi interface for emu10k1 driver
4  *     Copyright 1999, 2000 Creative Labs, Inc.
5  *
6  **********************************************************************
7  *
8  *     Date                 Author          Summary of changes
9  *     ----                 ------          ------------------
10  *     October 20, 1999     Bertrand Lee    base code release
11  *
12  **********************************************************************
13  *
14  *     This program is free software; you can redistribute it and/or
15  *     modify it under the terms of the GNU General Public License as
16  *     published by the Free Software Foundation; either version 2 of
17  *     the License, or (at your option) any later version.
18  *
19  *     This program is distributed in the hope that it will be useful,
20  *     but WITHOUT ANY WARRANTY; without even the implied warranty of
21  *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22  *     GNU General Public License for more details.
23  *
24  *     You should have received a copy of the GNU General Public
25  *     License along with this program; if not, write to the Free
26  *     Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,
27  *     USA.
28  *
29  **********************************************************************
30  */
31
32 #include <linux/module.h>
33 #include <linux/poll.h>
34 #include <linux/slab.h>
35 #include <linux/sched.h>
36 #include <linux/smp_lock.h>
37 #include <asm/uaccess.h>
38
39 #include "hwaccess.h"
40 #include "cardmo.h"
41 #include "cardmi.h"
42 #include "midi.h"
43
44 #ifdef EMU10K1_SEQUENCER
45 #include "../sound_config.h"
46 #endif
47
48 static DEFINE_SPINLOCK(midi_spinlock);
49
50 static void init_midi_hdr(struct midi_hdr *midihdr)
51 {
52         midihdr->bufferlength = MIDIIN_BUFLEN;
53         midihdr->bytesrecorded = 0;
54         midihdr->flags = 0;
55 }
56
57 static int midiin_add_buffer(struct emu10k1_mididevice *midi_dev, struct midi_hdr **midihdrptr)
58 {
59         struct midi_hdr *midihdr;
60
61         if ((midihdr = (struct midi_hdr *) kmalloc(sizeof(struct midi_hdr), GFP_KERNEL)) == NULL) {
62                 ERROR();
63                 return -EINVAL;
64         }
65
66         init_midi_hdr(midihdr);
67
68         midihdr->data = kmalloc(MIDIIN_BUFLEN, GFP_KERNEL);
69         if (!midihdr->data) {
70                 ERROR();
71                 kfree(midihdr);
72                 return -1;
73         }
74
75         if (emu10k1_mpuin_add_buffer(midi_dev->card->mpuin, midihdr) < 0) {
76                 ERROR();
77                 kfree(midihdr->data);
78                 kfree(midihdr);
79                 return -1;
80         }
81
82         *midihdrptr = midihdr;
83         list_add_tail(&midihdr->list, &midi_dev->mid_hdrs);
84
85         return 0;
86 }
87
88 static int emu10k1_midi_open(struct inode *inode, struct file *file)
89 {
90         int minor = iminor(inode);
91         struct emu10k1_card *card = NULL;
92         struct emu10k1_mididevice *midi_dev;
93         struct list_head *entry;
94
95         DPF(2, "emu10k1_midi_open()\n");
96
97         /* Check for correct device to open */
98         list_for_each(entry, &emu10k1_devs) {
99                 card = list_entry(entry, struct emu10k1_card, list);
100
101                 if (card->midi_dev == minor)
102                         goto match;
103         }
104
105         return -ENODEV;
106
107 match:
108 #ifdef EMU10K1_SEQUENCER
109         if (card->seq_mididev)  /* card is opened by sequencer */
110                 return -EBUSY;
111 #endif
112
113         /* Wait for device to become free */
114         mutex_lock(&card->open_sem);
115         while (card->open_mode & (file->f_mode << FMODE_MIDI_SHIFT)) {
116                 if (file->f_flags & O_NONBLOCK) {
117                         mutex_unlock(&card->open_sem);
118                         return -EBUSY;
119                 }
120
121                 mutex_unlock(&card->open_sem);
122                 interruptible_sleep_on(&card->open_wait);
123
124                 if (signal_pending(current)) {
125                         return -ERESTARTSYS;
126                 }
127
128                 mutex_lock(&card->open_sem);
129         }
130
131         if ((midi_dev = (struct emu10k1_mididevice *) kmalloc(sizeof(*midi_dev), GFP_KERNEL)) == NULL)
132                 return -EINVAL;
133
134         midi_dev->card = card;
135         midi_dev->mistate = MIDIIN_STATE_STOPPED;
136         init_waitqueue_head(&midi_dev->oWait);
137         init_waitqueue_head(&midi_dev->iWait);
138         midi_dev->ird = 0;
139         midi_dev->iwr = 0;
140         midi_dev->icnt = 0;
141         INIT_LIST_HEAD(&midi_dev->mid_hdrs);
142
143         if (file->f_mode & FMODE_READ) {
144                 struct midi_openinfo dsCardMidiOpenInfo;
145                 struct midi_hdr *midihdr1;
146                 struct midi_hdr *midihdr2;
147
148                 dsCardMidiOpenInfo.refdata = (unsigned long) midi_dev;
149
150                 if (emu10k1_mpuin_open(card, &dsCardMidiOpenInfo) < 0) {
151                         ERROR();
152                         kfree(midi_dev);
153                         return -ENODEV;
154                 }
155
156                 /* Add two buffers to receive sysex buffer */
157                 if (midiin_add_buffer(midi_dev, &midihdr1) < 0) {
158                         kfree(midi_dev);
159                         return -ENODEV;
160                 }
161
162                 if (midiin_add_buffer(midi_dev, &midihdr2) < 0) {
163                         list_del(&midihdr1->list);
164                         kfree(midihdr1->data);
165                         kfree(midihdr1);
166                         kfree(midi_dev);
167                         return -ENODEV;
168                 }
169         }
170
171         if (file->f_mode & FMODE_WRITE) {
172                 struct midi_openinfo dsCardMidiOpenInfo;
173
174                 dsCardMidiOpenInfo.refdata = (unsigned long) midi_dev;
175
176                 if (emu10k1_mpuout_open(card, &dsCardMidiOpenInfo) < 0) {
177                         ERROR();
178                         kfree(midi_dev);
179                         return -ENODEV;
180                 }
181         }
182
183         file->private_data = (void *) midi_dev;
184
185         card->open_mode |= (file->f_mode << FMODE_MIDI_SHIFT) & (FMODE_MIDI_READ | FMODE_MIDI_WRITE);
186
187         mutex_unlock(&card->open_sem);
188
189         return nonseekable_open(inode, file);
190 }
191
192 static int emu10k1_midi_release(struct inode *inode, struct file *file)
193 {
194         struct emu10k1_mididevice *midi_dev = (struct emu10k1_mididevice *) file->private_data;
195         struct emu10k1_card *card;
196
197         lock_kernel();
198
199         card = midi_dev->card;
200         DPF(2, "emu10k1_midi_release()\n");
201
202         if (file->f_mode & FMODE_WRITE) {
203                 if (!(file->f_flags & O_NONBLOCK)) {
204
205                         while (!signal_pending(current) && (card->mpuout->firstmidiq != NULL)) {
206                                 DPF(4, "Cannot close - buffers not empty\n");
207
208                                 interruptible_sleep_on(&midi_dev->oWait);
209
210                         }
211                 }
212
213                 emu10k1_mpuout_close(card);
214         }
215
216         if (file->f_mode & FMODE_READ) {
217                 struct midi_hdr *midihdr;
218
219                 if (midi_dev->mistate == MIDIIN_STATE_STARTED) {
220                         emu10k1_mpuin_stop(card);
221                         midi_dev->mistate = MIDIIN_STATE_STOPPED;
222                 }
223
224                 emu10k1_mpuin_reset(card);
225                 emu10k1_mpuin_close(card);
226
227                 while (!list_empty(&midi_dev->mid_hdrs)) {
228                         midihdr = list_entry(midi_dev->mid_hdrs.next, struct midi_hdr, list);
229
230                         list_del(midi_dev->mid_hdrs.next);
231                         kfree(midihdr->data);
232                         kfree(midihdr);
233                 }
234         }
235
236         kfree(midi_dev);
237
238         mutex_lock(&card->open_sem);
239         card->open_mode &= ~((file->f_mode << FMODE_MIDI_SHIFT) & (FMODE_MIDI_READ | FMODE_MIDI_WRITE));
240         mutex_unlock(&card->open_sem);
241         wake_up_interruptible(&card->open_wait);
242
243         unlock_kernel();
244
245         return 0;
246 }
247
248 static ssize_t emu10k1_midi_read(struct file *file, char __user *buffer, size_t count, loff_t * pos)
249 {
250         struct emu10k1_mididevice *midi_dev = (struct emu10k1_mididevice *) file->private_data;
251         ssize_t ret = 0;
252         u16 cnt;
253         unsigned long flags;
254
255         DPD(4, "emu10k1_midi_read(), count %#x\n", (u32) count);
256
257         if (!access_ok(VERIFY_WRITE, buffer, count))
258                 return -EFAULT;
259
260         if (midi_dev->mistate == MIDIIN_STATE_STOPPED) {
261                 if (emu10k1_mpuin_start(midi_dev->card) < 0) {
262                         ERROR();
263                         return -EINVAL;
264                 }
265
266                 midi_dev->mistate = MIDIIN_STATE_STARTED;
267         }
268
269         while (count > 0) {
270                 cnt = MIDIIN_BUFLEN - midi_dev->ird;
271
272                 spin_lock_irqsave(&midi_spinlock, flags);
273
274                 if (midi_dev->icnt < cnt)
275                         cnt = midi_dev->icnt;
276
277                 spin_unlock_irqrestore(&midi_spinlock, flags);
278
279                 if (cnt > count)
280                         cnt = count;
281
282                 if (cnt <= 0) {
283                         if (file->f_flags & O_NONBLOCK)
284                                 return ret ? ret : -EAGAIN;
285                         DPF(2, " Go to sleep...\n");
286
287                         interruptible_sleep_on(&midi_dev->iWait);
288
289                         if (signal_pending(current))
290                                 return ret ? ret : -ERESTARTSYS;
291
292                         continue;
293                 }
294
295                 if (copy_to_user(buffer, midi_dev->iBuf + midi_dev->ird, cnt)) {
296                         ERROR();
297                         return ret ? ret : -EFAULT;
298                 }
299
300                 midi_dev->ird += cnt;
301                 midi_dev->ird %= MIDIIN_BUFLEN;
302
303                 spin_lock_irqsave(&midi_spinlock, flags);
304
305                 midi_dev->icnt -= cnt;
306
307                 spin_unlock_irqrestore(&midi_spinlock, flags);
308
309                 count -= cnt;
310                 buffer += cnt;
311                 ret += cnt;
312
313                 if (midi_dev->icnt == 0)
314                         break;
315         }
316
317         return ret;
318 }
319
320 static ssize_t emu10k1_midi_write(struct file *file, const char __user *buffer, size_t count, loff_t * pos)
321 {
322         struct emu10k1_mididevice *midi_dev = (struct emu10k1_mididevice *) file->private_data;
323         struct midi_hdr *midihdr;
324         unsigned long flags;
325
326         DPD(4, "emu10k1_midi_write(), count=%#x\n", (u32) count);
327
328         if (!access_ok(VERIFY_READ, buffer, count))
329                 return -EFAULT;
330
331         if ((midihdr = (struct midi_hdr *) kmalloc(sizeof(struct midi_hdr), GFP_KERNEL)) == NULL)
332                 return -EINVAL;
333
334         midihdr->bufferlength = count;
335         midihdr->bytesrecorded = 0;
336         midihdr->flags = 0;
337
338         midihdr->data = kmalloc(count, GFP_KERNEL);
339         if (!midihdr->data) {
340                 ERROR();
341                 kfree(midihdr);
342                 return -EINVAL;
343         }
344
345         if (copy_from_user(midihdr->data, buffer, count)) {
346                 kfree(midihdr->data);
347                 kfree(midihdr);
348                 return -EFAULT;
349         }
350
351         spin_lock_irqsave(&midi_spinlock, flags);
352
353         if (emu10k1_mpuout_add_buffer(midi_dev->card, midihdr) < 0) {
354                 ERROR();
355                 kfree(midihdr->data);
356                 kfree(midihdr);
357                 spin_unlock_irqrestore(&midi_spinlock, flags);
358                 return -EINVAL;
359         }
360
361         spin_unlock_irqrestore(&midi_spinlock, flags);
362
363         return count;
364 }
365
366 static unsigned int emu10k1_midi_poll(struct file *file, struct poll_table_struct *wait)
367 {
368         struct emu10k1_mididevice *midi_dev = (struct emu10k1_mididevice *) file->private_data;
369         unsigned long flags;
370         unsigned int mask = 0;
371
372         DPF(4, "emu10k1_midi_poll() called\n");
373
374         if (file->f_mode & FMODE_WRITE)
375                 poll_wait(file, &midi_dev->oWait, wait);
376
377         if (file->f_mode & FMODE_READ)
378                 poll_wait(file, &midi_dev->iWait, wait);
379
380         spin_lock_irqsave(&midi_spinlock, flags);
381
382         if (file->f_mode & FMODE_WRITE)
383                 mask |= POLLOUT | POLLWRNORM;
384
385         if (file->f_mode & FMODE_READ) {
386                 if (midi_dev->mistate == MIDIIN_STATE_STARTED)
387                         if (midi_dev->icnt > 0)
388                                 mask |= POLLIN | POLLRDNORM;
389         }
390
391         spin_unlock_irqrestore(&midi_spinlock, flags);
392
393         return mask;
394 }
395
396 int emu10k1_midi_callback(unsigned long msg, unsigned long refdata, unsigned long *pmsg)
397 {
398         struct emu10k1_mididevice *midi_dev = (struct emu10k1_mididevice *) refdata;
399         struct midi_hdr *midihdr = NULL;
400         unsigned long flags;
401         int i;
402
403         DPF(4, "emu10k1_midi_callback()\n");
404
405         spin_lock_irqsave(&midi_spinlock, flags);
406
407         switch (msg) {
408         case ICARDMIDI_OUTLONGDATA:
409                 midihdr = (struct midi_hdr *) pmsg[2];
410
411                 kfree(midihdr->data);
412                 kfree(midihdr);
413                 wake_up_interruptible(&midi_dev->oWait);
414
415                 break;
416
417         case ICARDMIDI_INLONGDATA:
418                 midihdr = (struct midi_hdr *) pmsg[2];
419
420                 for (i = 0; i < midihdr->bytesrecorded; i++) {
421                         midi_dev->iBuf[midi_dev->iwr++] = midihdr->data[i];
422                         midi_dev->iwr %= MIDIIN_BUFLEN;
423                 }
424
425                 midi_dev->icnt += midihdr->bytesrecorded;
426
427                 if (midi_dev->mistate == MIDIIN_STATE_STARTED) {
428                         init_midi_hdr(midihdr);
429                         emu10k1_mpuin_add_buffer(midi_dev->card->mpuin, midihdr);
430                         wake_up_interruptible(&midi_dev->iWait);
431                 }
432                 break;
433
434         case ICARDMIDI_INDATA:
435                 {
436                         u8 *pBuf = (u8 *) & pmsg[1];
437                         u16 bytesvalid = pmsg[2];
438
439                         for (i = 0; i < bytesvalid; i++) {
440                                 midi_dev->iBuf[midi_dev->iwr++] = pBuf[i];
441                                 midi_dev->iwr %= MIDIIN_BUFLEN;
442                         }
443
444                         midi_dev->icnt += bytesvalid;
445                 }
446
447                 wake_up_interruptible(&midi_dev->iWait);
448                 break;
449
450         default:                /* Unknown message */
451                 spin_unlock_irqrestore(&midi_spinlock, flags);
452                 return -1;
453         }
454
455         spin_unlock_irqrestore(&midi_spinlock, flags);
456
457         return 0;
458 }
459
460 /* MIDI file operations */
461 struct file_operations emu10k1_midi_fops = {
462         .owner          = THIS_MODULE,
463         .read           = emu10k1_midi_read,
464         .write          = emu10k1_midi_write,
465         .poll           = emu10k1_midi_poll,
466         .open           = emu10k1_midi_open,
467         .release        = emu10k1_midi_release,
468 };
469
470
471 #ifdef EMU10K1_SEQUENCER
472
473 /* functions used for sequencer access */
474
475 int emu10k1_seq_midi_open(int dev, int mode,
476                                 void (*input) (int dev, unsigned char data),
477                                 void (*output) (int dev))
478 {
479         struct emu10k1_card *card;
480         struct midi_openinfo dsCardMidiOpenInfo;
481         struct emu10k1_mididevice *midi_dev;
482
483         if (midi_devs[dev] == NULL || midi_devs[dev]->devc == NULL)
484                 return -EINVAL;
485
486         card = midi_devs[dev]->devc;
487
488         if (card->open_mode)            /* card is opened native */
489                 return -EBUSY;
490                         
491         DPF(2, "emu10k1_seq_midi_open()\n");
492         
493         if ((midi_dev = (struct emu10k1_mididevice *) kmalloc(sizeof(*midi_dev), GFP_KERNEL)) == NULL)
494                 return -EINVAL;
495
496         midi_dev->card = card;
497         midi_dev->mistate = MIDIIN_STATE_STOPPED;
498         init_waitqueue_head(&midi_dev->oWait);
499         init_waitqueue_head(&midi_dev->iWait);
500         midi_dev->ird = 0;
501         midi_dev->iwr = 0;
502         midi_dev->icnt = 0;
503         INIT_LIST_HEAD(&midi_dev->mid_hdrs);
504
505         dsCardMidiOpenInfo.refdata = (unsigned long) midi_dev;
506
507         if (emu10k1_mpuout_open(card, &dsCardMidiOpenInfo) < 0) {
508                 ERROR();
509                 return -ENODEV;
510         }
511
512         card->seq_mididev = midi_dev;
513                 
514         return 0;
515 }
516
517 void emu10k1_seq_midi_close(int dev)
518 {
519         struct emu10k1_card *card;
520
521         DPF(2, "emu10k1_seq_midi_close()\n");
522         if (midi_devs[dev] == NULL || midi_devs[dev]->devc == NULL)
523                 return;
524
525         card = midi_devs[dev]->devc;
526         emu10k1_mpuout_close(card);
527
528         kfree(card->seq_mididev);
529         card->seq_mididev = NULL;
530 }
531
532 int emu10k1_seq_midi_out(int dev, unsigned char midi_byte)
533 {
534         struct emu10k1_card *card;
535         struct midi_hdr *midihdr;
536         unsigned long flags;
537
538         if (midi_devs[dev] == NULL || midi_devs[dev]->devc == NULL)
539                 return -EINVAL;
540
541         card = midi_devs[dev]->devc;
542
543         if ((midihdr = (struct midi_hdr *) kmalloc(sizeof(struct midi_hdr), GFP_KERNEL)) == NULL)
544                 return -EINVAL;
545
546         midihdr->bufferlength = 1;
547         midihdr->bytesrecorded = 0;
548         midihdr->flags = 0;
549
550         midihdr->data = kmalloc(1, GFP_KERNEL);
551         if (!midihdr->data) {
552                 ERROR();
553                 kfree(midihdr);
554                 return -EINVAL;
555         }
556
557         *(midihdr->data) = midi_byte;
558         
559         spin_lock_irqsave(&midi_spinlock, flags);
560
561         if (emu10k1_mpuout_add_buffer(card, midihdr) < 0) {
562                 ERROR();
563                 kfree(midihdr->data);
564                 kfree(midihdr);
565                 spin_unlock_irqrestore(&midi_spinlock, flags);
566                 return -EINVAL;
567         }
568
569         spin_unlock_irqrestore(&midi_spinlock, flags);
570
571         return 1;
572 }
573
574 int emu10k1_seq_midi_start_read(int dev)
575 {
576         return 0;
577 }
578
579 int emu10k1_seq_midi_end_read(int dev)
580 {
581         return 0;
582 }
583
584 void emu10k1_seq_midi_kick(int dev)
585 {
586 }
587
588 int emu10k1_seq_midi_buffer_status(int dev)
589 {
590         int count;
591         struct midi_queue *queue;
592         struct emu10k1_card *card;
593
594         if (midi_devs[dev] == NULL || midi_devs[dev]->devc == NULL)
595                 return -EINVAL;
596
597         count = 0;
598
599         card = midi_devs[dev]->devc;
600         queue = card->mpuout->firstmidiq;
601
602         while (queue != NULL) {
603                 count++;
604                 if (queue == card->mpuout->lastmidiq)
605                         break;
606
607                 queue = queue->next;
608         }
609
610         return count;
611 }
612
613 #endif
614