source: cmedia/trunk/Sblive/cardmi.c@ 354

Last change on this file since 354 was 354, checked in by stevenhl, 17 years ago

Import untested baseline cmedia sources, work products and binaries
Binaries and work products should be deleted from repository.
once new builds are verified to work.

File size: 20.7 KB
Line 
1/* $Id: cardmi.c,v 1.2 2000/05/28 16:50:45 sandervl Exp $ */
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.