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

Last change on this file since 148 was 148, checked in by sandervl, 25 years ago

beta 0.25 update

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 18.5 KB
Line 
1/* $Id: ioctl.cpp 148 2000-04-26 18:01:02Z sandervl $ */
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_MPU401_PLAY:
134 pstream = new MIDISTREAM(HardwareType, prp->s.ioctl.usSysFileNum);
135 break;
136#endif
137 default:
138 p->sReturnCode = INVALID_REQUEST;
139 prp->usStatus |= RPERR;
140 return;
141 } /* endswitch */
142
143 p->ulFlags |= VOLUME; /* volume control is supported */
144 p->ulFlags |= INPUT; /* Input select is supported */
145 p->ulFlags |= OUTPUT; /* Output select is supported */
146 p->ulFlags |= MONITOR; /* Record Monitor is supported */
147 p->sDeviceID = SB_LIVE; /* Reported in VSD dll */
148 pstream->ulSysFileNum = prp->s.ioctl.usSysFileNum;
149 p->pvReserved = (VOID FAR *) (ULONG) prp->s.ioctl.usSysFileNum;
150 p->sReturnCode = 0;
151 dprintf(("IoctlAudioInit: file nr: %lx", pstream->ulSysFileNum));
152}
153
154
155/**@internal
156 * @param PREQPACKET pointer to the strategy request packet
157 * @return None But the Status in the request packet is updated on error
158 * @notes
159 */
160void IoctlAudioCapability(PREQPACKET prp, USHORT LDev)
161{
162 PAUDIOHW pHWobj;
163 PAUDIO_CAPS p = (PAUDIO_CAPS)prp->s.ioctl.pvData;
164 ULONG ulDevicetype;
165
166 // get the hardware device type based on the datatype and operation
167 ulDevicetype = GetHardwareType((USHORT)p->ulDataType,(USHORT)p->ulOperation,LDev);
168
169 // Tell the caller we support this IOCTL
170 p->ulCapability = SUPPORT_CAP;
171
172 // get the pointer to the hardware object
173 // call DevCaps
174 // bailout if no hardware object is returned..
175 pHWobj = GetHardwareDevice(ulDevicetype);
176 if (pHWobj) {
177 pHWobj->DevCaps(p);
178 if (p->ulSupport != SUPPORT_SUCCESS) {
179 prp->usStatus |= RPERR;
180 }
181 }
182 else {
183 p->ulSupport = UNSUPPORTED_DATATYPE;
184 prp->usStatus |= RPERR;
185 }
186}
187
188/**@internal IoctlAudioControl
189 * @param PREQPACKET pointer to the strategy request packet
190 * @return None But the Status in the request packet is updated on error
191 * @notes
192 * if it's AUDIO_CHANGE, just report success, otherwise report failure
193 * this is because we don't support volume, balance, multiple in/out devices,
194 * etc. Also, START, STOP, RESUME, and PAUSE are redundant, so we don't
195 * support those either.
196 */
197void IoctlAudioControl(PREQPACKET prp)
198{
199 LPMCI_AUDIO_CONTROL p = (LPMCI_AUDIO_CONTROL) prp->s.ioctl.pvData;
200 LPMCI_AUDIO_CHANGE pAudChange;
201 LPMCI_TRACK_INFO pMasterVol;
202 PSTREAM pStream;
203 ULONG volume;
204 ULONG addr;
205
206 if (p->usIOCtlRequest != AUDIO_CHANGE) {
207 p->sReturnCode = INVALID_REQUEST;
208 prp->usStatus |= RPERR | RPBADCMD;
209 return;
210 }
211 p->sReturnCode=0;
212
213 pAudChange = (LPMCI_AUDIO_CHANGE)p->pbRequestInfo;
214
215 //Test for MMPM/2 bug (structure crosses selector boundary)
216 addr = OFFSETOF(pAudChange);
217 addr += sizeof(MCI_AUDIO_CHANGE);
218 if(addr >= 0x10000UL) {
219 dprintf(("Invalid MCI_AUDIO_CHANGE pointer %lx!!", (ULONG)pAudChange));
220 p->sReturnCode = INVALID_REQUEST;
221 prp->usStatus |= RPERR | RPBADCMD;
222 return;
223 }
224 pMasterVol = (LPMCI_TRACK_INFO)pAudChange->pvDevInfo;
225
226 //Test for MMPM/2 bug (structure crosses selector boundary)
227 addr = OFFSETOF(pMasterVol);
228 addr += sizeof(MCI_TRACK_INFO);
229 if(addr >= 0x10000UL) {
230 dprintf(("Invalid MCI_TRACK_INFO pointer %lx!!", (ULONG)pMasterVol));
231 p->sReturnCode = INVALID_REQUEST;
232 prp->usStatus |= RPERR | RPBADCMD;
233 return;
234 }
235
236 pStream = FindStream_fromFile((ULONG) prp->s.ioctl.usSysFileNum);
237 if(pStream == NULL) {
238 dprintf(("IoctlAudioControl stream %lx not found!", (ULONG) prp->s.ioctl.usSysFileNum));
239 DebugInt3();
240 return;
241 }
242 if(pAudChange->lBalance != AUDIO_IGNORE)
243 pStream->SetBalance(pAudChange->lBalance);
244
245 if(pAudChange->lVolume != AUDIO_IGNORE) {
246 // stream volume ranges from 0 to 0x7FFFFFFF (linear)
247 volume = pAudChange->lVolume >> 16UL;
248 volume = (volume*100UL)/0x7FFFUL;
249 dprintf(("Set stream volume of %x to %d", prp->s.ioctl.usSysFileNum, volume));
250 pStream->SetVolume(MAKE_VOLUME_LR(volume, volume));
251 }
252
253 if(pMasterVol && pMasterVol->usMasterVolume != AUDIO_IGNORE) {
254 // master volume ranges from 0 to 0x7FFF (linear)
255 volume = pMasterVol->usMasterVolume;
256 volume = (volume*100UL)/0x7FFFUL;
257 if(volume > 100) {
258 volume = 100;
259 }
260 dprintf(("Set mastervolume to %d", volume));
261 pStream->SetMasterVol(MAKE_VOLUME_LR(volume, volume));
262 }
263 if(!fRecSrcIOCTL90) {
264 for(int i=0;i<8;i++)
265 {
266 switch(pAudChange->rInputList[0].ulDevType) {
267 case NULL_INPUT:
268 break; //continue;
269 case STEREO_LINE_INPUT:
270 case LEFT_LINE_INPUT:
271 case RIGHT_LINE_INPUT:
272 pStream->SetInputSrc(MIX_RECSRC_LINE);
273 break;
274
275 case MIC_INPUT:
276 case BOOSTED_MIC_INPUT:
277 pStream->SetInputSrc(MIX_RECSRC_MIC);
278 break;
279
280 case PHONE_LINE_INPUT:
281 case HANDSET_INPUT:
282 case SYNTH_INPUT:
283 case DIGITAL_PHONE_LINE_INPUT:
284 case DIGITAL_HANDSET_INPUT:
285 case MIDI_IN_PORT:
286// case LOOPBACK:
287 pStream->SetInputSrc(MIX_RECSRC_MIXER);
288 break;
289 }
290 }
291 }
292 if(!fRecGainIOCTL90 && pAudChange->lGain != AUDIO_IGNORE) {
293 // input ranges from 0 to 0x7FFFFFFF (linear)
294 volume = pAudChange->lGain >> 16UL;
295 volume = (volume*100UL)/0x7FFFUL;
296 if(volume > 100) {
297 volume = 100;
298 }
299 dprintf(("Set input gain of %x to %d", prp->s.ioctl.usSysFileNum, volume));
300 pStream->SetInputGain(MAKE_VOLUME_LR(volume, volume));
301 }
302}
303//******************************************************************************
304//******************************************************************************
305void IoctlMixer(PREQPACKET prp)
306{
307 MIXSTRUCT FAR *pMixStruct = (MIXSTRUCT FAR *)prp->s.ioctl.pvData;
308 ULONG FAR *pIoctlData = (ULONG FAR *)prp->s.ioctl.pvData;
309 CHAR FAR *pIoctlMap = (CHAR FAR *)prp->s.ioctl.pvData; //getapimap
310 USHORT VolumeL, VolumeR;
311
312 if((prp->s.ioctl.bCode & 0xF0) == 0x40)
313 {
314 if(DevHelp_VerifyAccess(SELECTOROF(pMixStruct), sizeof(MIXSTRUCT), OFFSETOF(pMixStruct), VERIFY_READWRITE))
315 {
316 dprintf(("Invalid IOCTL90 pointer %lx!!", (ULONG)pMixStruct));
317 prp->usStatus |= RPERR | RPBADCMD;
318 return;
319 }
320 MixerSettings[prp->s.ioctl.bCode & 0xF].VolumeL = pMixStruct->VolumeL;
321 MixerSettings[prp->s.ioctl.bCode & 0xF].VolumeR = pMixStruct->VolumeR;
322 MixerSettings[prp->s.ioctl.bCode & 0xF].Mute = pMixStruct->Mute;
323 VolumeL = (USHORT)pMixStruct->VolumeL;
324 VolumeR = (USHORT)pMixStruct->VolumeR;
325 if(prp->s.ioctl.bCode != BASSTREBLESET) {
326 if(pMixStruct->Mute == 1)
327 VolumeL = VolumeR = 0;
328 }
329 }
330 else
331 if((prp->s.ioctl.bCode & 0xF0) == 0x60)
332 {
333 if(DevHelp_VerifyAccess(SELECTOROF(pMixStruct), sizeof(MIXSTRUCT), OFFSETOF(pMixStruct), VERIFY_READONLY))
334 {
335 dprintf(("Invalid IOCTL90 pointer %lx!!", (ULONG)pMixStruct));
336 prp->usStatus |= RPERR | RPBADCMD;
337 return;
338 }
339 }
340
341 switch(prp->s.ioctl.bCode) {
342 case MICSET:
343 OSS16_SetGlobalVol(prp->s.ioctl.usSysFileNum, MIX_SETMICVOL, MAKE_VOLUME_LR(VolumeL, VolumeR));
344 break;
345 case LINESET:
346 OSS16_SetGlobalVol(prp->s.ioctl.usSysFileNum, MIX_SETLINEINVOL, MAKE_VOLUME_LR(VolumeL, VolumeR));
347 break;
348 case CDSET:
349 OSS16_SetGlobalVol(prp->s.ioctl.usSysFileNum, MIX_SETCDVOL, MAKE_VOLUME_LR(VolumeL, VolumeR));
350 break;
351 case VIDEOSET:
352 OSS16_SetGlobalVol(prp->s.ioctl.usSysFileNum, MIX_SETVIDEOVOL, MAKE_VOLUME_LR(VolumeL, VolumeR));
353 break;
354 case AUXSET:
355 OSS16_SetGlobalVol(prp->s.ioctl.usSysFileNum, MIX_SETAUXVOL, MAKE_VOLUME_LR(VolumeL, VolumeR));
356 break;
357
358 case BASSTREBLESET:
359 OSS16_SetGlobalVol(prp->s.ioctl.usSysFileNum, MIX_SETBASS, MAKE_VOLUME_LR(VolumeL, VolumeL));
360 OSS16_SetGlobalVol(prp->s.ioctl.usSysFileNum, MIX_SETTREBLE, MAKE_VOLUME_LR(VolumeR, VolumeR));
361 break;
362#if 0
363 case STREAMVOLSET:
364 //release stream volume override?
365 if(pMixStruct->Mute == 2) {
366 fStreamVolIOCTL90 = FALSE;
367 break;
368 }
369 fStreamVolIOCTL90 = TRUE;
370 OSS16_SetGlobalVol(prp->s.ioctl.usSysFileNum, MIX_SETMASTERVOL, MAKE_VOLUME_LR(VolumeL, VolumeR));
371 break;
372#endif
373
374 case RECORDSRCSET:
375 {
376 int recsrc;
377
378 //release recording source override?
379 if(pMixStruct->Mute == 2) {
380 fRecSrcIOCTL90 = FALSE;
381 break;
382 }
383 fRecSrcIOCTL90 = TRUE;
384 switch(pMixStruct->VolumeL) {
385 case I90SRC_MIC:
386 recsrc = MIX_RECSRC_MIC;
387 break;
388 case I90SRC_CD:
389 recsrc = MIX_RECSRC_CD;
390 break;
391 case I90SRC_VIDEO:
392 recsrc = MIX_RECSRC_VIDEO;
393 break;
394 case I90SRC_LINE:
395 recsrc = MIX_RECSRC_LINE;
396 break;
397 case I90SRC_AUX:
398 recsrc = MIX_RECSRC_AUX;
399 break;
400// case I90SRC_RES5:
401// case I90SRC_RES6:
402// case I90SRC_PHONE:
403 default:
404 break;
405 }
406 OSS16_SetGlobalVol(prp->s.ioctl.usSysFileNum, MIX_SETINPUTSRC, recsrc);
407 break;
408 }
409 case RECORDGAINSET:
410 //release recording gain override?
411 if(pMixStruct->Mute == 2) {
412 fRecGainIOCTL90 = FALSE;
413 break;
414 }
415 fRecGainIOCTL90 = TRUE;
416 OSS16_SetGlobalVol(prp->s.ioctl.usSysFileNum, MIX_SETINPUTGAIN, MAKE_VOLUME_LR(VolumeL, VolumeR));
417 break;
418
419 case MICQUERY:
420 case LINEQUERY:
421 case AUXQUERY:
422 case CDQUERY:
423 case VIDEOQUERY:
424 case RECORDSRCQUERY:
425 case RECORDGAINQUERY:
426 pMixStruct->VolumeL = MixerSettings[prp->s.ioctl.bCode & 0xF].VolumeL;
427 pMixStruct->VolumeR = MixerSettings[prp->s.ioctl.bCode & 0xF].VolumeR;
428 pMixStruct->Mute = MixerSettings[prp->s.ioctl.bCode & 0xF].Mute;
429 break;
430
431 case BASSTREBLEQUERY:
432 pMixStruct->VolumeL = MixerSettings[prp->s.ioctl.bCode & 0xF].VolumeL;
433 pMixStruct->VolumeR = MixerSettings[prp->s.ioctl.bCode & 0xF].VolumeR;
434 pMixStruct->Mute = 3; //bass & treble
435 break;
436
437 case APILEVELQUERY:
438 if(DevHelp_VerifyAccess(SELECTOROF(pIoctlData), sizeof(ULONG), OFFSETOF(pIoctlData), VERIFY_READWRITE))
439 {
440 dprintf(("Invalid IOCTL90 pointer %lx!!", (ULONG)pIoctlData));
441 prp->usStatus |= RPERR | RPBADCMD;
442 return;
443 }
444 *pIoctlData = 2;
445 break;
446
447 case GETAPIMAP:
448 if(DevHelp_VerifyAccess(SELECTOROF(pIoctlMap), sizeof(SBLiveIOCTLMap), OFFSETOF(pIoctlMap), VERIFY_READWRITE))
449 {
450 dprintf(("Invalid IOCTL90 pointer %lx!!", (ULONG)pMixStruct));
451 prp->usStatus |= RPERR | RPBADCMD;
452 return;
453 }
454 _fmemcpy(pIoctlMap, SBLiveIOCTLMap, sizeof(SBLiveIOCTLMap));
455 break;
456// case STREAMVOLQUERY:
457// case MONOINSET:
458// case PHONESET:
459// case THREEDSET:
460// case MONOINQUERY:
461// case PHONEQUERY:
462// case THREEDQUERY:
463// case CALLBACKREG:
464// case MSGBUF:
465 default:
466 prp->usStatus |= RPERR | RPBADCMD;
467 return;
468 }
469}
470//******************************************************************************
471//******************************************************************************
472void MixerInit()
473{
474 REQPACKET rp;
475 MIXSTRUCT mixinfo;
476
477 SBLiveIOCTLMap[MICSET] = 1;
478 SBLiveIOCTLMap[MICQUERY] = 1;
479 SBLiveIOCTLMap[LINESET] = 1;
480 SBLiveIOCTLMap[LINEQUERY] = 1;
481 SBLiveIOCTLMap[CDSET] = 1;
482 SBLiveIOCTLMap[CDQUERY] = 1;
483 SBLiveIOCTLMap[VIDEOSET] = 1;
484 SBLiveIOCTLMap[VIDEOQUERY] = 1;
485 SBLiveIOCTLMap[AUXSET] = 1;
486 SBLiveIOCTLMap[AUXQUERY] = 1;
487 SBLiveIOCTLMap[BASSTREBLESET] = 1;
488 SBLiveIOCTLMap[BASSTREBLEQUERY] = 1;
489//// SBLiveIOCTLMap[STREAMVOLSET] = 1;
490//// SBLiveIOCTLMap[STREAMVOLQUERY] = 1;
491 SBLiveIOCTLMap[RECORDSRCSET] = 1;
492 SBLiveIOCTLMap[RECORDSRCQUERY] = 1;
493 SBLiveIOCTLMap[RECORDGAINSET] = 1;
494 SBLiveIOCTLMap[RECORDGAINQUERY] = 1;
495 SBLiveIOCTLMap[APILEVELQUERY] = 1;
496 SBLiveIOCTLMap[GETAPIMAP] = 1;
497// SBLiveIOCTLMap[CALLBACKREG] = 1;
498
499 //Set mic
500 rp.s.ioctl.bCode = MICSET;
501 rp.s.ioctl.pvData = (void FAR *)&mixinfo;
502 mixinfo.Mute = fMicMute;
503 mixinfo.VolumeR = mixinfo.VolumeL = 60;
504 IoctlMixer(&rp);
505
506 //Set line
507 rp.s.ioctl.bCode = LINESET;
508 rp.s.ioctl.pvData = (void FAR *)&mixinfo;
509 mixinfo.Mute = fLineMute;
510 mixinfo.VolumeR = mixinfo.VolumeL = 80;
511 IoctlMixer(&rp);
512
513 //Set CD
514 rp.s.ioctl.bCode = CDSET;
515 rp.s.ioctl.pvData = (void FAR *)&mixinfo;
516 mixinfo.Mute = fCDMute;
517 mixinfo.VolumeR = mixinfo.VolumeL = 80;
518 IoctlMixer(&rp);
519
520 //Set bass/treble
521 rp.s.ioctl.bCode = BASSTREBLESET;
522 rp.s.ioctl.pvData = (void FAR *)&mixinfo;
523 mixinfo.Mute = 3;
524 mixinfo.VolumeR = mixinfo.VolumeL = 50;
525 IoctlMixer(&rp);
526
527 //Set recording source to line in
528 rp.s.ioctl.bCode = RECORDSRCSET;
529 rp.s.ioctl.pvData = (void FAR *)&mixinfo;
530 mixinfo.Mute = 0;
531 mixinfo.VolumeL = I90SRC_LINE;
532 IoctlMixer(&rp);
533
534 //Release recording source override
535 rp.s.ioctl.bCode = RECORDSRCSET;
536 rp.s.ioctl.pvData = (void FAR *)&mixinfo;
537 mixinfo.Mute = 2;
538 mixinfo.VolumeL = I90SRC_LINE;
539 IoctlMixer(&rp);
540
541 //Set master volume
542 rp.s.ioctl.bCode = STREAMVOLSET;
543 rp.s.ioctl.pvData = (void FAR *)&mixinfo;
544 mixinfo.Mute = 0;
545 mixinfo.VolumeR = mixinfo.VolumeL = 90;
546 IoctlMixer(&rp);
547
548 //Release master volume override
549 rp.s.ioctl.bCode = STREAMVOLSET;
550 rp.s.ioctl.pvData = (void FAR *)&mixinfo;
551 mixinfo.Mute = 2;
552 mixinfo.VolumeR = mixinfo.VolumeL = 90;
553 IoctlMixer(&rp);
554}
555//******************************************************************************
556//******************************************************************************
557/**@internal
558 * @param PREQPACKET pointer to the strategy request packet
559 * @return None But the Status in the request packet is updated on error
560 * @notes
561 * StrategyIoctl is called from the strategy entry point to process IOCTL
562 * requests. only catagory 80x requests will be processed.
563 */
564/* extern "C" void StrategyIoctl(PREQPACKET prp, USHORT LDev)
565*
566*
567*
568*/
569extern "C" void StrategyIoctl(PREQPACKET prp, USHORT LDev)
570{
571 if(prp->s.ioctl.bCategory == 0x90) {
572 IoctlMixer(prp);
573 return;
574 }
575 if(prp->s.ioctl.bCategory != AUDIO_IOCTL_CAT) {
576 prp->usStatus |= RPERR | RPBADCMD;
577 return;
578 }
579
580 switch (prp->s.ioctl.bCode) {
581 case AUDIO_INIT:
582 IoctlAudioInit(prp, LDev);
583 break;
584 case AUDIO_CONTROL:
585 IoctlAudioControl(prp);
586 break;
587 case AUDIO_CAPABILITY:
588 IoctlAudioCapability(prp, LDev);
589 break;
590 default:
591 prp->usStatus |= RPERR | RPBADCMD;
592 break;
593 }
594 return;
595}
Note: See TracBrowser for help on using the repository browser.