File: /usr/src/linux/arch/mips/kernel/sysirix.c

1     /*
2      * sysirix.c: IRIX system call emulation.
3      *
4      * Copyright (C) 1996 David S. Miller
5      * Copyright (C) 1997 Miguel de Icaza
6      * Copyright (C) 1997, 1998, 1999, 2000 Ralf Baechle
7      */
8     #include <linux/kernel.h>
9     #include <linux/sched.h>
10     #include <linux/pagemap.h>
11     #include <linux/mm.h>
12     #include <linux/mman.h>
13     #include <linux/slab.h>
14     #include <linux/swap.h>
15     #include <linux/errno.h>
16     #include <linux/timex.h>
17     #include <linux/times.h>
18     #include <linux/elf.h>
19     #include <linux/msg.h>
20     #include <linux/shm.h>
21     #include <linux/smp.h>
22     #include <linux/smp_lock.h>
23     #include <linux/utsname.h>
24     #include <linux/file.h>
25     
26     #include <asm/ptrace.h>
27     #include <asm/page.h>
28     #include <asm/pgalloc.h>
29     #include <asm/uaccess.h>
30     #include <asm/inventory.h>
31     
32     /* 2,191 lines of complete and utter shit coming up... */
33     
34     extern int max_threads;
35     
36     /* The sysmp commands supported thus far. */
37     #define MP_NPROCS       	1 /* # processor in complex */
38     #define MP_NAPROCS      	2 /* # active processors in complex */
39     #define MP_PGSIZE           	14 /* Return system page size in v1. */
40     
41     asmlinkage int irix_sysmp(struct pt_regs *regs)
42     {
43     	unsigned long cmd;
44     	int base = 0;
45     	int error = 0;
46     
47     	if(regs->regs[2] == 1000)
48     		base = 1;
49     	cmd = regs->regs[base + 4];
50     	switch(cmd) {
51     	case MP_PGSIZE:
52     		error = PAGE_SIZE;
53     		break;
54     	case MP_NPROCS:
55     	case MP_NAPROCS:
56     		error = smp_num_cpus;
57     		break;
58     	default:
59     		printk("SYSMP[%s:%d]: Unsupported opcode %d\n",
60     		       current->comm, current->pid, (int)cmd);
61     		error = -EINVAL;
62     		break;
63     	}
64     
65     	return error;
66     }
67     
68     /* The prctl commands. */
69     #define PR_MAXPROCS          1 /* Tasks/user. */
70     #define PR_ISBLOCKED         2 /* If blocked, return 1. */
71     #define PR_SETSTACKSIZE      3 /* Set largest task stack size. */
72     #define PR_GETSTACKSIZE      4 /* Get largest task stack size. */
73     #define PR_MAXPPROCS         5 /* Num parallel tasks. */
74     #define PR_UNBLKONEXEC       6 /* When task exec/exit's, unblock. */
75     #define PR_SETEXITSIG        8 /* When task exit's, set signal. */
76     #define PR_RESIDENT          9 /* Make task unswappable. */
77     #define PR_ATTACHADDR       10 /* (Re-)Connect a vma to a task. */
78     #define PR_DETACHADDR       11 /* Disconnect a vma from a task. */
79     #define PR_TERMCHILD        12 /* When parent sleeps with fishes, kill child. */
80     #define PR_GETSHMASK        13 /* Get the sproc() share mask. */
81     #define PR_GETNSHARE        14 /* Number of share group members. */
82     #define PR_COREPID          15 /* Add task pid to name when it core. */
83     #define	PR_ATTACHADDRPERM   16 /* (Re-)Connect vma, with specified prot. */
84     #define PR_PTHREADEXIT      17 /* Kill a pthread without prejudice. */
85     
86     asmlinkage int irix_prctl(struct pt_regs *regs)
87     {
88     	unsigned long cmd;
89     	int error = 0, base = 0;
90     
91     	if (regs->regs[2] == 1000)
92     		base = 1;
93     	cmd = regs->regs[base + 4];
94     	switch (cmd) {
95     	case PR_MAXPROCS:
96     		printk("irix_prctl[%s:%d]: Wants PR_MAXPROCS\n",
97     		       current->comm, current->pid);
98     		error = max_threads;
99     		break;
100     
101     	case PR_ISBLOCKED: {
102     		struct task_struct *task;
103     
104     		printk("irix_prctl[%s:%d]: Wants PR_ISBLOCKED\n",
105     		       current->comm, current->pid);
106     		read_lock(&tasklist_lock);
107     		task = find_task_by_pid(regs->regs[base + 5]);
108     		error = -ESRCH;
109     		if (error)
110     			error = (task->run_list.next != NULL);
111     		read_unlock(&tasklist_lock);
112     		/* Can _your_ OS find this out that fast? */ 
113     		break;
114     	}
115     
116     	case PR_SETSTACKSIZE: {
117     		long value = regs->regs[base + 5];
118     
119     		printk("irix_prctl[%s:%d]: Wants PR_SETSTACKSIZE<%08lx>\n",
120     		       current->comm, current->pid, (unsigned long) value);
121     		if (value > RLIM_INFINITY)
122     			value = RLIM_INFINITY;
123     		if (capable(CAP_SYS_ADMIN)) {
124     			current->rlim[RLIMIT_STACK].rlim_max =
125     				current->rlim[RLIMIT_STACK].rlim_cur = value;
126     			error = value;
127     			break;
128     		}
129     		if (value > current->rlim[RLIMIT_STACK].rlim_max) {
130     			error = -EINVAL;
131     			break;
132     		}
133     		current->rlim[RLIMIT_STACK].rlim_cur = value;
134     		error = value;
135     		break;
136     	}
137     
138     	case PR_GETSTACKSIZE:
139     		printk("irix_prctl[%s:%d]: Wants PR_GETSTACKSIZE\n",
140     		       current->comm, current->pid);
141     		error = current->rlim[RLIMIT_STACK].rlim_cur;
142     		break;
143     
144     	case PR_MAXPPROCS:
145     		printk("irix_prctl[%s:%d]: Wants PR_MAXPROCS\n",
146     		       current->comm, current->pid);
147     		error = 1;
148     		break;
149     
150     	case PR_UNBLKONEXEC:
151     		printk("irix_prctl[%s:%d]: Wants PR_UNBLKONEXEC\n",
152     		       current->comm, current->pid);
153     		error = -EINVAL;
154     		break;
155     
156     	case PR_SETEXITSIG:
157     		printk("irix_prctl[%s:%d]: Wants PR_SETEXITSIG\n",
158     		       current->comm, current->pid);
159     
160     		/* We can probably play some game where we set the task
161     		 * exit_code to some non-zero value when this is requested,
162     		 * and check whether exit_code is already set in do_exit().
163     		 */
164     		error = -EINVAL;
165     		break;
166     
167     	case PR_RESIDENT:
168     		printk("irix_prctl[%s:%d]: Wants PR_RESIDENT\n",
169     		       current->comm, current->pid);
170     		error = 0; /* Compatibility indeed. */
171     		break;
172     
173     	case PR_ATTACHADDR:
174     		printk("irix_prctl[%s:%d]: Wants PR_ATTACHADDR\n",
175     		       current->comm, current->pid);
176     		error = -EINVAL;
177     		break;
178     
179     	case PR_DETACHADDR:
180     		printk("irix_prctl[%s:%d]: Wants PR_DETACHADDR\n",
181     		       current->comm, current->pid);
182     		error = -EINVAL;
183     		break;
184     
185     	case PR_TERMCHILD:
186     		printk("irix_prctl[%s:%d]: Wants PR_TERMCHILD\n",
187     		       current->comm, current->pid);
188     		error = -EINVAL;
189     		break;
190     
191     	case PR_GETSHMASK:
192     		printk("irix_prctl[%s:%d]: Wants PR_GETSHMASK\n",
193     		       current->comm, current->pid);
194     		error = -EINVAL; /* Until I have the sproc() stuff in. */
195     		break;
196     
197     	case PR_GETNSHARE:
198     		error = 0;       /* Until I have the sproc() stuff in. */
199     		break;
200     
201     	case PR_COREPID:
202     		printk("irix_prctl[%s:%d]: Wants PR_COREPID\n",
203     		       current->comm, current->pid);
204     		error = -EINVAL;
205     		break;
206     
207     	case PR_ATTACHADDRPERM:
208     		printk("irix_prctl[%s:%d]: Wants PR_ATTACHADDRPERM\n",
209     		       current->comm, current->pid);
210     		error = -EINVAL;
211     		break;
212     
213     	case PR_PTHREADEXIT:
214     		printk("irix_prctl[%s:%d]: Wants PR_PTHREADEXIT\n",
215     		       current->comm, current->pid);
216     		do_exit(regs->regs[base + 5]);
217     
218     	default:
219     		printk("irix_prctl[%s:%d]: Non-existant opcode %d\n",
220     		       current->comm, current->pid, (int)cmd);
221     		error = -EINVAL;
222     		break;
223     	}
224     
225     	return error;
226     }
227     
228     #undef DEBUG_PROCGRPS
229     
230     extern unsigned long irix_mapelf(int fd, struct elf_phdr *user_phdrp, int cnt);
231     extern asmlinkage int sys_setpgid(pid_t pid, pid_t pgid);
232     extern void sys_sync(void);
233     extern asmlinkage int sys_getsid(pid_t pid);
234     extern asmlinkage long sys_write (unsigned int fd, const char *buf, unsigned long count);
235     extern asmlinkage long sys_lseek (unsigned int fd, off_t offset, unsigned int origin);
236     extern asmlinkage int sys_getgroups(int gidsetsize, gid_t *grouplist);
237     extern asmlinkage int sys_setgroups(int gidsetsize, gid_t *grouplist);
238     extern int getrusage(struct task_struct *p, int who, struct rusage *ru);
239     extern char *prom_getenv(char *name);
240     extern long prom_setenv(char *name, char *value);
241     
242     /* The syssgi commands supported thus far. */
243     #define SGI_SYSID         1       /* Return unique per-machine identifier. */
244     #define SGI_INVENT        5       /* Fetch inventory  */
245     #   define SGI_INV_SIZEOF 1
246     #   define SGI_INV_READ   2
247     #define SGI_RDNAME        6       /* Return string name of a process. */
248     #define SGI_SETNVRAM	  8	  /* Set PROM variable. */
249     #define SGI_GETNVRAM	  9	  /* Get PROM variable. */
250     #define SGI_SETPGID      21       /* Set process group id. */
251     #define SGI_SYSCONF      22       /* POSIX sysconf garbage. */
252     #define SGI_PATHCONF     24       /* POSIX sysconf garbage. */
253     #define SGI_SETGROUPS    40       /* POSIX sysconf garbage. */
254     #define SGI_GETGROUPS    41       /* POSIX sysconf garbage. */
255     #define SGI_RUSAGE       56       /* BSD style rusage(). */
256     #define SGI_SSYNC        62       /* Synchronous fs sync. */
257     #define SGI_GETSID       65       /* SysVr4 get session id. */
258     #define SGI_ELFMAP       68       /* Map an elf image. */
259     #define SGI_TOSSTSAVE   108       /* Toss saved vma's. */
260     #define SGI_FP_BCOPY    129       /* Should FPU bcopy be used on this machine? */
261     #define SGI_PHYSP      1011       /* Translate virtual into physical page. */
262     
263     asmlinkage int irix_syssgi(struct pt_regs *regs)
264     {
265     	unsigned long cmd;
266     	int retval, base = 0;
267     
268     	if (regs->regs[2] == 1000)
269     		base = 1;
270     
271     	cmd = regs->regs[base + 4];
272     	switch(cmd) {
273     	case SGI_SYSID: {
274     		char *buf = (char *) regs->regs[base + 5];
275     
276     		/* XXX Use ethernet addr.... */
277     		retval = clear_user(buf, 64);
278     		break;
279     	}
280     #if 0
281     	case SGI_RDNAME: {
282     		int pid = (int) regs->regs[base + 5];
283     		char *buf = (char *) regs->regs[base + 6];
284     		struct task_struct *p;
285     		char comm[16];
286     
287     		retval = verify_area(VERIFY_WRITE, buf, 16);
288     		if (retval)
289     			break;
290     		read_lock(&tasklist_lock);
291     		p = find_task_by_pid(pid);
292     		if (!p) {
293     			read_unlock(&tasklist_lock);
294     			retval = -ESRCH;
295     			break;
296     		}
297     		memcpy(comm, p->comm, 16);
298     		read_unlock(&tasklist_lock);
299     
300     		/* XXX Need to check sizes. */
301     		copy_to_user(buf, p->comm, 16);
302     		retval = 0;
303     		break;
304     	}
305     
306     	case SGI_GETNVRAM: {
307     		char *name = (char *) regs->regs[base+5];
308     		char *buf = (char *) regs->regs[base+6];
309     		char *value;
310     		return -EINVAL;	/* til I fix it */
311     		retval = verify_area(VERIFY_WRITE, buf, 128);
312     		if (retval)
313     			break;
314     		value = prom_getenv(name);	/* PROM lock?  */
315     		if (!value) {
316     			retval = -EINVAL;
317     			break;
318     		}
319     		/* Do I strlen() for the length? */
320     		copy_to_user(buf, value, 128);
321     		retval = 0;
322     		break;
323     	}
324     
325     	case SGI_SETNVRAM: {
326     		char *name = (char *) regs->regs[base+5];
327     		char *value = (char *) regs->regs[base+6];
328     		return -EINVAL;	/* til I fix it */
329     		retval = prom_setenv(name, value);
330     		/* XXX make sure retval conforms to syssgi(2) */
331     		printk("[%s:%d] setnvram(\"%s\", \"%s\"): retval %d",
332     		       current->comm, current->pid, name, value, retval);
333     /*		if (retval == PROM_ENOENT)
334     		  	retval = -ENOENT; */
335     		break;				   
336     	}
337     #endif
338     
339     	case SGI_SETPGID: {
340     #ifdef DEBUG_PROCGRPS
341     		printk("[%s:%d] setpgid(%d, %d) ",
342     		       current->comm, current->pid,
343     		       (int) regs->regs[base + 5], (int)regs->regs[base + 6]);
344     #endif
345     		retval = sys_setpgid(regs->regs[base + 5], regs->regs[base + 6]);
346     
347     #ifdef DEBUG_PROCGRPS
348     		printk("retval=%d\n", retval);
349     #endif
350     	}
351     
352     	case SGI_SYSCONF: {
353     		switch(regs->regs[base + 5]) {
354     		case 1:
355     			retval = (MAX_ARG_PAGES >> 4); /* XXX estimate... */
356     			goto out;
357     		case 2:
358     			retval = max_threads;
359     			goto out;
360     		case 3:
361     			retval = HZ;
362     			goto out;
363     		case 4:
364     			retval = NGROUPS;
365     			goto out;
366     		case 5:
367     			retval = NR_OPEN;
368     			goto out;
369     		case 6:
370     			retval = 1;
371     			goto out;
372     		case 7:
373     			retval = 1;
374     			goto out;
375     		case 8:
376     			retval = 199009;
377     			goto out;
378     		case 11:
379     			retval = PAGE_SIZE;
380     			goto out;
381     		case 12:
382     			retval = 4;
383     			goto out;
384     		case 25:
385     		case 26:
386     		case 27:
387     		case 28:
388     		case 29:
389     		case 30:
390     			retval = 0;
391     			goto out;
392     		case 31:
393     			retval = 32;
394     			goto out;
395     		default:
396     			retval = -EINVAL;
397     			goto out;
398     		};
399     	}
400     
401     	case SGI_SETGROUPS:
402     		retval = sys_setgroups((int) regs->regs[base + 5],
403     		                       (gid_t *) regs->regs[base + 6]);
404     		break;
405     
406     	case SGI_GETGROUPS:
407     		retval = sys_getgroups((int) regs->regs[base + 5],
408     		                       (gid_t *) regs->regs[base + 6]);
409     		break;
410     
411     	case SGI_RUSAGE: {
412     		struct rusage *ru = (struct rusage *) regs->regs[base + 6];
413     
414     		switch((int) regs->regs[base + 5]) {
415     		case 0:
416     			/* rusage self */
417     			retval = getrusage(current, RUSAGE_SELF, ru);
418     			goto out;
419     
420     		case -1:
421     			/* rusage children */
422     			retval = getrusage(current, RUSAGE_CHILDREN, ru);
423     			goto out;
424     
425     		default:
426     			retval = -EINVAL;
427     			goto out;
428     		};
429     	}
430     
431     	case SGI_SSYNC:
432     		sys_sync();
433     		retval = 0;
434     		break;
435     
436     	case SGI_GETSID:
437     #ifdef DEBUG_PROCGRPS
438     		printk("[%s:%d] getsid(%d) ", current->comm, current->pid,
439     		       (int) regs->regs[base + 5]);
440     #endif
441     		retval = sys_getsid(regs->regs[base + 5]);
442     #ifdef DEBUG_PROCGRPS
443     		printk("retval=%d\n", retval);
444     #endif
445     		break;
446     
447     	case SGI_ELFMAP:
448     		retval = irix_mapelf((int) regs->regs[base + 5],
449     				     (struct elf_phdr *) regs->regs[base + 6],
450     				     (int) regs->regs[base + 7]);
451     		break;
452     
453     	case SGI_TOSSTSAVE:
454     		/* XXX We don't need to do anything? */
455     		retval = 0;
456     		break;
457     
458     	case SGI_FP_BCOPY:
459     		retval = 0;
460     		break;
461     
462     	case SGI_PHYSP: {
463     		unsigned long addr = regs->regs[base + 5];
464     		int *pageno = (int *) (regs->regs[base + 6]);
465     		struct mm_struct *mm = current->mm;
466     		pgd_t *pgdp;
467     		pmd_t *pmdp;
468     		pte_t *ptep;
469     
470     		retval = verify_area(VERIFY_WRITE, pageno, sizeof(int));
471     		if (retval)
472     			return retval;
473     
474     		down_read(&mm->mmap_sem);
475     		pgdp = pgd_offset(mm, addr);
476     		pmdp = pmd_offset(pgdp, addr);
477     		ptep = pte_offset(pmdp, addr);
478     		retval = -EINVAL;
479     		if (ptep) {
480     			pte_t pte = *ptep;
481     
482     			if (pte_val(pte) & (_PAGE_VALID | _PAGE_PRESENT)) {
483     				retval =  put_user((pte_val(pte) & PAGE_MASK) >>
484     				                   PAGE_SHIFT, pageno);
485     			}
486     		}
487     		up_read(&mm->mmap_sem);
488     		break;
489     	}
490     
491     	case SGI_INVENT: {
492     		int  arg1    = (int)    regs->regs [base + 5];
493     		void *buffer = (void *) regs->regs [base + 6];
494     		int  count   = (int)    regs->regs [base + 7];
495     
496     		switch (arg1) {
497     		case SGI_INV_SIZEOF:
498     			retval = sizeof (inventory_t);
499     			break;
500     		case SGI_INV_READ:
501     			retval = dump_inventory_to_user (buffer, count);
502     			break;
503     		default:
504     			retval = -EINVAL;
505     		}
506     		break;
507     	}
508     	
509     	default:
510     		printk("irix_syssgi: Unsupported command %d\n", (int)cmd);
511     		retval = -EINVAL;
512     		break;
513     	};
514     
515     out:
516     	return retval;
517     }
518     
519     asmlinkage int irix_gtime(struct pt_regs *regs)
520     {
521     	return CURRENT_TIME;
522     }
523     
524     int vm_enough_memory(long pages);
525     
526     /*
527      * IRIX is completely broken... it returns 0 on success, otherwise
528      * ENOMEM.
529      */
530     asmlinkage int irix_brk(unsigned long brk)
531     {
532     	unsigned long rlim;
533     	unsigned long newbrk, oldbrk;
534     	struct mm_struct *mm = current->mm;
535     	int ret;
536     
537     	down_write(&mm->mmap_sem);
538     	if (brk < mm->end_code) {
539     		ret = -ENOMEM;
540     		goto out;
541     	}
542     
543     	newbrk = PAGE_ALIGN(brk);
544     	oldbrk = PAGE_ALIGN(mm->brk);
545     	if (oldbrk == newbrk) {
546     		mm->brk = brk;
547     		ret = 0;
548     		goto out;
549     	}
550     
551     	/*
552     	 * Always allow shrinking brk
553     	 */
554     	if (brk <= mm->brk) {
555     		mm->brk = brk;
556     		do_munmap(mm, newbrk, oldbrk-newbrk);
557     		ret = 0;
558     		goto out;
559     	}
560     	/*
561     	 * Check against rlimit and stack..
562     	 */
563     	rlim = current->rlim[RLIMIT_DATA].rlim_cur;
564     	if (rlim >= RLIM_INFINITY)
565     		rlim = ~0;
566     	if (brk - mm->end_code > rlim) {
567     		ret = -ENOMEM;
568     		goto out;
569     	}
570     
571     	/*
572     	 * Check against existing mmap mappings.
573     	 */
574     	if (find_vma_intersection(mm, oldbrk, newbrk+PAGE_SIZE)) {
575     		ret = -ENOMEM;
576     		goto out;
577     	}
578     
579     	/*
580     	 * Check if we have enough memory..
581     	 */
582     	if (!vm_enough_memory((newbrk-oldbrk) >> PAGE_SHIFT)) {
583     		ret = -ENOMEM;
584     		goto out;
585     	}
586     
587     	/*
588     	 * Ok, looks good - let it rip.
589     	 */
590     	mm->brk = brk;
591     	do_brk(oldbrk, newbrk-oldbrk);
592     	ret = 0;
593     
594     out:
595     	up_write(&mm->mmap_sem);
596     	return ret;
597     }
598     
599     asmlinkage int irix_getpid(struct pt_regs *regs)
600     {
601     	regs->regs[3] = current->p_opptr->pid;
602     	return current->pid;
603     }
604     
605     asmlinkage int irix_getuid(struct pt_regs *regs)
606     {
607     	regs->regs[3] = current->euid;
608     	return current->uid;
609     }
610     
611     asmlinkage int irix_getgid(struct pt_regs *regs)
612     {
613     	regs->regs[3] = current->egid;
614     	return current->gid;
615     }
616     
617     extern rwlock_t xtime_lock;
618     
619     asmlinkage int irix_stime(int value)
620     {
621     	if (!capable(CAP_SYS_TIME))
622     		return -EPERM;
623     
624     	write_lock_irq(&xtime_lock);
625     	xtime.tv_sec = value;
626     	xtime.tv_usec = 0;
627     	time_maxerror = MAXPHASE;
628     	time_esterror = MAXPHASE;
629     	write_unlock_irq(&xtime_lock);
630     
631     	return 0;
632     }
633     
634     extern int do_setitimer(int which, struct itimerval *value,
635                             struct itimerval *ovalue);
636     
637     static inline void jiffiestotv(unsigned long jiffies, struct timeval *value)
638     {
639     	value->tv_usec = (jiffies % HZ) * (1000000 / HZ);
640     	value->tv_sec = jiffies / HZ;
641     }
642     
643     static inline void getitimer_real(struct itimerval *value)
644     {
645     	register unsigned long val, interval;
646     
647     	interval = current->it_real_incr;
648     	val = 0;
649     	if (del_timer(&current->real_timer)) {
650     		unsigned long now = jiffies;
651     		val = current->real_timer.expires;
652     		add_timer(&current->real_timer);
653     		/* look out for negative/zero itimer.. */
654     		if (val <= now)
655     			val = now+1;
656     		val -= now;
657     	}
658     	jiffiestotv(val, &value->it_value);
659     	jiffiestotv(interval, &value->it_interval);
660     }
661     
662     asmlinkage unsigned int irix_alarm(unsigned int seconds)
663     {
664     	struct itimerval it_new, it_old;
665     	unsigned int oldalarm;
666     
667     	if (!seconds) {
668     		getitimer_real(&it_old);
669     		del_timer(&current->real_timer);
670     	} else {
671     		it_new.it_interval.tv_sec = it_new.it_interval.tv_usec = 0;
672     		it_new.it_value.tv_sec = seconds;
673     		it_new.it_value.tv_usec = 0;
674     		do_setitimer(ITIMER_REAL, &it_new, &it_old);
675     	}
676     	oldalarm = it_old.it_value.tv_sec;
677     	/*
678     	 * ehhh.. We can't return 0 if we have an alarm pending ...
679     	 * And we'd better return too much than too little anyway
680     	 */
681     	if (it_old.it_value.tv_usec)
682     		oldalarm++;
683     
684     	return oldalarm;
685     }
686     
687     asmlinkage int irix_pause(void)
688     {
689     	current->state = TASK_INTERRUPTIBLE;
690     	schedule();
691     
692     	return -EINTR;
693     }
694     
695     extern asmlinkage long sys_mount(char * dev_name, char * dir_name, char * type,
696     				unsigned long new_flags, void * data);
697     
698     /* XXX need more than this... */
699     asmlinkage int irix_mount(char *dev_name, char *dir_name, unsigned long flags,
700     			  char *type, void *data, int datalen)
701     {
702     	printk("[%s:%d] irix_mount(%p,%p,%08lx,%p,%p,%d)\n",
703     	       current->comm, current->pid,
704     	       dev_name, dir_name, flags, type, data, datalen);
705     
706     	return sys_mount(dev_name, dir_name, type, flags, data);
707     }
708     
709     struct irix_statfs {
710     	short f_type;
711             long  f_bsize, f_frsize, f_blocks, f_bfree, f_files, f_ffree;
712     	char  f_fname[6], f_fpack[6];
713     };
714     
715     asmlinkage int irix_statfs(const char *path, struct irix_statfs *buf,
716     			   int len, int fs_type)
717     {
718     	struct nameidata nd;
719     	struct statfs kbuf;
720     	int error, i;
721     
722     	/* We don't support this feature yet. */
723     	if (fs_type) {
724     		error = -EINVAL;
725     		goto out;
726     	}
727     	error = verify_area(VERIFY_WRITE, buf, sizeof(struct irix_statfs));
728     	if (error)
729     		goto out;
730     	error = user_path_walk(path, &nd);
731     	if (error)
732     		goto out;
733     
734     	error = vfs_statfs(nd.dentry->d_inode->i_sb, &kbuf);
735     	if (error)
736     		goto dput_and_out;
737     
738     	__put_user(kbuf.f_type, &buf->f_type);
739     	__put_user(kbuf.f_bsize, &buf->f_bsize);
740     	__put_user(kbuf.f_frsize, &buf->f_frsize);
741     	__put_user(kbuf.f_blocks, &buf->f_blocks);
742     	__put_user(kbuf.f_bfree, &buf->f_bfree);
743     	__put_user(kbuf.f_files, &buf->f_files);
744     	__put_user(kbuf.f_ffree, &buf->f_ffree);
745     	for (i = 0; i < 6; i++) {
746     		__put_user(0, &buf->f_fname[i]);
747     		__put_user(0, &buf->f_fpack[i]);
748     	}
749     	error = 0;
750     
751     dput_and_out:
752     	path_release(&nd);
753     out:
754     	return error;
755     }
756     
757     asmlinkage int irix_fstatfs(unsigned int fd, struct irix_statfs *buf)
758     {
759     	struct statfs kbuf;
760     	struct file *file;
761     	int error, i;
762     
763     	error = verify_area(VERIFY_WRITE, buf, sizeof(struct irix_statfs));
764     	if (error)
765     		goto out;
766     	if (!(file = fget(fd))) {
767     		error = -EBADF;
768     		goto out;
769     	}
770     
771     	error = vfs_statfs(file->f_dentry->d_inode->i_sb, &kbuf);
772     	if (error)
773     		goto out_f;
774     
775     	__put_user(kbuf.f_type, &buf->f_type);
776     	__put_user(kbuf.f_bsize, &buf->f_bsize);
777     	__put_user(kbuf.f_frsize, &buf->f_frsize);
778     	__put_user(kbuf.f_blocks, &buf->f_blocks);
779     	__put_user(kbuf.f_bfree, &buf->f_bfree);
780     	__put_user(kbuf.f_files, &buf->f_files);
781     	__put_user(kbuf.f_ffree, &buf->f_ffree);
782     	for(i = 0; i < 6; i++) {
783     		__put_user(0, &buf->f_fname[i]);
784     		__put_user(0, &buf->f_fpack[i]);
785     	}
786     
787     out_f:
788     	fput(file);
789     out:
790     	return error;
791     }
792     
793     extern asmlinkage int sys_setpgid(pid_t pid, pid_t pgid);
794     extern asmlinkage int sys_setsid(void);
795     
796     asmlinkage int irix_setpgrp(int flags)
797     {
798     	int error;
799     
800     #ifdef DEBUG_PROCGRPS
801     	printk("[%s:%d] setpgrp(%d) ", current->comm, current->pid, flags);
802     #endif
803     	if(!flags)
804     		error = current->pgrp;
805     	else
806     		error = sys_setsid();
807     #ifdef DEBUG_PROCGRPS
808     	printk("returning %d\n", current->pgrp);
809     #endif
810     
811     	return error;
812     }
813     
814     asmlinkage int irix_times(struct tms * tbuf)
815     {
816     	int err = 0;
817     
818     	if (tbuf) {
819     		err = verify_area(VERIFY_WRITE,tbuf,sizeof *tbuf);
820     		if (err)
821     			return err;
822     		err |= __put_user(current->times.tms_utime,&tbuf->tms_utime);
823     		err |= __put_user(current->times.tms_stime,&tbuf->tms_stime);
824     		err |= __put_user(current->times.tms_cutime,&tbuf->tms_cutime);
825     		err |= __put_user(current->times.tms_cstime,&tbuf->tms_cstime);
826     	}
827     
828     	return err;
829     }
830     
831     asmlinkage int irix_exec(struct pt_regs *regs)
832     {
833     	int error, base = 0;
834     	char *filename;
835     
836     	if(regs->regs[2] == 1000)
837     		base = 1;
838     	filename = getname((char *) (long)regs->regs[base + 4]);
839     	error = PTR_ERR(filename);
840     	if (IS_ERR(filename))
841     		return error;
842     
843     	error = do_execve(filename, (char **) (long)regs->regs[base + 5],
844     	                  (char **) 0, regs);
845     	putname(filename);
846     
847     	return error;
848     }
849     
850     asmlinkage int irix_exece(struct pt_regs *regs)
851     {
852     	int error, base = 0;
853     	char *filename;
854     
855     	if (regs->regs[2] == 1000)
856     		base = 1;
857     	filename = getname((char *) (long)regs->regs[base + 4]);
858     	error = PTR_ERR(filename);
859     	if (IS_ERR(filename))
860     		return error;
861     	error = do_execve(filename, (char **) (long)regs->regs[base + 5],
862     	                  (char **) (long)regs->regs[base + 6], regs);
863     	putname(filename);
864     
865     	return error;
866     }
867     
868     asmlinkage unsigned long irix_gethostid(void)
869     {
870     	printk("[%s:%d]: irix_gethostid() called...\n",
871     	       current->comm, current->pid);
872     
873     	return -EINVAL;
874     }
875     
876     asmlinkage unsigned long irix_sethostid(unsigned long val)
877     {
878     	printk("[%s:%d]: irix_sethostid(%08lx) called...\n",
879     	       current->comm, current->pid, val);
880     
881     	return -EINVAL;
882     }
883     
884     extern asmlinkage int sys_socket(int family, int type, int protocol);
885     
886     asmlinkage int irix_socket(int family, int type, int protocol)
887     {
888     	switch(type) {
889     	case 1:
890     		type = SOCK_DGRAM;
891     		break;
892     
893     	case 2:
894     		type = SOCK_STREAM;
895     		break;
896     
897     	case 3:
898     		type = 9; /* Invalid... */
899     		break;
900     
901     	case 4:
902     		type = SOCK_RAW;
903     		break;
904     
905     	case 5:
906     		type = SOCK_RDM;
907     		break;
908     
909     	case 6:
910     		type = SOCK_SEQPACKET;
911     		break;
912     
913     	default:
914     		break;
915     	}
916     
917     	return sys_socket(family, type, protocol);
918     }
919     
920     asmlinkage int irix_getdomainname(char *name, int len)
921     {
922     	int error;
923     
924     	error = verify_area(VERIFY_WRITE, name, len);
925     	if (error)
926     		return error;
927     
928     	down_read(&uts_sem);
929     	if(len > (__NEW_UTS_LEN - 1))
930     		len = __NEW_UTS_LEN - 1;
931     	error = 0;
932     	if (copy_to_user(name, system_utsname.domainname, len))
933     		error = -EFAULT;
934     	up_read(&uts_sem);
935     
936     	return error;
937     }
938     
939     asmlinkage unsigned long irix_getpagesize(void)
940     {
941     	return PAGE_SIZE;
942     }
943     
944     asmlinkage int irix_msgsys(int opcode, unsigned long arg0, unsigned long arg1,
945     			   unsigned long arg2, unsigned long arg3,
946     			   unsigned long arg4)
947     {
948     	switch (opcode) {
949     	case 0:
950     		return sys_msgget((key_t) arg0, (int) arg1);
951     	case 1:
952     		return sys_msgctl((int) arg0, (int) arg1, (struct msqid_ds *)arg2);
953     	case 2:
954     		return sys_msgrcv((int) arg0, (struct msgbuf *) arg1,
955     				  (size_t) arg2, (long) arg3, (int) arg4);
956     	case 3:
957     		return sys_msgsnd((int) arg0, (struct msgbuf *) arg1,
958     				  (size_t) arg2, (int) arg3);
959     	default:
960     		return -EINVAL;
961     	}
962     }
963     
964     asmlinkage int irix_shmsys(int opcode, unsigned long arg0, unsigned long arg1,
965     			   unsigned long arg2, unsigned long arg3)
966     {
967     	switch (opcode) {
968     	case 0:
969     		return sys_shmat((int) arg0, (char *)arg1, (int) arg2,
970     				 (unsigned long *) arg3);
971     	case 1:
972     		return sys_shmctl((int)arg0, (int)arg1, (struct shmid_ds *)arg2);
973     	case 2:
974     		return sys_shmdt((char *)arg0);
975     	case 3:
976     		return sys_shmget((key_t) arg0, (int) arg1, (int) arg2);
977     	default:
978     		return -EINVAL;
979     	}
980     }
981     
982     asmlinkage int irix_semsys(int opcode, unsigned long arg0, unsigned long arg1,
983     			   unsigned long arg2, int arg3)
984     {
985     	switch (opcode) {
986     	case 0:
987     		return sys_semctl((int) arg0, (int) arg1, (int) arg2,
988     				  (union semun) arg3);
989     	case 1:
990     		return sys_semget((key_t) arg0, (int) arg1, (int) arg2);
991     	case 2:
992     		return sys_semop((int) arg0, (struct sembuf *)arg1,
993     				 (unsigned int) arg2);
994     	default:
995     		return -EINVAL;
996     	}
997     }
998     
999     static inline loff_t llseek(struct file *file, loff_t offset, int origin)
1000     {
1001     	loff_t (*fn)(struct file *, loff_t, int);
1002     	loff_t retval;
1003     
1004     	fn = default_llseek;
1005     	if (file->f_op && file->f_op->llseek)
1006             fn = file->f_op->llseek;
1007     	lock_kernel();
1008     	retval = fn(file, offset, origin);
1009     	unlock_kernel();
1010     	return retval;
1011     }
1012     
1013     asmlinkage int irix_lseek64(int fd, int _unused, int offhi, int offlow,
1014                                 int origin)
1015     {
1016     	int retval;
1017     	struct file * file;
1018     	loff_t offset;
1019     
1020     	retval = -EBADF;
1021     	file = fget(fd);
1022     	if (!file)
1023     		goto bad;
1024     	retval = -EINVAL;
1025     	if (origin > 2)
1026     		goto out_putf;
1027     
1028     	offset = llseek(file, ((loff_t) offhi << 32) | offlow, origin);
1029     	retval = (int) offset;
1030     
1031     out_putf:
1032     	fput(file);
1033     bad:
1034     	return retval;
1035     }
1036     
1037     asmlinkage int irix_sginap(int ticks)
1038     {
1039     	current->state = TASK_INTERRUPTIBLE;
1040     	schedule_timeout(ticks);
1041     	return 0;
1042     }
1043     
1044     asmlinkage int irix_sgikopt(char *istring, char *ostring, int len)
1045     {
1046     	return -EINVAL;
1047     }
1048     
1049     asmlinkage int irix_gettimeofday(struct timeval *tv)
1050     {
1051     	int retval;
1052     
1053     	retval = copy_to_user(tv, &xtime, sizeof(*tv)) ? -EFAULT : 0;
1054     	return retval;
1055     }
1056     
1057     #define IRIX_MAP_AUTOGROW 0x40
1058     
1059     asmlinkage unsigned long irix_mmap32(unsigned long addr, size_t len, int prot,
1060     				     int flags, int fd, off_t offset)
1061     {
1062     	struct file *file = NULL;
1063     	unsigned long retval;
1064     
1065     	if (!(flags & MAP_ANONYMOUS)) {
1066     		if (!(file = fget(fd)))
1067     			return -EBADF;
1068     
1069     		/* Ok, bad taste hack follows, try to think in something else
1070     		 * when reading this.  */
1071     		if (flags & IRIX_MAP_AUTOGROW) {
1072     			unsigned long old_pos;
1073     			long max_size = offset + len;
1074     			
1075     			if (max_size > file->f_dentry->d_inode->i_size) {
1076     				old_pos = sys_lseek (fd, max_size - 1, 0);
1077     				sys_write (fd, "", 1);
1078     				sys_lseek (fd, old_pos, 0);
1079     			}
1080     		}
1081     	}
1082     
1083     	flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
1084     
1085     	down_write(&current->mm->mmap_sem);
1086     	retval = do_mmap(file, addr, len, prot, flags, offset);
1087     	up_write(&current->mm->mmap_sem);
1088     	if (file)
1089     		fput(file);
1090     
1091     	return retval;
1092     }
1093     
1094     asmlinkage int irix_madvise(unsigned long addr, int len, int behavior)
1095     {
1096     	printk("[%s:%d] Wheee.. irix_madvise(%08lx,%d,%d)\n",
1097     	       current->comm, current->pid, addr, len, behavior);
1098     
1099     	return -EINVAL;
1100     }
1101     
1102     asmlinkage int irix_pagelock(char *addr, int len, int op)
1103     {
1104     	printk("[%s:%d] Wheee.. irix_pagelock(%p,%d,%d)\n",
1105     	       current->comm, current->pid, addr, len, op);
1106     
1107     	return -EINVAL;
1108     }
1109     
1110     asmlinkage int irix_quotactl(struct pt_regs *regs)
1111     {
1112     	printk("[%s:%d] Wheee.. irix_quotactl()\n",
1113     	       current->comm, current->pid);
1114     
1115     	return -EINVAL;
1116     }
1117     
1118     asmlinkage int irix_BSDsetpgrp(int pid, int pgrp)
1119     {
1120     	int error;
1121     
1122     #ifdef DEBUG_PROCGRPS
1123     	printk("[%s:%d] BSDsetpgrp(%d, %d) ", current->comm, current->pid,
1124     	       pid, pgrp);
1125     #endif
1126     	if(!pid)
1127     		pid = current->pid;
1128     
1129     	/* Wheee, weird sysv thing... */
1130     	if ((pgrp == 0) && (pid == current->pid))
1131     		error = sys_setsid();
1132     	else
1133     		error = sys_setpgid(pid, pgrp);
1134     
1135     #ifdef DEBUG_PROCGRPS
1136     	printk("error = %d\n", error);
1137     #endif
1138     
1139     	return error;
1140     }
1141     
1142     asmlinkage int irix_systeminfo(int cmd, char *buf, int cnt)
1143     {
1144     	printk("[%s:%d] Wheee.. irix_systeminfo(%d,%p,%d)\n",
1145     	       current->comm, current->pid, cmd, buf, cnt);
1146     
1147     	return -EINVAL;
1148     }
1149     
1150     struct iuname {
1151     	char sysname[257], nodename[257], release[257];
1152     	char version[257], machine[257];
1153     	char m_type[257], base_rel[257];
1154     	char _unused0[257], _unused1[257], _unused2[257];
1155     	char _unused3[257], _unused4[257], _unused5[257];
1156     };
1157     
1158     asmlinkage int irix_uname(struct iuname *buf)
1159     {
1160     	down_read(&uts_sem);
1161     	if (copy_to_user(system_utsname.sysname, buf->sysname, 65)
1162     	    || copy_to_user(system_utsname.nodename, buf->nodename, 65)
1163     	    || copy_to_user(system_utsname.release, buf->release, 65)
1164     	    || copy_to_user(system_utsname.version, buf->version, 65)
1165     	    || copy_to_user(system_utsname.machine, buf->machine, 65)) {
1166     		return -EFAULT;
1167     	}
1168     	up_read(&uts_sem);
1169     
1170     	return 1;
1171     }
1172     
1173     #undef DEBUG_XSTAT
1174     
1175     static inline u32
1176     linux_to_irix_dev_t (dev_t t)
1177     {
1178     	return MAJOR (t) << 18 | MINOR (t);
1179     }
1180     
1181     static inline int irix_xstat32_xlate(struct stat *kb, void *ubuf)
1182     {
1183     	struct xstat32 {
1184     		u32 st_dev, st_pad1[3], st_ino, st_mode, st_nlink, st_uid, st_gid;
1185     		u32 st_rdev, st_pad2[2], st_size, st_pad3;
1186     		u32 st_atime0, st_atime1;
1187     		u32 st_mtime0, st_mtime1;
1188     		u32 st_ctime0, st_ctime1;
1189     		u32 st_blksize, st_blocks;
1190     		char st_fstype[16];
1191     		u32 st_pad4[8];
1192     	} ub;
1193     
1194     	ub.st_dev     = linux_to_irix_dev_t (kb->st_dev);
1195     	ub.st_ino     = kb->st_ino;
1196     	ub.st_mode    = kb->st_mode;
1197     	ub.st_nlink   = kb->st_nlink;
1198     	ub.st_uid     = kb->st_uid;
1199     	ub.st_gid     = kb->st_gid;
1200     	ub.st_rdev    = linux_to_irix_dev_t (kb->st_rdev);
1201     	ub.st_size    = kb->st_size;
1202     	ub.st_atime0  = kb->st_atime;
1203     	ub.st_atime1  = 0;
1204     	ub.st_mtime0  = kb->st_mtime;
1205     	ub.st_mtime1  = 0;
1206     	ub.st_ctime0  = kb->st_ctime;
1207     	ub.st_ctime1  = 0;
1208     	ub.st_blksize = kb->st_blksize;
1209     	ub.st_blocks  = kb->st_blocks;
1210     	strcpy (ub.st_fstype, "efs");
1211     
1212     	return copy_to_user(ubuf, &ub, sizeof(ub)) ? -EFAULT : 0;
1213     }
1214     
1215     static inline void irix_xstat64_xlate(struct stat *sb)
1216     {
1217     	struct xstat64 {
1218     		u32 st_dev; s32 st_pad1[3];
1219     		unsigned long long st_ino;
1220     		u32 st_mode;
1221     		u32 st_nlink; s32 st_uid; s32 st_gid; u32 st_rdev;
1222     		s32 st_pad2[2];
1223     		long long st_size;
1224     		s32 st_pad3;
1225     		struct { s32 tv_sec, tv_nsec; } st_atime, st_mtime, st_ctime;
1226     		s32 st_blksize;
1227     		long long  st_blocks;
1228     		char st_fstype[16];
1229     		s32 st_pad4[8];
1230     	} ks;
1231     
1232     	ks.st_dev = linux_to_irix_dev_t (sb->st_dev);
1233     	ks.st_pad1[0] = ks.st_pad1[1] = ks.st_pad1[2] = 0;
1234     	ks.st_ino = (unsigned long long) sb->st_ino;
1235     	ks.st_mode = (u32) sb->st_mode;
1236     	ks.st_nlink = (u32) sb->st_nlink;
1237     	ks.st_uid = (s32) sb->st_uid;
1238     	ks.st_gid = (s32) sb->st_gid;
1239     	ks.st_rdev = linux_to_irix_dev_t (sb->st_rdev);
1240     	ks.st_pad2[0] = ks.st_pad2[1] = 0;
1241     	ks.st_size = (long long) sb->st_size;
1242     	ks.st_pad3 = 0;
1243     
1244     	/* XXX hackety hack... */
1245     	ks.st_atime.tv_sec = (s32) sb->st_atime; ks.st_atime.tv_nsec = 0;
1246     	ks.st_mtime.tv_sec = (s32) sb->st_atime; ks.st_mtime.tv_nsec = 0;
1247     	ks.st_ctime.tv_sec = (s32) sb->st_atime; ks.st_ctime.tv_nsec = 0;
1248     
1249     	ks.st_blksize = (s32) sb->st_blksize;
1250     	ks.st_blocks = (long long) sb->st_blocks;
1251     	memset(ks.st_fstype, 0, 16);
1252     	ks.st_pad4[0] = ks.st_pad4[1] = ks.st_pad4[2] = ks.st_pad4[3] = 0;
1253     	ks.st_pad4[4] = ks.st_pad4[5] = ks.st_pad4[6] = ks.st_pad4[7] = 0;
1254     
1255     	/* Now write it all back. */
1256     	copy_to_user(sb, &ks, sizeof(struct xstat64));
1257     }
1258     
1259     extern asmlinkage int sys_newstat(char * filename, struct stat * statbuf);
1260     
1261     asmlinkage int irix_xstat(int version, char *filename, struct stat *statbuf)
1262     {
1263     	int retval;
1264     
1265     #ifdef DEBUG_XSTAT
1266     	printk("[%s:%d] Wheee.. irix_xstat(%d,%s,%p) ",
1267     	       current->comm, current->pid, version, filename, statbuf);
1268     #endif
1269     	switch(version) {
1270     	case 2: {
1271     		struct stat kb;
1272     		mm_segment_t old_fs;
1273     
1274     		old_fs = get_fs(); set_fs(get_ds());
1275     		retval = sys_newstat(filename, &kb);
1276     		set_fs(old_fs);
1277     #ifdef DEBUG_XSTAT
1278     		printk("retval[%d]\n", retval);
1279     #endif
1280     		if(retval)
1281     			goto out;
1282     		retval = irix_xstat32_xlate(&kb, statbuf);
1283     		goto out;
1284     	}
1285     
1286     	case 3: {
1287     		retval = sys_newstat(filename, statbuf);
1288     #ifdef DEBUG_XSTAT
1289     		printk("retval[%d]\n", retval);
1290     #endif
1291     		if(retval)
1292     			goto out;
1293     
1294     		irix_xstat64_xlate(statbuf);
1295     		retval = 0;
1296     		break;
1297     	}
1298     
1299     	default:
1300     		retval = -EINVAL;
1301     		break;
1302     	}
1303     
1304     out:
1305     	return retval;
1306     }
1307     
1308     extern asmlinkage int sys_newlstat(char * filename, struct stat * statbuf);
1309     
1310     asmlinkage int irix_lxstat(int version, char *filename, struct stat *statbuf)
1311     {
1312     	int error;
1313     
1314     #ifdef DEBUG_XSTAT
1315     	printk("[%s:%d] Wheee.. irix_lxstat(%d,%s,%p) ",
1316     	       current->comm, current->pid, version, filename, statbuf);
1317     #endif
1318     	switch(version) {
1319     	case 2: {
1320     		struct stat kb;
1321     		mm_segment_t old_fs;
1322     
1323     		old_fs = get_fs(); set_fs(get_ds());
1324     		error = sys_newlstat(filename, &kb);
1325     		set_fs(old_fs);
1326     #ifdef DEBUG_XSTAT
1327     		printk("error[%d]\n", error);
1328     #endif
1329     		if(error)
1330     			goto out;
1331     		error = irix_xstat32_xlate(&kb, statbuf);
1332     		goto out;
1333     	}
1334     
1335     	case 3: {
1336     		error = sys_newlstat(filename, statbuf);
1337     #ifdef DEBUG_XSTAT
1338     		printk("error[%d]\n", error);
1339     #endif
1340     		if(error)
1341     			goto out;
1342     
1343     		irix_xstat64_xlate(statbuf);
1344     		error = 0;
1345     		goto out;
1346     	}
1347     
1348     	default:
1349     		error = -EINVAL;
1350     		goto out;
1351     	}
1352     
1353     out:
1354     	return error;
1355     }
1356     
1357     extern asmlinkage int sys_newfstat(unsigned int fd, struct stat * statbuf);
1358     
1359     asmlinkage int irix_fxstat(int version, int fd, struct stat *statbuf)
1360     {
1361     	int error;
1362     
1363     #ifdef DEBUG_XSTAT
1364     	printk("[%s:%d] Wheee.. irix_fxstat(%d,%d,%p) ",
1365     	       current->comm, current->pid, version, fd, statbuf);
1366     #endif
1367     	switch(version) {
1368     	case 2: {
1369     		struct stat kb;
1370     		mm_segment_t old_fs;
1371     
1372     		old_fs = get_fs(); set_fs(get_ds());
1373     		error = sys_newfstat(fd, &kb);
1374     		set_fs(old_fs);
1375     #ifdef DEBUG_XSTAT
1376     		printk("error[%d]\n", error);
1377     #endif
1378     		if(error)
1379     			goto out;
1380     		error = irix_xstat32_xlate(&kb, statbuf);
1381     		goto out;
1382     	}
1383     
1384     	case 3: {
1385     		error = sys_newfstat(fd, statbuf);
1386     #ifdef DEBUG_XSTAT
1387     		printk("error[%d]\n", error);
1388     #endif
1389     		if(error)
1390     			goto out;
1391     
1392     		irix_xstat64_xlate(statbuf);
1393     		error = 0;
1394     		goto out;
1395     	}
1396     
1397     	default:
1398     		error = -EINVAL;
1399     		goto out;
1400     	}
1401     
1402     out:
1403     	return error;
1404     }
1405     
1406     extern asmlinkage int sys_mknod(const char * filename, int mode, dev_t dev);
1407     
1408     asmlinkage int irix_xmknod(int ver, char *filename, int mode, dev_t dev)
1409     {
1410     	int retval;
1411     
1412     	printk("[%s:%d] Wheee.. irix_xmknod(%d,%s,%x,%x)\n",
1413     	       current->comm, current->pid, ver, filename, mode, (int) dev);
1414     
1415     	switch(ver) {
1416     	case 2:
1417     		retval = sys_mknod(filename, mode, dev);
1418     		break;
1419     
1420     	default:
1421     		retval = -EINVAL;
1422     		break;
1423     	};
1424     
1425     	return retval;
1426     }
1427     
1428     asmlinkage int irix_swapctl(int cmd, char *arg)
1429     {
1430     	printk("[%s:%d] Wheee.. irix_swapctl(%d,%p)\n",
1431     	       current->comm, current->pid, cmd, arg);
1432     
1433     	return -EINVAL;
1434     }
1435     
1436     struct irix_statvfs {
1437     	u32 f_bsize; u32 f_frsize; u32 f_blocks;
1438     	u32 f_bfree; u32 f_bavail; u32 f_files; u32 f_ffree; u32 f_favail;
1439     	u32 f_fsid; char f_basetype[16];
1440     	u32 f_flag; u32 f_namemax;
1441     	char	f_fstr[32]; u32 f_filler[16];
1442     };
1443     
1444     asmlinkage int irix_statvfs(char *fname, struct irix_statvfs *buf)
1445     {
1446     	struct nameidata nd;
1447     	struct statfs kbuf;
1448     	int error, i;
1449     
1450     	printk("[%s:%d] Wheee.. irix_statvfs(%s,%p)\n",
1451     	       current->comm, current->pid, fname, buf);
1452     	error = verify_area(VERIFY_WRITE, buf, sizeof(struct irix_statvfs));
1453     	if (error)
1454     		goto out;
1455     	error = user_path_walk(fname, &nd);
1456     	if (error)
1457     		goto out;
1458     	error = vfs_statfs(nd.dentry->d_inode->i_sb, &kbuf);
1459     	if (error)
1460     		goto dput_and_out;
1461     
1462     	__put_user(kbuf.f_bsize, &buf->f_bsize);
1463     	__put_user(kbuf.f_frsize, &buf->f_frsize);
1464     	__put_user(kbuf.f_blocks, &buf->f_blocks);
1465     	__put_user(kbuf.f_bfree, &buf->f_bfree);
1466     	__put_user(kbuf.f_bfree, &buf->f_bavail);  /* XXX hackety hack... */
1467     	__put_user(kbuf.f_files, &buf->f_files);
1468     	__put_user(kbuf.f_ffree, &buf->f_ffree);
1469     	__put_user(kbuf.f_ffree, &buf->f_favail);  /* XXX hackety hack... */
1470     #ifdef __MIPSEB__
1471     	__put_user(kbuf.f_fsid.val[1], &buf->f_fsid);
1472     #else
1473     	__put_user(kbuf.f_fsid.val[0], &buf->f_fsid);
1474     #endif
1475     	for (i = 0; i < 16; i++)
1476     		__put_user(0, &buf->f_basetype[i]);
1477     	__put_user(0, &buf->f_flag);
1478     	__put_user(kbuf.f_namelen, &buf->f_namemax);
1479     	for (i = 0; i < 32; i++)
1480     		__put_user(0, &buf->f_fstr[i]);
1481     
1482     	error = 0;
1483     
1484     dput_and_out:
1485     	path_release(&nd);
1486     out:
1487     	return error;
1488     }
1489     
1490     asmlinkage int irix_fstatvfs(int fd, struct irix_statvfs *buf)
1491     {
1492     	struct statfs kbuf;
1493     	struct file *file;
1494     	int error, i;
1495     
1496     	printk("[%s:%d] Wheee.. irix_fstatvfs(%d,%p)\n",
1497     	       current->comm, current->pid, fd, buf);
1498     
1499     	error = verify_area(VERIFY_WRITE, buf, sizeof(struct irix_statvfs));
1500     	if (error)
1501     		goto out;
1502     	if (!(file = fget(fd))) {
1503     		error = -EBADF;
1504     		goto out;
1505     	}
1506     	error = vfs_statfs(file->f_dentry->d_inode->i_sb, &kbuf);
1507     	if (error)
1508     		goto out_f;
1509     
1510     	__put_user(kbuf.f_bsize, &buf->f_bsize);
1511     	__put_user(kbuf.f_frsize, &buf->f_frsize);
1512     	__put_user(kbuf.f_blocks, &buf->f_blocks);
1513     	__put_user(kbuf.f_bfree, &buf->f_bfree);
1514     	__put_user(kbuf.f_bfree, &buf->f_bavail); /* XXX hackety hack... */
1515     	__put_user(kbuf.f_files, &buf->f_files);
1516     	__put_user(kbuf.f_ffree, &buf->f_ffree);
1517     	__put_user(kbuf.f_ffree, &buf->f_favail); /* XXX hackety hack... */
1518     #ifdef __MIPSEB__
1519     	__put_user(kbuf.f_fsid.val[1], &buf->f_fsid);
1520     #else
1521     	__put_user(kbuf.f_fsid.val[0], &buf->f_fsid);
1522     #endif
1523     	for(i = 0; i < 16; i++)
1524     		__put_user(0, &buf->f_basetype[i]);
1525     	__put_user(0, &buf->f_flag);
1526     	__put_user(kbuf.f_namelen, &buf->f_namemax);
1527     	__clear_user(&buf->f_fstr, sizeof(buf->f_fstr));
1528     
1529     out_f:
1530     	fput(file);
1531     out:
1532     	return error;
1533     }
1534     
1535     asmlinkage int irix_priocntl(struct pt_regs *regs)
1536     {
1537     	printk("[%s:%d] Wheee.. irix_priocntl()\n",
1538     	       current->comm, current->pid);
1539     
1540     	return -EINVAL;
1541     }
1542     
1543     asmlinkage int irix_sigqueue(int pid, int sig, int code, int val)
1544     {
1545     	printk("[%s:%d] Wheee.. irix_sigqueue(%d,%d,%d,%d)\n",
1546     	       current->comm, current->pid, pid, sig, code, val);
1547     
1548     	return -EINVAL;
1549     }
1550     
1551     extern asmlinkage int sys_truncate(const char * path, unsigned long length);
1552     extern asmlinkage int sys_ftruncate(unsigned int fd, unsigned long length);
1553     
1554     asmlinkage int irix_truncate64(char *name, int pad, int size1, int size2)
1555     {
1556     	int retval;
1557     
1558     	if (size1) {
1559     		retval = -EINVAL;
1560     		goto out;
1561     	}
1562     	retval = sys_truncate(name, size2);
1563     
1564     out:
1565     	return retval;
1566     }
1567     
1568     asmlinkage int irix_ftruncate64(int fd, int pad, int size1, int size2)
1569     {
1570     	int retval;
1571     
1572     	if (size1) {
1573     		retval = -EINVAL;
1574     		goto out;
1575     	}
1576     	retval = sys_ftruncate(fd, size2);
1577     
1578     out:
1579     	return retval;
1580     }
1581     
1582     extern asmlinkage unsigned long
1583     sys_mmap(unsigned long addr, size_t len, int prot, int flags, int fd,
1584              off_t offset);
1585     
1586     asmlinkage int irix_mmap64(struct pt_regs *regs)
1587     {
1588     	int len, prot, flags, fd, off1, off2, error, base = 0;
1589     	unsigned long addr, pgoff, *sp;
1590     	struct file *file = NULL;
1591     
1592     	if (regs->regs[2] == 1000)
1593     		base = 1;
1594     	sp = (unsigned long *) (regs->regs[29] + 16);
1595     	addr = regs->regs[base + 4];
1596     	len = regs->regs[base + 5];
1597     	prot = regs->regs[base + 6];
1598     	if (!base) {
1599     		flags = regs->regs[base + 7];
1600     		error = verify_area(VERIFY_READ, sp, (4 * sizeof(unsigned long)));
1601     		if(error)
1602     			goto out;
1603     		fd = sp[0];
1604     		__get_user(off1, &sp[1]);
1605     		__get_user(off2, &sp[2]);
1606     	} else {
1607     		error = verify_area(VERIFY_READ, sp, (5 * sizeof(unsigned long)));
1608     		if(error)
1609     			goto out;
1610     		__get_user(flags, &sp[0]);
1611     		__get_user(fd, &sp[1]);
1612     		__get_user(off1, &sp[2]);
1613     		__get_user(off2, &sp[3]);
1614     	}
1615     
1616     	if (off1 & PAGE_MASK) {
1617     		error = -EOVERFLOW;
1618     		goto out;
1619     	}
1620     
1621     	pgoff = (off1 << (32 - PAGE_SHIFT)) | (off2 >> PAGE_SHIFT);
1622     
1623     	if (!(flags & MAP_ANONYMOUS)) {
1624     		if (!(file = fget(fd))) {
1625     			error = -EBADF;
1626     			goto out;
1627     		}
1628     
1629     		/* Ok, bad taste hack follows, try to think in something else
1630     		   when reading this */
1631     		if (flags & IRIX_MAP_AUTOGROW) {
1632     			unsigned long old_pos;
1633     			long max_size = off2 + len;
1634     
1635     			if (max_size > file->f_dentry->d_inode->i_size) {
1636     				old_pos = sys_lseek (fd, max_size - 1, 0);
1637     				sys_write (fd, "", 1);
1638     				sys_lseek (fd, old_pos, 0);
1639     			}
1640     		}
1641     	}
1642     
1643     	flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
1644     
1645     	down_write(&current->mm->mmap_sem);
1646     	error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
1647     	up_write(&current->mm->mmap_sem);
1648     
1649     	if (file)
1650     		fput(file);
1651     
1652     out:
1653     	return error;
1654     }
1655     
1656     asmlinkage int irix_dmi(struct pt_regs *regs)
1657     {
1658     	printk("[%s:%d] Wheee.. irix_dmi()\n",
1659     	       current->comm, current->pid);
1660     
1661     	return -EINVAL;
1662     }
1663     
1664     asmlinkage int irix_pread(int fd, char *buf, int cnt, int off64,
1665     			  int off1, int off2)
1666     {
1667     	printk("[%s:%d] Wheee.. irix_pread(%d,%p,%d,%d,%d,%d)\n",
1668     	       current->comm, current->pid, fd, buf, cnt, off64, off1, off2);
1669     
1670     	return -EINVAL;
1671     }
1672     
1673     asmlinkage int irix_pwrite(int fd, char *buf, int cnt, int off64,
1674     			   int off1, int off2)
1675     {
1676     	printk("[%s:%d] Wheee.. irix_pwrite(%d,%p,%d,%d,%d,%d)\n",
1677     	       current->comm, current->pid, fd, buf, cnt, off64, off1, off2);
1678     
1679     	return -EINVAL;
1680     }
1681     
1682     asmlinkage int irix_sgifastpath(int cmd, unsigned long arg0, unsigned long arg1,
1683     				unsigned long arg2, unsigned long arg3,
1684     				unsigned long arg4, unsigned long arg5)
1685     {
1686     	printk("[%s:%d] Wheee.. irix_fastpath(%d,%08lx,%08lx,%08lx,%08lx,"
1687     	       "%08lx,%08lx)\n",
1688     	       current->comm, current->pid, cmd, arg0, arg1, arg2,
1689     	       arg3, arg4, arg5);
1690     
1691     	return -EINVAL;
1692     }
1693     
1694     struct irix_statvfs64 {
1695     	u32  f_bsize; u32 f_frsize;
1696     	u64  f_blocks; u64 f_bfree; u64 f_bavail;
1697     	u64  f_files; u64 f_ffree; u64 f_favail;
1698     	u32  f_fsid;
1699     	char f_basetype[16];
1700     	u32  f_flag; u32 f_namemax;
1701     	char f_fstr[32];
1702     	u32  f_filler[16];
1703     };
1704     
1705     asmlinkage int irix_statvfs64(char *fname, struct irix_statvfs64 *buf)
1706     {
1707     	struct nameidata nd;
1708     	struct statfs kbuf;
1709     	int error, i;
1710     
1711     	printk("[%s:%d] Wheee.. irix_statvfs(%s,%p)\n",
1712     	       current->comm, current->pid, fname, buf);
1713     	error = verify_area(VERIFY_WRITE, buf, sizeof(struct irix_statvfs));
1714     	if(error)
1715     		goto out;
1716     	error = user_path_walk(fname, &nd);
1717     	if (error)
1718     		goto out;
1719     	error = vfs_statfs(nd.dentry->d_inode->i_sb, &kbuf);
1720     	if (error)
1721     		goto dput_and_out;
1722     
1723     	__put_user(kbuf.f_bsize, &buf->f_bsize);
1724     	__put_user(kbuf.f_frsize, &buf->f_frsize);
1725     	__put_user(kbuf.f_blocks, &buf->f_blocks);
1726     	__put_user(kbuf.f_bfree, &buf->f_bfree);
1727     	__put_user(kbuf.f_bfree, &buf->f_bavail);  /* XXX hackety hack... */
1728     	__put_user(kbuf.f_files, &buf->f_files);
1729     	__put_user(kbuf.f_ffree, &buf->f_ffree);
1730     	__put_user(kbuf.f_ffree, &buf->f_favail);  /* XXX hackety hack... */
1731     #ifdef __MIPSEB__
1732     	__put_user(kbuf.f_fsid.val[1], &buf->f_fsid);
1733     #else
1734     	__put_user(kbuf.f_fsid.val[0], &buf->f_fsid);
1735     #endif
1736     	for(i = 0; i < 16; i++)
1737     		__put_user(0, &buf->f_basetype[i]);
1738     	__put_user(0, &buf->f_flag);
1739     	__put_user(kbuf.f_namelen, &buf->f_namemax);
1740     	for(i = 0; i < 32; i++)
1741     		__put_user(0, &buf->f_fstr[i]);
1742     
1743     	error = 0;
1744     
1745     dput_and_out:
1746     	path_release(&nd);
1747     out:
1748     	return error;
1749     }
1750     
1751     asmlinkage int irix_fstatvfs64(int fd, struct irix_statvfs *buf)
1752     {
1753     	struct statfs kbuf;
1754     	struct file *file;
1755     	int error, i;
1756     
1757     	printk("[%s:%d] Wheee.. irix_fstatvfs(%d,%p)\n",
1758     	       current->comm, current->pid, fd, buf);
1759     
1760     	error = verify_area(VERIFY_WRITE, buf, sizeof(struct irix_statvfs));
1761     	if (error)
1762     		goto out;
1763     	if (!(file = fget(fd))) {
1764     		error = -EBADF;
1765     		goto out;
1766     	}
1767     	error = vfs_statfs(file->f_dentry->d_inode->i_sb, &kbuf);
1768     	if (error)
1769     		goto out_f;
1770     
1771     	__put_user(kbuf.f_bsize, &buf->f_bsize);
1772     	__put_user(kbuf.f_frsize, &buf->f_frsize);
1773     	__put_user(kbuf.f_blocks, &buf->f_blocks);
1774     	__put_user(kbuf.f_bfree, &buf->f_bfree);
1775     	__put_user(kbuf.f_bfree, &buf->f_bavail);  /* XXX hackety hack... */
1776     	__put_user(kbuf.f_files, &buf->f_files);
1777     	__put_user(kbuf.f_ffree, &buf->f_ffree);
1778     	__put_user(kbuf.f_ffree, &buf->f_favail);  /* XXX hackety hack... */
1779     #ifdef __MIPSEB__
1780     	__put_user(kbuf.f_fsid.val[1], &buf->f_fsid);
1781     #else
1782     	__put_user(kbuf.f_fsid.val[0], &buf->f_fsid);
1783     #endif
1784     	for(i = 0; i < 16; i++)
1785     		__put_user(0, &buf->f_basetype[i]);
1786     	__put_user(0, &buf->f_flag);
1787     	__put_user(kbuf.f_namelen, &buf->f_namemax);
1788     	__clear_user(buf->f_fstr, sizeof(buf->f_fstr[i]));
1789     
1790     out_f:
1791     	fput(file);
1792     out:
1793     	return error;
1794     }
1795     
1796     asmlinkage int irix_getmountid(char *fname, unsigned long *midbuf)
1797     {
1798     	int err;
1799     
1800     	printk("[%s:%d] irix_getmountid(%s, %p)\n",
1801     	       current->comm, current->pid, fname, midbuf);
1802     	err = verify_area(VERIFY_WRITE, midbuf, (sizeof(unsigned long) * 4));
1803     	if (err)
1804     		return err;
1805     
1806     	/*
1807     	 * The idea with this system call is that when trying to determine
1808     	 * 'pwd' and it's a toss-up for some reason, userland can use the
1809     	 * fsid of the filesystem to try and make the right decision, but
1810     	 * we don't have this so for now. XXX
1811     	 */
1812     	err |= __put_user(0, &midbuf[0]);
1813     	err |= __put_user(0, &midbuf[1]);
1814     	err |= __put_user(0, &midbuf[2]);
1815     	err |= __put_user(0, &midbuf[3]);
1816     
1817     	return err;
1818     }
1819     
1820     asmlinkage int irix_nsproc(unsigned long entry, unsigned long mask,
1821     			   unsigned long arg, unsigned long sp, int slen)
1822     {
1823     	printk("[%s:%d] Wheee.. irix_nsproc(%08lx,%08lx,%08lx,%08lx,%d)\n",
1824     	       current->comm, current->pid, entry, mask, arg, sp, slen);
1825     
1826     	return -EINVAL;
1827     }
1828     
1829     #undef DEBUG_GETDENTS
1830     
1831     struct irix_dirent32 {
1832     	u32  d_ino;
1833     	u32  d_off;
1834     	unsigned short  d_reclen;
1835     	char d_name[1];
1836     };
1837     
1838     struct irix_dirent32_callback {
1839     	struct irix_dirent32 *current_dir;
1840     	struct irix_dirent32 *previous;
1841     	int count;
1842     	int error;
1843     };
1844     
1845     #define NAME_OFFSET32(de) ((int) ((de)->d_name - (char *) (de)))
1846     #define ROUND_UP32(x) (((x)+sizeof(u32)-1) & ~(sizeof(u32)-1))
1847     
1848     static int irix_filldir32(void *__buf, const char *name, int namlen,
1849                               loff_t offset, ino_t ino, unsigned int d_type)
1850     {
1851     	struct irix_dirent32 *dirent;
1852     	struct irix_dirent32_callback *buf =
1853     		 (struct irix_dirent32_callback *)__buf;
1854     	unsigned short reclen = ROUND_UP32(NAME_OFFSET32(dirent) + namlen + 1);
1855     
1856     #ifdef DEBUG_GETDENTS
1857     	printk("\nirix_filldir32[reclen<%d>namlen<%d>count<%d>]",
1858     	       reclen, namlen, buf->count);
1859     #endif
1860     	buf->error = -EINVAL;	/* only used if we fail.. */
1861     	if (reclen > buf->count)
1862     		return -EINVAL;
1863     	dirent = buf->previous;
1864     	if (dirent)
1865     		__put_user(offset, &dirent->d_off);
1866     	dirent = buf->current_dir;
1867     	buf->previous = dirent;
1868     	__put_user(ino, &dirent->d_ino);
1869     	__put_user(reclen, &dirent->d_reclen);
1870     	copy_to_user(dirent->d_name, name, namlen);
1871     	__put_user(0, &dirent->d_name[namlen]);
1872     	((char *) dirent) += reclen;
1873     	buf->current_dir = dirent;
1874     	buf->count -= reclen;
1875     
1876     	return 0;
1877     }
1878     
1879     asmlinkage int irix_ngetdents(unsigned int fd, void * dirent, unsigned int count, int *eob)
1880     {
1881     	struct file *file;
1882     	struct irix_dirent32 *lastdirent;
1883     	struct irix_dirent32_callback buf;
1884     	int error;
1885     
1886     #ifdef DEBUG_GETDENTS
1887     	printk("[%s:%d] ngetdents(%d, %p, %d, %p) ", current->comm,
1888     	       current->pid, fd, dirent, count, eob);
1889     #endif
1890     	error = -EBADF;
1891     	file = fget(fd);
1892     	if (!file)
1893     		goto out;
1894     
1895     	buf.current_dir = (struct irix_dirent32 *) dirent;
1896     	buf.previous = NULL;
1897     	buf.count = count;
1898     	buf.error = 0;
1899     
1900     	error = vfs_readdir(file, irix_filldir32, &buf);
1901     	if (error < 0)
1902     		goto out_putf;
1903     	error = buf.error;
1904     	lastdirent = buf.previous;
1905     	if (lastdirent) {
1906     		put_user(file->f_pos, &lastdirent->d_off);
1907     		error = count - buf.count;
1908     	}
1909     
1910     	if (put_user(0, eob) < 0) {
1911     		error = EFAULT;
1912     		goto out_putf;
1913     	}
1914     
1915     
1916     #ifdef DEBUG_GETDENTS
1917     	printk("eob=%d returning %d\n", *eob, count - buf.count);
1918     #endif
1919     	error = count - buf.count;
1920     
1921     out_putf:
1922     	fput(file);
1923     out:
1924     	return error;
1925     }
1926     
1927     struct irix_dirent64 {
1928     	u64            d_ino;
1929     	u64            d_off;
1930     	unsigned short d_reclen;
1931     	char           d_name[1];
1932     };
1933     
1934     struct irix_dirent64_callback {
1935     	struct irix_dirent64 *curr;
1936     	struct irix_dirent64 *previous;
1937     	int count;
1938     	int error;
1939     };
1940     
1941     #define NAME_OFFSET64(de) ((int) ((de)->d_name - (char *) (de)))
1942     #define ROUND_UP64(x) (((x)+sizeof(u64)-1) & ~(sizeof(u64)-1))
1943     
1944     static int irix_filldir64(void * __buf, const char * name, int namlen,
1945     			  loff_t offset, ino_t ino, unsigned int d_type)
1946     {
1947     	struct irix_dirent64 *dirent;
1948     	struct irix_dirent64_callback * buf =
1949     		(struct irix_dirent64_callback *) __buf;
1950     	unsigned short reclen = ROUND_UP64(NAME_OFFSET64(dirent) + namlen + 1);
1951     
1952     	buf->error = -EINVAL;	/* only used if we fail.. */
1953     	if (reclen > buf->count)
1954     		return -EINVAL;
1955     	dirent = buf->previous;
1956     	if (dirent)
1957     		__put_user(offset, &dirent->d_off);
1958     	dirent = buf->curr;
1959     	buf->previous = dirent;
1960     	__put_user(ino, &dirent->d_ino);
1961     	__put_user(reclen, &dirent->d_reclen);
1962     	__copy_to_user(dirent->d_name, name, namlen);
1963     	__put_user(0, &dirent->d_name[namlen]);
1964     	((char *) dirent) += reclen;
1965     	buf->curr = dirent;
1966     	buf->count -= reclen;
1967     
1968     	return 0;
1969     }
1970     
1971     asmlinkage int irix_getdents64(int fd, void *dirent, int cnt)
1972     {
1973     	struct file *file;
1974     	struct irix_dirent64 *lastdirent;
1975     	struct irix_dirent64_callback buf;
1976     	int error;
1977     
1978     #ifdef DEBUG_GETDENTS
1979     	printk("[%s:%d] getdents64(%d, %p, %d) ", current->comm,
1980     	       current->pid, fd, dirent, cnt);
1981     #endif
1982     	error = -EBADF;
1983     	if (!(file = fget(fd)))
1984     		goto out;
1985     
1986     	error = -EFAULT;
1987     	if (!access_ok(VERIFY_WRITE, dirent, cnt))
1988     		goto out_f;
1989     
1990     	error = -EINVAL;
1991     	if (cnt < (sizeof(struct irix_dirent64) + 255))
1992     		goto out_f;
1993     
1994     	buf.curr = (struct irix_dirent64 *) dirent;
1995     	buf.previous = NULL;
1996     	buf.count = cnt;
1997     	buf.error = 0;
1998     	error = vfs_readdir(file, irix_filldir64, &buf);
1999     	if (error < 0)
2000     		goto out_f;
2001     	lastdirent = buf.previous;
2002     	if (!lastdirent) {
2003     		error = buf.error;
2004     		goto out_f;
2005     	}
2006     	lastdirent->d_off = (u64) file->f_pos;
2007     #ifdef DEBUG_GETDENTS
2008     	printk("returning %d\n", cnt - buf.count);
2009     #endif
2010     	error = cnt - buf.count;
2011     
2012     out_f:
2013     	fput(file);
2014     out:
2015     	return error;
2016     }
2017     
2018     asmlinkage int irix_ngetdents64(int fd, void *dirent, int cnt, int *eob)
2019     {
2020     	struct file *file;
2021     	struct irix_dirent64 *lastdirent;
2022     	struct irix_dirent64_callback buf;
2023     	int error;
2024     
2025     #ifdef DEBUG_GETDENTS
2026     	printk("[%s:%d] ngetdents64(%d, %p, %d) ", current->comm,
2027     	       current->pid, fd, dirent, cnt);
2028     #endif
2029     	error = -EBADF;
2030     	if (!(file = fget(fd)))
2031     		goto out;
2032     
2033     	error = -EFAULT;
2034     	if (!access_ok(VERIFY_WRITE, dirent, cnt) ||
2035     	    !access_ok(VERIFY_WRITE, eob, sizeof(*eob)))
2036     		goto out_f;
2037     
2038     	error = -EINVAL;
2039     	if (cnt < (sizeof(struct irix_dirent64) + 255))
2040     		goto out_f;
2041     
2042     	*eob = 0;
2043     	buf.curr = (struct irix_dirent64 *) dirent;
2044     	buf.previous = NULL;
2045     	buf.count = cnt;
2046     	buf.error = 0;
2047     	error = vfs_readdir(file, irix_filldir64, &buf);
2048     	if (error < 0)
2049     		goto out_f;
2050     	lastdirent = buf.previous;
2051     	if (!lastdirent) {
2052     		error = buf.error;
2053     		goto out_f;
2054     	}
2055     	lastdirent->d_off = (u64) file->f_pos;
2056     #ifdef DEBUG_GETDENTS
2057     	printk("eob=%d returning %d\n", *eob, cnt - buf.count);
2058     #endif
2059     	error = cnt - buf.count;
2060     
2061     out_f:
2062     	fput(file);
2063     out:
2064     	return error;
2065     }
2066     
2067     asmlinkage int irix_uadmin(unsigned long op, unsigned long func, unsigned long arg)
2068     {
2069     	int retval;
2070     
2071     	switch (op) {
2072     	case 1:
2073     		/* Reboot */
2074     		printk("[%s:%d] irix_uadmin: Wants to reboot...\n",
2075     		       current->comm, current->pid);
2076     		retval = -EINVAL;
2077     		goto out;
2078     
2079     	case 2:
2080     		/* Shutdown */
2081     		printk("[%s:%d] irix_uadmin: Wants to shutdown...\n",
2082     		       current->comm, current->pid);
2083     		retval = -EINVAL;
2084     		goto out;
2085     
2086     	case 4:
2087     		/* Remount-root */
2088     		printk("[%s:%d] irix_uadmin: Wants to remount root...\n",
2089     		       current->comm, current->pid);
2090     		retval = -EINVAL;
2091     		goto out;
2092     
2093     	case 8:
2094     		/* Kill all tasks. */
2095     		printk("[%s:%d] irix_uadmin: Wants to kill all tasks...\n",
2096     		       current->comm, current->pid);
2097     		retval = -EINVAL;
2098     		goto out;
2099     
2100     	case 256:
2101     		/* Set magic mushrooms... */
2102     		printk("[%s:%d] irix_uadmin: Wants to set magic mushroom[%d]...\n",
2103     		       current->comm, current->pid, (int) func);
2104     		retval = -EINVAL;
2105     		goto out;
2106     
2107     	default:
2108     		printk("[%s:%d] irix_uadmin: Unknown operation [%d]...\n",
2109     		       current->comm, current->pid, (int) op);
2110     		retval = -EINVAL;
2111     		goto out;
2112     	};
2113     
2114     out:
2115     	return retval;
2116     }
2117     
2118     asmlinkage int irix_utssys(char *inbuf, int arg, int type, char *outbuf)
2119     {
2120     	int retval;
2121     
2122     	switch(type) {
2123     	case 0:
2124     		/* uname() */
2125     		retval = irix_uname((struct iuname *)inbuf);
2126     		goto out;
2127     
2128     	case 2:
2129     		/* ustat() */
2130     		printk("[%s:%d] irix_utssys: Wants to do ustat()\n",
2131     		       current->comm, current->pid);
2132     		retval = -EINVAL;
2133     		goto out;
2134     
2135     	case 3:
2136     		/* fusers() */
2137     		printk("[%s:%d] irix_utssys: Wants to do fusers()\n",
2138     		       current->comm, current->pid);
2139     		retval = -EINVAL;
2140     		goto out;
2141     
2142     	default:
2143     		printk("[%s:%d] irix_utssys: Wants to do unknown type[%d]\n",
2144     		       current->comm, current->pid, (int) type);
2145     		retval = -EINVAL;
2146     		goto out;
2147     	}
2148     
2149     out:
2150     	return retval;
2151     }
2152     
2153     #undef DEBUG_FCNTL
2154     
2155     extern asmlinkage long sys_fcntl(unsigned int fd, unsigned int cmd,
2156     				 unsigned long arg);
2157     
2158     #define IRIX_F_ALLOCSP 10
2159     
2160     asmlinkage int irix_fcntl(int fd, int cmd, int arg)
2161     {
2162     	int retval;
2163     
2164     #ifdef DEBUG_FCNTL
2165     	printk("[%s:%d] irix_fcntl(%d, %d, %d) ", current->comm,
2166     	       current->pid, fd, cmd, arg);
2167     #endif
2168     	if (cmd == IRIX_F_ALLOCSP){
2169     		return 0;
2170     	}
2171     	retval = sys_fcntl(fd, cmd, arg);
2172     #ifdef DEBUG_FCNTL
2173     	printk("%d\n", retval);
2174     #endif
2175     	return retval;
2176     }
2177     
2178     asmlinkage int irix_ulimit(int cmd, int arg)
2179     {
2180     	int retval;
2181     
2182     	switch(cmd) {
2183     	case 1:
2184     		printk("[%s:%d] irix_ulimit: Wants to get file size limit.\n",
2185     		       current->comm, current->pid);
2186     		retval = -EINVAL;
2187     		goto out;
2188     
2189     	case 2:
2190     		printk("[%s:%d] irix_ulimit: Wants to set file size limit.\n",
2191     		       current->comm, current->pid);
2192     		retval = -EINVAL;
2193     		goto out;
2194     
2195     	case 3:
2196     		printk("[%s:%d] irix_ulimit: Wants to get brk limit.\n",
2197     		       current->comm, current->pid);
2198     		retval = -EINVAL;
2199     		goto out;
2200     
2201     	case 4:
2202     #if 0
2203     		printk("[%s:%d] irix_ulimit: Wants to get fd limit.\n",
2204     		       current->comm, current->pid);
2205     		retval = -EINVAL;
2206     		goto out;
2207     #endif
2208     		retval = current->rlim[RLIMIT_NOFILE].rlim_cur;
2209     		goto out;
2210     
2211     	case 5:
2212     		printk("[%s:%d] irix_ulimit: Wants to get txt offset.\n",
2213     		       current->comm, current->pid);
2214     		retval = -EINVAL;
2215     		goto out;
2216     
2217     	default:
2218     		printk("[%s:%d] irix_ulimit: Unknown command [%d].\n",
2219     		       current->comm, current->pid, cmd);
2220     		retval = -EINVAL;
2221     		goto out;
2222     	}
2223     out:
2224     	return retval;
2225     }
2226     
2227     asmlinkage int irix_unimp(struct pt_regs *regs)
2228     {
2229     	printk("irix_unimp [%s:%d] v0=%d v1=%d a0=%08lx a1=%08lx a2=%08lx "
2230     	       "a3=%08lx\n", current->comm, current->pid,
2231     	       (int) regs->regs[2], (int) regs->regs[3],
2232     	       regs->regs[4], regs->regs[5], regs->regs[6], regs->regs[7]);
2233     
2234     	return -ENOSYS;
2235     }
2236