source: sbliveos2/trunk/sblive/cardmi.c

Last change on this file was 151, checked in by sandervl, 25 years ago

update

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 19.8 KB
Line 
1/* $Id: cardmi.c 151 2000-05-28 16:50:46Z sandervl $ */
2
3
4/*
5 **********************************************************************
6 * sblive_mi.c - MIDI UART input HAL for emu10k1 driver
7 * Copyright 1999, 2000 Creative Labs, Inc.
8 *
9 **********************************************************************
10 *
11 * Date Author Summary of changes
12 * ---- ------ ------------------
13 * October 20, 1999 Bertrand Lee base code release
14 * November 2, 1999 Alan Cox clean up
15 *
16 **********************************************************************
17 *
18 * This program is free software; you can redistribute it and/or
19 * modify it under the terms of the GNU General Public License as
20 * published by the Free Software Foundation; either version 2 of
21 * the License, or (at your option) any later version.
22 *
23 * This program is distributed in the hope that it will be useful,
24 * but WITHOUT ANY WARRANTY; without even the implied warranty of
25 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26 * GNU General Public License for more details.
27 *
28 * You should have received a copy of the GNU General Public
29 * License along with this program; if not, write to the Free
30 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,
31 * USA.
32 *
33 **********************************************************************
34 */
35
36#include "hwaccess.h"
37#include "cardmi.h"
38
39#ifdef TARGET_OS2
40extern int OSS32_ProcessMidiIRQ(unsigned long streamid);
41#endif
42
43static struct {
44 int (*Fn) (struct emu10k1_mpuin *, u8);
45} midistatefn[] = {
46
47 {
48 sblive_miStateParse}, {
49 sblive_miState3Byte}, /* 0x8n, 0x9n, 0xAn, 0xBn, 0xEn */
50 {
51 sblive_miState3ByteKey}, /* Byte 1 */
52 {
53 sblive_miState3ByteVel}, /* Byte 2 */
54 {
55 sblive_miState2Byte}, /* 0xCn, 0xDn */
56 {
57 sblive_miState2ByteKey}, /* Byte 1 */
58 {
59 sblive_miStateSysCommon2}, /* 0xF1 , 0xF3 */
60 {
61 sblive_miStateSysCommon2Key}, /* 0xF1 , 0xF3, Byte 1 */
62 {
63 sblive_miStateSysCommon3}, /* 0xF2 */
64 {
65 sblive_miStateSysCommon3Key}, /* 0xF2 , Byte 1 */
66 {
67 sblive_miStateSysCommon3Vel}, /* 0xF2 , Byte 2 */
68 {
69 sblive_miStateSysExNorm}, /* 0xF0, 0xF7, Normal mode */
70 {
71 sblive_miStateSysReal} /* 0xF4 - 0xF6 ,0xF8 - 0xFF */
72};
73
74/* Installs the IRQ handler for the MPU in port */
75
76/* and initialize parameters */
77
78int emu10k1_mpuin_open(struct emu10k1_card *card, struct midi_openinfo *openinfo)
79{
80 struct emu10k1_mpuin *card_mpuin = card->mpuin;
81
82 DPF(2, "emu10k1_mpuin_open\n");
83
84 if (!(card_mpuin->status & FLAGS_AVAILABLE))
85 return CTSTATUS_INUSE;
86
87 /* Copy open info and mark channel as in use */
88 card_mpuin->openinfo = *openinfo;
89 card_mpuin->status &= ~FLAGS_AVAILABLE; /* clear */
90 card_mpuin->status |= FLAGS_READY; /* set */
91 card_mpuin->status &= ~FLAGS_MIDM_STARTED; /* clear */
92 card_mpuin->firstmidiq = NULL;
93 card_mpuin->lastmidiq = NULL;
94 card_mpuin->qhead = 0;
95 card_mpuin->qtail = 0;
96
97 sblive_miStateInit(card_mpuin);
98
99 emu10k1_mpu_reset(card);
100 emu10k1_mpu_acquire(card);
101
102#ifdef TARGET_OS2
103 emu10k1_irq_enable(card, INTE_MIDIRXENABLE);
104#endif
105 return CTSTATUS_SUCCESS;
106}
107
108int emu10k1_mpuin_close(struct emu10k1_card *card)
109{
110 struct emu10k1_mpuin *card_mpuin = card->mpuin;
111
112 DPF(2, "emu10k1_mpuin_close()\n");
113
114 /* Check if there are pending input SysEx buffers */
115 if (card_mpuin->firstmidiq != NULL) {
116 ERROR();
117 return CTSTATUS_ERROR;
118 }
119
120 /* Disable RX interrupt */
121 emu10k1_irq_disable(card, INTE_MIDIRXENABLE);
122
123 emu10k1_mpu_release(card);
124
125 card_mpuin->status |= FLAGS_AVAILABLE; /* set */
126 card_mpuin->status &= ~FLAGS_MIDM_STARTED; /* clear */
127
128 return CTSTATUS_SUCCESS;
129}
130
131/* Adds MIDI buffer to local queue list */
132
133int emu10k1_mpuin_add_buffer(struct emu10k1_mpuin *card_mpuin, struct midi_hdr *midihdr)
134{
135 struct midi_queue *midiq;
136 unsigned long flags;
137
138 DPF(2, "emu10k1_mpuin_add_buffer()\n");
139
140 /* Update MIDI buffer flags */
141 midihdr->flags |= MIDIBUF_INQUEUE; /* set */
142 midihdr->flags &= ~MIDIBUF_DONE; /* clear */
143
144 if ((midiq = (struct midi_queue *) kmalloc(sizeof(struct midi_queue), GFP_ATOMIC)) == NULL) {
145 /* Message lost */
146 return CTSTATUS_ERROR;
147 }
148
149 midiq->next = NULL;
150 midiq->qtype = 1;
151 midiq->length = midihdr->bufferlength;
152 midiq->sizeLeft = midihdr->bufferlength;
153 midiq->midibyte = midihdr->data;
154 midiq->refdata = (unsigned long) midihdr;
155
156 spin_lock_irqsave(&card_mpuin->lock, flags);
157
158 if (card_mpuin->firstmidiq == NULL) {
159 card_mpuin->firstmidiq = midiq;
160 card_mpuin->lastmidiq = midiq;
161 } else {
162 (card_mpuin->lastmidiq)->next = midiq;
163 card_mpuin->lastmidiq = midiq;
164 }
165
166 spin_unlock_irqrestore(&card_mpuin->lock, flags);
167
168 return CTSTATUS_SUCCESS;
169}
170
171/* First set the Time Stamp if MIDI IN has not started. */
172
173/* Then enable RX Irq. */
174
175int emu10k1_mpuin_start(struct emu10k1_card *card)
176{
177 struct emu10k1_mpuin *card_mpuin = card->mpuin;
178 u8 dummy;
179
180 DPF(2, "emu10k1_mpuin_start()\n");
181
182 /* Set timestamp if not set */
183 if (card_mpuin->status & FLAGS_MIDM_STARTED) {
184 DPF(2, "Time Stamp not changed\n");
185 } else {
186 while (emu10k1_mpu_read_data(card, &dummy) == CTSTATUS_SUCCESS);
187
188 card_mpuin->status |= FLAGS_MIDM_STARTED; /* set */
189
190 /* Set new time stamp */
191 card_mpuin->timestart = (jiffies * 1000) / HZ;
192 DPD(2, "New Time Stamp = %d\n", card_mpuin->timestart);
193
194 card_mpuin->qhead = 0;
195 card_mpuin->qtail = 0;
196
197 emu10k1_irq_enable(card, INTE_MIDIRXENABLE);
198 }
199
200 return CTSTATUS_SUCCESS;
201}
202
203/* Disable the RX Irq. If a partial recorded buffer */
204
205/* exist, send it up to IMIDI level. */
206
207int emu10k1_mpuin_stop(struct emu10k1_card *card)
208{
209 struct emu10k1_mpuin *card_mpuin = card->mpuin;
210 struct midi_queue *midiq;
211 unsigned long flags;
212
213 DPF(2, "emu10k1_mpuin_stop()\n");
214
215 emu10k1_irq_disable(card, INTE_MIDIRXENABLE);
216
217 card_mpuin->status &= ~FLAGS_MIDM_STARTED; /* clear */
218
219 if (card_mpuin->firstmidiq) {
220 spin_lock_irqsave(&card_mpuin->lock, flags);
221
222 midiq = card_mpuin->firstmidiq;
223 if (midiq != NULL) {
224 if (midiq->sizeLeft == midiq->length)
225 midiq = NULL;
226 else {
227 card_mpuin->firstmidiq = midiq->next;
228 if (card_mpuin->firstmidiq == NULL)
229 card_mpuin->lastmidiq = NULL;
230 }
231 }
232
233 spin_unlock_irqrestore(&card_mpuin->lock, flags);
234
235 if (midiq) {
236 emu10k1_mpuin_callback(card_mpuin, ICARDMIDI_INLONGERROR, (unsigned long) midiq, 0);
237 kfree(midiq);
238 }
239 }
240
241 return CTSTATUS_SUCCESS;
242}
243
244/* Disable the RX Irq. If any buffer */
245
246/* exist, send it up to IMIDI level. */
247int emu10k1_mpuin_reset(struct emu10k1_card *card)
248{
249 struct emu10k1_mpuin *card_mpuin = card->mpuin;
250 struct midi_queue *midiq;
251
252 DPF(2, "emu10k1_mpuin_reset()\n");
253
254 emu10k1_irq_disable(card, INTE_MIDIRXENABLE);
255
256 while (card_mpuin->firstmidiq) {
257 midiq = card_mpuin->firstmidiq;
258 card_mpuin->firstmidiq = midiq->next;
259
260 if (midiq->sizeLeft == midiq->length)
261 emu10k1_mpuin_callback(card_mpuin, ICARDMIDI_INLONGDATA, (unsigned long) midiq, 0);
262 else
263 emu10k1_mpuin_callback(card_mpuin, ICARDMIDI_INLONGERROR, (unsigned long) midiq, 0);
264
265 kfree(midiq);
266 }
267
268 card_mpuin->lastmidiq = NULL;
269 card_mpuin->status &= ~FLAGS_MIDM_STARTED;
270
271 return CTSTATUS_SUCCESS;
272}
273
274/* Passes the message with the data back to the client */
275
276/* via IRQ & DPC callbacks to Ring 3 */
277int emu10k1_mpuin_callback(struct emu10k1_mpuin *card_mpuin, u32 msg, unsigned long data, u32 bytesvalid)
278{
279 unsigned long timein;
280 struct midi_queue *midiq;
281 unsigned long callback_msg[3];
282 struct midi_hdr *midihdr;
283
284 /* Called during ISR. The data & code touched are:
285 * 1. card_mpuin
286 * 2. The function to be called
287 */
288
289 timein = card_mpuin->timein;
290 if (card_mpuin->timestart <= timein)
291 callback_msg[0] = timein - card_mpuin->timestart;
292 else
293 callback_msg[0] = (~0x0L - card_mpuin->timestart) + timein;
294
295 if (msg == ICARDMIDI_INDATA || msg == ICARDMIDI_INDATAERROR) {
296 callback_msg[1] = data;
297 callback_msg[2] = bytesvalid;
298 DPD(2, "emu10k1_mpuin_callback: midimsg = %lx\n", data);
299 } else {
300 midiq = (struct midi_queue *) data;
301 midihdr = (struct midi_hdr *) midiq->refdata;
302
303 callback_msg[1] = midiq->length - midiq->sizeLeft;
304 callback_msg[2] = midiq->refdata;
305 midihdr->flags &= ~MIDIBUF_INQUEUE;
306 midihdr->flags |= MIDIBUF_DONE;
307
308 midihdr->bytesrecorded = midiq->length - midiq->sizeLeft;
309 }
310
311 /* Notify client that Sysex buffer has been sent */
312 emu10k1_midi_callback(msg, card_mpuin->openinfo.refdata, callback_msg);
313
314 return CTSTATUS_SUCCESS;
315}
316
317void emu10k1_mpuin_bh(unsigned long refdata)
318{
319 u8 data;
320 unsigned idx;
321 struct emu10k1_mpuin *card_mpuin = (struct emu10k1_mpuin *) refdata;
322 unsigned long flags;
323
324 while (card_mpuin->qhead != card_mpuin->qtail) {
325 spin_lock_irqsave(&card_mpuin->lock, flags);
326 idx = card_mpuin->qhead;
327 data = card_mpuin->midiq[idx].data;
328 card_mpuin->timein = card_mpuin->midiq[idx].timein;
329 idx = (idx + 1) % MIDIIN_MAX_BUFFER_SIZE;
330 card_mpuin->qhead = idx;
331 spin_unlock_irqrestore(&card_mpuin->lock, flags);
332
333 sblive_miStateEntry(card_mpuin, data);
334 }
335
336 return;
337}
338
339/* IRQ callback handler routine for the MPU in port */
340
341int emu10k1_mpuin_irqhandler(struct emu10k1_card *card)
342{
343 unsigned idx;
344 unsigned count;
345 u8 MPUIvalue;
346 struct emu10k1_mpuin *card_mpuin = card->mpuin;
347
348 /* IRQ service routine. The data and code touched are:
349 * 1. card_mpuin
350 */
351
352#ifdef TARGET_OS2
353 OSS32_ProcessMidiIRQ((unsigned long)card_mpuin->openinfo.refdata);
354 return CTSTATUS_SUCCESS;
355#else
356 count = 0;
357 idx = card_mpuin->qtail;
358
359 while (1) {
360 if (emu10k1_mpu_read_data(card, &MPUIvalue) == CTSTATUS_SUCCESS) {
361 ++count;
362 card_mpuin->midiq[idx].data = MPUIvalue;
363 card_mpuin->midiq[idx].timein = (jiffies * 1000) / HZ;
364 idx = (idx + 1) % MIDIIN_MAX_BUFFER_SIZE;
365 } else {
366 break;
367 }
368 }
369
370 if (count) {
371 card_mpuin->qtail = idx;
372
373 tasklet_hi_schedule(&card_mpuin->tasklet);
374 }
375
376 return CTSTATUS_SUCCESS;
377#endif
378}
379
380/*****************************************************************************/
381
382/* Supporting functions for Midi-In Interpretation State Machine */
383
384/*****************************************************************************/
385
386/* FIXME: This should be a macro */
387int sblive_miStateInit(struct emu10k1_mpuin *card_mpuin)
388{
389 card_mpuin->status = 0; /* For MIDI running status */
390 card_mpuin->fstatus = 0; /* For 0xFn status only */
391 card_mpuin->curstate = STIN_PARSE;
392 card_mpuin->laststate = STIN_PARSE;
393 card_mpuin->data = 0;
394 card_mpuin->timestart = 0;
395 card_mpuin->timein = 0;
396
397 return CTSTATUS_SUCCESS;
398}
399
400/* FIXME: This should be a macro */
401int sblive_miStateEntry(struct emu10k1_mpuin *card_mpuin, u8 data)
402{
403 return midistatefn[card_mpuin->curstate].Fn(card_mpuin, data);
404}
405
406int sblive_miStateParse(struct emu10k1_mpuin *card_mpuin, u8 data)
407{
408 switch (data & 0xf0) {
409 case 0x80:
410 case 0x90:
411 case 0xA0:
412 case 0xB0:
413 case 0xE0:
414 card_mpuin->curstate = STIN_3BYTE;
415 break;
416
417 case 0xC0:
418 case 0xD0:
419 card_mpuin->curstate = STIN_2BYTE;
420 break;
421
422 case 0xF0:
423 /* System messages do not affect the previous running status! */
424 switch (data & 0x0f) {
425 case 0x0:
426 card_mpuin->laststate = card_mpuin->curstate;
427 card_mpuin->curstate = STIN_SYS_EX_NORM;
428
429 if (card_mpuin->firstmidiq) {
430 struct midi_queue *midiq;
431
432 midiq = card_mpuin->firstmidiq;
433 *midiq->midibyte = data;
434 --midiq->sizeLeft;
435 ++midiq->midibyte;
436 }
437
438 return CTSTATUS_NEXT_BYTE;
439
440 case 0x7:
441 emu10k1_mpuin_callback(card_mpuin, ICARDMIDI_INDATAERROR, 0xf7, 0);
442 return CTSTATUS_ERROR;
443
444 case 0x2:
445 card_mpuin->laststate = card_mpuin->curstate;
446 card_mpuin->curstate = STIN_SYS_COMMON_3;
447 break;
448
449 case 0x1:
450 case 0x3:
451 card_mpuin->laststate = card_mpuin->curstate;
452 card_mpuin->curstate = STIN_SYS_COMMON_2;
453 break;
454
455 default:
456 /* includes 0xF4 - 0xF6, 0xF8 - 0xFF */
457 return midistatefn[STIN_SYS_REAL].Fn(card_mpuin, data);
458 }
459
460 break;
461
462 default:
463 DPF(2, "BUG: default case hit\n");
464 return CTSTATUS_ERROR;
465 }
466
467 return midistatefn[card_mpuin->curstate].Fn(card_mpuin, data);
468}
469
470int sblive_miState3Byte(struct emu10k1_mpuin *card_mpuin, u8 data)
471{
472 u8 temp = data & 0xf0;
473
474 if (temp < 0x80) {
475 return midistatefn[STIN_3BYTE_KEY].Fn(card_mpuin, data);
476 } else if (temp <= 0xe0 && temp != 0xc0 && temp != 0xd0) {
477 card_mpuin->status = data;
478 card_mpuin->curstate = STIN_3BYTE_KEY;
479
480 return CTSTATUS_NEXT_BYTE;
481 }
482
483 return midistatefn[STIN_PARSE].Fn(card_mpuin, data);
484}
485
486int sblive_miState3ByteKey(struct emu10k1_mpuin *card_mpuin, u8 data)
487
488/* byte 1 */
489{
490 unsigned long tmp;
491
492 if (data > 0x7f) {
493 /* Real-time messages check */
494 if (data > 0xf7)
495 return midistatefn[STIN_SYS_REAL].Fn(card_mpuin, data);
496
497 /* Invalid data! */
498 DPF(2, "Invalid data!\n");
499
500 card_mpuin->curstate = STIN_PARSE;
501 tmp = ((unsigned long) data) << 8;
502 tmp |= (unsigned long) card_mpuin->status;
503
504 emu10k1_mpuin_callback(card_mpuin, ICARDMIDI_INDATAERROR, tmp, 0);
505
506 return CTSTATUS_ERROR;
507 }
508
509 card_mpuin->data = data;
510 card_mpuin->curstate = STIN_3BYTE_VEL;
511
512 return CTSTATUS_NEXT_BYTE;
513}
514
515int sblive_miState3ByteVel(struct emu10k1_mpuin *card_mpuin, u8 data)
516
517/* byte 2 */
518{
519 unsigned long tmp;
520
521 if (data > 0x7f) {
522 /* Real-time messages check */
523 if (data > 0xf7)
524 return midistatefn[STIN_SYS_REAL].Fn(card_mpuin, data);
525
526 /* Invalid data! */
527 DPF(2, "Invalid data!\n");
528
529 card_mpuin->curstate = STIN_PARSE;
530 tmp = ((unsigned long) data) << 8;
531 tmp |= card_mpuin->data;
532 tmp = tmp << 8;
533 tmp |= (unsigned long) card_mpuin->status;
534
535 emu10k1_mpuin_callback(card_mpuin, ICARDMIDI_INDATAERROR, tmp, 0);
536
537 return CTSTATUS_ERROR;
538 }
539
540 card_mpuin->curstate = STIN_3BYTE;
541 tmp = (unsigned long) data;
542 tmp = tmp << 8;
543 tmp |= (unsigned long) card_mpuin->data;
544 tmp = tmp << 8;
545 tmp |= (unsigned long) card_mpuin->status;
546
547 emu10k1_mpuin_callback(card_mpuin, ICARDMIDI_INDATA, tmp, 3);
548
549 return CTSTATUS_SUCCESS;
550}
551
552int sblive_miState2Byte(struct emu10k1_mpuin *card_mpuin, u8 data)
553{
554 u8 temp = data & 0xf0;
555
556 if ((temp == 0xc0) || (temp == 0xd0)) {
557 card_mpuin->status = data;
558 card_mpuin->curstate = STIN_2BYTE_KEY;
559
560 return CTSTATUS_NEXT_BYTE;
561 }
562
563 if (temp < 0x80)
564 return midistatefn[STIN_2BYTE_KEY].Fn(card_mpuin, data);
565
566 return midistatefn[STIN_PARSE].Fn(card_mpuin, data);
567}
568
569int sblive_miState2ByteKey(struct emu10k1_mpuin *card_mpuin, u8 data)
570
571/* byte 1 */
572{
573 unsigned long tmp;
574
575 if (data > 0x7f) {
576 /* Real-time messages check */
577 if (data > 0xf7)
578 return midistatefn[STIN_SYS_REAL].Fn(card_mpuin, data);
579
580 /* Invalid data! */
581 DPF(2, "Invalid data!\n");
582
583 card_mpuin->curstate = STIN_PARSE;
584 tmp = (unsigned long) data;
585 tmp = tmp << 8;
586 tmp |= (unsigned long) card_mpuin->status;
587
588 emu10k1_mpuin_callback(card_mpuin, ICARDMIDI_INDATAERROR, tmp, 0);
589
590 return CTSTATUS_ERROR;
591 }
592
593 card_mpuin->curstate = STIN_2BYTE;
594 tmp = (unsigned long) data;
595 tmp = tmp << 8;
596 tmp |= (unsigned long) card_mpuin->status;
597
598 emu10k1_mpuin_callback(card_mpuin, ICARDMIDI_INDATA, tmp, 2);
599
600 return CTSTATUS_SUCCESS;
601}
602
603int sblive_miStateSysCommon2(struct emu10k1_mpuin *card_mpuin, u8 data)
604{
605 card_mpuin->fstatus = data;
606 card_mpuin->curstate = STIN_SYS_COMMON_2_KEY;
607
608 return CTSTATUS_NEXT_BYTE;
609}
610
611int sblive_miStateSysCommon2Key(struct emu10k1_mpuin *card_mpuin, u8 data)
612
613/* byte 1 */
614{
615 unsigned long tmp;
616
617 if (data > 0x7f) {
618 /* Real-time messages check */
619 if (data > 0xf7)
620 return midistatefn[STIN_SYS_REAL].Fn(card_mpuin, data);
621
622 /* Invalid data! */
623 DPF(2, "Invalid data!\n");
624
625 card_mpuin->curstate = card_mpuin->laststate;
626 tmp = (unsigned long) data;
627 tmp = tmp << 8;
628 tmp |= (unsigned long) card_mpuin->fstatus;
629
630 emu10k1_mpuin_callback(card_mpuin, ICARDMIDI_INDATAERROR, tmp, 0);
631
632 return CTSTATUS_ERROR;
633 }
634
635 card_mpuin->curstate = card_mpuin->laststate;
636 tmp = (unsigned long) data;
637 tmp = tmp << 8;
638 tmp |= (unsigned long) card_mpuin->fstatus;
639
640 emu10k1_mpuin_callback(card_mpuin, ICARDMIDI_INDATA, tmp, 2);
641
642 return CTSTATUS_SUCCESS;
643}
644
645int sblive_miStateSysCommon3(struct emu10k1_mpuin *card_mpuin, u8 data)
646{
647 card_mpuin->fstatus = data;
648 card_mpuin->curstate = STIN_SYS_COMMON_3_KEY;
649
650 return CTSTATUS_NEXT_BYTE;
651}
652
653int sblive_miStateSysCommon3Key(struct emu10k1_mpuin *card_mpuin, u8 data)
654
655/* byte 1 */
656{
657 unsigned long tmp;
658
659 if (data > 0x7f) {
660 /* Real-time messages check */
661 if (data > 0xf7)
662 return midistatefn[STIN_SYS_REAL].Fn(card_mpuin, data);
663
664 /* Invalid data! */
665 DPF(2, "Invalid data!\n");
666
667 card_mpuin->curstate = card_mpuin->laststate;
668 tmp = (unsigned long) data;
669 tmp = tmp << 8;
670 tmp |= (unsigned long) card_mpuin->fstatus;
671
672 emu10k1_mpuin_callback(card_mpuin, ICARDMIDI_INDATAERROR, tmp, 0);
673
674 return CTSTATUS_ERROR;
675 }
676
677 card_mpuin->data = data;
678 card_mpuin->curstate = STIN_SYS_COMMON_3_VEL;
679
680 return CTSTATUS_NEXT_BYTE;
681}
682
683int sblive_miStateSysCommon3Vel(struct emu10k1_mpuin *card_mpuin, u8 data)
684
685/* byte 2 */
686{
687 unsigned long tmp;
688
689 if (data > 0x7f) {
690 /* Real-time messages check */
691 if (data > 0xf7)
692 return midistatefn[STIN_SYS_REAL].Fn(card_mpuin, data);
693
694 /* Invalid data! */
695 DPF(2, "Invalid data!\n");
696
697 card_mpuin->curstate = card_mpuin->laststate;
698 tmp = (unsigned long) data;
699 tmp = tmp << 8;
700 tmp |= (unsigned long) card_mpuin->data;
701 tmp = tmp << 8;
702 tmp |= (unsigned long) card_mpuin->fstatus;
703
704 emu10k1_mpuin_callback(card_mpuin, ICARDMIDI_INDATAERROR, tmp, 0);
705
706 return CTSTATUS_ERROR;
707 }
708
709 card_mpuin->curstate = card_mpuin->laststate;
710 tmp = (unsigned long) data;
711 tmp = tmp << 8;
712 tmp |= (unsigned long) card_mpuin->data;
713 tmp = tmp << 8;
714 tmp |= (unsigned long) card_mpuin->fstatus;
715
716 emu10k1_mpuin_callback(card_mpuin, ICARDMIDI_INDATA, tmp, 3);
717
718 return CTSTATUS_SUCCESS;
719}
720
721int sblive_miStateSysExNorm(struct emu10k1_mpuin *card_mpuin, u8 data)
722{
723 unsigned long flags;
724
725 if ((data > 0x7f) && (data != 0xf7)) {
726 /* Real-time messages check */
727 if (data > 0xf7)
728 return midistatefn[STIN_SYS_REAL].Fn(card_mpuin, data);
729
730 /* Invalid Data! */
731 DPF(2, "Invalid data!\n");
732
733 card_mpuin->curstate = card_mpuin->laststate;
734
735 if (card_mpuin->firstmidiq) {
736 struct midi_queue *midiq;
737
738 midiq = card_mpuin->firstmidiq;
739 *midiq->midibyte = data;
740 --midiq->sizeLeft;
741 ++midiq->midibyte;
742
743 spin_lock_irqsave(&card_mpuin->lock, flags);
744
745 card_mpuin->firstmidiq = midiq->next;
746 if (card_mpuin->firstmidiq == NULL)
747 card_mpuin->lastmidiq = NULL;
748
749 spin_unlock_irqrestore(&card_mpuin->lock, flags);
750
751 emu10k1_mpuin_callback(card_mpuin, ICARDMIDI_INLONGERROR, (unsigned long) midiq, 0);
752
753 kfree(midiq);
754 }
755
756 return CTSTATUS_ERROR;
757 }
758
759 if (card_mpuin->firstmidiq) {
760 struct midi_queue *midiq;
761
762 midiq = card_mpuin->firstmidiq;
763 *midiq->midibyte = data;
764 --midiq->sizeLeft;
765 ++midiq->midibyte;
766 }
767
768 if (data == 0xf7) {
769 /* End of Sysex buffer */
770 /* Send down the buffer */
771
772 card_mpuin->curstate = card_mpuin->laststate;
773
774 if (card_mpuin->firstmidiq) {
775 struct midi_queue *midiq;
776
777 midiq = card_mpuin->firstmidiq;
778
779 spin_lock_irqsave(&card_mpuin->lock, flags);
780
781 card_mpuin->firstmidiq = midiq->next;
782 if (card_mpuin->firstmidiq == NULL)
783 card_mpuin->lastmidiq = NULL;
784
785 spin_unlock_irqrestore(&card_mpuin->lock, flags);
786
787 emu10k1_mpuin_callback(card_mpuin, ICARDMIDI_INLONGDATA, (unsigned long) midiq, 0);
788
789 kfree(midiq);
790 }
791
792 return CTSTATUS_SUCCESS;
793 }
794
795 if (card_mpuin->firstmidiq) {
796 struct midi_queue *midiq;
797
798 midiq = card_mpuin->firstmidiq;
799
800 if (midiq->sizeLeft == 0) {
801 /* Special case */
802
803 spin_lock_irqsave(&card_mpuin->lock, flags);
804
805 card_mpuin->firstmidiq = midiq->next;
806 if (card_mpuin->firstmidiq == NULL)
807 card_mpuin->lastmidiq = NULL;
808
809 spin_unlock_irqrestore(&card_mpuin->lock, flags);
810
811 emu10k1_mpuin_callback(card_mpuin, ICARDMIDI_INLONGDATA, (unsigned long) midiq, 0);
812
813 kfree(midiq);
814
815 return CTSTATUS_NEXT_BYTE;
816 }
817 }
818
819 return CTSTATUS_NEXT_BYTE;
820}
821
822int sblive_miStateSysReal(struct emu10k1_mpuin *card_mpuin, u8 data)
823{
824 emu10k1_mpuin_callback(card_mpuin, ICARDMIDI_INDATA, data, 1);
825
826 return CTSTATUS_NEXT_BYTE;
827}
Note: See TracBrowser for help on using the repository browser.