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