v2.4.8 -> v2.4.8.1
[opensuse:kernel.git] / drivers / sound / 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 #define __NO_VERSION__
33 #include <linux/module.h>
34 #include <linux/slab.h>
35 #include <linux/version.h>
36 #include <linux/sched.h>
37 #include <linux/smp_lock.h>
38 #include <asm/uaccess.h>
39
40 #include "hwaccess.h"
41 #include "cardmo.h"
42 #include "cardmi.h"
43 #include "midi.h"
44
45 #ifdef EMU10K1_SEQUENCER
46 #include "../sound_config.h"
47 #endif
48
49 static spinlock_t midi_spinlock __attribute((unused)) = SPIN_LOCK_UNLOCKED;
50
51 static void init_midi_hdr(struct midi_hdr *midihdr)
52 {
53         midihdr->bufferlength = MIDIIN_BUFLEN;
54         midihdr->bytesrecorded = 0;
55         midihdr->flags = 0;
56 }
57
58 static int midiin_add_buffer(struct emu10k1_mididevice *midi_dev, struct midi_hdr **midihdrptr)
59 {
60         struct midi_hdr *midihdr;
61
62         if ((midihdr = (struct midi_hdr *) kmalloc(sizeof(struct midi_hdr), GFP_KERNEL)) == NULL) {
63                 ERROR();
64                 return -EINVAL;
65         }
66
67         init_midi_hdr(midihdr);
68
69         if ((midihdr->data = (u8 *) kmalloc(MIDIIN_BUFLEN, GFP_KERNEL)) == NULL) {
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 = MINOR(inode->i_rdev);
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         
98         /* Check for correct device to open */
99         list_for_each(entry, &emu10k1_devs) {
100                 card = list_entry(entry, struct emu10k1_card, list);
101
102                 if (card->midi_dev == minor)
103                         goto match;
104         }
105
106         return -ENODEV;
107
108 match:
109 #ifdef EMU10K1_SEQUENCER
110         if(card->seq_mididev)   /* card is opened by sequencer */
111                         return -EBUSY;
112 #endif
113         
114
115         /* Wait for device to become free */
116         down(&card->open_sem);
117         while (card->open_mode & (file->f_mode << FMODE_MIDI_SHIFT)) {
118                 if (file->f_flags & O_NONBLOCK) {
119                         up(&card->open_sem);
120                         return -EBUSY;
121                 }
122
123                 up(&card->open_sem);
124                 interruptible_sleep_on(&card->open_wait);
125
126                 if (signal_pending(current)) {
127                         return -ERESTARTSYS;
128                 }
129
130                 down(&card->open_sem);
131         }
132
133         if ((midi_dev = (struct emu10k1_mididevice *) kmalloc(sizeof(*midi_dev), GFP_KERNEL)) == NULL) {
134                 return -EINVAL;
135         }
136
137         midi_dev->card = card;
138         midi_dev->mistate = MIDIIN_STATE_STOPPED;
139         init_waitqueue_head(&midi_dev->oWait);
140         init_waitqueue_head(&midi_dev->iWait);
141         midi_dev->ird = 0;
142         midi_dev->iwr = 0;
143         midi_dev->icnt = 0;
144         INIT_LIST_HEAD(&midi_dev->mid_hdrs);
145
146         if (file->f_mode & FMODE_READ) {
147                 struct midi_openinfo dsCardMidiOpenInfo;
148                 struct midi_hdr *midihdr1;
149                 struct midi_hdr *midihdr2;
150
151                 dsCardMidiOpenInfo.refdata = (unsigned long) midi_dev;
152
153                 if (emu10k1_mpuin_open(card, &dsCardMidiOpenInfo) < 0) {
154                         ERROR();
155                         kfree(midi_dev);
156                         return -ENODEV;
157                 }
158
159                 /* Add two buffers to receive sysex buffer */
160                 if (midiin_add_buffer(midi_dev, &midihdr1) < 0) {
161                         kfree(midi_dev);
162                         return -ENODEV;
163                 }
164
165                 if (midiin_add_buffer(midi_dev, &midihdr2) < 0) {
166                         list_del(&midihdr1->list);
167                         kfree(midihdr1->data);
168                         kfree(midihdr1);
169                         kfree(midi_dev);
170                         return -ENODEV;
171                 }
172         }
173
174         if (file->f_mode & FMODE_WRITE) {
175                 struct midi_openinfo dsCardMidiOpenInfo;
176
177                 dsCardMidiOpenInfo.refdata = (unsigned long) midi_dev;
178
179                 if (emu10k1_mpuout_open(card, &dsCardMidiOpenInfo) < 0) {
180                         ERROR();
181                         kfree(midi_dev);
182                         return -ENODEV;
183                 }
184         }
185
186         file->private_data = (void *) midi_dev;
187
188         card->open_mode |= (file->f_mode << FMODE_MIDI_SHIFT) & (FMODE_MIDI_READ | FMODE_MIDI_WRITE);
189
190         up(&card->open_sem);
191
192         return 0;
193 }
194
195 static int emu10k1_midi_release(struct inode *inode, struct file *file)
196 {
197         struct emu10k1_mididevice *midi_dev = (struct emu10k1_mididevice *) file->private_data;
198         struct emu10k1_card *card;
199
200         lock_kernel();
201
202         card = midi_dev->card;
203         DPF(2, "emu10k1_midi_release()\n");
204
205         if (file->f_mode & FMODE_WRITE) {
206                 if (!(file->f_flags & O_NONBLOCK)) {
207
208                         while (!signal_pending(current) && (card->mpuout->firstmidiq != NULL)) {
209                                 DPF(4, "Cannot close - buffers not empty\n");
210
211                                 interruptible_sleep_on(&midi_dev->oWait);
212
213                         }
214                 }
215
216                 emu10k1_mpuout_close(card);
217         }
218
219         if (file->f_mode & FMODE_READ) {
220                 struct midi_hdr *midihdr;
221
222                 if (midi_dev->mistate == MIDIIN_STATE_STARTED) {
223                         emu10k1_mpuin_stop(card);
224                         midi_dev->mistate = MIDIIN_STATE_STOPPED;
225                 }
226
227                 emu10k1_mpuin_reset(card);
228                 emu10k1_mpuin_close(card);
229
230                 while (!list_empty(&midi_dev->mid_hdrs)) {
231                         midihdr = list_entry(midi_dev->mid_hdrs.next, struct midi_hdr, list);
232
233                         list_del(midi_dev->mid_hdrs.next);
234                         kfree(midihdr->data);
235                         kfree(midihdr);
236                 }
237         }
238
239         kfree(midi_dev);
240
241         down(&card->open_sem);
242         card->open_mode &= ~((file->f_mode << FMODE_MIDI_SHIFT) & (FMODE_MIDI_READ | FMODE_MIDI_WRITE));
243         up(&card->open_sem);
244         wake_up_interruptible(&card->open_wait);
245
246         unlock_kernel();
247         
248
249         return 0;
250 }
251
252 static ssize_t emu10k1_midi_read(struct file *file, char *buffer, size_t count, loff_t * pos)
253 {
254         struct emu10k1_mididevice *midi_dev = (struct emu10k1_mididevice *) file->private_data;
255         ssize_t ret = 0;
256         u16 cnt;
257         unsigned long flags;
258
259         DPD(4, "emu10k1_midi_read(), count %#x\n", (u32) count);
260
261         if (pos != &file->f_pos)
262                 return -ESPIPE;
263
264         if (!access_ok(VERIFY_WRITE, buffer, count))
265                 return -EFAULT;
266
267         if (midi_dev->mistate == MIDIIN_STATE_STOPPED) {
268                 if (emu10k1_mpuin_start(midi_dev->card) < 0) {
269                         ERROR();
270                         return -EINVAL;
271                 }
272
273                 midi_dev->mistate = MIDIIN_STATE_STARTED;
274         }
275
276         while (count > 0) {
277                 cnt = MIDIIN_BUFLEN - midi_dev->ird;
278
279                 spin_lock_irqsave(&midi_spinlock, flags);
280
281                 if (midi_dev->icnt < cnt)
282                         cnt = midi_dev->icnt;
283
284                 spin_unlock_irqrestore(&midi_spinlock, flags);
285
286                 if (cnt > count)
287                         cnt = count;
288
289                 if (cnt <= 0) {
290                         if (file->f_flags & O_NONBLOCK)
291                                 return ret ? ret : -EAGAIN;
292                         DPF(2, " Go to sleep...\n");
293
294                         interruptible_sleep_on(&midi_dev->iWait);
295
296                         if (signal_pending(current))
297                                 return ret ? ret : -ERESTARTSYS;
298
299                         continue;
300                 }
301
302                 if (copy_to_user(buffer, midi_dev->iBuf + midi_dev->ird, cnt)) {
303                         ERROR();
304                         return ret ? ret : -EFAULT;
305                 }
306
307                 midi_dev->ird += cnt;
308                 midi_dev->ird %= MIDIIN_BUFLEN;
309
310                 spin_lock_irqsave(&midi_spinlock, flags);
311
312                 midi_dev->icnt -= cnt;
313
314                 spin_unlock_irqrestore(&midi_spinlock, flags);
315
316                 count -= cnt;
317                 buffer += cnt;
318                 ret += cnt;
319
320                 if (midi_dev->icnt == 0)
321                         break;
322         }
323
324         return ret;
325 }
326
327 static ssize_t emu10k1_midi_write(struct file *file, const char *buffer, size_t count, loff_t * pos)
328 {
329         struct emu10k1_mididevice *midi_dev = (struct emu10k1_mididevice *) file->private_data;
330         struct midi_hdr *midihdr;
331         ssize_t ret = 0;
332         unsigned long flags;
333
334         DPD(4, "emu10k1_midi_write(), count=%#x\n", (u32) count);
335
336         if (pos != &file->f_pos)
337                 return -ESPIPE;
338
339         if (!access_ok(VERIFY_READ, buffer, count))
340                 return -EFAULT;
341
342         if ((midihdr = (struct midi_hdr *) kmalloc(sizeof(struct midi_hdr), GFP_KERNEL)) == NULL)
343                 return -EINVAL;
344
345         midihdr->bufferlength = count;
346         midihdr->bytesrecorded = 0;
347         midihdr->flags = 0;
348
349         if ((midihdr->data = (u8 *) kmalloc(count, GFP_KERNEL)) == NULL) {
350                 ERROR();
351                 kfree(midihdr);
352                 return -EINVAL;
353         }
354
355         if (copy_from_user(midihdr->data, buffer, count)) {
356                 kfree(midihdr->data);
357                 kfree(midihdr);
358                 return ret ? ret : -EFAULT;
359         }
360
361         spin_lock_irqsave(&midi_spinlock, flags);
362
363         if (emu10k1_mpuout_add_buffer(midi_dev->card, midihdr) < 0) {
364                 ERROR();
365                 kfree(midihdr->data);
366                 kfree(midihdr);
367                 spin_unlock_irqrestore(&midi_spinlock, flags);
368                 return -EINVAL;
369         }
370
371         spin_unlock_irqrestore(&midi_spinlock, flags);
372
373         return count;
374 }
375
376 static unsigned int emu10k1_midi_poll(struct file *file, struct poll_table_struct *wait)
377 {
378         DPF(4, "emu10k1_midi_poll() called\n");
379         return 0;
380 }
381
382 int emu10k1_midi_callback(unsigned long msg, unsigned long refdata, unsigned long *pmsg)
383 {
384         struct emu10k1_mididevice *midi_dev = (struct emu10k1_mididevice *) refdata;
385         struct midi_hdr *midihdr = NULL;
386         unsigned long flags;
387         int i;
388
389         DPF(4, "emu10k1_midi_callback()\n");
390
391         spin_lock_irqsave(&midi_spinlock, flags);
392
393         switch (msg) {
394         case ICARDMIDI_OUTLONGDATA:
395                 midihdr = (struct midi_hdr *) pmsg[2];
396
397                 kfree(midihdr->data);
398                 kfree(midihdr);
399                 wake_up_interruptible(&midi_dev->oWait);
400
401                 break;
402
403         case ICARDMIDI_INLONGDATA:
404                 midihdr = (struct midi_hdr *) pmsg[2];
405
406                 for (i = 0; i < midihdr->bytesrecorded; i++) {
407                         midi_dev->iBuf[midi_dev->iwr++] = midihdr->data[i];
408                         midi_dev->iwr %= MIDIIN_BUFLEN;
409                 }
410
411                 midi_dev->icnt += midihdr->bytesrecorded;
412
413                 if (midi_dev->mistate == MIDIIN_STATE_STARTED) {
414                         init_midi_hdr(midihdr);
415                         emu10k1_mpuin_add_buffer(midi_dev->card->mpuin, midihdr);
416                         wake_up_interruptible(&midi_dev->iWait);
417                 }
418                 break;
419
420         case ICARDMIDI_INDATA:
421                 {
422                         u8 *pBuf = (u8 *) & pmsg[1];
423                         u16 bytesvalid = pmsg[2];
424
425                         for (i = 0; i < bytesvalid; i++) {
426                                 midi_dev->iBuf[midi_dev->iwr++] = pBuf[i];
427                                 midi_dev->iwr %= MIDIIN_BUFLEN;
428                         }
429
430                         midi_dev->icnt += bytesvalid;
431                 }
432
433                 wake_up_interruptible(&midi_dev->iWait);
434                 break;
435
436         default:                /* Unknown message */
437                 spin_unlock_irqrestore(&midi_spinlock, flags);
438                 return -1;
439         }
440
441         spin_unlock_irqrestore(&midi_spinlock, flags);
442
443         return 0;
444 }
445
446 /* MIDI file operations */
447 struct file_operations emu10k1_midi_fops = {
448         owner:          THIS_MODULE,
449         read:           emu10k1_midi_read,
450         write:          emu10k1_midi_write,
451         poll:           emu10k1_midi_poll,
452         open:           emu10k1_midi_open,
453         release:        emu10k1_midi_release,
454 };
455
456
457 #ifdef EMU10K1_SEQUENCER
458
459 /* functions used for sequencer access */
460
461 int emu10k1_seq_midi_open(int dev, int mode,
462                                 void (*input) (int dev, unsigned char data),
463                                 void (*output) (int dev))
464 {
465     struct emu10k1_card *card;
466     struct midi_openinfo dsCardMidiOpenInfo;
467         struct emu10k1_mididevice *midi_dev;
468                 
469         if(    midi_devs[dev] == NULL
470                 || midi_devs[dev]->devc == NULL)
471                         return -EINVAL;
472
473         card = midi_devs[dev]->devc;
474
475         if(card->open_mode)             /* card is opened native */
476                         return -EBUSY;
477                         
478         DPF(2, "emu10k1_seq_midi_open()\n");
479         
480         if ((midi_dev = (struct emu10k1_mididevice *) kmalloc(sizeof(*midi_dev), GFP_KERNEL)) == NULL) {
481                 return -EINVAL;
482         }
483
484         midi_dev->card = card;
485         midi_dev->mistate = MIDIIN_STATE_STOPPED;
486         init_waitqueue_head(&midi_dev->oWait);
487         init_waitqueue_head(&midi_dev->iWait);
488         midi_dev->ird = 0;
489         midi_dev->iwr = 0;
490         midi_dev->icnt = 0;
491         INIT_LIST_HEAD(&midi_dev->mid_hdrs);
492
493         dsCardMidiOpenInfo.refdata = (unsigned long) midi_dev;
494
495     if (emu10k1_mpuout_open(card, &dsCardMidiOpenInfo) < 0) {
496         ERROR();
497         return -ENODEV;
498     }
499
500         card->seq_mididev = midi_dev;
501                 
502         return 0;
503 }
504
505 void emu10k1_seq_midi_close(int dev)
506 {
507         struct emu10k1_card *card;
508
509         DPF(2, "emu10k1_seq_midi_close()\n");
510     if(    midi_devs[dev] == NULL
511         || midi_devs[dev]->devc == NULL)
512                         return;
513
514         card = midi_devs[dev]->devc;
515         emu10k1_mpuout_close(card);
516
517         if(card->seq_mididev) {
518                         kfree(card->seq_mididev);
519                         card->seq_mididev = 0;
520         }
521 }
522
523 int emu10k1_seq_midi_out(int dev, unsigned char midi_byte)
524 {
525
526         struct emu10k1_card *card;
527         struct midi_hdr *midihdr;
528         unsigned long flags;
529
530         if(    midi_devs[dev] == NULL
531         || midi_devs[dev]->devc == NULL)
532                         return -EINVAL;
533
534         card = midi_devs[dev]->devc;
535
536         if ((midihdr = (struct midi_hdr *) kmalloc(sizeof(struct midi_hdr), GFP_KERNEL)) == NULL)
537                 return -EINVAL;
538
539         midihdr->bufferlength = 1;
540         midihdr->bytesrecorded = 0;
541         midihdr->flags = 0;
542
543         if ((midihdr->data = (u8 *) kmalloc(1, GFP_KERNEL)) == NULL) {
544                 ERROR();
545                 kfree(midihdr);
546                 return -EINVAL;
547         }
548
549         *(midihdr->data) = midi_byte;
550         
551         spin_lock_irqsave(&midi_spinlock, flags);
552
553         if (emu10k1_mpuout_add_buffer(card, midihdr) < 0) {
554                 ERROR();
555                 kfree(midihdr->data);
556                 kfree(midihdr);
557                 spin_unlock_irqrestore(&midi_spinlock, flags);
558                 return -EINVAL;
559         }
560
561         spin_unlock_irqrestore(&midi_spinlock, flags);
562
563         return 1;
564 }
565
566 int emu10k1_seq_midi_start_read(int dev)
567 {
568         return 0;
569 }
570
571 int emu10k1_seq_midi_end_read(int dev)
572 {
573         return 0;
574 }
575
576 void emu10k1_seq_midi_kick(int dev)
577 {
578 }
579
580 int emu10k1_seq_midi_buffer_status(int dev)
581 {
582         int count;
583         struct midi_queue *queue;
584         struct emu10k1_card *card;
585
586         if(    midi_devs[dev] == NULL
587         || midi_devs[dev]->devc == NULL)
588                         return -EINVAL;
589
590         count = 0;
591         
592         card = midi_devs[dev]->devc;
593         queue = card->mpuout->firstmidiq;
594
595         while(queue != NULL) {
596                         count++;
597                         if(queue == card->mpuout->lastmidiq)
598                                         break;
599                         queue = queue->next;
600         }
601         return count;
602 }
603
604 #endif
605