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

Last change on this file since 625 was 625, checked in by Paul Smedley, 5 years ago

Code cleanups to simplify future maintenance, update regmap/regcache/rbtree to linux 4.19.163 level

File size: 27.2 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 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
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 dprintf(("GetUniaudPcmCaps1: wave open error %i %s at pcm %i", ret, (j == 0) ?"PLAY":"REC", i));
305 continue;
306 //goto fail;
307 }
308 pHandle = (soundhandle *)streamid;
309 if(pHandle == NULL || pHandle->magic != MAGIC_WAVE_ALSA32) {
310 rprintf(("GetUniaudPcmCaps: invalid stream id"));
311 ret = OSSERR_INVALID_STREAMID;
312 //goto fail;
313 }
314
315 //set operation to non-blocking
316 pHandle->file.f_flags = O_NONBLOCK;
317
318 dprintf(("GetUniaudPcmCaps: cp1. pcm %i, phandle %x", i, pHandle));
319 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_PCM_IOCTL_INFO, (ULONG)pcminfo);
320 if(ret != 0) {
321 rprintf(("GetUniaudPcmCaps: SNDRV_PCM_IOCTL_INFO error %i", ret));
322 ret = UNIXToOSSError(ret);
323 continue;
324 }
325 if(pcminfo->name[0]) {
326 strncpy(pcaps->szDeviceName, pcminfo->name, sizeof(pcaps->szDeviceName));
327 }
328 else strncpy(pcaps->szDeviceName, pcminfo->id, sizeof(pcaps->szDeviceName));
329
330 if(pcminfo->subname[0]) {
331 strncpy(pcaps->szMixerName, pcminfo->subname, sizeof(pcaps->szMixerName));
332 }
333
334 pWaveCaps->nrStreams = pcminfo->subdevices_count;
335
336 dprintf(("GetUniaudPcmCaps: pcm %i, cp2. nr of streams: %i", i, pWaveCaps->nrStreams));
337 //get all hardware parameters
338 _snd_pcm_hw_params_any(params);
339 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_PCM_IOCTL_HW_REFINE, (ULONG)params);
340 if(ret != 0) {
341 dprintf(("GetUniaudPcmCaps: SNDRV_PCM_IOCTL_HW_REFINE error %i", ret));
342 ret = UNIXToOSSError(ret);
343 //goto fail;
344 continue;
345 }
346 //dprintf("GetUniaudPcmCaps: cp3"));
347
348 pWaveCaps->ulMinChannels = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS)->min;
349 pWaveCaps->ulMaxChannels = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS)->max;
350 dprintf(("chan: from %i to %i\n", pWaveCaps->ulMinChannels,pWaveCaps->ulMaxChannels));
351 pWaveCaps->ulChanFlags = 0;
352 if(pWaveCaps->ulMinChannels == 1) {
353 pWaveCaps->ulChanFlags |= OSS32_CAPS_PCM_CHAN_MONO;
354 }
355 if(pWaveCaps->ulMaxChannels >= 2) {
356 pWaveCaps->ulChanFlags |= OSS32_CAPS_PCM_CHAN_STEREO;
357 }
358 if(pWaveCaps->ulMaxChannels >= 4) {
359 pWaveCaps->ulChanFlags |= OSS32_CAPS_PCM_CHAN_QUAD;
360 }
361 if(pWaveCaps->ulMaxChannels >= 6) {
362 pWaveCaps->ulChanFlags |= OSS32_CAPS_PCM_CHAN_5_1;
363 }
364 pWaveCaps->ulMinRate = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE)->min;
365 pWaveCaps->ulMaxRate = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE)->max;
366
367 mask = hw_param_mask(params, SNDRV_PCM_HW_PARAM_RATE_MASK);
368 //mask = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
369 pWaveCaps->ulRateFlags = mask->bits[0];
370
371 pWaveCaps->ulRateFlags = ALSAToOSSRateFlags(pWaveCaps->ulRateFlags);
372
373 pWaveCaps->ulDataFormats = 0;
374
375 mask = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
376 format_mask = mask->bits[0];
377 for(fmt=0;fmt<32;fmt++)
378 {
379 if(format_mask & (1 << fmt))
380 {
381 int f = ALSAToOSSDataType(fmt);
382 if (f >= 0)
383 pWaveCaps->ulDataFormats |= f;
384 }
385 }
386
387 OSS32_WaveClose(streamid);
388 streamid = 0;
389 } // for j
390 pcaps++; // next pcm
391 } // for i
392
393 if (pcminfo) kfree(pcminfo);
394 return OSSERR_SUCCESS;
395}
396
397void FillCaps(ULONG deviceid)
398{
399 int pcms = 0;
400
401 pcms = pcm_instances(deviceid);
402
403 //dprintf(("FillCaps: pcms=%i\n", pcms));
404 if (!pcmcaps[deviceid])
405 {
406 pcmcaps[deviceid] = (POSS32_DEVCAPS)kmalloc(sizeof(OSS32_DEVCAPS)*pcms, GFP_KERNEL);
407 if (pcmcaps[deviceid])
408 {
409 memset(pcmcaps[deviceid], 0, sizeof(OSS32_DEVCAPS)*pcms);
410 GetUniaudPcmCaps1(deviceid, (void *)pcmcaps[deviceid]);
411 }
412 }
413 return;
414}
415
416int GetUniaudPcmCaps(ULONG deviceid, void *caps)
417{
418 int pcms = 0;
419
420 pcms = pcm_instances(deviceid);
421
422// printk("pcms = %i\n", pcms);
423 if (pcmcaps[deviceid])
424 {
425 memcpy((unsigned char*)caps,(unsigned char*)pcmcaps[deviceid],sizeof(OSS32_DEVCAPS)*pcms);
426 return 0;
427 }
428 else
429 {
430 return -1;
431 }
432}
433
434/*
435 returns power state of given card
436 */
437int UniaudCtlGetPowerState(ULONG deviceid, void *state)
438{
439 mixerhandle *pHandle = NULL;
440 int ret;
441 //int i, j;
442
443 if(alsa_fops == NULL) {
444 ret = OSSERR_NO_DEVICE_AVAILABLE;
445 goto failure;
446 }
447
448 pHandle = kmalloc(sizeof(mixerhandle), GFP_KERNEL);
449 if(pHandle == NULL) {
450 ret = OSSERR_OUT_OF_MEMORY;
451 goto failure;
452 }
453 memset(pHandle, 0, sizeof(mixerhandle));
454
455 //set operation to non-blocking
456 pHandle->file.f_flags = O_NONBLOCK;
457
458 //setup pointers in file structure (used internally by ALSA)
459 pHandle->file.f_dentry = &pHandle->d_entry;
460 pHandle->file.f_dentry->d_inode = &pHandle->inode;
461
462 pHandle->file.f_mode = FMODE_WRITE;
463 pHandle->inode.i_rdev = SNDRV_MINOR(deviceid, SNDRV_MINOR_CONTROL);
464
465 ret = alsa_fops->open(&pHandle->inode, &pHandle->file);
466 if(ret) {
467 goto failure;
468 }
469 //retrieve mixer information
470 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file,
471 SNDRV_CTL_IOCTL_POWER_STATE,
472 (ULONG)state);
473
474 pHandle->file.f_op->release(&pHandle->inode, &pHandle->file);
475
476 kfree(pHandle);
477
478 if(ret) {
479 goto failure;
480 }
481
482 return OSSERR_SUCCESS;
483failure:
484 DebugInt3();
485 return ret;
486}
487
488/*
489 sets power state for given card
490 */
491int UniaudCtlSetPowerState(ULONG deviceid, void *state)
492{
493 mixerhandle *pHandle = NULL;
494 int ret;
495 //int 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;
549 //int i, j;
550
551 //dprintf(("GetUniaudCardInfo"));
552
553 if(alsa_fops == NULL) {
554 ret = OSSERR_NO_DEVICE_AVAILABLE;
555 goto failure;
556 }
557
558 pHandle = kmalloc(sizeof(mixerhandle), GFP_KERNEL);
559 if(pHandle == NULL) {
560 ret = OSSERR_OUT_OF_MEMORY;
561 goto failure;
562 }
563 memset(pHandle, 0, sizeof(mixerhandle));
564
565 //set operation to non-blocking
566 pHandle->file.f_flags = O_NONBLOCK;
567
568 //setup pointers in file structure (used internally by ALSA)
569 pHandle->file.f_dentry = &pHandle->d_entry;
570 pHandle->file.f_dentry->d_inode = &pHandle->inode;
571
572 pHandle->file.f_mode = FMODE_WRITE;
573 pHandle->inode.i_rdev = SNDRV_MINOR(deviceid, SNDRV_MINOR_CONTROL);
574
575 ret = alsa_fops->open(&pHandle->inode, &pHandle->file);
576 if(ret) {
577 goto failure;
578 }
579 //retrieve mixer information
580 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file,
581 SNDRV_CTL_IOCTL_CARD_INFO,
582 (ULONG)(struct snd_ctl_card_info *)info);
583 if(ret) {
584 ret = pHandle->file.f_op->release(&pHandle->inode, &pHandle->file);
585 goto failure;
586 }
587 ret = pHandle->file.f_op->release(&pHandle->inode, &pHandle->file);
588
589 if(pHandle) {
590 kfree(pHandle);
591 }
592 return OSSERR_SUCCESS;
593failure:
594 if(pHandle) {
595 kfree(pHandle);
596 }
597 DebugInt3();
598 return OSSERR_OUT_OF_MEMORY;
599}
600
601int GetUniaudControlNum(ULONG deviceid)
602{
603 mixerhandle *pHandle = NULL;
604 int ret, sz;
605 //int i, j;
606
607 //dprintf(("GetUniaudControlNum"));
608
609 if(alsa_fops == NULL) {
610 ret = OSSERR_NO_DEVICE_AVAILABLE;
611 goto failure;
612 }
613
614 sz = sizeof(mixerhandle);
615 pHandle = kmalloc(sz, GFP_KERNEL);
616 if(pHandle == NULL) {
617 ret = OSSERR_OUT_OF_MEMORY;
618 goto failure;
619 }
620 memset(pHandle, 0, sizeof(mixerhandle));
621
622 //set operation to non-blocking
623 pHandle->file.f_flags = O_NONBLOCK;
624
625 //setup pointers in file structure (used internally by ALSA)
626 pHandle->file.f_dentry = &pHandle->d_entry;
627 pHandle->file.f_dentry->d_inode = &pHandle->inode;
628
629 pHandle->file.f_mode = FMODE_WRITE;
630 pHandle->inode.i_rdev = SNDRV_MINOR(deviceid, SNDRV_MINOR_CONTROL);
631
632 ret = alsa_fops->open(&pHandle->inode, &pHandle->file);
633 if(ret) {
634 goto failure;
635 }
636 //retrieve mixer information
637 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file,
638 SNDRV_CTL_IOCTL_CARD_INFO,
639 (ULONG)&pHandle->info);
640 if(ret) {
641 ret = pHandle->file.f_op->release(&pHandle->inode, &pHandle->file);
642 goto failure;
643 }
644 //get the number of mixer elements
645 pHandle->list.offset = 0;
646 pHandle->list.space = 0;
647 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file,
648 SNDRV_CTL_IOCTL_ELEM_LIST,
649 (ULONG)&pHandle->list);
650 if(ret) {
651 ret = pHandle->file.f_op->release(&pHandle->inode, &pHandle->file);
652 goto failure;
653 }
654 ret = pHandle->file.f_op->release(&pHandle->inode, &pHandle->file);
655 if(pHandle) {
656 if(pHandle->pids) kfree(pHandle->pids);
657 kfree(pHandle);
658 }
659 return pHandle->list.count;
660failure:
661 if(pHandle) {
662 if(pHandle->pids) kfree(pHandle->pids);
663 kfree(pHandle);
664 }
665 DebugInt3();
666 return OSSERR_OUT_OF_MEMORY;
667}
668
669int GetUniaudControls(ULONG deviceid, void *pids)
670{
671 mixerhandle *pHandle = NULL;
672 int ret, sz;
673 //int i, j;
674
675 //dprintf(("GetUniaudControls"));
676
677 if(alsa_fops == NULL) {
678 ret = OSSERR_NO_DEVICE_AVAILABLE;
679 goto failure;
680 }
681
682 sz = sizeof(mixerhandle);
683 pHandle = kmalloc(sz, GFP_KERNEL);
684 if(pHandle == NULL) {
685 ret = OSSERR_OUT_OF_MEMORY;
686 goto failure;
687 }
688 memset(pHandle, 0, sizeof(mixerhandle));
689
690 //set operation to non-blocking
691 pHandle->file.f_flags = O_NONBLOCK;
692
693 //setup pointers in file structure (used internally by ALSA)
694 pHandle->file.f_dentry = &pHandle->d_entry;
695 pHandle->file.f_dentry->d_inode = &pHandle->inode;
696
697 pHandle->file.f_mode = FMODE_WRITE;
698 pHandle->inode.i_rdev = SNDRV_MINOR(deviceid, SNDRV_MINOR_CONTROL);
699
700 ret = alsa_fops->open(&pHandle->inode, &pHandle->file);
701 if(ret) {
702 goto failure;
703 }
704 //retrieve mixer information
705 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file,
706 SNDRV_CTL_IOCTL_CARD_INFO,
707 (ULONG)&pHandle->info);
708 if(ret) {
709 ret = pHandle->file.f_op->release(&pHandle->inode, &pHandle->file);
710 goto failure;
711 }
712 //get the number of mixer elements
713 pHandle->list.offset = 0;
714 pHandle->list.space = 0;
715 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file,
716 SNDRV_CTL_IOCTL_ELEM_LIST,
717 (ULONG)&pHandle->list);
718 if(ret) {
719 ret = pHandle->file.f_op->release(&pHandle->inode, &pHandle->file);
720 goto failure;
721 }
722
723 //allocate memory for all mixer elements
724 pHandle->pids = (struct snd_ctl_elem_id *)pids;
725 //kmalloc(sizeof(struct snd_ctl_elem_id)*pHandle->list.count, GFP_KERNEL);
726 if(pHandle->pids == NULL) {
727 ret = pHandle->file.f_op->release(&pHandle->inode, &pHandle->file);
728 goto failure;
729 }
730 //and retrieve all mixer elements
731 pHandle->list.offset = 0;
732 pHandle->list.space = pHandle->list.count;
733 pHandle->list.pids = pHandle->pids;
734 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file,
735 SNDRV_CTL_IOCTL_ELEM_LIST,
736 (ULONG)&pHandle->list);
737 if(ret) {
738 ret = pHandle->file.f_op->release(&pHandle->inode, &pHandle->file);
739 goto failure;
740 }
741// if (pids)
742// memcpy(pids, pHandle->pids,
743// sizeof(struct snd_ctl_elem_id)*pHandle->list.count);
744
745 ret = pHandle->file.f_op->release(&pHandle->inode, &pHandle->file);
746 if(pHandle) {
747// if(pHandle->pids) kfree(pHandle->pids);
748 kfree(pHandle);
749 }
750 return pHandle->list.count;
751failure:
752 if(pHandle) {
753// if(pHandle->pids) kfree(pHandle->pids);
754 kfree(pHandle);
755 }
756 DebugInt3();
757 return OSSERR_OUT_OF_MEMORY;
758}
759
760int GetUniaudControlInfo(ULONG deviceid, ULONG id, void *info)
761{
762 //struct snd_ctl_elem_value *pElem = NULL;
763 struct snd_ctl_elem_info *pElemInfo = NULL;
764 mixerhandle *pHandle = NULL;
765 int ret, sz;
766 //int i, j;
767
768 //dprintf(("GetUniaudControlInfo"));
769
770 if(alsa_fops == NULL) {
771 ret = OSSERR_NO_DEVICE_AVAILABLE;
772 goto failure;
773 }
774
775 sz = sizeof(mixerhandle);
776 pHandle = kmalloc(sz, GFP_KERNEL);
777 if(pHandle == NULL) {
778 ret = OSSERR_OUT_OF_MEMORY;
779 goto failure;
780 }
781 memset(pHandle, 0, sizeof(mixerhandle));
782
783 //set operation to non-blocking
784 pHandle->file.f_flags = O_NONBLOCK;
785
786 //setup pointers in file structure (used internally by ALSA)
787 pHandle->file.f_dentry = &pHandle->d_entry;
788 pHandle->file.f_dentry->d_inode = &pHandle->inode;
789
790 pHandle->file.f_mode = FMODE_WRITE;
791 pHandle->inode.i_rdev = SNDRV_MINOR(deviceid, SNDRV_MINOR_CONTROL);
792
793 ret = alsa_fops->open(&pHandle->inode, &pHandle->file);
794 if(ret) {
795 goto failure;
796 }
797
798 //allocate memory for info element
799 pElemInfo = (struct snd_ctl_elem_info *)info;
800 if(pElemInfo == NULL) {
801 ret = pHandle->file.f_op->release(&pHandle->inode, &pHandle->file);
802 goto failure;
803 }
804
805// printk("sizeof elem_info %i\n",sizeof(struct snd_ctl_elem_info));
806
807 pElemInfo->id.numid = id;
808 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_CTL_IOCTL_ELEM_INFO, (ULONG)pElemInfo);
809 ret = pHandle->file.f_op->release(&pHandle->inode, &pHandle->file);
810 if(pHandle) kfree(pHandle);
811// printk("elem type: %i, id: %i, card: %i\n", pElemInfo->type, pElemInfo->id.numid, deviceid);
812 return OSSERR_SUCCESS;
813
814failure:
815 if(pHandle) {
816 kfree(pHandle);
817 }
818 DebugInt3();
819 return OSSERR_OUT_OF_MEMORY;
820}
821
822int GetUniaudControlValueGet(ULONG deviceid, ULONG id, void *value)
823{
824 struct snd_ctl_elem_value *pElem = NULL;
825 //struct snd_ctl_elem_info *pElemInfo = NULL;
826 mixerhandle *pHandle = NULL;
827 int ret, sz;
828 //int i, j;
829
830 if(alsa_fops == NULL) {
831 ret = OSSERR_NO_DEVICE_AVAILABLE;
832 goto failure;
833 }
834
835 sz = sizeof(mixerhandle);
836 pHandle = kmalloc(sz, GFP_KERNEL);
837 if(pHandle == NULL) {
838 ret = OSSERR_OUT_OF_MEMORY;
839 goto failure;
840 }
841 memset(pHandle, 0, sizeof(mixerhandle));
842
843 //set operation to non-blocking
844 pHandle->file.f_flags = O_NONBLOCK;
845
846 //setup pointers in file structure (used internally by ALSA)
847 pHandle->file.f_dentry = &pHandle->d_entry;
848 pHandle->file.f_dentry->d_inode = &pHandle->inode;
849
850 pHandle->file.f_mode = FMODE_WRITE;
851 pHandle->inode.i_rdev = SNDRV_MINOR(deviceid, SNDRV_MINOR_CONTROL);
852
853 ret = alsa_fops->open(&pHandle->inode, &pHandle->file);
854 if(ret) {
855 goto failure;
856 }
857
858 pElem = (struct snd_ctl_elem_value *)value;
859 if(pElem == NULL) {
860 ret = pHandle->file.f_op->release(&pHandle->inode, &pHandle->file);
861 goto failure;
862 }
863
864 pElem->id.numid = id;
865 pElem->indirect = 0;
866 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_CTL_IOCTL_ELEM_READ, (ULONG)pElem);
867 ret = pHandle->file.f_op->release(&pHandle->inode, &pHandle->file);
868 if(pHandle) kfree(pHandle);
869
870 //dprintf(("GetUniaudControlValueGet: id=%x 0=%x 1=%x", pElem->id.numid, pElem->value.integer.value[0], pElem->value.integer.value[1]));
871
872 return OSSERR_SUCCESS;
873failure:
874 if(pHandle) {
875 kfree(pHandle);
876 }
877 DebugInt3();
878 return OSSERR_OUT_OF_MEMORY;
879}
880
881int GetUniaudControlValuePut(ULONG deviceid, ULONG id, void *value)
882{
883 struct snd_ctl_elem_value *pElem = NULL;
884 //struct snd_ctl_elem_info *pElemInfo = NULL;
885 mixerhandle *pHandle = NULL;
886 int ret, sz;
887 //int i, j;
888
889 if(alsa_fops == NULL) {
890 ret = OSSERR_NO_DEVICE_AVAILABLE;
891 goto failure;
892 }
893
894 sz = sizeof(mixerhandle);
895 pHandle = kmalloc(sz, GFP_KERNEL);
896 if(pHandle == NULL) {
897 ret = OSSERR_OUT_OF_MEMORY;
898 goto failure;
899 }
900 memset(pHandle, 0, sizeof(mixerhandle));
901
902 //set operation to non-blocking
903 pHandle->file.f_flags = O_NONBLOCK;
904
905 //setup pointers in file structure (used internally by ALSA)
906 pHandle->file.f_dentry = &pHandle->d_entry;
907 pHandle->file.f_dentry->d_inode = &pHandle->inode;
908
909 pHandle->file.f_mode = FMODE_WRITE;
910 pHandle->inode.i_rdev = SNDRV_MINOR(deviceid, SNDRV_MINOR_CONTROL);
911
912 ret = alsa_fops->open(&pHandle->inode, &pHandle->file);
913 if(ret) {
914 goto failure;
915 }
916
917 pElem = (struct snd_ctl_elem_value *)value;
918 if(pElem == NULL) {
919 ret = pHandle->file.f_op->release(&pHandle->inode, &pHandle->file);
920 goto failure;
921 }
922
923 pElem->id.numid = id;
924 pElem->indirect = 0;
925
926 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_CTL_IOCTL_ELEM_WRITE, (ULONG)pElem);
927 ret = pHandle->file.f_op->release(&pHandle->inode, &pHandle->file);
928 if(pHandle) kfree(pHandle);
929
930 return OSSERR_SUCCESS;
931
932failure:
933 if(pHandle) {
934 kfree(pHandle);
935 }
936 DebugInt3();
937 return OSSERR_OUT_OF_MEMORY;
938}
939
940int UniaudIoctlHWRefine(OSSSTREAMID streamid, void *pHwParams)
941{
942 int ret;
943 soundhandle *pHandle = (soundhandle *)streamid;
944 struct snd_pcm_hw_params *params = NULL;
945 params = (struct snd_pcm_hw_params *)pHwParams;
946
947 //dprintf(("UniaudIoctlHWRefine"));
948
949 if (!params) return -1001;
950
951 if (!pHandle) return -1002;
952
953 pHandle->file.f_flags = O_NONBLOCK;
954 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_PCM_IOCTL_HW_REFINE, (ULONG)params);
955 return ret;
956}
957
958int UniaudIoctlHWParamSet(OSSSTREAMID streamid, void *pHwParams)
959{
960 int ret;
961 soundhandle *pHandle = (soundhandle *)streamid;
962 struct snd_pcm_hw_params *params = NULL;
963 params = (struct snd_pcm_hw_params *)pHwParams;
964
965 //dprintf(("UniaudIoctlHWParamSet"));
966
967 if (!params) return -1001;
968 if (!pHandle) return -1002;
969
970 pHandle->file.f_flags = O_NONBLOCK;
971 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_PCM_IOCTL_HW_PARAMS, (ULONG)params);
972 return ret;
973}
974
975int UniaudIoctlSWParamSet(OSSSTREAMID streamid, void *pSwParams)
976{
977 int ret;
978 soundhandle *pHandle = (soundhandle *)streamid;
979 struct snd_pcm_sw_params *params = NULL;
980
981 params = (struct snd_pcm_sw_params *)pSwParams;
982
983 //dprintf(("UniaudIoctlSWParamSet"));
984
985 if (!params) return -1001;
986 if (!pHandle) return -1002;
987
988 pHandle->file.f_flags = O_NONBLOCK;
989
990 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_PCM_IOCTL_SW_PARAMS, (ULONG)params);
991 return ret;
992}
993
994int UniaudIoctlPCMStatus(OSSSTREAMID streamid, void *pstatus)
995{
996 int ret;
997 soundhandle *pHandle = (soundhandle *)streamid;
998 struct snd_pcm_status *status = (struct snd_pcm_status *)pstatus;
999
1000 //dprintf(("UniaudIoctlPCMStatus"));
1001
1002 if (!status) return -1001;
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_STATUS, (ULONG)status);
1008 return ret;
1009}
1010
1011int UniaudIoctlPCMWrite(OSSSTREAMID streamid, char *buf, int size)
1012{
1013 int ret;
1014 soundhandle *pHandle = (soundhandle *)streamid;
1015
1016 //dprintf(("UniaudIoctlPCMWrite"));
1017
1018 if (!buf) return -1001;
1019 if (!pHandle) return -1002;
1020
1021 pHandle->file.f_flags = O_NONBLOCK;
1022
1023 ret = pHandle->file.f_op->write(&pHandle->file, buf, size, &pHandle->file.f_pos);
1024
1025 return ret;
1026}
1027
1028int UniaudIoctlPCMRead(OSSSTREAMID streamid, char *buf, int size)
1029{
1030 int ret;
1031 soundhandle *pHandle = (soundhandle *)streamid;
1032
1033 if (!buf) return -1001;
1034 if (!pHandle) return -1002;
1035
1036 //dprintf(("UniaudIoctlPCMRead"));
1037
1038 pHandle->file.f_flags = O_NONBLOCK;
1039
1040 ret = pHandle->file.f_op->read(&pHandle->file, buf, size, &pHandle->file.f_pos);
1041
1042 return ret;
1043}
1044
1045int UniaudIoctlPCMPrepare(OSSSTREAMID streamid)
1046{
1047 int ret;
1048 soundhandle *pHandle = (soundhandle *)streamid;
1049
1050 //dprintf(("UniaudIoctlPCMPrepare"));
1051
1052 if (!pHandle) return -1002;
1053
1054 pHandle->file.f_flags = O_NONBLOCK;
1055
1056 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_PCM_IOCTL_PREPARE, 0);
1057 return ret;
1058}
1059
1060int UniaudIoctlPCMResume(OSSSTREAMID streamid, int pause)
1061{
1062 int ret;
1063 soundhandle *pHandle = (soundhandle *)streamid;
1064
1065 //dprintf(("UniaudIoctlPCMResume: %x", pause));
1066
1067 if (!pHandle) return -1002;
1068
1069 pHandle->file.f_flags = O_NONBLOCK;
1070
1071 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_PCM_IOCTL_PAUSE, pause);
1072
1073 return ret;
1074}
1075
1076int UniaudIoctlPCMStart(OSSSTREAMID streamid)
1077{
1078 int ret;
1079 soundhandle *pHandle = (soundhandle *)streamid;
1080
1081 //dprintf(("UniaudIoctlPCMStart"));
1082
1083 if (!pHandle) return -1002;
1084
1085 pHandle->file.f_flags = O_NONBLOCK;
1086
1087 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_PCM_IOCTL_START, 0);
1088
1089 return ret;
1090}
1091
1092int UniaudIoctlPCMDrop(OSSSTREAMID streamid)
1093{
1094 int ret;
1095 soundhandle *pHandle = (soundhandle *)streamid;
1096
1097 //dprintf(("UniaudIoctlPCMDrop"));
1098
1099 if (!pHandle) return -1002;
1100
1101 pHandle->file.f_flags = O_NONBLOCK;
1102
1103 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_PCM_IOCTL_DROP, 0);
1104
1105 return ret;
1106}
1107
1108void UniaudCloseAll(USHORT fileid)
1109{
1110 int i;
1111
1112 for (i=0; i < 8*256; i++)
1113 {
1114 if (opened_handles[i].handle != 0)
1115 {
1116 if (fileid)
1117 {
1118 if (fileid == opened_handles[i].FileId)
1119 {
1120 opened_handles[i].reuse = 0;
1121 if (OSS32_WaveClose((OSSSTREAMID)opened_handles[i].handle) == 0)
1122 opened_handles[i].handle = 0;
1123 }
1124 }
1125 else
1126 {
1127 opened_handles[i].reuse = 0;
1128 if (OSS32_WaveClose((OSSSTREAMID)opened_handles[i].handle) == 0)
1129 opened_handles[i].handle = 0;
1130 }
1131 }
1132 }
1133 return;
1134}
Note: See TracBrowser for help on using the repository browser.