source: GPL/branches/uniaud32-next/lib32/ioctl.c

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

More code cleanups from AlexT from #os2russian

File size: 27.0 KB
RevLine 
[32]1/*
2
3 IOCTL funcs
4 Written by Vlad Stelmahovsky with help from Stepan Kazakov
5
6 */
7
[305]8#include <sound/core.h>
[32]9#include <sound/control.h>
10#include <sound/info.h>
11#include <sound/pcm.h>
12#include <sound/pcm_params.h>
13#include <sound/minors.h>
14#include <linux/file.h>
15#include <linux/soundcard.h>
16
17#define LINUX
18#include <ossidc32.h>
19#include <stacktoflat.h>
20#include <stdlib.h>
21#include "soundoss.h"
22
[677]23#include <kee.h>
[675]24#include <u32ioctl.h>
25
[32]26POSS32_DEVCAPS pcmcaps[8] = {0,0,0,0,0,0,0,0};
27extern int pcm_device;
28extern OpenedHandles opened_handles[8*256];
29
30/*
31 * Control ID changed by an external
32 * set by snd_ctl_notify()
33 */
[305]34struct snd_pcm_substream *substream_int[8*256] = {0}; // interrupted substream
[470]35
[32]36int control_id_changed = 0;
37int card_id_changed = 0;
38int unlock_all = 0;
39int pcm_instances(int card_id);
40
[479]41void uniaud_set_interrupted_substream(struct snd_pcm_substream *substream)
[470]42{
[528]43 int i;
[470]44
[528]45 for (i=0; i < 8*256; i++)
46 {
47 if (substream_int[i] == 0)
48 {
49 substream_int[i] = substream; // interrupted substream
50 // printk("added %x to %i\n", substream, i);
51 break;
52 }
53 if (substream_int[i] == substream)
54 {
55 // printk("already exist %x at %i\n", substream, i);
56 break;
57 }
58 }
[470]59}
60
[32]61int WaitForControlChange(int card_id, int timeout)
62{
[528]63 int ctl_id;
64 int i = 0;
[32]65
[528]66 while (1)
67 {
68 if (control_id_changed != 0 && card_id_changed == card_id)
69 {
70 ctl_id = control_id_changed;
71 control_id_changed = 0;
72 break;
73 }
74 i++;
[32]75
[528]76 if (i > timeout)
77 return -ETIME;
[32]78
[677]79 KernBlock((ULONG)&WaitForControlChange, 1, 0, 0, 0);
[528]80 if (unlock_all)
81 {
82 unlock_all = 0;
83 break;
84 }
85 }
86 return ctl_id;
[32]87}
88
89int WaitForPCMInterrupt(void *handle, int timeout)
90{
[528]91 int i = 0;
92 int j = 0;
93 struct snd_pcm_file *pcm_file = NULL;
94 struct snd_pcm_substream *substream;
95 struct snd_pcm_runtime *runtime;
96 soundhandle *pHandle = (soundhandle *)handle;
97 struct file *pfile;
[32]98
[528]99 if (handle == NULL)
100 return -ENXIO;
[32]101
[528]102 pfile = &pHandle->file;
[32]103
[528]104 if (pfile == NULL)
105 return -ENXIO;
[32]106
[528]107 pcm_file = (struct snd_pcm_file *)pfile->private_data;
[32]108
[528]109 if (pcm_file == NULL)
110 return -ENXIO;
[32]111
[528]112 substream = pcm_file->substream;
[32]113
[528]114 if (substream == NULL)
115 return -ENXIO;
[32]116
[528]117 runtime = substream->runtime;
[32]118
[528]119 if ((pfile->f_mode == FMODE_WRITE) &&
120 (runtime->status->state != SNDRV_PCM_STATE_RUNNING))
121 return -EBADFD;
[32]122
[598]123 //printk("wait for %x. tout %i\n",substream, timeout);
[32]124
[528]125 while (1)
126 {
127 for (i=0; i < 8*256; i++)
128 {
129 if (substream_int[i] == substream)
130 {
131// printk("found %x at %i\n",substream_int[i], i);
132 substream_int[i] = 0;
133 //printk("j =%i\n",j);
134 return j; /* milliseconds */
135 }
136 }
[32]137
[528]138 if (j++ > timeout)
139 {
[542]140 dprintf(("WaitForPCMInterrupt: Timeout j=%i handle=%x\n", j, pHandle));
[528]141 return -ETIME;
142 }
[32]143
[677]144 KernBlock((ULONG)&WaitForPCMInterrupt, 1, 0, 0, 0);
[528]145 if (unlock_all)
146 {
147 unlock_all = 0;
148 break;
149 }
150 }
151 //printk("j at exit =%i\n",j);
152 return j;
[32]153}
154
155/*
156 returns number of registered cards
157 */
158int GetNumberOfCards(void)
159{
[528]160 return nrCardsDetected;
[32]161}
162
163/*
164 returns number of registered pcm instances
165 */
166int GetNumberOfPcm(int card_id)
167{
[528]168 return pcm_instances(card_id);
[32]169}
170
171int SetPCMInstance(int card_id, int pcm)
172{
[528]173 if (pcm>=0 && pcm <= pcm_instances(card_id))
174 {
175 pcm_device = pcm;
176 return pcm;
177 } else
178 return pcm_device;
[32]179}
180
[675]181/*
[32]182int GetPcmForChannels(ULONG deviceid, int type, int channels)
183{
[528]184 POSS32_DEVCAPS pcaps = NULL;
185 WAVE_CAPS *wc;
186 int i;
187 int sel_pcm = -1;
[32]188
[528]189 if (!pcmcaps[deviceid])
190 {
191 FillCaps(deviceid);
192 if (!pcmcaps[deviceid])
193 {
194 printk("Error querying caps for device: %i\n", deviceid);
195 return -1;
196 }
197 }
[32]198
[528]199 pcaps = pcmcaps[deviceid];
[32]200
[528]201 for (i=0; i<pcm_instances(deviceid);i++)
202 {
203 switch(type)
204 {
205 case OSS32_CAPS_WAVE_PLAYBACK: // play
206 wc = &pcaps->waveOutCaps;
207 break;
208 case OSS32_CAPS_WAVE_CAPTURE: // record
209 wc = &pcaps->waveInCaps;
210 break;
211 }
212 if (wc->ulMaxChannels == channels)
213 {
214 sel_pcm = i;
215 break;
216 }
217 pcaps++;
218 }
[32]219
[528]220 return sel_pcm;
[32]221}
[675]222*/
[32]223
224int GetMaxChannels(ULONG deviceid, int type)
225{
[528]226 POSS32_DEVCAPS pcaps = NULL;
227 WAVE_CAPS *wc;
228 int i;
[598]229 //int sel_pcm = -1;
[528]230 int max_ch = 0;
[32]231
[528]232 if (!pcmcaps[deviceid])
233 {
234 FillCaps(deviceid);
235 if (!pcmcaps[deviceid])
236 {
237 printk("Error querying caps for device: %i\n", deviceid);
238 return -1;
239 }
240 }
[32]241
[528]242 pcaps = pcmcaps[deviceid];
[32]243
[528]244 for (i=0; i<pcm_instances(deviceid);i++)
245 {
246 switch(type)
247 {
248 case OSS32_CAPS_WAVE_PLAYBACK: // play
249 wc = &pcaps->waveOutCaps;
250 break;
251 case OSS32_CAPS_WAVE_CAPTURE: // record
252 wc = &pcaps->waveInCaps;
253 break;
254 }
255 if (wc->ulMaxChannels > max_ch)
256 max_ch = wc->ulMaxChannels;
257 pcaps++;
258 }
259 return max_ch;
[32]260}
261
262/*
263 returns pcm caps
264 */
[675]265static int GetUniaudPcmCaps1(ULONG deviceid, void *caps)
[32]266{
[528]267 POSS32_DEVCAPS pcaps = (POSS32_DEVCAPS)caps;
268 int i;
269 OSSSTREAMID streamid = 0;
270 soundhandle *pHandle;
271 struct snd_pcm_info *pcminfo = NULL;
272 struct snd_pcm_hw_params *params;
273 int ret, fmt, j;
274 ULONG format_mask;
275 struct snd_mask *mask;
276 int pcms = 0;
[32]277
[528]278 pcms = pcm_instances(deviceid);
[625]279
[528]280 if (!pcaps || !pcms) return -1;
[32]281
[479]282
[528]283 //these structures are too big to put on the stack
284 pcminfo = (struct snd_pcm_info *)kmalloc(sizeof(struct snd_pcm_info)+sizeof(struct snd_pcm_hw_params), GFP_KERNEL);
285 if(pcminfo == NULL) {
286 DebugInt3();
287 rprintf(("GetUniaudPcmCaps: out of memory"));
288 return OSSERR_OUT_OF_MEMORY;
289 }
290 params = (struct snd_pcm_hw_params *)(pcminfo+1);
[32]291
[528]292 for (i=0; i<pcms;i++)
293 {
294 pcaps->nrDevices = nrCardsDetected;
295 pcaps->ulCaps = OSS32_CAPS_WAVE_PLAYBACK | OSS32_CAPS_WAVE_CAPTURE;
[32]296
[528]297 //query wave in & out caps
298 for(j=0;j<2;j++)
299 {
300 PWAVE_CAPS pWaveCaps = (j == 0) ? &pcaps->waveOutCaps : &pcaps->waveInCaps;
[32]301
[528]302 ret = OSS32_WaveOpen(deviceid, (j == 0) ? OSS32_STREAM_WAVEOUT : OSS32_STREAM_WAVEIN, &streamid, i, 0);
303 if(ret != OSSERR_SUCCESS)
304 {
[615]305 dprintf(("GetUniaudPcmCaps1: wave open error %i %s at pcm %i", ret, (j == 0) ?"PLAY":"REC", i));
[528]306 continue;
307 //goto fail;
308 }
309 pHandle = (soundhandle *)streamid;
310 if(pHandle == NULL || pHandle->magic != MAGIC_WAVE_ALSA32) {
311 rprintf(("GetUniaudPcmCaps: invalid stream id"));
312 ret = OSSERR_INVALID_STREAMID;
313 //goto fail;
314 }
[32]315
[528]316 //set operation to non-blocking
317 pHandle->file.f_flags = O_NONBLOCK;
[32]318
[615]319 dprintf(("GetUniaudPcmCaps: cp1. pcm %i, phandle %x", i, pHandle));
[644]320 ret = pHandle->file.f_op->unlocked_ioctl(&pHandle->file, SNDRV_PCM_IOCTL_INFO, (ULONG)pcminfo);
[528]321 if(ret != 0) {
322 rprintf(("GetUniaudPcmCaps: SNDRV_PCM_IOCTL_INFO error %i", ret));
323 ret = UNIXToOSSError(ret);
324 continue;
325 }
326 if(pcminfo->name[0]) {
327 strncpy(pcaps->szDeviceName, pcminfo->name, sizeof(pcaps->szDeviceName));
328 }
329 else strncpy(pcaps->szDeviceName, pcminfo->id, sizeof(pcaps->szDeviceName));
[32]330
[528]331 if(pcminfo->subname[0]) {
332 strncpy(pcaps->szMixerName, pcminfo->subname, sizeof(pcaps->szMixerName));
333 }
[32]334
[528]335 pWaveCaps->nrStreams = pcminfo->subdevices_count;
[32]336
[615]337 dprintf(("GetUniaudPcmCaps: pcm %i, cp2. nr of streams: %i", i, pWaveCaps->nrStreams));
[528]338 //get all hardware parameters
339 _snd_pcm_hw_params_any(params);
[644]340 ret = pHandle->file.f_op->unlocked_ioctl(&pHandle->file, SNDRV_PCM_IOCTL_HW_REFINE, (ULONG)params);
[528]341 if(ret != 0) {
342 dprintf(("GetUniaudPcmCaps: SNDRV_PCM_IOCTL_HW_REFINE error %i", ret));
343 ret = UNIXToOSSError(ret);
344 //goto fail;
345 continue;
346 }
347 //dprintf("GetUniaudPcmCaps: cp3"));
[32]348
[528]349 pWaveCaps->ulMinChannels = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS)->min;
350 pWaveCaps->ulMaxChannels = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS)->max;
351 dprintf(("chan: from %i to %i\n", pWaveCaps->ulMinChannels,pWaveCaps->ulMaxChannels));
352 pWaveCaps->ulChanFlags = 0;
353 if(pWaveCaps->ulMinChannels == 1) {
354 pWaveCaps->ulChanFlags |= OSS32_CAPS_PCM_CHAN_MONO;
355 }
356 if(pWaveCaps->ulMaxChannels >= 2) {
357 pWaveCaps->ulChanFlags |= OSS32_CAPS_PCM_CHAN_STEREO;
358 }
359 if(pWaveCaps->ulMaxChannels >= 4) {
360 pWaveCaps->ulChanFlags |= OSS32_CAPS_PCM_CHAN_QUAD;
361 }
362 if(pWaveCaps->ulMaxChannels >= 6) {
363 pWaveCaps->ulChanFlags |= OSS32_CAPS_PCM_CHAN_5_1;
364 }
365 pWaveCaps->ulMinRate = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE)->min;
366 pWaveCaps->ulMaxRate = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE)->max;
[32]367
[528]368 mask = hw_param_mask(params, SNDRV_PCM_HW_PARAM_RATE_MASK);
[518]369 //mask = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
[528]370 pWaveCaps->ulRateFlags = mask->bits[0];
[32]371
[528]372 pWaveCaps->ulRateFlags = ALSAToOSSRateFlags(pWaveCaps->ulRateFlags);
[32]373
[528]374 pWaveCaps->ulDataFormats = 0;
[32]375
[528]376 mask = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
377 format_mask = mask->bits[0];
378 for(fmt=0;fmt<32;fmt++)
379 {
380 if(format_mask & (1 << fmt))
381 {
382 int f = ALSAToOSSDataType(fmt);
383 if (f >= 0)
384 pWaveCaps->ulDataFormats |= f;
385 }
386 }
[32]387
[528]388 OSS32_WaveClose(streamid);
389 streamid = 0;
390 } // for j
391 pcaps++; // next pcm
392 } // for i
[32]393
[528]394 if (pcminfo) kfree(pcminfo);
395 return OSSERR_SUCCESS;
[32]396}
397
[479]398void FillCaps(ULONG deviceid)
399{
[528]400 int pcms = 0;
[479]401
[528]402 pcms = pcm_instances(deviceid);
[479]403
[549]404 //dprintf(("FillCaps: pcms=%i\n", pcms));
[528]405 if (!pcmcaps[deviceid])
406 {
407 pcmcaps[deviceid] = (POSS32_DEVCAPS)kmalloc(sizeof(OSS32_DEVCAPS)*pcms, GFP_KERNEL);
408 if (pcmcaps[deviceid])
409 {
410 memset(pcmcaps[deviceid], 0, sizeof(OSS32_DEVCAPS)*pcms);
411 GetUniaudPcmCaps1(deviceid, (void *)pcmcaps[deviceid]);
412 }
413 }
414 return;
[479]415}
416
417int GetUniaudPcmCaps(ULONG deviceid, void *caps)
418{
[528]419 int pcms = 0;
[479]420
[528]421 pcms = pcm_instances(deviceid);
[479]422
[528]423// printk("pcms = %i\n", pcms);
424 if (pcmcaps[deviceid])
425 {
426 memcpy((unsigned char*)caps,(unsigned char*)pcmcaps[deviceid],sizeof(OSS32_DEVCAPS)*pcms);
427 return 0;
428 }
429 else
430 {
431 return -1;
432 }
[479]433}
434
[32]435/*
436 returns power state of given card
437 */
438int UniaudCtlGetPowerState(ULONG deviceid, void *state)
439{
[528]440 mixerhandle *pHandle = NULL;
[598]441 int ret;
442 //int i, j;
[32]443
[528]444 if(alsa_fops == NULL) {
445 ret = OSSERR_NO_DEVICE_AVAILABLE;
446 goto failure;
447 }
[32]448
[528]449 pHandle = kmalloc(sizeof(mixerhandle), GFP_KERNEL);
450 if(pHandle == NULL) {
451 ret = OSSERR_OUT_OF_MEMORY;
452 goto failure;
453 }
454 memset(pHandle, 0, sizeof(mixerhandle));
[32]455
[528]456 //set operation to non-blocking
457 pHandle->file.f_flags = O_NONBLOCK;
[32]458
[528]459 //setup pointers in file structure (used internally by ALSA)
460 pHandle->file.f_dentry = &pHandle->d_entry;
461 pHandle->file.f_dentry->d_inode = &pHandle->inode;
[32]462
[528]463 pHandle->file.f_mode = FMODE_WRITE;
464 pHandle->inode.i_rdev = SNDRV_MINOR(deviceid, SNDRV_MINOR_CONTROL);
[32]465
[528]466 ret = alsa_fops->open(&pHandle->inode, &pHandle->file);
467 if(ret) {
468 goto failure;
469 }
470 //retrieve mixer information
[644]471 ret = pHandle->file.f_op->unlocked_ioctl(&pHandle->file,
[528]472 SNDRV_CTL_IOCTL_POWER_STATE,
473 (ULONG)state);
[32]474
[528]475 pHandle->file.f_op->release(&pHandle->inode, &pHandle->file);
[32]476
[528]477 kfree(pHandle);
[32]478
[528]479 if(ret) {
480 goto failure;
481 }
[32]482
[528]483 return OSSERR_SUCCESS;
[32]484failure:
[528]485 DebugInt3();
486 return ret;
[32]487}
488
489/*
490 sets power state for given card
491 */
492int UniaudCtlSetPowerState(ULONG deviceid, void *state)
493{
[528]494 mixerhandle *pHandle = NULL;
[598]495 int ret;
496 //int i, j;
[32]497
[528]498 if(alsa_fops == NULL) {
499 ret = OSSERR_NO_DEVICE_AVAILABLE;
500 goto failure;
501 }
[32]502
[528]503 pHandle = kmalloc(sizeof(mixerhandle), GFP_KERNEL);
504 if(pHandle == NULL) {
505 ret = OSSERR_OUT_OF_MEMORY;
506 goto failure;
507 }
508 memset(pHandle, 0, sizeof(mixerhandle));
[32]509
[528]510 //set operation to non-blocking
511 pHandle->file.f_flags = O_NONBLOCK;
[32]512
[528]513 //setup pointers in file structure (used internally by ALSA)
514 pHandle->file.f_dentry = &pHandle->d_entry;
515 pHandle->file.f_dentry->d_inode = &pHandle->inode;
[32]516
[528]517 pHandle->file.f_mode = FMODE_WRITE;
518 pHandle->inode.i_rdev = SNDRV_MINOR(deviceid, SNDRV_MINOR_CONTROL);
[32]519
[528]520 ret = alsa_fops->open(&pHandle->inode, &pHandle->file);
521 if(ret) {
522 goto failure;
523 }
524 //retrieve mixer information
[644]525 ret = pHandle->file.f_op->unlocked_ioctl(&pHandle->file,
[528]526 SNDRV_CTL_IOCTL_POWER,
527 (ULONG)state);
[32]528
[528]529 pHandle->file.f_op->release(&pHandle->inode, &pHandle->file);
[32]530
[528]531 kfree(pHandle);
[32]532
[528]533 if(ret) {
534 goto failure;
535 }
[32]536
[528]537 return OSSERR_SUCCESS;
[32]538failure:
[528]539 DebugInt3();
540 return ret;
[32]541}
542
543/*
544 returns card info
545 */
546int GetUniaudCardInfo(ULONG deviceid, void *info)
547{
[528]548 mixerhandle *pHandle = NULL;
[598]549 int ret;
550 //int i, j;
[32]551
[549]552 //dprintf(("GetUniaudCardInfo"));
[542]553
[528]554 if(alsa_fops == NULL) {
555 ret = OSSERR_NO_DEVICE_AVAILABLE;
556 goto failure;
557 }
[32]558
[528]559 pHandle = kmalloc(sizeof(mixerhandle), GFP_KERNEL);
560 if(pHandle == NULL) {
561 ret = OSSERR_OUT_OF_MEMORY;
562 goto failure;
563 }
564 memset(pHandle, 0, sizeof(mixerhandle));
[32]565
[528]566 //set operation to non-blocking
567 pHandle->file.f_flags = O_NONBLOCK;
[32]568
[528]569 //setup pointers in file structure (used internally by ALSA)
570 pHandle->file.f_dentry = &pHandle->d_entry;
571 pHandle->file.f_dentry->d_inode = &pHandle->inode;
[32]572
[528]573 pHandle->file.f_mode = FMODE_WRITE;
574 pHandle->inode.i_rdev = SNDRV_MINOR(deviceid, SNDRV_MINOR_CONTROL);
[32]575
[528]576 ret = alsa_fops->open(&pHandle->inode, &pHandle->file);
577 if(ret) {
578 goto failure;
579 }
580 //retrieve mixer information
[644]581 ret = pHandle->file.f_op->unlocked_ioctl(&pHandle->file,
[528]582 SNDRV_CTL_IOCTL_CARD_INFO,
583 (ULONG)(struct snd_ctl_card_info *)info);
584 if(ret) {
585 ret = pHandle->file.f_op->release(&pHandle->inode, &pHandle->file);
586 goto failure;
587 }
588 ret = pHandle->file.f_op->release(&pHandle->inode, &pHandle->file);
[32]589
[528]590 if(pHandle) {
591 kfree(pHandle);
592 }
593 return OSSERR_SUCCESS;
[32]594failure:
[528]595 if(pHandle) {
596 kfree(pHandle);
597 }
598 DebugInt3();
599 return OSSERR_OUT_OF_MEMORY;
[32]600}
601
602int GetUniaudControlNum(ULONG deviceid)
603{
[528]604 mixerhandle *pHandle = NULL;
[598]605 int ret, sz;
606 //int i, j;
[32]607
[549]608 //dprintf(("GetUniaudControlNum"));
[542]609
[528]610 if(alsa_fops == NULL) {
611 ret = OSSERR_NO_DEVICE_AVAILABLE;
612 goto failure;
613 }
[32]614
[528]615 sz = sizeof(mixerhandle);
616 pHandle = kmalloc(sz, GFP_KERNEL);
617 if(pHandle == NULL) {
618 ret = OSSERR_OUT_OF_MEMORY;
619 goto failure;
620 }
621 memset(pHandle, 0, sizeof(mixerhandle));
[32]622
[528]623 //set operation to non-blocking
624 pHandle->file.f_flags = O_NONBLOCK;
[32]625
[528]626 //setup pointers in file structure (used internally by ALSA)
627 pHandle->file.f_dentry = &pHandle->d_entry;
628 pHandle->file.f_dentry->d_inode = &pHandle->inode;
[32]629
[528]630 pHandle->file.f_mode = FMODE_WRITE;
631 pHandle->inode.i_rdev = SNDRV_MINOR(deviceid, SNDRV_MINOR_CONTROL);
[32]632
[528]633 ret = alsa_fops->open(&pHandle->inode, &pHandle->file);
634 if(ret) {
635 goto failure;
636 }
637 //retrieve mixer information
[644]638 ret = pHandle->file.f_op->unlocked_ioctl(&pHandle->file,
[528]639 SNDRV_CTL_IOCTL_CARD_INFO,
640 (ULONG)&pHandle->info);
641 if(ret) {
642 ret = pHandle->file.f_op->release(&pHandle->inode, &pHandle->file);
643 goto failure;
644 }
645 //get the number of mixer elements
646 pHandle->list.offset = 0;
647 pHandle->list.space = 0;
[644]648 ret = pHandle->file.f_op->unlocked_ioctl(&pHandle->file,
[528]649 SNDRV_CTL_IOCTL_ELEM_LIST,
650 (ULONG)&pHandle->list);
651 if(ret) {
652 ret = pHandle->file.f_op->release(&pHandle->inode, &pHandle->file);
653 goto failure;
654 }
655 ret = pHandle->file.f_op->release(&pHandle->inode, &pHandle->file);
656 if(pHandle) {
657 if(pHandle->pids) kfree(pHandle->pids);
658 kfree(pHandle);
659 }
660 return pHandle->list.count;
[32]661failure:
[528]662 if(pHandle) {
663 if(pHandle->pids) kfree(pHandle->pids);
664 kfree(pHandle);
665 }
666 DebugInt3();
667 return OSSERR_OUT_OF_MEMORY;
[32]668}
669
670int GetUniaudControls(ULONG deviceid, void *pids)
671{
[528]672 mixerhandle *pHandle = NULL;
[598]673 int ret, sz;
674 //int i, j;
[32]675
[549]676 //dprintf(("GetUniaudControls"));
[542]677
[528]678 if(alsa_fops == NULL) {
679 ret = OSSERR_NO_DEVICE_AVAILABLE;
680 goto failure;
681 }
[32]682
[528]683 sz = sizeof(mixerhandle);
684 pHandle = kmalloc(sz, GFP_KERNEL);
685 if(pHandle == NULL) {
686 ret = OSSERR_OUT_OF_MEMORY;
687 goto failure;
688 }
689 memset(pHandle, 0, sizeof(mixerhandle));
[32]690
[528]691 //set operation to non-blocking
692 pHandle->file.f_flags = O_NONBLOCK;
[32]693
[528]694 //setup pointers in file structure (used internally by ALSA)
695 pHandle->file.f_dentry = &pHandle->d_entry;
696 pHandle->file.f_dentry->d_inode = &pHandle->inode;
[32]697
[528]698 pHandle->file.f_mode = FMODE_WRITE;
699 pHandle->inode.i_rdev = SNDRV_MINOR(deviceid, SNDRV_MINOR_CONTROL);
[32]700
[528]701 ret = alsa_fops->open(&pHandle->inode, &pHandle->file);
702 if(ret) {
703 goto failure;
704 }
705 //retrieve mixer information
[644]706 ret = pHandle->file.f_op->unlocked_ioctl(&pHandle->file,
[528]707 SNDRV_CTL_IOCTL_CARD_INFO,
708 (ULONG)&pHandle->info);
709 if(ret) {
710 ret = pHandle->file.f_op->release(&pHandle->inode, &pHandle->file);
711 goto failure;
712 }
713 //get the number of mixer elements
714 pHandle->list.offset = 0;
715 pHandle->list.space = 0;
[644]716 ret = pHandle->file.f_op->unlocked_ioctl(&pHandle->file,
[528]717 SNDRV_CTL_IOCTL_ELEM_LIST,
718 (ULONG)&pHandle->list);
719 if(ret) {
720 ret = pHandle->file.f_op->release(&pHandle->inode, &pHandle->file);
721 goto failure;
722 }
[32]723
[528]724 //allocate memory for all mixer elements
725 pHandle->pids = (struct snd_ctl_elem_id *)pids;
726 //kmalloc(sizeof(struct snd_ctl_elem_id)*pHandle->list.count, GFP_KERNEL);
727 if(pHandle->pids == NULL) {
728 ret = pHandle->file.f_op->release(&pHandle->inode, &pHandle->file);
729 goto failure;
730 }
731 //and retrieve all mixer elements
732 pHandle->list.offset = 0;
733 pHandle->list.space = pHandle->list.count;
734 pHandle->list.pids = pHandle->pids;
[644]735 ret = pHandle->file.f_op->unlocked_ioctl(&pHandle->file,
[528]736 SNDRV_CTL_IOCTL_ELEM_LIST,
737 (ULONG)&pHandle->list);
738 if(ret) {
739 ret = pHandle->file.f_op->release(&pHandle->inode, &pHandle->file);
740 goto failure;
741 }
742// if (pids)
743// memcpy(pids, pHandle->pids,
744// sizeof(struct snd_ctl_elem_id)*pHandle->list.count);
[32]745
[528]746 ret = pHandle->file.f_op->release(&pHandle->inode, &pHandle->file);
747 if(pHandle) {
748// if(pHandle->pids) kfree(pHandle->pids);
749 kfree(pHandle);
750 }
751 return pHandle->list.count;
[32]752failure:
[528]753 if(pHandle) {
754// if(pHandle->pids) kfree(pHandle->pids);
755 kfree(pHandle);
756 }
757 DebugInt3();
758 return OSSERR_OUT_OF_MEMORY;
[32]759}
760
761int GetUniaudControlInfo(ULONG deviceid, ULONG id, void *info)
762{
[598]763 //struct snd_ctl_elem_value *pElem = NULL;
[528]764 struct snd_ctl_elem_info *pElemInfo = NULL;
765 mixerhandle *pHandle = NULL;
[598]766 int ret, sz;
767 //int i, j;
[32]768
[549]769 //dprintf(("GetUniaudControlInfo"));
[542]770
[528]771 if(alsa_fops == NULL) {
772 ret = OSSERR_NO_DEVICE_AVAILABLE;
773 goto failure;
774 }
[32]775
[528]776 sz = sizeof(mixerhandle);
777 pHandle = kmalloc(sz, GFP_KERNEL);
778 if(pHandle == NULL) {
779 ret = OSSERR_OUT_OF_MEMORY;
780 goto failure;
781 }
782 memset(pHandle, 0, sizeof(mixerhandle));
[32]783
[528]784 //set operation to non-blocking
785 pHandle->file.f_flags = O_NONBLOCK;
[32]786
[528]787 //setup pointers in file structure (used internally by ALSA)
788 pHandle->file.f_dentry = &pHandle->d_entry;
789 pHandle->file.f_dentry->d_inode = &pHandle->inode;
[32]790
[528]791 pHandle->file.f_mode = FMODE_WRITE;
792 pHandle->inode.i_rdev = SNDRV_MINOR(deviceid, SNDRV_MINOR_CONTROL);
[32]793
[528]794 ret = alsa_fops->open(&pHandle->inode, &pHandle->file);
795 if(ret) {
796 goto failure;
797 }
[32]798
[528]799 //allocate memory for info element
800 pElemInfo = (struct snd_ctl_elem_info *)info;
801 if(pElemInfo == NULL) {
802 ret = pHandle->file.f_op->release(&pHandle->inode, &pHandle->file);
803 goto failure;
804 }
[32]805
[528]806// printk("sizeof elem_info %i\n",sizeof(struct snd_ctl_elem_info));
[32]807
[528]808 pElemInfo->id.numid = id;
[644]809 ret = pHandle->file.f_op->unlocked_ioctl(&pHandle->file, SNDRV_CTL_IOCTL_ELEM_INFO, (ULONG)pElemInfo);
[528]810 ret = pHandle->file.f_op->release(&pHandle->inode, &pHandle->file);
811 if(pHandle) kfree(pHandle);
812// printk("elem type: %i, id: %i, card: %i\n", pElemInfo->type, pElemInfo->id.numid, deviceid);
813 return OSSERR_SUCCESS;
[32]814
815failure:
[528]816 if(pHandle) {
817 kfree(pHandle);
818 }
819 DebugInt3();
820 return OSSERR_OUT_OF_MEMORY;
[32]821}
822
823int GetUniaudControlValueGet(ULONG deviceid, ULONG id, void *value)
824{
[528]825 struct snd_ctl_elem_value *pElem = NULL;
[542]826 //struct snd_ctl_elem_info *pElemInfo = NULL;
[528]827 mixerhandle *pHandle = NULL;
[598]828 int ret, sz;
829 //int i, j;
[32]830
[528]831 if(alsa_fops == NULL) {
832 ret = OSSERR_NO_DEVICE_AVAILABLE;
833 goto failure;
834 }
[32]835
[528]836 sz = sizeof(mixerhandle);
837 pHandle = kmalloc(sz, GFP_KERNEL);
838 if(pHandle == NULL) {
839 ret = OSSERR_OUT_OF_MEMORY;
840 goto failure;
841 }
842 memset(pHandle, 0, sizeof(mixerhandle));
[32]843
[528]844 //set operation to non-blocking
845 pHandle->file.f_flags = O_NONBLOCK;
[32]846
[528]847 //setup pointers in file structure (used internally by ALSA)
848 pHandle->file.f_dentry = &pHandle->d_entry;
849 pHandle->file.f_dentry->d_inode = &pHandle->inode;
[32]850
[528]851 pHandle->file.f_mode = FMODE_WRITE;
852 pHandle->inode.i_rdev = SNDRV_MINOR(deviceid, SNDRV_MINOR_CONTROL);
[32]853
[528]854 ret = alsa_fops->open(&pHandle->inode, &pHandle->file);
855 if(ret) {
856 goto failure;
857 }
[32]858
[528]859 pElem = (struct snd_ctl_elem_value *)value;
860 if(pElem == NULL) {
861 ret = pHandle->file.f_op->release(&pHandle->inode, &pHandle->file);
862 goto failure;
863 }
[32]864
[528]865 pElem->id.numid = id;
866 pElem->indirect = 0;
[644]867 ret = pHandle->file.f_op->unlocked_ioctl(&pHandle->file, SNDRV_CTL_IOCTL_ELEM_READ, (ULONG)pElem);
[528]868 ret = pHandle->file.f_op->release(&pHandle->inode, &pHandle->file);
869 if(pHandle) kfree(pHandle);
[32]870
[549]871 //dprintf(("GetUniaudControlValueGet: id=%x 0=%x 1=%x", pElem->id.numid, pElem->value.integer.value[0], pElem->value.integer.value[1]));
[542]872
[528]873 return OSSERR_SUCCESS;
[32]874failure:
[528]875 if(pHandle) {
876 kfree(pHandle);
877 }
878 DebugInt3();
879 return OSSERR_OUT_OF_MEMORY;
[32]880}
881
882int GetUniaudControlValuePut(ULONG deviceid, ULONG id, void *value)
883{
[528]884 struct snd_ctl_elem_value *pElem = NULL;
[542]885 //struct snd_ctl_elem_info *pElemInfo = NULL;
[528]886 mixerhandle *pHandle = NULL;
[598]887 int ret, sz;
888 //int i, j;
[32]889
[528]890 if(alsa_fops == NULL) {
891 ret = OSSERR_NO_DEVICE_AVAILABLE;
892 goto failure;
893 }
[32]894
[528]895 sz = sizeof(mixerhandle);
896 pHandle = kmalloc(sz, GFP_KERNEL);
897 if(pHandle == NULL) {
898 ret = OSSERR_OUT_OF_MEMORY;
899 goto failure;
900 }
901 memset(pHandle, 0, sizeof(mixerhandle));
[32]902
[528]903 //set operation to non-blocking
904 pHandle->file.f_flags = O_NONBLOCK;
[32]905
[528]906 //setup pointers in file structure (used internally by ALSA)
907 pHandle->file.f_dentry = &pHandle->d_entry;
908 pHandle->file.f_dentry->d_inode = &pHandle->inode;
[32]909
[528]910 pHandle->file.f_mode = FMODE_WRITE;
911 pHandle->inode.i_rdev = SNDRV_MINOR(deviceid, SNDRV_MINOR_CONTROL);
[32]912
[528]913 ret = alsa_fops->open(&pHandle->inode, &pHandle->file);
914 if(ret) {
915 goto failure;
916 }
[32]917
[528]918 pElem = (struct snd_ctl_elem_value *)value;
919 if(pElem == NULL) {
920 ret = pHandle->file.f_op->release(&pHandle->inode, &pHandle->file);
921 goto failure;
922 }
[32]923
[528]924 pElem->id.numid = id;
925 pElem->indirect = 0;
[542]926
[644]927 ret = pHandle->file.f_op->unlocked_ioctl(&pHandle->file, SNDRV_CTL_IOCTL_ELEM_WRITE, (ULONG)pElem);
[528]928 ret = pHandle->file.f_op->release(&pHandle->inode, &pHandle->file);
929 if(pHandle) kfree(pHandle);
[32]930
[528]931 return OSSERR_SUCCESS;
[32]932
933failure:
[528]934 if(pHandle) {
935 kfree(pHandle);
936 }
937 DebugInt3();
938 return OSSERR_OUT_OF_MEMORY;
[32]939}
940
941int UniaudIoctlHWRefine(OSSSTREAMID streamid, void *pHwParams)
942{
[528]943 int ret;
944 soundhandle *pHandle = (soundhandle *)streamid;
945 struct snd_pcm_hw_params *params = NULL;
946 params = (struct snd_pcm_hw_params *)pHwParams;
[32]947
[549]948 //dprintf(("UniaudIoctlHWRefine"));
[542]949
[528]950 if (!params) return -1001;
[32]951
[528]952 if (!pHandle) return -1002;
[32]953
[528]954 pHandle->file.f_flags = O_NONBLOCK;
[644]955 ret = pHandle->file.f_op->unlocked_ioctl(&pHandle->file, SNDRV_PCM_IOCTL_HW_REFINE, (ULONG)params);
[528]956 return ret;
[32]957}
958
959int UniaudIoctlHWParamSet(OSSSTREAMID streamid, void *pHwParams)
960{
[528]961 int ret;
962 soundhandle *pHandle = (soundhandle *)streamid;
963 struct snd_pcm_hw_params *params = NULL;
964 params = (struct snd_pcm_hw_params *)pHwParams;
[32]965
[549]966 //dprintf(("UniaudIoctlHWParamSet"));
[542]967
[528]968 if (!params) return -1001;
969 if (!pHandle) return -1002;
[32]970
[528]971 pHandle->file.f_flags = O_NONBLOCK;
[644]972 ret = pHandle->file.f_op->unlocked_ioctl(&pHandle->file, SNDRV_PCM_IOCTL_HW_PARAMS, (ULONG)params);
[528]973 return ret;
[32]974}
975
976int UniaudIoctlSWParamSet(OSSSTREAMID streamid, void *pSwParams)
977{
[528]978 int ret;
979 soundhandle *pHandle = (soundhandle *)streamid;
980 struct snd_pcm_sw_params *params = NULL;
[542]981
[528]982 params = (struct snd_pcm_sw_params *)pSwParams;
[32]983
[549]984 //dprintf(("UniaudIoctlSWParamSet"));
[542]985
[528]986 if (!params) return -1001;
987 if (!pHandle) return -1002;
[32]988
[528]989 pHandle->file.f_flags = O_NONBLOCK;
[32]990
[644]991 ret = pHandle->file.f_op->unlocked_ioctl(&pHandle->file, SNDRV_PCM_IOCTL_SW_PARAMS, (ULONG)params);
[528]992 return ret;
[32]993}
994
995int UniaudIoctlPCMStatus(OSSSTREAMID streamid, void *pstatus)
996{
[528]997 int ret;
998 soundhandle *pHandle = (soundhandle *)streamid;
999 struct snd_pcm_status *status = (struct snd_pcm_status *)pstatus;
[32]1000
[549]1001 //dprintf(("UniaudIoctlPCMStatus"));
[542]1002
[528]1003 if (!status) return -1001;
1004 if (!pHandle) return -1002;
[32]1005
[528]1006 pHandle->file.f_flags = O_NONBLOCK;
[32]1007
[644]1008 ret = pHandle->file.f_op->unlocked_ioctl(&pHandle->file, SNDRV_PCM_IOCTL_STATUS, (ULONG)status);
[528]1009 return ret;
[32]1010}
1011
1012int UniaudIoctlPCMWrite(OSSSTREAMID streamid, char *buf, int size)
1013{
[528]1014 int ret;
1015 soundhandle *pHandle = (soundhandle *)streamid;
[32]1016
[549]1017 //dprintf(("UniaudIoctlPCMWrite"));
[542]1018
[528]1019 if (!buf) return -1001;
1020 if (!pHandle) return -1002;
[32]1021
[528]1022 pHandle->file.f_flags = O_NONBLOCK;
[32]1023
[528]1024 ret = pHandle->file.f_op->write(&pHandle->file, buf, size, &pHandle->file.f_pos);
[32]1025
[528]1026 return ret;
[32]1027}
1028
1029int UniaudIoctlPCMRead(OSSSTREAMID streamid, char *buf, int size)
1030{
[528]1031 int ret;
1032 soundhandle *pHandle = (soundhandle *)streamid;
[32]1033
[528]1034 if (!buf) return -1001;
1035 if (!pHandle) return -1002;
[32]1036
[549]1037 //dprintf(("UniaudIoctlPCMRead"));
[542]1038
[528]1039 pHandle->file.f_flags = O_NONBLOCK;
[32]1040
[528]1041 ret = pHandle->file.f_op->read(&pHandle->file, buf, size, &pHandle->file.f_pos);
[32]1042
[528]1043 return ret;
[32]1044}
1045
1046int UniaudIoctlPCMPrepare(OSSSTREAMID streamid)
1047{
[528]1048 int ret;
1049 soundhandle *pHandle = (soundhandle *)streamid;
[32]1050
[549]1051 //dprintf(("UniaudIoctlPCMPrepare"));
[542]1052
[528]1053 if (!pHandle) return -1002;
[32]1054
[528]1055 pHandle->file.f_flags = O_NONBLOCK;
[32]1056
[644]1057 ret = pHandle->file.f_op->unlocked_ioctl(&pHandle->file, SNDRV_PCM_IOCTL_PREPARE, 0);
[528]1058 return ret;
[32]1059}
1060
1061int UniaudIoctlPCMResume(OSSSTREAMID streamid, int pause)
1062{
[528]1063 int ret;
1064 soundhandle *pHandle = (soundhandle *)streamid;
[32]1065
[549]1066 //dprintf(("UniaudIoctlPCMResume: %x", pause));
[542]1067
[528]1068 if (!pHandle) return -1002;
[32]1069
[528]1070 pHandle->file.f_flags = O_NONBLOCK;
[32]1071
[644]1072 ret = pHandle->file.f_op->unlocked_ioctl(&pHandle->file, SNDRV_PCM_IOCTL_PAUSE, pause);
[32]1073
[528]1074 return ret;
[32]1075}
1076
1077int UniaudIoctlPCMStart(OSSSTREAMID streamid)
1078{
[528]1079 int ret;
1080 soundhandle *pHandle = (soundhandle *)streamid;
[32]1081
[549]1082 //dprintf(("UniaudIoctlPCMStart"));
[542]1083
[528]1084 if (!pHandle) return -1002;
[32]1085
[528]1086 pHandle->file.f_flags = O_NONBLOCK;
[32]1087
[644]1088 ret = pHandle->file.f_op->unlocked_ioctl(&pHandle->file, SNDRV_PCM_IOCTL_START, 0);
[32]1089
[528]1090 return ret;
[32]1091}
1092
1093int UniaudIoctlPCMDrop(OSSSTREAMID streamid)
1094{
[528]1095 int ret;
1096 soundhandle *pHandle = (soundhandle *)streamid;
[32]1097
[549]1098 //dprintf(("UniaudIoctlPCMDrop"));
[542]1099
[528]1100 if (!pHandle) return -1002;
[32]1101
[528]1102 pHandle->file.f_flags = O_NONBLOCK;
[32]1103
[644]1104 ret = pHandle->file.f_op->unlocked_ioctl(&pHandle->file, SNDRV_PCM_IOCTL_DROP, 0);
[32]1105
[528]1106 return ret;
[32]1107}
1108
1109void UniaudCloseAll(USHORT fileid)
1110{
[528]1111 int i;
[32]1112
[528]1113 for (i=0; i < 8*256; i++)
1114 {
1115 if (opened_handles[i].handle != 0)
1116 {
1117 if (fileid)
1118 {
1119 if (fileid == opened_handles[i].FileId)
1120 {
1121 opened_handles[i].reuse = 0;
1122 if (OSS32_WaveClose((OSSSTREAMID)opened_handles[i].handle) == 0)
1123 opened_handles[i].handle = 0;
1124 }
1125 }
1126 else
1127 {
1128 opened_handles[i].reuse = 0;
1129 if (OSS32_WaveClose((OSSSTREAMID)opened_handles[i].handle) == 0)
1130 opened_handles[i].handle = 0;
1131 }
1132 }
1133 }
1134 return;
[32]1135}
Note: See TracBrowser for help on using the repository browser.