patch-2.4.0-test12 linux/arch/mips64/kernel/ioctl32.c

Next file: linux/arch/mips64/kernel/linux32.c
Previous file: linux/arch/mips64/defconfig-ip27
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.4.0-test11/linux/arch/mips64/kernel/ioctl32.c linux/arch/mips64/kernel/ioctl32.c
@@ -3,28 +3,65 @@
  *
  * Copyright (C) 2000 Silicon Graphics, Inc.
  * Written by Ulf Carlsson (ulfc@engr.sgi.com)
+ * Copyright (C) 2000 Ralf Baechle
  *
- * Mostly from the sparc64 ioctl32 implementation.
+ * Mostly stolen from the sparc64 ioctl32 implementation.
  */
-
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/fs.h>
 #include <linux/sched.h>
 #include <linux/mm.h>
+#include <linux/mtio.h>
 #include <linux/init.h>
 #include <linux/file.h>
 #include <linux/vt.h>
 #include <linux/kd.h>
 #include <linux/netdevice.h>
 #include <linux/route.h>
+#include <linux/hdreg.h>
+#include <linux/blkpg.h>
+#include <linux/blkdev.h>
+#include <linux/elevator.h>
+#include <linux/auto_fs.h>
+#include <linux/ext2_fs.h>
 #include <asm/types.h>
 #include <asm/uaccess.h>
 
-#define A(__x) ((unsigned long)(__x))
-
 long sys_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg);
 
+static int w_long(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+	mm_segment_t old_fs = get_fs();
+	int err;
+	unsigned long val;
+	
+	set_fs (KERNEL_DS);
+	err = sys_ioctl(fd, cmd, (unsigned long)&val);
+	set_fs (old_fs);
+	if (!err && put_user((unsigned int) val, (u32 *)arg))
+		return -EFAULT;
+	return err;
+}
+
+static int rw_long(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+	mm_segment_t old_fs = get_fs();
+	int err;
+	unsigned long val;
+
+	if (get_user(val, (u32 *)arg))
+		return -EFAULT;
+	set_fs(KERNEL_DS);
+	err = sys_ioctl(fd, cmd, (unsigned long)&val);
+	set_fs (old_fs);
+	if (!err && put_user(val, (u32 *)arg))
+		return -EFAULT;
+	return err;
+}
+
+#define A(__x) ((unsigned long)(__x))
+
 struct timeval32 {
 	int tv_sec;
 	int tv_usec;
@@ -283,20 +320,217 @@
 	return sys_ioctl(fd, cmd, arg);
 }
 
-static int w_long(unsigned int fd, unsigned int cmd, unsigned long arg)
+struct hd_geometry32 {
+	unsigned char heads;
+	unsigned char sectors;
+	unsigned short cylinders;
+	u32 start;
+};
+
+static int hdio_getgeo(unsigned int fd, unsigned int cmd, unsigned long arg)
 {
 	mm_segment_t old_fs = get_fs();
+	struct hd_geometry geo;
 	int err;
-	unsigned long val;
-	
+
 	set_fs (KERNEL_DS);
-	err = sys_ioctl(fd, cmd, (unsigned long)&val);
+	err = sys_ioctl(fd, HDIO_GETGEO, (unsigned long)&geo);
 	set_fs (old_fs);
-	if (!err && put_user((unsigned int) val, (u32 *)arg))
-		return -EFAULT;
+	if (!err) {
+		err = copy_to_user ((struct hd_geometry32 *)arg, &geo, 4);
+		err |= __put_user (geo.start, &(((struct hd_geometry32 *)arg)->start));
+	}
+
+	return err ? -EFAULT : 0;
+}
+
+static int hdio_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+	mm_segment_t old_fs = get_fs();
+	unsigned long kval;
+	unsigned int *uvp;
+	int error;
+
+	set_fs(KERNEL_DS);
+	error = sys_ioctl(fd, cmd, (long)&kval);
+	set_fs(old_fs);
+
+	if (error == 0) {
+		uvp = (unsigned int *)arg;
+		if (put_user(kval, uvp))
+			error = -EFAULT;
+	}
+
+	return error;
+}
+
+struct blkpg_ioctl_arg32 {
+	int op;
+	int flags;
+	int datalen;
+	u32 data;
+};
+
+static int blkpg_ioctl_trans(unsigned int fd, unsigned int cmd,
+                             struct blkpg_ioctl_arg32 *arg)
+{
+	struct blkpg_ioctl_arg a;
+	struct blkpg_partition p;
+	int err;
+	mm_segment_t old_fs = get_fs();
+	
+	err = get_user(a.op, &arg->op);
+	err |= __get_user(a.flags, &arg->flags);
+	err |= __get_user(a.datalen, &arg->datalen);
+	err |= __get_user((long)a.data, &arg->data);
+	if (err) return err;
+	switch (a.op) {
+	case BLKPG_ADD_PARTITION:
+	case BLKPG_DEL_PARTITION:
+		if (a.datalen < sizeof(struct blkpg_partition))
+			return -EINVAL;
+                if (copy_from_user(&p, a.data, sizeof(struct blkpg_partition)))
+			return -EFAULT;
+		a.data = &p;
+		set_fs (KERNEL_DS);
+		err = sys_ioctl(fd, cmd, (unsigned long)&a);
+		set_fs (old_fs);
+	default:
+		return -EINVAL;
+	}                                        
 	return err;
 }
 
