source: GPL/trunk/lib32/ioctl.c@ 76

Last change on this file since 76 was 76, checked in by vladest, 19 years ago

Latest ALSA patches
HDA patches
Patch for Intel from Rudy's
Fixes locks on NM256 chipsets
Fixes PM on Maestro3 chipsets

File size: 29.8 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 opened_handles[i].reuse = 0;
1066 if (OSS32_WaveClose((OSSSTREAMID)opened_handles[i].handle) == 0)
1067 opened_handles[i].handle = 0;
1068 }
1069 }
1070 else
1071 {
1072 opened_handles[i].reuse = 0;
1073 if (OSS32_WaveClose((OSSSTREAMID)opened_handles[i].handle) == 0)
1074 opened_handles[i].handle = 0;
1075 }
1076 }
1077 }
1078 return;
1079}
Note: See TracBrowser for help on using the repository browser.