source: GPL/trunk/lib32/ioctl.c@ 86

Last change on this file since 86 was 86, checked in by vladest, 19 years ago

Added missed files
Applied latest modifications of ALSA
Reworked sharing strategy between MMOS2 and UNIAUD API

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