source: GPL/branches/uniaud32-next/lib32/ioctl.c@ 715

Last change on this file since 715 was 677, checked in by Paul Smedley, 4 years ago

More code cleanups from AlexT from #os2russian

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