Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/compat/linux/arch/i386 Add i386-specific code for a few ...



details:   https://anonhg.NetBSD.org/src/rev/6801c401f78b
branches:  trunk
changeset: 500339:6801c401f78b
user:      fvdl <fvdl%NetBSD.org@localhost>
date:      Sun Dec 10 14:09:59 2000 +0000

description:
Add i386-specific code for a few ioctl calls.

diffstat:

 sys/compat/linux/arch/i386/linux_machdep.c |  126 ++++++++++++++++++++++++++++-
 sys/compat/linux/arch/i386/linux_machdep.h |    3 +-
 2 files changed, 124 insertions(+), 5 deletions(-)

diffs (215 lines):

diff -r 2255ab1047a9 -r 6801c401f78b sys/compat/linux/arch/i386/linux_machdep.c
--- a/sys/compat/linux/arch/i386/linux_machdep.c        Sun Dec 10 14:08:48 2000 +0000
+++ b/sys/compat/linux/arch/i386/linux_machdep.c        Sun Dec 10 14:09:59 2000 +0000
@@ -1,7 +1,7 @@
-/*     $NetBSD: linux_machdep.c,v 1.51 2000/11/29 22:05:36 jdolecek Exp $      */
+/*     $NetBSD: linux_machdep.c,v 1.52 2000/12/10 14:09:59 fvdl Exp $  */
 
 /*-
- * Copyright (c) 1995 The NetBSD Foundation, Inc.
+ * Copyright (c) 1995, 2000 The NetBSD Foundation, Inc.
  * All rights reserved.
  *
  * This code is derived from software contributed to The NetBSD Foundation
@@ -63,11 +63,14 @@
 #include <sys/syscallargs.h>
 #include <sys/filedesc.h>
 #include <sys/exec_elf.h>
+#include <sys/disklabel.h>
+#include <miscfs/specfs/specdev.h>
 
 #include <compat/linux/common/linux_types.h>
 #include <compat/linux/common/linux_signal.h>
 #include <compat/linux/common/linux_util.h>
 #include <compat/linux/common/linux_ioctl.h>
+#include <compat/linux/common/linux_hdio.h>
 #include <compat/linux/common/linux_exec.h>
 #include <compat/linux/common/linux_machdep.h>
 
@@ -91,6 +94,7 @@
 #endif
 #if (NWSDISPLAY > 0)
 #include <sys/ioctl.h>
+#include <dev/wscons/wsconsio.h>
 #include <dev/wscons/wsdisplay_usl_io.h>
 #if defined(_KERNEL) && !defined(_LKM)
 #include "opt_xserver.h"
@@ -105,6 +109,10 @@
     register_t *));
 #endif
 
+static struct biosdisk_info *fd2biosinfo __P((struct proc *, struct file *));
+extern struct disklist *i386_alldisks;
+extern const char *findblkname __P((int));
+
 /*
  * Deal with some i386-specific things in the Linux emulation code.
  */
@@ -538,6 +546,41 @@
 };
 #endif
 
+static struct biosdisk_info *
+fd2biosinfo(p, fp)
+       struct proc *p;
+       struct file *fp;
+{
+       struct vnode *vp;
+       const char *blkname;
+       char diskname[16];
+       int i;
+       struct nativedisk_info *nip;
+       struct disklist *dl = i386_alldisks;
+
+       if (fp->f_type != DTYPE_VNODE)
+               return NULL;
+       vp = (struct vnode *)fp->f_data;
+
+       if (vp->v_type != VBLK)
+               return NULL;
+
+       blkname = findblkname(major(vp->v_rdev));
+       snprintf(diskname, sizeof diskname, "%s%u", blkname,
+           DISKUNIT(vp->v_rdev));
+
+       for (i = 0; i < dl->dl_nnativedisks; i++) {
+               nip = &dl->dl_nativedisks[i];
+               if (strcmp(diskname, nip->ni_devname))
+                       continue;
+               if (nip->ni_nmatches != 0)
+                       return &dl->dl_biosdisks[nip->ni_biosmatches[0]];
+       }
+
+       return NULL;
+}
+
+
 /*
  * We come here in a last attempt to satisfy a Linux ioctl() call
  */
@@ -554,17 +597,39 @@
        } */ *uap = v;
        struct sys_ioctl_args bia;
        u_long com;
+       int error, error1;
 #if (NWSDISPLAY > 0)
-       int error;
        struct vt_mode lvt;
        caddr_t bvtp, sg;
        struct kbentry kbe;
 #endif
+       struct linux_hd_geometry hdg;
+       struct linux_hd_big_geometry hdg_big;
+       struct biosdisk_info *bip;
+       struct filedesc *fdp;
+       struct file *fp;
+       int fd;
+       struct disklabel label, *labp;
+       struct partinfo partp;
+       int (*ioctlf) __P((struct file *, u_long, caddr_t, struct proc *));
+       u_long start, biostotal, realtotal;
+       u_char heads, sectors;
+       u_int cylinders;
 
