summaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorMiguel de Icaza <miguel@nuclecu.unam.mx>1997-09-21 22:58:44 +0000
committerMiguel de Icaza <miguel@nuclecu.unam.mx>1997-09-21 22:58:44 +0000
commitd2694e61bb4bf77c3ff96c4e308572a1b41d0231 (patch)
tree1ab2de9d4c7fb1897aba80875d54080605b62e07 /arch
parent3235bbb7f72c2f2e6a3c72981d648f271da5449d (diff)
1. inventory support.
2. Autogrow mmap flag for irix binaries bad taste hack. 3. fixed irix stat32 4. IRIX_ALLOC_SP fcntl ignored.
Diffstat (limited to 'arch')
-rw-r--r--arch/mips/kernel/sysirix.c126
1 files changed, 105 insertions, 21 deletions
diff --git a/arch/mips/kernel/sysirix.c b/arch/mips/kernel/sysirix.c
index 011a4e5cc..711a52791 100644
--- a/arch/mips/kernel/sysirix.c
+++ b/arch/mips/kernel/sysirix.c
@@ -1,7 +1,8 @@
-/* $Id: sysirix.c,v 1.6 1997/08/11 22:24:56 shaver Exp $
+/* $Id: sysirix.c,v 1.7 1997/09/13 23:49:30 shaver Exp $
* sysirix.c: IRIX system call emulation.
*
* Copyright (C) 1996 David S. Miller
+ * Copyright (C) 1997 Miguel de Icaza
*/
#include <linux/kernel.h>
@@ -26,8 +27,9 @@
#include <asm/pgtable.h>
#include <asm/uaccess.h>
#include <asm/sgialib.h>
+#include <asm/inventory.h>
-/* 2,300 lines of complete and utter shit coming up... */
+/* 2,526 lines of complete and utter shit coming up... */
/* The sysmp commands supported thus far. */
#define MP_NPROCS 1 /* # processor in complex */
@@ -49,9 +51,8 @@ asmlinkage int irix_sysmp(struct pt_regs *regs)
error = PAGE_SIZE;
break;
case MP_NPROCS:
- error = NR_CPUS;
- break;
case MP_NAPROCS:
+ error = 1;
error = NR_CPUS;
break;
default:
@@ -233,6 +234,8 @@ extern unsigned long irix_mapelf(int fd, struct elf_phdr *user_phdrp, int cnt);
extern asmlinkage int sys_setpgid(pid_t pid, pid_t pgid);
extern void sys_sync(void);
extern asmlinkage int sys_getsid(pid_t pid);
+extern asmlinkage long sys_write (unsigned int fd, const char *buf, unsigned long count);
+extern asmlinkage long sys_lseek (unsigned int fd, off_t offset, unsigned int origin);
extern asmlinkage int sys_getgroups(int gidsetsize, gid_t *grouplist);
extern asmlinkage int sys_setgroups(int gidsetsize, gid_t *grouplist);
extern int getrusage(struct task_struct *p, int who, struct rusage *ru);
@@ -241,6 +244,9 @@ extern long prom_setenv(char *name, char *value);
/* The syssgi commands supported thus far. */
#define SGI_SYSID 1 /* Return unique per-machine identifier. */
+#define SGI_INVENT 5 /* Fetch inventory */
+# define SGI_INV_SIZEOF 1
+# define SGI_INV_READ 2
#define SGI_RDNAME 6 /* Return string name of a process. */
#define SGI_SETNVRAM 8 /* Set PROM variable. */
#define SGI_GETNVRAM 9 /* Get PROM variable. */
@@ -275,7 +281,7 @@ asmlinkage int irix_syssgi(struct pt_regs *regs)
retval = clear_user(buf, 64);
break;
}
-
+#if 0
case SGI_RDNAME: {
int pid = (int) regs->regs[base + 5];
char *buf = (char *) regs->regs[base + 6];
@@ -325,11 +331,12 @@ asmlinkage int irix_syssgi(struct pt_regs *regs)
printk("[%s:%d] setnvram(\"%s\", \"%s\"): retval %d",
current->comm, current->pid,
name, value, retval);
- if (retval == PROM_ENOENT)
- retval = -ENOENT;
+/* if (retval == PROM_ENOENT)
+ retval = -ENOENT; */
break;
}
-
+#endif
+
case SGI_SETPGID: {
#ifdef DEBUG_PROCGRPS
printk("[%s:%d] setpgid(%d, %d) ",
@@ -476,6 +483,24 @@ asmlinkage int irix_syssgi(struct pt_regs *regs)
break;
}
+ case SGI_INVENT: {
+ int arg1 = (int) regs->regs [base + 5];
+ void *buffer = (void *) regs->regs [base + 6];
+ int count = (int) regs->regs [base + 7];
+
+ switch (arg1){
+ case SGI_INV_SIZEOF:
+ retval = sizeof (inventory_t);
+ break;
+ case SGI_INV_READ:
+ retval = dump_inventory_to_user (buffer, count);
+ break;
+ default:
+ retval = -EINVAL;
+ }
+ break;
+ }
+
default:
printk("irix_syssgi: Unsupported command %d\n", (int)cmd);
retval = -EINVAL;
@@ -799,7 +824,6 @@ asmlinkage int irix_fstatfs(unsigned int fd, struct irix_statfs *buf)
}
error = 0;
-dput_and_out:
dput(dentry);
out:
unlock_kernel();
@@ -1076,6 +1100,8 @@ asmlinkage int irix_gettimeofday(struct timeval *tv)
return retval;
}
+#define IRIX_MAP_AUTOGROW 0x40
+
asmlinkage unsigned long irix_mmap32(unsigned long addr, size_t len, int prot,
int flags, int fd, off_t offset)
{
@@ -1088,7 +1114,19 @@ asmlinkage unsigned long irix_mmap32(unsigned long addr, size_t len, int prot,
retval = -EBADF;
goto out;
}
+ /* Ok, bad taste hack follows, try to think in something else when reading this */
+ if (flags & IRIX_MAP_AUTOGROW){
+ unsigned long old_pos;
+ long max_size = offset + len;
+
+ if (max_size > file->f_dentry->d_inode->i_size){
+ old_pos = sys_lseek (fd, max_size - 1, 0);
+ sys_write (fd, "", 1);
+ sys_lseek (fd, old_pos, 0);
+ }
+ }
}
+
flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
retval = do_mmap(file, addr, len, prot, flags, offset);
@@ -1190,7 +1228,13 @@ out:
#undef DEBUG_XSTAT
-static inline int irix_xstat32_xlate(struct stat *kb, struct stat *ubuf)
+static inline u32
+linux_to_irix_dev_t (dev_t t)
+{
+ return MAJOR (t) << 18 | MINOR (t);
+}
+
+static inline int irix_xstat32_xlate(struct stat *kb, void *ubuf)
{
struct xstat32 {
u32 st_dev, st_pad1[3], st_ino, st_mode, st_nlink, st_uid, st_gid;
@@ -1201,9 +1245,27 @@ static inline int irix_xstat32_xlate(struct stat *kb, struct stat *ubuf)
u32 st_blksize, st_blocks;
char st_fstype[16];
u32 st_pad4[8];
- } *ub = (struct xstat32 *) ubuf;
-
- return copy_to_user(ub, kb, sizeof(*ub)) ? -EFAULT : 0;
+ } ub;
+
+ ub.st_dev = linux_to_irix_dev_t (kb->st_dev);
+ ub.st_ino = kb->st_ino;
+ ub.st_mode = kb->st_mode;
+ ub.st_nlink = kb->st_nlink;
+ ub.st_uid = kb->st_uid;
+ ub.st_gid = kb->st_gid;
+ ub.st_rdev = linux_to_irix_dev_t (kb->st_rdev);
+ ub.st_size = kb->st_size;
+ ub.st_atime0 = kb->st_atime;
+ ub.st_atime1 = 0;
+ ub.st_mtime0 = kb->st_mtime;
+ ub.st_mtime1 = 0;
+ ub.st_ctime0 = kb->st_ctime;
+ ub.st_ctime1 = 0;
+ ub.st_blksize = kb->st_blksize;
+ ub.st_blocks = kb->st_blocks;
+ strcpy (ub.st_fstype, "efs");
+
+ return copy_to_user(ubuf, &ub, sizeof(ub)) ? -EFAULT : 0;
}
static inline void irix_xstat64_xlate(struct stat *sb)
@@ -1223,14 +1285,14 @@ static inline void irix_xstat64_xlate(struct stat *sb)
s32 st_pad4[8];
} ks;
- ks.st_dev = (u32) sb->st_dev;
+ ks.st_dev = linux_to_irix_dev_t (sb->st_dev);
ks.st_pad1[0] = ks.st_pad1[1] = ks.st_pad1[2] = 0;
ks.st_ino = (unsigned long long) sb->st_ino;
ks.st_mode = (u32) sb->st_mode;
ks.st_nlink = (u32) sb->st_nlink;
ks.st_uid = (s32) sb->st_uid;
ks.st_gid = (s32) sb->st_gid;
- ks.st_rdev = (u32) sb->st_rdev;
+ ks.st_rdev = linux_to_irix_dev_t (sb->st_rdev);
ks.st_pad2[0] = ks.st_pad2[1] = 0;
ks.st_size = (long long) sb->st_size;
ks.st_pad3 = 0;
@@ -1564,7 +1626,6 @@ asmlinkage int irix_fstatvfs(int fd, struct irix_statvfs *buf)
error = 0;
-dput_and_out:
dput(dentry);
out:
unlock_kernel();
@@ -1719,10 +1780,10 @@ extern asmlinkage unsigned long sys_mmap(unsigned long addr, size_t len, int pro
asmlinkage int irix_mmap64(struct pt_regs *regs)
{
+ int len, prot, flags, fd, off1, off2, error, base = 0;
unsigned long addr, *sp;
- int len, prot, flags, fd, off1, off2, base = 0;
- int error;
-
+ struct file *file;
+
lock_kernel();
if(regs->regs[2] == 1000)
base = 1;
@@ -1751,6 +1812,26 @@ asmlinkage int irix_mmap64(struct pt_regs *regs)
error = -EINVAL;
goto out;
}
+
+ if(!(flags & MAP_ANONYMOUS)) {
+ if(fd >= NR_OPEN || !(file = current->files->fd[fd])) {
+ error = -EBADF;
+ goto out;
+ }
+
+ /* Ok, bad taste hack follows, try to think in something else when reading this */
+ if (flags & IRIX_MAP_AUTOGROW){
+ unsigned long old_pos;
+ long max_size = off2 + len;
+
+ if (max_size > file->f_dentry->d_inode->i_size){
+ old_pos = sys_lseek (fd, max_size - 1, 0);
+ sys_write (fd, "", 1);
+ sys_lseek (fd, old_pos, 0);
+ }
+ }
+ }
+
error = sys_mmap(addr, (size_t) len, prot, flags, fd, off2);
out:
@@ -1929,7 +2010,6 @@ asmlinkage int irix_fstatvfs64(int fd, struct irix_statvfs *buf)
error = 0;
-dput_and_out:
dput(dentry);
out:
unlock_kernel();
@@ -2360,6 +2440,8 @@ out:
extern asmlinkage long sys_fcntl(unsigned int fd, unsigned int cmd,
unsigned long arg);
+#define IRIX_F_ALLOCSP 10
+
asmlinkage int irix_fcntl(int fd, int cmd, int arg)
{
int retval;
@@ -2369,7 +2451,9 @@ asmlinkage int irix_fcntl(int fd, int cmd, int arg)
printk("[%s:%d] irix_fcntl(%d, %d, %d) ", current->comm,
current->pid, fd, cmd, arg);
#endif
-
+ if (cmd == IRIX_F_ALLOCSP){
+ return 0;
+ }
retval = sys_fcntl(fd, cmd, arg);
#ifdef DEBUG_FCNTL
printk("%d\n", retval);