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

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

Changes to PCI bus scan, malloc, cleanup all warnings, misc other changes

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