-       SCARG(&bia, fd) = SCARG(uap, fd);
+       fd = SCARG(uap, fd);
+       SCARG(&bia, fd) = fd;
        SCARG(&bia, data) = SCARG(uap, data);
        com = SCARG(uap, com);
 
+       fdp = p->p_fd;
+
+       if (fd < 0 || fd >= fdp->fd_nfiles)
+               return NULL;
+
+       fp = fdp->fd_ofiles[fd];
+       if (fp == NULL)
+               return NULL;
+
        switch (com) {
 #if (NWSDISPLAY > 0)
        case LINUX_KDGKBMODE:
@@ -622,6 +687,9 @@
                        return error;
                SCARG(&bia, data) = bvtp;
                break;
+       case LINUX_VT_DISALLOCATE:
+               /* XXX should use WSDISPLAYIO_DELSCREEN */
+               return 0;
        case LINUX_VT_RELDISP:
                com = VT_RELDISP;
                break;
@@ -653,6 +721,56 @@
                kbe.kb_value = linux_keytabs[kbe.kb_table][kbe.kb_index];
                return (copyout(&kbe, SCARG(uap, data),
                                sizeof(struct kbentry)));
+       case LINUX_HDIO_GETGEO:
+       case LINUX_HDIO_GETGEO_BIG:
+               /*
+                * Try to mimic Linux behaviour: return the BIOS geometry
+                * if possible (extending its # of cylinders if it's beyond
+                * the 1023 limit), fall back to the MI geometry (i.e.
+                * the real geometry) if not found, by returning an
+                * error. See common/linux_hdio.c
+                */
+               FILE_USE(fp);
+               bip = fd2biosinfo(p, fp);
+               ioctlf = fp->f_ops->fo_ioctl;
+               error = ioctlf(fp, DIOCGDEFLABEL, (caddr_t)&label, p);
+               error1 = ioctlf(fp, DIOCGPART, (caddr_t)&partp, p);
+               FILE_UNUSE(fp, p);
+               if (error != 0 && error1 != 0)
+                       return error1;
+               labp = error != 0 ? &label : partp.disklab;
+               start = error1 != 0 ? partp.part->p_offset : 0;
+               if (bip != NULL && bip->bi_head != 0 && bip->bi_sec != 0
+                   && bip->bi_cyl != 0) {
+                       heads = bip->bi_head;
+                       sectors = bip->bi_sec;
+                       cylinders = bip->bi_cyl;
+                       biostotal = heads * sectors * cylinders;
+                       realtotal = labp->d_ntracks * labp->d_nsectors *
+                           labp->d_ncylinders;
+                       if (realtotal > biostotal)
+                               cylinders = realtotal / (heads * sectors);
+               } else {
+                       heads = labp->d_ntracks;
+                       cylinders = labp->d_ncylinders;
+                       sectors = labp->d_nsectors;
+               }
+               if (com == LINUX_HDIO_GETGEO) {
+                       hdg.start = start;
+                       hdg.heads = heads;
+                       hdg.cylinders = cylinders;
+                       hdg.sectors = sectors;
+                       return copyout(&hdg, SCARG(uap, data), sizeof hdg);
+               } else {
+                       hdg_big.start = start;
+                       hdg_big.heads = heads;
+                       hdg_big.cylinders = cylinders;
+                       hdg_big.sectors = sectors;
+                       return copyout(&hdg_big, SCARG(uap, data),
+                           sizeof hdg_big);
+               }
+               return 0;
+
 #endif
        default:
                printf("linux_machdepioctl: invalid ioctl %08lx\n", com);
diff -r 2255ab1047a9 -r 6801c401f78b sys/compat/linux/arch/i386/linux_machdep.h
--- a/sys/compat/linux/arch/i386/linux_machdep.h        Sun Dec 10 14:08:48 2000 +0000
+++ b/sys/compat/linux/arch/i386/linux_machdep.h        Sun Dec 10 14:09:59 2000 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: linux_machdep.h,v 1.14 2000/12/09 19:51:44 christos Exp $      */
+/*     $NetBSD: linux_machdep.h,v 1.15 2000/12/10 14:09:59 fvdl Exp $  */
 
 /*-
  * Copyright (c) 1995 The NetBSD Foundation, Inc.
@@ -125,6 +125,7 @@
 #define LINUX_VT_RELDISP    0x5605
 #define LINUX_VT_ACTIVATE   0x5606
 #define LINUX_VT_WAITACTIVE 0x5607
+#define LINUX_VT_DISALLOCATE   0x5608
 
 /*
  * Does the port have separated linux_syscall() ?



Home | Main Index | Thread Index | Old Index