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

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

merge changes from trunk

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