source: GPL/lib32/ioctl.c@ 18

Last change on this file since 18 was 18, checked in by vladest, 20 years ago

initial import

File size: 29.7 KB
Line 
1/*
2
3 IOCTL funcs
4 Written by Vlad Stelmahovsky with help from Stepan Kazakov
5
6 */
7
8#include <sound/driver.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 */
31snd_pcm_substream_t *substream_int[8*256] = {0}; // interrupted substream
32int control_id_changed = 0;
33int card_id_changed = 0;
34int unlock_all = 0;
35int GetUniaudPcmCaps(ULONG deviceid, void *caps);
36void FillCaps(ULONG deviceid);
37int pcm_instances(int card_id);
38
39int WaitForControlChange(int card_id, int timeout)
40{
41 int ctl_id;
42 ULONG blkid = 0;
43 int i = 0;
44
45 while (1)
46 {
47 if (control_id_changed != 0 && card_id_changed == card_id)
48 {
49 ctl_id = control_id_changed;
50 control_id_changed = 0;
51 break;
52 }
53 i++;
54
55 if (i > timeout)
56 return -ETIME;
57
58 MyDevBlock(blkid, 1, 0);
59 if (unlock_all)
60 {
61 unlock_all = 0;
62 break;
63 }
64 }
65 return ctl_id;
66}
67
68int WaitForPCMInterrupt(void *handle, int timeout)
69{
70 ULONG blkid = 0;
71 int i = 0;
72 int j = 0;
73 snd_pcm_file_t *pcm_file = NULL;
74 snd_pcm_substream_t *substream;
75 snd_pcm_runtime_t *runtime;
76 soundhandle *pHandle = (soundhandle *)handle;
77 struct file *pfile;
78
79 if (handle == NULL)
80 return -ENXIO;
81
82 pfile = &pHandle->file;
83
84 if (pfile == NULL)
85 return -ENXIO;
86
87 pcm_file = (snd_pcm_file_t *)pfile->private_data;
88
89 if (pcm_file == NULL)
90 return -ENXIO;
91
92 substream = pcm_file->substream;
93
94 if (substream == NULL)
95 return -ENXIO;
96
97 runtime = substream->runtime;
98
99 if ((pfile->f_mode == FMODE_WRITE) &&
100 (runtime->status->state != SNDRV_PCM_STATE_RUNNING))
101 return -EBADFD;
102
103 //printk("wait for %x. tout %i\n",substream, timeout);
104
105 while (1)
106 {
107 for (i=0; i < 8*256; i++)
108 {
109 if (substream_int[i] == substream)
110 {
111// printk("found %x at %i\n",substream_int[i], i);
112 substream_int[i] = 0;
113 //printk("j =%i\n",j);
114 return j; /* milliseconds */
115 }
116 }
117
118 if (j++ > timeout)
119 {
120 printk("j with tout =%i\n",j);
121 return -ETIME;
122 }
123
124 MyDevBlock(blkid, 1, 0);
125 if (unlock_all)
126 {
127 unlock_all = 0;
128 break;
129 }
130 }
131 //printk("j at exit =%i\n",j);
132 return j;
133}
134
135/*
136 returns number of registered cards
137 */
138int GetNumberOfCards(void)
139{
140 return nrCardsDetected;
141}
142
143/*
144 returns number of registered pcm instances
145 */
146int GetNumberOfPcm(int card_id)
147{
148 return pcm_instances(card_id);
149}
150
151int SetPCMInstance(int card_id, int pcm)
152{
153 if (pcm>=0 && pcm <= pcm_instances(card_id))
154 {
155 pcm_device = pcm;
156 return pcm;
157 } else
158 return pcm_device;
159}
160
161int GetPcmForChannels(ULONG deviceid, int type, int channels)
162{
163 POSS32_DEVCAPS pcaps = NULL;
164 WAVE_CAPS *wc;
165 int i;
166 int sel_pcm = -1;
167
168 if (!pcmcaps[deviceid])
169 {
170 FillCaps(deviceid);
171 if (!pcmcaps[deviceid])
172 {
173 printk("Error querying caps for device: %i\n", deviceid);
174 return -1;
175 }
176 }
177
178 pcaps = pcmcaps[deviceid];
179
180 for (i=0; i<pcm_instances(deviceid);i++)
181 {
182 switch(type)
183 {
184 case OSS32_CAPS_WAVE_PLAYBACK: // play
185 wc = &pcaps->waveOutCaps;
186 break;
187 case OSS32_CAPS_WAVE_CAPTURE: // record
188 wc = &pcaps->waveInCaps;
189 break;
190 }
191 if (wc->ulMaxChannels == channels)
192 {
193 sel_pcm = i;
194 break;
195 }
196 pcaps++;
197 }
198
199 return sel_pcm;
200}
201
202int GetMaxChannels(ULONG deviceid, int type)
203{
204 POSS32_DEVCAPS pcaps = NULL;
205 WAVE_CAPS *wc;
206 int i;
207 int sel_pcm = -1;
208 int max_ch = 0;
209
210 if (!pcmcaps[deviceid])
211 {
212 FillCaps(deviceid);
213 if (!pcmcaps[deviceid])
214 {
215 printk("Error querying caps for device: %i\n", deviceid);
216 return -1;
217 }
218 }
219
220 pcaps = pcmcaps[deviceid];
221
222 for (i=0; i<pcm_instances(deviceid);i++)
223 {
224 switch(type)
225 {
226 case OSS32_CAPS_WAVE_PLAYBACK: // play
227 wc = &pcaps->waveOutCaps;
228 break;
229 case OSS32_CAPS_WAVE_CAPTURE: // record
230 wc = &pcaps->waveInCaps;
231 break;
232 }
233 if (wc->ulMaxChannels > max_ch)
234 max_ch = wc->ulMaxChannels;
235 pcaps++;
236 }
237 return max_ch;
238}
239
240void FillCaps(ULONG deviceid)
241{
242 int pcms = 0;
243
244 pcms = pcm_instances(deviceid);
245
246// printk("pcms = %i\n", pcms);
247 if (!pcmcaps[deviceid])
248 {
249 pcmcaps[deviceid] = (POSS32_DEVCAPS)kmalloc(sizeof(OSS32_DEVCAPS)*pcms, GFP_KERNEL);
250 if (pcmcaps[deviceid])
251 {
252 memset(pcmcaps[deviceid], 0, sizeof(OSS32_DEVCAPS)*pcms);
253 GetUniaudPcmCaps1(deviceid, (void *)pcmcaps[deviceid]);
254 }
255 }
256 return;
257}
258
259int GetUniaudPcmCaps(ULONG deviceid, void *caps)
260{
261 int pcms = 0;
262
263 pcms = pcm_instances(deviceid);
264
265// printk("pcms = %i\n", pcms);
266 if (pcmcaps[deviceid])
267 {
268 memcpy((unsigned char*)caps,(unsigned char*)pcmcaps[deviceid],sizeof(OSS32_DEVCAPS)*pcms);
269 return 0;
270 }
271 else
272 {
273 return -1;
274 }
275}
276
277/*
278 returns pcm caps
279 */
280int GetUniaudPcmCaps1(ULONG deviceid, void *caps)
281{
282 POSS32_DEVCAPS pcaps = (POSS32_DEVCAPS)caps;
283 int i;
284 OSSSTREAMID streamid = 0;
285 soundhandle *pHandle;
286 snd_pcm_info_t *pcminfo = NULL;
287 snd_pcm_hw_params_t *params;
288 int ret, fmt, j;
289 ULONG format_mask;
290 snd_mask_t *mask;
291 int pcms = 0;
292
293 pcms = pcm_instances(deviceid);
294
295 if (!pcaps || !pcms) return -1;
296
297
298 //these structures are too big to put on the stack
299 pcminfo = (snd_pcm_info_t *)kmalloc(sizeof(snd_pcm_info_t)+sizeof(snd_pcm_hw_params_t), GFP_KERNEL);
300 if(pcminfo == NULL) {
301 DebugInt3();
302 printk("GetUniaudPcmCaps: out of memory\n");
303 return OSSERR_OUT_OF_MEMORY;
304 }
305 params = (snd_pcm_hw_params_t *)(pcminfo+1);
306
307 for (i=0; i<pcms;i++)
308 {
309 pcaps->nrDevices = nrCardsDetected;
310 pcaps->ulCaps = OSS32_CAPS_WAVE_PLAYBACK | OSS32_CAPS_WAVE_CAPTURE;
311
312 //query wave in & out caps
313 for(j=0;j<2;j++)
314 {
315 PWAVE_CAPS pWaveCaps = (j == 0) ? &pcaps->waveOutCaps : &pcaps->waveInCaps;
316
317 ret = OSS32_WaveOpen(deviceid, (j == 0) ? OSS32_STREAM_WAVEOUT : OSS32_STREAM_WAVEIN, &streamid, i, 0);
318 if(ret != OSSERR_SUCCESS)
319 {
320 printk("GetUniaudPcmCaps: wave open error %i %s at pcm %i\n", ret,
321 (j == 0) ?"PLAY":"REC", i);
322 continue;
323// goto fail;
324 }
325 pHandle = (soundhandle *)streamid;
326 if(pHandle == NULL || pHandle->magic != MAGIC_WAVE_ALSA32) {
327 printk("GetUniaudPcmCaps: invalid stream id \n");
328 ret = OSSERR_INVALID_STREAMID;
329// goto fail;
330 }
331
332 //set operation to non-blocking
333 pHandle->file.f_flags = O_NONBLOCK;
334
335 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_PCM_IOCTL_INFO, (ULONG)pcminfo);
336 if(ret != 0) {
337 printk("GetUniaudPcmCaps: SNDRV_PCM_IOCTL_INFO error %i\n", ret);
338 ret = UNIXToOSSError(ret);
339 continue;
340 }
341 if(pcminfo->name[0]) {
342 strncpy(pcaps->szDeviceName, pcminfo->name, sizeof(pcaps->szDeviceName));
343 }
344 else strncpy(pcaps->szDeviceName, pcminfo->id, sizeof(pcaps->szDeviceName));
345
346 if(pcminfo->subname[0]) {
347 strncpy(pcaps->szMixerName, pcminfo->subname, sizeof(pcaps->szMixerName));
348 }
349
350 pWaveCaps->nrStreams = pcminfo->subdevices_count;
351
352 //get all hardware parameters
353 _snd_pcm_hw_params_any(params);
354 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_PCM_IOCTL_HW_REFINE, (ULONG)params);
355 if(ret != 0) {
356 printk("GetUniaudPcmCaps: SNDRV_PCM_IOCTL_HW_REFINE error %i\n", ret);
357 ret = UNIXToOSSError(ret);
358 //goto fail;
359 continue;
360 }
361
362 pWaveCaps->ulMinChannels = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS)->min;
363 pWaveCaps->ulMaxChannels = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS)->max;
364 printk("chan: from %i to %i\n", pWaveCaps->ulMinChannels,pWaveCaps->ulMaxChannels);
365 pWaveCaps->ulChanFlags = 0;
366 if(pWaveCaps->ulMinChannels == 1) {
367 pWaveCaps->ulChanFlags |= OSS32_CAPS_PCM_CHAN_MONO;
368 }
369 if(pWaveCaps->ulMaxChannels >= 2) {
370 pWaveCaps->ulChanFlags |= OSS32_CAPS_PCM_CHAN_STEREO;
371 }
372 if(pWaveCaps->ulMaxChannels >= 4) {
373 pWaveCaps->ulChanFlags |= OSS32_CAPS_PCM_CHAN_QUAD;
374 }
375 if(pWaveCaps->ulMaxChannels >= 6) {
376 pWaveCaps->ulChanFlags |= OSS32_CAPS_PCM_CHAN_5_1;
377 }
378
379 pWaveCaps->ulMinRate = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE)->min;
380 pWaveCaps->ulMaxRate = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE)->max;
381
382 mask = hw_param_mask(params, SNDRV_PCM_HW_PARAM_RATE_MASK);
383 pWaveCaps->ulRateFlags = mask->bits[0];
384
385 pWaveCaps->ulRateFlags = ALSAToOSSRateFlags(pWaveCaps->ulRateFlags);
386
387 pWaveCaps->ulDataFormats = 0;
388
389 mask = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
390 format_mask = mask->bits[0];
391 for(fmt=0;fmt<32;fmt++)
392 {
393 if(format_mask & (1 << fmt))
394 {
395 int f = ALSAToOSSDataType(fmt);
396 if (f >= 0)
397 pWaveCaps->ulDataFormats |= f;
398 }
399 }
400
401 OSS32_WaveClose(streamid);
402 streamid = 0;
403 } // for j
404 pcaps++; // next pcm
405 } // for i
406
407 if (pcminfo) kfree(pcminfo);
408 return OSSERR_SUCCESS;
409}
410
411/*
412 returns power state of given card
413 */
414int UniaudCtlGetPowerState(ULONG deviceid, void *state)
415{
416 mixerhandle *pHandle = NULL;
417 int ret, i, j;
418
419 if(alsa_fops == NULL) {
420 ret = OSSERR_NO_DEVICE_AVAILABLE;
421 goto failure;
422 }
423
424 pHandle = kmalloc(sizeof(mixerhandle), GFP_KERNEL);
425 if(pHandle == NULL) {
426 ret = OSSERR_OUT_OF_MEMORY;
427 goto failure;
428 }
429 memset(pHandle, 0, sizeof(mixerhandle));
430
431 //set operation to non-blocking
432 pHandle->file.f_flags = O_NONBLOCK;
433
434 //setup pointers in file structure (used internally by ALSA)
435 pHandle->file.f_dentry = &pHandle->d_entry;
436 pHandle->file.f_dentry->d_inode = &pHandle->inode;
437
438 pHandle->file.f_mode = FMODE_WRITE;
439 pHandle->inode.i_rdev = SNDRV_MINOR(deviceid, SNDRV_MINOR_CONTROL);
440
441 ret = alsa_fops->open(&pHandle->inode, &pHandle->file);
442 if(ret) {
443 goto failure;
444 }
445 //retrieve mixer information
446 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file,
447 SNDRV_CTL_IOCTL_POWER_STATE,
448 (ULONG)state);
449
450 pHandle->file.f_op->release(&pHandle->inode, &pHandle->file);
451
452 kfree(pHandle);
453
454 if(ret) {
455 goto failure;
456 }
457
458 return OSSERR_SUCCESS;
459failure:
460 DebugInt3();
461 return ret;
462}
463
464/*
465 sets power state for given card
466 */
467int UniaudCtlSetPowerState(ULONG deviceid, void *state)
468{
469 mixerhandle *pHandle = NULL;
470 int ret, i, j;
471
472 if(alsa_fops == NULL) {
473 ret = OSSERR_NO_DEVICE_AVAILABLE;
474 goto failure;
475 }
476
477 pHandle = kmalloc(sizeof(mixerhandle), GFP_KERNEL);
478 if(pHandle == NULL) {
479 ret = OSSERR_OUT_OF_MEMORY;
480 goto failure;
481 }
482 memset(pHandle, 0, sizeof(mixerhandle));
483
484 //set operation to non-blocking
485 pHandle->file.f_flags = O_NONBLOCK;
486
487 //setup pointers in file structure (used internally by ALSA)
488 pHandle->file.f_dentry = &pHandle->d_entry;
489 pHandle->file.f_dentry->d_inode = &pHandle->inode;
490
491 pHandle->file.f_mode = FMODE_WRITE;
492 pHandle->inode.i_rdev = SNDRV_MINOR(deviceid, SNDRV_MINOR_CONTROL);
493
494 ret = alsa_fops->open(&pHandle->inode, &pHandle->file);
495 if(ret) {
496 goto failure;
497 }
498 //retrieve mixer information
499 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file,
500 SNDRV_CTL_IOCTL_POWER,
501 (ULONG)state);
502
503 pHandle->file.f_op->release(&pHandle->inode, &pHandle->file);
504
505 kfree(pHandle);
506
507 if(ret) {
508 goto failure;
509 }
510
511 return OSSERR_SUCCESS;
512failure:
513 DebugInt3();
514 return ret;
515}
516
517/*
518 returns card info
519 */
520int GetUniaudCardInfo(ULONG deviceid, void *info)
521{
522 mixerhandle *pHandle = NULL;
523 int ret, i, j;
524// snd_ctl_card_info_t *pinfo;
525
526 if(alsa_fops == NULL) {
527 ret = OSSERR_NO_DEVICE_AVAILABLE;
528 goto failure;
529 }
530
531 pHandle = kmalloc(sizeof(mixerhandle), GFP_KERNEL);
532 if(pHandle == NULL) {
533 ret = OSSERR_OUT_OF_MEMORY;
534 goto failure;
535 }
536 memset(pHandle, 0, sizeof(mixerhandle));
537
538 //set operation to non-blocking
539 pHandle->file.f_flags = O_NONBLOCK;
540
541 //setup pointers in file structure (used internally by ALSA)
542 pHandle->file.f_dentry = &pHandle->d_entry;
543 pHandle->file.f_dentry->d_inode = &pHandle->inode;
544
545 pHandle->file.f_mode = FMODE_WRITE;
546 pHandle->inode.i_rdev = SNDRV_MINOR(deviceid, SNDRV_MINOR_CONTROL);
547
548 ret = alsa_fops->open(&pHandle->inode, &pHandle->file);
549 if(ret) {
550 goto failure;
551 }
552 //retrieve mixer information
553 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file,
554 SNDRV_CTL_IOCTL_CARD_INFO,
555 (ULONG)(snd_ctl_card_info_t *)info);
556 if(ret) {
557 ret = pHandle->file.f_op->release(&pHandle->inode, &pHandle->file);
558 goto failure;
559 }
560 ret = pHandle->file.f_op->release(&pHandle->inode, &pHandle->file);
561
562 if(pHandle) {
563 kfree(pHandle);
564 }
565 return OSSERR_SUCCESS;
566failure:
567 if(pHandle) {
568 kfree(pHandle);
569 }
570 DebugInt3();
571 return OSSERR_OUT_OF_MEMORY;
572}
573
574int GetUniaudControlNum(ULONG deviceid)
575{
576 mixerhandle *pHandle = NULL;
577 int ret, i, j, sz;
578
579 if(alsa_fops == NULL) {
580 ret = OSSERR_NO_DEVICE_AVAILABLE;
581 goto failure;
582 }
583
584 sz = sizeof(mixerhandle);
585 pHandle = kmalloc(sz, GFP_KERNEL);
586 if(pHandle == NULL) {
587 ret = OSSERR_OUT_OF_MEMORY;
588 goto failure;
589 }
590 memset(pHandle, 0, sizeof(mixerhandle));
591
592 //set operation to non-blocking
593 pHandle->file.f_flags = O_NONBLOCK;
594
595 //setup pointers in file structure (used internally by ALSA)
596 pHandle->file.f_dentry = &pHandle->d_entry;
597 pHandle->file.f_dentry->d_inode = &pHandle->inode;
598
599 pHandle->file.f_mode = FMODE_WRITE;
600 pHandle->inode.i_rdev = SNDRV_MINOR(deviceid, SNDRV_MINOR_CONTROL);
601
602 ret = alsa_fops->open(&pHandle->inode, &pHandle->file);
603 if(ret) {
604 goto failure;
605 }
606 //retrieve mixer information
607 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file,
608 SNDRV_CTL_IOCTL_CARD_INFO,
609 (ULONG)&pHandle->info);
610 if(ret) {
611 ret = pHandle->file.f_op->release(&pHandle->inode, &pHandle->file);
612 goto failure;
613 }
614 //get the number of mixer elements
615 pHandle->list.offset = 0;
616 pHandle->list.space = 0;
617 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file,
618 SNDRV_CTL_IOCTL_ELEM_LIST,
619 (ULONG)&pHandle->list);
620 if(ret) {
621 ret = pHandle->file.f_op->release(&pHandle->inode, &pHandle->file);
622 goto failure;
623 }
624 ret = pHandle->file.f_op->release(&pHandle->inode, &pHandle->file);
625 if(pHandle) {
626 if(pHandle->pids) kfree(pHandle->pids);
627 kfree(pHandle);
628 }
629 return pHandle->list.count;
630failure:
631 if(pHandle) {
632 if(pHandle->pids) kfree(pHandle->pids);
633 kfree(pHandle);
634 }
635 DebugInt3();
636 return OSSERR_OUT_OF_MEMORY;
637}
638
639int GetUniaudControls(ULONG deviceid, void *pids)
640{
641 mixerhandle *pHandle = NULL;
642 int ret, i, j, sz;
643
644 if(alsa_fops == NULL) {
645 ret = OSSERR_NO_DEVICE_AVAILABLE;
646 goto failure;
647 }
648
649 sz = sizeof(mixerhandle);
650 pHandle = kmalloc(sz, GFP_KERNEL);
651 if(pHandle == NULL) {
652 ret = OSSERR_OUT_OF_MEMORY;
653 goto failure;
654 }
655 memset(pHandle, 0, sizeof(mixerhandle));
656
657 //set operation to non-blocking
658 pHandle->file.f_flags = O_NONBLOCK;
659
660 //setup pointers in file structure (used internally by ALSA)
661 pHandle->file.f_dentry = &pHandle->d_entry;
662 pHandle->file.f_dentry->d_inode = &pHandle->inode;
663
664 pHandle->file.f_mode = FMODE_WRITE;
665 pHandle->inode.i_rdev = SNDRV_MINOR(deviceid, SNDRV_MINOR_CONTROL);
666
667 ret = alsa_fops->open(&pHandle->inode, &pHandle->file);
668 if(ret) {
669 goto failure;
670 }
671 //retrieve mixer information
672 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file,
673 SNDRV_CTL_IOCTL_CARD_INFO,
674 (ULONG)&pHandle->info);
675 if(ret) {
676 ret = pHandle->file.f_op->release(&pHandle->inode, &pHandle->file);
677 goto failure;
678 }
679 //get the number of mixer elements
680 pHandle->list.offset = 0;
681 pHandle->list.space = 0;
682 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file,
683 SNDRV_CTL_IOCTL_ELEM_LIST,
684 (ULONG)&pHandle->list);
685 if(ret) {
686 ret = pHandle->file.f_op->release(&pHandle->inode, &pHandle->file);
687 goto failure;
688 }
689
690 //allocate memory for all mixer elements
691 pHandle->pids = (snd_ctl_elem_id_t *)pids;
692 //kmalloc(sizeof(snd_ctl_elem_id_t)*pHandle->list.count, GFP_KERNEL);
693 if(pHandle->pids == NULL) {
694 ret = pHandle->file.f_op->release(&pHandle->inode, &pHandle->file);
695 goto failure;
696 }
697 //and retrieve all mixer elements
698 pHandle->list.offset = 0;
699 pHandle->list.space = pHandle->list.count;
700 pHandle->list.pids = pHandle->pids;
701 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file,
702 SNDRV_CTL_IOCTL_ELEM_LIST,
703 (ULONG)&pHandle->list);
704 if(ret) {
705 ret = pHandle->file.f_op->release(&pHandle->inode, &pHandle->file);
706 goto failure;
707 }
708// if (pids)
709// memcpy(pids, pHandle->pids,
710// sizeof(snd_ctl_elem_id_t)*pHandle->list.count);
711
712 ret = pHandle->file.f_op->release(&pHandle->inode, &pHandle->file);
713 if(pHandle) {
714// if(pHandle->pids) kfree(pHandle->pids);
715 kfree(pHandle);
716 }
717 return pHandle->list.count;
718failure:
719 if(pHandle) {
720// if(pHandle->pids) kfree(pHandle->pids);
721 kfree(pHandle);
722 }
723 DebugInt3();
724 return OSSERR_OUT_OF_MEMORY;
725}
726
727int GetUniaudControlInfo(ULONG deviceid, ULONG id, void *info)
728{
729 snd_ctl_elem_value_t *pElem = NULL;
730 snd_ctl_elem_info_t *pElemInfo = NULL;
731 mixerhandle *pHandle = NULL;
732 int ret, i, j, sz;
733
734 if(alsa_fops == NULL) {
735 ret = OSSERR_NO_DEVICE_AVAILABLE;
736 goto failure;
737 }
738
739 sz = sizeof(mixerhandle);
740 pHandle = kmalloc(sz, GFP_KERNEL);
741 if(pHandle == NULL) {
742 ret = OSSERR_OUT_OF_MEMORY;
743 goto failure;
744 }
745 memset(pHandle, 0, sizeof(mixerhandle));
746
747 //set operation to non-blocking
748 pHandle->file.f_flags = O_NONBLOCK;
749
750 //setup pointers in file structure (used internally by ALSA)
751 pHandle->file.f_dentry = &pHandle->d_entry;
752 pHandle->file.f_dentry->d_inode = &pHandle->inode;
753
754 pHandle->file.f_mode = FMODE_WRITE;
755 pHandle->inode.i_rdev = SNDRV_MINOR(deviceid, SNDRV_MINOR_CONTROL);
756
757 ret = alsa_fops->open(&pHandle->inode, &pHandle->file);
758 if(ret) {
759 goto failure;
760 }
761
762 //allocate memory for info element
763 pElemInfo = (snd_ctl_elem_info_t *)info;
764 if(pElemInfo == NULL) {
765 ret = pHandle->file.f_op->release(&pHandle->inode, &pHandle->file);
766 goto failure;
767 }
768
769// printk("sizeof elem_info %i\n",sizeof(snd_ctl_elem_info_t));
770
771 pElemInfo->id.numid = id;
772 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_CTL_IOCTL_ELEM_INFO, (ULONG)pElemInfo);
773 ret = pHandle->file.f_op->release(&pHandle->inode, &pHandle->file);
774 if(pHandle) kfree(pHandle);
775// printk("elem type: %i, id: %i, card: %i\n", pElemInfo->type, pElemInfo->id.numid, deviceid);
776 return OSSERR_SUCCESS;
777
778failure:
779 if(pHandle) {
780 kfree(pHandle);
781 }
782 DebugInt3();
783 return OSSERR_OUT_OF_MEMORY;
784}
785
786int GetUniaudControlValueGet(ULONG deviceid, ULONG id, void *value)
787{
788 snd_ctl_elem_value_t *pElem = NULL;
789 snd_ctl_elem_info_t *pElemInfo = NULL;
790 mixerhandle *pHandle = NULL;
791 int ret, i, j, sz;
792
793 if(alsa_fops == NULL) {
794 ret = OSSERR_NO_DEVICE_AVAILABLE;
795 goto failure;
796 }
797
798 sz = sizeof(mixerhandle);
799 pHandle = kmalloc(sz, GFP_KERNEL);
800 if(pHandle == NULL) {
801 ret = OSSERR_OUT_OF_MEMORY;
802 goto failure;
803 }
804 memset(pHandle, 0, sizeof(mixerhandle));
805
806 //set operation to non-blocking
807 pHandle->file.f_flags = O_NONBLOCK;
808
809 //setup pointers in file structure (used internally by ALSA)
810 pHandle->file.f_dentry = &pHandle->d_entry;
811 pHandle->file.f_dentry->d_inode = &pHandle->inode;
812
813 pHandle->file.f_mode = FMODE_WRITE;
814 pHandle->inode.i_rdev = SNDRV_MINOR(deviceid, SNDRV_MINOR_CONTROL);
815
816 ret = alsa_fops->open(&pHandle->inode, &pHandle->file);
817 if(ret) {
818 goto failure;
819 }
820
821 pElem = (snd_ctl_elem_value_t *)value;
822 if(pElem == NULL) {
823 ret = pHandle->file.f_op->release(&pHandle->inode, &pHandle->file);
824 goto failure;
825 }
826
827// printk("sizeof elem_info %i\n",sizeof(snd_ctl_elem_info_t));
828
829 pElem->id.numid = id;
830 pElem->indirect = 0;
831 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_CTL_IOCTL_ELEM_READ, (ULONG)pElem);
832 ret = pHandle->file.f_op->release(&pHandle->inode, &pHandle->file);
833 if(pHandle) kfree(pHandle);
834
835 return OSSERR_SUCCESS;
836failure:
837 if(pHandle) {
838 kfree(pHandle);
839 }
840 DebugInt3();
841 return OSSERR_OUT_OF_MEMORY;
842}
843
844int GetUniaudControlValuePut(ULONG deviceid, ULONG id, void *value)
845{
846 snd_ctl_elem_value_t *pElem = NULL;
847 snd_ctl_elem_info_t *pElemInfo = NULL;
848 mixerhandle *pHandle = NULL;
849 int ret, i, j, sz;
850
851 if(alsa_fops == NULL) {
852 ret = OSSERR_NO_DEVICE_AVAILABLE;
853 goto failure;
854 }
855
856 sz = sizeof(mixerhandle);
857 pHandle = kmalloc(sz, GFP_KERNEL);
858 if(pHandle == NULL) {
859 ret = OSSERR_OUT_OF_MEMORY;
860 goto failure;
861 }
862 memset(pHandle, 0, sizeof(mixerhandle));
863
864 //set operation to non-blocking
865 pHandle->file.f_flags = O_NONBLOCK;
866
867 //setup pointers in file structure (used internally by ALSA)
868 pHandle->file.f_dentry = &pHandle->d_entry;
869 pHandle->file.f_dentry->d_inode = &pHandle->inode;
870
871 pHandle->file.f_mode = FMODE_WRITE;
872 pHandle->inode.i_rdev = SNDRV_MINOR(deviceid, SNDRV_MINOR_CONTROL);
873
874 ret = alsa_fops->open(&pHandle->inode, &pHandle->file);
875 if(ret) {
876 goto failure;
877 }
878
879 pElem = (snd_ctl_elem_value_t *)value;
880 if(pElem == NULL) {
881 ret = pHandle->file.f_op->release(&pHandle->inode, &pHandle->file);
882 goto failure;
883 }
884
885// printk("sizeof elem_info %i\n",sizeof(snd_ctl_elem_info_t));
886
887 pElem->id.numid = id;
888 pElem->indirect = 0;
889 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_CTL_IOCTL_ELEM_WRITE, (ULONG)pElem);
890 ret = pHandle->file.f_op->release(&pHandle->inode, &pHandle->file);
891 if(pHandle) kfree(pHandle);
892
893 return OSSERR_SUCCESS;
894
895failure:
896 if(pHandle) {
897 kfree(pHandle);
898 }
899 DebugInt3();
900 return OSSERR_OUT_OF_MEMORY;
901}
902
903int UniaudIoctlHWRefine(OSSSTREAMID streamid, void *pHwParams)
904{
905 int ret;
906 soundhandle *pHandle = (soundhandle *)streamid;
907 snd_pcm_hw_params_t *params = NULL;
908
909 params = (snd_pcm_hw_params_t *)pHwParams;
910
911 if (!params) return -1001;
912
913 if (!pHandle) return -1002;
914
915 pHandle->file.f_flags = O_NONBLOCK;
916 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_PCM_IOCTL_HW_REFINE, (ULONG)params);
917 return ret;
918}
919
920int UniaudIoctlHWParamSet(OSSSTREAMID streamid, void *pHwParams)
921{
922 int ret;
923 soundhandle *pHandle = (soundhandle *)streamid;
924 snd_pcm_hw_params_t *params = NULL;
925
926 params = (snd_pcm_hw_params_t *)pHwParams;
927
928 if (!params) return -1001;
929 if (!pHandle) return -1002;
930
931 pHandle->file.f_flags = O_NONBLOCK;
932 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_PCM_IOCTL_HW_PARAMS, (ULONG)params);
933 return ret;
934}
935
936int UniaudIoctlSWParamSet(OSSSTREAMID streamid, void *pSwParams)
937{
938 int ret;
939 soundhandle *pHandle = (soundhandle *)streamid;
940 snd_pcm_sw_params_t *params = NULL;
941
942 params = (snd_pcm_sw_params_t *)pSwParams;
943
944 if (!params) return -1001;
945 if (!pHandle) return -1002;
946
947 pHandle->file.f_flags = O_NONBLOCK;
948
949 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_PCM_IOCTL_SW_PARAMS, (ULONG)params);
950 return ret;
951}
952
953int UniaudIoctlPCMStatus(OSSSTREAMID streamid, void *pstatus)
954{
955 int ret;
956 soundhandle *pHandle = (soundhandle *)streamid;
957 snd_pcm_status_t *status = (snd_pcm_status_t *)pstatus;
958
959 if (!status) return -1001;
960 if (!pHandle) return -1002;
961
962 pHandle->file.f_flags = O_NONBLOCK;
963
964 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_PCM_IOCTL_STATUS, (ULONG)status);
965 return ret;
966}
967
968int UniaudIoctlPCMWrite(OSSSTREAMID streamid, char *buf, int size)
969{
970 int ret;
971 soundhandle *pHandle = (soundhandle *)streamid;
972
973 if (!buf) return -1001;
974 if (!pHandle) return -1002;
975
976 pHandle->file.f_flags = O_NONBLOCK;
977
978 ret = pHandle->file.f_op->write(&pHandle->file, buf, size, &pHandle->file.f_pos);
979
980 return ret;
981}
982
983int UniaudIoctlPCMRead(OSSSTREAMID streamid, char *buf, int size)
984{
985 int ret;
986 soundhandle *pHandle = (soundhandle *)streamid;
987
988 if (!buf) return -1001;
989 if (!pHandle) return -1002;
990
991 pHandle->file.f_flags = O_NONBLOCK;
992
993 ret = pHandle->file.f_op->read(&pHandle->file, buf, size, &pHandle->file.f_pos);
994
995 return ret;
996}
997
998int UniaudIoctlPCMPrepare(OSSSTREAMID streamid)
999{
1000 int ret;
1001 soundhandle *pHandle = (soundhandle *)streamid;
1002
1003 if (!pHandle) return -1002;
1004
1005 pHandle->file.f_flags = O_NONBLOCK;
1006
1007 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_PCM_IOCTL_PREPARE, 0);
1008 return ret;
1009}
1010
1011int UniaudIoctlPCMResume(OSSSTREAMID streamid, int pause)
1012{
1013 int ret;
1014 soundhandle *pHandle = (soundhandle *)streamid;
1015
1016 if (!pHandle) return -1002;
1017
1018 pHandle->file.f_flags = O_NONBLOCK;
1019
1020 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_PCM_IOCTL_PAUSE, pause);
1021
1022 return ret;
1023}
1024
1025int UniaudIoctlPCMStart(OSSSTREAMID streamid)
1026{
1027 int ret;
1028 soundhandle *pHandle = (soundhandle *)streamid;
1029
1030 if (!pHandle) return -1002;
1031
1032 pHandle->file.f_flags = O_NONBLOCK;
1033
1034 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_PCM_IOCTL_START, 0);
1035
1036 return ret;
1037}
1038
1039int UniaudIoctlPCMDrop(OSSSTREAMID streamid)
1040{
1041 int ret;
1042 soundhandle *pHandle = (soundhandle *)streamid;
1043
1044 if (!pHandle) return -1002;
1045
1046 pHandle->file.f_flags = O_NONBLOCK;
1047
1048 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_PCM_IOCTL_DROP, 0);
1049
1050 return ret;
1051}
1052
1053void UniaudCloseAll(USHORT fileid)
1054{
1055 int i;
1056
1057 for (i=0; i < 8*256; i++)
1058 {
1059 if (opened_handles[i].handle != 0)
1060 {
1061 if (fileid)
1062 {
1063 if (fileid == opened_handles[i].FileId)
1064 {
1065 if (OSS32_WaveClose((OSSSTREAMID)opened_handles[i].handle) == 0)
1066 opened_handles[i].handle = 0;
1067 }
1068 }
1069 else
1070 {
1071 if (OSS32_WaveClose((OSSSTREAMID)opened_handles[i].handle) == 0)
1072 opened_handles[i].handle = 0;
1073 }
1074 }
1075 }
1076 return;
1077}
Note: See TracBrowser for help on using the repository browser.