source: GPL/branches/uniaud32-2.1.x/lib32/ioctl.c@ 543

Last change on this file since 543 was 543, checked in by David Azarewicz, 15 years ago

Merge changes from trunk

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