Annotation of sys/compat/linux/linux_cdrom.c, Revision 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