+struct mtget32 {
+	__u32	mt_type;
+	__u32	mt_resid;
+	__u32	mt_dsreg;
+	__u32	mt_gstat;
+	__u32	mt_erreg;
+	__kernel_daddr_t32	mt_fileno;
+	__kernel_daddr_t32	mt_blkno;
+};
+#define MTIOCGET32	_IOR('m', 2, struct mtget32)
+
+struct mtpos32 {
+	__u32	mt_blkno;
+};
+#define MTIOCPOS32	_IOR('m', 3, struct mtpos32)
+
+struct mtconfiginfo32 {
+	__u32	mt_type;
+	__u32	ifc_type;
+	__u16	irqnr;
+	__u16	dmanr;
+	__u16	port;
+	__u32	debug;
+	__u32	have_dens:1;
+	__u32	have_bsf:1;
+	__u32	have_fsr:1;
+	__u32	have_bsr:1;
+	__u32	have_eod:1;
+	__u32	have_seek:1;
+	__u32	have_tell:1;
+	__u32	have_ras1:1;
+	__u32	have_ras2:1;
+	__u32	have_ras3:1;
+	__u32	have_qfa:1;
+	__u32	pad1:5;
+	char	reserved[10];
+};
+#define	MTIOCGETCONFIG32	_IOR('m', 4, struct mtconfiginfo32)
+#define	MTIOCSETCONFIG32	_IOW('m', 5, struct mtconfiginfo32)
+
+static int mt_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+	mm_segment_t old_fs = get_fs();
+	struct mtconfiginfo info;
+	struct mtget get;
+	struct mtpos pos;
+	unsigned long kcmd;
+	void *karg;
+	int err = 0;
+
+	switch(cmd) {
+	case MTIOCPOS32:
+		kcmd = MTIOCPOS;
+		karg = &pos;
+		break;
+	case MTIOCGET32:
+		kcmd = MTIOCGET;
+		karg = &get;
+		break;
+	case MTIOCGETCONFIG32:
+		kcmd = MTIOCGETCONFIG;
+		karg = &info;
+		break;
+	case MTIOCSETCONFIG32:
+		kcmd = MTIOCSETCONFIG;
+		karg = &info;
+		err = __get_user(info.mt_type, &((struct mtconfiginfo32 *)arg)->mt_type);
+		err |= __get_user(info.ifc_type, &((struct mtconfiginfo32 *)arg)->ifc_type);
+		err |= __get_user(info.irqnr, &((struct mtconfiginfo32 *)arg)->irqnr);
+		err |= __get_user(info.dmanr, &((struct mtconfiginfo32 *)arg)->dmanr);
+		err |= __get_user(info.port, &((struct mtconfiginfo32 *)arg)->port);
+		err |= __get_user(info.debug, &((struct mtconfiginfo32 *)arg)->debug);
+		err |= __copy_from_user((char *)&info.debug + sizeof(info.debug),
+				     (char *)&((struct mtconfiginfo32 *)arg)->debug
+				     + sizeof(((struct mtconfiginfo32 *)arg)->debug), sizeof(__u32));
+		if (err)
+			return -EFAULT;
+		break;
+	default:
+		do {
+			static int count = 0;
+			if (++count <= 20)
+				printk("mt_ioctl: Unknown cmd fd(%d) "
+				       "cmd(%08x) arg(%08x)\n",
+				       (int)fd, (unsigned int)cmd, (unsigned int)arg);
+		} while(0);
+		return -EINVAL;
+	}
+	set_fs (KERNEL_DS);
+	err = sys_ioctl (fd, kcmd, (unsigned long)karg);
+	set_fs (old_fs);
+	if (err)
+		return err;
+	switch (cmd) {
+	case MTIOCPOS32:
+		err = __put_user(pos.mt_blkno, &((struct mtpos32 *)arg)->mt_blkno);
+		break;
+	case MTIOCGET32:
+		err = __put_user(get.mt_type, &((struct mtget32 *)arg)->mt_type);
+		err |= __put_user(get.mt_resid, &((struct mtget32 *)arg)->mt_resid);
+		err |= __put_user(get.mt_dsreg, &((struct mtget32 *)arg)->mt_dsreg);
+		err |= __put_user(get.mt_gstat, &((struct mtget32 *)arg)->mt_gstat);
+		err |= __put_user(get.mt_erreg, &((struct mtget32 *)arg)->mt_erreg);
+		err |= __put_user(get.mt_fileno, &((struct mtget32 *)arg)->mt_fileno);
+		err |= __put_user(get.mt_blkno, &((struct mtget32 *)arg)->mt_blkno);
+		break;
+	case MTIOCGETCONFIG32:
+		err = __put_user(info.mt_type, &((struct mtconfiginfo32 *)arg)->mt_type);
+		err |= __put_user(info.ifc_type, &((struct mtconfiginfo32 *)arg)->ifc_type);
+		err |= __put_user(info.irqnr, &((struct mtconfiginfo32 *)arg)->irqnr);
+		err |= __put_user(info.dmanr, &((struct mtconfiginfo32 *)arg)->dmanr);
+		err |= __put_user(info.port, &((struct mtconfiginfo32 *)arg)->port);
+		err |= __put_user(info.debug, &((struct mtconfiginfo32 *)arg)->debug);
+		err |= __copy_to_user((char *)&((struct mtconfiginfo32 *)arg)->debug
+			    		   + sizeof(((struct mtconfiginfo32 *)arg)->debug),
+					   (char *)&info.debug + sizeof(info.debug), sizeof(__u32));
+		break;
+	case MTIOCSETCONFIG32:
+		break;
+	}
+	return err ? -EFAULT: 0;
+}
+
+#define AUTOFS_IOC_SETTIMEOUT32 _IOWR(0x93,0x64,unsigned int)
+
+static int ioc_settimeout(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+	return rw_long(fd, AUTOFS_IOC_SETTIMEOUT, arg);
+}
+
 struct ioctl32_handler {
 	unsigned int cmd;
 	int (*function)(unsigned int, unsigned int, unsigned long);
@@ -437,8 +671,66 @@
 	IOCTL32_HANDLER(EXT2_IOC32_GETVERSION, do_ext2_ioctl),
 	IOCTL32_HANDLER(EXT2_IOC32_SETVERSION, do_ext2_ioctl),
 
-	IOCTL32_HANDLER(BLKGETSIZE, w_long)
-
+	IOCTL32_HANDLER(HDIO_GETGEO, hdio_getgeo),	/* hdreg.h ioctls  */
+	IOCTL32_HANDLER(HDIO_GET_UNMASKINTR, hdio_ioctl_trans),
+	IOCTL32_HANDLER(HDIO_GET_MULTCOUNT, hdio_ioctl_trans),
+	// HDIO_OBSOLETE_IDENTITY
+	IOCTL32_HANDLER(HDIO_GET_KEEPSETTINGS, hdio_ioctl_trans),
+	IOCTL32_HANDLER(HDIO_GET_32BIT, hdio_ioctl_trans),
+	IOCTL32_HANDLER(HDIO_GET_NOWERR, hdio_ioctl_trans),
+	IOCTL32_HANDLER(HDIO_GET_DMA, hdio_ioctl_trans),
+	IOCTL32_HANDLER(HDIO_GET_NICE, hdio_ioctl_trans),
+	IOCTL32_DEFAULT(HDIO_GET_IDENTITY),
+	IOCTL32_DEFAULT(HDIO_DRIVE_RESET),
+	// HDIO_TRISTATE_HWIF				/* not implemented */
+	// HDIO_DRIVE_TASK				/* To do, need specs */
+	IOCTL32_DEFAULT(HDIO_DRIVE_CMD),
+	IOCTL32_DEFAULT(HDIO_SET_MULTCOUNT),
+	IOCTL32_DEFAULT(HDIO_SET_UNMASKINTR),
+	IOCTL32_DEFAULT(HDIO_SET_KEEPSETTINGS),
+	IOCTL32_DEFAULT(HDIO_SET_32BIT),
+	IOCTL32_DEFAULT(HDIO_SET_NOWERR),
+	IOCTL32_DEFAULT(HDIO_SET_DMA),
+	IOCTL32_DEFAULT(HDIO_SET_PIO_MODE),
+	IOCTL32_DEFAULT(HDIO_SCAN_HWIF),
+	IOCTL32_DEFAULT(HDIO_SET_NICE),
+	//HDIO_UNREGISTER_HWIF
+
+	IOCTL32_DEFAULT(BLKROSET),			/* fs.h ioctls  */
+	IOCTL32_DEFAULT(BLKROGET),
+	IOCTL32_DEFAULT(BLKRRPART),
+	IOCTL32_HANDLER(BLKGETSIZE, w_long),
+
+	IOCTL32_DEFAULT(BLKFLSBUF),
+	IOCTL32_DEFAULT(BLKRASET),
+	IOCTL32_HANDLER(BLKRAGET, w_long),
+	IOCTL32_DEFAULT(BLKFRASET),
+	IOCTL32_HANDLER(BLKFRAGET, w_long),
+	IOCTL32_DEFAULT(BLKSECTSET),
+	IOCTL32_HANDLER(BLKSECTGET, w_long),
+	IOCTL32_DEFAULT(BLKSSZGET),
+	IOCTL32_HANDLER(BLKPG, blkpg_ioctl_trans),
+	IOCTL32_DEFAULT(BLKELVGET),
+	IOCTL32_DEFAULT(BLKELVSET),
+
+	IOCTL32_DEFAULT(MTIOCTOP),			/* mtio.h ioctls  */
+	IOCTL32_HANDLER(MTIOCGET32, mt_ioctl_trans),
+	IOCTL32_HANDLER(MTIOCPOS32, mt_ioctl_trans),
+	IOCTL32_HANDLER(MTIOCGETCONFIG32, mt_ioctl_trans),
+	IOCTL32_HANDLER(MTIOCSETCONFIG32, mt_ioctl_trans),
+	// MTIOCRDFTSEG
+	// MTIOCWRFTSEG
+	// MTIOCVOLINFO
+	// MTIOCGETSIZE
+	// MTIOCFTFORMAT
+	// MTIOCFTCMD
+
+	IOCTL32_DEFAULT(AUTOFS_IOC_READY),		/* auto_fs.h ioctls */
+	IOCTL32_DEFAULT(AUTOFS_IOC_FAIL),
+	IOCTL32_DEFAULT(AUTOFS_IOC_CATATONIC),
+	IOCTL32_DEFAULT(AUTOFS_IOC_PROTOVER),
+	IOCTL32_HANDLER(AUTOFS_IOC_SETTIMEOUT32, ioc_settimeout),
+	IOCTL32_DEFAULT(AUTOFS_IOC_EXPIRE)
 };
 
 #define NR_IOCTL32_HANDLERS	(sizeof(ioctl32_handler_table) /	\

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)