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

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

More code cleanups from AlexT from #os2russian

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