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

Last change on this file since 675 was 675, 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 <u32ioctl.h>
24
25POSS32_DEVCAPS pcmcaps[8] = {0,0,0,0,0,0,0,0};
26extern int pcm_device;
27extern OpenedHandles opened_handles[8*256];
28
29/*
30 * Control ID changed by an external
31 * set by snd_ctl_notify()
32 */
33struct snd_pcm_substream *substream_int[8*256] = {0}; // interrupted substream
34
35int control_id_changed = 0;
36int card_id_changed = 0;
37int unlock_all = 0;
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
182/*
183int GetPcmForChannels(ULONG deviceid, int type, int channels)
184{
185 POSS32_DEVCAPS pcaps = NULL;
186 WAVE_CAPS *wc;
187 int i;
188 int sel_pcm = -1;
189
190 if (!pcmcaps[deviceid])
191 {
192 FillCaps(deviceid);
193 if (!pcmcaps[deviceid])
194 {
195 printk("Error querying caps for device: %i\n", deviceid);
196 return -1;
197 }
198 }
199
200 pcaps = pcmcaps[deviceid];
201
202 for (i=0; i<pcm_instances(deviceid);i++)
203 {
204 switch(type)
205 {
206 case OSS32_CAPS_WAVE_PLAYBACK: // play
207 wc = &pcaps->waveOutCaps;
208 break;
209 case OSS32_CAPS_WAVE_CAPTURE: // record
210 wc = &pcaps->waveInCaps;
211 break;
212 }
213 if (wc->ulMaxChannels == channels)
214 {
215 sel_pcm = i;
216 break;
217 }
218 pcaps++;
219 }
220
221 return sel_pcm;
222}
223*/
224
225int GetMaxChannels(ULONG deviceid, int type)
226{
227 POSS32_DEVCAPS pcaps = NULL;
228 WAVE_CAPS *wc;
229 int i;
230 //int sel_pcm = -1;
231 int max_ch = 0;
232
233 if (!pcmcaps[deviceid])
234 {
235 FillCaps(deviceid);
236 if (!pcmcaps[deviceid])
237 {
238 printk("Error querying caps for device: %i\n", deviceid);
239 return -1;
240 }
241 }
242
243 pcaps = pcmcaps[deviceid];
244
245 for (i=0; i<pcm_instances(deviceid);i++)
246 {
247 switch(type)
248 {
249 case OSS32_CAPS_WAVE_PLAYBACK: // play
250 wc = &pcaps->waveOutCaps;
251 break;
252 case OSS32_CAPS_WAVE_CAPTURE: // record
253 wc = &pcaps->waveInCaps;
254 break;
255 }
256 if (wc->ulMaxChannels > max_ch)
257 max_ch = wc->ulMaxChannels;
258 pcaps++;
259 }
260 return max_ch;
261}
262
263/*
264 returns pcm caps
265 */
266static int GetUniaudPcmCaps1(ULONG deviceid, void *caps)
267{
268 POSS32_DEVCAPS pcaps = (POSS32_DEVCAPS)caps;
269 int i;
270 OSSSTREAMID streamid = 0;
271 soundhandle *pHandle;
272 struct snd_pcm_info *pcminfo = NULL;
273 struct snd_pcm_hw_params *params;
274 int ret, fmt, j;
275 ULONG format_mask;
276 struct snd_mask *mask;
277 int pcms = 0;
278
279 pcms = pcm_instances(deviceid);
280
281 if (!pcaps || !pcms) return -1;
282
283
284 //these structures are too big to put on the stack
285 pcminfo = (struct snd_pcm_info *)kmalloc(sizeof(struct snd_pcm_info)+sizeof(struct snd_pcm_hw_params), GFP_KERNEL);
286 if(pcminfo == NULL) {
287 DebugInt3();
288 rprintf(("GetUniaudPcmCaps: out of memory"));
289 return OSSERR_OUT_OF_MEMORY;
290 }
291 params = (struct snd_pcm_hw_params *)(pcminfo+1);
292
293 for (i=0; i<pcms;i++)
294 {
295 pcaps->nrDevices = nrCardsDetected;
296 pcaps->ulCaps = OSS32_CAPS_WAVE_PLAYBACK | OSS32_CAPS_WAVE_CAPTURE;
297
298 //query wave in & out caps
299 for(j=0;j<2;j++)
300 {
301 PWAVE_CAPS pWaveCaps = (j == 0) ? &pcaps->waveOutCaps : &pcaps->waveInCaps;
302
303 ret = OSS32_WaveOpen(deviceid, (j == 0) ? OSS32_STREAM_WAVEOUT : OSS32_STREAM_WAVEIN, &streamid, i, 0);
304 if(ret != OSSERR_SUCCESS)
305 {
306 dprintf(("GetUniaudPcmCaps1: wave open error %i %s at pcm %i", ret, (j == 0) ?"PLAY":"REC", i));
307 continue;
308 //goto fail;
309 }
310 pHandle = (soundhandle *)streamid;
311 if(pHandle == NULL || pHandle->magic != MAGIC_WAVE_ALSA32) {
312 rprintf(("GetUniaudPcmCaps: invalid stream id"));
313 ret = OSSERR_INVALID_STREAMID;
314 //goto fail;
315 }
316
317 //set operation to non-blocking
318 pHandle->file.f_flags = O_NONBLOCK;
319
320 dprintf(("GetUniaudPcmCaps: cp1. pcm %i, phandle %x", i, pHandle));
321 ret = pHandle->file.f_op->unlocked_ioctl(&pHandle->file, SNDRV_PCM_IOCTL_INFO, (ULONG)pcminfo);
322 if(ret != 0) {
323 rprintf(("GetUniaudPcmCaps: SNDRV_PCM_IOCTL_INFO error %i", ret));
324 ret = UNIXToOSSError(ret);
325 continue;
326 }
327 if(pcminfo->name[0]) {
328 strncpy(pcaps->szDeviceName, pcminfo->name, sizeof(pcaps->szDeviceName));
329 }
330 else strncpy(pcaps->szDeviceName, pcminfo->id, sizeof(pcaps->szDeviceName));
331
332 if(pcminfo->subname[0]) {
333 strncpy(pcaps->szMixerName, pcminfo->subname, sizeof(pcaps->szMixerName));
334 }
335
336 pWaveCaps->nrStreams = pcminfo->subdevices_count;
337
338 dprintf(("GetUniaudPcmCaps: pcm %i, cp2. nr of streams: %i", i, pWaveCaps->nrStreams));
339 //get all hardware parameters
340 _snd_pcm_hw_params_any(params);
341 ret = pHandle->file.f_op->unlocked_ioctl(&pHandle->file, SNDRV_PCM_IOCTL_HW_REFINE, (ULONG)params);
342 if(ret != 0) {
343 dprintf(("GetUniaudPcmCaps: SNDRV_PCM_IOCTL_HW_REFINE error %i", ret));
344 ret = UNIXToOSSError(ret);
345 //goto fail;
346 continue;
347 }
348 //dprintf("GetUniaudPcmCaps: cp3"));
349
350 pWaveCaps->ulMinChannels = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS)->min;
351 pWaveCaps->ulMaxChannels = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS)->max;
352 dprintf(("chan: from %i to %i\n", pWaveCaps->ulMinChannels,pWaveCaps->ulMaxChannels));
353 pWaveCaps->ulChanFlags = 0;
354 if(pWaveCaps->ulMinChannels == 1) {
355 pWaveCaps->ulChanFlags |= OSS32_CAPS_PCM_CHAN_MONO;
356 }
357 if(pWaveCaps->ulMaxChannels >= 2) {
358 pWaveCaps->ulChanFlags |= OSS32_CAPS_PCM_CHAN_STEREO;
359 }
360 if(pWaveCaps->ulMaxChannels >= 4) {
361 pWaveCaps->ulChanFlags |= OSS32_CAPS_PCM_CHAN_QUAD;
362 }
363 if(pWaveCaps->ulMaxChannels >= 6) {
364 pWaveCaps->ulChanFlags |= OSS32_CAPS_PCM_CHAN_5_1;
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 //dprintf(("FillCaps: pcms=%i\n", pcms));
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;
443 //int i, j;
444
445 if(alsa_fops == NULL) {
446 ret = OSSERR_NO_DEVICE_AVAILABLE;
447 goto failure;
448 }
449
450 pHandle = kmalloc(sizeof(mixerhandle), GFP_KERNEL);
451 if(pHandle == NULL) {
452 ret = OSSERR_OUT_OF_MEMORY;
453 goto failure;
454 }
455 memset(pHandle, 0, sizeof(mixerhandle));
456
457 //set operation to non-blocking
458 pHandle->file.f_flags = O_NONBLOCK;
459
460 //setup pointers in file structure (used internally by ALSA)
461 pHandle->file.f_dentry = &pHandle->d_entry;
462 pHandle->file.f_dentry->d_inode = &pHandle->inode;
463
464 pHandle->file.f_mode = FMODE_WRITE;
465 pHandle->inode.i_rdev = SNDRV_MINOR(deviceid, SNDRV_MINOR_CONTROL);
466
467 ret = alsa_fops->open(&pHandle->inode, &pHandle->file);
468 if(ret) {
469 goto failure;
470 }
471 //retrieve mixer information
472 ret = pHandle->file.f_op->unlocked_ioctl(&pHandle->file,
473 SNDRV_CTL_IOCTL_POWER_STATE,
474 (ULONG)state);
475
476 pHandle->file.f_op->release(&pHandle->inode, &pHandle->file);
477
478 kfree(pHandle);
479
480 if(ret) {
481 goto failure;
482 }
483
484 return OSSERR_SUCCESS;
485failure:
486 DebugInt3();
487 return ret;
488}
489
490/*
491 sets power state for given card
492 */
493int UniaudCtlSetPowerState(ULONG deviceid, void *state)
494{
495 mixerhandle *pHandle = NULL;
496 int ret;
497 //int i, j;
498
499 if(alsa_fops == NULL) {
500 ret = OSSERR_NO_DEVICE_AVAILABLE;
501 goto failure;
502 }
503
504 pHandle = kmalloc(sizeof(mixerhandle), GFP_KERNEL);
505 if(pHandle == NULL) {
506 ret = OSSERR_OUT_OF_MEMORY;
507 goto failure;
508 }
509 memset(pHandle, 0, sizeof(mixerhandle));
510
511 //set operation to non-blocking
512 pHandle->file.f_flags = O_NONBLOCK;
513
514 //setup pointers in file structure (used internally by ALSA)
515 pHandle->file.f_dentry = &pHandle->d_entry;
516 pHandle->file.f_dentry->d_inode = &pHandle->inode;
517
518 pHandle->file.f_mode = FMODE_WRITE;
519 pHandle->inode.i_rdev = SNDRV_MINOR(deviceid, SNDRV_MINOR_CONTROL);
520
521 ret = alsa_fops->open(&pHandle->inode, &pHandle->file);
522 if(ret) {
523 goto failure;
524 }
525 //retrieve mixer information
526 ret = pHandle->file.f_op->unlocked_ioctl(&pHandle->file,
527 SNDRV_CTL_IOCTL_POWER,
528 (ULONG)state);
529
530 pHandle->file.f_op->release(&pHandle->inode, &pHandle->file);
531
532 kfree(pHandle);
533
534 if(ret) {
535 goto failure;
536 }
537
538 return OSSERR_SUCCESS;
539failure:
540 DebugInt3();
541 return ret;
542}
543
544/*
545 returns card info
546 */
547int GetUniaudCardInfo(ULONG deviceid, void *info)
548{
549 mixerhandle *pHandle = NULL;
550 int ret;
551 //int i, j;
552
553 //dprintf(("GetUniaudCardInfo"));
554
555 if(alsa_fops == NULL) {
556 ret = OSSERR_NO_DEVICE_AVAILABLE;
557 goto failure;
558 }
559
560 pHandle = kmalloc(sizeof(mixerhandle), GFP_KERNEL);
561 if(pHandle == NULL) {
562 ret = OSSERR_OUT_OF_MEMORY;
563 goto failure;
564 }
565 memset(pHandle, 0, sizeof(mixerhandle));
566
567 //set operation to non-blocking
568 pHandle->file.f_flags = O_NONBLOCK;
569
570 //setup pointers in file structure (used internally by ALSA)
571 pHandle->file.f_dentry = &pHandle->d_entry;
572 pHandle->file.f_dentry->d_inode = &pHandle->inode;
573
574 pHandle->file.f_mode = FMODE_WRITE;
575 pHandle->inode.i_rdev = SNDRV_MINOR(deviceid, SNDRV_MINOR_CONTROL);
576
577 ret = alsa_fops->open(&pHandle->inode, &pHandle->file);
578 if(ret) {
579 goto failure;
580 }
581 //retrieve mixer information
582 ret = pHandle->file.f_op->unlocked_ioctl(&pHandle->file,
583 SNDRV_CTL_IOCTL_CARD_INFO,
584 (ULONG)(struct snd_ctl_card_info *)info);
585 if(ret) {
586 ret = pHandle->file.f_op->release(&pHandle->inode, &pHandle->file);
587 goto failure;
588 }
589 ret = pHandle->file.f_op->release(&pHandle->inode, &pHandle->file);
590
591 if(pHandle) {
592 kfree(pHandle);
593 }
594 return OSSERR_SUCCESS;
595failure:
596 if(pHandle) {
597 kfree(pHandle);
598 }
599 DebugInt3();
600 return OSSERR_OUT_OF_MEMORY;
601}
602
603int GetUniaudControlNum(ULONG deviceid)
604{
605 mixerhandle *pHandle = NULL;
606 int ret, sz;
607 //int i, j;
608
609 //dprintf(("GetUniaudControlNum"));
610
611 if(alsa_fops == NULL) {
612 ret = OSSERR_NO_DEVICE_AVAILABLE;
613 goto failure;
614 }
615
616 sz = sizeof(mixerhandle);
617 pHandle = kmalloc(sz, GFP_KERNEL);
618 if(pHandle == NULL) {
619 ret = OSSERR_OUT_OF_MEMORY;
620 goto failure;
621 }
622 memset(pHandle, 0, sizeof(mixerhandle));
623
624 //set operation to non-blocking
625 pHandle->file.f_flags = O_NONBLOCK;
626
627 //setup pointers in file structure (used internally by ALSA)
628 pHandle->file.f_dentry = &pHandle->d_entry;
629 pHandle->file.f_dentry->d_inode = &pHandle->inode;
630
631 pHandle->file.f_mode = FMODE_WRITE;
632 pHandle->inode.i_rdev = SNDRV_MINOR(deviceid, SNDRV_MINOR_CONTROL);
633
634 ret = alsa_fops->open(&pHandle->inode, &pHandle->file);
635 if(ret) {
636 goto failure;
637 }
638 //retrieve mixer information
639 ret = pHandle->file.f_op->unlocked_ioctl(&pHandle->file,
640 SNDRV_CTL_IOCTL_CARD_INFO,
641 (ULONG)&pHandle->info);
642 if(ret) {
643 ret = pHandle->file.f_op->release(&pHandle->inode, &pHandle->file);
644 goto failure;
645 }
646 //get the number of mixer elements
647 pHandle->list.offset = 0;
648 pHandle->list.space = 0;
649 ret = pHandle->file.f_op->unlocked_ioctl(&pHandle->file,
650 SNDRV_CTL_IOCTL_ELEM_LIST,
651 (ULONG)&pHandle->list);
652 if(ret) {
653 ret = pHandle->file.f_op->release(&pHandle->inode, &pHandle->file);
654 goto failure;
655 }
656 ret = pHandle->file.f_op->release(&pHandle->inode, &pHandle->file);
657 if(pHandle) {
658 if(pHandle->pids) kfree(pHandle->pids);
659 kfree(pHandle);
660 }
661 return pHandle->list.count;
662failure:
663 if(pHandle) {
664 if(pHandle->pids) kfree(pHandle->pids);
665 kfree(pHandle);
666 }
667 DebugInt3();
668 return OSSERR_OUT_OF_MEMORY;
669}
670
671int GetUniaudControls(ULONG deviceid, void *pids)
672{
673 mixerhandle *pHandle = NULL;
674 int ret, sz;
675 //int i, j;
676
677 //dprintf(("GetUniaudControls"));
678
679 if(alsa_fops == NULL) {
680 ret = OSSERR_NO_DEVICE_AVAILABLE;
681 goto failure;
682 }
683
684 sz = sizeof(mixerhandle);
685 pHandle = kmalloc(sz, GFP_KERNEL);
686 if(pHandle == NULL) {
687 ret = OSSERR_OUT_OF_MEMORY;
688 goto failure;
689 }
690 memset(pHandle, 0, sizeof(mixerhandle));
691
692 //set operation to non-blocking
693 pHandle->file.f_flags = O_NONBLOCK;
694
695 //setup pointers in file structure (used internally by ALSA)
696 pHandle->file.f_dentry = &pHandle->d_entry;
697 pHandle->file.f_dentry->d_inode = &pHandle->inode;
698
699 pHandle->file.f_mode = FMODE_WRITE;
700 pHandle->inode.i_rdev = SNDRV_MINOR(deviceid, SNDRV_MINOR_CONTROL);
701
702 ret = alsa_fops->open(&pHandle->inode, &pHandle->file);
703 if(ret) {
704 goto failure;
705 }
706 //retrieve mixer information
707 ret = pHandle->file.f_op->unlocked_ioctl(&pHandle->file,
708 SNDRV_CTL_IOCTL_CARD_INFO,
709 (ULONG)&pHandle->info);
710 if(ret) {
711 ret = pHandle->file.f_op->release(&pHandle->inode, &pHandle->file);
712 goto failure;
713 }
714 //get the number of mixer elements
715 pHandle->list.offset = 0;
716 pHandle->list.space = 0;
717 ret = pHandle->file.f_op->unlocked_ioctl(&pHandle->file,
718 SNDRV_CTL_IOCTL_ELEM_LIST,
719 (ULONG)&pHandle->list);
720 if(ret) {
721 ret = pHandle->file.f_op->release(&pHandle->inode, &pHandle->file);
722 goto failure;
723 }
724
725 //allocate memory for all mixer elements
726 pHandle->pids = (struct snd_ctl_elem_id *)pids;
727 //kmalloc(sizeof(struct snd_ctl_elem_id)*pHandle->list.count, GFP_KERNEL);
728 if(pHandle->pids == NULL) {
729 ret = pHandle->file.f_op->release(&pHandle->inode, &pHandle->file);
730 goto failure;
731 }
732 //and retrieve all mixer elements
733 pHandle->list.offset = 0;
734 pHandle->list.space = pHandle->list.count;
735 pHandle->list.pids = pHandle->pids;
736 ret = pHandle->file.f_op->unlocked_ioctl(&pHandle->file,
737 SNDRV_CTL_IOCTL_ELEM_LIST,
738 (ULONG)&pHandle->list);
739 if(ret) {
740 ret = pHandle->file.f_op->release(&pHandle->inode, &pHandle->file);
741 goto failure;
742 }
743// if (pids)
744// memcpy(pids, pHandle->pids,
745// sizeof(struct snd_ctl_elem_id)*pHandle->list.count);
746
747 ret = pHandle->file.f_op->release(&pHandle->inode, &pHandle->file);
748 if(pHandle) {
749// if(pHandle->pids) kfree(pHandle->pids);
750 kfree(pHandle);
751 }
752 return pHandle->list.count;
753failure:
754 if(pHandle) {
755// if(pHandle->pids) kfree(pHandle->pids);
756 kfree(pHandle);
757 }
758 DebugInt3();
759 return OSSERR_OUT_OF_MEMORY;
760}
761
762int GetUniaudControlInfo(ULONG deviceid, ULONG id, void *info)
763{
764 //struct snd_ctl_elem_value *pElem = NULL;
765 struct snd_ctl_elem_info *pElemInfo = NULL;
766 mixerhandle *pHandle = NULL;
767 int ret, sz;
768 //int i, j;
769
770 //dprintf(("GetUniaudControlInfo"));
771
772 if(alsa_fops == NULL) {
773 ret = OSSERR_NO_DEVICE_AVAILABLE;
774 goto failure;
775 }
776
777 sz = sizeof(mixerhandle);
778 pHandle = kmalloc(sz, GFP_KERNEL);
779 if(pHandle == NULL) {
780 ret = OSSERR_OUT_OF_MEMORY;
781 goto failure;
782 }
783 memset(pHandle, 0, sizeof(mixerhandle));
784
785 //set operation to non-blocking
786 pHandle->file.f_flags = O_NONBLOCK;
787
788 //setup pointers in file structure (used internally by ALSA)
789 pHandle->file.f_dentry = &pHandle->d_entry;
790 pHandle->file.f_dentry->d_inode = &pHandle->inode;
791
792 pHandle->file.f_mode = FMODE_WRITE;
793 pHandle->inode.i_rdev = SNDRV_MINOR(deviceid, SNDRV_MINOR_CONTROL);
794
795 ret = alsa_fops->open(&pHandle->inode, &pHandle->file);
796 if(ret) {
797 goto failure;
798 }
799
800 //allocate memory for info element
801 pElemInfo = (struct snd_ctl_elem_info *)info;
802 if(pElemInfo == NULL) {
803 ret = pHandle->file.f_op->release(&pHandle->inode, &pHandle->file);
804 goto failure;
805 }
806
807// printk("sizeof elem_info %i\n",sizeof(struct snd_ctl_elem_info));
808
809 pElemInfo->id.numid = id;
810 ret = pHandle->file.f_op->unlocked_ioctl(&pHandle->file, SNDRV_CTL_IOCTL_ELEM_INFO, (ULONG)pElemInfo);
811 ret = pHandle->file.f_op->release(&pHandle->inode, &pHandle->file);
812 if(pHandle) kfree(pHandle);
813// printk("elem type: %i, id: %i, card: %i\n", pElemInfo->type, pElemInfo->id.numid, deviceid);
814 return OSSERR_SUCCESS;
815
816failure:
817 if(pHandle) {
818 kfree(pHandle);
819 }
820 DebugInt3();
821 return OSSERR_OUT_OF_MEMORY;
822}
823
824int GetUniaudControlValueGet(ULONG deviceid, ULONG id, void *value)
825{
826 struct snd_ctl_elem_value *pElem = NULL;
827 //struct snd_ctl_elem_info *pElemInfo = NULL;
828 mixerhandle *pHandle = NULL;
829 int ret, sz;
830 //int i, j;
831
832 if(alsa_fops == NULL) {
833 ret = OSSERR_NO_DEVICE_AVAILABLE;
834 goto failure;
835 }
836
837 sz = sizeof(mixerhandle);
838 pHandle = kmalloc(sz, GFP_KERNEL);
839 if(pHandle == NULL) {
840 ret = OSSERR_OUT_OF_MEMORY;
841 goto failure;
842 }
843 memset(pHandle, 0, sizeof(mixerhandle));
844
845 //set operation to non-blocking
846 pHandle->file.f_flags = O_NONBLOCK;
847
848 //setup pointers in file structure (used internally by ALSA)
849 pHandle->file.f_dentry = &pHandle->d_entry;
850 pHandle->file.f_dentry->d_inode = &pHandle->inode;
851
852 pHandle->file.f_mode = FMODE_WRITE;
853 pHandle->inode.i_rdev = SNDRV_MINOR(deviceid, SNDRV_MINOR_CONTROL);
854
855 ret = alsa_fops->open(&pHandle->inode, &pHandle->file);
856 if(ret) {
857 goto failure;
858 }
859
860 pElem = (struct snd_ctl_elem_value *)value;
861 if(pElem == NULL) {
862 ret = pHandle->file.f_op->release(&pHandle->inode, &pHandle->file);
863 goto failure;
864 }
865
866 pElem->id.numid = id;
867 pElem->indirect = 0;
868 ret = pHandle->file.f_op->unlocked_ioctl(&pHandle->file, SNDRV_CTL_IOCTL_ELEM_READ, (ULONG)pElem);
869 ret = pHandle->file.f_op->release(&pHandle->inode, &pHandle->file);
870 if(pHandle) kfree(pHandle);
871
872 //dprintf(("GetUniaudControlValueGet: id=%x 0=%x 1=%x", pElem->id.numid, pElem->value.integer.value[0], pElem->value.integer.value[1]));
873
874 return OSSERR_SUCCESS;
875failure:
876 if(pHandle) {
877 kfree(pHandle);
878 }
879 DebugInt3();
880 return OSSERR_OUT_OF_MEMORY;
881}
882
883int GetUniaudControlValuePut(ULONG deviceid, ULONG id, void *value)
884{
885 struct snd_ctl_elem_value *pElem = NULL;
886 //struct snd_ctl_elem_info *pElemInfo = NULL;
887 mixerhandle *pHandle = NULL;
888 int ret, sz;
889 //int i, j;
890
891 if(alsa_fops == NULL) {
892 ret = OSSERR_NO_DEVICE_AVAILABLE;
893 goto failure;
894 }
895
896 sz = sizeof(mixerhandle);
897 pHandle = kmalloc(sz, GFP_KERNEL);
898 if(pHandle == NULL) {
899 ret = OSSERR_OUT_OF_MEMORY;
900 goto failure;
901 }
902 memset(pHandle, 0, sizeof(mixerhandle));
903
904 //set operation to non-blocking
905 pHandle->file.f_flags = O_NONBLOCK;
906
907 //setup pointers in file structure (used internally by ALSA)
908 pHandle->file.f_dentry = &pHandle->d_entry;
909 pHandle->file.f_dentry->d_inode = &pHandle->inode;
910
911 pHandle->file.f_mode = FMODE_WRITE;
912 pHandle->inode.i_rdev = SNDRV_MINOR(deviceid, SNDRV_MINOR_CONTROL);
913
914 ret = alsa_fops->open(&pHandle->inode, &pHandle->file);
915 if(ret) {
916 goto failure;
917 }
918
919 pElem = (struct snd_ctl_elem_value *)value;
920 if(pElem == NULL) {
921 ret = pHandle->file.f_op->release(&pHandle->inode, &pHandle->file);
922 goto failure;
923 }
924
925 pElem->id.numid = id;
926 pElem->indirect = 0;
927
928 ret = pHandle->file.f_op->unlocked_ioctl(&pHandle->file, SNDRV_CTL_IOCTL_ELEM_WRITE, (ULONG)pElem);
929 ret = pHandle->file.f_op->release(&pHandle->inode, &pHandle->file);
930 if(pHandle) kfree(pHandle);
931
932 return OSSERR_SUCCESS;
933
934failure:
935 if(pHandle) {
936 kfree(pHandle);
937 }
938 DebugInt3();
939 return OSSERR_OUT_OF_MEMORY;
940}
941
942int UniaudIoctlHWRefine(OSSSTREAMID streamid, void *pHwParams)
943{
944 int ret;
945 soundhandle *pHandle = (soundhandle *)streamid;
946 struct snd_pcm_hw_params *params = NULL;
947 params = (struct snd_pcm_hw_params *)pHwParams;
948
949 //dprintf(("UniaudIoctlHWRefine"));
950
951 if (!params) return -1001;
952
953 if (!pHandle) return -1002;
954
955 pHandle->file.f_flags = O_NONBLOCK;
956 ret = pHandle->file.f_op->unlocked_ioctl(&pHandle->file, SNDRV_PCM_IOCTL_HW_REFINE, (ULONG)params);
957 return ret;
958}
959
960int UniaudIoctlHWParamSet(OSSSTREAMID streamid, void *pHwParams)
961{
962 int ret;
963 soundhandle *pHandle = (soundhandle *)streamid;
964 struct snd_pcm_hw_params *params = NULL;
965 params = (struct snd_pcm_hw_params *)pHwParams;
966
967 //dprintf(("UniaudIoctlHWParamSet"));
968
969 if (!params) return -1001;
970 if (!pHandle) return -1002;
971
972 pHandle->file.f_flags = O_NONBLOCK;
973 ret = pHandle->file.f_op->unlocked_ioctl(&pHandle->file, SNDRV_PCM_IOCTL_HW_PARAMS, (ULONG)params);
974 return ret;
975}
976
977int UniaudIoctlSWParamSet(OSSSTREAMID streamid, void *pSwParams)
978{
979 int ret;
980 soundhandle *pHandle = (soundhandle *)streamid;
981 struct snd_pcm_sw_params *params = NULL;
982
983 params = (struct snd_pcm_sw_params *)pSwParams;
984
985 //dprintf(("UniaudIoctlSWParamSet"));
986
987 if (!params) return -1001;
988 if (!pHandle) return -1002;
989
990 pHandle->file.f_flags = O_NONBLOCK;
991
992 ret = pHandle->file.f_op->unlocked_ioctl(&pHandle->file, SNDRV_PCM_IOCTL_SW_PARAMS, (ULONG)params);
993 return ret;
994}
995
996int UniaudIoctlPCMStatus(OSSSTREAMID streamid, void *pstatus)
997{
998 int ret;
999 soundhandle *pHandle = (soundhandle *)streamid;
1000 struct snd_pcm_status *status = (struct snd_pcm_status *)pstatus;
1001
1002 //dprintf(("UniaudIoctlPCMStatus"));
1003
1004 if (!status) return -1001;
1005 if (!pHandle) return -1002;
1006
1007 pHandle->file.f_flags = O_NONBLOCK;
1008
1009 ret = pHandle->file.f_op->unlocked_ioctl(&pHandle->file, SNDRV_PCM_IOCTL_STATUS, (ULONG)status);
1010 return ret;
1011}
1012
1013int UniaudIoctlPCMWrite(OSSSTREAMID streamid, char *buf, int size)
1014{
1015 int ret;
1016 soundhandle *pHandle = (soundhandle *)streamid;
1017
1018 //dprintf(("UniaudIoctlPCMWrite"));
1019
1020 if (!buf) return -1001;
1021 if (!pHandle) return -1002;
1022
1023 pHandle->file.f_flags = O_NONBLOCK;
1024
1025 ret = pHandle->file.f_op->write(&pHandle->file, buf, size, &pHandle->file.f_pos);
1026
1027 return ret;
1028}
1029
1030int UniaudIoctlPCMRead(OSSSTREAMID streamid, char *buf, int size)
1031{
1032 int ret;
1033 soundhandle *pHandle = (soundhandle *)streamid;
1034
1035 if (!buf) return -1001;
1036 if (!pHandle) return -1002;
1037
1038 //dprintf(("UniaudIoctlPCMRead"));
1039
1040 pHandle->file.f_flags = O_NONBLOCK;
1041
1042 ret = pHandle->file.f_op->read(&pHandle->file, buf, size, &pHandle->file.f_pos);
1043
1044 return ret;
1045}
1046
1047int UniaudIoctlPCMPrepare(OSSSTREAMID streamid)
1048{
1049 int ret;
1050 soundhandle *pHandle = (soundhandle *)streamid;
1051
1052 //dprintf(("UniaudIoctlPCMPrepare"));
1053
1054 if (!pHandle) return -1002;
1055
1056 pHandle->file.f_flags = O_NONBLOCK;
1057
1058 ret = pHandle->file.f_op->unlocked_ioctl(&pHandle->file, SNDRV_PCM_IOCTL_PREPARE, 0);
1059 return ret;
1060}
1061
1062int UniaudIoctlPCMResume(OSSSTREAMID streamid, int pause)
1063{
1064 int ret;
1065 soundhandle *pHandle = (soundhandle *)streamid;
1066
1067 //dprintf(("UniaudIoctlPCMResume: %x", pause));
1068
1069 if (!pHandle) return -1002;
1070
1071 pHandle->file.f_flags = O_NONBLOCK;
1072
1073 ret = pHandle->file.f_op->unlocked_ioctl(&pHandle->file, SNDRV_PCM_IOCTL_PAUSE, pause);
1074
1075 return ret;
1076}
1077
1078int UniaudIoctlPCMStart(OSSSTREAMID streamid)
1079{
1080 int ret;
1081 soundhandle *pHandle = (soundhandle *)streamid;
1082
1083 //dprintf(("UniaudIoctlPCMStart"));
1084
1085 if (!pHandle) return -1002;
1086
1087 pHandle->file.f_flags = O_NONBLOCK;
1088
1089 ret = pHandle->file.f_op->unlocked_ioctl(&pHandle->file, SNDRV_PCM_IOCTL_START, 0);
1090
1091 return ret;
1092}
1093
1094int UniaudIoctlPCMDrop(OSSSTREAMID streamid)
1095{
1096 int ret;
1097 soundhandle *pHandle = (soundhandle *)streamid;
1098
1099 //dprintf(("UniaudIoctlPCMDrop"));
1100
1101 if (!pHandle) return -1002;
1102
1103 pHandle->file.f_flags = O_NONBLOCK;
1104
1105 ret = pHandle->file.f_op->unlocked_ioctl(&pHandle->file, SNDRV_PCM_IOCTL_DROP, 0);
1106
1107 return ret;
1108}
1109
1110void UniaudCloseAll(USHORT fileid)
1111{
1112 int i;
1113
1114 for (i=0; i < 8*256; i++)
1115 {
1116 if (opened_handles[i].handle != 0)
1117 {
1118 if (fileid)
1119 {
1120 if (fileid == opened_handles[i].FileId)
1121 {
1122 opened_handles[i].reuse = 0;
1123 if (OSS32_WaveClose((OSSSTREAMID)opened_handles[i].handle) == 0)
1124 opened_handles[i].handle = 0;
1125 }
1126 }
1127 else
1128 {
1129 opened_handles[i].reuse = 0;
1130 if (OSS32_WaveClose((OSSSTREAMID)opened_handles[i].handle) == 0)
1131 opened_handles[i].handle = 0;
1132 }
1133 }
1134 }
1135 return;
1136}
Note: See TracBrowser for help on using the repository browser.