source: GPL/trunk/drv32/dispatch.c@ 479

Last change on this file since 479 was 479, checked in by David Azarewicz, 15 years ago

Cleanup compiler warnings

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