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

Last change on this file since 304 was 111, checked in by Brendan Oakley, 18 years ago

Paul's improvements to Makefiles and hda support

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); //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 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.