This source file includes following definitions.
- bsd_addr_to_linux_addr
- linux_ioctl_cdrom
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33 #include <sys/param.h>
34 #include <sys/proc.h>
35 #include <sys/systm.h>
36 #include <sys/file.h>
37 #include <sys/filedesc.h>
38 #include <sys/ioctl.h>
39 #include <sys/mount.h>
40 #include <sys/cdio.h>
41
42 #include <sys/syscallargs.h>
43
44 #include <compat/linux/linux_types.h>
45 #include <compat/linux/linux_ioctl.h>
46 #include <compat/linux/linux_signal.h>
47 #include <compat/linux/linux_syscallargs.h>
48 #include <compat/linux/linux_util.h>
49 #include <compat/linux/linux_cdrom.h>
50
51 void bsd_addr_to_linux_addr(union msf_lba *bsd,
52 union linux_cdrom_addr *linux, int format);
53
54 void
55 bsd_addr_to_linux_addr(bsd, linux, format)
56 union msf_lba *bsd;
57 union linux_cdrom_addr *linux;
58 int format;
59 {
60 if (format == CD_MSF_FORMAT) {
61 linux->msf.minute = bsd->msf.minute;
62 linux->msf.second = bsd->msf.second;
63 linux->msf.frame = bsd->msf.frame;
64 } else
65 linux->lba = bsd->lba;
66 }
67
68 int
69 linux_ioctl_cdrom(p, v, retval)
70 struct proc *p;
71 void *v;
72 register_t *retval;
73 {
74 struct linux_sys_ioctl_args
75
76
77
78 *uap = v;
79 struct file *fp;
80 struct filedesc *fdp;
81 caddr_t sg;
82 u_long com, arg;
83 struct sys_ioctl_args ia;
84 int error;
85
86 union {
87 struct cd_toc_entry te;
88 struct cd_sub_channel_info scinfo;
89 } data;
90 union {
91 struct ioc_toc_header th;
92 struct ioc_read_toc_entry tes;
93 struct ioc_play_track ti;
94 struct ioc_play_msf msf;
95 struct ioc_play_blocks blk;
96 struct ioc_read_subchannel sc;
97 struct ioc_vol vol;
98 } tmpb;
99 union {
100 struct linux_cdrom_tochdr th;
101 struct linux_cdrom_tocentry te;
102 struct linux_cdrom_ti ti;
103 struct linux_cdrom_msf msf;
104 struct linux_cdrom_blk blk;
105 struct linux_cdrom_subchnl sc;
106 struct linux_cdrom_volctrl vol;
107 } tmpl;
108
109
110 fdp = p->p_fd;
111 if ((fp = fd_getfile(fdp, SCARG(uap, fd))) == NULL)
112 return (EBADF);
113 FREF(fp);
114
115 if ((fp->f_flag & (FREAD | FWRITE)) == 0) {
116 error = EBADF;
117 goto out;
118 }
119
120 com = SCARG(uap, com);
121 retval[0] = 0;
122
123 switch (com) {
124 case LINUX_CDROMREADTOCHDR:
125 error = (*fp->f_ops->fo_ioctl)(fp, CDIOREADTOCHEADER,
126 (caddr_t)&tmpb.th, p);
127 if (error)
128 goto out;
129 tmpl.th.cdth_trk0 = tmpb.th.starting_track;
130 tmpl.th.cdth_trk1 = tmpb.th.ending_track;
131 error = copyout(&tmpl, SCARG(uap, data), sizeof tmpl.th);
132 goto out;
133 case LINUX_CDROMREADTOCENTRY:
134 error = copyin(SCARG(uap, data), &tmpl.te, sizeof tmpl.te);
135 if (error)
136 goto out;
137
138 sg = stackgap_init(p->p_emul);
139
140 bzero(&tmpb.tes, sizeof tmpb.tes);
141 tmpb.tes.starting_track = tmpl.te.cdte_track;
142 tmpb.tes.address_format = (tmpl.te.cdte_format == LINUX_CDROM_MSF)
143 ? CD_MSF_FORMAT : CD_LBA_FORMAT;
144 tmpb.tes.data_len = sizeof(struct cd_toc_entry);
145 tmpb.tes.data = stackgap_alloc(&sg, tmpb.tes.data_len);
146
147 error = (*fp->f_ops->fo_ioctl)(fp, CDIOREADTOCENTRYS,
148 (caddr_t)&tmpb.tes, p);
149 if (error)
150 goto out;
151 if ((error = copyin(tmpb.tes.data, &data.te, sizeof data.te)))
152 goto out;
153
154 tmpl.te.cdte_ctrl = data.te.control;
155 tmpl.te.cdte_adr = data.te.addr_type;
156 tmpl.te.cdte_track = data.te.track;
157 tmpl.te.cdte_datamode = CD_TRACK_INFO;
158 bsd_addr_to_linux_addr(&data.te.addr, &tmpl.te.cdte_addr,
159 tmpb.tes.address_format);
160 error = copyout(&tmpl, SCARG(uap, data), sizeof tmpl.te);
161 goto out;
162 case LINUX_CDROMSUBCHNL:
163 error = copyin(SCARG(uap, data), &tmpl.sc, sizeof tmpl.sc);
164 if (error)
165 goto out;
166
167 sg = stackgap_init(p->p_emul);
168
169 bzero(&tmpb.sc, sizeof tmpb.sc);
170 tmpb.sc.data_format = CD_CURRENT_POSITION;
171 tmpb.sc.address_format = (tmpl.sc.cdsc_format == LINUX_CDROM_MSF)
172 ? CD_MSF_FORMAT : CD_LBA_FORMAT;
173 tmpb.sc.data_len = sizeof(struct cd_sub_channel_info);
174 tmpb.sc.data = stackgap_alloc(&sg, tmpb.sc.data_len);
175
176 error = (*fp->f_ops->fo_ioctl)(fp, CDIOCREADSUBCHANNEL,
177 (caddr_t)&tmpb.sc, p);
178 if (error)
179 goto out;
180 if ((error = copyin(tmpb.sc.data, &data.scinfo, sizeof data.scinfo)))
181 goto out;
182
183 tmpl.sc.cdsc_audiostatus = data.scinfo.header.audio_status;
184 tmpl.sc.cdsc_adr = data.scinfo.what.position.addr_type;
185 tmpl.sc.cdsc_ctrl = data.scinfo.what.position.control;
186 tmpl.sc.cdsc_trk = data.scinfo.what.position.track_number;
187 tmpl.sc.cdsc_ind = data.scinfo.what.position.index_number;
188 bsd_addr_to_linux_addr(&data.scinfo.what.position.absaddr,
189 &tmpl.sc.cdsc_absaddr,
190 tmpb.sc.address_format);
191 bsd_addr_to_linux_addr(&data.scinfo.what.position.reladdr,
192 &tmpl.sc.cdsc_reladdr,
193 tmpb.sc.address_format);
194
195 error = copyout(&tmpl, SCARG(uap, data), sizeof tmpl.sc);
196 goto out;
197 case LINUX_CDROMPLAYTRKIND:
198 error = copyin(SCARG(uap, data), &tmpl.ti, sizeof tmpl.ti);
199 if (error)
200 goto out;
201
202 tmpb.ti.start_track = tmpl.ti.cdti_trk0;
203 tmpb.ti.start_index = tmpl.ti.cdti_ind0;
204 tmpb.ti.end_track = tmpl.ti.cdti_trk1;
205 tmpb.ti.end_index = tmpl.ti.cdti_ind1;
206 error = (*fp->f_ops->fo_ioctl)(fp, CDIOCPLAYTRACKS,
207 (caddr_t)&tmpb.ti, p);
208 goto out;
209 case LINUX_CDROMPLAYMSF:
210 error = copyin(SCARG(uap, data), &tmpl.msf, sizeof tmpl.msf);
211 if (error)
212 goto out;
213
214 tmpb.msf.start_m = tmpl.msf.cdmsf_min0;
215 tmpb.msf.start_s = tmpl.msf.cdmsf_sec0;
216 tmpb.msf.start_f = tmpl.msf.cdmsf_frame0;
217 tmpb.msf.end_m = tmpl.msf.cdmsf_min1;
218 tmpb.msf.end_s = tmpl.msf.cdmsf_sec1;
219 tmpb.msf.end_f = tmpl.msf.cdmsf_frame1;
220
221 error = (*fp->f_ops->fo_ioctl)(fp, CDIOCPLAYMSF,
222 (caddr_t)&tmpb.msf, p);
223 goto out;
224 case LINUX_CDROMPLAYBLK:
225 error = copyin(SCARG(uap, data), &tmpl.blk, sizeof tmpl.blk);
226 if (error)
227 goto out;
228
229 tmpb.blk.blk = tmpl.blk.from;
230 tmpb.blk.len = tmpl.blk.len;
231
232 error = (*fp->f_ops->fo_ioctl)(fp, CDIOCPLAYBLOCKS,
233 (caddr_t)&tmpb.blk, p);
234 goto out;
235 case LINUX_CDROMVOLCTRL:
236 error = copyin(SCARG(uap, data), &tmpl.vol, sizeof tmpl.vol);
237 if (error)
238 goto out;
239
240 tmpb.vol.vol[0] = tmpl.vol.channel0;
241 tmpb.vol.vol[1] = tmpl.vol.channel1;
242 tmpb.vol.vol[2] = tmpl.vol.channel2;
243 tmpb.vol.vol[3] = tmpl.vol.channel3;
244
245 error = (*fp->f_ops->fo_ioctl)(fp, CDIOCSETVOL,
246 (caddr_t)&tmpb.vol, p);
247 goto out;
248 case LINUX_CDROMVOLREAD:
249 error = (*fp->f_ops->fo_ioctl)(fp, CDIOCGETVOL,
250 (caddr_t)&tmpb.vol, p);
251 if (error)
252 goto out;
253
254 tmpl.vol.channel0 = tmpb.vol.vol[0];
255 tmpl.vol.channel1 = tmpb.vol.vol[1];
256 tmpl.vol.channel2 = tmpb.vol.vol[2];
257 tmpl.vol.channel3 = tmpb.vol.vol[3];
258
259 error = copyout(&tmpl.vol, SCARG(uap, data), sizeof tmpl.vol);
260 goto out;
261 case LINUX_CDROMPAUSE:
262 SCARG(&ia, com) = CDIOCPAUSE;
263 break;
264 case LINUX_CDROMRESUME:
265 SCARG(&ia, com) = CDIOCRESUME;
266 break;
267 case LINUX_CDROMSTOP:
268 SCARG(&ia, com) = CDIOCSTOP;
269 break;
270 case LINUX_CDROMSTART:
271 SCARG(&ia, com) = CDIOCSTART;
272 break;
273 case LINUX_CDROMEJECT_SW:
274 error = copyin(SCARG(uap, data), &arg, sizeof arg);
275 if (error)
276 goto out;
277 SCARG(&ia, com) = arg ? CDIOCALLOW : CDIOCPREVENT;
278 break;
279 case LINUX_CDROMEJECT:
280 SCARG(&ia, com) = CDIOCEJECT;
281 break;
282 case LINUX_CDROMRESET:
283 SCARG(&ia, com) = CDIOCRESET;
284 break;
285 default:
286 printf("linux_ioctl_cdrom: invalid ioctl %08lx\n", com);
287 error = EINVAL;
288 goto out;
289 }
290
291 SCARG(&ia, fd) = SCARG(uap, fd);
292 SCARG(&ia, data) = SCARG(uap, data);
293 error = sys_ioctl(p, &ia, retval);
294
295 out:
296 FRELE(fp);
297 return (error);
298 }