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

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

Cleanup compiler warnings

File size: 30.9 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 printk("j with tout =%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 printk("GetUniaudPcmCaps: out of memory\n");
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 printk("GetUniaudPcmCaps: wave open error %i %s at pcm %i\n", ret,
305 (j == 0) ?"PLAY":"REC", i);
306 continue;
307// goto fail;
308 }
309 pHandle = (soundhandle *)streamid;
310 if(pHandle == NULL || pHandle->magic != MAGIC_WAVE_ALSA32) {
311 printk("GetUniaudPcmCaps: invalid stream id \n");
312 ret = OSSERR_INVALID_STREAMID;
313// goto fail;
314 }
315
316 //set operation to non-blocking
317 pHandle->file.f_flags = O_NONBLOCK;
318
319 printk("GetUniaudPcmCaps: cp1. phandle %x\n", pHandle);
320 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_PCM_IOCTL_INFO, (ULONG)pcminfo);
321 if(ret != 0) {
322 printk("GetUniaudPcmCaps: SNDRV_PCM_IOCTL_INFO error %i\n", ret);
323 ret = UNIXToOSSError(ret);
324 continue;
325 }
326 if(pcminfo->name[0]) {
327 strncpy(pcaps->szDeviceName, pcminfo->name, sizeof(pcaps->szDeviceName));
328 }
329 else strncpy(pcaps->szDeviceName, pcminfo->id, sizeof(pcaps->szDeviceName));
330
331 if(pcminfo->subname[0]) {
332 strncpy(pcaps->szMixerName, pcminfo->subname, sizeof(pcaps->szMixerName));
333 }
334
335 pWaveCaps->nrStreams = pcminfo->subdevices_count;
336
337 printk("GetUniaudPcmCaps: cp2. nr of streams: %i\n", pWaveCaps->nrStreams);
338 //get all hardware parameters
339 _snd_pcm_hw_params_any(params);
340 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_PCM_IOCTL_HW_REFINE, (ULONG)params);
341 if(ret != 0) {
342 printk("GetUniaudPcmCaps: SNDRV_PCM_IOCTL_HW_REFINE error %i\n", ret);
343 ret = UNIXToOSSError(ret);
344 //goto fail;
345 continue;
346 }
347 printk("GetUniaudPcmCaps: cp3\n");
348
349 pWaveCaps->ulMinChannels = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS)->min;
350 pWaveCaps->ulMaxChannels = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS)->max;
351 printk("chan: from %i to %i\n", pWaveCaps->ulMinChannels,pWaveCaps->ulMaxChannels);
352 pWaveCaps->ulChanFlags = 0;
353 if(pWaveCaps->ulMinChannels == 1) {
354 pWaveCaps->ulChanFlags |= OSS32_CAPS_PCM_CHAN_MONO;
355 }
356 if(pWaveCaps->ulMaxChannels >= 2) {
357 pWaveCaps->ulChanFlags |= OSS32_CAPS_PCM_CHAN_STEREO;
358 }
359 if(pWaveCaps->ulMaxChannels >= 4) {
360 pWaveCaps->ulChanFlags |= OSS32_CAPS_PCM_CHAN_QUAD;
361 }
362 if(pWaveCaps->ulMaxChannels >= 6) {
363 pWaveCaps->ulChanFlags |= OSS32_CAPS_PCM_CHAN_5_1;
364 }
365
366 pWaveCaps->ulMinRate = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE)->min;
367 pWaveCaps->ulMaxRate = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE)->max;
368
369 mask = hw_param_mask(params, SNDRV_PCM_HW_PARAM_RATE_MASK);
370// mask = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
371 pWaveCaps->ulRateFlags = mask->bits[0];
372
373 pWaveCaps->ulRateFlags = ALSAToOSSRateFlags(pWaveCaps->ulRateFlags);
374
375 pWaveCaps->ulDataFormats = 0;
376
377 mask = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
378 format_mask = mask->bits[0];
379 for(fmt=0;fmt<32;fmt++)
380 {
381 if(format_mask & (1 << fmt))
382 {
383 int f = ALSAToOSSDataType(fmt);
384 if (f >= 0)
385 pWaveCaps->ulDataFormats |= f;
386 }
387 }
388
389 OSS32_WaveClose(streamid);
390 streamid = 0;
391 } // for j
392 pcaps++; // next pcm
393 } // for i
394
395 if (pcminfo) kfree(pcminfo);
396 return OSSERR_SUCCESS;
397}
398
399void FillCaps(ULONG deviceid)
400{
401 int pcms = 0;
402
403 pcms = pcm_instances(deviceid);
404
405 printk("pcms = %i\n", pcms); //uncommented
406 if (!pcmcaps[deviceid])
407 {
408 pcmcaps[deviceid] = (POSS32_DEVCAPS)kmalloc(sizeof(OSS32_DEVCAPS)*pcms, GFP_KERNEL);
409 if (pcmcaps[deviceid])
410 {
411 memset(pcmcaps[deviceid], 0, sizeof(OSS32_DEVCAPS)*pcms);
412 GetUniaudPcmCaps1(deviceid, (void *)pcmcaps[deviceid]);
413 }
414 }
415 return;
416}
417
418int GetUniaudPcmCaps(ULONG deviceid, void *caps)
419{
420 int pcms = 0;
421
422 pcms = pcm_instances(deviceid);
423
424// printk("pcms = %i\n", pcms);
425 if (pcmcaps[deviceid])
426 {
427 memcpy((unsigned char*)caps,(unsigned char*)pcmcaps[deviceid],sizeof(OSS32_DEVCAPS)*pcms);
428 return 0;
429 }
430 else
431 {
432 return -1;
433 }
434}
435
436/*
437 returns power state of given card
438 */
439int UniaudCtlGetPowerState(ULONG deviceid, void *state)
440{
441 mixerhandle *pHandle = NULL;
442 int ret, i, j;
443
444 if(alsa_fops == NULL) {
445 ret = OSSERR_NO_DEVICE_AVAILABLE;
446 goto failure;
447 }
448
449 pHandle = kmalloc(sizeof(mixerhandle), GFP_KERNEL);
450 if(pHandle == NULL) {
451 ret = OSSERR_OUT_OF_MEMORY;
452 goto failure;
453 }
454 memset(pHandle, 0, sizeof(mixerhandle));
455
456 //set operation to non-blocking
457 pHandle->file.f_flags = O_NONBLOCK;
458
459 //setup pointers in file structure (used internally by ALSA)
460 pHandle->file.f_dentry = &pHandle->d_entry;
461 pHandle->file.f_dentry->d_inode = &pHandle->inode;
462
463 pHandle->file.f_mode = FMODE_WRITE;
464 pHandle->inode.i_rdev = SNDRV_MINOR(deviceid, SNDRV_MINOR_CONTROL);
465
466 ret = alsa_fops->open(&pHandle->inode, &pHandle->file);
467 if(ret) {
468 goto failure;
469 }
470 //retrieve mixer information
471 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file,
472 SNDRV_CTL_IOCTL_POWER_STATE,
473 (ULONG)state);
474
475 pHandle->file.f_op->release(&pHandle->inode, &pHandle->file);
476
477 kfree(pHandle);
478
479 if(ret) {
480 goto failure;
481 }
482
483 return OSSERR_SUCCESS;
484failure:
485 DebugInt3();
486 return ret;
487}
488
489/*
490 sets power state for given card
491 */
492int UniaudCtlSetPowerState(ULONG deviceid, void *state)
493{
494 mixerhandle *pHandle = NULL;
495 int ret, i, j;
496
497 if(alsa_fops == NULL) {
498 ret = OSSERR_NO_DEVICE_AVAILABLE;
499 goto failure;
500 }
501
502 pHandle = kmalloc(sizeof(mixerhandle), GFP_KERNEL);
503 if(pHandle == NULL) {
504 ret = OSSERR_OUT_OF_MEMORY;
505 goto failure;
506 }
507 memset(pHandle, 0, sizeof(mixerhandle));
508
509 //set operation to non-blocking
510 pHandle->file.f_flags = O_NONBLOCK;
511
512 //setup pointers in file structure (used internally by ALSA)
513 pHandle->file.f_dentry = &pHandle->d_entry;
514 pHandle->file.f_dentry->d_inode = &pHandle->inode;
515
516 pHandle->file.f_mode = FMODE_WRITE;
517 pHandle->inode.i_rdev = SNDRV_MINOR(deviceid, SNDRV_MINOR_CONTROL);
518
519 ret = alsa_fops->open(&pHandle->inode, &pHandle->file);
520 if(ret) {
521 goto failure;
522 }
523 //retrieve mixer information
524 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file,
525 SNDRV_CTL_IOCTL_POWER,
526 (ULONG)state);
527
528 pHandle->file.f_op->release(&pHandle->inode, &pHandle->file);
529
530 kfree(pHandle);
531
532 if(ret) {
533 goto failure;
534 }
535
536 return OSSERR_SUCCESS;
537failure:
538 DebugInt3();
539 return ret;
540}
541
542/*
543 returns card info
544 */
545int GetUniaudCardInfo(ULONG deviceid, void *info)
546{
547 mixerhandle *pHandle = NULL;
548 int ret, i, j;
549// struct snd_ctl_card_info *pinfo;
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 if(alsa_fops == NULL) {
605 ret = OSSERR_NO_DEVICE_AVAILABLE;
606 goto failure;
607 }
608
609 sz = sizeof(mixerhandle);
610 pHandle = kmalloc(sz, GFP_KERNEL);
611 if(pHandle == NULL) {
612 ret = OSSERR_OUT_OF_MEMORY;
613 goto failure;
614 }
615 memset(pHandle, 0, sizeof(mixerhandle));
616
617 //set operation to non-blocking
618 pHandle->file.f_flags = O_NONBLOCK;
619
620 //setup pointers in file structure (used internally by ALSA)
621 pHandle->file.f_dentry = &pHandle->d_entry;
622 pHandle->file.f_dentry->d_inode = &pHandle->inode;
623
624 pHandle->file.f_mode = FMODE_WRITE;
625 pHandle->inode.i_rdev = SNDRV_MINOR(deviceid, SNDRV_MINOR_CONTROL);
626
627 ret = alsa_fops->open(&pHandle->inode, &pHandle->file);
628 if(ret) {
629 goto failure;
630 }
631 //retrieve mixer information
632 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file,
633 SNDRV_CTL_IOCTL_CARD_INFO,
634 (ULONG)&pHandle->info);
635 if(ret) {
636 ret = pHandle->file.f_op->release(&pHandle->inode, &pHandle->file);
637 goto failure;
638 }
639 //get the number of mixer elements
640 pHandle->list.offset = 0;
641 pHandle->list.space = 0;
642 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file,
643 SNDRV_CTL_IOCTL_ELEM_LIST,
644 (ULONG)&pHandle->list);
645 if(ret) {
646 ret = pHandle->file.f_op->release(&pHandle->inode, &pHandle->file);
647 goto failure;
648 }
649 ret = pHandle->file.f_op->release(&pHandle->inode, &pHandle->file);
650 if(pHandle) {
651 if(pHandle->pids) kfree(pHandle->pids);
652 kfree(pHandle);
653 }
654 return pHandle->list.count;
655failure:
656 if(pHandle) {
657 if(pHandle->pids) kfree(pHandle->pids);
658 kfree(pHandle);
659 }
660 DebugInt3();
661 return OSSERR_OUT_OF_MEMORY;
662}
663
664int GetUniaudControls(ULONG deviceid, void *pids)
665{
666 mixerhandle *pHandle = NULL;
667 int ret, i, j, sz;
668
669 if(alsa_fops == NULL) {
670 ret = OSSERR_NO_DEVICE_AVAILABLE;
671 goto failure;
672 }
673
674 sz = sizeof(mixerhandle);
675 pHandle = kmalloc(sz, GFP_KERNEL);
676 if(pHandle == NULL) {
677 ret = OSSERR_OUT_OF_MEMORY;
678 goto failure;
679 }
680 memset(pHandle, 0, sizeof(mixerhandle));
681
682 //set operation to non-blocking
683 pHandle->file.f_flags = O_NONBLOCK;
684
685 //setup pointers in file structure (used internally by ALSA)
686 pHandle->file.f_dentry = &pHandle->d_entry;
687 pHandle->file.f_dentry->d_inode = &pHandle->inode;
688
689 pHandle->file.f_mode = FMODE_WRITE;
690 pHandle->inode.i_rdev = SNDRV_MINOR(deviceid, SNDRV_MINOR_CONTROL);
691
692 ret = alsa_fops->open(&pHandle->inode, &pHandle->file);
693 if(ret) {
694 goto failure;
695 }
696 //retrieve mixer information
697 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file,
698 SNDRV_CTL_IOCTL_CARD_INFO,
699 (ULONG)&pHandle->info);
700 if(ret) {
701 ret = pHandle->file.f_op->release(&pHandle->inode, &pHandle->file);
702 goto failure;
703 }
704 //get the number of mixer elements
705 pHandle->list.offset = 0;
706 pHandle->list.space = 0;
707 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file,
708 SNDRV_CTL_IOCTL_ELEM_LIST,
709 (ULONG)&pHandle->list);
710 if(ret) {
711 ret = pHandle->file.f_op->release(&pHandle->inode, &pHandle->file);
712 goto failure;
713 }
714
715 //allocate memory for all mixer elements
716 pHandle->pids = (struct snd_ctl_elem_id *)pids;
717 //kmalloc(sizeof(struct snd_ctl_elem_id)*pHandle->list.count, GFP_KERNEL);
718 if(pHandle->pids == NULL) {
719 ret = pHandle->file.f_op->release(&pHandle->inode, &pHandle->file);
720 goto failure;
721 }
722 //and retrieve all mixer elements
723 pHandle->list.offset = 0;
724 pHandle->list.space = pHandle->list.count;
725 pHandle->list.pids = pHandle->pids;
726 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file,
727 SNDRV_CTL_IOCTL_ELEM_LIST,
728 (ULONG)&pHandle->list);
729 if(ret) {
730 ret = pHandle->file.f_op->release(&pHandle->inode, &pHandle->file);
731 goto failure;
732 }
733// if (pids)
734// memcpy(pids, pHandle->pids,
735// sizeof(struct snd_ctl_elem_id)*pHandle->list.count);
736
737 ret = pHandle->file.f_op->release(&pHandle->inode, &pHandle->file);
738 if(pHandle) {
739// if(pHandle->pids) kfree(pHandle->pids);
740 kfree(pHandle);
741 }
742 return pHandle->list.count;
743failure:
744 if(pHandle) {
745// if(pHandle->pids) kfree(pHandle->pids);
746 kfree(pHandle);
747 }
748 DebugInt3();
749 return OSSERR_OUT_OF_MEMORY;
750}
751
752int GetUniaudControlInfo(ULONG deviceid, ULONG id, void *info)
753{
754 struct snd_ctl_elem_value *pElem = NULL;
755 struct snd_ctl_elem_info *pElemInfo = NULL;
756 mixerhandle *pHandle = NULL;
757 int ret, i, j, sz;
758
759 if(alsa_fops == NULL) {
760 ret = OSSERR_NO_DEVICE_AVAILABLE;
761 goto failure;
762 }
763
764 sz = sizeof(mixerhandle);
765 pHandle = kmalloc(sz, GFP_KERNEL);
766 if(pHandle == NULL) {
767 ret = OSSERR_OUT_OF_MEMORY;
768 goto failure;
769 }
770 memset(pHandle, 0, sizeof(mixerhandle));
771
772 //set operation to non-blocking
773 pHandle->file.f_flags = O_NONBLOCK;
774
775 //setup pointers in file structure (used internally by ALSA)
776 pHandle->file.f_dentry = &pHandle->d_entry;
777 pHandle->file.f_dentry->d_inode = &pHandle->inode;
778
779 pHandle->file.f_mode = FMODE_WRITE;
780 pHandle->inode.i_rdev = SNDRV_MINOR(deviceid, SNDRV_MINOR_CONTROL);
781
782 ret = alsa_fops->open(&pHandle->inode, &pHandle->file);
783 if(ret) {
784 goto failure;
785 }
786
787 //allocate memory for info element
788 pElemInfo = (struct snd_ctl_elem_info *)info;
789 if(pElemInfo == NULL) {
790 ret = pHandle->file.f_op->release(&pHandle->inode, &pHandle->file);
791 goto failure;
792 }
793
794// printk("sizeof elem_info %i\n",sizeof(struct snd_ctl_elem_info));
795
796 pElemInfo->id.numid = id;
797 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_CTL_IOCTL_ELEM_INFO, (ULONG)pElemInfo);
798 ret = pHandle->file.f_op->release(&pHandle->inode, &pHandle->file);
799 if(pHandle) kfree(pHandle);
800// printk("elem type: %i, id: %i, card: %i\n", pElemInfo->type, pElemInfo->id.numid, deviceid);
801 return OSSERR_SUCCESS;
802
803failure:
804 if(pHandle) {
805 kfree(pHandle);
806 }
807 DebugInt3();
808 return OSSERR_OUT_OF_MEMORY;
809}
810
811int GetUniaudControlValueGet(ULONG deviceid, ULONG id, void *value)
812{
813 struct snd_ctl_elem_value *pElem = NULL;
814 struct snd_ctl_elem_info *pElemInfo = NULL;
815 mixerhandle *pHandle = NULL;
816 int ret, i, j, sz;
817
818 if(alsa_fops == NULL) {
819 ret = OSSERR_NO_DEVICE_AVAILABLE;
820 goto failure;
821 }
822
823 sz = sizeof(mixerhandle);
824 pHandle = kmalloc(sz, GFP_KERNEL);
825 if(pHandle == NULL) {
826 ret = OSSERR_OUT_OF_MEMORY;
827 goto failure;
828 }
829 memset(pHandle, 0, sizeof(mixerhandle));
830
831 //set operation to non-blocking
832 pHandle->file.f_flags = O_NONBLOCK;
833
834 //setup pointers in file structure (used internally by ALSA)
835 pHandle->file.f_dentry = &pHandle->d_entry;
836 pHandle->file.f_dentry->d_inode = &pHandle->inode;
837
838 pHandle->file.f_mode = FMODE_WRITE;
839 pHandle->inode.i_rdev = SNDRV_MINOR(deviceid, SNDRV_MINOR_CONTROL);
840
841 ret = alsa_fops->open(&pHandle->inode, &pHandle->file);
842 if(ret) {
843 goto failure;
844 }
845
846 pElem = (struct snd_ctl_elem_value *)value;
847 if(pElem == NULL) {
848 ret = pHandle->file.f_op->release(&pHandle->inode, &pHandle->file);
849 goto failure;
850 }
851
852// printk("sizeof elem_info %i\n",sizeof(struct snd_ctl_elem_info));
853
854 pElem->id.numid = id;
855 pElem->indirect = 0;
856 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_CTL_IOCTL_ELEM_READ, (ULONG)pElem);
857 ret = pHandle->file.f_op->release(&pHandle->inode, &pHandle->file);
858 if(pHandle) kfree(pHandle);
859
860 return OSSERR_SUCCESS;
861failure:
862 if(pHandle) {
863 kfree(pHandle);
864 }
865 DebugInt3();
866 return OSSERR_OUT_OF_MEMORY;
867}
868
869int GetUniaudControlValuePut(ULONG deviceid, ULONG id, void *value)
870{
871 struct snd_ctl_elem_value *pElem = NULL;
872 struct snd_ctl_elem_info *pElemInfo = NULL;
873 mixerhandle *pHandle = NULL;
874 int ret, i, j, sz;
875
876 if(alsa_fops == NULL) {
877 ret = OSSERR_NO_DEVICE_AVAILABLE;
878 goto failure;
879 }
880
881 sz = sizeof(mixerhandle);
882 pHandle = kmalloc(sz, GFP_KERNEL);
883 if(pHandle == NULL) {
884 ret = OSSERR_OUT_OF_MEMORY;
885 goto failure;
886 }
887 memset(pHandle, 0, sizeof(mixerhandle));
888
889 //set operation to non-blocking
890 pHandle->file.f_flags = O_NONBLOCK;
891
892 //setup pointers in file structure (used internally by ALSA)
893 pHandle->file.f_dentry = &pHandle->d_entry;
894 pHandle->file.f_dentry->d_inode = &pHandle->inode;
895
896 pHandle->file.f_mode = FMODE_WRITE;
897 pHandle->inode.i_rdev = SNDRV_MINOR(deviceid, SNDRV_MINOR_CONTROL);
898
899 ret = alsa_fops->open(&pHandle->inode, &pHandle->file);
900 if(ret) {
901 goto failure;
902 }
903
904 pElem = (struct snd_ctl_elem_value *)value;
905 if(pElem == NULL) {
906 ret = pHandle->file.f_op->release(&pHandle->inode, &pHandle->file);
907 goto failure;
908 }
909
910// printk("sizeof elem_info %i\n",sizeof(struct snd_ctl_elem_info));
911
912 pElem->id.numid = id;
913 pElem->indirect = 0;
914 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_CTL_IOCTL_ELEM_WRITE, (ULONG)pElem);
915 ret = pHandle->file.f_op->release(&pHandle->inode, &pHandle->file);
916 if(pHandle) kfree(pHandle);
917
918 return OSSERR_SUCCESS;
919
920failure:
921 if(pHandle) {
922 kfree(pHandle);
923 }
924 DebugInt3();
925 return OSSERR_OUT_OF_MEMORY;
926}
927
928int UniaudIoctlHWRefine(OSSSTREAMID streamid, void *pHwParams)
929{
930 int ret;
931 soundhandle *pHandle = (soundhandle *)streamid;
932 struct snd_pcm_hw_params *params = NULL;
933 printk("PS UniaudIoctlHWRefine\n");
934 params = (struct snd_pcm_hw_params *)pHwParams;
935
936 if (!params) return -1001;
937
938 if (!pHandle) return -1002;
939
940 pHandle->file.f_flags = O_NONBLOCK;
941 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_PCM_IOCTL_HW_REFINE, (ULONG)params);
942 return ret;
943}
944
945int UniaudIoctlHWParamSet(OSSSTREAMID streamid, void *pHwParams)
946{
947 int ret;
948 soundhandle *pHandle = (soundhandle *)streamid;
949 struct snd_pcm_hw_params *params = NULL;
950 printk("PS UniaudIoctlHWParamSet\n");
951 params = (struct snd_pcm_hw_params *)pHwParams;
952
953 if (!params) return -1001;
954 if (!pHandle) return -1002;
955
956 pHandle->file.f_flags = O_NONBLOCK;
957 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_PCM_IOCTL_HW_PARAMS, (ULONG)params);
958 return ret;
959}
960
961int UniaudIoctlSWParamSet(OSSSTREAMID streamid, void *pSwParams)
962{
963 int ret;
964 soundhandle *pHandle = (soundhandle *)streamid;
965 struct snd_pcm_sw_params *params = NULL;
966 printk("PS UniaudIoctlSWParamSet\n");
967 params = (struct snd_pcm_sw_params *)pSwParams;
968
969 if (!params) return -1001;
970 if (!pHandle) return -1002;
971
972 pHandle->file.f_flags = O_NONBLOCK;
973
974 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_PCM_IOCTL_SW_PARAMS, (ULONG)params);
975 return ret;
976}
977
978int UniaudIoctlPCMStatus(OSSSTREAMID streamid, void *pstatus)
979{
980 int ret;
981 soundhandle *pHandle = (soundhandle *)streamid;
982 struct snd_pcm_status *status = (struct snd_pcm_status *)pstatus;
983
984 if (!status) return -1001;
985 if (!pHandle) return -1002;
986
987 pHandle->file.f_flags = O_NONBLOCK;
988
989 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_PCM_IOCTL_STATUS, (ULONG)status);
990 return ret;
991}
992
993int UniaudIoctlPCMWrite(OSSSTREAMID streamid, char *buf, int size)
994{
995 int ret;
996 soundhandle *pHandle = (soundhandle *)streamid;
997
998 if (!buf) return -1001;
999 if (!pHandle) return -1002;
1000
1001 pHandle->file.f_flags = O_NONBLOCK;
1002
1003 ret = pHandle->file.f_op->write(&pHandle->file, buf, size, &pHandle->file.f_pos);
1004
1005 return ret;
1006}
1007
1008int UniaudIoctlPCMRead(OSSSTREAMID streamid, char *buf, int size)
1009{
1010 int ret;
1011 soundhandle *pHandle = (soundhandle *)streamid;
1012
1013 if (!buf) return -1001;
1014 if (!pHandle) return -1002;
1015
1016 pHandle->file.f_flags = O_NONBLOCK;
1017
1018 ret = pHandle->file.f_op->read(&pHandle->file, buf, size, &pHandle->file.f_pos);
1019
1020 return ret;
1021}
1022
1023int UniaudIoctlPCMPrepare(OSSSTREAMID streamid)
1024{
1025 int ret;
1026 soundhandle *pHandle = (soundhandle *)streamid;
1027
1028 if (!pHandle) return -1002;
1029
1030 pHandle->file.f_flags = O_NONBLOCK;
1031
1032 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_PCM_IOCTL_PREPARE, 0);
1033 return ret;
1034}
1035
1036int UniaudIoctlPCMResume(OSSSTREAMID streamid, int pause)
1037{
1038 int ret;
1039 soundhandle *pHandle = (soundhandle *)streamid;
1040
1041 if (!pHandle) return -1002;
1042
1043 pHandle->file.f_flags = O_NONBLOCK;
1044
1045 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_PCM_IOCTL_PAUSE, pause);
1046
1047 return ret;
1048}
1049
1050int UniaudIoctlPCMStart(OSSSTREAMID streamid)
1051{
1052 int ret;
1053 soundhandle *pHandle = (soundhandle *)streamid;
1054
1055 if (!pHandle) return -1002;
1056
1057 pHandle->file.f_flags = O_NONBLOCK;
1058
1059 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_PCM_IOCTL_START, 0);
1060
1061 return ret;
1062}
1063
1064int UniaudIoctlPCMDrop(OSSSTREAMID streamid)
1065{
1066 int ret;
1067 soundhandle *pHandle = (soundhandle *)streamid;
1068
1069 if (!pHandle) return -1002;
1070
1071 pHandle->file.f_flags = O_NONBLOCK;
1072
1073 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_PCM_IOCTL_DROP, 0);
1074
1075 return ret;
1076}
1077
1078void UniaudCloseAll(USHORT fileid)
1079{
1080 int i;
1081
1082 for (i=0; i < 8*256; i++)
1083 {
1084 if (opened_handles[i].handle != 0)
1085 {
1086 if (fileid)
1087 {
1088 if (fileid == opened_handles[i].FileId)
1089 {
1090 opened_handles[i].reuse = 0;
1091 if (OSS32_WaveClose((OSSSTREAMID)opened_handles[i].handle) == 0)
1092 opened_handles[i].handle = 0;
1093 }
1094 }
1095 else
1096 {
1097 opened_handles[i].reuse = 0;
1098 if (OSS32_WaveClose((OSSSTREAMID)opened_handles[i].handle) == 0)
1099 opened_handles[i].handle = 0;
1100 }
1101 }
1102 }
1103 return;
1104}
Note: See TracBrowser for help on using the repository browser.