patch-2_6_7-vs1_9_1_12
[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 0;
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 (pos != &file->f_pos)
257                 return -ESPIPE;
258
259         if (!access_ok(VERIFY_WRITE, buffer, count))
260                 return -EFAULT;
261
262         if (midi_dev->mistate == MIDIIN_STATE_STOPPED) {
263                 if (emu10k1_mpuin_start(midi_dev->card) < 0) {
264                         ERROR();
265                         return -EINVAL;
266                 }
267
268                 midi_dev->mistate = MIDIIN_STATE_STARTED;
269         }
270
271         while (count > 0) {
272                 cnt = MIDIIN_BUFLEN - midi_dev->ird;
273
274                 spin_lock_irqsave(&midi_spinlock, flags);
275
276                 if (midi_dev->icnt < cnt)
277                         cnt = midi_dev->icnt;
278
279                 spin_unlock_irqrestore(&midi_spinlock, flags);
280
281                 if (cnt > count)
282                         cnt = count;
283
284                 if (cnt <= 0) {
285                         if (file->f_flags & O_NONBLOCK)
286                                 return ret ? ret : -EAGAIN;
287                         DPF(2, " Go to sleep...\n");
288
289                         interruptible_sleep_on(&midi_dev->iWait);
290
291                         if (signal_pending(current))
292                                 return ret ? ret : -ERESTARTSYS;
293
294                         continue;
295                 }
296
297                 if (copy_to_user(buffer, midi_dev->iBuf + midi_dev->ird, cnt)) {
298                         ERROR();
299                         return ret ? ret : -EFAULT;
300                 }
301
302                 midi_dev->ird += cnt;
303                 midi_dev->ird %= MIDIIN_BUFLEN;
304
305                 spin_lock_irqsave(&midi_spinlock, flags);
306
307                 midi_dev->icnt -= cnt;
308
309                 spin_unlock_irqrestore(&midi_spinlock, flags);
310
311                 count -= cnt;
312                 buffer += cnt;
313                 ret += cnt;
314
315                 if (midi_dev->icnt == 0)
316                         break;
317         }
318
319         return ret;
320 }
321
322 static ssize_t emu10k1_midi_write(struct file *file, const char __user *buffer, size_t count, loff_t * pos)
323 {
324         struct emu10k1_mididevice *midi_dev = (struct emu10k1_mididevice *) file->private_data;
325         struct midi_hdr *midihdr;
326         ssize_t ret = 0;
327         unsigned long flags;
328
329         DPD(4, "emu10k1_midi_write(), count=%#x\n", (u32) count);
330
331         if (pos != &file->f_pos)
332                 return -ESPIPE;
333
334         if (!access_ok(VERIFY_READ, buffer, count))
335                 return -EFAULT;
336
337         if ((midihdr = (struct midi_hdr *) kmalloc(sizeof(struct midi_hdr), GFP_KERNEL)) == NULL)
338                 return -EINVAL;
339
340         midihdr->bufferlength = count;
341         midihdr->bytesrecorded = 0;
342         midihdr->flags = 0;
343
344         if ((midihdr->data = (u8 *) kmalloc(count, GFP_KERNEL)) == NULL) {
345                 ERROR();
346                 kfree(midihdr);
347                 return -EINVAL;
348         }
349
350         if (copy_from_user(midihdr->data, buffer, count)) {
351                 kfree(midihdr->data);
352                 kfree(midihdr);
353                 return ret ? ret : -EFAULT;
354         }
355
356         spin_lock_irqsave(&midi_spinlock, flags);
357
358         if (emu10k1_mpuout_add_buffer(midi_dev->card, midihdr) < 0) {
359                 ERROR();
360                 kfree(midihdr->data);
361                 kfree(midihdr);
362                 spin_unlock_irqrestore(&midi_spinlock, flags);
363                 return -EINVAL;
364         }
365
366         spin_unlock_irqrestore(&midi_spinlock, flags);
367
368         return count;
369 }
370
371 static unsigned int emu10k1_midi_poll(struct file *file, struct poll_table_struct *wait)
372 {
373         struct emu10k1_mididevice *midi_dev = (struct emu10k1_mididevice *) file->private_data;
374         unsigned long flags;
375         unsigned int mask = 0;
376
377         DPF(4, "emu10k1_midi_poll() called\n");
378
379         if (file->f_mode & FMODE_WRITE)
380                 poll_wait(file, &midi_dev->oWait, wait);
381
382         if (file->f_mode & FMODE_READ)
383                 poll_wait(file, &midi_dev->iWait, wait);
384
385         spin_lock_irqsave(&midi_spinlock, flags);
386
387         if (file->f_mode & FMODE_WRITE)
388                 mask |= POLLOUT | POLLWRNORM;
389
390         if (file->f_mode & FMODE_READ) {
391                 if (midi_dev->mistate == MIDIIN_STATE_STARTED)
392                         if (midi_dev->icnt > 0)
393                                 mask |= POLLIN | POLLRDNORM;
394         }
395
396         spin_unlock_irqrestore(&midi_spinlock, flags);
397
398         return mask;
399 }
400
401 int emu10k1_midi_callback(unsigned long msg, unsigned long refdata, unsigned long *pmsg)
402 {
403         struct emu10k1_mididevice *midi_dev = (struct emu10k1_mididevice *) refdata;
404         struct midi_hdr *midihdr = NULL;
405         unsigned long flags;
406         int i;
407
408         DPF(4, "emu10k1_midi_callback()\n");
409
410         spin_lock_irqsave(&midi_spinlock, flags);
411
412         switch (msg) {
413         case ICARDMIDI_OUTLONGDATA:
414                 midihdr = (struct midi_hdr *) pmsg[2];
415
416                 kfree(midihdr->data);
417                 kfree(midihdr);
418                 wake_up_interruptible(&midi_dev->oWait);
419
420                 break;
421
422         case ICARDMIDI_INLONGDATA:
423                 midihdr = (struct midi_hdr *) pmsg[2];
424
425                 for (i = 0; i < midihdr->bytesrecorded; i++) {
426                         midi_dev->iBuf[midi_dev->iwr++] = midihdr->data[i];
427                         midi_dev->iwr %= MIDIIN_BUFLEN;
428                 }
429
430                 midi_dev->icnt += midihdr->bytesrecorded;
431
432                 if (midi_dev->mistate == MIDIIN_STATE_STARTED) {
433                         init_midi_hdr(midihdr);
434                         emu10k1_mpuin_add_buffer(midi_dev->card->mpuin, midihdr);
435                         wake_up_interruptible(&midi_dev->iWait);
436                 }
437                 break;
438
439         case ICARDMIDI_INDATA:
440                 {
441                         u8 *pBuf = (u8 *) & pmsg[1];
442                         u16 bytesvalid = pmsg[2];
443
444                         for (i = 0; i < bytesvalid; i++) {
445                                 midi_dev->iBuf[midi_dev->iwr++] = pBuf[i];
446                                 midi_dev->iwr %= MIDIIN_BUFLEN;
447                         }
448
449                         midi_dev->icnt += bytesvalid;
450                 }
451
452                 wake_up_interruptible(&midi_dev->iWait);
453                 break;
454
455         default:                /* Unknown message */
456                 spin_unlock_irqrestore(&midi_spinlock, flags);
457                 return -1;
458         }
459
460         spin_unlock_irqrestore(&midi_spinlock, flags);
461
462         return 0;
463 }
464
465 /* MIDI file operations */
466 struct file_operations emu10k1_midi_fops = {
467         .owner          = THIS_MODULE,
468         .read           = emu10k1_midi_read,
469         .write          = emu10k1_midi_write,
470         .poll           = emu10k1_midi_poll,
471         .open           = emu10k1_midi_open,
472         .release        = emu10k1_midi_release,
473 };
474
475
476 #ifdef EMU10K1_SEQUENCER
477
478 /* functions used for sequencer access */
479
480 int emu10k1_seq_midi_open(int dev, int mode,
481                                 void (*input) (int dev, unsigned char data),
482                                 void (*output) (int dev))
483 {
484         struct emu10k1_card *card;
485         struct midi_openinfo dsCardMidiOpenInfo;
486         struct emu10k1_mididevice *midi_dev;
487
488         if (midi_devs[dev] == NULL || midi_devs[dev]->devc == NULL)
489                 return -EINVAL;
490
491         card = midi_devs[dev]->devc;
492
493         if (card->open_mode)            /* card is opened native */
494                 return -EBUSY;
495                         
496         DPF(2, "emu10k1_seq_midi_open()\n");
497         
498         if ((midi_dev = (struct emu10k1_mididevice *) kmalloc(sizeof(*midi_dev), GFP_KERNEL)) == NULL)
499                 return -EINVAL;
500
501         midi_dev->card = card;
502         midi_dev->mistate = MIDIIN_STATE_STOPPED;
503         init_waitqueue_head(&midi_dev->oWait);
504         init_waitqueue_head(&midi_dev->iWait);
505         midi_dev->ird = 0;
506         midi_dev->iwr = 0;
507         midi_dev->icnt = 0;
508         INIT_LIST_HEAD(&midi_dev->mid_hdrs);
509
510         dsCardMidiOpenInfo.refdata = (unsigned long) midi_dev;
511
512         if (emu10k1_mpuout_open(card, &dsCardMidiOpenInfo) < 0) {
513                 ERROR();
514                 return -ENODEV;
515         }
516
517         card->seq_mididev = midi_dev;
518                 
519         return 0;
520 }
521
522 void emu10k1_seq_midi_close(int dev)
523 {
524         struct emu10k1_card *card;
525
526         DPF(2, "emu10k1_seq_midi_close()\n");
527         if (midi_devs[dev] == NULL || midi_devs[dev]->devc == NULL)
528                 return;
529
530         card = midi_devs[dev]->devc;
531         emu10k1_mpuout_close(card);
532
533         if (card->seq_mididev) {
534                 kfree(card->seq_mididev);
535                 card->seq_mididev = 0;
536         }
537 }
538
539 int emu10k1_seq_midi_out(int dev, unsigned char midi_byte)
540 {
541         struct emu10k1_card *card;
542         struct midi_hdr *midihdr;
543         unsigned long flags;
544
545         if (midi_devs[dev] == NULL || midi_devs[dev]->devc == NULL)
546                 return -EINVAL;
547
548         card = midi_devs[dev]->devc;
549
550         if ((midihdr = (struct midi_hdr *) kmalloc(sizeof(struct midi_hdr), GFP_KERNEL)) == NULL)
551                 return -EINVAL;
552
553         midihdr->bufferlength = 1;
554         midihdr->bytesrecorded = 0;
555         midihdr->flags = 0;
556
557         if ((midihdr->data = (u8 *) kmalloc(1, GFP_KERNEL)) == NULL) {
558                 ERROR();
559                 kfree(midihdr);
560                 return -EINVAL;
561         }
562
563         *(midihdr->data) = midi_byte;
564         
565         spin_lock_irqsave(&midi_spinlock, flags);
566
567         if (emu10k1_mpuout_add_buffer(card, midihdr) < 0) {
568                 ERROR();
569                 kfree(midihdr->data);
570                 kfree(midihdr);
571                 spin_unlock_irqrestore(&midi_spinlock, flags);
572                 return -EINVAL;
573         }
574
575         spin_unlock_irqrestore(&midi_spinlock, flags);
576
577         return 1;
578 }
579
580 int emu10k1_seq_midi_start_read(int dev)
581 {
582         return 0;
583 }
584
585 int emu10k1_seq_midi_end_read(int dev)
586 {
587         return 0;
588 }
589
590 void emu10k1_seq_midi_kick(int dev)
591 {
592 }
593
594 int emu10k1_seq_midi_buffer_status(int dev)
595 {
596         int count;
597         struct midi_queue *queue;
598         struct emu10k1_card *card;
599
600         if (midi_devs[dev] == NULL || midi_devs[dev]->devc == NULL)
601                 return -EINVAL;
602
603         count = 0;
604
605         card = midi_devs[dev]->devc;
606         queue = card->mpuout->firstmidiq;
607
608         while (queue != NULL) {
609                 count++;
610                 if (queue == card->mpuout->lastmidiq)
611                         break;
612
613                 queue = queue->next;
614         }
615
616         return count;
617 }
618
619 #endif
620