From owner-freebsd-multimedia Mon Jun 14 18:49:46 1999 Delivered-To: freebsd-multimedia@freebsd.org Received: from bilby.prth.tensor.pgs.com (bilby.prth.tensor.pgs.com [157.147.232.237]) by hub.freebsd.org (Postfix) with ESMTP id E643114C47; Mon, 14 Jun 1999 18:48:46 -0700 (PDT) (envelope-from shocking@ariadne.prth.tensor.pgs.com) Received: from bandicoot.prth.tensor.pgs.com (bandicoot.prth.tensor.pgs.com [157.147.224.1]) by bilby.prth.tensor.pgs.com (8.9.3/8.8.8) with ESMTP id JAA21358; Tue, 15 Jun 1999 09:47:42 +0800 (WST) Received: from ariadne.tensor.pgs.com (ariadne [157.147.227.36]) by bandicoot.prth.tensor.pgs.com (8.9.3/8.8.8) with SMTP id JAA07246; Tue, 15 Jun 1999 09:48:41 +0800 (WST) Received: from ariadne by ariadne.tensor.pgs.com (SMI-8.6/SMI-SVR4) id JAA09202; Tue, 15 Jun 1999 09:48:40 +0800 Message-Id: <199906150148.JAA09202@ariadne.tensor.pgs.com> X-Mailer: exmh version 2.0.2 2/24/98 To: current@freebsd.org, multimedia@freebsd.org Subject: Voodoo device driver for current enclosed (2nd try!) Mime-Version: 1.0 Content-Type: text/plain; charset=iso-8859-1 Content-Transfer-Encoding: quoted-printable Date: Tue, 15 Jun 1999 09:48:40 +0800 From: Stephen Hocking-Senior Programmer PGS Tensor Perth Sender: owner-freebsd-multimedia@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.org Find herein the files that make up my so far unsuccessful attempt to writ= e a voodoo device driver. It was translated wholesale from Daryl Strauss's driver for Linux, although I've messed up something along the way. At the= moment, it will lock up the machine hard shortly after mmaping the card's= memory. I'm about to go on holidays for a week, so I thought I'd throw th= is out for you all to take a look at and hopefully find out what I've done wrong. In order to use it you will have to add to /sys/i386/conf/files.i386 the following line - pci/voodoo.c optional voodoo device-driver And then to your machine config file device voodoo0 # I hope this works.... You'll have to cut'n'paste the files into the appropriate directories (la= st time I sent a uuencoded tar file, but that hasn't appeared yet), config y= our kernel and recompile & reinstall your linux emulator module. You will als= o have to have the appropriate version of glide for your card (note that the dri= ver doesn't as yet support the voodoo3 series, although this would be trivial= to add), and a copy of the glide SDK. I've been using the little test progra= ms that come with the SDK. I apologise for the humungous size of this meesag= e, but I have nowhere I can put it up for public ftp. ------- CUT HERE --- /sys/pci/voodoo.c ---------- /* * Copyright ME * * voodoo driver * $Id: make_device_driver.sh,v 1.0 Tue Aug 18 14:09:07 EST 1998 crb Exp = $" */ #include "pci.h" #if NPCI >0 #include "opt_devfs.h" #include "voodoo.h" /* generated file.. * defines NVOODOO */ #include #include #include /* SYSINIT stuff */ #include /* cdevsw stuff */ #include #include #include /* malloc region * definitions */ #include /* DELAY() */ #include #include #include #include #include #include /* NCPI definitions */ #include /* pci variables etc. */ #include /* pci register * definitions etc. */ #include /* voodoo IOCTL * definitions */ #ifdef DEVFS #include /* DEVFS defintitions */ #endif /* DEVFS */ #ifndef _IOC_DIR #define _IOC_DIR(x) (x & IOC_DIRMASK) #endif #define VENDOR_3DFX 0x121a #define VENDOR_ALLIANCE 0x1142 #define ID_VOODOO1 1 #define ID_VOODOO2 2 #define ID_AT3D 0x643d #define VOODOO1 ((ID_VOODOO1 << 16) | VENDOR_3DFX) #define VOODOO2 ((ID_VOODOO2 << 16) | VENDOR_3DFX) #define RUSH ((ID_AT3D << 16) | VENDOR_ALLIANCE) #define PCI_VENDOR_ID_FREEBSD 0x0 #define PCI_DEVICE_ID_FREEBSD 0x2 #define PCI_COMMAND_FREEBSD 0x4 #define PCI_REVISION_ID_FREEBSD 0x8 #define PCI_BASE_ADDRESS_0_FREEBSD 0x10 #define SST1_PCI_SPECIAL1_FREEBSD 0x40 #define SST1_PCI_SPECIAL2_FREEBSD 0x44 #define SST1_PCI_SPECIAL3_FREEBSD 0x48 #define SST1_PCI_SPECIAL4_FREEBSD 0x54 #define VGA_INPUT_STATUS_1C 0x3DA #define VGA_MISC_OUTPUT_READ 0x3cc #define VGA_MISC_OUTPUT_WRITE 0x3c2 #define SC_INDEX 0x3c4 #define SC_DATA 0x3c5 /* Function prototypes (these should all be static except for voodoointr(= )) */ static d_open_t voodooopen; static d_close_t voodooclose; static d_ioctl_t voodooioctl; static d_mmap_t voodoommap; static char *voodooprobe(pcici_t tag, pcidi_t type); static void voodooattach(pcici_t tag, int unit); static u_long voodoocount; typedef struct pioData_t { short port; short size; int device; void *value; } pioData; typedef struct cardInfo_t { pcici_t tag; vm_offset_t virbase, physbase; int vendor; pcidi_t type; int addr; struct file *curFile; } cardInfo; #define MAXCARDS 16 cardInfo cards[MAXCARDS]; static int numCards=3D0; #define CDEV_MAJOR 107 static struct cdevsw voodoo_cdevsw =3D { voodooopen, voodooclose, noread, nowrite, voodooioctl, NULL, noreset, nodevtotty, nopoll, voodoommap, nostrategy, "voodoo", noparms, CDEV_MAJOR, nodump, nopsize, 0, 0, -1 }; static struct pci_device voodoo_device =3D { "voodoo", voodooprobe, voodooattach, &voodoocount, NULL }; /* The DATA_SET macro includes the pci device in the set of pci devices * that will be probed at config time. */ #ifdef COMPAT_PCI_DRIVER COMPAT_PCI_DRIVER (voodoo, voodoo_device); #else DATA_SET(pcidevice_set, voodoo_device); #endif #define UNIT(dev) minor(dev) /* assume one minor * number per unit */ /* * One of these per allocated device */ struct voodoo_softc { #ifdef DEVFS static void *devfs_token; #endif }; typedef struct voodoo_softc *sc_p; static sc_p sca[NVOODOO]; /* this function should discriminate if this device is * or is not handled by this driver, often this will be * as simple as testing the pci id of the device */ static void storeCard(pcici_t tag, pcidi_t type, char *name) { cards[numCards].tag =3D tag; cards[numCards].type =3D (type & 0xffff0000) >> 16; cards[numCards].vendor =3D type & 0xffff; pci_map_mem(tag, PCI_MAP_REG_START, & cards[numCards].virbase, &cards[n= umCards].physbase); cards[numCards].physbase &=3D ~0xF; /* cards[numCards].physbase =3D (pci_cfgread(tag, PCIR_MAPS, 4) & ~0xF= );*/ printf("%s has mem at phys 0x%lx, vir 0x%lx type 0x%x, vendor 0x%x\n", name, cards[numCards].physbase, cards[numCards].virbase, = cards[numCards].type, cards[numCards].vendor); /* Read configuration here */ numCards++; } static char * voodooprobe(pcici_t tag, pcidi_t type) { char *board_type =3D (char *)0; switch (type) { case VOODOO1: board_type =3D "3DFX Voodoo 1"; storeCard(tag, type, board_type); break; case VOODOO2: board_type =3D "3DFX Voodoo 2"; storeCard(tag, type, board_type); break; case RUSH: board_type =3D "AT3D Rush"; storeCard(tag, type, board_type); break; }; return board_type; } /* * Called if the probe succeeded. */ static void voodooattach(pcici_t tag, int unit) { sc_p scp =3D sca[unit]; /* Allocate storage for this instance . */ scp =3D malloc(sizeof(*scp), M_DEVBUF, M_NOWAIT); if (scp =3D=3D NULL) { uprintf("voodoo%d failed to allocate driver storage\n", unit); return; } bzero(scp, sizeof(*scp)); sca[unit] =3D scp; /* Store whatever seems wise. */ #if DEVFS scp->devfs_token =3D devfs_add_devswf(&voodoo_cdevsw, unit, DV_CHR, UID_ROOT, GID_KMEM, 0600, "3dfx%d", unit); #endif /* Set up video mem addresses and port i/o addresses. */ } /* * Macro to check that the unit number is valid * Often this isn't needed as once the open() is performed, * the unit number is pretty much safe.. The exception would be if we * implemented devices that could "go away". in which case all these rout= ines * would be wise to check the number, DIAGNOSTIC or not. */ #define CHECKUNIT(RETVAL) \ do { /* the do-while is a safe way to do this grouping */ \ if (unit > NVOODOO) { \ uprintf(__FUNCTION__ ":bad unit %d \n", unit); \ return (RETVAL); \ } \ if (scp =3D=3D NULL) { \ uprintf( __FUNCTION__ ": unit %d not attached\n", unit); \ return (RETVAL); \ } \ } while (0) #ifdef DIAGNOSTIC #define CHECKUNIT_DIAG(RETVAL) CHECKUNIT(RETVAL) #else /* DIAGNOSTIC */ #define CHECKUNIT_DIAG(RETVAL) #endif /* DIAGNOSTIC */ static int doQueryBoards(void) { /* printf("Called doQueryBoards %d\n", numCards); */ return numCards; } static int doQueryFetch(pioData *desc) { char retchar; short retword; int retlong; /* printf("Called doQueryFetch\n"); */ if (desc->device<0 || desc->device>=3DnumCards) return EINVAL; switch (desc->port) { case PCI_VENDOR_ID_FREEBSD: if (desc->size!=3D2) return EINVAL; copyout(&cards[desc->device].vendor, desc->value, desc->size); return 0; case PCI_DEVICE_ID_FREEBSD: if (desc->size!=3D2) return EINVAL; copyout(&cards[desc->device].type, desc->value, desc->size); return 0; case PCI_BASE_ADDRESS_0_FREEBSD: if (desc->size!=3D4) return EINVAL; copyout(&cards[desc->device].addr, desc->value, desc->size); return 0; case SST1_PCI_SPECIAL1_FREEBSD: if (desc->size!=3D4) return EINVAL; break; case PCI_REVISION_ID_FREEBSD: if (desc->size!=3D1) return EINVAL; break; case SST1_PCI_SPECIAL4_FREEBSD: if (desc->size!=3D4) return EINVAL; break; default: return EINVAL; } switch (desc->size) { case 1: retchar =3D pci_cfgread(cards[desc->device].tag, desc->port, 1); copyout(&retchar, desc->value, 1); break; case 2: retword =3D pci_cfgread(cards[desc->device].tag, desc->port, 2); copyout(&retword, desc->value, 2); break; case 4: retlong =3D pci_cfgread(cards[desc->device].tag, desc->port, 4); copyout(&retlong, desc->value, 4); break; default: return EINVAL; } return 0; } static int doQueryUpdate(pioData *desc) { int retval; int preval; int mask; char retchar; short retword; int retlong; printf("Called doQueryUpdate\n"); if (desc->device<0 || desc->device>=3DnumCards) return EINVAL; switch (desc->port) { case PCI_COMMAND_FREEBSD: if (desc->size!=3D2) return EINVAL; break; case SST1_PCI_SPECIAL1_FREEBSD: if (desc->size!=3D4) return EINVAL; break; case SST1_PCI_SPECIAL2_FREEBSD: if (desc->size!=3D4) return EINVAL; break; case SST1_PCI_SPECIAL3_FREEBSD: if (desc->size!=3D4) return EINVAL; break; case SST1_PCI_SPECIAL4_FREEBSD: if (desc->size!=3D4) return EINVAL; break; default: return EINVAL; } retval =3D pci_cfgread(cards[desc->device].tag, desc->port & ~0x3, 4); switch (desc->size) { case 1: copyin(desc->value, &retchar, 1); preval=3Dretchar<<(8*(desc->port&0x3)); mask=3D0xFF<<(8*(desc->port&0x3)); break; case 2: copyin(desc->value, &retword, 2); preval=3Dretword<<(8*(desc->port&0x3)); mask=3D0xFFFF<<(8*(desc->port&0x3)); break; case 4: copyin(desc->value, &retlong, 4); preval=3Dretlong; mask=3D~0; break; default: return EINVAL; } retval =3D (retval & ~mask) | preval; printf("Updating port %d with 0x%x\n", desc->port, retval); pci_cfgwrite(cards[desc->device].tag, desc->port, retval, 4); return 0; } static int doQuery(unsigned int cmd, pioData *desc) { /* printf("Called doQuery\n"); */ if (_IOC_NR(cmd)=3D=3D2) return doQueryBoards(); if (_IOC_NR(cmd)=3D=3D3) return doQueryFetch(desc); if (_IOC_NR(cmd)=3D=3D4) return doQueryUpdate(desc); return EINVAL; } static int doPIORead(pioData *desc) { char retchar; short retword; int retlong; printf("called doPIORead\n"); switch (desc->port) { case VGA_INPUT_STATUS_1C: break; case SC_INDEX: break; case SC_DATA: break; case VGA_MISC_OUTPUT_READ: break; default: return EPERM; } if (desc->size!=3D1) { return EINVAL; } switch (desc->size) { case 1: retchar=3Dinb(desc->port); copyout(&retchar, desc->value, sizeof(char)); break; case 2: retword=3Dinw(desc->port); copyout(&retword, desc->value, sizeof(short)); break; case 4: retlong=3Dinl(desc->port); copyout(&retlong, desc->value, sizeof(int)); break; default: return EINVAL; } return 0; } static int doPIOWrite(pioData *desc) { char retchar; short retword; int retlong; printf("Called doPIOWrite\n"); switch (desc->port) { case SC_INDEX: break; case SC_DATA: break; case VGA_MISC_OUTPUT_WRITE: break; default: return EPERM; } if (desc->size!=3D1) { return EINVAL; } switch (desc->size) { case 1: copyin(desc->value, &retchar, sizeof(char)); outb(desc->port, retchar); break; case 2: copyin(desc->value, &retword, sizeof(short)); outw(desc->port, retword); break; case 4: copyin(desc->value, &retlong, sizeof(int)); outl(desc->port, retlong); break; default: return EINVAL; } return 0; } static int doPIO(unsigned int cmd, pioData *desc) { printf("Called doPIO\n"); if (_IOC_DIR(cmd)=3D=3DIOCV_OUT) return doPIORead(desc); if (_IOC_DIR(cmd)=3D=3DIOCV_IN) return doPIOWrite(desc); return EINVAL; } static int = voodooioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc * = p) { int unit =3D UNIT(dev); sc_p scp =3D sca[unit]; pioData *desc =3D data; CHECKUNIT_DIAG(ENXIO); /* printf("Hey, somebody ioctl'd me with %x at %x!!\n", cmd, data); if (data !=3D NULL) printf("desc->device %d, desc->port %d, desc->s= ize %d desc->value 0x%x\n", desc->device, desc->port, desc->size, desc->value); */ switch (_IOC_TYPE(cmd)) { case '3': return doQuery(cmd, desc); break; case 0: return doPIO(cmd, desc); break; default: printf("And I didn't like it!\n"); return ENXIO; } return (0); } /* * You also need read, write, open, close routines. * This should get you started */ static int voodooopen(dev_t dev, int oflags, int devtype, struct proc * p) { int unit =3D UNIT(dev); sc_p scp =3D sca[unit]; printf("Voodoo opened!\n"); CHECKUNIT(ENXIO); /* Do processing */ return (0); } static int voodooclose(dev_t dev, int fflag, int devtype, struct proc * p) { int unit =3D UNIT(dev); sc_p scp =3D sca[unit]; CHECKUNIT_DIAG(ENXIO); /* Do processing */ return (0); } static int voodoommap(dev_t dev, vm_offset_t offset, int nprot) { int unit =3D UNIT(dev), i; sc_p scp =3D sca[unit]; CHECKUNIT_DIAG(-1); printf("Someone trying to mmap me on unit %d..\n", unit); /* Do processing */ if (offset >=3D 0x1000000) = return (-1); return (i386_btop(cards[unit].physbase + offset)); } /* * Now for some driver initialization. There are basically 2 options * here you can either use the drvinit function for initialization that * needs to occur before any probing is done, or keep state in a global * you can use in the probe routine to see if probe is being called for * the fist time, and do your initalization there. */ static void voodoo_drvinit(void *unused) { dev_t dev; dev =3D makedev(CDEV_MAJOR, 0); cdevsw_add(&voodoo_cdevsw); } SYSINIT(voodoodev, SI_SUB_DRIVERS, SI_ORDER_MIDDLE + CDEV_MAJOR, voodoo_drvinit, NULL) #endif /* NPCI */ ------------ CUT HERE -------- /sys/sys/voodooio.h ------------- /* * Definitions needed to access the voodoo device (ioctls etc) * see mtio.h , ioctl.h as examples */ #ifndef SYS_DHIO_H #define SYS_DHIO_H #ifndef KERNEL #include #endif /* #include */ /* * define an ioctl here */ #define DHIOCRESET _IO('D', 0) /* reset the voodoo device */ #define GETVOODOO 0x3302 #define SETVOODOO 0x3303 #define MOREVOODOO 0x3300 #define _IOC_NRBITS 8 #define _IOC_TYPEBITS 8 #define _IOC_SIZEBITS 14 #define _IOC_DIRBITS 2 #define _IOC_NRMASK ((1 << _IOC_NRBITS)-1) #define _IOC_TYPEMASK ((1 << _IOC_TYPEBITS)-1) #define _IOC_SIZEMASK ((1 << _IOC_SIZEBITS)-1) #define _IOC_DIRMASK ((1 << _IOC_DIRBITS)-1) #define _IOC_NRSHIFT 0 #define _IOC_TYPESHIFT (_IOC_NRSHIFT+_IOC_NRBITS) #define _IOC_SIZESHIFT (_IOC_TYPESHIFT+_IOC_TYPEBITS) #define _IOC_DIRSHIFT (_IOC_SIZESHIFT+_IOC_SIZEBITS) /* * Direction bits. */ #define _IOC_NONE 0U #define _IOC_WRITE 1U #define _IOC_READ 2U #define _IOCV(dir,type,nr,size) \ (((dir) << _IOC_DIRSHIFT) | \ ((type) << _IOC_TYPESHIFT) | \ ((nr) << _IOC_NRSHIFT) | \ ((size) << _IOC_SIZESHIFT)) /* used to create numbers */ #define _IOV(type,nr) _IOCV(_IOC_NONE,(type),(nr),0) #define _IORV(type,nr,size) _IOCV(_IOC_READ,(type),(nr),sizeof(size)) #define _IOWV(type,nr,size) _IOCV(_IOC_WRITE,(type),(nr),sizeof(size)) #define _IOWRV(type,nr,size) _IOCV(_IOC_READ|_IOC_WRITE,(type),(nr),sizeo= f(size)) /* used to decode ioctl numbers.. */ #define _IOC_DIR(nr) (((nr) >> _IOC_DIRSHIFT) & _IOC_DIRMASK) #define _IOC_TYPE(nr) (((nr) >> _IOC_TYPESHIFT) & _IOC_TYPEMASK) #define _IOC_NR(nr) (((nr) >> _IOC_NRSHIFT) & _IOC_NRMASK) #define _IOC_SIZE(nr) (((nr) >> _IOC_SIZESHIFT) & _IOC_SIZEMASK) /* ...and for the drivers/sound files... */ #define IOCV_IN (_IOC_WRITE << _IOC_DIRSHIFT) #define IOCV_OUT (_IOC_READ << _IOC_DIRSHIFT) #define IOCV_INOUT ((_IOC_WRITE|_IOC_READ) << _IOC_DIRSHIFT) #define IOCSIZE_MASK (_IOC_SIZEMASK << _IOC_SIZESHIFT) #define IOCSIZE_SHIFT (_IOC_SIZESHIFT) #endif ----------------- CUT HERE ---------- /sys/i386/linux/linux_ioctl.c -----= --- /* * Copyright (c) 1994-1995 S=F8ren Schmidt * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer * in this position and unchanged. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the= * documentation and/or other materials provided with the distribution= =2E * 3. The name of the author may not be used to endorse or promote produc= ts * derived from this software withough specific prior written permissi= on * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANT= IES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED= =2E * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, B= UT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF U= SE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE = OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * $Id: linux_ioctl.c,v 1.33 1999/05/09 16:04:04 peter Exp $ */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define ISSIGVALID(sig) ((sig) > 0 && (sig) < NSIG) struct linux_termio { unsigned short c_iflag; unsigned short c_oflag; unsigned short c_cflag; unsigned short c_lflag; unsigned char c_line; unsigned char c_cc[LINUX_NCC]; }; struct linux_termios { unsigned long c_iflag; unsigned long c_oflag; unsigned long c_cflag; unsigned long c_lflag; unsigned char c_line; unsigned char c_cc[LINUX_NCCS]; }; struct linux_winsize { unsigned short ws_row, ws_col; unsigned short ws_xpixel, ws_ypixel; }; static struct speedtab sptab[] =3D { { 0, 0 }, { 50, 1 }, { 75, 2 }, { 110, 3 }, { 134, 4 }, { 135, 4 }, { 150, 5 }, { 200, 6 }, { 300, 7 }, { 600, 8 }, { 1200, 9 }, { 1800, 10 }, { 2400, 11 }, { 4800, 12 }, { 9600, 13 }, { 19200, 14 }, { 38400, 15 }, = { 57600, 4097 }, { 115200, 4098 }, {-1, -1 } }; struct linux_serial_struct { int type; int line; int port; int irq; int flags; int xmit_fifo_size; int custom_divisor; int baud_base; unsigned short close_delay; char reserved_char[2]; int hub6; unsigned short closing_wait; unsigned short closing_wait2; int reserved[4]; }; static int linux_to_bsd_speed(int code, struct speedtab *table) { for ( ; table->sp_code !=3D -1; table++) if (table->sp_code =3D=3D code) return (table->sp_speed); return -1; } static int bsd_to_linux_speed(int speed, struct speedtab *table) { for ( ; table->sp_speed !=3D -1; table++) if (table->sp_speed =3D=3D speed) return (table->sp_code); return -1; } static void bsd_to_linux_termios(struct termios *bsd_termios, = struct linux_termios *linux_termios) { int i; #ifdef DEBUG printf("LINUX: BSD termios structure (input):\n"); printf("i=3D%08x o=3D%08x c=3D%08x l=3D%08x ispeed=3D%d ospeed=3D%d\n= ", bsd_termios->c_iflag, bsd_termios->c_oflag, bsd_termios->c_cflag, bsd_termios->c_lflag, bsd_termios->c_ispeed, bsd_termios->c_ospeed); printf("c_cc "); for (i=3D0; ic_cc[i]); printf("\n"); #endif linux_termios->c_iflag =3D 0; if (bsd_termios->c_iflag & IGNBRK) linux_termios->c_iflag |=3D LINUX_IGNBRK; if (bsd_termios->c_iflag & BRKINT) linux_termios->c_iflag |=3D LINUX_BRKINT; if (bsd_termios->c_iflag & IGNPAR) linux_termios->c_iflag |=3D LINUX_IGNPAR; if (bsd_termios->c_iflag & PARMRK) linux_termios->c_iflag |=3D LINUX_PARMRK; if (bsd_termios->c_iflag & INPCK) linux_termios->c_iflag |=3D LINUX_INPCK; if (bsd_termios->c_iflag & ISTRIP) linux_termios->c_iflag |=3D LINUX_ISTRIP; if (bsd_termios->c_iflag & INLCR) linux_termios->c_iflag |=3D LINUX_INLCR; if (bsd_termios->c_iflag & IGNCR) linux_termios->c_iflag |=3D LINUX_IGNCR; if (bsd_termios->c_iflag & ICRNL) linux_termios->c_iflag |=3D LINUX_ICRNL; if (bsd_termios->c_iflag & IXON) linux_termios->c_iflag |=3D LINUX_IXANY; if (bsd_termios->c_iflag & IXON) linux_termios->c_iflag |=3D LINUX_IXON; if (bsd_termios->c_iflag & IXOFF) linux_termios->c_iflag |=3D LINUX_IXOFF; if (bsd_termios->c_iflag & IMAXBEL) linux_termios->c_iflag |=3D LINUX_IMAXBEL; linux_termios->c_oflag =3D 0; if (bsd_termios->c_oflag & OPOST) linux_termios->c_oflag |=3D LINUX_OPOST; if (bsd_termios->c_oflag & ONLCR) linux_termios->c_oflag |=3D LINUX_ONLCR; if (bsd_termios->c_oflag & OXTABS) linux_termios->c_oflag |=3D LINUX_XTABS; linux_termios->c_cflag =3D bsd_to_linux_speed(bsd_termios->c_ispeed, sptab); linux_termios->c_cflag |=3D (bsd_termios->c_cflag & CSIZE) >> 4; if (bsd_termios->c_cflag & CSTOPB) linux_termios->c_cflag |=3D LINUX_CSTOPB; if (bsd_termios->c_cflag & CREAD) linux_termios->c_cflag |=3D LINUX_CREAD; if (bsd_termios->c_cflag & PARENB) linux_termios->c_cflag |=3D LINUX_PARENB; if (bsd_termios->c_cflag & PARODD) linux_termios->c_cflag |=3D LINUX_PARODD; if (bsd_termios->c_cflag & HUPCL) linux_termios->c_cflag |=3D LINUX_HUPCL; if (bsd_termios->c_cflag & CLOCAL) linux_termios->c_cflag |=3D LINUX_CLOCAL; if (bsd_termios->c_cflag & CRTSCTS) linux_termios->c_cflag |=3D LINUX_CRTSCTS; linux_termios->c_lflag =3D 0; if (bsd_termios->c_lflag & ISIG) linux_termios->c_lflag |=3D LINUX_ISIG; if (bsd_termios->c_lflag & ICANON) linux_termios->c_lflag |=3D LINUX_ICANON; if (bsd_termios->c_lflag & ECHO) linux_termios->c_lflag |=3D LINUX_ECHO; if (bsd_termios->c_lflag & ECHOE) linux_termios->c_lflag |=3D LINUX_ECHOE; if (bsd_termios->c_lflag & ECHOK) linux_termios->c_lflag |=3D LINUX_ECHOK; if (bsd_termios->c_lflag & ECHONL) linux_termios->c_lflag |=3D LINUX_ECHONL; if (bsd_termios->c_lflag & NOFLSH) linux_termios->c_lflag |=3D LINUX_NOFLSH; if (bsd_termios->c_lflag & TOSTOP) linux_termios->c_lflag |=3D LINUX_TOSTOP; if (bsd_termios->c_lflag & ECHOCTL) linux_termios->c_lflag |=3D LINUX_ECHOCTL; if (bsd_termios->c_lflag & ECHOPRT) linux_termios->c_lflag |=3D LINUX_ECHOPRT; if (bsd_termios->c_lflag & ECHOKE) linux_termios->c_lflag |=3D LINUX_ECHOKE; if (bsd_termios->c_lflag & FLUSHO) linux_termios->c_lflag |=3D LINUX_FLUSHO; if (bsd_termios->c_lflag & PENDIN) linux_termios->c_lflag |=3D LINUX_PENDIN; if (bsd_termios->c_lflag & IEXTEN) linux_termios->c_lflag |=3D LINUX_IEXTEN; for (i=3D0; ic_cc[i] =3D LINUX_POSIX_VDISABLE; linux_termios->c_cc[LINUX_VINTR] =3D bsd_termios->c_cc[VINTR]; linux_termios->c_cc[LINUX_VQUIT] =3D bsd_termios->c_cc[VQUIT]; linux_termios->c_cc[LINUX_VERASE] =3D bsd_termios->c_cc[VERASE]; linux_termios->c_cc[LINUX_VKILL] =3D bsd_termios->c_cc[VKILL]; linux_termios->c_cc[LINUX_VEOF] =3D bsd_termios->c_cc[VEOF]; linux_termios->c_cc[LINUX_VEOL] =3D bsd_termios->c_cc[VEOL]; linux_termios->c_cc[LINUX_VMIN] =3D bsd_termios->c_cc[VMIN]; linux_termios->c_cc[LINUX_VTIME] =3D bsd_termios->c_cc[VTIME]; linux_termios->c_cc[LINUX_VEOL2] =3D bsd_termios->c_cc[VEOL2]; linux_termios->c_cc[LINUX_VSWTC] =3D _POSIX_VDISABLE; linux_termios->c_cc[LINUX_VSUSP] =3D bsd_termios->c_cc[VSUSP]; linux_termios->c_cc[LINUX_VSTART] =3D bsd_termios->c_cc[VSTART]; linux_termios->c_cc[LINUX_VSTOP] =3D bsd_termios->c_cc[VSTOP]; linux_termios->c_cc[LINUX_VREPRINT] =3D bsd_termios->c_cc[VREPRINT]; linux_termios->c_cc[LINUX_VDISCARD] =3D bsd_termios->c_cc[VDISCARD]; linux_termios->c_cc[LINUX_VWERASE] =3D bsd_termios->c_cc[VWERASE]; linux_termios->c_cc[LINUX_VLNEXT] =3D bsd_termios->c_cc[VLNEXT]; for (i=3D0; ic_cc[i] =3D=3D _POSIX_VDISABLE) linux_termios->c_cc[i] =3D LINUX_POSIX_VDISABLE; } linux_termios->c_line =3D 0; #ifdef DEBUG printf("LINUX: LINUX termios structure (output):\n"); printf("i=3D%08lx o=3D%08lx c=3D%08lx l=3D%08lx line=3D%d\n", linux_termios->c_iflag, linux_termios->c_oflag, linux_termios->c_cflag, linux_termios->c_lflag, linux_termios->c_line); printf("c_cc "); for (i=3D0; ic_cc[i]); printf("\n"); #endif } static void linux_to_bsd_termios(struct linux_termios *linux_termios, struct termios *bsd_termios) { int i; #ifdef DEBUG printf("LINUX: LINUX termios structure (input):\n"); printf("i=3D%08lx o=3D%08lx c=3D%08lx l=3D%08lx line=3D%d\n", linux_termios->c_iflag, linux_termios->c_oflag, linux_termios->c_cflag, linux_termios->c_lflag, linux_termios->c_line); printf("c_cc "); for (i=3D0; ic_cc[i]); printf("\n"); #endif bsd_termios->c_iflag =3D 0; if (linux_termios->c_iflag & LINUX_IGNBRK) bsd_termios->c_iflag |=3D IGNBRK; if (linux_termios->c_iflag & LINUX_BRKINT) bsd_termios->c_iflag |=3D BRKINT; if (linux_termios->c_iflag & LINUX_IGNPAR) bsd_termios->c_iflag |=3D IGNPAR; if (linux_termios->c_iflag & LINUX_PARMRK) bsd_termios->c_iflag |=3D PARMRK; if (linux_termios->c_iflag & LINUX_INPCK) bsd_termios->c_iflag |=3D INPCK; if (linux_termios->c_iflag & LINUX_ISTRIP) bsd_termios->c_iflag |=3D ISTRIP; if (linux_termios->c_iflag & LINUX_INLCR) bsd_termios->c_iflag |=3D INLCR; if (linux_termios->c_iflag & LINUX_IGNCR) bsd_termios->c_iflag |=3D IGNCR; if (linux_termios->c_iflag & LINUX_ICRNL) bsd_termios->c_iflag |=3D ICRNL; if (linux_termios->c_iflag & LINUX_IXON) bsd_termios->c_iflag |=3D IXANY; if (linux_termios->c_iflag & LINUX_IXON) bsd_termios->c_iflag |=3D IXON; if (linux_termios->c_iflag & LINUX_IXOFF) bsd_termios->c_iflag |=3D IXOFF; if (linux_termios->c_iflag & LINUX_IMAXBEL) bsd_termios->c_iflag |=3D IMAXBEL; bsd_termios->c_oflag =3D 0; if (linux_termios->c_oflag & LINUX_OPOST) bsd_termios->c_oflag |=3D OPOST; if (linux_termios->c_oflag & LINUX_ONLCR) bsd_termios->c_oflag |=3D ONLCR; if (linux_termios->c_oflag & LINUX_XTABS) bsd_termios->c_oflag |=3D OXTABS; bsd_termios->c_cflag =3D (linux_termios->c_cflag & LINUX_CSIZE) << 4;= if (linux_termios->c_cflag & LINUX_CSTOPB) bsd_termios->c_cflag |=3D CSTOPB; if (linux_termios->c_cflag & LINUX_PARENB) bsd_termios->c_cflag |=3D PARENB; if (linux_termios->c_cflag & LINUX_PARODD) bsd_termios->c_cflag |=3D PARODD; if (linux_termios->c_cflag & LINUX_HUPCL) bsd_termios->c_cflag |=3D HUPCL; if (linux_termios->c_cflag & LINUX_CLOCAL) bsd_termios->c_cflag |=3D CLOCAL; if (linux_termios->c_cflag & LINUX_CRTSCTS) bsd_termios->c_cflag |=3D CRTSCTS; bsd_termios->c_lflag =3D 0; if (linux_termios->c_lflag & LINUX_ISIG) bsd_termios->c_lflag |=3D ISIG; if (linux_termios->c_lflag & LINUX_ICANON) bsd_termios->c_lflag |=3D ICANON; if (linux_termios->c_lflag & LINUX_ECHO) bsd_termios->c_lflag |=3D ECHO; if (linux_termios->c_lflag & LINUX_ECHOE) bsd_termios->c_lflag |=3D ECHOE; if (linux_termios->c_lflag & LINUX_ECHOK) bsd_termios->c_lflag |=3D ECHOK; if (linux_termios->c_lflag & LINUX_ECHONL) bsd_termios->c_lflag |=3D ECHONL; if (linux_termios->c_lflag & LINUX_NOFLSH) bsd_termios->c_lflag |=3D NOFLSH; if (linux_termios->c_lflag & LINUX_TOSTOP) bsd_termios->c_lflag |=3D TOSTOP; if (linux_termios->c_lflag & LINUX_ECHOCTL) bsd_termios->c_lflag |=3D ECHOCTL; if (linux_termios->c_lflag & LINUX_ECHOPRT) bsd_termios->c_lflag |=3D ECHOPRT; if (linux_termios->c_lflag & LINUX_ECHOKE) bsd_termios->c_lflag |=3D ECHOKE; if (linux_termios->c_lflag & LINUX_FLUSHO) bsd_termios->c_lflag |=3D FLUSHO; if (linux_termios->c_lflag & LINUX_PENDIN) bsd_termios->c_lflag |=3D PENDIN; if (linux_termios->c_lflag & IEXTEN) bsd_termios->c_lflag |=3D IEXTEN; for (i=3D0; ic_cc[i] =3D _POSIX_VDISABLE; bsd_termios->c_cc[VINTR] =3D linux_termios->c_cc[LINUX_VINTR]; bsd_termios->c_cc[VQUIT] =3D linux_termios->c_cc[LINUX_VQUIT]; bsd_termios->c_cc[VERASE] =3D linux_termios->c_cc[LINUX_VERASE]; bsd_termios->c_cc[VKILL] =3D linux_termios->c_cc[LINUX_VKILL]; bsd_termios->c_cc[VEOF] =3D linux_termios->c_cc[LINUX_VEOF]; bsd_termios->c_cc[VEOL] =3D linux_termios->c_cc[LINUX_VEOL]; bsd_termios->c_cc[VMIN] =3D linux_termios->c_cc[LINUX_VMIN]; bsd_termios->c_cc[VTIME] =3D linux_termios->c_cc[LINUX_VTIME]; bsd_termios->c_cc[VEOL2] =3D linux_termios->c_cc[LINUX_VEOL2]; bsd_termios->c_cc[VSUSP] =3D linux_termios->c_cc[LINUX_VSUSP]; bsd_termios->c_cc[VSTART] =3D linux_termios->c_cc[LINUX_VSTART]; bsd_termios->c_cc[VSTOP] =3D linux_termios->c_cc[LINUX_VSTOP]; bsd_termios->c_cc[VREPRINT] =3D linux_termios->c_cc[LINUX_VREPRINT]; bsd_termios->c_cc[VDISCARD] =3D linux_termios->c_cc[LINUX_VDISCARD]; bsd_termios->c_cc[VWERASE] =3D linux_termios->c_cc[LINUX_VWERASE]; bsd_termios->c_cc[VLNEXT] =3D linux_termios->c_cc[LINUX_VLNEXT]; for (i=3D0; ic_cc[i] =3D=3D LINUX_POSIX_VDISABLE) bsd_termios->c_cc[i] =3D _POSIX_VDISABLE; } bsd_termios->c_ispeed =3D bsd_termios->c_ospeed =3D linux_to_bsd_speed(linux_termios->c_cflag & LINUX_CBAUD, sptab); #ifdef DEBUG printf("LINUX: BSD termios structure (output):\n"); printf("i=3D%08x o=3D%08x c=3D%08x l=3D%08x ispeed=3D%d ospeed=3D%d\n", bsd_termios->c_iflag, bsd_termios->c_oflag, bsd_termios->c_cflag, bsd_termios->c_lflag, bsd_termios->c_ispeed, bsd_termios->c_ospeed); printf("c_cc "); for (i=3D0; ic_cc[i]); printf("\n"); #endif } static void bsd_to_linux_termio(struct termios *bsd_termios, = struct linux_termio *linux_termio) { struct linux_termios tmios; bsd_to_linux_termios(bsd_termios, &tmios); linux_termio->c_iflag =3D tmios.c_iflag; linux_termio->c_oflag =3D tmios.c_oflag; linux_termio->c_cflag =3D tmios.c_cflag; linux_termio->c_lflag =3D tmios.c_lflag; linux_termio->c_line =3D tmios.c_line; memcpy(linux_termio->c_cc, tmios.c_cc, LINUX_NCC); } static void linux_to_bsd_termio(struct linux_termio *linux_termio, struct termios *bsd_termios) { struct linux_termios tmios; int i; tmios.c_iflag =3D linux_termio->c_iflag; tmios.c_oflag =3D linux_termio->c_oflag; tmios.c_cflag =3D linux_termio->c_cflag; tmios.c_lflag =3D linux_termio->c_lflag; for (i=3D0; ic_cc, LINUX_NCC); linux_to_bsd_termios(&tmios, bsd_termios); } static void linux_tiocgserial(struct file *fp, struct linux_serial_struct *lss) { if (!fp || !lss) return; lss->type =3D LINUX_PORT_16550A; lss->flags =3D 0; lss->close_delay =3D 0; } static void linux_tiocsserial(struct file *fp, struct linux_serial_struct *lss) { if (!fp || !lss) return; } struct linux_cdrom_msf { u_char cdmsf_min0; u_char cdmsf_sec0; u_char cdmsf_frame0; u_char cdmsf_min1; u_char cdmsf_sec1; u_char cdmsf_frame1; }; struct linux_cdrom_tochdr { u_char cdth_trk0; u_char cdth_trk1; }; union linux_cdrom_addr { struct { u_char minute; u_char second; u_char frame; } msf; int lba; }; struct linux_cdrom_tocentry { u_char cdte_track; = u_char cdte_adr:4; u_char cdte_ctrl:4; u_char cdte_format; = union linux_cdrom_addr cdte_addr; u_char cdte_datamode; = }; #if 0 static void linux_to_bsd_msf_lba(u_char address_format, union linux_cdrom_addr *lp, union msf_lba *bp) { if (address_format =3D=3D CD_LBA_FORMAT) bp->lba =3D lp->lba; else { bp->msf.minute =3D lp->msf.minute; bp->msf.second =3D lp->msf.second; bp->msf.frame =3D lp->msf.frame; } } #endif static void bsd_to_linux_msf_lba(u_char address_format, union msf_lba *bp, union linux_cdrom_addr *lp) { if (address_format =3D=3D CD_LBA_FORMAT) lp->lba =3D bp->lba; else { lp->msf.minute =3D bp->msf.minute; lp->msf.second =3D bp->msf.second; lp->msf.frame =3D bp->msf.frame; } } static unsigned dirbits[4] =3D { IOC_VOID, IOC_OUT, IOC_IN, IOC_INOUT }; #define SETDIR(c) (((c) & ~IOC_DIRMASK) | dirbits[args->cmd >> 30]) int linux_ioctl(struct proc *p, struct linux_ioctl_args *args) { struct termios bsd_termios; struct linux_termios linux_termios; struct linux_termio linux_termio; struct filedesc *fdp =3D p->p_fd; struct file *fp; int (*func)(struct file *fp, u_long com, caddr_t data, struct proc *p= ); int bsd_line, linux_line; int error; #ifdef DEBUG printf("Linux-emul(%ld): ioctl(%d, %04lx, *)\n", = (long)p->p_pid, args->fd, args->cmd); #endif if ((unsigned)args->fd >=3D fdp->fd_nfiles = || (fp =3D fdp->fd_ofiles[args->fd]) =3D=3D 0) return EBADF; if (!fp || (fp->f_flag & (FREAD | FWRITE)) =3D=3D 0) { return EBADF; } func =3D fp->f_ops->fo_ioctl; switch (args->cmd & 0xffff) { case LINUX_TCGETA: if ((error =3D (*func)(fp, TIOCGETA, (caddr_t)&bsd_termios, p)) !=3D 0) return error; bsd_to_linux_termio(&bsd_termios, &linux_termio); return copyout((caddr_t)&linux_termio, (caddr_t)args->arg, sizeof(linux_termio)); case LINUX_TCSETA: linux_to_bsd_termio((struct linux_termio *)args->arg, &bsd_termios); return (*func)(fp, TIOCSETA, (caddr_t)&bsd_termios, p); case LINUX_TCSETAW: linux_to_bsd_termio((struct linux_termio *)args->arg, &bsd_termios); return (*func)(fp, TIOCSETAW, (caddr_t)&bsd_termios, p); case LINUX_TCSETAF: linux_to_bsd_termio((struct linux_termio *)args->arg, &bsd_termios); return (*func)(fp, TIOCSETAF, (caddr_t)&bsd_termios, p); case LINUX_TCGETS: if ((error =3D (*func)(fp, TIOCGETA, (caddr_t)&bsd_termios, p)) !=3D 0) return error; bsd_to_linux_termios(&bsd_termios, &linux_termios); return copyout((caddr_t)&linux_termios, (caddr_t)args->arg, sizeof(linux_termios)); case LINUX_TCSETS: linux_to_bsd_termios((struct linux_termios *)args->arg, &bsd_termios); return (*func)(fp, TIOCSETA, (caddr_t)&bsd_termios, p); case LINUX_TCSETSW: linux_to_bsd_termios((struct linux_termios *)args->arg, &bsd_termios); return (*func)(fp, TIOCSETAW, (caddr_t)&bsd_termios, p); case LINUX_TCSETSF: linux_to_bsd_termios((struct linux_termios *)args->arg, &bsd_termios); return (*func)(fp, TIOCSETAF, (caddr_t)&bsd_termios, p); = case LINUX_TIOCGPGRP: args->cmd =3D TIOCGPGRP; return ioctl(p, (struct ioctl_args *)args); case LINUX_TIOCSPGRP: args->cmd =3D TIOCSPGRP; return ioctl(p, (struct ioctl_args *)args); case LINUX_TIOCGWINSZ: args->cmd =3D TIOCGWINSZ; return ioctl(p, (struct ioctl_args *)args); case LINUX_TIOCSWINSZ: args->cmd =3D TIOCSWINSZ; return ioctl(p, (struct ioctl_args *)args); case LINUX_FIONREAD: args->cmd =3D FIONREAD; return ioctl(p, (struct ioctl_args *)args); case LINUX_FIONBIO: args->cmd =3D FIONBIO; return ioctl(p, (struct ioctl_args *)args); case LINUX_FIOASYNC: args->cmd =3D FIOASYNC; return ioctl(p, (struct ioctl_args *)args); case LINUX_FIONCLEX: args->cmd =3D FIONCLEX; return ioctl(p, (struct ioctl_args *)args); case LINUX_FIOCLEX: args->cmd =3D FIOCLEX; return ioctl(p, (struct ioctl_args *)args); case LINUX_TIOCEXCL: args->cmd =3D TIOCEXCL; return ioctl(p, (struct ioctl_args *)args); case LINUX_TIOCNXCL: args->cmd =3D TIOCNXCL; return ioctl(p, (struct ioctl_args *)args); case LINUX_TIOCCONS: args->cmd =3D TIOCCONS; return ioctl(p, (struct ioctl_args *)args); case LINUX_TIOCNOTTY: args->cmd =3D TIOCNOTTY; return ioctl(p, (struct ioctl_args *)args); case LINUX_SIOCGIFCONF: args->cmd =3D OSIOCGIFCONF; return ioctl(p, (struct ioctl_args *)args); case LINUX_SIOCGIFFLAGS: args->cmd =3D SIOCGIFFLAGS; return ioctl(p, (struct ioctl_args *)args); case LINUX_SIOCGIFADDR: args->cmd =3D OSIOCGIFADDR; return ioctl(p, (struct ioctl_args *)args); case LINUX_SIOCGIFDSTADDR: args->cmd =3D OSIOCGIFDSTADDR; return ioctl(p, (struct ioctl_args *)args); case LINUX_SIOCGIFBRDADDR: args->cmd =3D OSIOCGIFBRDADDR; return ioctl(p, (struct ioctl_args *)args); case LINUX_SIOCGIFNETMASK: args->cmd =3D OSIOCGIFNETMASK; return ioctl(p, (struct ioctl_args *)args); /* get hardware address */ case LINUX_SIOCGIFHWADDR: { int ifn; struct ifnet *ifp; struct ifaddr *ifa; struct sockaddr_dl *sdl; struct linux_ifreq *ifr =3D (struct linux_ifreq *)args->arg; /* = * Note that we don't actually respect the name in the ifreq structure, = as * Linux interface names are all different */ for (ifn =3D 0; ifn < if_index; ifn++) { ifp =3D ifnet_addrs[ifn]->ifa_ifp; /* pointer to interface */ if (ifp->if_type =3D=3D IFT_ETHER) { /* looks good */ /* walk the address list */ for (ifa =3D TAILQ_FIRST(&ifp->if_addrhead); ifa; ifa =3D TAILQ_NEXT(if= a, ifa_link)) { if ((sdl =3D (struct sockaddr_dl *)ifa->ifa_addr) && /* we have an = address structure */ (sdl->sdl_family =3D=3D AF_LINK) && /* it's a link address */ (sdl->sdl_type =3D=3D IFT_ETHER)) { /* for an ethernet link */ return(copyout(LLADDR(sdl), (caddr_t)&ifr->ifr_hwaddr.sa_data, LINUX_I= FHWADDRLEN)); } } } } return(ENOENT); /* ??? */ } case LINUX_SIOCADDMULTI: args->cmd =3D SIOCADDMULTI; return ioctl(p, (struct ioctl_args *)args); case LINUX_SIOCDELMULTI: args->cmd =3D SIOCDELMULTI; return ioctl(p, (struct ioctl_args *)args); case LINUX_FIOSETOWN: args->cmd =3D FIOSETOWN; return ioctl(p, (struct ioctl_args *)args); case LINUX_SIOCSPGRP: args->cmd =3D SIOCSPGRP; return ioctl(p, (struct ioctl_args *)args); case LINUX_FIOGETOWN: args->cmd =3D FIOGETOWN; return ioctl(p, (struct ioctl_args *)args); case LINUX_SIOCGPGRP: args->cmd =3D SIOCGPGRP; return ioctl(p, (struct ioctl_args *)args); case LINUX_SIOCATMARK: args->cmd =3D SIOCATMARK; return ioctl(p, (struct ioctl_args *)args); case LINUX_TIOCSETD: switch (args->arg) { case LINUX_N_TTY: bsd_line =3D TTYDISC; return (*func)(fp, TIOCSETD, (caddr_t)&bsd_line, p); case LINUX_N_SLIP: bsd_line =3D SLIPDISC; return (*func)(fp, TIOCSETD, (caddr_t)&bsd_line, p); case LINUX_N_PPP: bsd_line =3D PPPDISC; return (*func)(fp, TIOCSETD, (caddr_t)&bsd_line, p); default: return EINVAL; } case LINUX_TIOCGETD: bsd_line =3D TTYDISC; error =3D(*func)(fp, TIOCSETD, (caddr_t)&bsd_line, p); if (error) return error; switch (bsd_line) { case TTYDISC: linux_line =3D LINUX_N_TTY; break; case SLIPDISC: linux_line =3D LINUX_N_SLIP; break; case PPPDISC: linux_line =3D LINUX_N_PPP; break; default: return EINVAL; } return copyout(&linux_line, (caddr_t)args->arg, = sizeof(int)); case LINUX_SNDCTL_SEQ_RESET: args->cmd =3D SNDCTL_SEQ_RESET; return ioctl(p, (struct ioctl_args *)args); case LINUX_SNDCTL_SEQ_SYNC: args->cmd =3D SNDCTL_SEQ_SYNC; return ioctl(p, (struct ioctl_args *)args); case LINUX_SNDCTL_SYNTH_INFO: args->cmd =3D SNDCTL_SYNTH_INFO; return ioctl(p, (struct ioctl_args *)args); case LINUX_SNDCTL_SEQ_CTRLRATE: args->cmd =3D SNDCTL_SEQ_CTRLRATE; return ioctl(p, (struct ioctl_args *)args); case LINUX_SNDCTL_SEQ_GETOUTCOUNT: args->cmd =3D SNDCTL_SEQ_GETOUTCOUNT; return ioctl(p, (struct ioctl_args *)args); case LINUX_SNDCTL_SEQ_GETINCOUNT: args->cmd =3D SNDCTL_SEQ_GETINCOUNT; return ioctl(p, (struct ioctl_args *)args); case LINUX_SNDCTL_SEQ_PERCMODE: args->cmd =3D SNDCTL_SEQ_PERCMODE; return ioctl(p, (struct ioctl_args *)args); case LINUX_SNDCTL_FM_LOAD_INSTR: args->cmd =3D SNDCTL_FM_LOAD_INSTR; return ioctl(p, (struct ioctl_args *)args); case LINUX_SNDCTL_SEQ_TESTMIDI: args->cmd =3D SNDCTL_SEQ_TESTMIDI; return ioctl(p, (struct ioctl_args *)args); case LINUX_SNDCTL_SEQ_RESETSAMPLES: args->cmd =3D SNDCTL_SEQ_RESETSAMPLES; return ioctl(p, (struct ioctl_args *)args); case LINUX_SNDCTL_SEQ_NRSYNTHS: args->cmd =3D SNDCTL_SEQ_NRSYNTHS; return ioctl(p, (struct ioctl_args *)args); case LINUX_SNDCTL_SEQ_NRMIDIS: args->cmd =3D SNDCTL_SEQ_NRMIDIS; return ioctl(p, (struct ioctl_args *)args); case LINUX_SNDCTL_MIDI_INFO: args->cmd =3D SNDCTL_MIDI_INFO; return ioctl(p, (struct ioctl_args *)args); case LINUX_SNDCTL_SEQ_TRESHOLD: args->cmd =3D SNDCTL_SEQ_TRESHOLD; return ioctl(p, (struct ioctl_args *)args); case LINUX_SNDCTL_SYNTH_MEMAVL: args->cmd =3D SNDCTL_SYNTH_MEMAVL; return ioctl(p, (struct ioctl_args *)args); case LINUX_SNDCTL_DSP_GETOPTR : args->cmd =3D SNDCTL_DSP_GETOPTR; return ioctl(p, (struct ioctl_args *)args); case LINUX_SNDCTL_DSP_GETIPTR : args->cmd =3D SNDCTL_DSP_GETIPTR; return ioctl(p, (struct ioctl_args *)args); case LINUX_SNDCTL_DSP_SETTRIGGER: args->cmd =3D SNDCTL_DSP_SETTRIGGER; return ioctl(p, (struct ioctl_args *)args); case LINUX_SNDCTL_DSP_GETCAPS: args->cmd =3D SNDCTL_DSP_GETCAPS; return ioctl(p, (struct ioctl_args *)args); case LINUX_SNDCTL_DSP_RESET: args->cmd =3D SNDCTL_DSP_RESET; return ioctl(p, (struct ioctl_args *)args); case LINUX_SNDCTL_DSP_SYNC: args->cmd =3D SNDCTL_DSP_SYNC; return ioctl(p, (struct ioctl_args *)args); case LINUX_SNDCTL_DSP_SPEED: args->cmd =3D SNDCTL_DSP_SPEED; return ioctl(p, (struct ioctl_args *)args); case LINUX_SNDCTL_DSP_STEREO: args->cmd =3D SNDCTL_DSP_STEREO; return ioctl(p, (struct ioctl_args *)args); case LINUX_SNDCTL_DSP_GETBLKSIZE: /* LINUX_SNDCTL_DSP_SETBLKSIZE */ args->cmd =3D SNDCTL_DSP_GETBLKSIZE; return ioctl(p, (struct ioctl_args *)args); case LINUX_SNDCTL_DSP_SETFMT: args->cmd =3D SNDCTL_DSP_SETFMT; return ioctl(p, (struct ioctl_args *)args); case LINUX_SOUND_PCM_WRITE_CHANNELS: args->cmd =3D SOUND_PCM_WRITE_CHANNELS; return ioctl(p, (struct ioctl_args *)args); case LINUX_SOUND_PCM_WRITE_FILTER: args->cmd =3D SOUND_PCM_WRITE_FILTER; return ioctl(p, (struct ioctl_args *)args); case LINUX_SNDCTL_DSP_POST: args->cmd =3D SNDCTL_DSP_POST; return ioctl(p, (struct ioctl_args *)args); case LINUX_SNDCTL_DSP_SUBDIVIDE: args->cmd =3D SNDCTL_DSP_SUBDIVIDE; return ioctl(p, (struct ioctl_args *)args); case LINUX_SNDCTL_DSP_SETFRAGMENT: args->cmd =3D SNDCTL_DSP_SETFRAGMENT; return ioctl(p, (struct ioctl_args *)args); case LINUX_SNDCTL_DSP_GETFMTS: args->cmd =3D SNDCTL_DSP_GETFMTS; return ioctl(p, (struct ioctl_args *)args); case LINUX_SNDCTL_DSP_GETOSPACE: args->cmd =3D SNDCTL_DSP_GETOSPACE; return ioctl(p, (struct ioctl_args *)args); case LINUX_SNDCTL_DSP_GETISPACE: args->cmd =3D SNDCTL_DSP_GETISPACE; return ioctl(p, (struct ioctl_args *)args); case LINUX_SNDCTL_DSP_NONBLOCK: args->cmd =3D SNDCTL_DSP_NONBLOCK; return ioctl(p, (struct ioctl_args *)args); case LINUX_SOUND_MIXER_WRITE_VOLUME: args->cmd =3D SETDIR(SOUND_MIXER_WRITE_VOLUME); return ioctl(p, (struct ioctl_args *)args); case LINUX_SOUND_MIXER_WRITE_BASS: args->cmd =3D SETDIR(SOUND_MIXER_WRITE_BASS); return ioctl(p, (struct ioctl_args *)args); case LINUX_SOUND_MIXER_WRITE_TREBLE: args->cmd =3D SETDIR(SOUND_MIXER_WRITE_TREBLE); return ioctl(p, (struct ioctl_args *)args); case LINUX_SOUND_MIXER_WRITE_SYNTH: args->cmd =3D SETDIR(SOUND_MIXER_WRITE_SYNTH); return ioctl(p, (struct ioctl_args *)args); case LINUX_SOUND_MIXER_WRITE_PCM: args->cmd =3D SETDIR(SOUND_MIXER_WRITE_PCM); return ioctl(p, (struct ioctl_args *)args); case LINUX_SOUND_MIXER_WRITE_SPEAKER: args->cmd =3D SETDIR(SOUND_MIXER_WRITE_SPEAKER); return ioctl(p, (struct ioctl_args *)args); case LINUX_SOUND_MIXER_WRITE_LINE: args->cmd =3D SETDIR(SOUND_MIXER_WRITE_LINE); return ioctl(p, (struct ioctl_args *)args); case LINUX_SOUND_MIXER_WRITE_MIC: args->cmd =3D SETDIR(SOUND_MIXER_WRITE_MIC); return ioctl(p, (struct ioctl_args *)args); case LINUX_SOUND_MIXER_WRITE_CD: args->cmd =3D SETDIR(SOUND_MIXER_WRITE_CD); return ioctl(p, (struct ioctl_args *)args); case LINUX_SOUND_MIXER_WRITE_IMIX: args->cmd =3D SETDIR(SOUND_MIXER_WRITE_IMIX); return ioctl(p, (struct ioctl_args *)args); case LINUX_SOUND_MIXER_WRITE_ALTPCM: args->cmd =3D SETDIR(SOUND_MIXER_WRITE_ALTPCM); return ioctl(p, (struct ioctl_args *)args); case LINUX_SOUND_MIXER_WRITE_RECLEV: args->cmd =3D SETDIR(SOUND_MIXER_WRITE_RECLEV); return ioctl(p, (struct ioctl_args *)args); case LINUX_SOUND_MIXER_WRITE_IGAIN: args->cmd =3D SETDIR(SOUND_MIXER_WRITE_IGAIN); return ioctl(p, (struct ioctl_args *)args); case LINUX_SOUND_MIXER_WRITE_OGAIN: args->cmd =3D SETDIR(SOUND_MIXER_WRITE_OGAIN); return ioctl(p, (struct ioctl_args *)args); case LINUX_SOUND_MIXER_WRITE_LINE1: args->cmd =3D SETDIR(SOUND_MIXER_WRITE_LINE1); return ioctl(p, (struct ioctl_args *)args); case LINUX_SOUND_MIXER_WRITE_LINE2: args->cmd =3D SETDIR(SOUND_MIXER_WRITE_LINE2); return ioctl(p, (struct ioctl_args *)args); case LINUX_SOUND_MIXER_WRITE_LINE3: args->cmd =3D SETDIR(SOUND_MIXER_WRITE_LINE3); return ioctl(p, (struct ioctl_args *)args); case LINUX_SOUND_MIXER_READ_DEVMASK: args->cmd =3D SOUND_MIXER_READ_DEVMASK; return ioctl(p, (struct ioctl_args *)args); case LINUX_TIOCGSERIAL: linux_tiocgserial(fp, (struct linux_serial_struct *)args->arg); return 0; case LINUX_TIOCSSERIAL: linux_tiocsserial(fp, (struct linux_serial_struct *)args->arg); return 0; case LINUX_TCFLSH: args->cmd =3D TIOCFLUSH; switch (args->arg) { case LINUX_TCIFLUSH: args->arg =3D FREAD; break; case LINUX_TCOFLUSH: args->arg =3D FWRITE; break; case LINUX_TCIOFLUSH: args->arg =3D FREAD | FWRITE; break; default: return EINVAL; } return ioctl(p, (struct ioctl_args *)args); case LINUX_VT_OPENQRY: args->cmd =3D VT_OPENQRY; return ioctl(p, (struct ioctl_args *)args); case LINUX_VT_GETMODE: args->cmd =3D VT_GETMODE; return ioctl(p, (struct ioctl_args *)args); case LINUX_VT_SETMODE: = { struct vt_mode *mode; args->cmd =3D VT_SETMODE; mode =3D (struct vt_mode *)args->arg; if (!ISSIGVALID(mode->frsig) && ISSIGVALID(mode->acqsig)) mode->frsig =3D mode->acqsig; return ioctl(p, (struct ioctl_args *)args); } case LINUX_VT_GETSTATE: args->cmd =3D VT_GETACTIVE; return ioctl(p, (struct ioctl_args *)args); case LINUX_VT_ACTIVATE: args->cmd =3D VT_ACTIVATE; return ioctl(p, (struct ioctl_args *)args); case LINUX_VT_WAITACTIVE: args->cmd =3D VT_WAITACTIVE; return ioctl(p, (struct ioctl_args *)args); case LINUX_KDGKBMODE: args->cmd =3D KDGKBMODE; return ioctl(p, (struct ioctl_args *)args); case LINUX_KDSKBMODE: { int kbdmode; switch (args->arg) { case LINUX_KBD_RAW: kbdmode =3D K_RAW; return (*func)(fp, KDSKBMODE, (caddr_t)&kbdmode, p); case LINUX_KBD_XLATE: = kbdmode =3D K_XLATE; return (*func)(fp, KDSKBMODE , (caddr_t)&kbdmode, p); case LINUX_KBD_MEDIUMRAW: kbdmode =3D K_RAW; return (*func)(fp, KDSKBMODE , (caddr_t)&kbdmode, p); default: return EINVAL; } } case LINUX_KDGETMODE: args->cmd =3D KDGETMODE; return ioctl(p, (struct ioctl_args *)args); case LINUX_KDSETMODE: args->cmd =3D KDSETMODE; return ioctl(p, (struct ioctl_args *)args); case LINUX_KDSETLED: args->cmd =3D KDSETLED; return ioctl(p, (struct ioctl_args *)args); case LINUX_KDGETLED: args->cmd =3D KDGETLED; return ioctl(p, (struct ioctl_args *)args); case LINUX_KIOCSOUND: args->cmd =3D KIOCSOUND; return ioctl(p, (struct ioctl_args *)args); case LINUX_KDMKTONE: args->cmd =3D KDMKTONE; return ioctl(p, (struct ioctl_args *)args); case LINUX_CDROMPAUSE: args->cmd =3D CDIOCPAUSE; return ioctl(p, (struct ioctl_args *)args); case LINUX_CDROMRESUME: args->cmd =3D CDIOCRESUME; return ioctl(p, (struct ioctl_args *)args); case LINUX_CDROMPLAYMSF: args->cmd =3D CDIOCPLAYMSF; return ioctl(p, (struct ioctl_args *)args); case LINUX_CDROMPLAYTRKIND: args->cmd =3D CDIOCPLAYTRACKS; return ioctl(p, (struct ioctl_args *)args); case LINUX_CDROMSTART: args->cmd =3D CDIOCSTART; return ioctl(p, (struct ioctl_args *)args); case LINUX_CDROMSTOP: args->cmd =3D CDIOCSTOP; return ioctl(p, (struct ioctl_args *)args); case LINUX_CDROMEJECT: args->cmd =3D CDIOCEJECT; return ioctl(p, (struct ioctl_args *)args); case LINUX_CDROMRESET: args->cmd =3D CDIOCRESET; return ioctl(p, (struct ioctl_args *)args); case LINUX_CDROMREADTOCHDR: { struct ioc_toc_header th; struct linux_cdrom_tochdr lth; error =3D (*func)(fp, CDIOREADTOCHEADER, (caddr_t)&th, p); if (!error) { lth.cdth_trk0 =3D th.starting_track; lth.cdth_trk1 =3D th.ending_track; copyout((caddr_t)<h, (caddr_t)args->arg, sizeof(lth)); } return error; } case LINUX_CDROMREADTOCENTRY: { struct linux_cdrom_tocentry lte, *ltep =3D (struct linux_cdrom_tocentry *)args->arg; struct ioc_read_toc_single_entry irtse; irtse.address_format =3D ltep->cdte_format; irtse.track =3D ltep->cdte_track; error =3D (*func)(fp, CDIOREADTOCENTRY, (caddr_t)&irtse, p); if (!error) { lte =3D *ltep; lte.cdte_ctrl =3D irtse.entry.control; lte.cdte_adr =3D irtse.entry.addr_type; bsd_to_linux_msf_lba(irtse.address_format, &irtse.entry.addr, <e.cdte_addr); copyout((caddr_t)<e, (caddr_t)args->arg, sizeof(lte)); } return error; } case 0x3304: case 0x3303: case 0x3302: { int myretval; struct pioData { short port; short size; int device; void *value; } *desc; desc =3D (struct pioData *)args->arg; myretval =3D (*func)(fp, args->cmd, (caddr_t)args->arg, p); if (myretval !=3D EINVAL) { p->p_retval[0] =3D myretval; return 0; } else return myretval; } } uprintf("LINUX: 'ioctl' fd=3D%d, typ=3D0x%x(%c), num=3D0x%x not imple= mented\n", args->fd, (u_int)((args->cmd & 0xffff00) >> 8), (int)((args->cmd & 0xffff00) >> 8), (u_int)(args->cmd & 0xff)); return EINVAL; } -- = The views expressed above are not those of PGS Tensor. "We've heard that a million monkeys at a million keyboards could prod= uce the Complete Works of Shakespeare; now, thanks to the Internet, we k= now this is not true." Robert Wilensky, University of Califor= nia To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-multimedia" in the body of the message