VServer 1.9.2 (patch-2.6.8.1-vs1.9.2.diff)
[linux-2.6.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 spinlock_t midi_spinlock __attribute((unused)) = SPIN_LOCK_UNLOCKED;
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         if ((midihdr->data = (u8 *) kmalloc(MIDIIN_BUFLEN, GFP_KERNEL)) == NULL) {
69                 ERROR();
70                 kfree(midihdr);
71                 return -1;
72         }
73
74         if (emu10k1_mpuin_add_buffer(midi_dev->card->mpuin, midihdr) < 0) {
75                 ERROR();
76                 kfree(midihdr->data);
77                 kfree(midihdr);
78                 return -1;
79         }
80
81         *midihdrptr = midihdr;
82         list_add_tail(&midihdr->list, &midi_dev->mid_hdrs);
83
84         return 0;
85 }
86
87 static int emu10k1_midi_open(struct inode *inode, struct file *file)
88 {
89         int minor = iminor(inode);
90         struct emu10k1_card *card = NULL;
91         struct emu10k1_mididevice *midi_dev;
92         struct list_head *entry;
93
94         DPF(2, "emu10k1_midi_open()\n");
95
96         /* Check for correct device to open */
97         list_for_each(entry, &emu10k1_devs) {
98                 card = list_entry(entry, struct emu10k1_card, list);
99
100                 if (card->midi_dev == minor)
101                         goto match;
102         }
103
104         return -ENODEV;
105
106 match:
107 #ifdef EMU10K1_SEQUENCER
108         if (card->seq_mididev)  /* card is opened by sequencer */
109                 return -EBUSY;
110 #endif
111
112         /* Wait for device to become free */
113         down(&card->open_sem);
114         while (card->open_mode & (file->f_mode << FMODE_MIDI_SHIFT)) {
115                 if (file->f_flags & O_NONBLOCK) {
116                         up(&card->open_sem);
117                         return -EBUSY;
118                 }
119
120                 up(&card->open_sem);
121                 interruptible_sleep_on(&card->open_wait);
122
123                 if (signal_pending(current)) {
124                         return -ERESTARTSYS;
125                 }
126
127                 down(&card->open_sem);
128         }
129
130         if ((midi_dev = (struct emu10k1_mididevice *) kmalloc(sizeof(*midi_dev), GFP_KERNEL)) == NULL)
131                 return -EINVAL;
132
133         midi_dev->card = card;
134         midi_dev->mistate = MIDIIN_STATE_STOPPED;
135         init_waitqueue_head(&midi_dev->oWait);
136         init_waitqueue_head(&midi_dev->iWait);
137         midi_dev->ird = 0;
138         midi_dev->iwr = 0;
139         midi_dev->icnt = 0;
140         INIT_LIST_HEAD(&midi_dev->mid_hdrs);
141
142         if (file->f_mode & FMODE_READ) {
143                 struct midi_openinfo dsCardMidiOpenInfo;
144                 struct midi_hdr *midihdr1;
145                 struct midi_hdr *midihdr2;
146
147                 dsCardMidiOpenInfo.refdata = (unsigned long) midi_dev;
148
149                 if (emu10k1_mpuin_open(card, &dsCardMidiOpenInfo) < 0) {
150                         ERROR();
151                         kfree(midi_dev);
152                         return -ENODEV;
153                 }
154
155                 /* Add two buffers to receive sysex buffer */
156                 if (midiin_add_buffer(midi_dev, &midihdr1) < 0) {
157                         kfree(midi_dev);
158                         return -ENODEV;
159                 }
160
161                 if (midiin_add_buffer(midi_dev, &midihdr2) < 0) {
162                         list_del(&midihdr1->list);
163                         kfree(midihdr1->data);
164                         kfree(midihdr1);
165                         kfree(midi_dev);
166                         return -ENODEV;
167                 }
168         }
169
170         if (file->f_mode & FMODE_WRITE) {
171                 struct midi_openinfo dsCardMidiOpenInfo;
172
173                 dsCardMidiOpenInfo.refdata = (unsigned long) midi_dev;
174
175                 if (emu10k1_mpuout_open(card, &dsCardMidiOpenInfo) < 0) {
176                         ERROR();
177                         kfree(midi_dev);
178                         return -ENODEV;
179                 }
180         }
181
182         file->private_data = (void *) midi_dev;
183
184         card->open_mode |= (file->f_mode << FMODE_MIDI_SHIFT) & (FMODE_MIDI_READ | FMODE_MIDI_WRITE);
185
186         up(&card->open_sem);
187
188         return nonseekable_open(inode, file);
189 }
190
191 static int emu10k1_midi_release(struct inode *inode, struct file *file)
192 {
193         struct emu10k1_mididevice *midi_dev = (struct emu10k1_mididevice *) file->private_data;
194         struct emu10k1_card *card;
195
196         lock_kernel();
197
198         card = midi_dev->card;
199         DPF(2, "emu10k1_midi_release()\n");
200
201         if (file->f_mode & FMODE_WRITE) {
202                 if (!(file->f_flags & O_NONBLOCK)) {
203
204                         while (!signal_pending(current) && (card->mpuout->firstmidiq != NULL)) {
205                                 DPF(4, "Cannot close - buffers not empty\n");
206
207                                 interruptible_sleep_on(&midi_dev->oWait);
208
209                         }
210                 }
211
212                 emu10k1_mpuout_close(card);
213         }
214
215         if (file->f_mode & FMODE_READ) {
216                 struct midi_hdr *midihdr;
217
218                 if (midi_dev->mistate == MIDIIN_STATE_STARTED) {
219                         emu10k1_mpuin_stop(card);
220                         midi_dev->mistate = MIDIIN_STATE_STOPPED;
221                 }
222
223                 emu10k1_mpuin_reset(card);
224                 emu10k1_mpuin_close(card);
225
226                 while (!list_empty(&midi_dev->mid_hdrs)) {
227                         midihdr = list_entry(midi_dev->mid_hdrs.next, struct midi_hdr, list);
228
229                         list_del(midi_dev->mid_hdrs.next);
230                         kfree(midihdr->data);
231                         kfree(midihdr);
232                 }
233         }
234
235         kfree(midi_dev);
236
237         down(&card->open_sem);
238         card->open_mode &= ~((file->f_mode << FMODE_MIDI_SHIFT) & (FMODE_MIDI_READ | FMODE_MIDI_WRITE));
239         up(&card->open_sem);
240         wake_up_interruptible(&card->open_wait);
241
242         unlock_kernel();
243
244         return 0;
245 }
246
247 static ssize_t emu10k1_midi_read(struct file *file, char __user *buffer, size_t count, loff_t * pos)
248 {
249         struct emu10k1_mididevice *midi_dev = (struct emu10k1_mididevice *) file->private_data;
250         ssize_t ret = 0;
251         u16 cnt;
252         unsigned long flags;
253
254         DPD(4, "emu10k1_midi_read(), count %#x\n", (u32) count);
255
256         if (!access_ok(VERIFY_WRITE, buffer, count))
257                 return -EFAULT;
258
259         if (midi_dev->mistate == MIDIIN_STATE_STOPPED) {
260                 if (emu10k1_mpuin_start(midi_dev->card) < 0) {
261                         ERROR();
262                         return -EINVAL;
263                 }
264
265                 midi_dev->mistate = MIDIIN_STATE_STARTED;
266         }
267
268         while (count > 0) {
269                 cnt = MIDIIN_BUFLEN - midi_dev->ird;
270
271                 spin_lock_irqsave(&midi_spinlock, flags);
272
273                 if (midi_dev->icnt < cnt)
274                         cnt = midi_dev->icnt;
275
276                 spin_unlock_irqrestore(&midi_spinlock, flags);
277
278                 if (cnt > count)
279                         cnt = count;
280
281                 if (cnt <= 0) {
282                         if (file->f_flags & O_NONBLOCK)
283                                 return ret ? ret : -EAGAIN;
284                         DPF(2, " Go to sleep...\n");
285
286                         interruptible_sleep_on(&midi_dev->iWait);
287
288                         if (signal_pending(current))
289                                 return ret ? ret : -ERESTARTSYS;
290
291                         continue;
292                 }
293
294                 if (copy_to_user(buffer, midi_dev->iBuf + midi_dev->ird, cnt)) {
295                         ERROR();
296                         return ret ? ret : -EFAULT;
297                 }
298
299                 midi_dev->ird += cnt;
300                 midi_dev->ird %= MIDIIN_BUFLEN;
301
302                 spin_lock_irqsave(&midi_spinlock, flags);
303
304                 midi_dev->icnt -= cnt;
305
306                 spin_unlock_irqrestore(&midi_spinlock, flags);
307
308                 count -= cnt;
309                 buffer += cnt;
310                 ret += cnt;
311
312                 if (midi_dev->icnt == 0)
313                         break;
314         }
315
316         return ret;
317 }
318
319 static ssize_t emu10k1_midi_write(struct file *file, const char __user *buffer, size_t count, loff_t * pos)
320 {
321         struct emu10k1_mididevice *midi_dev = (struct emu10k1_mididevice *) file->private_data;
322         struct midi_hdr *midihdr;
323         ssize_t ret = 0;
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         if ((midihdr->data = (u8 *) kmalloc(count, GFP_KERNEL)) == NULL) {
339                 ERROR();
340                 kfree(midihdr);
341                 return -EINVAL;
342         }
343
344         if (copy_from_user(midihdr->data, buffer, count)) {
345                 kfree(midihdr->data);
346                 kfree(midihdr);
347                 return ret ? ret : -EFAULT;
348         }
349
350         spin_lock_irqsave(&midi_spinlock, flags);
351
352         if (emu10k1_mpuout_add_buffer(midi_dev->card, midihdr) < 0) {
353                 ERROR();
354                 kfree(midihdr->data);
355                 kfree(midihdr);
356                 spin_unlock_irqrestore(&midi_spinlock, flags);
357                 return -EINVAL;
358         }
359
360         spin_unlock_irqrestore(&midi_spinlock, flags);
361
362         return count;
363 }
364
365 static unsigned int emu10k1_midi_poll(struct file *file, struct poll_table_struct *wait)
366 {
367         struct emu10k1_mididevice *midi_dev = (struct emu10k1_mididevice *) file->private_data;
368         unsigned long flags;
369         unsigned int mask = 0;
370
371         DPF(4, "emu10k1_midi_poll() called\n");
372
373         if (file->f_mode & FMODE_WRITE)
374                 poll_wait(file, &midi_dev->oWait, wait);
375
376         if (file->f_mode & FMODE_READ)
377                 poll_wait(file, &midi_dev->iWait, wait);
378
379         spin_lock_irqsave(&midi_spinlock, flags);
380
381         if (file->f_mode & FMODE_WRITE)
382                 mask |= POLLOUT | POLLWRNORM;
383
384         if (file->f_mode & FMODE_READ) {
385                 if (midi_dev->mistate == MIDIIN_STATE_STARTED)
386                         if (midi_dev->icnt > 0)
387                                 mask |= POLLIN | POLLRDNORM;
388         }
389
390         spin_unlock_irqrestore(&midi_spinlock, flags);
391
392         return mask;
393 }
394
395 int emu10k1_midi_callback(unsigned long msg, unsigned long refdata, unsigned long *pmsg)
396 {
397         struct emu10k1_mididevice *midi_dev = (struct emu10k1_mididevice *) refdata;
398         struct midi_hdr *midihdr = NULL;
399         unsigned long flags;
400         int i;
401
402         DPF(4, "emu10k1_midi_callback()\n");
403
404         spin_lock_irqsave(&midi_spinlock, flags);
405
406         switch (msg) {
407         case ICARDMIDI_OUTLONGDATA:
408                 midihdr = (struct midi_hdr *) pmsg[2];
409
410                 kfree(midihdr->data);
411                 kfree(midihdr);
412                 wake_up_interruptible(&midi_dev->oWait);
413
414                 break;
415
416         case ICARDMIDI_INLONGDATA:
417                 midihdr = (struct midi_hdr *) pmsg[2];
418
419                 for (i = 0; i < midihdr->bytesrecorded; i++) {
420                         midi_dev->iBuf[midi_dev->iwr++] = midihdr->data[i];
421                         midi_dev->iwr %= MIDIIN_BUFLEN;
422                 }
423
424                 midi_dev->icnt += midihdr->bytesrecorded;
425
426                 if (midi_dev->mistate == MIDIIN_STATE_STARTED) {
427                         init_midi_hdr(midihdr);
428                         emu10k1_mpuin_add_buffer(midi_dev->card->mpuin, midihdr);
429                         wake_up_interruptible(&midi_dev->iWait);
430                 }
431                 break;
432
433         case ICARDMIDI_INDATA:
434                 {
435                         u8 *pBuf = (u8 *) & pmsg[1];
436                         u16 bytesvalid = pmsg[2];
437
438                         for (i = 0; i < bytesvalid; i++) {
439                                 midi_dev->iBuf[midi_dev->iwr++] = pBuf[i];
440                                 midi_dev->iwr %= MIDIIN_BUFLEN;
441                         }
442
443                         midi_dev->icnt += bytesvalid;
444                 }
445
446                 wake_up_interruptible(&midi_dev->iWait);
447                 break;
448
449         default:                /* Unknown message */
450                 spin_unlock_irqrestore(&midi_spinlock, flags);
451                 return -1;
452         }
453
454         spin_unlock_irqrestore(&midi_spinlock, flags);
455
456         return 0;
457 }
458
459 /* MIDI file operations */
460 struct file_operations emu10k1_midi_fops = {
461         .owner          = THIS_MODULE,
462         .read           = emu10k1_midi_read,
463         .write          = emu10k1_midi_write,
464         .poll           = emu10k1_midi_poll,
465         .open           = emu10k1_midi_open,
466         .release        = emu10k1_midi_release,
467 };
468
469
470 #ifdef EMU10K1_SEQUENCER
471
472 /* functions used for sequencer access */
473
474 int emu10k1_seq_midi_open(int dev, int mode,
475                                 void (*input) (int dev, unsigned char data),
476                                 void (*output) (int dev))
477 {
478         struct emu10k1_card *card;
479         struct midi_openinfo dsCardMidiOpenInfo;
480         struct emu10k1_mididevice *midi_dev;
481
482         if (midi_devs[dev] == NULL || midi_devs[dev]->devc == NULL)
483                 return -EINVAL;
484
485         card = midi_devs[dev]->devc;
486
487         if (card->open_mode)            /* card is opened native */
488                 return -EBUSY;
489                         
490         DPF(2, "emu10k1_seq_midi_open()\n");
491         
492         if ((midi_dev = (struct emu10k1_mididevice *) kmalloc(sizeof(*midi_dev), GFP_KERNEL)) == NULL)
493                 return -EINVAL;
494
495         midi_dev->card = card;
496         midi_dev->mistate = MIDIIN_STATE_STOPPED;
497         init_waitqueue_head(&midi_dev->oWait);
498         init_waitqueue_head(&midi_dev->iWait);
499         midi_dev->ird = 0;
500         midi_dev->iwr = 0;
501         midi_dev->icnt = 0;
502         INIT_LIST_HEAD(&midi_dev->mid_hdrs);
503
504         dsCardMidiOpenInfo.refdata = (unsigned long) midi_dev;
505
506         if (emu10k1_mpuout_open(card, &dsCardMidiOpenInfo) < 0) {
507                 ERROR();
508                 return -ENODEV;
509         }
510
511         card->seq_mididev = midi_dev;
512                 
513         return 0;
514 }
515
516 void emu10k1_seq_midi_close(int dev)
517 {
518         struct emu10k1_card *card;
519
520         DPF(2, "emu10k1_seq_midi_close()\n");
521         if (midi_devs[dev] == NULL || midi_devs[dev]->devc == NULL)
522                 return;
523
524         card = midi_devs[dev]->devc;
525         emu10k1_mpuout_close(card);
526
527         if (card->seq_mididev) {
528                 kfree(card->seq_mididev);
529                 card->seq_mididev = NULL;
530         }
531 }
532
533 int emu10k1_seq_midi_out(int dev, unsigned char midi_byte)
534 {
535         struct emu10k1_card *card;
536         struct midi_hdr *midihdr;
537         unsigned long flags;
538
539         if (midi_devs[dev] == NULL || midi_devs[dev]->devc == NULL)
540                 return -EINVAL;
541
542         card = midi_devs[dev]->devc;
543
544         if ((midihdr = (struct midi_hdr *) kmalloc(sizeof(struct midi_hdr), GFP_KERNEL)) == NULL)
545                 return -EINVAL;
546
547         midihdr->bufferlength = 1;
548         midihdr->bytesrecorded = 0;
549         midihdr->flags = 0;
550
551         if ((midihdr->data = (u8 *) kmalloc(1, GFP_KERNEL)) == NULL) {
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