source: GPL/branches/uniaud-2.0/lib32/ioctl.c@ 313

Last change on this file since 313 was 307, checked in by Paul Smedley, 17 years ago

Fix for detection of sample rate from Yoda

File size: 30.2 KB
Line 
1/*
2
3 IOCTL funcs
4 Written by Vlad Stelmahovsky with help from Stepan Kazakov
5
6 */
7
8#include <sound/core.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 */
31struct snd_pcm_substream *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 struct snd_pcm_file *pcm_file = NULL;
74 struct snd_pcm_substream *substream;
75 struct snd_pcm_runtime *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 = (struct snd_pcm_file *)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); //uncommented
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 struct snd_pcm_info *pcminfo = NULL;
287 struct snd_pcm_hw_params *params;
288 int ret, fmt, j;
289 ULONG format_mask;
290 struct snd_mask *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 = (struct snd_pcm_info *)kmalloc(sizeof(struct snd_pcm_info)+sizeof(struct snd_pcm_hw_params), GFP_KERNEL);
300 if(pcminfo == NULL) {
301 DebugInt3();
302 printk("GetUniaudPcmCaps: out of memory\n");
303 return OSSERR_OUT_OF_MEMORY;
304 }
305 params = (struct snd_pcm_hw_params *)(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// mask = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
387 pWaveCaps->ulRateFlags = mask->bits[0];
388
389 pWaveCaps->ulRateFlags = ALSAToOSSRateFlags(pWaveCaps->ulRateFlags);
390
391 pWaveCaps->ulDataFormats = 0;
392
393 mask = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
394 format_mask = mask->bits[0];
395 for(fmt=0;fmt<32;fmt++)
396 {
397 if(format_mask & (1 << fmt))
398 {
399 int f = ALSAToOSSDataType(fmt);
400 if (f >= 0)
401 pWaveCaps->ulDataFormats |= f;
402 }
403 }
404
405 OSS32_WaveClose(streamid);
406 streamid = 0;
407 } // for j
408 pcaps++; // next pcm
409 } // for i
410
411 if (pcminfo) kfree(pcminfo);
412 return OSSERR_SUCCESS;
413}
414
415/*
416 returns power state of given card
417 */
418int UniaudCtlGetPowerState(ULONG deviceid, void *state)
419{
420 mixerhandle *pHandle = NULL;
421 int ret, i, j;
422
423 if(alsa_fops == NULL) {
424 ret = OSSERR_NO_DEVICE_AVAILABLE;
425 goto failure;
426 }
427
428 pHandle = kmalloc(sizeof(mixerhandle), GFP_KERNEL);
429 if(pHandle == NULL) {
430 ret = OSSERR_OUT_OF_MEMORY;
431 goto failure;
432 }
433 memset(pHandle, 0, sizeof(mixerhandle));
434
435 //set operation to non-blocking
436 pHandle->file.f_flags = O_NONBLOCK;
437
438 //setup pointers in file structure (used internally by ALSA)
439 pHandle->file.f_dentry = &pHandle->d_entry;
440 pHandle->file.f_dentry->d_inode = &pHandle->inode;
441
442 pHandle->file.f_mode = FMODE_WRITE;
443 pHandle->inode.i_rdev = SNDRV_MINOR(deviceid, SNDRV_MINOR_CONTROL);
444
445 ret = alsa_fops->open(&pHandle->inode, &pHandle->file);
446 if(ret) {
447 goto failure;
448 }
449 //retrieve mixer information
450 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file,
451 SNDRV_CTL_IOCTL_POWER_STATE,
452 (ULONG)state);
453
454 pHandle->file.f_op->release(&pHandle->inode, &pHandle->file);
455
456 kfree(pHandle);
457
458 if(ret) {
459 goto failure;
460 }
461
462 return OSSERR_SUCCESS;
463failure:
464 DebugInt3();
465 return ret;
466}
467
468/*
469 sets power state for given card
470 */
471int UniaudCtlSetPowerState(ULONG deviceid, void *state)
472{
473 mixerhandle *pHandle = NULL;
474 int ret, i, j;
475
476 if(alsa_fops == NULL) {
477 ret = OSSERR_NO_DEVICE_AVAILABLE;
478 goto failure;
479 }
480
481 pHandle = kmalloc(sizeof(mixerhandle), GFP_KERNEL);
482 if(pHandle == NULL) {
483 ret = OSSERR_OUT_OF_MEMORY;
484 goto failure;
485 }
486 memset(pHandle, 0, sizeof(mixerhandle));
487
488 //set operation to non-blocking
489 pHandle->file.f_flags = O_NONBLOCK;
490
491 //setup pointers in file structure (used internally by ALSA)
492 pHandle->file.f_dentry = &pHandle->d_entry;
493 pHandle->file.f_dentry->d_inode = &pHandle->inode;
494
495 pHandle->file.f_mode = FMODE_WRITE;
496 pHandle->inode.i_rdev = SNDRV_MINOR(deviceid, SNDRV_MINOR_CONTROL);
497
498 ret = alsa_fops->open(&pHandle->inode, &pHandle->file);
499 if(ret) {
500 goto failure;
501 }
502 //retrieve mixer information
503 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file,
504 SNDRV_CTL_IOCTL_POWER,
505 (ULONG)state);
506
507 pHandle->file.f_op->release(&pHandle->inode, &pHandle->file);
508
509 kfree(pHandle);
510
511 if(ret) {
512 goto failure;
513 }
514
515 return OSSERR_SUCCESS;
516failure:
517 DebugInt3();
518 return ret;
519}
520
521/*
522 returns card info
523 */
524int GetUniaudCardInfo(ULONG deviceid, void *info)
525{
526 mixerhandle *pHandle = NULL;
527 int ret, i, j;
528// struct snd_ctl_card_info *pinfo;
529
530 if(alsa_fops == NULL) {
531 ret = OSSERR_NO_DEVICE_AVAILABLE;
532 goto failure;
533 }
534
535 pHandle = kmalloc(sizeof(mixerhandle), GFP_KERNEL);
536 if(pHandle == NULL) {
537 ret = OSSERR_OUT_OF_MEMORY;
538 goto failure;
539 }
540 memset(pHandle, 0, sizeof(mixerhandle));
541
542 //set operation to non-blocking
543 pHandle->file.f_flags = O_NONBLOCK;
544
545 //setup pointers in file structure (used internally by ALSA)
546 pHandle->file.f_dentry = &pHandle->d_entry;
547 pHandle->file.f_dentry->d_inode = &pHandle->inode;
548
549 pHandle->file.f_mode = FMODE_WRITE;
550 pHandle->inode.i_rdev = SNDRV_MINOR(deviceid, SNDRV_MINOR_CONTROL);
551
552 ret = alsa_fops->open(&pHandle->inode, &pHandle->file);
553 if(ret) {
554 goto failure;
555 }
556 //retrieve mixer information
557 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file,
558 SNDRV_CTL_IOCTL_CARD_INFO,
559 (ULONG)(struct snd_ctl_card_info *)info);
560 if(ret) {
561 ret = pHandle->file.f_op->release(&pHandle->inode, &pHandle->file);
562 goto failure;
563 }
564 ret = pHandle->file.f_op->release(&pHandle->inode, &pHandle->file);
565
566 if(pHandle) {
567 kfree(pHandle);
568 }
569 return OSSERR_SUCCESS;
570failure:
571 if(pHandle) {
572 kfree(pHandle);
573 }
574 DebugInt3();
575 return OSSERR_OUT_OF_MEMORY;
576}
577
578int GetUniaudControlNum(ULONG deviceid)
579{
580 mixerhandle *pHandle = NULL;
581 int ret, i, j, sz;
582
583 if(alsa_fops == NULL) {
584 ret = OSSERR_NO_DEVICE_AVAILABLE;
585 goto failure;
586 }
587
588 sz = sizeof(mixerhandle);
589 pHandle = kmalloc(sz, GFP_KERNEL);
590 if(pHandle == NULL) {
591 ret = OSSERR_OUT_OF_MEMORY;
592 goto failure;
593 }
594 memset(pHandle, 0, sizeof(mixerhandle));
595
596 //set operation to non-blocking
597 pHandle->file.f_flags = O_NONBLOCK;
598
599 //setup pointers in file structure (used internally by ALSA)
600 pHandle->file.f_dentry = &pHandle->d_entry;
601 pHandle->file.f_dentry->d_inode = &pHandle->inode;
602
603 pHandle->file.f_mode = FMODE_WRITE;
604 pHandle->inode.i_rdev = SNDRV_MINOR(deviceid, SNDRV_MINOR_CONTROL);
605
606 ret = alsa_fops->open(&pHandle->inode, &pHandle->file);
607 if(ret) {
608 goto failure;
609 }
610 //retrieve mixer information
611 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file,
612 SNDRV_CTL_IOCTL_CARD_INFO,
613 (ULONG)&pHandle->info);
614 if(ret) {
615 ret = pHandle->file.f_op->release(&pHandle->inode, &pHandle->file);
616 goto failure;
617 }
618 //get the number of mixer elements
619 pHandle->list.offset = 0;
620 pHandle->list.space = 0;
621 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file,
622 SNDRV_CTL_IOCTL_ELEM_LIST,
623 (ULONG)&pHandle->list);
624 if(ret) {
625 ret = pHandle->file.f_op->release(&pHandle->inode, &pHandle->file);
626 goto failure;
627 }
628 ret = pHandle->file.f_op->release(&pHandle->inode, &pHandle->file);
629 if(pHandle) {
630 if(pHandle->pids) kfree(pHandle->pids);
631 kfree(pHandle);
632 }
633 return pHandle->list.count;
634failure:
635 if(pHandle) {
636 if(pHandle->pids) kfree(pHandle->pids);
637 kfree(pHandle);
638 }
639 DebugInt3();
640 return OSSERR_OUT_OF_MEMORY;
641}
642
643int GetUniaudControls(ULONG deviceid, void *pids)
644{
645 mixerhandle *pHandle = NULL;
646 int ret, i, j, sz;
647
648 if(alsa_fops == NULL) {
649 ret = OSSERR_NO_DEVICE_AVAILABLE;
650 goto failure;
651 }
652
653 sz = sizeof(mixerhandle);
654 pHandle = kmalloc(sz, GFP_KERNEL);
655 if(pHandle == NULL) {
656 ret = OSSERR_OUT_OF_MEMORY;
657 goto failure;
658 }
659 memset(pHandle, 0, sizeof(mixerhandle));
660
661 //set operation to non-blocking
662 pHandle->file.f_flags = O_NONBLOCK;
663
664 //setup pointers in file structure (used internally by ALSA)
665 pHandle->file.f_dentry = &pHandle->d_entry;
666 pHandle->file.f_dentry->d_inode = &pHandle->inode;
667
668 pHandle->file.f_mode = FMODE_WRITE;
669 pHandle->inode.i_rdev = SNDRV_MINOR(deviceid, SNDRV_MINOR_CONTROL);
670
671 ret = alsa_fops->open(&pHandle->inode, &pHandle->file);
672 if(ret) {
673 goto failure;
674 }
675 //retrieve mixer information
676 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file,
677 SNDRV_CTL_IOCTL_CARD_INFO,
678 (ULONG)&pHandle->info);
679 if(ret) {
680 ret = pHandle->file.f_op->release(&pHandle->inode, &pHandle->file);
681 goto failure;
682 }
683 //get the number of mixer elements
684 pHandle->list.offset = 0;
685 pHandle->list.space = 0;
686 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file,
687 SNDRV_CTL_IOCTL_ELEM_LIST,
688 (ULONG)&pHandle->list);
689 if(ret) {
690 ret = pHandle->file.f_op->release(&pHandle->inode, &pHandle->file);
691 goto failure;
692 }
693
694 //allocate memory for all mixer elements
695 pHandle->pids = (struct snd_ctl_elem_id *)pids;
696 //kmalloc(sizeof(struct snd_ctl_elem_id)*pHandle->list.count, GFP_KERNEL);
697 if(pHandle->pids == NULL) {
698 ret = pHandle->file.f_op->release(&pHandle->inode, &pHandle->file);
699 goto failure;
700 }
701 //and retrieve all mixer elements
702 pHandle->list.offset = 0;
703 pHandle->list.space = pHandle->list.count;
704 pHandle->list.pids = pHandle->pids;
705 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file,
706 SNDRV_CTL_IOCTL_ELEM_LIST,
707 (ULONG)&pHandle->list);
708 if(ret) {
709 ret = pHandle->file.f_op->release(&pHandle->inode, &pHandle->file);
710 goto failure;
711 }
712// if (pids)
713// memcpy(pids, pHandle->pids,
714// sizeof(struct snd_ctl_elem_id)*pHandle->list.count);
715
716 ret = pHandle->file.f_op->release(&pHandle->inode, &pHandle->file);
717 if(pHandle) {
718// if(pHandle->pids) kfree(pHandle->pids);
719 kfree(pHandle);
720 }
721 return pHandle->list.count;
722failure:
723 if(pHandle) {
724// if(pHandle->pids) kfree(pHandle->pids);
725 kfree(pHandle);
726 }
727 DebugInt3();
728 return OSSERR_OUT_OF_MEMORY;
729}
730
731int GetUniaudControlInfo(ULONG deviceid, ULONG id, void *info)
732{
733 struct snd_ctl_elem_value *pElem = NULL;
734 struct snd_ctl_elem_info *pElemInfo = NULL;
735 mixerhandle *pHandle = NULL;
736 int ret, i, j, sz;
737
738 if(alsa_fops == NULL) {
739 ret = OSSERR_NO_DEVICE_AVAILABLE;
740 goto failure;
741 }
742
743 sz = sizeof(mixerhandle);
744 pHandle = kmalloc(sz, GFP_KERNEL);
745 if(pHandle == NULL) {
746 ret = OSSERR_OUT_OF_MEMORY;
747 goto failure;
748 }
749 memset(pHandle, 0, sizeof(mixerhandle));
750
751 //set operation to non-blocking
752 pHandle->file.f_flags = O_NONBLOCK;
753
754 //setup pointers in file structure (used internally by ALSA)
755 pHandle->file.f_dentry = &pHandle->d_entry;
756 pHandle->file.f_dentry->d_inode = &pHandle->inode;
757
758 pHandle->file.f_mode = FMODE_WRITE;
759 pHandle->inode.i_rdev = SNDRV_MINOR(deviceid, SNDRV_MINOR_CONTROL);
760
761 ret = alsa_fops->open(&pHandle->inode, &pHandle->file);
762 if(ret) {
763 goto failure;
764 }
765
766 //allocate memory for info element
767 pElemInfo = (struct snd_ctl_elem_info *)info;
768 if(pElemInfo == NULL) {
769 ret = pHandle->file.f_op->release(&pHandle->inode, &pHandle->file);
770 goto failure;
771 }
772
773// printk("sizeof elem_info %i\n",sizeof(struct snd_ctl_elem_info));
774
775 pElemInfo->id.numid = id;
776 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_CTL_IOCTL_ELEM_INFO, (ULONG)pElemInfo);
777 ret = pHandle->file.f_op->release(&pHandle->inode, &pHandle->file);
778 if(pHandle) kfree(pHandle);
779// printk("elem type: %i, id: %i, card: %i\n", pElemInfo->type, pElemInfo->id.numid, deviceid);
780 return OSSERR_SUCCESS;
781
782failure:
783 if(pHandle) {
784 kfree(pHandle);
785 }
786 DebugInt3();
787 return OSSERR_OUT_OF_MEMORY;
788}
789
790int GetUniaudControlValueGet(ULONG deviceid, ULONG id, void *value)
791{
792 struct snd_ctl_elem_value *pElem = NULL;
793 struct snd_ctl_elem_info *pElemInfo = NULL;
794 mixerhandle *pHandle = NULL;
795 int ret, i, j, sz;
796
797 if(alsa_fops == NULL) {
798 ret = OSSERR_NO_DEVICE_AVAILABLE;
799 goto failure;
800 }
801
802 sz = sizeof(mixerhandle);
803 pHandle = kmalloc(sz, GFP_KERNEL);
804 if(pHandle == NULL) {
805 ret = OSSERR_OUT_OF_MEMORY;
806 goto failure;
807 }
808 memset(pHandle, 0, sizeof(mixerhandle));
809
810 //set operation to non-blocking
811 pHandle->file.f_flags = O_NONBLOCK;
812
813 //setup pointers in file structure (used internally by ALSA)
814 pHandle->file.f_dentry = &pHandle->d_entry;
815 pHandle->file.f_dentry->d_inode = &pHandle->inode;
816
817 pHandle->file.f_mode = FMODE_WRITE;
818 pHandle->inode.i_rdev = SNDRV_MINOR(deviceid, SNDRV_MINOR_CONTROL);
819
820 ret = alsa_fops->open(&pHandle->inode, &pHandle->file);
821 if(ret) {
822 goto failure;
823 }
824
825 pElem = (struct snd_ctl_elem_value *)value;
826 if(pElem == NULL) {
827 ret = pHandle->file.f_op->release(&pHandle->inode, &pHandle->file);
828 goto failure;
829 }
830
831// printk("sizeof elem_info %i\n",sizeof(struct snd_ctl_elem_info));
832
833 pElem->id.numid = id;
834 pElem->indirect = 0;
835 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_CTL_IOCTL_ELEM_READ, (ULONG)pElem);
836 ret = pHandle->file.f_op->release(&pHandle->inode, &pHandle->file);
837 if(pHandle) kfree(pHandle);
838
839 return OSSERR_SUCCESS;
840failure:
841 if(pHandle) {
842 kfree(pHandle);
843 }
844 DebugInt3();
845 return OSSERR_OUT_OF_MEMORY;
846}
847
848int GetUniaudControlValuePut(ULONG deviceid, ULONG id, void *value)
849{
850 struct snd_ctl_elem_value *pElem = NULL;
851 struct snd_ctl_elem_info *pElemInfo = NULL;
852 mixerhandle *pHandle = NULL;
853 int ret, i, j, sz;
854
855 if(alsa_fops == NULL) {
856 ret = OSSERR_NO_DEVICE_AVAILABLE;
857 goto failure;
858 }
859
860 sz = sizeof(mixerhandle);
861 pHandle = kmalloc(sz, GFP_KERNEL);
862 if(pHandle == NULL) {
863 ret = OSSERR_OUT_OF_MEMORY;
864 goto failure;
865 }
866 memset(pHandle, 0, sizeof(mixerhandle));
867
868 //set operation to non-blocking
869 pHandle->file.f_flags = O_NONBLOCK;
870
871 //setup pointers in file structure (used internally by ALSA)
872 pHandle->file.f_dentry = &pHandle->d_entry;
873 pHandle->file.f_dentry->d_inode = &pHandle->inode;
874
875 pHandle->file.f_mode = FMODE_WRITE;
876 pHandle->inode.i_rdev = SNDRV_MINOR(deviceid, SNDRV_MINOR_CONTROL);
877
878 ret = alsa_fops->open(&pHandle->inode, &pHandle->file);
879 if(ret) {
880 goto failure;
881 }
882
883 pElem = (struct snd_ctl_elem_value *)value;
884 if(pElem == NULL) {
885 ret = pHandle->file.f_op->release(&pHandle->inode, &pHandle->file);
886 goto failure;
887 }
888
889// printk("sizeof elem_info %i\n",sizeof(struct snd_ctl_elem_info));
890
891 pElem->id.numid = id;
892 pElem->indirect = 0;
893 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_CTL_IOCTL_ELEM_WRITE, (ULONG)pElem);
894 ret = pHandle->file.f_op->release(&pHandle->inode, &pHandle->file);
895 if(pHandle) kfree(pHandle);
896
897 return OSSERR_SUCCESS;
898
899failure:
900 if(pHandle) {
901 kfree(pHandle);
902 }
903 DebugInt3();
904 return OSSERR_OUT_OF_MEMORY;
905}
906
907int UniaudIoctlHWRefine(OSSSTREAMID streamid, void *pHwParams)
908{
909 int ret;
910 soundhandle *pHandle = (soundhandle *)streamid;
911 struct snd_pcm_hw_params *params = NULL;
912
913 params = (struct snd_pcm_hw_params *)pHwParams;
914
915 if (!params) return -1001;
916
917 if (!pHandle) return -1002;
918
919 pHandle->file.f_flags = O_NONBLOCK;
920 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_PCM_IOCTL_HW_REFINE, (ULONG)params);
921 return ret;
922}
923
924int UniaudIoctlHWParamSet(OSSSTREAMID streamid, void *pHwParams)
925{
926 int ret;
927 soundhandle *pHandle = (soundhandle *)streamid;
928 struct snd_pcm_hw_params *params = NULL;
929
930 params = (struct snd_pcm_hw_params *)pHwParams;
931
932 if (!params) return -1001;
933 if (!pHandle) return -1002;
934
935 pHandle->file.f_flags = O_NONBLOCK;
936 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_PCM_IOCTL_HW_PARAMS, (ULONG)params);
937 return ret;
938}
939
940int UniaudIoctlSWParamSet(OSSSTREAMID streamid, void *pSwParams)
941{
942 int ret;
943 soundhandle *pHandle = (soundhandle *)streamid;
944 struct snd_pcm_sw_params *params = NULL;
945
946 params = (struct snd_pcm_sw_params *)pSwParams;
947
948 if (!params) return -1001;
949 if (!pHandle) return -1002;
950
951 pHandle->file.f_flags = O_NONBLOCK;
952
953 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_PCM_IOCTL_SW_PARAMS, (ULONG)params);
954 return ret;
955}
956
957int UniaudIoctlPCMStatus(OSSSTREAMID streamid, void *pstatus)
958{
959 int ret;
960 soundhandle *pHandle = (soundhandle *)streamid;
961 struct snd_pcm_status *status = (struct snd_pcm_status *)pstatus;
962
963 if (!status) return -1001;
964 if (!pHandle) return -1002;
965
966 pHandle->file.f_flags = O_NONBLOCK;
967
968 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_PCM_IOCTL_STATUS, (ULONG)status);
969 return ret;
970}
971
972int UniaudIoctlPCMWrite(OSSSTREAMID streamid, char *buf, int size)
973{
974 int ret;
975 soundhandle *pHandle = (soundhandle *)streamid;
976
977 if (!buf) return -1001;
978 if (!pHandle) return -1002;
979
980 pHandle->file.f_flags = O_NONBLOCK;
981
982 ret = pHandle->file.f_op->write(&pHandle->file, buf, size, &pHandle->file.f_pos);
983
984 return ret;
985}
986
987int UniaudIoctlPCMRead(OSSSTREAMID streamid, char *buf, int size)
988{
989 int ret;
990 soundhandle *pHandle = (soundhandle *)streamid;
991
992 if (!buf) return -1001;
993 if (!pHandle) return -1002;
994
995 pHandle->file.f_flags = O_NONBLOCK;
996
997 ret = pHandle->file.f_op->read(&pHandle->file, buf, size, &pHandle->file.f_pos);
998
999 return ret;
1000}
1001
1002int UniaudIoctlPCMPrepare(OSSSTREAMID streamid)
1003{
1004 int ret;
1005 soundhandle *pHandle = (soundhandle *)streamid;
1006
1007 if (!pHandle) return -1002;
1008
1009 pHandle->file.f_flags = O_NONBLOCK;
1010
1011 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_PCM_IOCTL_PREPARE, 0);
1012 return ret;
1013}
1014
1015int UniaudIoctlPCMResume(OSSSTREAMID streamid, int pause)
1016{
1017 int ret;
1018 soundhandle *pHandle = (soundhandle *)streamid;
1019
1020 if (!pHandle) return -1002;
1021
1022 pHandle->file.f_flags = O_NONBLOCK;
1023
1024 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_PCM_IOCTL_PAUSE, pause);
1025
1026 return ret;
1027}
1028
1029int UniaudIoctlPCMStart(OSSSTREAMID streamid)
1030{
1031 int ret;
1032 soundhandle *pHandle = (soundhandle *)streamid;
1033
1034 if (!pHandle) return -1002;
1035
1036 pHandle->file.f_flags = O_NONBLOCK;
1037
1038 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_PCM_IOCTL_START, 0);
1039
1040 return ret;
1041}
1042
1043int UniaudIoctlPCMDrop(OSSSTREAMID streamid)
1044{
1045 int ret;
1046 soundhandle *pHandle = (soundhandle *)streamid;
1047
1048 if (!pHandle) return -1002;
1049
1050 pHandle->file.f_flags = O_NONBLOCK;
1051
1052 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_PCM_IOCTL_DROP, 0);
1053
1054 return ret;
1055}
1056
1057void UniaudCloseAll(USHORT fileid)
1058{
1059 int i;
1060
1061 for (i=0; i < 8*256; i++)
1062 {
1063 if (opened_handles[i].handle != 0)
1064 {
1065 if (fileid)
1066 {
1067 if (fileid == opened_handles[i].FileId)
1068 {
1069 opened_handles[i].reuse = 0;
1070 if (OSS32_WaveClose((OSSSTREAMID)opened_handles[i].handle) == 0)
1071 opened_handles[i].handle = 0;
1072 }
1073 }
1074 else
1075 {
1076 opened_handles[i].reuse = 0;
1077 if (OSS32_WaveClose((OSSSTREAMID)opened_handles[i].handle) == 0)
1078 opened_handles[i].handle = 0;
1079 }
1080 }
1081 }
1082 return;
1083}
Note: See TracBrowser for help on using the repository browser.