Get rid of question mark, the vendor ID is correct.
[dragonfly.git] / sys / dev / sound / isa / i386 / patmgr.c
1 /*
2  * sound/patmgr.c
3  * 
4  * The patch maneger interface for the /dev/sequencer
5  * 
6  * Copyright by Hannu Savolainen 1993
7  * 
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions are
10  * met: 1. Redistributions of source code must retain the above copyright
11  * notice, this list of conditions and the following disclaimer. 2.
12  * Redistributions in binary form must reproduce the above copyright notice,
13  * this list of conditions and the following disclaimer in the documentation
14  * and/or other materials provided with the distribution.
15  * 
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY
17  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19  * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
20  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
23  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26  * SUCH DAMAGE.
27  * 
28  * $DragonFly: src/sys/dev/sound/isa/i386/Attic/patmgr.c,v 1.2 2003/08/07 21:17:12 dillon Exp $
29  */
30
31 #define PATMGR_C
32 #include "sound_config.h"
33
34 #if defined(CONFIG_SEQUENCER)
35
36 static int     *server_procs[MAX_SYNTH_DEV] = {NULL};
37 static volatile struct snd_wait server_wait_flag[MAX_SYNTH_DEV] = { {0}};
38
39 static struct patmgr_info *mbox[MAX_SYNTH_DEV] = {NULL};
40 static volatile int msg_direction[MAX_SYNTH_DEV] = {0};
41
42 static int      pmgr_opened[MAX_SYNTH_DEV] = {0};
43
44 #define A_TO_S  1
45 #define S_TO_A  2
46
47 static int     *appl_proc = NULL;
48 static volatile struct snd_wait appl_wait_flag =
49 {0};
50
51 int
52 pmgr_open(int dev)
53 {
54     if (dev < 0 || dev >= num_synths)
55         return -(ENXIO);
56
57     if (pmgr_opened[dev])
58         return -(EBUSY);
59     pmgr_opened[dev] = 1;
60
61     server_wait_flag[dev].aborting = 0;
62     server_wait_flag[dev].mode = WK_NONE;
63
64     return 0;
65 }
66
67 void
68 pmgr_release(int dev)
69 {
70
71     if (mbox[dev]) {    /* Killed in action. Inform the client */
72
73         mbox[dev]->key = PM_ERROR;
74         mbox[dev]->parm1 = -(EIO);
75
76         if ((appl_wait_flag.mode & WK_SLEEP)) {
77             appl_wait_flag.mode = WK_WAKEUP;
78             wakeup(appl_proc);
79         };
80     }
81     pmgr_opened[dev] = 0;
82 }
83
84 int
85 pmgr_read(int dev, struct fileinfo * file, snd_rw_buf * buf, int count)
86 {
87     u_long   flags;
88     int             ok = 0;
89
90     if (count != sizeof(struct patmgr_info)) {
91         printf("PATMGR%d: Invalid read count\n", dev);
92         return -(EIO);
93     }
94     while (!ok && !(server_wait_flag[dev].aborting)) {
95         flags = splhigh();
96
97         while (!(mbox[dev] && msg_direction[dev] == A_TO_S) &&
98                !(server_wait_flag[dev].aborting)) {
99
100             int  chn;
101             server_procs[dev] = &chn;
102             DO_SLEEP(chn, server_wait_flag[dev], 0); 
103
104         }
105
106         if (mbox[dev] && msg_direction[dev] == A_TO_S) {
107
108             if (uiomove((char *) mbox[dev], count, buf)) {
109                 printf("sb: Bad copyout()!\n");
110             };
111             msg_direction[dev] = 0;
112             ok = 1;
113         }
114         splx(flags);
115
116     }
117
118     if (!ok)
119         return -(EINTR);
120     return count;
121 }
122
123 int
124 pmgr_write(int dev, struct fileinfo * file, snd_rw_buf * buf, int count)
125 {
126     u_long   flags;
127
128     if (count < 4) {
129         printf("PATMGR%d: Write count < 4\n", dev);
130         return -(EIO);
131     }
132     if (uiomove((char *) mbox[dev], 4, buf)) {
133         printf("sb: Bad copyin()!\n");
134     };
135
136     if (*(u_char *) mbox[dev] == SEQ_FULLSIZE) {
137         int             tmp_dev;
138
139         tmp_dev = ((u_short *) mbox[dev])[2];
140         if (tmp_dev != dev)
141             return -(ENXIO);
142
143         return synth_devs[dev]->load_patch(dev, *(u_short *) mbox[dev],
144                                                    buf, 4, count, 1);
145     }
146     if (count != sizeof(struct patmgr_info)) {
147         printf("PATMGR%d: Invalid write count\n", dev);
148         return -(EIO);
149     }
150     /*
151      * If everything went OK, there should be a preallocated buffer in
152      * the mailbox and a client waiting.
153      */
154
155     flags = splhigh();
156
157     if (mbox[dev] && !msg_direction[dev]) {
158
159         if (uiomove(&((char *) mbox[dev])[4], count - 4, buf)) {
160             printf("sb: Bad copyin()!\n");
161         };
162         msg_direction[dev] = S_TO_A;
163
164         if ((appl_wait_flag.mode & WK_SLEEP)) {
165             appl_wait_flag.mode = WK_WAKEUP;
166             wakeup(appl_proc);
167         }
168     }
169     splx(flags);
170
171     return count;
172 }
173
174 int
175 pmgr_access(int dev, struct patmgr_info * rec)
176 {
177     u_long   flags;
178     int             err = 0;
179
180     flags = splhigh();
181
182     if (mbox[dev])
183         printf("  PATMGR: Server %d mbox full. Why?\n", dev);
184     else {
185         int             chn;
186
187         rec->key = PM_K_COMMAND;
188         mbox[dev] = rec;
189         msg_direction[dev] = A_TO_S;
190
191         if ((server_wait_flag[dev].mode & WK_SLEEP)) {
192             server_wait_flag[dev].mode = WK_WAKEUP;
193             wakeup(server_procs[dev]);
194         }
195
196
197         appl_proc = &chn;
198         DO_SLEEP(chn, appl_wait_flag, 0);
199
200         if (msg_direction[dev] != S_TO_A) {
201             rec->key = PM_ERROR;
202             rec->parm1 = -(EIO);
203         } else if (rec->key == PM_ERROR) {
204             err = rec->parm1;
205             if (err > 0)
206                 err = -err;
207         }
208         mbox[dev] = NULL;
209         msg_direction[dev] = 0;
210     }
211
212     splx(flags);
213
214     return err;
215 }
216
217 int
218 pmgr_inform(int dev, int event, u_long p1, u_long p2, u_long p3, u_long p4)
219 {
220     u_long   flags;
221     int             err = 0;
222
223     struct patmgr_info *tmp_mbox;
224
225     if (!pmgr_opened[dev])
226         return 0;
227
228     tmp_mbox = (struct patmgr_info *) malloc(sizeof(struct patmgr_info), M_TEMP, M_WAITOK);
229
230     if (tmp_mbox == NULL) {
231         printf("pmgr: Couldn't allocate memory for a message\n");
232         return 0;
233     }
234     flags = splhigh();
235
236     if (mbox[dev])
237         printf("  PATMGR: Server %d mbox full. Why?\n", dev);
238     else {
239         int             chn;
240
241         mbox[dev] = tmp_mbox;
242         mbox[dev]->key = PM_K_EVENT;
243         mbox[dev]->command = event;
244         mbox[dev]->parm1 = p1;
245         mbox[dev]->parm2 = p2;
246         mbox[dev]->parm3 = p3;
247         msg_direction[dev] = A_TO_S;
248
249         if ((server_wait_flag[dev].mode & WK_SLEEP)) {
250             server_wait_flag[dev].mode = WK_WAKEUP;
251             wakeup(server_procs[dev]);
252         }
253
254
255         appl_proc = &chn;
256         DO_SLEEP(chn, appl_wait_flag, 0);
257
258         mbox[dev] = NULL;
259         msg_direction[dev] = 0;
260     }
261
262     splx(flags);
263     free(tmp_mbox, M_TEMP);
264
265     return err;
266 }
267
268 #endif