source: sbliveos2/trunk/sblive/cardmi.c@ 142

Last change on this file since 142 was 142, checked in by ktk, 25 years ago

Import

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