source: GPL/branches/uniaud32-next/drv32/dispatch.c@ 677

Last change on this file since 677 was 677, checked in by Paul Smedley, 4 years ago

More code cleanups from AlexT from #os2russian

File size: 15.5 KB
Line 
1/* $Id: dispatch.c,v 1.1.1.1 2003/07/02 13:56:56 eleph Exp $ */
2/*
3 * Strategy handlers for IOCtl and close
4 *
5 * (C) 2000-2002 InnoTek Systemberatung GmbH
6 * (C) 2000-2001 Sander van Leeuwen (sandervl@xs4all.nl)
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License as
10 * published by the Free Software Foundation; either version 2 of
11 * the License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public
19 * License along with this program; if not, write to the Free
20 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,
21 * USA.
22 *
23 */
24
25#define INCL_NOPMAPI
26#define INCL_DOSMISC
27#include <os2.h>
28
29#include <dbgos2.h>
30#include <ossidc.h>
31#include <ossidc32.h>
32#include <version.h>
33#include <kee.h>
34#include <u32ioctl.h>
35#include "strategy.h"
36
37/*
38 * structure passed to pcm open ioctl
39 */
40#pragma pack(1)
41typedef struct ioctl_pcm {
42 ULONG deviceid; // card number
43 ULONG streamtype; // type of stream (play or record)
44 ULONG pcm; // pcm instance
45 int size; // data size
46 ULONG ret; // return code
47} ioctl_pcm;
48#pragma pack()
49
50ULONG StratIOCtl(REQPACKET __far* rp)
51{
52 USHORT rc = 0;
53 KEEVMLock lhParm, lhData;
54 char *linParm;
55 char *linData;
56 ULONG *pData;
57 ULONG card_id;
58 ULONG ctl_id;
59
60 if (rp->ioctl.bCategory != CAT_IOCTL_OSS32)
61 {
62 //printk("not our cat %x. func %x\n", rp->Category, rp->Function);
63 // not our category, exit with error
64 return (RPERR_BADCOMMAND | RPDONE);
65 }
66
67 #ifdef DEBUG
68 //printk("StratIOCtl 0x%x\n", rp->Function);
69 #endif
70 // printk("cmd: %x, len: %i, pack: %x\n",rp->ioctl.bFunction, rp->ioctl.usParmLen, rp->ioctl.pvParm);
71 // work with Parm Packet
72 if ((rp->ioctl.usParmLen != 0 ||
73 rp->ioctl.bFunction == IOCTL_OSS32_ATTACH /*16 bit ioctl*/) &&
74 ((rp->ioctl.pvParm & 0xfffcffff) != 0))
75 {
76 // got Parm Packet
77 linParm = (char*)KernSelToFlat(rp->ioctl.pvParm);
78
79 if (rp->ioctl.bFunction == IOCTL_OSS32_ATTACH)
80 {
81 rc = KernVMLock(KEE_VML_LONGLOCK, (PVOID)linParm, 4, &lhParm, (KEEVMPageList*)-1, 0);
82 }
83 else
84 {
85 rc = KernVMLock(KEE_VML_LONGLOCK, (PVOID)linParm, rp->ioctl.usParmLen, &lhParm, (KEEVMPageList*)-1, 0);
86 }
87
88 if (rc != 0)
89 {
90 printk("error in KernVMLock rc = %i\n",rc);
91 return (RPERR_PARAMETER | RPDONE);
92 }
93 }
94 else
95 {
96 // no Parm Packet
97 linParm = NULL;
98 }
99
100 // work with Data Packet
101 if ((rp->ioctl.usDataLen != 0) &&
102 ((rp->ioctl.pvData & 0xfffcffff) != 0))
103 {
104 // got Data Packet
105 linData = (char*)KernSelToFlat(rp->ioctl.pvData);
106
107 rc = KernVMLock(KEE_VML_LONGLOCK, (PVOID)linData, rp->ioctl.usDataLen, &lhData, (KEEVMPageList*)-1, 0);
108 if (rc != 0)
109 {
110 printk("error in KernVMLock rc = %i\n",rc);
111 if (linParm != NULL)
112 {
113 // linParm present & locked, must to unlock it
114 KernVMUnlock(&lhParm);
115 }
116 return (RPERR_PARAMETER | RPDONE);
117 }
118 } else
119 {
120 // no Data Packet
121 linData = NULL;
122 }
123
124 // functions handling
125 rc = RPDONE; // ok by default
126
127 switch(rp->ioctl.bFunction)
128 {
129 case IOCTL_OSS32_ATTACH:
130 {
131 dprintf(("OSS32_ATTACH\n"));
132 card_id = (ULONG) *linParm;
133 // Check if audio init was successful
134 if (OSS32_QueryNames(card_id, NULL, 0, NULL, 0, FALSE) != OSSERR_SUCCESS)
135 {
136 rc = RPERR_GENERAL | RPDONE;
137 }
138 } break;
139
140 case IOCTL_OSS32_VERSION:
141 {
142 dprintf(("OSS32_VERSION\n"));
143 if (rp->ioctl.usDataLen < sizeof(ULONG))
144 {
145 // invalid Data Pkt
146 rc = RPERR_PARAMETER | RPDONE;
147 break;
148 }
149 pData = (ULONG *) linData;
150 (*pData) = RM_VERSION;
151
152 } break;
153
154 case IOCTL_OSS32_GET_PCM_NUM:
155 {
156 dprintf(("GET_PCM_NUM\n"));
157 if (rp->ioctl.usDataLen < sizeof(ULONG))
158 {
159 // invalid Data Pkt
160 rc = RPERR_PARAMETER | RPDONE;
161 break;
162 }
163 card_id = (ULONG) *linParm;
164 pData = (ULONG *) linData;
165 (*pData) = GetNumberOfPcm(card_id);
166
167 } break;
168
169 case IOCTL_OSS32_CARDS_NUM:
170 dprintf(("OSS32_CARDS_NUM\n"));
171 if (rp->ioctl.usDataLen < sizeof(ULONG))
172 {
173 // invalid Data Pkt
174 rc = RPERR_PARAMETER | RPDONE;
175 break;
176 }
177 pData = (ULONG *) linData;
178 (*pData) = GetNumberOfCards();
179 break;
180
181 case IOCTL_OSS32_PCM_CAPS:
182 {
183 dprintf(("OSS32_PCM_CAPS\n"));
184 if (rp->ioctl.usDataLen < sizeof(ULONG))
185 {
186 // invalid Data Pkt
187 rc = RPERR_PARAMETER | RPDONE;
188 break;
189 }
190 card_id = (ULONG) *linParm;
191 pData = (ULONG *) linData;
192 GetUniaudPcmCaps(card_id,(void*)*pData);
193 } break;
194
195 case IOCTL_OSS32_CARD_INFO:
196 {
197 dprintf(("OSS32_CARD_INFO\n"));
198 if (rp->ioctl.usDataLen < sizeof(ULONG))
199 {
200 // invalid Data Pkt
201 rc = RPERR_PARAMETER | RPDONE;
202 break;
203 }
204 pData = (ULONG *) linData;
205 card_id = (ULONG) *linParm;
206 GetUniaudCardInfo(card_id,(void*)*pData);
207 } break;
208
209 case IOCTL_OSS32_GET_POWER_STATE:
210 {
211 dprintf(("OSS32_GET_POWER_STATE\n"));
212 if (rp->ioctl.usDataLen < sizeof(ULONG))
213 {
214 // invalid Data Pkt
215 rc = RPERR_PARAMETER | RPDONE;
216 break;
217 }
218 pData = (ULONG *) linData;
219 card_id = (ULONG) *linParm;
220 UniaudCtlGetPowerState(card_id,(void*)*pData);
221 } break;
222
223 case IOCTL_OSS32_SET_POWER_STATE:
224 {
225 dprintf(("OSS32_SET_POWER_STATE\n"));
226 if (rp->ioctl.usDataLen < sizeof(ULONG))
227 {
228 // invalid Data Pkt
229 rc = RPERR_PARAMETER | RPDONE;
230 break;
231 }
232 pData = (ULONG *) linData;
233 card_id = (ULONG) *linParm;
234 UniaudCtlSetPowerState(card_id,(void*)*pData);
235 } break;
236
237 case IOCTL_OSS32_GET_CNTRLS_NUM:
238 {
239 dprintf(("OSS32_GET_CNTRLS_NUM\n"));
240 if (rp->ioctl.usDataLen < sizeof(ULONG))
241 {
242 // invalid Data Pkt
243 rc = RPERR_PARAMETER | RPDONE;
244 break;
245 }
246 pData = (ULONG *) linData;
247 card_id = (ULONG) *linParm;
248 (*pData) = GetUniaudControlNum(card_id);
249
250 } break;
251
252
253 case IOCTL_OSS32_GET_CNTRLS:
254 {
255 dprintf(("OSS32_GET_CNTRLS\n"));
256 if (rp->ioctl.usDataLen < sizeof(ULONG))
257 {
258 // invalid Data Pkt
259 rc = RPERR_PARAMETER | RPDONE;
260 break;
261 }
262 pData = (ULONG *) linData;
263 card_id = (ULONG) *linParm;
264 GetUniaudControls(card_id,(void*)*pData);
265 } break;
266
267 case IOCTL_OSS32_CNTRL_INFO:
268 {
269 dprintf(("OSS32_CNTRL_INFO\n"));
270
271 if (rp->ioctl.usDataLen < sizeof(ULONG))
272 {
273 // invalid Data Pkt
274 rc = RPERR_PARAMETER | RPDONE;
275 break;
276 }
277
278 if (rp->ioctl.usParmLen < sizeof(ULONG))
279 {
280 // invalid Data Pkt
281 rc = RPERR_PARAMETER | RPDONE;
282 break;
283 }
284
285 pData = (ULONG *) linData;
286 ULONG id = *((ULONG *)linParm);
287 card_id = (id >> 16) & 0x0000FFFF;
288 ctl_id = id & 0x0000FFFF;
289// printk("id: %x, card: %x, ctl: %x\n",id, card_id, ctl_id);
290 GetUniaudControlInfo(card_id, ctl_id, (void*)*pData);
291 } break;
292
293 case IOCTL_OSS32_CNTRL_GET:
294 {
295 dprintf(("OSS32_CNTRL_GET\n"));
296 if (rp->ioctl.usDataLen < sizeof(ULONG))
297 {
298 // invalid Data Pkt
299 rc = RPERR_PARAMETER | RPDONE;
300 break;
301 }
302
303 if (rp->ioctl.usParmLen < sizeof(ULONG))
304 {
305 // invalid Data Pkt
306 rc = RPERR_PARAMETER | RPDONE;
307 break;
308 }
309
310 pData = (ULONG *) linData;
311 ULONG id = *((ULONG *)linParm);
312 card_id = (id >> 16) & 0x0000FFFF;
313 ctl_id = id & 0x0000FFFF;
314
315 GetUniaudControlValueGet(card_id, ctl_id,(void*)*pData);
316 } break;
317
318 case IOCTL_OSS32_CNTRL_PUT:
319 {
320 dprintf(("OSS32_CNTRL_PUT\n"));
321
322 if (rp->ioctl.usDataLen < sizeof(ULONG)) {
323 // invalid Data Pkt
324 rc = RPERR_PARAMETER | RPDONE;
325 break;
326 }
327
328 if (rp->ioctl.usParmLen < sizeof(ULONG)) {
329 // invalid Data Pkt
330 rc = RPERR_PARAMETER | RPDONE;
331 break;
332 }
333
334 pData = (ULONG *)linData;
335 ULONG id = *((ULONG *)linParm);
336 card_id = (id >> 16) & 0x0000FFFF;
337 ctl_id = id & 0x0000FFFF;
338
339 GetUniaudControlValuePut(card_id, ctl_id,(void*)*pData);
340 } break;
341
342 case IOCTL_OSS32_SET_PCM:
343 {
344 dprintf(("OSS32_SET_PCM\n"));
345
346 if (rp->ioctl.usParmLen < sizeof(ULONG))
347 {
348 // invalid Data Pkt
349 rc = RPERR_PARAMETER | RPDONE;
350 break;
351 }
352
353 ULONG pcm = (ULONG) *linParm;
354
355 printk("set PCM %i\n",pcm);
356 SetPCMInstance(0, pcm);
357 } break;
358
359 case IOCTL_OSS32_CNTRL_WAIT:
360 {
361 dprintf(("OSS32_CNTRL_WAIT\n"));
362 if (rp->ioctl.usDataLen < sizeof(ULONG))
363 {
364 // invalid Data Pkt
365 rc = RPERR_PARAMETER | RPDONE;
366 break;
367 }
368 ioctl_pcm *pcm = (ioctl_pcm *)linParm;
369 pData = (ULONG *) linData;
370 (*pData) = WaitForControlChange(pcm->deviceid, pcm->streamtype);
371 }
372 break;
373 case IOCTL_OSS32_PCM_OPEN:
374 {
375 pData = (ULONG *)linData;
376 ioctl_pcm *pcm = (ioctl_pcm *)linParm;
377
378 dprintf(("OSS32_PCM_OPEN\n"));
379 // close all pcms from uniaud16 first
380 pcm->ret = OSS32_WaveOpen(pcm->deviceid, pcm->streamtype, pData, pcm->pcm, rp->ioctl.usSysFileNum);
381 }
382 break;
383
384 case IOCTL_OSS32_PCM_CLOSE:
385 {
386 ULONG alsa_id = *((ULONG *)linParm);
387
388 dprintf(("OSS32_PCM_CLOSE\n"));
389 OSS32_WaveClose(alsa_id);
390 }
391 break;
392 case IOCTL_OSS32_PCM_READ:
393 {
394 char *pData1 = (char *)linData;
395 ioctl_pcm *pcm = (ioctl_pcm *)linParm;
396
397 dprintf(("OSS32_PCM_READ\n"));
398 pcm->ret = UniaudIoctlPCMRead(pcm->deviceid, pData1, pcm->size);
399 }
400 break;
401 case IOCTL_OSS32_PCM_WRITE:
402 {
403 char *pData1 = (char *)linData;
404 ioctl_pcm *pcm = (ioctl_pcm *)linParm;
405
406 dprintf(("OSS32_PCM_WRITE\n"));
407 pcm->ret = UniaudIoctlPCMWrite(pcm->deviceid, pData1, pcm->size);
408 }
409 break;
410 case IOCTL_OSS32_PCM_PAUSE:
411 {
412 ioctl_pcm *pcm = (ioctl_pcm *)linParm;
413
414 dprintf(("OSS32_PCM_PAUSE\n"));
415 pcm->ret = UniaudIoctlPCMResume(pcm->deviceid, 0);
416 }
417 break;
418 case IOCTL_OSS32_PCM_RESUME:
419 {
420 ioctl_pcm *pcm = (ioctl_pcm *)linParm;
421
422 dprintf(("OSS32_PCM_RESUME\n"));
423 pcm->ret = UniaudIoctlPCMResume(pcm->deviceid, 1);
424 }
425 break;
426 case IOCTL_OSS32_PCM_START:
427 {
428 ioctl_pcm *pcm = (ioctl_pcm *)linParm;
429
430 dprintf(("OSS32_PCM_START\n"));
431 pcm->ret = UniaudIoctlPCMStart(pcm->deviceid);
432 }
433 break;
434 case IOCTL_OSS32_PCM_DROP:
435 {
436 ioctl_pcm *pcm = (ioctl_pcm *)linParm;
437
438 dprintf(("OSS32_PCM_DROP\n"));
439 pcm->ret = UniaudIoctlPCMDrop(pcm->deviceid);
440 }
441 break;
442 case IOCTL_OSS32_PCM_DRAIN:
443 break;
444 case IOCTL_OSS32_PCM_STATUS:
445 {
446 void *pData1 = (void *)linData;
447 ioctl_pcm *pcm = (ioctl_pcm *)linParm;
448
449 dprintf(("OSS32_PCM_STATUS\n"));
450 pcm->ret = UniaudIoctlPCMStatus(pcm->deviceid, pData1);
451 }
452 break;
453 case IOCTL_OSS32_PCM_REFINEHWPARAMS:
454 {
455 void *pData1 = (void *)linData;
456 ioctl_pcm *pcm = (ioctl_pcm *)linParm;
457
458 dprintf(("OSS32_PCM_REFINEHWPARAMS\n"));
459 pcm->ret = UniaudIoctlHWRefine(pcm->deviceid, pData1);
460 }
461 break;
462 case IOCTL_OSS32_PCM_SETHWPARAMS:
463 {
464 void *pData1 = (void *)linData;
465 ioctl_pcm *pcm = (ioctl_pcm *)linParm;
466
467 dprintf(("OSS32_PCM_SETHWPARAMS\n"));
468 pcm->ret = UniaudIoctlHWParamSet(pcm->deviceid, pData1);
469 }
470 break;
471 case IOCTL_OSS32_PCM_SETSWPARAMS:
472 {
473 void *pData1 = (void *)linData;
474 ioctl_pcm *pcm = (ioctl_pcm *)linParm;
475
476 dprintf(("OSS32_PCM_SETSWPARAMS\n"));
477 pcm->ret = UniaudIoctlSWParamSet(pcm->deviceid, pData1);
478 }
479 break;
480 case IOCTL_OSS32_PCM_PREPARE:
481 {
482 ioctl_pcm *pcm = (ioctl_pcm *)linParm;
483
484 dprintf(("OSS32_PCM_PREPARE\n"));
485 pcm->ret = UniaudIoctlPCMPrepare(pcm->deviceid);
486 }
487 break;
488
489 case IOCTL_OSS32_PCM_CLOSE_ALL:
490 {
491 int unlock = (int)*linParm;
492
493 dprintf(("OSS32_PCM_CLOSE_ALL\n"));
494 if (unlock)
495 unlock_all = 1;
496 else
497 UniaudCloseAll(0);
498 }
499 break;
500 case IOCTL_OSS32_PCM_CLOSE_16:
501 dprintf(("OSS32_PCM_CLOSE_16\n"));
502 OSS32_CloseUNI16();
503 break;
504 case IOCTL_OSS32_PCM_WAIT_INT:
505 {
506 ioctl_pcm *pcm = (ioctl_pcm *)linParm;
507
508 dprintf(("OSS32_PCM_WAIT_INT\n"));
509 pcm->ret = WaitForPCMInterrupt((void*)pcm->deviceid, pcm->streamtype);
510 }
511 break;
512
513 default:
514 {
515 printk("invalid function code %i\n",rp->ioctl.bFunction);
516 // invalid function code
517 rc = RPERR_PARAMETER | RPDONE;
518 } break;
519 }
520
521 // unlock Parm & Data if needed
522 if (linParm != NULL)
523 {
524 // linParm present & locked, must to unlock it
525 KernVMUnlock(&lhParm);
526 }
527 if (linData != NULL)
528 {
529 // linData present & locked, must to unlock it
530 KernVMUnlock(&lhData);
531 }
532
533 // all done
534 return (rc);
535}
Note: See TracBrowser for help on using the repository browser.