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