source: cmedia/trunk/Sblive/cardmo.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: 6.4 KB
Line 
1/* $Id: cardmo.c,v 1.1 2000/04/23 14:55:42 ktk Exp $ */
2
3
4/*
5 **********************************************************************
6 * cardmo.c - MIDI UART output 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 cleaned 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 "cardmo.h"
38
39/* Installs the IRQ handler for the MPU out port *
40 * and initialize parameters */
41
42int emu10k1_mpuout_open(struct emu10k1_card *card, struct midi_openinfo *openinfo)
43{
44 struct emu10k1_mpuout *card_mpuout = card->mpuout;
45
46 DPF(2, "emu10k1_mpuout_open()\n");
47
48 if (!(card_mpuout->status & FLAGS_AVAILABLE))
49 return CTSTATUS_INUSE;
50
51 /* Copy open info and mark channel as in use */
52 card_mpuout->intr = 0;
53 card_mpuout->openinfo = *openinfo;
54 card_mpuout->status &= ~FLAGS_AVAILABLE;
55 card_mpuout->laststatus = 0x80;
56 card_mpuout->firstmidiq = NULL;
57 card_mpuout->lastmidiq = NULL;
58
59 emu10k1_mpu_reset(card);
60 emu10k1_mpu_acquire(card);
61
62 return CTSTATUS_SUCCESS;
63}
64
65int emu10k1_mpuout_close(struct emu10k1_card *card)
66{
67 struct emu10k1_mpuout *card_mpuout = card->mpuout;
68 struct midi_queue *midiq;
69 struct midi_hdr *midihdr;
70 unsigned long flags;
71
72 DPF(2, "emu10k1_mpuout_close()\n");
73
74 emu10k1_irq_disable(card, INTE_MIDITXENABLE);
75
76 spin_lock_irqsave(&card_mpuout->lock, flags);
77
78 while (card_mpuout->firstmidiq != NULL) {
79 midiq = card_mpuout->firstmidiq;
80 midihdr = (struct midi_hdr *) midiq->refdata;
81
82 card_mpuout->firstmidiq = midiq->next;
83
84 kfree(midihdr->data);
85 kfree(midihdr);
86 kfree(midiq);
87 }
88
89 card_mpuout->lastmidiq = NULL;
90
91 emu10k1_mpu_release(card);
92
93 card_mpuout->status |= FLAGS_AVAILABLE;
94
95 spin_unlock_irqrestore(&card_mpuout->lock, flags);
96
97 return CTSTATUS_SUCCESS;
98}
99
100/* If there isn't enough buffer space, reject Midi Buffer. *
101* Otherwise, disable TX, create object to hold Midi *
102* uffer, update buffer flags and other parameters *
103* before enabling TX again. */
104
105int emu10k1_mpuout_add_buffer(struct emu10k1_card *card, struct midi_hdr *midihdr)
106{
107 struct emu10k1_mpuout *card_mpuout = card->mpuout;
108 struct midi_queue *midiq;
109 unsigned long flags;
110
111 DPF(2, "emu10k1_mpuout_add_buffer()\n");
112
113 if (card_mpuout->state == CARDMIDIOUT_STATE_SUSPEND)
114 return CTSTATUS_SUCCESS;
115
116 midihdr->flags |= MIDIBUF_INQUEUE;
117 midihdr->flags &= ~MIDIBUF_DONE;
118
119 if ((midiq = (struct midi_queue *) kmalloc(sizeof(struct midi_queue), GFP_KERNEL)) == NULL) {
120 /* Message lost */
121 return CTSTATUS_NOMEMORY;
122 }
123
124 midiq->next = NULL;
125 midiq->qtype = 1;
126 midiq->length = midihdr->bufferlength;
127 midiq->sizeLeft = midihdr->bufferlength;
128 midiq->midibyte = midihdr->data;
129
130 midiq->refdata = (unsigned long) midihdr;
131
132 spin_lock_irqsave(&card_mpuout->lock, flags);
133
134 if (card_mpuout->firstmidiq == NULL) {
135 card_mpuout->firstmidiq = midiq;
136 card_mpuout->lastmidiq = midiq;
137 } else {
138 (card_mpuout->lastmidiq)->next = midiq;
139 card_mpuout->lastmidiq = midiq;
140 }
141
142 card_mpuout->intr = 0;
143
144 emu10k1_irq_enable(card, INTE_MIDITXENABLE);
145
146 spin_unlock_irqrestore(&card_mpuout->lock, flags);
147
148 return CTSTATUS_SUCCESS;
149}
150
151void emu10k1_mpuout_bh(unsigned long refdata)
152{
153 struct emu10k1_card *card = (struct emu10k1_card *) refdata;
154 struct emu10k1_mpuout *card_mpuout = card->mpuout;
155 int cByteSent = 0;
156 int status;
157 struct midi_queue *midiq;
158 struct midi_queue *doneq = NULL;
159 unsigned long flags;
160
161 spin_lock_irqsave(&card_mpuout->lock, flags);
162
163 while (card_mpuout->firstmidiq != NULL) {
164 midiq = card_mpuout->firstmidiq;
165
166 while (cByteSent < 4 && midiq->sizeLeft) {
167 status = emu10k1_mpu_write_data(card, *midiq->midibyte);
168
169 if (status == CTSTATUS_SUCCESS) {
170 ++cByteSent;
171 --midiq->sizeLeft;
172 ++midiq->midibyte;
173 } else {
174 DPF(2, "emu10k1_mpuoutDpcCallback error!!\n");
175 }
176 }
177
178 if (midiq->sizeLeft == 0) {
179 if (doneq == NULL)
180 doneq = midiq;
181 card_mpuout->firstmidiq = midiq->next;
182 } else
183 break;
184 }
185
186 if (card_mpuout->firstmidiq == NULL)
187 card_mpuout->lastmidiq = NULL;
188
189 if (doneq != NULL) {
190 while (doneq != card_mpuout->firstmidiq) {
191 unsigned long callback_msg[3];
192
193 midiq = doneq;
194 doneq = midiq->next;
195
196 if (midiq->qtype) {
197 callback_msg[0] = 0;
198 callback_msg[1] = midiq->length;
199 callback_msg[2] = midiq->refdata;
200
201 emu10k1_midi_callback(ICARDMIDI_OUTLONGDATA, card_mpuout->openinfo.refdata, callback_msg);
202 } else if (((u8) midiq->refdata) < 0xF0 && ((u8) midiq->refdata) > 0x7F)
203 card_mpuout->laststatus = (u8) midiq->refdata;
204
205 kfree(midiq);
206 }
207 }
208
209 if ((card_mpuout->firstmidiq != NULL) || cByteSent) {
210 card_mpuout->intr = 0;
211 emu10k1_irq_enable(card, INTE_MIDITXENABLE);
212 }
213
214 spin_unlock_irqrestore(&card_mpuout->lock, flags);
215
216 return;
217}
218
219int emu10k1_mpuout_irqhandler(struct emu10k1_card *card)
220{
221 struct emu10k1_mpuout *card_mpuout = card->mpuout;
222
223 DPF(4, "emu10k1_mpuout_irqhandler\n");
224
225 card_mpuout->intr = 1;
226 emu10k1_irq_disable(card, INTE_MIDITXENABLE);
227
228 tasklet_hi_schedule(&card_mpuout->tasklet);
229
230 return CTSTATUS_SUCCESS;
231}
Note: See TracBrowser for help on using the repository browser.