The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/i386/linux/linux_ioctl.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*
    2  * Copyright (c) 1994-1995 Søren Schmidt
    3  * All rights reserved.
    4  *
    5  * Redistribution and use in source and binary forms, with or without
    6  * modification, are permitted provided that the following conditions
    7  * are met:
    8  * 1. Redistributions of source code must retain the above copyright
    9  *    notice, this list of conditions and the following disclaimer
   10  *    in this position and unchanged.
   11  * 2. Redistributions in binary form must reproduce the above copyright
   12  *    notice, this list of conditions and the following disclaimer in the
   13  *    documentation and/or other materials provided with the distribution.
   14  * 3. The name of the author may not be used to endorse or promote products
   15  *    derived from this software withough specific prior written permission
   16  *
   17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
   18  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   19  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
   20  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
   21  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
   22  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   23  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
   24  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
   26  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   27  *
   28  * $FreeBSD$
   29  */
   30 
   31 #include <sys/param.h>
   32 #include <sys/systm.h>
   33 #include <sys/sysproto.h>
   34 #include <sys/proc.h>
   35 #include <sys/cdio.h>
   36 #include <sys/fcntl.h>
   37 #include <sys/file.h>
   38 #include <sys/filedesc.h>
   39 #include <sys/filio.h>
   40 #include <sys/tty.h>
   41 #include <sys/socket.h>
   42 #include <net/if.h>
   43 #include <net/if_dl.h>
   44 #include <net/if_types.h>
   45 #include <sys/sockio.h>
   46 
   47 #include <machine/soundcard.h>
   48 #include <machine/console.h>
   49 
   50 #include <i386/linux/linux.h>
   51 #include <i386/linux/linux_proto.h>
   52 #include <i386/linux/linux_util.h>
   53 
   54 #define ISSIGVALID(sig)         ((sig) > 0 && (sig) < NSIG)
   55 
   56 struct linux_termio {
   57     unsigned short c_iflag;
   58     unsigned short c_oflag;
   59     unsigned short c_cflag;
   60     unsigned short c_lflag;
   61     unsigned char c_line;
   62     unsigned char c_cc[LINUX_NCC];
   63 };
   64 
   65 
   66 struct linux_termios {
   67     unsigned int    c_iflag;
   68     unsigned int    c_oflag;
   69     unsigned int    c_cflag;
   70     unsigned int    c_lflag;
   71     unsigned char   c_line;
   72     unsigned char   c_cc[LINUX_NCCS];
   73 };
   74 
   75 struct linux_winsize {
   76     unsigned short ws_row, ws_col;
   77     unsigned short ws_xpixel, ws_ypixel;
   78 };
   79 
   80 static struct speedtab sptab[] = {
   81     { B0, LINUX_B0 }, { B50, LINUX_B50 },
   82     { B75, LINUX_B75 }, { B110, LINUX_B110 },
   83     { B134, LINUX_B134 }, { B150, LINUX_B150 },
   84     { B200, LINUX_B200 }, { B300, LINUX_B300 },
   85     { B600, LINUX_B600 }, { B1200, LINUX_B1200 },
   86     { B1800, LINUX_B1800 }, { B2400, LINUX_B2400 },
   87     { B4800, LINUX_B4800 }, { B9600, LINUX_B9600 },
   88     { B19200, LINUX_B19200 }, { B38400, LINUX_B38400 },
   89     { B57600, LINUX_B57600 }, { B115200, LINUX_B115200 },
   90     {-1, -1 }
   91 };
   92 
   93 struct linux_serial_struct {
   94         int     type;
   95         int     line;
   96         int     port;
   97         int     irq;
   98         int     flags;
   99         int     xmit_fifo_size;
  100         int     custom_divisor;
  101         int     baud_base;
  102         unsigned short  close_delay;
  103         char    reserved_char[2];
  104         int     hub6;
  105         unsigned short  closing_wait;
  106         unsigned short  closing_wait2;
  107         int     reserved[4];
  108 };
  109 
  110 struct linux_cdrom_msf
  111 {
  112     u_char      cdmsf_min0;
  113     u_char      cdmsf_sec0;
  114     u_char      cdmsf_frame0;
  115     u_char      cdmsf_min1;
  116     u_char      cdmsf_sec1;
  117     u_char      cdmsf_frame1;
  118 };
  119 
  120 struct linux_cdrom_tochdr
  121 {
  122     u_char      cdth_trk0;
  123     u_char      cdth_trk1;
  124 };
  125 
  126 union linux_cdrom_addr
  127 {
  128     struct {
  129         u_char  minute;
  130         u_char  second;
  131         u_char  frame;
  132     } msf;
  133     int         lba;
  134 };
  135 
  136 struct linux_cdrom_tocentry
  137 {
  138     u_char      cdte_track;     
  139     u_char      cdte_adr:4;
  140     u_char      cdte_ctrl:4;
  141     u_char      cdte_format;    
  142     union linux_cdrom_addr cdte_addr;
  143     u_char      cdte_datamode;  
  144 };
  145 
  146 struct linux_cdrom_subchnl
  147 {
  148     u_char      cdsc_format;
  149     u_char      cdsc_audiostatus;
  150     u_char      cdsc_adr:4;
  151     u_char      cdsc_ctrl:4;
  152     u_char      cdsc_trk;
  153     u_char      cdsc_ind;
  154     union linux_cdrom_addr cdsc_absaddr;
  155     union linux_cdrom_addr cdsc_reladdr;
  156 };
  157 
  158 
  159 static int
  160 linux_to_bsd_speed(int code, struct speedtab *table)
  161 {
  162     for ( ; table->sp_code != -1; table++)
  163         if (table->sp_code == code)
  164             return (table->sp_speed);
  165     return -1;
  166 }
  167 
  168 static int
  169 bsd_to_linux_speed(int speed, struct speedtab *table)
  170 {
  171     for ( ; table->sp_speed != -1; table++)
  172         if (table->sp_speed == speed)
  173             return (table->sp_code);
  174     return -1;
  175 }
  176 
  177 static void
  178 bsd_to_linux_termios(struct termios *bsd_termios, 
  179                 struct linux_termios *linux_termios)
  180 {
  181     int i;
  182 
  183 #ifdef DEBUG
  184     printf("LINUX: BSD termios structure (input):\n");
  185     printf("i=%08x o=%08x c=%08x l=%08x ispeed=%d ospeed=%d\n",
  186            bsd_termios->c_iflag, bsd_termios->c_oflag,
  187            bsd_termios->c_cflag, bsd_termios->c_lflag,
  188            bsd_termios->c_ispeed, bsd_termios->c_ospeed);
  189     printf("c_cc ");
  190     for (i=0; i<NCCS; i++)
  191         printf("%02x ", bsd_termios->c_cc[i]);
  192     printf("\n");
  193 #endif
  194     linux_termios->c_iflag = 0;
  195     if (bsd_termios->c_iflag & IGNBRK)
  196         linux_termios->c_iflag |= LINUX_IGNBRK;
  197     if (bsd_termios->c_iflag & BRKINT)
  198         linux_termios->c_iflag |= LINUX_BRKINT;
  199     if (bsd_termios->c_iflag & IGNPAR)
  200         linux_termios->c_iflag |= LINUX_IGNPAR;
  201     if (bsd_termios->c_iflag & PARMRK)
  202         linux_termios->c_iflag |= LINUX_PARMRK;
  203     if (bsd_termios->c_iflag & INPCK)
  204         linux_termios->c_iflag |= LINUX_INPCK;
  205     if (bsd_termios->c_iflag & ISTRIP)
  206         linux_termios->c_iflag |= LINUX_ISTRIP;
  207     if (bsd_termios->c_iflag & INLCR)
  208         linux_termios->c_iflag |= LINUX_INLCR;
  209     if (bsd_termios->c_iflag & IGNCR)
  210         linux_termios->c_iflag |= LINUX_IGNCR;
  211     if (bsd_termios->c_iflag & ICRNL)
  212         linux_termios->c_iflag |= LINUX_ICRNL;
  213     if (bsd_termios->c_iflag & IXON)
  214         linux_termios->c_iflag |= LINUX_IXON;
  215     if (bsd_termios->c_iflag & IXANY)
  216         linux_termios->c_iflag |= LINUX_IXANY;
  217     if (bsd_termios->c_iflag & IXOFF)
  218         linux_termios->c_iflag |= LINUX_IXOFF;
  219     if (bsd_termios->c_iflag & IMAXBEL)
  220         linux_termios->c_iflag |= LINUX_IMAXBEL;
  221 
  222     linux_termios->c_oflag = 0;
  223     if (bsd_termios->c_oflag & OPOST)
  224         linux_termios->c_oflag |= LINUX_OPOST;
  225     if (bsd_termios->c_oflag & ONLCR)
  226         linux_termios->c_oflag |= LINUX_ONLCR;
  227     if (bsd_termios->c_oflag & OXTABS)
  228         linux_termios->c_oflag |= LINUX_XTABS;
  229 
  230     linux_termios->c_cflag =
  231         bsd_to_linux_speed(bsd_termios->c_ispeed, sptab);
  232     linux_termios->c_cflag |= (bsd_termios->c_cflag & CSIZE) >> 4;
  233     if (bsd_termios->c_cflag & CSTOPB)
  234         linux_termios->c_cflag |= LINUX_CSTOPB;
  235     if (bsd_termios->c_cflag & CREAD)
  236         linux_termios->c_cflag |= LINUX_CREAD;
  237     if (bsd_termios->c_cflag & PARENB)
  238         linux_termios->c_cflag |= LINUX_PARENB;
  239     if (bsd_termios->c_cflag & PARODD)
  240         linux_termios->c_cflag |= LINUX_PARODD;
  241     if (bsd_termios->c_cflag & HUPCL)
  242         linux_termios->c_cflag |= LINUX_HUPCL;
  243     if (bsd_termios->c_cflag & CLOCAL)
  244         linux_termios->c_cflag |= LINUX_CLOCAL;
  245     if (bsd_termios->c_cflag & CRTSCTS)
  246         linux_termios->c_cflag |= LINUX_CRTSCTS;
  247 
  248     linux_termios->c_lflag = 0;
  249     if (bsd_termios->c_lflag & ISIG)
  250         linux_termios->c_lflag |= LINUX_ISIG;
  251     if (bsd_termios->c_lflag & ICANON)
  252         linux_termios->c_lflag |= LINUX_ICANON;
  253     if (bsd_termios->c_lflag & ECHO)
  254         linux_termios->c_lflag |= LINUX_ECHO;
  255     if (bsd_termios->c_lflag & ECHOE)
  256         linux_termios->c_lflag |= LINUX_ECHOE;
  257     if (bsd_termios->c_lflag & ECHOK)
  258         linux_termios->c_lflag |= LINUX_ECHOK;
  259     if (bsd_termios->c_lflag & ECHONL)
  260         linux_termios->c_lflag |= LINUX_ECHONL;
  261     if (bsd_termios->c_lflag & NOFLSH)
  262         linux_termios->c_lflag |= LINUX_NOFLSH;
  263     if (bsd_termios->c_lflag & TOSTOP)
  264         linux_termios->c_lflag |= LINUX_TOSTOP;
  265     if (bsd_termios->c_lflag & ECHOCTL)
  266         linux_termios->c_lflag |= LINUX_ECHOCTL;
  267     if (bsd_termios->c_lflag & ECHOPRT)
  268         linux_termios->c_lflag |= LINUX_ECHOPRT;
  269     if (bsd_termios->c_lflag & ECHOKE)
  270         linux_termios->c_lflag |= LINUX_ECHOKE;
  271     if (bsd_termios->c_lflag & FLUSHO)
  272         linux_termios->c_lflag |= LINUX_FLUSHO;
  273     if (bsd_termios->c_lflag & PENDIN)
  274         linux_termios->c_lflag |= LINUX_PENDIN;
  275     if (bsd_termios->c_lflag & IEXTEN)
  276         linux_termios->c_lflag |= LINUX_IEXTEN;
  277 
  278     for (i=0; i<LINUX_NCCS; i++) 
  279         linux_termios->c_cc[i] = LINUX_POSIX_VDISABLE;
  280     linux_termios->c_cc[LINUX_VINTR] = bsd_termios->c_cc[VINTR];
  281     linux_termios->c_cc[LINUX_VQUIT] = bsd_termios->c_cc[VQUIT];
  282     linux_termios->c_cc[LINUX_VERASE] = bsd_termios->c_cc[VERASE];
  283     linux_termios->c_cc[LINUX_VKILL] = bsd_termios->c_cc[VKILL];
  284     linux_termios->c_cc[LINUX_VEOF] = bsd_termios->c_cc[VEOF];
  285     linux_termios->c_cc[LINUX_VEOL] = bsd_termios->c_cc[VEOL];
  286     linux_termios->c_cc[LINUX_VMIN] = bsd_termios->c_cc[VMIN];
  287     linux_termios->c_cc[LINUX_VTIME] = bsd_termios->c_cc[VTIME];
  288     linux_termios->c_cc[LINUX_VEOL2] = bsd_termios->c_cc[VEOL2];
  289     linux_termios->c_cc[LINUX_VSUSP] = bsd_termios->c_cc[VSUSP];
  290     linux_termios->c_cc[LINUX_VSTART] = bsd_termios->c_cc[VSTART];
  291     linux_termios->c_cc[LINUX_VSTOP] = bsd_termios->c_cc[VSTOP];
  292     linux_termios->c_cc[LINUX_VREPRINT] = bsd_termios->c_cc[VREPRINT];
  293     linux_termios->c_cc[LINUX_VDISCARD] = bsd_termios->c_cc[VDISCARD];
  294     linux_termios->c_cc[LINUX_VWERASE] = bsd_termios->c_cc[VWERASE];
  295     linux_termios->c_cc[LINUX_VLNEXT] = bsd_termios->c_cc[VLNEXT];
  296 
  297     for (i=0; i<LINUX_NCCS; i++) {
  298       if (linux_termios->c_cc[i] == _POSIX_VDISABLE)
  299         linux_termios->c_cc[i] = LINUX_POSIX_VDISABLE;
  300     }
  301 
  302     linux_termios->c_line = 0;
  303 #ifdef DEBUG
  304     printf("LINUX: LINUX termios structure (output):\n");
  305     printf("i=%08lx o=%08lx c=%08lx l=%08lx line=%d\n",
  306         linux_termios->c_iflag, linux_termios->c_oflag, linux_termios->c_cflag,
  307         linux_termios->c_lflag, linux_termios->c_line);
  308     printf("c_cc ");
  309     for (i=0; i<LINUX_NCCS; i++) 
  310         printf("%02x ", linux_termios->c_cc[i]);
  311     printf("\n");
  312 #endif
  313 }
  314 
  315 
  316 static void
  317 linux_to_bsd_termios(struct linux_termios *linux_termios,
  318                 struct termios *bsd_termios)
  319 {
  320     int i;
  321 #ifdef DEBUG
  322     printf("LINUX: LINUX termios structure (input):\n");
  323     printf("i=%08lx o=%08lx c=%08lx l=%08lx line=%d\n",
  324         linux_termios->c_iflag, linux_termios->c_oflag, linux_termios->c_cflag,
  325         linux_termios->c_lflag, linux_termios->c_line);
  326     printf("c_cc ");
  327     for (i=0; i<LINUX_NCCS; i++) 
  328         printf("%02x ", linux_termios->c_cc[i]);
  329     printf("\n");
  330 #endif
  331     bsd_termios->c_iflag = 0;
  332     if (linux_termios->c_iflag & LINUX_IGNBRK)
  333         bsd_termios->c_iflag |= IGNBRK;
  334     if (linux_termios->c_iflag & LINUX_BRKINT)
  335         bsd_termios->c_iflag |= BRKINT;
  336     if (linux_termios->c_iflag & LINUX_IGNPAR)
  337         bsd_termios->c_iflag |= IGNPAR;
  338     if (linux_termios->c_iflag & LINUX_PARMRK)
  339         bsd_termios->c_iflag |= PARMRK;
  340     if (linux_termios->c_iflag & LINUX_INPCK)
  341         bsd_termios->c_iflag |= INPCK;
  342     if (linux_termios->c_iflag & LINUX_ISTRIP)
  343         bsd_termios->c_iflag |= ISTRIP;
  344     if (linux_termios->c_iflag & LINUX_INLCR)
  345         bsd_termios->c_iflag |= INLCR;
  346     if (linux_termios->c_iflag & LINUX_IGNCR)
  347         bsd_termios->c_iflag |= IGNCR;
  348     if (linux_termios->c_iflag & LINUX_ICRNL)
  349         bsd_termios->c_iflag |= ICRNL;
  350     if (linux_termios->c_iflag & LINUX_IXON)
  351         bsd_termios->c_iflag |= IXON;
  352     if (linux_termios->c_iflag & LINUX_IXANY)
  353         bsd_termios->c_iflag |= IXANY;
  354     if (linux_termios->c_iflag & LINUX_IXOFF)
  355         bsd_termios->c_iflag |= IXOFF;
  356     if (linux_termios->c_iflag & LINUX_IMAXBEL)
  357         bsd_termios->c_iflag |= IMAXBEL;
  358 
  359     bsd_termios->c_oflag = 0;
  360     if (linux_termios->c_oflag & LINUX_OPOST)
  361         bsd_termios->c_oflag |= OPOST;
  362     if (linux_termios->c_oflag & LINUX_ONLCR)
  363         bsd_termios->c_oflag |= ONLCR;
  364     if (linux_termios->c_oflag & LINUX_XTABS)
  365         bsd_termios->c_oflag |= OXTABS;
  366 
  367     bsd_termios->c_cflag = (linux_termios->c_cflag & LINUX_CSIZE) << 4;
  368     if (linux_termios->c_cflag & LINUX_CSTOPB)
  369         bsd_termios->c_cflag |= CSTOPB;
  370     if (linux_termios->c_cflag & LINUX_CREAD)
  371         bsd_termios->c_cflag |= CREAD;
  372     if (linux_termios->c_cflag & LINUX_PARENB)
  373         bsd_termios->c_cflag |= PARENB;
  374     if (linux_termios->c_cflag & LINUX_PARODD)
  375         bsd_termios->c_cflag |= PARODD;
  376     if (linux_termios->c_cflag & LINUX_HUPCL)
  377         bsd_termios->c_cflag |= HUPCL;
  378     if (linux_termios->c_cflag & LINUX_CLOCAL)
  379         bsd_termios->c_cflag |= CLOCAL;
  380     if (linux_termios->c_cflag & LINUX_CRTSCTS)
  381         bsd_termios->c_cflag |= CRTSCTS;
  382 
  383     bsd_termios->c_lflag = 0;
  384     if (linux_termios->c_lflag & LINUX_ISIG)
  385         bsd_termios->c_lflag |= ISIG;
  386     if (linux_termios->c_lflag & LINUX_ICANON)
  387         bsd_termios->c_lflag |= ICANON;
  388     if (linux_termios->c_lflag & LINUX_ECHO)
  389         bsd_termios->c_lflag |= ECHO;
  390     if (linux_termios->c_lflag & LINUX_ECHOE)
  391         bsd_termios->c_lflag |= ECHOE;
  392     if (linux_termios->c_lflag & LINUX_ECHOK)
  393         bsd_termios->c_lflag |= ECHOK;
  394     if (linux_termios->c_lflag & LINUX_ECHONL)
  395         bsd_termios->c_lflag |= ECHONL;
  396     if (linux_termios->c_lflag & LINUX_NOFLSH)
  397         bsd_termios->c_lflag |= NOFLSH;
  398     if (linux_termios->c_lflag & LINUX_TOSTOP)
  399         bsd_termios->c_lflag |= TOSTOP;
  400     if (linux_termios->c_lflag & LINUX_ECHOCTL)
  401         bsd_termios->c_lflag |= ECHOCTL;
  402     if (linux_termios->c_lflag & LINUX_ECHOPRT)
  403         bsd_termios->c_lflag |= ECHOPRT;
  404     if (linux_termios->c_lflag & LINUX_ECHOKE)
  405         bsd_termios->c_lflag |= ECHOKE;
  406     if (linux_termios->c_lflag & LINUX_FLUSHO)
  407         bsd_termios->c_lflag |= FLUSHO;
  408     if (linux_termios->c_lflag & LINUX_PENDIN)
  409         bsd_termios->c_lflag |= PENDIN;
  410     if (linux_termios->c_lflag & LINUX_IEXTEN)
  411         bsd_termios->c_lflag |= IEXTEN;
  412 
  413     for (i=0; i<NCCS; i++)
  414         bsd_termios->c_cc[i] = _POSIX_VDISABLE;
  415     bsd_termios->c_cc[VINTR] = linux_termios->c_cc[LINUX_VINTR];
  416     bsd_termios->c_cc[VQUIT] = linux_termios->c_cc[LINUX_VQUIT];
  417     bsd_termios->c_cc[VERASE] = linux_termios->c_cc[LINUX_VERASE];
  418     bsd_termios->c_cc[VKILL] = linux_termios->c_cc[LINUX_VKILL];
  419     bsd_termios->c_cc[VEOF] = linux_termios->c_cc[LINUX_VEOF];
  420     bsd_termios->c_cc[VEOL] = linux_termios->c_cc[LINUX_VEOL];
  421     bsd_termios->c_cc[VMIN] = linux_termios->c_cc[LINUX_VMIN];
  422     bsd_termios->c_cc[VTIME] = linux_termios->c_cc[LINUX_VTIME];
  423     bsd_termios->c_cc[VEOL2] = linux_termios->c_cc[LINUX_VEOL2];
  424     bsd_termios->c_cc[VSUSP] = linux_termios->c_cc[LINUX_VSUSP];
  425     bsd_termios->c_cc[VSTART] = linux_termios->c_cc[LINUX_VSTART];
  426     bsd_termios->c_cc[VSTOP] = linux_termios->c_cc[LINUX_VSTOP];
  427     bsd_termios->c_cc[VREPRINT] = linux_termios->c_cc[LINUX_VREPRINT];
  428     bsd_termios->c_cc[VDISCARD] = linux_termios->c_cc[LINUX_VDISCARD];
  429     bsd_termios->c_cc[VWERASE] = linux_termios->c_cc[LINUX_VWERASE];
  430     bsd_termios->c_cc[VLNEXT] = linux_termios->c_cc[LINUX_VLNEXT];
  431 
  432     for (i=0; i<NCCS; i++) {
  433       if (bsd_termios->c_cc[i] == LINUX_POSIX_VDISABLE)
  434         bsd_termios->c_cc[i] = _POSIX_VDISABLE;
  435     }
  436 
  437     bsd_termios->c_ispeed = bsd_termios->c_ospeed =
  438         linux_to_bsd_speed(linux_termios->c_cflag & LINUX_CBAUD, sptab);
  439 #ifdef DEBUG
  440         printf("LINUX: BSD termios structure (output):\n");
  441         printf("i=%08x o=%08x c=%08x l=%08x ispeed=%d ospeed=%d\n",
  442                bsd_termios->c_iflag, bsd_termios->c_oflag,
  443                bsd_termios->c_cflag, bsd_termios->c_lflag,
  444                bsd_termios->c_ispeed, bsd_termios->c_ospeed);
  445         printf("c_cc ");
  446         for (i=0; i<NCCS; i++) 
  447             printf("%02x ", bsd_termios->c_cc[i]);
  448         printf("\n");
  449 #endif
  450 }
  451 
  452 
  453 static void
  454 bsd_to_linux_termio(struct termios *bsd_termios, 
  455                 struct linux_termio *linux_termio)
  456 {
  457   struct linux_termios tmios;
  458 
  459   bsd_to_linux_termios(bsd_termios, &tmios);
  460   linux_termio->c_iflag = tmios.c_iflag;
  461   linux_termio->c_oflag = tmios.c_oflag;
  462   linux_termio->c_cflag = tmios.c_cflag;
  463   linux_termio->c_lflag = tmios.c_lflag;
  464   linux_termio->c_line  = tmios.c_line;
  465   memcpy(linux_termio->c_cc, tmios.c_cc, LINUX_NCC);
  466 }
  467 
  468 static void
  469 linux_to_bsd_termio(struct linux_termio *linux_termio,
  470                 struct termios *bsd_termios)
  471 {
  472   struct linux_termios tmios;
  473   int i;
  474 
  475   tmios.c_iflag = linux_termio->c_iflag;
  476   tmios.c_oflag = linux_termio->c_oflag;
  477   tmios.c_cflag = linux_termio->c_cflag;
  478   tmios.c_lflag = linux_termio->c_lflag;
  479 
  480   for (i=LINUX_NCC; i<LINUX_NCCS; i++)
  481     tmios.c_cc[i] = LINUX_POSIX_VDISABLE;
  482   memcpy(tmios.c_cc, linux_termio->c_cc, LINUX_NCC);
  483 
  484   linux_to_bsd_termios(&tmios, bsd_termios);
  485 }
  486 
  487 static void
  488 bsd_to_linux_msf_lba(u_char address_format,
  489     union msf_lba *bp, union linux_cdrom_addr *lp)
  490 {
  491     if (address_format == CD_LBA_FORMAT)
  492         lp->lba = bp->lba;
  493     else {
  494         lp->msf.minute = bp->msf.minute;
  495         lp->msf.second = bp->msf.second;
  496         lp->msf.frame = bp->msf.frame;
  497     }
  498 }
  499 
  500 static void
  501 set_linux_cdrom_addr(union linux_cdrom_addr *addr, int format, int lba)
  502 {
  503     if (format == LINUX_CDROM_MSF) {
  504         addr->msf.frame = lba % 75;
  505         lba /= 75;
  506         lba += 2;
  507         addr->msf.second = lba % 60;
  508         addr->msf.minute = lba / 60;
  509     }
  510     else
  511         addr->lba = lba;
  512 }
  513 
  514 static unsigned dirbits[4] = { IOC_VOID, IOC_IN, IOC_OUT, IOC_INOUT };
  515 
  516 #define SETDIR(c)       (((c) & ~IOC_DIRMASK) | dirbits[args->cmd >> 30])
  517 
  518 int
  519 linux_ioctl(struct proc *p, struct linux_ioctl_args *args)
  520 {
  521     struct termios bsd_termios;
  522     struct linux_termios linux_termios;
  523     struct linux_termio linux_termio;
  524     struct filedesc *fdp = p->p_fd;
  525     struct file *fp;
  526     int (*func)(struct file *fp, u_long com, caddr_t data, struct proc *p);
  527     int bsd_line, linux_line;
  528     int error;
  529 
  530 #ifdef DEBUG
  531     printf("Linux-emul(%ld): ioctl(%d, %04lx, *)\n", 
  532         (long)p->p_pid, args->fd, args->cmd);
  533 #endif
  534     if ((unsigned)args->fd >= fdp->fd_nfiles 
  535         || (fp = fdp->fd_ofiles[args->fd]) == 0)
  536         return EBADF;
  537 
  538     if (!fp || (fp->f_flag & (FREAD | FWRITE)) == 0) {
  539         return EBADF;
  540     }
  541 
  542     func = fp->f_ops->fo_ioctl;
  543     switch (args->cmd & 0xffff) {
  544 
  545     case LINUX_TCGETA:
  546         if ((error = (*func)(fp, TIOCGETA, (caddr_t)&bsd_termios, p)) != 0)
  547             return error;
  548         bsd_to_linux_termio(&bsd_termios, &linux_termio);
  549         return copyout((caddr_t)&linux_termio, (caddr_t)args->arg,
  550                        sizeof(linux_termio));
  551 
  552     case LINUX_TCSETA:
  553         error = copyin((caddr_t)args->arg, &linux_termio, sizeof(linux_termio));
  554         if (error)
  555             return error;
  556         linux_to_bsd_termio(&linux_termio, &bsd_termios);
  557         return (*func)(fp, TIOCSETA, (caddr_t)&bsd_termios, p);
  558 
  559     case LINUX_TCSETAW:
  560         error = copyin((caddr_t)args->arg, &linux_termio, sizeof(linux_termio));
  561         if (error)
  562             return error;
  563         linux_to_bsd_termio(&linux_termio, &bsd_termios);
  564         return (*func)(fp, TIOCSETAW, (caddr_t)&bsd_termios, p);
  565 
  566     case LINUX_TCSETAF:
  567         error = copyin((caddr_t)args->arg, &linux_termio, sizeof(linux_termio));
  568         if (error)
  569             return error;
  570         linux_to_bsd_termio(&linux_termio, &bsd_termios);
  571         return (*func)(fp, TIOCSETAF, (caddr_t)&bsd_termios, p);
  572 
  573     case LINUX_TCGETS:
  574         if ((error = (*func)(fp, TIOCGETA, (caddr_t)&bsd_termios, p)) != 0)
  575             return error;
  576         bsd_to_linux_termios(&bsd_termios, &linux_termios);
  577         return copyout((caddr_t)&linux_termios, (caddr_t)args->arg,
  578                        sizeof(linux_termios));
  579 
  580     case LINUX_TCSETS:
  581         error = copyin((caddr_t)args->arg, &linux_termios,
  582                        sizeof(linux_termios));
  583         if (error)
  584             return error;
  585         linux_to_bsd_termios(&linux_termios, &bsd_termios);
  586         return (*func)(fp, TIOCSETA, (caddr_t)&bsd_termios, p);
  587 
  588     case LINUX_TCSETSW:
  589         error = copyin((caddr_t)args->arg, &linux_termios,
  590                        sizeof(linux_termios));
  591         if (error)
  592             return error;
  593         linux_to_bsd_termios(&linux_termios, &bsd_termios);
  594         return (*func)(fp, TIOCSETAW, (caddr_t)&bsd_termios, p);
  595 
  596     case LINUX_TCSETSF:
  597         error = copyin((caddr_t)args->arg, &linux_termios,
  598                        sizeof(linux_termios));
  599         if (error)
  600             return error;
  601         linux_to_bsd_termios(&linux_termios, &bsd_termios);
  602         return (*func)(fp, TIOCSETAF, (caddr_t)&bsd_termios, p);
  603             
  604     case LINUX_TIOCGPGRP:
  605         args->cmd = TIOCGPGRP;
  606         return ioctl(p, (struct ioctl_args *)args);
  607 
  608     case LINUX_TIOCSPGRP:
  609         args->cmd = TIOCSPGRP;
  610         return ioctl(p, (struct ioctl_args *)args);
  611 
  612     case LINUX_TIOCGWINSZ:
  613         args->cmd = TIOCGWINSZ;
  614         return ioctl(p, (struct ioctl_args *)args);
  615 
  616     case LINUX_TIOCSWINSZ:
  617         args->cmd = TIOCSWINSZ;
  618         return ioctl(p, (struct ioctl_args *)args);
  619 
  620     case LINUX_TIOCMGET:
  621         args->cmd = TIOCMGET;
  622         return ioctl(p, (struct ioctl_args *)args);
  623 
  624     case LINUX_TIOCMBIS:
  625         args->cmd = TIOCMBIS;
  626         return ioctl(p, (struct ioctl_args *)args);
  627 
  628     case LINUX_TIOCMBIC:
  629         args->cmd = TIOCMBIC;
  630         return ioctl(p, (struct ioctl_args *)args);
  631 
  632     case LINUX_TIOCMSET:
  633         args->cmd = TIOCMSET;
  634         return ioctl(p, (struct ioctl_args *)args);
  635 
  636     case LINUX_FIONREAD:
  637         args->cmd = FIONREAD;
  638         return ioctl(p, (struct ioctl_args *)args);
  639 
  640     case LINUX_FIONBIO:
  641         args->cmd = FIONBIO;
  642         return ioctl(p, (struct ioctl_args *)args);
  643 
  644     case LINUX_FIOASYNC:
  645         args->cmd = FIOASYNC;
  646         return ioctl(p, (struct ioctl_args *)args);
  647 
  648     case LINUX_FIONCLEX:
  649         args->cmd = FIONCLEX;
  650         return ioctl(p, (struct ioctl_args *)args);
  651 
  652     case LINUX_FIOCLEX:
  653         args->cmd = FIOCLEX;
  654         return ioctl(p, (struct ioctl_args *)args);
  655 
  656     case LINUX_TIOCEXCL:
  657         args->cmd = TIOCEXCL;
  658         return ioctl(p, (struct ioctl_args *)args);
  659 
  660     case LINUX_TIOCNXCL:
  661         args->cmd = TIOCNXCL;
  662         return ioctl(p, (struct ioctl_args *)args);
  663 
  664     case LINUX_TIOCCONS:
  665         args->cmd = TIOCCONS;
  666         return ioctl(p, (struct ioctl_args *)args);
  667 
  668     case LINUX_TIOCNOTTY:
  669         args->cmd = TIOCNOTTY;
  670         return ioctl(p, (struct ioctl_args *)args);
  671 
  672     case LINUX_SIOCGIFCONF:
  673         args->cmd = OSIOCGIFCONF;
  674         return ioctl(p, (struct ioctl_args *)args);
  675 
  676     case LINUX_SIOCGIFFLAGS:
  677         args->cmd = SIOCGIFFLAGS;
  678         return ioctl(p, (struct ioctl_args *)args);
  679 
  680     case LINUX_SIOCGIFADDR:
  681         args->cmd = OSIOCGIFADDR;
  682         return ioctl(p, (struct ioctl_args *)args);
  683 
  684     case LINUX_SIOCGIFDSTADDR:
  685         args->cmd = OSIOCGIFDSTADDR;
  686         return ioctl(p, (struct ioctl_args *)args);
  687 
  688     case LINUX_SIOCGIFBRDADDR:
  689         args->cmd = OSIOCGIFBRDADDR;
  690         return ioctl(p, (struct ioctl_args *)args);
  691 
  692     case LINUX_SIOCGIFNETMASK:
  693         args->cmd = OSIOCGIFNETMASK;
  694         return ioctl(p, (struct ioctl_args *)args);
  695 
  696         /* get hardware address */
  697     case LINUX_SIOCGIFHWADDR:
  698     {
  699         int                     ifn;
  700         struct ifnet            *ifp;
  701         struct ifaddr           *ifa;
  702         struct sockaddr_dl      *sdl;
  703         struct linux_ifreq      *ifr = (struct linux_ifreq *)args->arg;
  704 
  705         /* 
  706          * Note that we don't actually respect the name in the ifreq structure, as
  707          * Linux interface names are all different
  708          */
  709 
  710         for (ifn = 0; ifn < if_index; ifn++) {
  711 
  712             ifp = ifnet_addrs[ifn]->ifa_ifp;    /* pointer to interface */
  713             if (ifp->if_type == IFT_ETHER) {    /* looks good */
  714                 /* walk the address list */
  715                 for (ifa = TAILQ_FIRST(&ifp->if_addrhead); ifa; ifa = TAILQ_NEXT(ifa, ifa_link)) {
  716                     if ((sdl = (struct sockaddr_dl *)ifa->ifa_addr) &&  /* we have an address structure */
  717                         (sdl->sdl_family == AF_LINK) &&                 /* it's a link address */
  718                         (sdl->sdl_type == IFT_ETHER)) {                 /* for an ethernet link */
  719 
  720                         return(copyout(LLADDR(sdl), (caddr_t)&ifr->ifr_hwaddr.sa_data, LINUX_IFHWADDRLEN));
  721                     }
  722                 }
  723             }
  724         }
  725         return(ENOENT);         /* ??? */
  726     }
  727 
  728     case LINUX_SIOCADDMULTI:
  729         args->cmd = SIOCADDMULTI;
  730         return ioctl(p, (struct ioctl_args *)args);
  731 
  732     case LINUX_SIOCDELMULTI:
  733         args->cmd = SIOCDELMULTI;
  734         return ioctl(p, (struct ioctl_args *)args);
  735 
  736     case LINUX_FIOSETOWN:
  737         args->cmd = FIOSETOWN;
  738         return ioctl(p, (struct ioctl_args *)args);
  739 
  740     case LINUX_SIOCSPGRP:
  741         args->cmd = SIOCSPGRP;
  742         return ioctl(p, (struct ioctl_args *)args);
  743 
  744     case LINUX_FIOGETOWN:
  745         args->cmd = FIOGETOWN;
  746         return ioctl(p, (struct ioctl_args *)args);
  747 
  748     case LINUX_SIOCGPGRP:
  749         args->cmd = SIOCGPGRP;
  750         return ioctl(p, (struct ioctl_args *)args);
  751 
  752     case LINUX_SIOCATMARK:
  753         args->cmd = SIOCATMARK;
  754         return ioctl(p, (struct ioctl_args *)args);
  755 
  756     case LINUX_TIOCSETD:
  757         switch (args->arg) {
  758         case LINUX_N_TTY:
  759             bsd_line = TTYDISC;
  760             return (*func)(fp, TIOCSETD, (caddr_t)&bsd_line, p);
  761         case LINUX_N_SLIP:
  762             bsd_line = SLIPDISC;
  763             return (*func)(fp, TIOCSETD, (caddr_t)&bsd_line, p);
  764         case LINUX_N_PPP:
  765             bsd_line = PPPDISC;
  766             return (*func)(fp, TIOCSETD, (caddr_t)&bsd_line, p);
  767         default:
  768             return EINVAL;
  769         }
  770 
  771     case LINUX_TIOCGETD:
  772         bsd_line = TTYDISC;
  773         if (error =(*func)(fp, TIOCGETD, (caddr_t)&bsd_line, p))
  774             return error;
  775         switch (bsd_line) {
  776         case TTYDISC:
  777             linux_line = LINUX_N_TTY;
  778             break;
  779         case SLIPDISC:
  780             linux_line = LINUX_N_SLIP;
  781             break;
  782         case PPPDISC:
  783             linux_line = LINUX_N_PPP;
  784             break;
  785         default:
  786             return EINVAL;
  787         }
  788         return copyout(&linux_line, (caddr_t)args->arg, 
  789                        sizeof(int));
  790 
  791     case LINUX_SNDCTL_SEQ_RESET:
  792         args->cmd = SNDCTL_SEQ_RESET;
  793         return ioctl(p, (struct ioctl_args *)args);
  794 
  795     case LINUX_SNDCTL_SEQ_SYNC:
  796         args->cmd = SNDCTL_SEQ_SYNC;
  797         return ioctl(p, (struct ioctl_args *)args);
  798 
  799     case LINUX_SNDCTL_SYNTH_INFO:
  800         args->cmd = SNDCTL_SYNTH_INFO;
  801         return ioctl(p, (struct ioctl_args *)args);
  802 
  803     case LINUX_SNDCTL_SEQ_CTRLRATE:
  804         args->cmd = SNDCTL_SEQ_CTRLRATE;
  805         return ioctl(p, (struct ioctl_args *)args);
  806 
  807     case LINUX_SNDCTL_SEQ_GETOUTCOUNT:
  808         args->cmd = SNDCTL_SEQ_GETOUTCOUNT;
  809         return ioctl(p, (struct ioctl_args *)args);
  810 
  811     case LINUX_SNDCTL_SEQ_GETINCOUNT:
  812         args->cmd = SNDCTL_SEQ_GETINCOUNT;
  813         return ioctl(p, (struct ioctl_args *)args);
  814 
  815     case LINUX_SNDCTL_SEQ_PERCMODE:
  816         args->cmd = SNDCTL_SEQ_PERCMODE;
  817         return ioctl(p, (struct ioctl_args *)args);
  818 
  819     case LINUX_SNDCTL_FM_LOAD_INSTR:
  820         args->cmd = SNDCTL_FM_LOAD_INSTR;
  821         return ioctl(p, (struct ioctl_args *)args);
  822 
  823     case LINUX_SNDCTL_SEQ_TESTMIDI:
  824         args->cmd = SNDCTL_SEQ_TESTMIDI;
  825         return ioctl(p, (struct ioctl_args *)args);
  826 
  827     case LINUX_SNDCTL_SEQ_RESETSAMPLES:
  828         args->cmd = SNDCTL_SEQ_RESETSAMPLES;
  829         return ioctl(p, (struct ioctl_args *)args);
  830 
  831     case LINUX_SNDCTL_SEQ_NRSYNTHS:
  832         args->cmd = SNDCTL_SEQ_NRSYNTHS;
  833         return ioctl(p, (struct ioctl_args *)args);
  834 
  835     case LINUX_SNDCTL_SEQ_NRMIDIS:
  836         args->cmd = SNDCTL_SEQ_NRMIDIS;
  837         return ioctl(p, (struct ioctl_args *)args);
  838 
  839     case LINUX_SNDCTL_MIDI_INFO:
  840         args->cmd = SNDCTL_MIDI_INFO;
  841         return ioctl(p, (struct ioctl_args *)args);
  842 
  843     case LINUX_SNDCTL_SEQ_TRESHOLD:
  844         args->cmd = SNDCTL_SEQ_TRESHOLD;
  845         return ioctl(p, (struct ioctl_args *)args);
  846 
  847     case LINUX_SNDCTL_SYNTH_MEMAVL:
  848         args->cmd = SNDCTL_SYNTH_MEMAVL;
  849         return ioctl(p, (struct ioctl_args *)args);
  850 
  851     case LINUX_SNDCTL_DSP_GETOPTR :
  852         args->cmd = SNDCTL_DSP_GETOPTR;
  853         return ioctl(p, (struct ioctl_args *)args);
  854 
  855     case LINUX_SNDCTL_DSP_GETIPTR :
  856         args->cmd = SNDCTL_DSP_GETIPTR;
  857         return ioctl(p, (struct ioctl_args *)args);
  858 
  859     case LINUX_SNDCTL_DSP_SETTRIGGER:
  860         args->cmd = SNDCTL_DSP_SETTRIGGER;
  861         return ioctl(p, (struct ioctl_args *)args);
  862 
  863     case LINUX_SNDCTL_DSP_GETCAPS:
  864         args->cmd = SNDCTL_DSP_GETCAPS;
  865         return ioctl(p, (struct ioctl_args *)args);
  866 
  867     case LINUX_SNDCTL_DSP_RESET:
  868         args->cmd = SNDCTL_DSP_RESET;
  869         return ioctl(p, (struct ioctl_args *)args);
  870 
  871     case LINUX_SNDCTL_DSP_SYNC:
  872         args->cmd = SNDCTL_DSP_SYNC;
  873         return ioctl(p, (struct ioctl_args *)args);
  874 
  875     case LINUX_SNDCTL_DSP_SPEED:
  876         args->cmd = SNDCTL_DSP_SPEED;
  877         return ioctl(p, (struct ioctl_args *)args);
  878 
  879     case LINUX_SNDCTL_DSP_STEREO:
  880         args->cmd = SNDCTL_DSP_STEREO;
  881         return ioctl(p, (struct ioctl_args *)args);
  882 
  883     case LINUX_SNDCTL_DSP_GETBLKSIZE:
  884       /* LINUX_SNDCTL_DSP_SETBLKSIZE */
  885         args->cmd = SNDCTL_DSP_GETBLKSIZE;
  886         return ioctl(p, (struct ioctl_args *)args);
  887 
  888     case LINUX_SNDCTL_DSP_GETODELAY:
  889         args->cmd = SNDCTL_DSP_GETODELAY;
  890         return ioctl(p, (struct ioctl_args *)args);
  891 
  892     case LINUX_SNDCTL_DSP_SETFMT:
  893         args->cmd = SNDCTL_DSP_SETFMT;
  894         return ioctl(p, (struct ioctl_args *)args);
  895 
  896     case LINUX_SOUND_PCM_WRITE_CHANNELS:
  897         args->cmd = SOUND_PCM_WRITE_CHANNELS;
  898         return ioctl(p, (struct ioctl_args *)args);
  899 
  900     case LINUX_SOUND_PCM_WRITE_FILTER:
  901         args->cmd = SOUND_PCM_WRITE_FILTER;
  902         return ioctl(p, (struct ioctl_args *)args);
  903 
  904     case LINUX_SNDCTL_DSP_POST:
  905         args->cmd = SNDCTL_DSP_POST;
  906         return ioctl(p, (struct ioctl_args *)args);
  907 
  908     case LINUX_SNDCTL_DSP_SUBDIVIDE:
  909         args->cmd = SNDCTL_DSP_SUBDIVIDE;
  910         return ioctl(p, (struct ioctl_args *)args);
  911 
  912     case LINUX_SNDCTL_DSP_SETFRAGMENT:
  913         args->cmd = SNDCTL_DSP_SETFRAGMENT;
  914         return ioctl(p, (struct ioctl_args *)args);
  915 
  916     case LINUX_SNDCTL_DSP_GETFMTS:
  917         args->cmd = SNDCTL_DSP_GETFMTS;
  918         return ioctl(p, (struct ioctl_args *)args);
  919 
  920     case LINUX_SNDCTL_DSP_GETOSPACE:
  921         args->cmd = SNDCTL_DSP_GETOSPACE;
  922         return ioctl(p, (struct ioctl_args *)args);
  923 
  924     case LINUX_SNDCTL_DSP_GETISPACE:
  925         args->cmd = SNDCTL_DSP_GETISPACE;
  926         return ioctl(p, (struct ioctl_args *)args);
  927 
  928     case LINUX_SNDCTL_DSP_NONBLOCK:
  929         args->cmd = SNDCTL_DSP_NONBLOCK;
  930         return ioctl(p, (struct ioctl_args *)args);
  931 
  932     case LINUX_SOUND_MIXER_WRITE_VOLUME:
  933         args->cmd = SETDIR(SOUND_MIXER_WRITE_VOLUME);
  934         return ioctl(p, (struct ioctl_args *)args);
  935 
  936     case LINUX_SOUND_MIXER_WRITE_BASS:
  937         args->cmd = SETDIR(SOUND_MIXER_WRITE_BASS);
  938         return ioctl(p, (struct ioctl_args *)args);
  939 
  940     case LINUX_SOUND_MIXER_WRITE_TREBLE:
  941         args->cmd = SETDIR(SOUND_MIXER_WRITE_TREBLE);
  942         return ioctl(p, (struct ioctl_args *)args);
  943 
  944     case LINUX_SOUND_MIXER_WRITE_SYNTH:
  945         args->cmd = SETDIR(SOUND_MIXER_WRITE_SYNTH);
  946         return ioctl(p, (struct ioctl_args *)args);
  947 
  948     case LINUX_SOUND_MIXER_WRITE_PCM:
  949         args->cmd = SETDIR(SOUND_MIXER_WRITE_PCM);
  950         return ioctl(p, (struct ioctl_args *)args);
  951 
  952     case LINUX_SOUND_MIXER_WRITE_SPEAKER:
  953         args->cmd = SETDIR(SOUND_MIXER_WRITE_SPEAKER);
  954         return ioctl(p, (struct ioctl_args *)args);
  955 
  956     case LINUX_SOUND_MIXER_WRITE_LINE:
  957         args->cmd = SETDIR(SOUND_MIXER_WRITE_LINE);
  958         return ioctl(p, (struct ioctl_args *)args);
  959 
  960     case LINUX_SOUND_MIXER_WRITE_MIC:
  961         args->cmd = SETDIR(SOUND_MIXER_WRITE_MIC);
  962         return ioctl(p, (struct ioctl_args *)args);
  963 
  964     case LINUX_SOUND_MIXER_WRITE_CD:
  965         args->cmd = SETDIR(SOUND_MIXER_WRITE_CD);
  966         return ioctl(p, (struct ioctl_args *)args);
  967 
  968     case LINUX_SOUND_MIXER_WRITE_IMIX:
  969         args->cmd = SETDIR(SOUND_MIXER_WRITE_IMIX);
  970         return ioctl(p, (struct ioctl_args *)args);
  971 
  972     case LINUX_SOUND_MIXER_WRITE_ALTPCM:
  973         args->cmd = SETDIR(SOUND_MIXER_WRITE_ALTPCM);
  974         return ioctl(p, (struct ioctl_args *)args);
  975 
  976     case LINUX_SOUND_MIXER_WRITE_RECLEV:
  977         args->cmd = SETDIR(SOUND_MIXER_WRITE_RECLEV);
  978         return ioctl(p, (struct ioctl_args *)args);
  979 
  980     case LINUX_SOUND_MIXER_WRITE_IGAIN:
  981         args->cmd = SETDIR(SOUND_MIXER_WRITE_IGAIN);
  982         return ioctl(p, (struct ioctl_args *)args);
  983 
  984     case LINUX_SOUND_MIXER_WRITE_OGAIN:
  985         args->cmd = SETDIR(SOUND_MIXER_WRITE_OGAIN);
  986         return ioctl(p, (struct ioctl_args *)args);
  987 
  988     case LINUX_SOUND_MIXER_WRITE_LINE1:
  989         args->cmd = SETDIR(SOUND_MIXER_WRITE_LINE1);
  990         return ioctl(p, (struct ioctl_args *)args);
  991 
  992     case LINUX_SOUND_MIXER_WRITE_LINE2:
  993         args->cmd = SETDIR(SOUND_MIXER_WRITE_LINE2);
  994         return ioctl(p, (struct ioctl_args *)args);
  995 
  996     case LINUX_SOUND_MIXER_WRITE_LINE3:
  997         args->cmd = SETDIR(SOUND_MIXER_WRITE_LINE3);
  998         return ioctl(p, (struct ioctl_args *)args);
  999 
 1000     case LINUX_SOUND_MIXER_READ_DEVMASK:
 1001         args->cmd = SOUND_MIXER_READ_DEVMASK;
 1002         return ioctl(p, (struct ioctl_args *)args);
 1003 
 1004     case LINUX_TIOCGSERIAL: {
 1005         struct linux_serial_struct lss;
 1006 
 1007         lss.type = LINUX_PORT_16550A;
 1008         lss.flags = 0;
 1009         lss.close_delay = 0;
 1010         return copyout((caddr_t)&lss, (caddr_t)args->arg, sizeof(lss));
 1011     }
 1012 
 1013     case LINUX_TIOCSSERIAL: {
 1014         struct linux_serial_struct lss;
 1015 
 1016         error = copyin((caddr_t)args->arg, (caddr_t)&lss, sizeof(lss));
 1017         if (error)
 1018             return error;
 1019         /*
 1020          * XXX - It really helps to have an implementation that does nothing.
 1021          *       NOT!
 1022          */
 1023         return 0;
 1024     }
 1025 
 1026     case LINUX_TCXONC:
 1027         switch (args->arg) {
 1028         case LINUX_TCOOFF:
 1029             args->cmd = TIOCSTOP;
 1030             break;
 1031         case LINUX_TCOON:
 1032             args->cmd = TIOCSTART;
 1033             break;
 1034         case LINUX_TCIOFF:
 1035         case LINUX_TCION: {
 1036             u_char c;
 1037             struct write_args wr;
 1038             error = (*func)(fp, TIOCGETA, (caddr_t)&bsd_termios, p);
 1039             if (error != 0)
 1040                 return error;
 1041             c = bsd_termios.c_cc[args->arg == LINUX_TCIOFF ? VSTOP : VSTART];
 1042             if (c != _POSIX_VDISABLE) {
 1043                 wr.fd = args->fd;
 1044                 wr.buf = &c;
 1045                 wr.nbyte = sizeof(c);
 1046                 return write(p, &wr);
 1047             }
 1048             else
 1049                 return (0);
 1050         }
 1051         default:
 1052             return EINVAL;
 1053         }
 1054         args->arg = 0;
 1055         return ioctl(p, (struct ioctl_args *)args);
 1056 
 1057     case LINUX_TCFLSH:
 1058       args->cmd = TIOCFLUSH;
 1059       switch (args->arg) {
 1060         case LINUX_TCIFLUSH:
 1061                 args->arg = FREAD;
 1062                 break;
 1063         case LINUX_TCOFLUSH:
 1064                 args->arg = FWRITE;
 1065                 break;
 1066         case LINUX_TCIOFLUSH:
 1067                 args->arg = FREAD | FWRITE;
 1068                 break;
 1069         default:
 1070                 return EINVAL;
 1071       }
 1072       return ioctl(p, (struct ioctl_args *)args);
 1073 
 1074    case LINUX_VT_OPENQRY:
 1075 
 1076         args->cmd = VT_OPENQRY;
 1077         return  ioctl(p, (struct ioctl_args *)args);
 1078 
 1079     case LINUX_VT_GETMODE:
 1080 
 1081         args->cmd = VT_GETMODE;
 1082         return  ioctl(p, (struct ioctl_args *)args);
 1083 
 1084     case LINUX_VT_RELDISP:
 1085 
 1086         args->cmd = VT_RELDISP;
 1087         return  ioctl(p, (struct ioctl_args *)args);
 1088 
 1089     case LINUX_VT_SETMODE: 
 1090       {
 1091         struct vt_mode *mode;
 1092         args->cmd = VT_SETMODE;
 1093         mode = (struct vt_mode *)args->arg;
 1094         if (!ISSIGVALID(mode->frsig) && ISSIGVALID(mode->acqsig))
 1095             mode->frsig = mode->acqsig;
 1096         return ioctl(p, (struct ioctl_args *)args);
 1097       }
 1098 
 1099     case LINUX_VT_GETSTATE:
 1100 
 1101         args->cmd = VT_GETACTIVE;
 1102         return  ioctl(p, (struct ioctl_args *)args);
 1103 
 1104     case LINUX_VT_ACTIVATE:
 1105 
 1106         args->cmd = VT_ACTIVATE;
 1107         return  ioctl(p, (struct ioctl_args *)args);
 1108 
 1109     case LINUX_VT_WAITACTIVE:
 1110 
 1111         args->cmd = VT_WAITACTIVE;
 1112         return  ioctl(p, (struct ioctl_args *)args);
 1113 
 1114     case LINUX_KDGKBMODE:
 1115 
 1116         args->cmd = KDGKBMODE;
 1117         return ioctl(p, (struct ioctl_args *)args);
 1118 
 1119     case LINUX_KDSKBMODE:
 1120       {
 1121         int kbdmode;
 1122         switch (args->arg) {
 1123         case LINUX_KBD_RAW:
 1124             kbdmode = K_RAW;
 1125             return (*func)(fp, KDSKBMODE, (caddr_t)&kbdmode, p);
 1126         case LINUX_KBD_XLATE:  
 1127             kbdmode = K_XLATE;
 1128             return (*func)(fp, KDSKBMODE , (caddr_t)&kbdmode, p);
 1129         case LINUX_KBD_MEDIUMRAW:
 1130             kbdmode = K_RAW;
 1131             return (*func)(fp, KDSKBMODE , (caddr_t)&kbdmode, p);
 1132         default:
 1133             return EINVAL;
 1134         }
 1135       }
 1136 
 1137     case LINUX_KDGETMODE:
 1138         args->cmd = KDGETMODE;
 1139         return  ioctl(p, (struct ioctl_args *)args);
 1140 
 1141     case LINUX_KDSETMODE:
 1142         args->cmd = KDSETMODE;
 1143         return  ioctl(p, (struct ioctl_args *)args);
 1144 
 1145     case LINUX_KDSETLED:
 1146         args->cmd = KDSETLED;
 1147         return  ioctl(p, (struct ioctl_args *)args);
 1148 
 1149     case LINUX_KDGETLED:
 1150         args->cmd = KDGETLED;
 1151         return  ioctl(p, (struct ioctl_args *)args);
 1152 
 1153     case LINUX_KIOCSOUND:
 1154         args->cmd = KIOCSOUND;
 1155         return  ioctl(p, (struct ioctl_args *)args);
 1156 
 1157     case LINUX_KDMKTONE:
 1158         args->cmd = KDMKTONE;
 1159         return  ioctl(p, (struct ioctl_args *)args);
 1160 
 1161 
 1162     case LINUX_CDROMPAUSE:
 1163         args->cmd = CDIOCPAUSE;
 1164         return  ioctl(p, (struct ioctl_args *)args);
 1165 
 1166     case LINUX_CDROMRESUME:
 1167         args->cmd = CDIOCRESUME;
 1168         return  ioctl(p, (struct ioctl_args *)args);
 1169 
 1170     case LINUX_CDROMPLAYMSF:
 1171         args->cmd = CDIOCPLAYMSF;
 1172         return  ioctl(p, (struct ioctl_args *)args);
 1173 
 1174     case LINUX_CDROMPLAYTRKIND:
 1175         args->cmd = CDIOCPLAYTRACKS;
 1176         return  ioctl(p, (struct ioctl_args *)args);
 1177 
 1178     case LINUX_CDROMSTART:
 1179         args->cmd = CDIOCSTART;
 1180         return  ioctl(p, (struct ioctl_args *)args);
 1181 
 1182     case LINUX_CDROMSTOP:
 1183         args->cmd = CDIOCSTOP;
 1184         return  ioctl(p, (struct ioctl_args *)args);
 1185 
 1186     case LINUX_CDROMEJECT:
 1187         args->cmd = CDIOCEJECT;
 1188         return  ioctl(p, (struct ioctl_args *)args);
 1189 
 1190     case LINUX_CDROMRESET:
 1191         args->cmd = CDIOCRESET;
 1192         return  ioctl(p, (struct ioctl_args *)args);
 1193 
 1194     case LINUX_CDROMREADTOCHDR: {
 1195         struct ioc_toc_header th;
 1196         struct linux_cdrom_tochdr lth;
 1197         error = (*func)(fp, CDIOREADTOCHEADER, (caddr_t)&th, p);
 1198         if (!error) {
 1199             lth.cdth_trk0 = th.starting_track;
 1200             lth.cdth_trk1 = th.ending_track;
 1201             copyout((caddr_t)&lth, (caddr_t)args->arg, sizeof(lth));
 1202         }
 1203         return error;
 1204     }
 1205 
 1206     case LINUX_CDROMREADTOCENTRY: {
 1207         struct linux_cdrom_tocentry lte, *ltep =
 1208             (struct linux_cdrom_tocentry *)args->arg;
 1209         struct ioc_read_toc_single_entry irtse;
 1210         irtse.address_format = ltep->cdte_format;
 1211         irtse.track = ltep->cdte_track;
 1212         error = (*func)(fp, CDIOREADTOCENTRY, (caddr_t)&irtse, p);
 1213         if (!error) {
 1214             lte = *ltep;
 1215             lte.cdte_ctrl = irtse.entry.control;
 1216             lte.cdte_adr = irtse.entry.addr_type;
 1217             bsd_to_linux_msf_lba(irtse.address_format,
 1218                 &irtse.entry.addr, &lte.cdte_addr);
 1219             copyout((caddr_t)&lte, (caddr_t)args->arg, sizeof(lte));
 1220         }
 1221         return error;
 1222     }
 1223 
 1224     case LINUX_CDROMSUBCHNL: {
 1225         caddr_t sg;
 1226         struct linux_cdrom_subchnl sc;
 1227         struct ioc_read_subchannel bsdsc;
 1228         struct cd_sub_channel_info *bsdinfo;
 1229 
 1230         sg = stackgap_init();
 1231         bsdinfo = (struct cd_sub_channel_info*)stackgap_alloc(&sg,
 1232                                 sizeof(struct cd_sub_channel_info));
 1233 
 1234         bsdsc.address_format = CD_LBA_FORMAT;
 1235         bsdsc.data_format = CD_CURRENT_POSITION;
 1236         bsdsc.data_len = sizeof(struct cd_sub_channel_info);
 1237         bsdsc.data = bsdinfo;
 1238         error = (*func)(fp, CDIOCREADSUBCHANNEL, (caddr_t)&bsdsc, p);
 1239         if (error)
 1240             return error;
 1241 
 1242         error = copyin((caddr_t)args->arg, (caddr_t)&sc,
 1243                        sizeof(struct linux_cdrom_subchnl));
 1244         if (error)
 1245             return error;
 1246 
 1247         sc.cdsc_audiostatus = bsdinfo->header.audio_status;
 1248         sc.cdsc_adr = bsdinfo->what.position.addr_type;
 1249         sc.cdsc_ctrl = bsdinfo->what.position.control;
 1250         sc.cdsc_trk = bsdinfo->what.position.track_number;
 1251         sc.cdsc_ind = bsdinfo->what.position.index_number;
 1252         set_linux_cdrom_addr(&sc.cdsc_absaddr, sc.cdsc_format,
 1253                              bsdinfo->what.position.absaddr.lba);
 1254         set_linux_cdrom_addr(&sc.cdsc_reladdr, sc.cdsc_format,
 1255                              bsdinfo->what.position.reladdr.lba);
 1256         error = copyout((caddr_t)&sc, (caddr_t)args->arg,
 1257                         sizeof(struct linux_cdrom_subchnl));
 1258         return error;
 1259     }
 1260 
 1261     }
 1262 
 1263     uprintf("LINUX: 'ioctl' fd=%d, typ=0x%x(%c), num=0x%x not implemented\n",
 1264         args->fd, (u_int)((args->cmd & 0xffff00) >> 8),
 1265         (int)((args->cmd & 0xffff00) >> 8), (u_int)(args->cmd & 0xff));
 1266     return EINVAL;
 1267 }

Cache object: 639e9c5e329f08b87d26f5bf0558a27f


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.