From 82173212eed01ffbc811b39fc162b301ba57b16f Mon Sep 17 00:00:00 2001 From: Ben Gras Date: Tue, 25 Jul 2006 09:41:40 +0000 Subject: [PATCH] Introduction of a 'big' ioctl, with more bits (20) reserved for encoding the size field. The TIOCSFON ioctl size (8192) didn't get encoded properly, as there weren't enough bits for it (12) in the regular format. The new format has only one type field, and an extra flag (_IOC_BIG) turned on. FS checks for this flag and uses the alternative decoding of the ioctl codes to determine the size when doing grants. This unbreaks loadfont, although that still uses a phys copy in tty. --- drivers/tty/tty.c | 3 +++ include/minix/ioctl.h | 37 +++++++++++++++++++++++++++---------- include/sys/ioc_tty.h | 3 ++- servers/fs/device.c | 6 +++++- 4 files changed, 37 insertions(+), 12 deletions(-) diff --git a/drivers/tty/tty.c b/drivers/tty/tty.c index 7af69877e..993cbbe3e 100644 --- a/drivers/tty/tty.c +++ b/drivers/tty/tty.c @@ -670,6 +670,9 @@ int safe; if (isconsole(tp)) r = kbd_loadmap(m_ptr, safe); break; + case TIOCSFON_OLD: + printf("TTY: old TIOCSFON ignored.\n"); + break; case TIOCSFON: /* Load a font into an EGA or VGA card (hs@hck.hr) */ if (isconsole(tp)) r = con_loadfont(m_ptr); diff --git a/include/minix/ioctl.h b/include/minix/ioctl.h index 88113039f..6f1bf0193 100755 --- a/include/minix/ioctl.h +++ b/include/minix/ioctl.h @@ -16,12 +16,18 @@ * of the parameter in the high-order word. The 3 high bits of the high- * order word are used to encode the in/out/void status of the parameter. */ -#define _IOCPARM_MASK 0x1FFF -#define _IOC_VOID 0x20000000 -#define _IOCTYPE_MASK 0xFFFF -#define _IOC_IN 0x40000000 -#define _IOC_OUT 0x80000000 -#define _IOC_INOUT (_IOC_IN | _IOC_OUT) +#define _IOCPARM_MASK 0x0FFF +#define _IOCPARM_MASK_BIG 0x0FFFFF +#define _IOC_VOID 0x20000000 +#define _IOCTYPE_MASK 0xFFFF +#define _IOC_IN 0x40000000 +#define _IOC_OUT 0x80000000 +#define _IOC_INOUT (_IOC_IN | _IOC_OUT) + +/* Flag indicating ioctl format with only one type field, and more bits + * for the size field (using mask _IOCPARM_MASK_BIG). + */ +#define _IOC_BIG 0x10000000 #define _IO(x,y) ((x << 8) | y | _IOC_VOID) #define _IOR(x,y,t) ((x << 8) | y | ((sizeof(t) & _IOCPARM_MASK) << 16) |\ @@ -31,11 +37,22 @@ #define _IORW(x,y,t) ((x << 8) | y | ((sizeof(t) & _IOCPARM_MASK) << 16) |\ _IOC_INOUT) +#define _IOW_BIG(y,t) (y | ((sizeof(t) & _IOCPARM_MASK_BIG) << 8) \ + | _IOC_IN | _IOC_BIG) +#define _IOR_BIG(y,t) (y | ((sizeof(t) & _IOCPARM_MASK_BIG) << 8) \ + | _IOC_OUT | _IOC_BIG) +#define _IORW_BIG(y,t) (y | ((sizeof(t) & _IOCPARM_MASK_BIG) << 8) \ + | _IOC_INOUT | _IOC_BIG) + /* Decode an ioctl call. */ -#define _MINIX_IOCTL_SIZE(i) (((i) >> 16) & _IOCPARM_MASK) -#define _MINIX_IOCTL_IOR(i) ((i) & _IOC_OUT) -#define _MINIX_IOCTL_IORW(i) ((i) & _IOC_INOUT) -#define _MINIX_IOCTL_IOW(i) ((i) & _IOC_IN) +#define _MINIX_IOCTL_SIZE(i) (((i) >> 16) & _IOCPARM_MASK) +#define _MINIX_IOCTL_IOR(i) ((i) & _IOC_OUT) +#define _MINIX_IOCTL_IORW(i) ((i) & _IOC_INOUT) +#define _MINIX_IOCTL_IOW(i) ((i) & _IOC_IN) + +/* Recognize and decode size of a 'big' ioctl call. */ +#define _MINIX_IOCTL_BIG(i) ((i) & _IOC_BIG) +#define _MINIX_IOCTL_SIZE_BIG(i) (((i) >> 8) & _IOCPARM_MASK_BIG) #else /* No fancy encoding on a 16-bit machine. */ diff --git a/include/sys/ioc_tty.h b/include/sys/ioc_tty.h index e2f09d227..948a41e09 100755 --- a/include/sys/ioc_tty.h +++ b/include/sys/ioc_tty.h @@ -22,7 +22,8 @@ #define TIOCSWINSZ _IOW('T', 17, struct winsize) #define TIOCGPGRP _IOW('T', 18, int) #define TIOCSPGRP _IOW('T', 19, int) -#define TIOCSFON _IOW('T', 20, u8_t [8192]) +#define TIOCSFON_OLD _IOW('T', 20, u8_t [8192]) +#define TIOCSFON _IOW_BIG(1, u8_t [8192]) /* Legacy */ #define TIOCGETP _IOR('t', 1, struct sgttyb) diff --git a/servers/fs/device.c b/servers/fs/device.c index 3426cbc49..3db2a10d3 100644 --- a/servers/fs/device.c +++ b/servers/fs/device.c @@ -24,6 +24,7 @@ #include #include #include +#include #include "file.h" #include "fproc.h" #include "inode.h" @@ -239,7 +240,10 @@ off_t *pos; *op = DEV_IOCTL_S; if(_MINIX_IOCTL_IOR(m_in.REQUEST)) access |= CPF_WRITE; if(_MINIX_IOCTL_IOW(m_in.REQUEST)) access |= CPF_READ; - size = _MINIX_IOCTL_SIZE(m_in.REQUEST); + if(_MINIX_IOCTL_BIG(m_in.REQUEST)) + size = _MINIX_IOCTL_SIZE_BIG(m_in.REQUEST); + else + size = _MINIX_IOCTL_SIZE(m_in.REQUEST); /* Do this even if no I/O happens with the ioctl, in * order to disambiguate requests with DEV_IOCTL_S. -- 2.11.4.GIT