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(¤t->real_timer)) {
650 unsigned long now = jiffies;
651 val = current->real_timer.expires;
652 add_timer(¤t->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(¤t->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(¤t->mm->mmap_sem);
1086 retval = do_mmap(file, addr, len, prot, flags, offset);
1087 up_write(¤t->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(¤t->mm->mmap_sem);
1646 error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
1647 up_write(¤t->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