Annotation of sys/compat/linux/linux_cdrom.c, Revision 1.1.1.1
1.1 nbrk 1:
2: /* $OpenBSD: linux_cdrom.c,v 1.8 2002/03/14 01:26:50 millert Exp $ */
3: /*
4: * Copyright 1997 Niels Provos <provos@physnet.uni-hamburg.de>
5: * All rights reserved.
6: *
7: * Redistribution and use in source and binary forms, with or without
8: * modification, are permitted provided that the following conditions
9: * are met:
10: * 1. Redistributions of source code must retain the above copyright
11: * notice, this list of conditions and the following disclaimer.
12: * 2. Redistributions in binary form must reproduce the above copyright
13: * notice, this list of conditions and the following disclaimer in the
14: * documentation and/or other materials provided with the distribution.
15: * 3. All advertising materials mentioning features or use of this software
16: * must display the following acknowledgement:
17: * This product includes software developed by Niels Provos.
18: * 4. The name of the author may not be used to endorse or promote products
19: * derived from this software without specific prior written permission.
20: *
21: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
22: * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
23: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
24: * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
25: * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
26: * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27: * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28: * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
30: * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
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: syscallarg(int) fd;
76: syscallarg(u_long) com;
77: syscallarg(caddr_t) data;
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: }
CVSweb