source: sbliveos2/trunk/drv16/ioctl.cpp@ 145

Last change on this file since 145 was 142, checked in by ktk, 25 years ago

Import

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 17.8 KB
Line 
1/* $Id: ioctl.cpp 142 2000-04-23 14:55:46Z ktk $ */
2
3/* SCCSID = %W% %E% */
4/****************************************************************************
5 * *
6 * Copyright (c) IBM Corporation 1994 - 1997. *
7 * *
8 * The following IBM OS/2 source code is provided to you solely for the *
9 * the purpose of assisting you in your development of OS/2 device drivers. *
10 * You may use this code in accordance with the IBM License Agreement *
11 * provided in the IBM Device Driver Source Kit for OS/2. *
12 * *
13 ****************************************************************************/
14/**@internal %W%
15 * @notes
16 * the functions that implement all the IOCTLs (command 10x) received by
17 * the device driver via the strategy entry.
18 * @version %I%
19 * @context Unless otherwise noted, all interfaces are Ring-0, 16-bit,
20 * <stack context>.
21 * @history
22 *
23 */
24#define INCL_NOPMAPI
25#include <os2.h>
26#include <audio.h>
27
28#include "strategy.h"
29#include "audiohw.hpp"
30#include "mpu401.hpp"
31#include "wavehw.hpp"
32#include "wavestrm.hpp"
33#include "midistrm.hpp"
34
35#include <include.h>
36#include <sbvsd.h>
37#include <dbgos2.h>
38#include <devhelp.h>
39#include <ossidc.h>
40#include <ioctl90.h>
41#include <parse.h>
42#include "ioctl.h"
43
44//Map of possible 256 supported ioctls (IOCTl 90 mixer api)
45char SBLiveIOCTLMap[256] = {0};
46MIXSTRUCT MixerSettings[16] = {0};
47
48//override flags for rec src & gain mixer commands
49BOOL fRecSrcIOCTL90 = FALSE;
50BOOL fRecGainIOCTL90 = FALSE;
51
52/**@internal
53 * @param PREQPACKET pointer to the strategy request packet
54 * @return None But the Status in the request packet is updated on error
55 * @notes
56 * The Audio Init Ioctl only 2 things happen in here :
57 * 1. We call CheckForStream to make sure there is not already a stream
58 * registered with the same sysfilenumber. If we get a good rc from that
59 * 2: we look at sMode in the MCI_AUDIO_INIT to determine the type of stream
60 * to init and call the approprate stream constructor.
61 *
62 */
63void IoctlAudioInit(PREQPACKET prp, USHORT LDev)
64{
65 LPMCI_AUDIO_INIT p = (LPMCI_AUDIO_INIT)prp->s.ioctl.pvData;
66 PAUDIOHW pHWobj;
67 PSTREAM pstream;
68 ULONG HardwareType;
69
70 // if this is an IDLE or De-Init request
71 // fetch the stream object based on the sysfilenum and turn on the
72 // stream idle bit in the stream state then write the sysfilenum
73 // into the request packet, set rc = 0 and return
74 if (p->sMode == IDLE) {
75 pstream = FindStream_fromFile((ULONG) prp->s.ioctl.usSysFileNum);
76 if (pstream)
77 pstream->ulStreamState |= STREAM_IDLE;
78 p->pvReserved = (VOID FAR *) (ULONG)prp->s.ioctl.usSysFileNum;
79 p->sReturnCode = 0;
80 return;
81 }
82 // call FindStream_fromFile to see if there is already a stream
83 // for this sysfilenum. if there is then see if the idle bit is on,
84 // if the idle bit is on, reset it, then write the sysfilenum
85 // into the request packet, set rc = 0 and return
86 // MMPM sends idle down to a stream that is "losing" the hardware but
87 // should not go away. It usually is associated with an app losing
88 // focus. If the idle bit is not the stream is either not registered or
89 // is being "re-initted" in another mode or with different file
90 // attributes. "Re-initting" a stream is a total hack on the part
91 // of MMPM they should de-register the stream and then init a new
92 // stream but they don't . If anyone ever writes a VSD that behaves
93 // "correctly" then this code can be deleted.
94 // Either way delete the stream and build a new one with
95 // this request packet.
96 pstream = FindStream_fromFile((ULONG) prp->s.ioctl.usSysFileNum);
97 if (pstream) {
98 if (pstream->ulStreamState & STREAM_IDLE) {
99 pstream->ulStreamState &= STREAM_NOT_IDLE;
100 p->pvReserved = (VOID FAR *) (ULONG)prp->s.ioctl.usSysFileNum;
101 p->sReturnCode = 0;
102 return;
103 }
104 else {
105 delete pstream;
106 }
107 }
108
109 // get the hardware type
110 // return with bad status if the harware type is invalid/unsupported
111 HardwareType = GetHardwareType(p->sMode, (USHORT)p->ulOperation, LDev);
112 if (HardwareType == AUDIOHW_INVALID_DEVICE) {
113 p->sReturnCode = INVALID_REQUEST;
114 prp->usStatus |= RPERR;
115 return;
116 }
117 // make sure we have a Hardware object that can handle this
118 // data type and operation..
119 pHWobj = GetHardwareDevice(HardwareType);
120 if (pHWobj == NULL) {
121 p->sReturnCode = INVALID_REQUEST;
122 prp->usStatus |= RPERR;
123 return;
124 }
125
126 p->ulFlags = 0; /* Zero the Flags */
127 switch (HardwareType) {
128 case AUDIOHW_WAVE_PLAY:
129 case AUDIOHW_WAVE_CAPTURE:
130 pstream = new WAVESTREAM(HardwareType,p,prp->s.ioctl.usSysFileNum);
131 break;
132#if 0
133 case AUDIOHW_FMSYNTH_CAPTURE:
134 case AUDIOHW_FMSYNTH_PLAY:
135 case AUDIOHW_MPU401_CAPTURE:
136 case AUDIOHW_MPU401_PLAY:
137 pstream = new MIDISTREAM(HardwareType);
138 break;
139#endif
140 default:
141 p->sReturnCode = INVALID_REQUEST;
142 prp->usStatus |= RPERR;
143 return;
144 } /* endswitch */
145
146 p->ulFlags |= VOLUME; /* volume control is supported */
147 p->ulFlags |= INPUT; /* Input select is supported */
148 p->ulFlags |= OUTPUT; /* Output select is supported */
149 p->ulFlags |= MONITOR; /* Record Monitor is supported */
150 p->sDeviceID = SB_LIVE; /* Reported in VSD dll */
151 pstream->ulSysFileNum = prp->s.ioctl.usSysFileNum;
152 p->pvReserved = (VOID FAR *) (ULONG) prp->s.ioctl.usSysFileNum;
153 p->sReturnCode = 0;
154 dprintf(("IoctlAudioInit: file nr: %lx", pstream->ulSysFileNum));
155}
156
157
158/**@internal
159 * @param PREQPACKET pointer to the strategy request packet
160 * @return None But the Status in the request packet is updated on error
161 * @notes
162 */
163void IoctlAudioCapability(PREQPACKET prp, USHORT LDev)
164{
165 PAUDIOHW pHWobj;
166 PAUDIO_CAPS p = (PAUDIO_CAPS)prp->s.ioctl.pvData;
167 ULONG ulDevicetype;
168
169 // get the hardware device type based on the datatype and operation
170 ulDevicetype = GetHardwareType((USHORT)p->ulDataType,(USHORT)p->ulOperation,LDev);
171
172 // Tell the caller we support this IOCTL
173 p->ulCapability = SUPPORT_CAP;
174
175 // get the pointer to the hardware object
176 // call DevCaps
177 // bailout if no hardware object is returned..
178 pHWobj = GetHardwareDevice(ulDevicetype);
179 if (pHWobj) {
180 pHWobj->DevCaps(p);
181 if (p->ulSupport != SUPPORT_SUCCESS) {
182 prp->usStatus |= RPERR;
183 }
184 }
185 else {
186 p->ulSupport = UNSUPPORTED_DATATYPE;
187 prp->usStatus |= RPERR;
188 }
189}
190
191/**@internal IoctlAudioControl
192 * @param PREQPACKET pointer to the strategy request packet
193 * @return None But the Status in the request packet is updated on error
194 * @notes
195 * if it's AUDIO_CHANGE, just report success, otherwise report failure
196 * this is because we don't support volume, balance, multiple in/out devices,
197 * etc. Also, START, STOP, RESUME, and PAUSE are redundant, so we don't
198 * support those either.
199 */
200void IoctlAudioControl(PREQPACKET prp)
201{
202 LPMCI_AUDIO_CONTROL p = (LPMCI_AUDIO_CONTROL) prp->s.ioctl.pvData;
203 LPMCI_AUDIO_CHANGE pAudChange;
204 LPMCI_TRACK_INFO pMasterVol;
205 PSTREAM pStream;
206
207 if (p->usIOCtlRequest != AUDIO_CHANGE) {
208 p->sReturnCode = INVALID_REQUEST;
209 prp->usStatus |= RPERR | RPBADCMD;
210 return;
211 }
212 p->sReturnCode=0;
213
214 pAudChange = (LPMCI_AUDIO_CHANGE)p->pbRequestInfo;
215
216 if(DevHelp_VerifyAccess(SELECTOROF(pAudChange), sizeof(MCI_AUDIO_CHANGE), OFFSETOF(pAudChange), VERIFY_READONLY))
217 {
218 dprintf(("Invalid MCI_AUDIO_CHANGE pointer %lx!!", (ULONG)pAudChange));
219 p->sReturnCode = INVALID_REQUEST;
220 prp->usStatus |= RPERR | RPBADCMD;
221 return;
222 }
223 pMasterVol = (LPMCI_TRACK_INFO)pAudChange->pvDevInfo;
224 if(DevHelp_VerifyAccess(SELECTOROF(pMasterVol), sizeof(MCI_TRACK_INFO), OFFSETOF(pMasterVol), VERIFY_READONLY))
225 {
226 dprintf(("Invalid MCI_TRACK_INFO pointer %lx!!", (ULONG)pMasterVol));
227 p->sReturnCode = INVALID_REQUEST;
228 prp->usStatus |= RPERR | RPBADCMD;
229 return;
230 }
231
232 pStream = FindStream_fromFile((ULONG) prp->s.ioctl.usSysFileNum);
233 if(pStream == NULL) {
234 dprintf(("IoctlAudioControl stream %lx not found!", (ULONG) prp->s.ioctl.usSysFileNum));
235 DebugInt3();
236 return;
237 }
238 if(pAudChange->lBalance != AUDIO_IGNORE)
239 pStream->SetBalance(pAudChange->lBalance);
240
241 if(pAudChange->lVolume != AUDIO_IGNORE)
242 pStream->SetVolume(pAudChange->lVolume);
243
244 if(pMasterVol && pMasterVol->usMasterVolume != AUDIO_IGNORE) {
245 // master volume ranges from 0 to 0x7FFF (linear)
246 ULONG volume = pMasterVol->usMasterVolume;
247
248 volume = (volume*100UL)/0x7FFFUL;
249 if(volume > 100) {
250 volume = 100;
251 }
252 volume = (((USHORT)volume << 16) | (USHORT)volume);
253 pStream->SetMasterVol(volume);
254 }
255 for(int i=0;i<8;i++)
256 {
257 switch(pAudChange->rInputList[0].ulDevType) {
258 case NULL_INPUT:
259 break; //continue;
260 case STEREO_LINE_INPUT:
261 case LEFT_LINE_INPUT:
262 case RIGHT_LINE_INPUT:
263 pStream->SetInputSrc(MIX_RECSRC_LINE);
264 break;
265
266 case MIC_INPUT:
267 case BOOSTED_MIC_INPUT:
268 pStream->SetInputSrc(MIX_RECSRC_MIC);
269 break;
270
271 case PHONE_LINE_INPUT:
272 case HANDSET_INPUT:
273 case SYNTH_INPUT:
274 case DIGITAL_PHONE_LINE_INPUT:
275 case DIGITAL_HANDSET_INPUT:
276 case MIDI_IN_PORT:
277// case LOOPBACK:
278 pStream->SetInputSrc(MIX_RECSRC_MIXER);
279 break;
280 }
281 }
282 pStream->SetInputGain(pAudChange->lGain);
283}
284//******************************************************************************
285//******************************************************************************
286void IoctlMixer(PREQPACKET prp)
287{
288 MIXSTRUCT FAR *pMixStruct = (MIXSTRUCT FAR *)prp->s.ioctl.pvData;
289 ULONG FAR *pIoctlData = (ULONG FAR *)prp->s.ioctl.pvData;
290 CHAR FAR *pIoctlMap = (CHAR FAR *)prp->s.ioctl.pvData; //getapimap
291 USHORT VolumeL, VolumeR;
292
293 if((prp->s.ioctl.bCode & 0xF0) == 0x40)
294 {
295 if(DevHelp_VerifyAccess(SELECTOROF(pMixStruct), sizeof(MIXSTRUCT), OFFSETOF(pMixStruct), VERIFY_READWRITE))
296 {
297 dprintf(("Invalid IOCTL90 pointer %lx!!", (ULONG)pMixStruct));
298 prp->usStatus |= RPERR | RPBADCMD;
299 return;
300 }
301 MixerSettings[prp->s.ioctl.bCode & 0xF].VolumeL = pMixStruct->VolumeL;
302 MixerSettings[prp->s.ioctl.bCode & 0xF].VolumeR = pMixStruct->VolumeR;
303 MixerSettings[prp->s.ioctl.bCode & 0xF].Mute = pMixStruct->Mute;
304 VolumeL = (USHORT)pMixStruct->VolumeL;
305 VolumeR = (USHORT)pMixStruct->VolumeR;
306 if(prp->s.ioctl.bCode != BASSTREBLESET) {
307 if(pMixStruct->Mute == 1)
308 VolumeL = VolumeR = 0;
309 }
310 }
311 else
312 if((prp->s.ioctl.bCode & 0xF0) == 0x60)
313 {
314 if(DevHelp_VerifyAccess(SELECTOROF(pMixStruct), sizeof(MIXSTRUCT), OFFSETOF(pMixStruct), VERIFY_READONLY))
315 {
316 dprintf(("Invalid IOCTL90 pointer %lx!!", (ULONG)pMixStruct));
317 prp->usStatus |= RPERR | RPBADCMD;
318 return;
319 }
320 }
321
322 switch(prp->s.ioctl.bCode) {
323 case MICSET:
324 OSS16_SetGlobalVol(prp->s.ioctl.usSysFileNum, MIX_SETMICVOL, MAKE_VOLUME(VolumeL, VolumeR));
325 break;
326 case LINESET:
327 OSS16_SetGlobalVol(prp->s.ioctl.usSysFileNum, MIX_SETLINEINVOL, MAKE_VOLUME(VolumeL, VolumeR));
328 break;
329 case CDSET:
330 OSS16_SetGlobalVol(prp->s.ioctl.usSysFileNum, MIX_SETCDVOL, MAKE_VOLUME(VolumeL, VolumeR));
331 break;
332 case VIDEOSET:
333 OSS16_SetGlobalVol(prp->s.ioctl.usSysFileNum, MIX_SETVIDEOVOL, MAKE_VOLUME(VolumeL, VolumeR));
334 break;
335 case AUXSET:
336 OSS16_SetGlobalVol(prp->s.ioctl.usSysFileNum, MIX_SETAUXVOL, MAKE_VOLUME(VolumeL, VolumeR));
337 break;
338
339 case BASSTREBLESET:
340 OSS16_SetGlobalVol(prp->s.ioctl.usSysFileNum, MIX_SETBASS, MAKE_VOLUME(VolumeL, VolumeL));
341 OSS16_SetGlobalVol(prp->s.ioctl.usSysFileNum, MIX_SETTREBLE, MAKE_VOLUME(VolumeR, VolumeR));
342 break;
343#if 0
344 case STREAMVOLSET:
345 //release stream volume override?
346 if(pMixStruct->Mute == 2) {
347 fStreamVolIOCTL90 = FALSE;
348 break;
349 }
350 fStreamVolIOCTL90 = TRUE;
351 OSS16_SetGlobalVol(prp->s.ioctl.usSysFileNum, MIX_SETMASTERVOL, MAKE_VOLUME(VolumeL, VolumeR));
352 break;
353#endif
354
355 case RECORDSRCSET:
356 {
357 int recsrc;
358
359 //release recording source override?
360 if(pMixStruct->Mute == 2) {
361 fRecSrcIOCTL90 = FALSE;
362 break;
363 }
364 fRecSrcIOCTL90 = TRUE;
365 switch(pMixStruct->VolumeL) {
366 case I90SRC_MIC:
367 recsrc = MIX_RECSRC_MIC;
368 break;
369 case I90SRC_CD:
370 recsrc = MIX_RECSRC_CD;
371 break;
372 case I90SRC_VIDEO:
373 recsrc = MIX_RECSRC_VIDEO;
374 break;
375 case I90SRC_LINE:
376 recsrc = MIX_RECSRC_LINE;
377 break;
378 case I90SRC_AUX:
379 recsrc = MIX_RECSRC_AUX;
380 break;
381// case I90SRC_RES5:
382// case I90SRC_RES6:
383// case I90SRC_PHONE:
384 default:
385 break;
386 }
387 OSS16_SetGlobalVol(prp->s.ioctl.usSysFileNum, MIX_SETINPUTSRC, recsrc);
388 break;
389 }
390 case RECORDGAINSET:
391 //release recording gain override?
392 if(pMixStruct->Mute == 2) {
393 fRecGainIOCTL90 = FALSE;
394 break;
395 }
396 fRecGainIOCTL90 = TRUE;
397 OSS16_SetGlobalVol(prp->s.ioctl.usSysFileNum, MIX_SETINPUTGAIN, MAKE_VOLUME(VolumeL, VolumeR));
398 break;
399
400 case MICQUERY:
401 case LINEQUERY:
402 case AUXQUERY:
403 case CDQUERY:
404 case VIDEOQUERY:
405 case RECORDSRCQUERY:
406 case RECORDGAINQUERY:
407 pMixStruct->VolumeL = MixerSettings[prp->s.ioctl.bCode & 0xF].VolumeL;
408 pMixStruct->VolumeR = MixerSettings[prp->s.ioctl.bCode & 0xF].VolumeR;
409 pMixStruct->Mute = MixerSettings[prp->s.ioctl.bCode & 0xF].Mute;
410 break;
411
412 case BASSTREBLEQUERY:
413 pMixStruct->VolumeL = MixerSettings[prp->s.ioctl.bCode & 0xF].VolumeL;
414 pMixStruct->VolumeR = MixerSettings[prp->s.ioctl.bCode & 0xF].VolumeR;
415 pMixStruct->Mute = 3; //bass & treble
416 break;
417
418 case APILEVELQUERY:
419 if(DevHelp_VerifyAccess(SELECTOROF(pIoctlData), sizeof(ULONG), OFFSETOF(pIoctlData), VERIFY_READWRITE))
420 {
421 dprintf(("Invalid IOCTL90 pointer %lx!!", (ULONG)pIoctlData));
422 prp->usStatus |= RPERR | RPBADCMD;
423 return;
424 }
425 *pIoctlData = 2;
426 break;
427
428 case GETAPIMAP:
429 if(DevHelp_VerifyAccess(SELECTOROF(pIoctlMap), 256, OFFSETOF(pIoctlMap), VERIFY_READWRITE))
430 {
431 dprintf(("Invalid IOCTL90 pointer %lx!!", (ULONG)pMixStruct));
432 prp->usStatus |= RPERR | RPBADCMD;
433 return;
434 }
435 _fmemcpy(pIoctlMap, SBLiveIOCTLMap, sizeof(SBLiveIOCTLMap));
436 break;
437// case STREAMVOLQUERY:
438// case MONOINSET:
439// case PHONESET:
440// case THREEDSET:
441// case MONOINQUERY:
442// case PHONEQUERY:
443// case THREEDQUERY:
444// case CALLBACKREG:
445// case MSGBUF:
446 default:
447 prp->usStatus |= RPERR | RPBADCMD;
448 return;
449 }
450}
451//******************************************************************************
452//******************************************************************************
453void MixerInit()
454{
455 REQPACKET rp;
456 MIXSTRUCT mixinfo;
457
458 SBLiveIOCTLMap[MICSET] = 1;
459 SBLiveIOCTLMap[MICQUERY] = 1;
460 SBLiveIOCTLMap[LINESET] = 1;
461 SBLiveIOCTLMap[LINEQUERY] = 1;
462 SBLiveIOCTLMap[CDSET] = 1;
463 SBLiveIOCTLMap[CDQUERY] = 1;
464 SBLiveIOCTLMap[VIDEOSET] = 1;
465 SBLiveIOCTLMap[VIDEOQUERY] = 1;
466 SBLiveIOCTLMap[AUXSET] = 1;
467 SBLiveIOCTLMap[AUXQUERY] = 1;
468 SBLiveIOCTLMap[BASSTREBLESET] = 1;
469 SBLiveIOCTLMap[BASSTREBLEQUERY] = 1;
470//// SBLiveIOCTLMap[STREAMVOLSET] = 1;
471//// SBLiveIOCTLMap[STREAMVOLQUERY] = 1;
472 SBLiveIOCTLMap[RECORDSRCSET] = 1;
473 SBLiveIOCTLMap[RECORDSRCQUERY] = 1;
474 SBLiveIOCTLMap[RECORDGAINSET] = 1;
475 SBLiveIOCTLMap[RECORDGAINQUERY] = 1;
476 SBLiveIOCTLMap[APILEVELQUERY] = 1;
477 SBLiveIOCTLMap[GETAPIMAP] = 1;
478// SBLiveIOCTLMap[CALLBACKREG] = 1;
479
480 //Set mic
481 rp.s.ioctl.bCode = MICSET;
482 rp.s.ioctl.pvData = (void FAR *)&mixinfo;
483 mixinfo.Mute = fMicMute;
484 mixinfo.VolumeR = mixinfo.VolumeL = 60;
485 IoctlMixer(&rp);
486
487 //Set line
488 rp.s.ioctl.bCode = LINESET;
489 rp.s.ioctl.pvData = (void FAR *)&mixinfo;
490 mixinfo.Mute = fLineMute;
491 mixinfo.VolumeR = mixinfo.VolumeL = 80;
492 IoctlMixer(&rp);
493
494 //Set CD
495 rp.s.ioctl.bCode = CDSET;
496 rp.s.ioctl.pvData = (void FAR *)&mixinfo;
497 mixinfo.Mute = fCDMute;
498 mixinfo.VolumeR = mixinfo.VolumeL = 80;
499 IoctlMixer(&rp);
500
501 //Set bass/treble
502 rp.s.ioctl.bCode = BASSTREBLESET;
503 rp.s.ioctl.pvData = (void FAR *)&mixinfo;
504 mixinfo.Mute = 3;
505 mixinfo.VolumeR = mixinfo.VolumeL = 50;
506 IoctlMixer(&rp);
507
508 //Set recording source to line in
509 rp.s.ioctl.bCode = RECORDSRCSET;
510 rp.s.ioctl.pvData = (void FAR *)&mixinfo;
511 mixinfo.Mute = 0;
512 mixinfo.VolumeL = I90SRC_LINE;
513 IoctlMixer(&rp);
514
515 //Release recording source override
516 rp.s.ioctl.bCode = RECORDSRCSET;
517 rp.s.ioctl.pvData = (void FAR *)&mixinfo;
518 mixinfo.Mute = 2;
519 mixinfo.VolumeL = I90SRC_LINE;
520 IoctlMixer(&rp);
521
522 //Set master volume
523 rp.s.ioctl.bCode = STREAMVOLSET;
524 rp.s.ioctl.pvData = (void FAR *)&mixinfo;
525 mixinfo.Mute = 0;
526 mixinfo.VolumeR = mixinfo.VolumeL = 90;
527 IoctlMixer(&rp);
528
529 //Release master volume override
530 rp.s.ioctl.bCode = STREAMVOLSET;
531 rp.s.ioctl.pvData = (void FAR *)&mixinfo;
532 mixinfo.Mute = 2;
533 mixinfo.VolumeR = mixinfo.VolumeL = 90;
534 IoctlMixer(&rp);
535}
536//******************************************************************************
537//******************************************************************************
538/**@internal
539 * @param PREQPACKET pointer to the strategy request packet
540 * @return None But the Status in the request packet is updated on error
541 * @notes
542 * StrategyIoctl is called from the strategy entry point to process IOCTL
543 * requests. only catagory 80x requests will be processed.
544 */
545/* extern "C" void StrategyIoctl(PREQPACKET prp, USHORT LDev)
546*
547*
548*
549*/
550extern "C" void StrategyIoctl(PREQPACKET prp, USHORT LDev)
551{
552 if(prp->s.ioctl.bCategory == 0x90) {
553 IoctlMixer(prp);
554 return;
555 }
556 if(prp->s.ioctl.bCategory != AUDIO_IOCTL_CAT) {
557 prp->usStatus |= RPERR | RPBADCMD;
558 return;
559 }
560
561 switch (prp->s.ioctl.bCode) {
562 case AUDIO_INIT:
563 IoctlAudioInit(prp, LDev);
564 break;
565 case AUDIO_CONTROL:
566 IoctlAudioControl(prp);
567 break;
568 case AUDIO_CAPABILITY:
569 IoctlAudioCapability(prp, LDev);
570 break;
571 default:
572 prp->usStatus |= RPERR | RPBADCMD;
573 break;
574 }
575 return;
576}
Note: See TracBrowser for help on using the repository browser.