ossaudio.c revision 1.1 1 1.1 mycroft #include <sys/param.h>
2 1.1 mycroft #include <sys/proc.h>
3 1.1 mycroft #include <sys/systm.h>
4 1.1 mycroft #include <sys/file.h>
5 1.1 mycroft #include <sys/filedesc.h>
6 1.1 mycroft #include <sys/ioctl.h>
7 1.1 mycroft #include <sys/mount.h>
8 1.1 mycroft #include <sys/audioio.h>
9 1.1 mycroft
10 1.1 mycroft #include <sys/syscallargs.h>
11 1.1 mycroft
12 1.1 mycroft #include <compat/linux/linux_types.h>
13 1.1 mycroft #include <compat/linux/linux_ioctl.h>
14 1.1 mycroft #include <compat/linux/linux_signal.h>
15 1.1 mycroft #include <compat/linux/linux_syscallargs.h>
16 1.1 mycroft #include <compat/linux/linux_audio.h>
17 1.1 mycroft
18 1.1 mycroft int
19 1.1 mycroft linux_ioctl_audio(p, uap, retval)
20 1.1 mycroft register struct proc *p;
21 1.1 mycroft register struct linux_sys_ioctl_args /* {
22 1.1 mycroft syscallarg(int) fd;
23 1.1 mycroft syscallarg(u_long) com;
24 1.1 mycroft syscallarg(caddr_t) data;
25 1.1 mycroft } */ *uap;
26 1.1 mycroft register_t *retval;
27 1.1 mycroft {
28 1.1 mycroft register struct file *fp;
29 1.1 mycroft register struct filedesc *fdp;
30 1.1 mycroft u_long com;
31 1.1 mycroft struct audio_info tmpinfo;
32 1.1 mycroft int idat;
33 1.1 mycroft int error;
34 1.1 mycroft
35 1.1 mycroft fdp = p->p_fd;
36 1.1 mycroft if ((u_int)SCARG(uap, fd) >= fdp->fd_nfiles ||
37 1.1 mycroft (fp = fdp->fd_ofiles[SCARG(uap, fd)]) == NULL)
38 1.1 mycroft return (EBADF);
39 1.1 mycroft
40 1.1 mycroft if ((fp->f_flag & (FREAD | FWRITE)) == 0)
41 1.1 mycroft return (EBADF);
42 1.1 mycroft
43 1.1 mycroft com = SCARG(uap, com);
44 1.1 mycroft retval[0] = 0;
45 1.1 mycroft
46 1.1 mycroft switch (com) {
47 1.1 mycroft case LINUX_SNDCTL_DSP_RESET:
48 1.1 mycroft error = (*fp->f_ops->fo_ioctl)(fp, AUDIO_FLUSH, (caddr_t)0, p);
49 1.1 mycroft if (error)
50 1.1 mycroft return error;
51 1.1 mycroft break;
52 1.1 mycroft case LINUX_SNDCTL_DSP_SYNC:
53 1.1 mycroft case LINUX_SNDCTL_DSP_POST:
54 1.1 mycroft error = (*fp->f_ops->fo_ioctl)(fp, AUDIO_DRAIN, (caddr_t)0, p);
55 1.1 mycroft if (error)
56 1.1 mycroft return error;
57 1.1 mycroft break;
58 1.1 mycroft case LINUX_SNDCTL_DSP_SPEED:
59 1.1 mycroft AUDIO_INITINFO(&tmpinfo);
60 1.1 mycroft error = copyin(SCARG(uap, data), &idat, sizeof idat);
61 1.1 mycroft if (error)
62 1.1 mycroft return error;
63 1.1 mycroft tmpinfo.play.sample_rate =
64 1.1 mycroft tmpinfo.record.sample_rate = idat;
65 1.1 mycroft (void) (*fp->f_ops->fo_ioctl)(fp, AUDIO_SETINFO, (caddr_t)&tmpinfo, p);
66 1.1 mycroft error = (*fp->f_ops->fo_ioctl)(fp, AUDIO_GETINFO, (caddr_t)&tmpinfo, p);
67 1.1 mycroft if (error)
68 1.1 mycroft return error;
69 1.1 mycroft idat = tmpinfo.play.sample_rate;
70 1.1 mycroft error = copyout(&idat, SCARG(uap, data), sizeof idat);
71 1.1 mycroft if (error)
72 1.1 mycroft return error;
73 1.1 mycroft break;
74 1.1 mycroft case LINUX_SNDCTL_DSP_STEREO:
75 1.1 mycroft AUDIO_INITINFO(&tmpinfo);
76 1.1 mycroft error = copyin(SCARG(uap, data), &idat, sizeof idat);
77 1.1 mycroft if (error)
78 1.1 mycroft return error;
79 1.1 mycroft tmpinfo.play.channels =
80 1.1 mycroft tmpinfo.record.channels = idat ? 2 : 1;
81 1.1 mycroft (void) (*fp->f_ops->fo_ioctl)(fp, AUDIO_SETINFO, (caddr_t)&tmpinfo, p);
82 1.1 mycroft error = (*fp->f_ops->fo_ioctl)(fp, AUDIO_GETINFO, (caddr_t)&tmpinfo, p);
83 1.1 mycroft if (error)
84 1.1 mycroft return error;
85 1.1 mycroft idat = tmpinfo.play.channels - 1;
86 1.1 mycroft error = copyout(&idat, SCARG(uap, data), sizeof idat);
87 1.1 mycroft if (error)
88 1.1 mycroft return error;
89 1.1 mycroft break;
90 1.1 mycroft case LINUX_SNDCTL_DSP_GETBLKSIZE:
91 1.1 mycroft error = (*fp->f_ops->fo_ioctl)(fp, AUDIO_GETINFO, (caddr_t)&tmpinfo, p);
92 1.1 mycroft if (error)
93 1.1 mycroft return error;
94 1.1 mycroft idat = tmpinfo.blocksize;
95 1.1 mycroft error = copyout(&idat, SCARG(uap, data), sizeof idat);
96 1.1 mycroft if (error)
97 1.1 mycroft return error;
98 1.1 mycroft break;
99 1.1 mycroft case LINUX_SNDCTL_DSP_SETFMT:
100 1.1 mycroft AUDIO_INITINFO(&tmpinfo);
101 1.1 mycroft error = copyin(SCARG(uap, data), &idat, sizeof idat);
102 1.1 mycroft if (error)
103 1.1 mycroft return error;
104 1.1 mycroft switch (idat) {
105 1.1 mycroft case LINUX_AFMT_MU_LAW:
106 1.1 mycroft tmpinfo.play.precision =
107 1.1 mycroft tmpinfo.record.precision = 8;
108 1.1 mycroft tmpinfo.play.encoding =
109 1.1 mycroft tmpinfo.record.encoding = AUDIO_ENCODING_ULAW;
110 1.1 mycroft break;
111 1.1 mycroft case LINUX_AFMT_A_LAW:
112 1.1 mycroft tmpinfo.play.precision =
113 1.1 mycroft tmpinfo.record.precision = 8;
114 1.1 mycroft tmpinfo.play.encoding =
115 1.1 mycroft tmpinfo.record.encoding = AUDIO_ENCODING_ALAW;
116 1.1 mycroft break;
117 1.1 mycroft case LINUX_AFMT_U8:
118 1.1 mycroft tmpinfo.play.precision =
119 1.1 mycroft tmpinfo.record.precision = 8;
120 1.1 mycroft tmpinfo.play.encoding =
121 1.1 mycroft tmpinfo.record.encoding = AUDIO_ENCODING_LINEAR;
122 1.1 mycroft break;
123 1.1 mycroft case LINUX_AFMT_S16_LE:
124 1.1 mycroft tmpinfo.play.precision =
125 1.1 mycroft tmpinfo.record.precision = 16;
126 1.1 mycroft tmpinfo.play.encoding =
127 1.1 mycroft tmpinfo.record.encoding = AUDIO_ENCODING_LINEAR;
128 1.1 mycroft break;
129 1.1 mycroft default:
130 1.1 mycroft return EINVAL;
131 1.1 mycroft }
132 1.1 mycroft (void) (*fp->f_ops->fo_ioctl)(fp, AUDIO_SETINFO, (caddr_t)&tmpinfo, p);
133 1.1 mycroft error = (*fp->f_ops->fo_ioctl)(fp, AUDIO_GETINFO, (caddr_t)&tmpinfo, p);
134 1.1 mycroft if (error)
135 1.1 mycroft return error;
136 1.1 mycroft /*XXXX*/
137 1.1 mycroft break;
138 1.1 mycroft case LINUX_SNDCTL_DSP_SETFRAGMENT:
139 1.1 mycroft AUDIO_INITINFO(&tmpinfo);
140 1.1 mycroft error = copyin(SCARG(uap, data), &idat, sizeof idat);
141 1.1 mycroft if (error)
142 1.1 mycroft return error;
143 1.1 mycroft if ((idat & 0xffff) < 4 || (idat & 0xffff) > 17)
144 1.1 mycroft return EINVAL;
145 1.1 mycroft tmpinfo.blocksize = 1 << (idat & 0xffff);
146 1.1 mycroft tmpinfo.hiwat = (idat >> 16) & 0xffff;
147 1.1 mycroft (void) (*fp->f_ops->fo_ioctl)(fp, AUDIO_SETINFO, (caddr_t)&tmpinfo, p);
148 1.1 mycroft error = (*fp->f_ops->fo_ioctl)(fp, AUDIO_GETINFO, (caddr_t)&tmpinfo, p);
149 1.1 mycroft if (error)
150 1.1 mycroft return error;
151 1.1 mycroft idat = tmpinfo.blocksize;
152 1.1 mycroft error = copyout(&idat, SCARG(uap, data), sizeof idat);
153 1.1 mycroft if (error)
154 1.1 mycroft return error;
155 1.1 mycroft break;
156 1.1 mycroft case LINUX_SNDCTL_DSP_GETFMTS:
157 1.1 mycroft idat = LINUX_AFMT_MU_LAW | LINUX_AFMT_U8 | LINUX_AFMT_S16_LE;
158 1.1 mycroft error = copyout(&idat, SCARG(uap, data), sizeof idat);
159 1.1 mycroft if (error)
160 1.1 mycroft return error;
161 1.1 mycroft break;
162 1.1 mycroft default:
163 1.1 mycroft return EINVAL;
164 1.1 mycroft }
165 1.1 mycroft
166 1.1 mycroft return 0;
167 1.1 mycroft }
168