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