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

Last change on this file since 550 was 550, checked in by David Azarewicz, 14 years ago

merge interrupt fixes 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
549 //dprintf(("GetUniaudCardInfo"));
550
551 if(alsa_fops == NULL) {
552 ret = OSSERR_NO_DEVICE_AVAILABLE;
553 goto failure;
554 }
555
556 pHandle = kmalloc(sizeof(mixerhandle), GFP_KERNEL);
557 if(pHandle == NULL) {
558 ret = OSSERR_OUT_OF_MEMORY;
559 goto failure;
560 }
561 memset(pHandle, 0, sizeof(mixerhandle));
562
563 //set operation to non-blocking
564 pHandle->file.f_flags = O_NONBLOCK;
565
566 //setup pointers in file structure (used internally by ALSA)
567 pHandle->file.f_dentry = &pHandle->d_entry;
568 pHandle->file.f_dentry->d_inode = &pHandle->inode;
569
570 pHandle->file.f_mode = FMODE_WRITE;
571 pHandle->inode.i_rdev = SNDRV_MINOR(deviceid, SNDRV_MINOR_CONTROL);
572
573 ret = alsa_fops->open(&pHandle->inode, &pHandle->file);
574 if(ret) {
575 goto failure;
576 }
577 //retrieve mixer information
578 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file,
579 SNDRV_CTL_IOCTL_CARD_INFO,
580 (ULONG)(struct snd_ctl_card_info *)info);
581 if(ret) {
582 ret = pHandle->file.f_op->release(&pHandle->inode, &pHandle->file);
583 goto failure;
584 }
585 ret = pHandle->file.f_op->release(&pHandle->inode, &pHandle->file);
586
587 if(pHandle) {
588 kfree(pHandle);
589 }
590 return OSSERR_SUCCESS;
591failure:
592 if(pHandle) {
593 kfree(pHandle);
594 }
595 DebugInt3();
596 return OSSERR_OUT_OF_MEMORY;
597}
598
599int GetUniaudControlNum(ULONG deviceid)
600{
601 mixerhandle *pHandle = NULL;
602 int ret, i, j, sz;
603
604 //dprintf(("GetUniaudControlNum"));
605
606 if(alsa_fops == NULL) {
607 ret = OSSERR_NO_DEVICE_AVAILABLE;
608 goto failure;
609 }
610
611 sz = sizeof(mixerhandle);
612 pHandle = kmalloc(sz, GFP_KERNEL);
613 if(pHandle == NULL) {
614 ret = OSSERR_OUT_OF_MEMORY;
615 goto failure;
616 }
617 memset(pHandle, 0, sizeof(mixerhandle));
618
619 //set operation to non-blocking
620 pHandle->file.f_flags = O_NONBLOCK;
621
622 //setup pointers in file structure (used internally by ALSA)
623 pHandle->file.f_dentry = &pHandle->d_entry;
624 pHandle->file.f_dentry->d_inode = &pHandle->inode;
625
626 pHandle->file.f_mode = FMODE_WRITE;
627 pHandle->inode.i_rdev = SNDRV_MINOR(deviceid, SNDRV_MINOR_CONTROL);
628
629 ret = alsa_fops->open(&pHandle->inode, &pHandle->file);
630 if(ret) {
631 goto failure;
632 }
633 //retrieve mixer information
634 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file,
635 SNDRV_CTL_IOCTL_CARD_INFO,
636 (ULONG)&pHandle->info);
637 if(ret) {
638 ret = pHandle->file.f_op->release(&pHandle->inode, &pHandle->file);
639 goto failure;
640 }
641 //get the number of mixer elements
642 pHandle->list.offset = 0;
643 pHandle->list.space = 0;
644 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file,
645 SNDRV_CTL_IOCTL_ELEM_LIST,
646 (ULONG)&pHandle->list);
647 if(ret) {
648 ret = pHandle->file.f_op->release(&pHandle->inode, &pHandle->file);
649 goto failure;
650 }
651 ret = pHandle->file.f_op->release(&pHandle->inode, &pHandle->file);
652 if(pHandle) {
653 if(pHandle->pids) kfree(pHandle->pids);
654 kfree(pHandle);
655 }
656 return pHandle->list.count;
657failure:
658 if(pHandle) {
659 if(pHandle->pids) kfree(pHandle->pids);
660 kfree(pHandle);
661 }
662 DebugInt3();
663 return OSSERR_OUT_OF_MEMORY;
664}
665
666int GetUniaudControls(ULONG deviceid, void *pids)
667{
668 mixerhandle *pHandle = NULL;
669 int ret, i, j, sz;
670
671 //dprintf(("GetUniaudControls"));
672
673 if(alsa_fops == NULL) {
674 ret = OSSERR_NO_DEVICE_AVAILABLE;
675 goto failure;
676 }
677
678 sz = sizeof(mixerhandle);
679 pHandle = kmalloc(sz, GFP_KERNEL);
680 if(pHandle == NULL) {
681 ret = OSSERR_OUT_OF_MEMORY;
682 goto failure;
683 }
684 memset(pHandle, 0, sizeof(mixerhandle));
685
686 //set operation to non-blocking
687 pHandle->file.f_flags = O_NONBLOCK;
688
689 //setup pointers in file structure (used internally by ALSA)
690 pHandle->file.f_dentry = &pHandle->d_entry;
691 pHandle->file.f_dentry->d_inode = &pHandle->inode;
692
693 pHandle->file.f_mode = FMODE_WRITE;
694 pHandle->inode.i_rdev = SNDRV_MINOR(deviceid, SNDRV_MINOR_CONTROL);
695
696 ret = alsa_fops->open(&pHandle->inode, &pHandle->file);
697 if(ret) {
698 goto failure;
699 }
700 //retrieve mixer information
701 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file,
702 SNDRV_CTL_IOCTL_CARD_INFO,
703 (ULONG)&pHandle->info);
704 if(ret) {
705 ret = pHandle->file.f_op->release(&pHandle->inode, &pHandle->file);
706 goto failure;
707 }
708 //get the number of mixer elements
709 pHandle->list.offset = 0;
710 pHandle->list.space = 0;
711 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file,
712 SNDRV_CTL_IOCTL_ELEM_LIST,
713 (ULONG)&pHandle->list);
714 if(ret) {
715 ret = pHandle->file.f_op->release(&pHandle->inode, &pHandle->file);
716 goto failure;
717 }
718
719 //allocate memory for all mixer elements
720 pHandle->pids = (struct snd_ctl_elem_id *)pids;
721 //kmalloc(sizeof(struct snd_ctl_elem_id)*pHandle->list.count, GFP_KERNEL);
722 if(pHandle->pids == NULL) {
723 ret = pHandle->file.f_op->release(&pHandle->inode, &pHandle->file);
724 goto failure;
725 }
726 //and retrieve all mixer elements
727 pHandle->list.offset = 0;
728 pHandle->list.space = pHandle->list.count;
729 pHandle->list.pids = pHandle->pids;
730 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file,
731 SNDRV_CTL_IOCTL_ELEM_LIST,
732 (ULONG)&pHandle->list);
733 if(ret) {
734 ret = pHandle->file.f_op->release(&pHandle->inode, &pHandle->file);
735 goto failure;
736 }
737// if (pids)
738// memcpy(pids, pHandle->pids,
739// sizeof(struct snd_ctl_elem_id)*pHandle->list.count);
740
741 ret = pHandle->file.f_op->release(&pHandle->inode, &pHandle->file);
742 if(pHandle) {
743// if(pHandle->pids) kfree(pHandle->pids);
744 kfree(pHandle);
745 }
746 return pHandle->list.count;
747failure:
748 if(pHandle) {
749// if(pHandle->pids) kfree(pHandle->pids);
750 kfree(pHandle);
751 }
752 DebugInt3();
753 return OSSERR_OUT_OF_MEMORY;
754}
755
756int GetUniaudControlInfo(ULONG deviceid, ULONG id, void *info)
757{
758 struct snd_ctl_elem_value *pElem = NULL;
759 struct snd_ctl_elem_info *pElemInfo = NULL;
760 mixerhandle *pHandle = NULL;
761 int ret, i, j, sz;
762
763 //dprintf(("GetUniaudControlInfo"));
764
765 if(alsa_fops == NULL) {
766 ret = OSSERR_NO_DEVICE_AVAILABLE;
767 goto failure;
768 }
769
770 sz = sizeof(mixerhandle);
771 pHandle = kmalloc(sz, GFP_KERNEL);
772 if(pHandle == NULL) {
773 ret = OSSERR_OUT_OF_MEMORY;
774 goto failure;
775 }
776 memset(pHandle, 0, sizeof(mixerhandle));
777
778 //set operation to non-blocking
779 pHandle->file.f_flags = O_NONBLOCK;
780
781 //setup pointers in file structure (used internally by ALSA)
782 pHandle->file.f_dentry = &pHandle->d_entry;
783 pHandle->file.f_dentry->d_inode = &pHandle->inode;
784
785 pHandle->file.f_mode = FMODE_WRITE;
786 pHandle->inode.i_rdev = SNDRV_MINOR(deviceid, SNDRV_MINOR_CONTROL);
787
788 ret = alsa_fops->open(&pHandle->inode, &pHandle->file);
789 if(ret) {
790 goto failure;
791 }
792
793 //allocate memory for info element
794 pElemInfo = (struct snd_ctl_elem_info *)info;
795 if(pElemInfo == NULL) {
796 ret = pHandle->file.f_op->release(&pHandle->inode, &pHandle->file);
797 goto failure;
798 }
799
800// printk("sizeof elem_info %i\n",sizeof(struct snd_ctl_elem_info));
801
802 pElemInfo->id.numid = id;
803 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_CTL_IOCTL_ELEM_INFO, (ULONG)pElemInfo);
804 ret = pHandle->file.f_op->release(&pHandle->inode, &pHandle->file);
805 if(pHandle) kfree(pHandle);
806// printk("elem type: %i, id: %i, card: %i\n", pElemInfo->type, pElemInfo->id.numid, deviceid);
807 return OSSERR_SUCCESS;
808
809failure:
810 if(pHandle) {
811 kfree(pHandle);
812 }
813 DebugInt3();
814 return OSSERR_OUT_OF_MEMORY;
815}
816
817int GetUniaudControlValueGet(ULONG deviceid, ULONG id, void *value)
818{
819 struct snd_ctl_elem_value *pElem = NULL;
820 //struct snd_ctl_elem_info *pElemInfo = NULL;
821 mixerhandle *pHandle = NULL;
822 int ret, i, j, sz;
823
824 if(alsa_fops == NULL) {
825 ret = OSSERR_NO_DEVICE_AVAILABLE;
826 goto failure;
827 }
828
829 sz = sizeof(mixerhandle);
830 pHandle = kmalloc(sz, GFP_KERNEL);
831 if(pHandle == NULL) {
832 ret = OSSERR_OUT_OF_MEMORY;
833 goto failure;
834 }
835 memset(pHandle, 0, sizeof(mixerhandle));
836
837 //set operation to non-blocking
838 pHandle->file.f_flags = O_NONBLOCK;
839
840 //setup pointers in file structure (used internally by ALSA)
841 pHandle->file.f_dentry = &pHandle->d_entry;
842 pHandle->file.f_dentry->d_inode = &pHandle->inode;
843
844 pHandle->file.f_mode = FMODE_WRITE;
845 pHandle->inode.i_rdev = SNDRV_MINOR(deviceid, SNDRV_MINOR_CONTROL);
846
847 ret = alsa_fops->open(&pHandle->inode, &pHandle->file);
848 if(ret) {
849 goto failure;
850 }
851
852 pElem = (struct snd_ctl_elem_value *)value;
853 if(pElem == NULL) {
854 ret = pHandle->file.f_op->release(&pHandle->inode, &pHandle->file);
855 goto failure;
856 }
857
858 pElem->id.numid = id;
859 pElem->indirect = 0;
860 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_CTL_IOCTL_ELEM_READ, (ULONG)pElem);
861 ret = pHandle->file.f_op->release(&pHandle->inode, &pHandle->file);
862 if(pHandle) kfree(pHandle);
863
864 //dprintf(("GetUniaudControlValueGet: id=%x 0=%x 1=%x", pElem->id.numid, pElem->value.integer.value[0], pElem->value.integer.value[1]));
865
866 return OSSERR_SUCCESS;
867failure:
868 if(pHandle) {
869 kfree(pHandle);
870 }
871 DebugInt3();
872 return OSSERR_OUT_OF_MEMORY;
873}
874
875int GetUniaudControlValuePut(ULONG deviceid, ULONG id, void *value)
876{
877 struct snd_ctl_elem_value *pElem = NULL;
878 //struct snd_ctl_elem_info *pElemInfo = NULL;
879 mixerhandle *pHandle = NULL;
880 int ret, i, j, sz;
881
882 if(alsa_fops == NULL) {
883 ret = OSSERR_NO_DEVICE_AVAILABLE;
884 goto failure;
885 }
886
887 sz = sizeof(mixerhandle);
888 pHandle = kmalloc(sz, GFP_KERNEL);
889 if(pHandle == NULL) {
890 ret = OSSERR_OUT_OF_MEMORY;
891 goto failure;
892 }
893 memset(pHandle, 0, sizeof(mixerhandle));
894
895 //set operation to non-blocking
896 pHandle->file.f_flags = O_NONBLOCK;
897
898 //setup pointers in file structure (used internally by ALSA)
899 pHandle->file.f_dentry = &pHandle->d_entry;
900 pHandle->file.f_dentry->d_inode = &pHandle->inode;
901
902 pHandle->file.f_mode = FMODE_WRITE;
903 pHandle->inode.i_rdev = SNDRV_MINOR(deviceid, SNDRV_MINOR_CONTROL);
904
905 ret = alsa_fops->open(&pHandle->inode, &pHandle->file);
906 if(ret) {
907 goto failure;
908 }
909
910 pElem = (struct snd_ctl_elem_value *)value;
911 if(pElem == NULL) {
912 ret = pHandle->file.f_op->release(&pHandle->inode, &pHandle->file);
913 goto failure;
914 }
915
916 pElem->id.numid = id;
917 pElem->indirect = 0;
918
919 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_CTL_IOCTL_ELEM_WRITE, (ULONG)pElem);
920 ret = pHandle->file.f_op->release(&pHandle->inode, &pHandle->file);
921 if(pHandle) kfree(pHandle);
922
923 return OSSERR_SUCCESS;
924
925failure:
926 if(pHandle) {
927 kfree(pHandle);
928 }
929 DebugInt3();
930 return OSSERR_OUT_OF_MEMORY;
931}
932
933int UniaudIoctlHWRefine(OSSSTREAMID streamid, void *pHwParams)
934{
935 int ret;
936 soundhandle *pHandle = (soundhandle *)streamid;
937 struct snd_pcm_hw_params *params = NULL;
938 params = (struct snd_pcm_hw_params *)pHwParams;
939
940 //dprintf(("UniaudIoctlHWRefine"));
941
942 if (!params) return -1001;
943
944 if (!pHandle) return -1002;
945
946 pHandle->file.f_flags = O_NONBLOCK;
947 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_PCM_IOCTL_HW_REFINE, (ULONG)params);
948 return ret;
949}
950
951int UniaudIoctlHWParamSet(OSSSTREAMID streamid, void *pHwParams)
952{
953 int ret;
954 soundhandle *pHandle = (soundhandle *)streamid;
955 struct snd_pcm_hw_params *params = NULL;
956 params = (struct snd_pcm_hw_params *)pHwParams;
957
958 //dprintf(("UniaudIoctlHWParamSet"));
959
960 if (!params) return -1001;
961 if (!pHandle) return -1002;
962
963 pHandle->file.f_flags = O_NONBLOCK;
964 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_PCM_IOCTL_HW_PARAMS, (ULONG)params);
965 return ret;
966}
967
968int UniaudIoctlSWParamSet(OSSSTREAMID streamid, void *pSwParams)
969{
970 int ret;
971 soundhandle *pHandle = (soundhandle *)streamid;
972 struct snd_pcm_sw_params *params = NULL;
973
974 params = (struct snd_pcm_sw_params *)pSwParams;
975
976 //dprintf(("UniaudIoctlSWParamSet"));
977
978 if (!params) return -1001;
979 if (!pHandle) return -1002;
980
981 pHandle->file.f_flags = O_NONBLOCK;
982
983 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_PCM_IOCTL_SW_PARAMS, (ULONG)params);
984 return ret;
985}
986
987int UniaudIoctlPCMStatus(OSSSTREAMID streamid, void *pstatus)
988{
989 int ret;
990 soundhandle *pHandle = (soundhandle *)streamid;
991 struct snd_pcm_status *status = (struct snd_pcm_status *)pstatus;
992
993 //dprintf(("UniaudIoctlPCMStatus"));
994
995 if (!status) return -1001;
996 if (!pHandle) return -1002;
997
998 pHandle->file.f_flags = O_NONBLOCK;
999
1000 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_PCM_IOCTL_STATUS, (ULONG)status);
1001 return ret;
1002}
1003
1004int UniaudIoctlPCMWrite(OSSSTREAMID streamid, char *buf, int size)
1005{
1006 int ret;
1007 soundhandle *pHandle = (soundhandle *)streamid;
1008
1009 //dprintf(("UniaudIoctlPCMWrite"));
1010
1011 if (!buf) return -1001;
1012 if (!pHandle) return -1002;
1013
1014 pHandle->file.f_flags = O_NONBLOCK;
1015
1016 ret = pHandle->file.f_op->write(&pHandle->file, buf, size, &pHandle->file.f_pos);
1017
1018 return ret;
1019}
1020
1021int UniaudIoctlPCMRead(OSSSTREAMID streamid, char *buf, int size)
1022{
1023 int ret;
1024 soundhandle *pHandle = (soundhandle *)streamid;
1025
1026 if (!buf) return -1001;
1027 if (!pHandle) return -1002;
1028
1029 //dprintf(("UniaudIoctlPCMRead"));
1030
1031 pHandle->file.f_flags = O_NONBLOCK;
1032
1033 ret = pHandle->file.f_op->read(&pHandle->file, buf, size, &pHandle->file.f_pos);
1034
1035 return ret;
1036}
1037
1038int UniaudIoctlPCMPrepare(OSSSTREAMID streamid)
1039{
1040 int ret;
1041 soundhandle *pHandle = (soundhandle *)streamid;
1042
1043 //dprintf(("UniaudIoctlPCMPrepare"));
1044
1045 if (!pHandle) return -1002;
1046
1047 pHandle->file.f_flags = O_NONBLOCK;
1048
1049 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_PCM_IOCTL_PREPARE, 0);
1050 return ret;
1051}
1052
1053int UniaudIoctlPCMResume(OSSSTREAMID streamid, int pause)
1054{
1055 int ret;
1056 soundhandle *pHandle = (soundhandle *)streamid;
1057
1058 //dprintf(("UniaudIoctlPCMResume: %x", pause));
1059
1060 if (!pHandle) return -1002;
1061
1062 pHandle->file.f_flags = O_NONBLOCK;
1063
1064 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_PCM_IOCTL_PAUSE, pause);
1065
1066 return ret;
1067}
1068
1069int UniaudIoctlPCMStart(OSSSTREAMID streamid)
1070{
1071 int ret;
1072 soundhandle *pHandle = (soundhandle *)streamid;
1073
1074 //dprintf(("UniaudIoctlPCMStart"));
1075
1076 if (!pHandle) return -1002;
1077
1078 pHandle->file.f_flags = O_NONBLOCK;
1079
1080 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_PCM_IOCTL_START, 0);
1081
1082 return ret;
1083}
1084
1085int UniaudIoctlPCMDrop(OSSSTREAMID streamid)
1086{
1087 int ret;
1088 soundhandle *pHandle = (soundhandle *)streamid;
1089
1090 //dprintf(("UniaudIoctlPCMDrop"));
1091
1092 if (!pHandle) return -1002;
1093
1094 pHandle->file.f_flags = O_NONBLOCK;
1095
1096 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_PCM_IOCTL_DROP, 0);
1097
1098 return ret;
1099}
1100
1101void UniaudCloseAll(USHORT fileid)
1102{
1103 int i;
1104
1105 for (i=0; i < 8*256; i++)
1106 {
1107 if (opened_handles[i].handle != 0)
1108 {
1109 if (fileid)
1110 {
1111 if (fileid == opened_handles[i].FileId)
1112 {
1113 opened_handles[i].reuse = 0;
1114 if (OSS32_WaveClose((OSSSTREAMID)opened_handles[i].handle) == 0)
1115 opened_handles[i].handle = 0;
1116 }
1117 }
1118 else
1119 {
1120 opened_handles[i].reuse = 0;
1121 if (OSS32_WaveClose((OSSSTREAMID)opened_handles[i].handle) == 0)
1122 opened_handles[i].handle = 0;
1123 }
1124 }
1125 }
1126 return;
1127}
Note: See TracBrowser for help on using the repository browser.