root/compat/linux/linux_cdrom.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. bsd_addr_to_linux_addr
  2. linux_ioctl_cdrom

    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 }

/* [<][>][^][v][top][bottom][index][help] */