1
2
3
4
5
6
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
33
34extern int max_threads;
35
36
37#define MP_NPROCS 1
38#define MP_NAPROCS 2
39#define MP_PGSIZE 14
40
41asmlinkage 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
69#define PR_MAXPROCS 1
70#define PR_ISBLOCKED 2
71#define PR_SETSTACKSIZE 3
72#define PR_GETSTACKSIZE 4
73#define PR_MAXPPROCS 5
74#define PR_UNBLKONEXEC 6
75#define PR_SETEXITSIG 8
76#define PR_RESIDENT 9
77#define PR_ATTACHADDR 10
78#define PR_DETACHADDR 11
79#define PR_TERMCHILD 12
80#define PR_GETSHMASK 13
81#define PR_GETNSHARE 14
82#define PR_COREPID 15
83#define PR_ATTACHADDRPERM 16
84#define PR_PTHREADEXIT 17
85
86asmlinkage 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
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
161
162
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;
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;
195 break;
196
197 case PR_GETNSHARE:
198 error = 0;
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
230extern unsigned long irix_mapelf(int fd, struct elf_phdr *user_phdrp, int cnt);
231extern asmlinkage int sys_setpgid(pid_t pid, pid_t pgid);
232extern void sys_sync(void);
233extern asmlinkage int sys_getsid(pid_t pid);
234extern asmlinkage long sys_write (unsigned int fd, const char *buf, unsigned long count);
235extern asmlinkage long sys_lseek (unsigned int fd, off_t offset, unsigned int origin);
236extern asmlinkage int sys_getgroups(int gidsetsize, gid_t *grouplist);
237extern asmlinkage int sys_setgroups(int gidsetsize, gid_t *grouplist);
238extern int getrusage(struct task_struct *p, int who, struct rusage *ru);
239extern char *prom_getenv(char *name);
240extern long prom_setenv(char *name, char *value);
241
242
243#define SGI_SYSID 1
244#define SGI_INVENT 5
245# define SGI_INV_SIZEOF 1
246# define SGI_INV_READ 2
247#define SGI_RDNAME 6
248#define SGI_SETNVRAM 8
249#define SGI_GETNVRAM 9
250#define SGI_SETPGID 21
251#define SGI_SYSCONF 22
252#define SGI_PATHCONF 24
253#define SGI_SETGROUPS 40
254#define SGI_GETGROUPS 41
255#define SGI_RUSAGE 56
256#define SGI_SSYNC 62
257#define SGI_GETSID 65
258#define SGI_ELFMAP 68
259#define SGI_TOSSTSAVE 108
260#define SGI_FP_BCOPY 129
261#define SGI_PHYSP 1011
262
263asmlinkage 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
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
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;
311 retval = verify_area(VERIFY_WRITE, buf, 128);
312 if (retval)
313 break;
314 value = prom_getenv(name);
315 if (!value) {
316 retval = -EINVAL;
317 break;
318 }
319
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;
329 retval = prom_setenv(name, value);
330
331 printk("[%s:%d] setnvram(\"%s\", \"%s\"): retval %d",
332 current->comm, current->pid, name, value, retval);
333
334
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);
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
417 retval = getrusage(current, RUSAGE_SELF, ru);
418 goto out;
419
420 case -1:
421
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
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
515out:
516 return retval;
517}
518
519asmlinkage int irix_gtime(struct pt_regs *regs)
520{
521 return CURRENT_TIME;
522}
523
524int vm_enough_memory(long pages);
525
526
527
528
529
530asmlinkage 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
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
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
573
574 if (find_vma_intersection(mm, oldbrk, newbrk+PAGE_SIZE)) {
575 ret = -ENOMEM;
576 goto out;
577 }
578
579
580
581
582 if (!vm_enough_memory((newbrk-oldbrk) >> PAGE_SHIFT)) {
583 ret = -ENOMEM;
584 goto out;
585 }
586
587
588
589
590 mm->brk = brk;
591 do_brk(oldbrk, newbrk-oldbrk);
592 ret = 0;
593
594out:
595 up_write(&mm->mmap_sem);
596 return ret;
597}
598
599asmlinkage int irix_getpid(struct pt_regs *regs)
600{
601 regs->regs[3] = current->p_opptr->pid;
602 return current->pid;
603}
604
605asmlinkage int irix_getuid(struct pt_regs *regs)
606{
607 regs->regs[3] = current->euid;
608 return current->uid;
609}
610
611asmlinkage int irix_getgid(struct pt_regs *regs)
612{
613 regs->regs[3] = current->egid;
614 return current->gid;
615}
616
617extern rwlock_t xtime_lock;
618
619asmlinkage 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_adjust = 0;
628 time_status |= STA_UNSYNC;
629 time_maxerror = NTP_PHASE_LIMIT;
630 time_esterror = NTP_PHASE_LIMIT;
631 write_unlock_irq(&xtime_lock);
632
633 return 0;
634}
635
636extern int do_setitimer(int which, struct itimerval *value,
637 struct itimerval *ovalue);
638
639static inline void jiffiestotv(unsigned long jiffies, struct timeval *value)
640{
641 value->tv_usec = (jiffies % HZ) * (1000000 / HZ);
642 value->tv_sec = jiffies / HZ;
643}
644
645static inline void getitimer_real(struct itimerval *value)
646{
647 register unsigned long val, interval;
648
649 interval = current->it_real_incr;
650 val = 0;
651 if (del_timer(¤t->real_timer)) {
652 unsigned long now = jiffies;
653 val = current->real_timer.expires;
654 add_timer(¤t->real_timer);
655
656 if (val <= now)
657 val = now+1;
658 val -= now;
659 }
660 jiffiestotv(val, &value->it_value);
661 jiffiestotv(interval, &value->it_interval);
662}
663
664asmlinkage unsigned int irix_alarm(unsigned int seconds)
665{
666 struct itimerval it_new, it_old;
667 unsigned int oldalarm;
668
669 if (!seconds) {
670 getitimer_real(&it_old);
671 del_timer(¤t->real_timer);
672 } else {
673 it_new.it_interval.tv_sec = it_new.it_interval.tv_usec = 0;
674 it_new.it_value.tv_sec = seconds;
675 it_new.it_value.tv_usec = 0;
676 do_setitimer(ITIMER_REAL, &it_new, &it_old);
677 }
678 oldalarm = it_old.it_value.tv_sec;
679
680
681
682
683 if (it_old.it_value.tv_usec)
684 oldalarm++;
685
686 return oldalarm;
687}
688
689asmlinkage int irix_pause(void)
690{
691 current->state = TASK_INTERRUPTIBLE;
692 schedule();
693
694 return -EINTR;
695}
696
697extern asmlinkage long sys_mount(char * dev_name, char * dir_name, char * type,
698 unsigned long new_flags, void * data);
699
700
701asmlinkage int irix_mount(char *dev_name, char *dir_name, unsigned long flags,
702 char *type, void *data, int datalen)
703{
704 printk("[%s:%d] irix_mount(%p,%p,%08lx,%p,%p,%d)\n",
705 current->comm, current->pid,
706 dev_name, dir_name, flags, type, data, datalen);
707
708 return sys_mount(dev_name, dir_name, type, flags, data);
709}
710
711struct irix_statfs {
712 short f_type;
713 long f_bsize, f_frsize, f_blocks, f_bfree, f_files, f_ffree;
714 char f_fname[6], f_fpack[6];
715};
716
717asmlinkage int irix_statfs(const char *path, struct irix_statfs *buf,
718 int len, int fs_type)
719{
720 struct nameidata nd;
721 struct statfs kbuf;
722 int error, i;
723
724
725 if (fs_type) {
726 error = -EINVAL;
727 goto out;
728 }
729 error = verify_area(VERIFY_WRITE, buf, sizeof(struct irix_statfs));
730 if (error)
731 goto out;
732 error = user_path_walk(path, &nd);
733 if (error)
734 goto out;
735
736 error = vfs_statfs(nd.dentry->d_inode->i_sb, &kbuf);
737 if (error)
738 goto dput_and_out;
739
740 __put_user(kbuf.f_type, &buf->f_type);
741 __put_user(kbuf.f_bsize, &buf->f_bsize);
742 __put_user(kbuf.f_frsize, &buf->f_frsize);
743 __put_user(kbuf.f_blocks, &buf->f_blocks);
744 __put_user(kbuf.f_bfree, &buf->f_bfree);
745 __put_user(kbuf.f_files, &buf->f_files);
746 __put_user(kbuf.f_ffree, &buf->f_ffree);
747 for (i = 0; i < 6; i++) {
748 __put_user(0, &buf->f_fname[i]);
749 __put_user(0, &buf->f_fpack[i]);
750 }
751 error = 0;
752
753dput_and_out:
754 path_release(&nd);
755out:
756 return error;
757}
758
759asmlinkage int irix_fstatfs(unsigned int fd, struct irix_statfs *buf)
760{
761 struct statfs kbuf;
762 struct file *file;
763 int error, i;
764
765 error = verify_area(VERIFY_WRITE, buf, sizeof(struct irix_statfs));
766 if (error)
767 goto out;
768 if (!(file = fget(fd))) {
769 error = -EBADF;
770 goto out;
771 }
772
773 error = vfs_statfs(file->f_dentry->d_inode->i_sb, &kbuf);
774 if (error)
775 goto out_f;
776
777 __put_user(kbuf.f_type, &buf->f_type);
778 __put_user(kbuf.f_bsize, &buf->f_bsize);
779 __put_user(kbuf.f_frsize, &buf->f_frsize);
780 __put_user(kbuf.f_blocks, &buf->f_blocks);
781 __put_user(kbuf.f_bfree, &buf->f_bfree);
782 __put_user(kbuf.f_files, &buf->f_files);
783 __put_user(kbuf.f_ffree, &buf->f_ffree);
784 for(i = 0; i < 6; i++) {
785 __put_user(0, &buf->f_fname[i]);
786 __put_user(0, &buf->f_fpack[i]);
787 }
788
789out_f:
790 fput(file);
791out:
792 return error;
793}
794
795extern asmlinkage int sys_setpgid(pid_t pid, pid_t pgid);
796extern asmlinkage int sys_setsid(void);
797
798asmlinkage int irix_setpgrp(int flags)
799{
800 int error;
801
802#ifdef DEBUG_PROCGRPS
803 printk("[%s:%d] setpgrp(%d) ", current->comm, current->pid, flags);
804#endif
805 if(!flags)
806 error = current->pgrp;
807 else
808 error = sys_setsid();
809#ifdef DEBUG_PROCGRPS
810 printk("returning %d\n", current->pgrp);
811#endif
812
813 return error;
814}
815
816asmlinkage int irix_times(struct tms * tbuf)
817{
818 int err = 0;
819
820 if (tbuf) {
821 err = verify_area(VERIFY_WRITE,tbuf,sizeof *tbuf);
822 if (err)
823 return err;
824 err |= __put_user(current->times.tms_utime,&tbuf->tms_utime);
825 err |= __put_user(current->times.tms_stime,&tbuf->tms_stime);
826 err |= __put_user(current->times.tms_cutime,&tbuf->tms_cutime);
827 err |= __put_user(current->times.tms_cstime,&tbuf->tms_cstime);
828 }
829
830 return err;
831}
832
833asmlinkage int irix_exec(struct pt_regs *regs)
834{
835 int error, base = 0;
836 char *filename;
837
838 if(regs->regs[2] == 1000)
839 base = 1;
840 filename = getname((char *) (long)regs->regs[base + 4]);
841 error = PTR_ERR(filename);
842 if (IS_ERR(filename))
843 return error;
844
845 error = do_execve(filename, (char **) (long)regs->regs[base + 5],
846 (char **) 0, regs);
847 putname(filename);
848
849 return error;
850}
851
852asmlinkage int irix_exece(struct pt_regs *regs)
853{
854 int error, base = 0;
855 char *filename;
856
857 if (regs->regs[2] == 1000)
858 base = 1;
859 filename = getname((char *) (long)regs->regs[base + 4]);
860 error = PTR_ERR(filename);
861 if (IS_ERR(filename))
862 return error;
863 error = do_execve(filename, (char **) (long)regs->regs[base + 5],
864 (char **) (long)regs->regs[base + 6], regs);
865 putname(filename);
866
867 return error;
868}
869
870asmlinkage unsigned long irix_gethostid(void)
871{
872 printk("[%s:%d]: irix_gethostid() called...\n",
873 current->comm, current->pid);
874
875 return -EINVAL;
876}
877
878asmlinkage unsigned long irix_sethostid(unsigned long val)
879{
880 printk("[%s:%d]: irix_sethostid(%08lx) called...\n",
881 current->comm, current->pid, val);
882
883 return -EINVAL;
884}
885
886extern asmlinkage int sys_socket(int family, int type, int protocol);
887
888asmlinkage int irix_socket(int family, int type, int protocol)
889{
890 switch(type) {
891 case 1:
892 type = SOCK_DGRAM;
893 break;
894
895 case 2:
896 type = SOCK_STREAM;
897 break;
898
899 case 3:
900 type = 9;
901 break;
902
903 case 4:
904 type = SOCK_RAW;
905 break;
906
907 case 5:
908 type = SOCK_RDM;
909 break;
910
911 case 6:
912 type = SOCK_SEQPACKET;
913 break;
914
915 default:
916 break;
917 }
918
919 return sys_socket(family, type, protocol);
920}
921
922asmlinkage int irix_getdomainname(char *name, int len)
923{
924 int error;
925
926 error = verify_area(VERIFY_WRITE, name, len);
927 if (error)
928 return error;
929
930 down_read(&uts_sem);
931 if (len > __NEW_UTS_LEN)
932 len = __NEW_UTS_LEN;
933 error = 0;
934 if (copy_to_user(name, system_utsname.domainname, len))
935 error = -EFAULT;
936 up_read(&uts_sem);
937
938 return error;
939}
940
941asmlinkage unsigned long irix_getpagesize(void)
942{
943 return PAGE_SIZE;
944}
945
946asmlinkage int irix_msgsys(int opcode, unsigned long arg0, unsigned long arg1,
947 unsigned long arg2, unsigned long arg3,
948 unsigned long arg4)
949{
950 switch (opcode) {
951 case 0:
952 return sys_msgget((key_t) arg0, (int) arg1);
953 case 1:
954 return sys_msgctl((int) arg0, (int) arg1, (struct msqid_ds *)arg2);
955 case 2:
956 return sys_msgrcv((int) arg0, (struct msgbuf *) arg1,
957 (size_t) arg2, (long) arg3, (int) arg4);
958 case 3:
959 return sys_msgsnd((int) arg0, (struct msgbuf *) arg1,
960 (size_t) arg2, (int) arg3);
961 default:
962 return -EINVAL;
963 }
964}
965
966asmlinkage int irix_shmsys(int opcode, unsigned long arg0, unsigned long arg1,
967 unsigned long arg2, unsigned long arg3)
968{
969 switch (opcode) {
970 case 0:
971 return sys_shmat((int) arg0, (char *)arg1, (int) arg2,
972 (unsigned long *) arg3);
973 case 1:
974 return sys_shmctl((int)arg0, (int)arg1, (struct shmid_ds *)arg2);
975 case 2:
976 return sys_shmdt((char *)arg0);
977 case 3:
978 return sys_shmget((key_t) arg0, (int) arg1, (int) arg2);
979 default:
980 return -EINVAL;
981 }
982}
983
984asmlinkage int irix_semsys(int opcode, unsigned long arg0, unsigned long arg1,
985 unsigned long arg2, int arg3)
986{
987 switch (opcode) {
988 case 0:
989 return sys_semctl((int) arg0, (int) arg1, (int) arg2,
990 (union semun) arg3);
991 case 1:
992 return sys_semget((key_t) arg0, (int) arg1, (int) arg2);
993 case 2:
994 return sys_semop((int) arg0, (struct sembuf *)arg1,
995 (unsigned int) arg2);
996 default:
997 return -EINVAL;
998 }
999}
1000
1001static inline loff_t llseek(struct file *file, loff_t offset, int origin)
1002{
1003 loff_t (*fn)(struct file *, loff_t, int);
1004 loff_t retval;
1005
1006 fn = default_llseek;
1007 if (file->f_op && file->f_op->llseek)
1008 fn = file->f_op->llseek;
1009 lock_kernel();
1010 retval = fn(file, offset, origin);
1011 unlock_kernel();
1012 return retval;
1013}
1014
1015asmlinkage int irix_lseek64(int fd, int _unused, int offhi, int offlow,
1016 int origin)
1017{
1018 int retval;
1019 struct file * file;
1020 loff_t offset;
1021
1022 retval = -EBADF;
1023 file = fget(fd);
1024 if (!file)
1025 goto bad;
1026 retval = -EINVAL;
1027 if (origin > 2)
1028 goto out_putf;
1029
1030 offset = llseek(file, ((loff_t) offhi << 32) | offlow, origin);
1031 retval = (int) offset;
1032
1033out_putf:
1034 fput(file);
1035bad:
1036 return retval;
1037}
1038
1039asmlinkage int irix_sginap(int ticks)
1040{
1041 current->state = TASK_INTERRUPTIBLE;
1042 schedule_timeout(ticks);
1043 return 0;
1044}
1045
1046asmlinkage int irix_sgikopt(char *istring, char *ostring, int len)
1047{
1048 return -EINVAL;
1049}
1050
1051asmlinkage int irix_gettimeofday(struct timeval *tv)
1052{
1053 int retval;
1054
1055 retval = copy_to_user(tv, &xtime, sizeof(*tv)) ? -EFAULT : 0;
1056 return retval;
1057}
1058
1059#define IRIX_MAP_AUTOGROW 0x40
1060
1061asmlinkage unsigned long irix_mmap32(unsigned long addr, size_t len, int prot,
1062 int flags, int fd, off_t offset)
1063{
1064 struct file *file = NULL;
1065 unsigned long retval;
1066
1067 if (!(flags & MAP_ANONYMOUS)) {
1068 if (!(file = fget(fd)))
1069 return -EBADF;
1070
1071
1072
1073 if (flags & IRIX_MAP_AUTOGROW) {
1074 unsigned long old_pos;
1075 long max_size = offset + len;
1076
1077 if (max_size > file->f_dentry->d_inode->i_size) {
1078 old_pos = sys_lseek (fd, max_size - 1, 0);
1079 sys_write (fd, "", 1);
1080 sys_lseek (fd, old_pos, 0);
1081 }
1082 }
1083 }
1084
1085 flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
1086
1087 down_write(¤t->mm->mmap_sem);
1088 retval = do_mmap(file, addr, len, prot, flags, offset);
1089 up_write(¤t->mm->mmap_sem);
1090 if (file)
1091 fput(file);
1092
1093 return retval;
1094}
1095
1096asmlinkage int irix_madvise(unsigned long addr, int len, int behavior)
1097{
1098 printk("[%s:%d] Wheee.. irix_madvise(%08lx,%d,%d)\n",
1099 current->comm, current->pid, addr, len, behavior);
1100
1101 return -EINVAL;
1102}
1103
1104asmlinkage int irix_pagelock(char *addr, int len, int op)
1105{
1106 printk("[%s:%d] Wheee.. irix_pagelock(%p,%d,%d)\n",
1107 current->comm, current->pid, addr, len, op);
1108
1109 return -EINVAL;
1110}
1111
1112asmlinkage int irix_quotactl(struct pt_regs *regs)
1113{
1114 printk("[%s:%d] Wheee.. irix_quotactl()\n",
1115 current->comm, current->pid);
1116
1117 return -EINVAL;
1118}
1119
1120asmlinkage int irix_BSDsetpgrp(int pid, int pgrp)
1121{
1122 int error;
1123
1124#ifdef DEBUG_PROCGRPS
1125 printk("[%s:%d] BSDsetpgrp(%d, %d) ", current->comm, current->pid,
1126 pid, pgrp);
1127#endif
1128 if(!pid)
1129 pid = current->pid;
1130
1131
1132 if ((pgrp == 0) && (pid == current->pid))
1133 error = sys_setsid();
1134 else
1135 error = sys_setpgid(pid, pgrp);
1136
1137#ifdef DEBUG_PROCGRPS
1138 printk("error = %d\n", error);
1139#endif
1140
1141 return error;
1142}
1143
1144asmlinkage int irix_systeminfo(int cmd, char *buf, int cnt)
1145{
1146 printk("[%s:%d] Wheee.. irix_systeminfo(%d,%p,%d)\n",
1147 current->comm, current->pid, cmd, buf, cnt);
1148
1149 return -EINVAL;
1150}
1151
1152struct iuname {
1153 char sysname[257], nodename[257], release[257];
1154 char version[257], machine[257];
1155 char m_type[257], base_rel[257];
1156 char _unused0[257], _unused1[257], _unused2[257];
1157 char _unused3[257], _unused4[257], _unused5[257];
1158};
1159
1160asmlinkage int irix_uname(struct iuname *buf)
1161{
1162 down_read(&uts_sem);
1163 if (copy_to_user(system_utsname.sysname, buf->sysname, 65)
1164 || copy_to_user(system_utsname.nodename, buf->nodename, 65)
1165 || copy_to_user(system_utsname.release, buf->release, 65)
1166 || copy_to_user(system_utsname.version, buf->version, 65)
1167 || copy_to_user(system_utsname.machine, buf->machine, 65)) {
1168 return -EFAULT;
1169 }
1170 up_read(&uts_sem);
1171
1172 return 1;
1173}
1174
1175#undef DEBUG_XSTAT
1176
1177static inline u32
1178linux_to_irix_dev_t (dev_t t)
1179{
1180 return MAJOR (t) << 18 | MINOR (t);
1181}
1182
1183static inline int irix_xstat32_xlate(struct stat *kb, void *ubuf)
1184{
1185 struct xstat32 {
1186 u32 st_dev, st_pad1[3], st_ino, st_mode, st_nlink, st_uid, st_gid;
1187 u32 st_rdev, st_pad2[2], st_size, st_pad3;
1188 u32 st_atime0, st_atime1;
1189 u32 st_mtime0, st_mtime1;
1190 u32 st_ctime0, st_ctime1;
1191 u32 st_blksize, st_blocks;
1192 char st_fstype[16];
1193 u32 st_pad4[8];
1194 } ub;
1195
1196 ub.st_dev = linux_to_irix_dev_t (kb->st_dev);
1197 ub.st_ino = kb->st_ino;
1198 ub.st_mode = kb->st_mode;
1199 ub.st_nlink = kb->st_nlink;
1200 ub.st_uid = kb->st_uid;
1201 ub.st_gid = kb->st_gid;
1202 ub.st_rdev = linux_to_irix_dev_t (kb->st_rdev);
1203 ub.st_size = kb->st_size;
1204 ub.st_atime0 = kb->st_atime;
1205 ub.st_atime1 = 0;
1206 ub.st_mtime0 = kb->st_mtime;
1207 ub.st_mtime1 = 0;
1208 ub.st_ctime0 = kb->st_ctime;
1209 ub.st_ctime1 = 0;
1210 ub.st_blksize = kb->st_blksize;
1211 ub.st_blocks = kb->st_blocks;
1212 strcpy (ub.st_fstype, "efs");
1213
1214 return copy_to_user(ubuf, &ub, sizeof(ub)) ? -EFAULT : 0;
1215}
1216
1217static inline void irix_xstat64_xlate(struct stat *sb)
1218{
1219 struct xstat64 {
1220 u32 st_dev; s32 st_pad1[3];
1221 unsigned long long st_ino;
1222 u32 st_mode;
1223 u32 st_nlink; s32 st_uid; s32 st_gid; u32 st_rdev;
1224 s32 st_pad2[2];
1225 long long st_size;
1226 s32 st_pad3;
1227 struct { s32 tv_sec, tv_nsec; } st_atime, st_mtime, st_ctime;
1228 s32 st_blksize;
1229 long long st_blocks;
1230 char st_fstype[16];
1231 s32 st_pad4[8];
1232 } ks;
1233
1234 ks.st_dev = linux_to_irix_dev_t (sb->st_dev);
1235 ks.st_pad1[0] = ks.st_pad1[1] = ks.st_pad1[2] = 0;
1236 ks.st_ino = (unsigned long long) sb->st_ino;
1237 ks.st_mode = (u32) sb->st_mode;
1238 ks.st_nlink = (u32) sb->st_nlink;
1239 ks.st_uid = (s32) sb->st_uid;
1240 ks.st_gid = (s32) sb->st_gid;
1241 ks.st_rdev = linux_to_irix_dev_t (sb->st_rdev);
1242 ks.st_pad2[0] = ks.st_pad2[1] = 0;
1243 ks.st_size = (long long) sb->st_size;
1244 ks.st_pad3 = 0;
1245
1246
1247 ks.st_atime.tv_sec = (s32) sb->st_atime; ks.st_atime.tv_nsec = 0;
1248 ks.st_mtime.tv_sec = (s32) sb->st_atime; ks.st_mtime.tv_nsec = 0;
1249 ks.st_ctime.tv_sec = (s32) sb->st_atime; ks.st_ctime.tv_nsec = 0;
1250
1251 ks.st_blksize = (s32) sb->st_blksize;
1252 ks.st_blocks = (long long) sb->st_blocks;
1253 memset(ks.st_fstype, 0, 16);
1254 ks.st_pad4[0] = ks.st_pad4[1] = ks.st_pad4[2] = ks.st_pad4[3] = 0;
1255 ks.st_pad4[4] = ks.st_pad4[5] = ks.st_pad4[6] = ks.st_pad4[7] = 0;
1256
1257
1258 copy_to_user(sb, &ks, sizeof(struct xstat64));
1259}
1260
1261extern asmlinkage int sys_newstat(char * filename, struct stat * statbuf);
1262
1263asmlinkage int irix_xstat(int version, char *filename, struct stat *statbuf)
1264{
1265 int retval;
1266
1267#ifdef DEBUG_XSTAT
1268 printk("[%s:%d] Wheee.. irix_xstat(%d,%s,%p) ",
1269 current->comm, current->pid, version, filename, statbuf);
1270#endif
1271 switch(version) {
1272 case 2: {
1273 struct stat kb;
1274 mm_segment_t old_fs;
1275
1276 old_fs = get_fs(); set_fs(get_ds());
1277 retval = sys_newstat(filename, &kb);
1278 set_fs(old_fs);
1279#ifdef DEBUG_XSTAT
1280 printk("retval[%d]\n", retval);
1281#endif
1282 if(retval)
1283 goto out;
1284 retval = irix_xstat32_xlate(&kb, statbuf);
1285 goto out;
1286 }
1287
1288 case 3: {
1289 retval = sys_newstat(filename, statbuf);
1290#ifdef DEBUG_XSTAT
1291 printk("retval[%d]\n", retval);
1292#endif
1293 if(retval)
1294 goto out;
1295
1296 irix_xstat64_xlate(statbuf);
1297 retval = 0;
1298 break;
1299 }
1300
1301 default:
1302 retval = -EINVAL;
1303 break;
1304 }
1305
1306out:
1307 return retval;
1308}
1309
1310extern asmlinkage int sys_newlstat(char * filename, struct stat * statbuf);
1311
1312asmlinkage int irix_lxstat(int version, char *filename, struct stat *statbuf)
1313{
1314 int error;
1315
1316#ifdef DEBUG_XSTAT
1317 printk("[%s:%d] Wheee.. irix_lxstat(%d,%s,%p) ",
1318 current->comm, current->pid, version, filename, statbuf);
1319#endif
1320 switch(version) {
1321 case 2: {
1322 struct stat kb;
1323 mm_segment_t old_fs;
1324
1325 old_fs = get_fs(); set_fs(get_ds());
1326 error = sys_newlstat(filename, &kb);
1327 set_fs(old_fs);
1328#ifdef DEBUG_XSTAT
1329 printk("error[%d]\n", error);
1330#endif
1331 if(error)
1332 goto out;
1333 error = irix_xstat32_xlate(&kb, statbuf);
1334 goto out;
1335 }
1336
1337 case 3: {
1338 error = sys_newlstat(filename, statbuf);
1339#ifdef DEBUG_XSTAT
1340 printk("error[%d]\n", error);
1341#endif
1342 if(error)
1343 goto out;
1344
1345 irix_xstat64_xlate(statbuf);
1346 error = 0;
1347 goto out;
1348 }
1349
1350 default:
1351 error = -EINVAL;
1352 goto out;
1353 }
1354
1355out:
1356 return error;
1357}
1358
1359extern asmlinkage int sys_newfstat(unsigned int fd, struct stat * statbuf);
1360
1361asmlinkage int irix_fxstat(int version, int fd, struct stat *statbuf)
1362{
1363 int error;
1364
1365#ifdef DEBUG_XSTAT
1366 printk("[%s:%d] Wheee.. irix_fxstat(%d,%d,%p) ",
1367 current->comm, current->pid, version, fd, statbuf);
1368#endif
1369 switch(version) {
1370 case 2: {
1371 struct stat kb;
1372 mm_segment_t old_fs;
1373
1374 old_fs = get_fs(); set_fs(get_ds());
1375 error = sys_newfstat(fd, &kb);
1376 set_fs(old_fs);
1377#ifdef DEBUG_XSTAT
1378 printk("error[%d]\n", error);
1379#endif
1380 if(error)
1381 goto out;
1382 error = irix_xstat32_xlate(&kb, statbuf);
1383 goto out;
1384 }
1385
1386 case 3: {
1387 error = sys_newfstat(fd, statbuf);
1388#ifdef DEBUG_XSTAT
1389 printk("error[%d]\n", error);
1390#endif
1391 if(error)
1392 goto out;
1393
1394 irix_xstat64_xlate(statbuf);
1395 error = 0;
1396 goto out;
1397 }
1398
1399 default:
1400 error = -EINVAL;
1401 goto out;
1402 }
1403
1404out:
1405 return error;
1406}
1407
1408extern asmlinkage int sys_mknod(const char * filename, int mode, dev_t dev);
1409
1410asmlinkage int irix_xmknod(int ver, char *filename, int mode, dev_t dev)
1411{
1412 int retval;
1413
1414 printk("[%s:%d] Wheee.. irix_xmknod(%d,%s,%x,%x)\n",
1415 current->comm, current->pid, ver, filename, mode, (int) dev);
1416
1417 switch(ver) {
1418 case 2:
1419 retval = sys_mknod(filename, mode, dev);
1420 break;
1421
1422 default:
1423 retval = -EINVAL;
1424 break;
1425 };
1426
1427 return retval;
1428}
1429
1430asmlinkage int irix_swapctl(int cmd, char *arg)
1431{
1432 printk("[%s:%d] Wheee.. irix_swapctl(%d,%p)\n",
1433 current->comm, current->pid, cmd, arg);
1434
1435 return -EINVAL;
1436}
1437
1438struct irix_statvfs {
1439 u32 f_bsize; u32 f_frsize; u32 f_blocks;
1440 u32 f_bfree; u32 f_bavail; u32 f_files; u32 f_ffree; u32 f_favail;
1441 u32 f_fsid; char f_basetype[16];
1442 u32 f_flag; u32 f_namemax;
1443 char f_fstr[32]; u32 f_filler[16];
1444};
1445
1446asmlinkage int irix_statvfs(char *fname, struct irix_statvfs *buf)
1447{
1448 struct nameidata nd;
1449 struct statfs kbuf;
1450 int error, i;
1451
1452 printk("[%s:%d] Wheee.. irix_statvfs(%s,%p)\n",
1453 current->comm, current->pid, fname, buf);
1454 error = verify_area(VERIFY_WRITE, buf, sizeof(struct irix_statvfs));
1455 if (error)
1456 goto out;
1457 error = user_path_walk(fname, &nd);
1458 if (error)
1459 goto out;
1460 error = vfs_statfs(nd.dentry->d_inode->i_sb, &kbuf);
1461 if (error)
1462 goto dput_and_out;
1463
1464 __put_user(kbuf.f_bsize, &buf->f_bsize);
1465 __put_user(kbuf.f_frsize, &buf->f_frsize);
1466 __put_user(kbuf.f_blocks, &buf->f_blocks);
1467 __put_user(kbuf.f_bfree, &buf->f_bfree);
1468 __put_user(kbuf.f_bfree, &buf->f_bavail);
1469 __put_user(kbuf.f_files, &buf->f_files);
1470 __put_user(kbuf.f_ffree, &buf->f_ffree);
1471 __put_user(kbuf.f_ffree, &buf->f_favail);
1472#ifdef __MIPSEB__
1473 __put_user(kbuf.f_fsid.val[1], &buf->f_fsid);
1474#else
1475 __put_user(kbuf.f_fsid.val[0], &buf->f_fsid);
1476#endif
1477 for (i = 0; i < 16; i++)
1478 __put_user(0, &buf->f_basetype[i]);
1479 __put_user(0, &buf->f_flag);
1480 __put_user(kbuf.f_namelen, &buf->f_namemax);
1481 for (i = 0; i < 32; i++)
1482 __put_user(0, &buf->f_fstr[i]);
1483
1484 error = 0;
1485
1486dput_and_out:
1487 path_release(&nd);
1488out:
1489 return error;
1490}
1491
1492asmlinkage int irix_fstatvfs(int fd, struct irix_statvfs *buf)
1493{
1494 struct statfs kbuf;
1495 struct file *file;
1496 int error, i;
1497
1498 printk("[%s:%d] Wheee.. irix_fstatvfs(%d,%p)\n",
1499 current->comm, current->pid, fd, buf);
1500
1501 error = verify_area(VERIFY_WRITE, buf, sizeof(struct irix_statvfs));
1502 if (error)
1503 goto out;
1504 if (!(file = fget(fd))) {
1505 error = -EBADF;
1506 goto out;
1507 }
1508 error = vfs_statfs(file->f_dentry->d_inode->i_sb, &kbuf);
1509 if (error)
1510 goto out_f;
1511
1512 __put_user(kbuf.f_bsize, &buf->f_bsize);
1513 __put_user(kbuf.f_frsize, &buf->f_frsize);
1514 __put_user(kbuf.f_blocks, &buf->f_blocks);
1515 __put_user(kbuf.f_bfree, &buf->f_bfree);
1516 __put_user(kbuf.f_bfree, &buf->f_bavail);
1517 __put_user(kbuf.f_files, &buf->f_files);
1518 __put_user(kbuf.f_ffree, &buf->f_ffree);
1519 __put_user(kbuf.f_ffree, &buf->f_favail);
1520#ifdef __MIPSEB__
1521 __put_user(kbuf.f_fsid.val[1], &buf->f_fsid);
1522#else
1523 __put_user(kbuf.f_fsid.val[0], &buf->f_fsid);
1524#endif
1525 for(i = 0; i < 16; i++)
1526 __put_user(0, &buf->f_basetype[i]);
1527 __put_user(0, &buf->f_flag);
1528 __put_user(kbuf.f_namelen, &buf->f_namemax);
1529 __clear_user(&buf->f_fstr, sizeof(buf->f_fstr));
1530
1531out_f:
1532 fput(file);
1533out:
1534 return error;
1535}
1536
1537asmlinkage int irix_priocntl(struct pt_regs *regs)
1538{
1539 printk("[%s:%d] Wheee.. irix_priocntl()\n",
1540 current->comm, current->pid);
1541
1542 return -EINVAL;
1543}
1544
1545asmlinkage int irix_sigqueue(int pid, int sig, int code, int val)
1546{
1547 printk("[%s:%d] Wheee.. irix_sigqueue(%d,%d,%d,%d)\n",
1548 current->comm, current->pid, pid, sig, code, val);
1549
1550 return -EINVAL;
1551}
1552
1553extern asmlinkage int sys_truncate(const char * path, unsigned long length);
1554extern asmlinkage int sys_ftruncate(unsigned int fd, unsigned long length);
1555
1556asmlinkage int irix_truncate64(char *name, int pad, int size1, int size2)
1557{
1558 int retval;
1559
1560 if (size1) {
1561 retval = -EINVAL;
1562 goto out;
1563 }
1564 retval = sys_truncate(name, size2);
1565
1566out:
1567 return retval;
1568}
1569
1570asmlinkage int irix_ftruncate64(int fd, int pad, int size1, int size2)
1571{
1572 int retval;
1573
1574 if (size1) {
1575 retval = -EINVAL;
1576 goto out;
1577 }
1578 retval = sys_ftruncate(fd, size2);
1579
1580out:
1581 return retval;
1582}
1583
1584extern asmlinkage unsigned long
1585sys_mmap(unsigned long addr, size_t len, int prot, int flags, int fd,
1586 off_t offset);
1587
1588asmlinkage int irix_mmap64(struct pt_regs *regs)
1589{
1590 int len, prot, flags, fd, off1, off2, error, base = 0;
1591 unsigned long addr, pgoff, *sp;
1592 struct file *file = NULL;
1593
1594 if (regs->regs[2] == 1000)
1595 base = 1;
1596 sp = (unsigned long *) (regs->regs[29] + 16);
1597 addr = regs->regs[base + 4];
1598 len = regs->regs[base + 5];
1599 prot = regs->regs[base + 6];
1600 if (!base) {
1601 flags = regs->regs[base + 7];
1602 error = verify_area(VERIFY_READ, sp, (4 * sizeof(unsigned long)));
1603 if(error)
1604 goto out;
1605 fd = sp[0];
1606 __get_user(off1, &sp[1]);
1607 __get_user(off2, &sp[2]);
1608 } else {
1609 error = verify_area(VERIFY_READ, sp, (5 * sizeof(unsigned long)));
1610 if(error)
1611 goto out;
1612 __get_user(flags, &sp[0]);
1613 __get_user(fd, &sp[1]);
1614 __get_user(off1, &sp[2]);
1615 __get_user(off2, &sp[3]);
1616 }
1617
1618 if (off1 & PAGE_MASK) {
1619 error = -EOVERFLOW;
1620 goto out;
1621 }
1622
1623 pgoff = (off1 << (32 - PAGE_SHIFT)) | (off2 >> PAGE_SHIFT);
1624
1625 if (!(flags & MAP_ANONYMOUS)) {
1626 if (!(file = fget(fd))) {
1627 error = -EBADF;
1628 goto out;
1629 }
1630
1631
1632
1633 if (flags & IRIX_MAP_AUTOGROW) {
1634 unsigned long old_pos;
1635 long max_size = off2 + len;
1636
1637 if (max_size > file->f_dentry->d_inode->i_size) {
1638 old_pos = sys_lseek (fd, max_size - 1, 0);
1639 sys_write (fd, "", 1);
1640 sys_lseek (fd, old_pos, 0);
1641 }
1642 }
1643 }
1644
1645 flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
1646
1647 down_write(¤t->mm->mmap_sem);
1648 error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
1649 up_write(¤t->mm->mmap_sem);
1650
1651 if (file)
1652 fput(file);
1653
1654out:
1655 return error;
1656}
1657
1658asmlinkage int irix_dmi(struct pt_regs *regs)
1659{
1660 printk("[%s:%d] Wheee.. irix_dmi()\n",
1661 current->comm, current->pid);
1662
1663 return -EINVAL;
1664}
1665
1666asmlinkage int irix_pread(int fd, char *buf, int cnt, int off64,
1667 int off1, int off2)
1668{
1669 printk("[%s:%d] Wheee.. irix_pread(%d,%p,%d,%d,%d,%d)\n",
1670 current->comm, current->pid, fd, buf, cnt, off64, off1, off2);
1671
1672 return -EINVAL;
1673}
1674
1675asmlinkage int irix_pwrite(int fd, char *buf, int cnt, int off64,
1676 int off1, int off2)
1677{
1678 printk("[%s:%d] Wheee.. irix_pwrite(%d,%p,%d,%d,%d,%d)\n",
1679 current->comm, current->pid, fd, buf, cnt, off64, off1, off2);
1680
1681 return -EINVAL;
1682}
1683
1684asmlinkage int irix_sgifastpath(int cmd, unsigned long arg0, unsigned long arg1,
1685 unsigned long arg2, unsigned long arg3,
1686 unsigned long arg4, unsigned long arg5)
1687{
1688 printk("[%s:%d] Wheee.. irix_fastpath(%d,%08lx,%08lx,%08lx,%08lx,"
1689 "%08lx,%08lx)\n",
1690 current->comm, current->pid, cmd, arg0, arg1, arg2,
1691 arg3, arg4, arg5);
1692
1693 return -EINVAL;
1694}
1695
1696struct irix_statvfs64 {
1697 u32 f_bsize; u32 f_frsize;
1698 u64 f_blocks; u64 f_bfree; u64 f_bavail;
1699 u64 f_files; u64 f_ffree; u64 f_favail;
1700 u32 f_fsid;
1701 char f_basetype[16];
1702 u32 f_flag; u32 f_namemax;
1703 char f_fstr[32];
1704 u32 f_filler[16];
1705};
1706
1707asmlinkage int irix_statvfs64(char *fname, struct irix_statvfs64 *buf)
1708{
1709 struct nameidata nd;
1710 struct statfs kbuf;
1711 int error, i;
1712
1713 printk("[%s:%d] Wheee.. irix_statvfs(%s,%p)\n",
1714 current->comm, current->pid, fname, buf);
1715 error = verify_area(VERIFY_WRITE, buf, sizeof(struct irix_statvfs64));
1716 if(error)
1717 goto out;
1718 error = user_path_walk(fname, &nd);
1719 if (error)
1720 goto out;
1721 error = vfs_statfs(nd.dentry->d_inode->i_sb, &kbuf);
1722 if (error)
1723 goto dput_and_out;
1724
1725 __put_user(kbuf.f_bsize, &buf->f_bsize);
1726 __put_user(kbuf.f_frsize, &buf->f_frsize);
1727 __put_user(kbuf.f_blocks, &buf->f_blocks);
1728 __put_user(kbuf.f_bfree, &buf->f_bfree);
1729 __put_user(kbuf.f_bfree, &buf->f_bavail);
1730 __put_user(kbuf.f_files, &buf->f_files);
1731 __put_user(kbuf.f_ffree, &buf->f_ffree);
1732 __put_user(kbuf.f_ffree, &buf->f_favail);
1733#ifdef __MIPSEB__
1734 __put_user(kbuf.f_fsid.val[1], &buf->f_fsid);
1735#else
1736 __put_user(kbuf.f_fsid.val[0], &buf->f_fsid);
1737#endif
1738 for(i = 0; i < 16; i++)
1739 __put_user(0, &buf->f_basetype[i]);
1740 __put_user(0, &buf->f_flag);
1741 __put_user(kbuf.f_namelen, &buf->f_namemax);
1742 for(i = 0; i < 32; i++)
1743 __put_user(0, &buf->f_fstr[i]);
1744
1745 error = 0;
1746
1747dput_and_out:
1748 path_release(&nd);
1749out:
1750 return error;
1751}
1752
1753asmlinkage int irix_fstatvfs64(int fd, struct irix_statvfs *buf)
1754{
1755 struct statfs kbuf;
1756 struct file *file;
1757 int error, i;
1758
1759 printk("[%s:%d] Wheee.. irix_fstatvfs(%d,%p)\n",
1760 current->comm, current->pid, fd, buf);
1761
1762 error = verify_area(VERIFY_WRITE, buf, sizeof(struct irix_statvfs));
1763 if (error)
1764 goto out;
1765 if (!(file = fget(fd))) {
1766 error = -EBADF;
1767 goto out;
1768 }
1769 error = vfs_statfs(file->f_dentry->d_inode->i_sb, &kbuf);
1770 if (error)
1771 goto out_f;
1772
1773 __put_user(kbuf.f_bsize, &buf->f_bsize);
1774 __put_user(kbuf.f_frsize, &buf->f_frsize);
1775 __put_user(kbuf.f_blocks, &buf->f_blocks);
1776 __put_user(kbuf.f_bfree, &buf->f_bfree);
1777 __put_user(kbuf.f_bfree, &buf->f_bavail);
1778 __put_user(kbuf.f_files, &buf->f_files);
1779 __put_user(kbuf.f_ffree, &buf->f_ffree);
1780 __put_user(kbuf.f_ffree, &buf->f_favail);
1781#ifdef __MIPSEB__
1782 __put_user(kbuf.f_fsid.val[1], &buf->f_fsid);
1783#else
1784 __put_user(kbuf.f_fsid.val[0], &buf->f_fsid);
1785#endif
1786 for(i = 0; i < 16; i++)
1787 __put_user(0, &buf->f_basetype[i]);
1788 __put_user(0, &buf->f_flag);
1789 __put_user(kbuf.f_namelen, &buf->f_namemax);
1790 __clear_user(buf->f_fstr, sizeof(buf->f_fstr[i]));
1791
1792out_f:
1793 fput(file);
1794out:
1795 return error;
1796}
1797
1798asmlinkage int irix_getmountid(char *fname, unsigned long *midbuf)
1799{
1800 int err;
1801
1802 printk("[%s:%d] irix_getmountid(%s, %p)\n",
1803 current->comm, current->pid, fname, midbuf);
1804 err = verify_area(VERIFY_WRITE, midbuf, (sizeof(unsigned long) * 4));
1805 if (err)
1806 return err;
1807
1808
1809
1810
1811
1812
1813
1814 err |= __put_user(0, &midbuf[0]);
1815 err |= __put_user(0, &midbuf[1]);
1816 err |= __put_user(0, &midbuf[2]);
1817 err |= __put_user(0, &midbuf[3]);
1818
1819 return err;
1820}
1821
1822asmlinkage int irix_nsproc(unsigned long entry, unsigned long mask,
1823 unsigned long arg, unsigned long sp, int slen)
1824{
1825 printk("[%s:%d] Wheee.. irix_nsproc(%08lx,%08lx,%08lx,%08lx,%d)\n",
1826 current->comm, current->pid, entry, mask, arg, sp, slen);
1827
1828 return -EINVAL;
1829}
1830
1831#undef DEBUG_GETDENTS
1832
1833struct irix_dirent32 {
1834 u32 d_ino;
1835 u32 d_off;
1836 unsigned short d_reclen;
1837 char d_name[1];
1838};
1839
1840struct irix_dirent32_callback {
1841 struct irix_dirent32 *current_dir;
1842 struct irix_dirent32 *previous;
1843 int count;
1844 int error;
1845};
1846
1847#define NAME_OFFSET32(de) ((int) ((de)->d_name - (char *) (de)))
1848#define ROUND_UP32(x) (((x)+sizeof(u32)-1) & ~(sizeof(u32)-1))
1849
1850static int irix_filldir32(void *__buf, const char *name, int namlen,
1851 loff_t offset, ino_t ino, unsigned int d_type)
1852{
1853 struct irix_dirent32 *dirent;
1854 struct irix_dirent32_callback *buf =
1855 (struct irix_dirent32_callback *)__buf;
1856 unsigned short reclen = ROUND_UP32(NAME_OFFSET32(dirent) + namlen + 1);
1857
1858#ifdef DEBUG_GETDENTS
1859 printk("\nirix_filldir32[reclen<%d>namlen<%d>count<%d>]",
1860 reclen, namlen, buf->count);
1861#endif
1862 buf->error = -EINVAL;
1863 if (reclen > buf->count)
1864 return -EINVAL;
1865 dirent = buf->previous;
1866 if (dirent)
1867 __put_user(offset, &dirent->d_off);
1868 dirent = buf->current_dir;
1869 buf->previous = dirent;
1870 __put_user(ino, &dirent->d_ino);
1871 __put_user(reclen, &dirent->d_reclen);
1872 copy_to_user(dirent->d_name, name, namlen);
1873 __put_user(0, &dirent->d_name[namlen]);
1874 ((char *) dirent) += reclen;
1875 buf->current_dir = dirent;
1876 buf->count -= reclen;
1877
1878 return 0;
1879}
1880
1881asmlinkage int irix_ngetdents(unsigned int fd, void * dirent,
1882 unsigned int count, int *eob)
1883{
1884 struct file *file;
1885 struct irix_dirent32 *lastdirent;
1886 struct irix_dirent32_callback buf;
1887 int error;
1888
1889#ifdef DEBUG_GETDENTS
1890 printk("[%s:%d] ngetdents(%d, %p, %d, %p) ", current->comm,
1891 current->pid, fd, dirent, count, eob);
1892#endif
1893 error = -EBADF;
1894 file = fget(fd);
1895 if (!file)
1896 goto out;
1897
1898 buf.current_dir = (struct irix_dirent32 *) dirent;
1899 buf.previous = NULL;
1900 buf.count = count;
1901 buf.error = 0;
1902
1903 error = vfs_readdir(file, irix_filldir32, &buf);
1904 if (error < 0)
1905 goto out_putf;
1906
1907 error = buf.error;
1908 lastdirent = buf.previous;
1909 if (lastdirent) {
1910 put_user(file->f_pos, &lastdirent->d_off);
1911 error = count - buf.count;
1912 }
1913
1914 if (put_user(0, eob) < 0) {
1915 error = -EFAULT;
1916 goto out_putf;
1917 }
1918
1919#ifdef DEBUG_GETDENTS
1920 printk("eob=%d returning %d\n", *eob, count - buf.count);
1921#endif
1922 error = count - buf.count;
1923
1924out_putf:
1925 fput(file);
1926out:
1927 return error;
1928}
1929
1930struct irix_dirent64 {
1931 u64 d_ino;
1932 u64 d_off;
1933 unsigned short d_reclen;
1934 char d_name[1];
1935};
1936
1937struct irix_dirent64_callback {
1938 struct irix_dirent64 *curr;
1939 struct irix_dirent64 *previous;
1940 int count;
1941 int error;
1942};
1943
1944#define NAME_OFFSET64(de) ((int) ((de)->d_name - (char *) (de)))
1945#define ROUND_UP64(x) (((x)+sizeof(u64)-1) & ~(sizeof(u64)-1))
1946
1947static int irix_filldir64(void * __buf, const char * name, int namlen,
1948 loff_t offset, ino_t ino, unsigned int d_type)
1949{
1950 struct irix_dirent64 *dirent;
1951 struct irix_dirent64_callback * buf =
1952 (struct irix_dirent64_callback *) __buf;
1953 unsigned short reclen = ROUND_UP64(NAME_OFFSET64(dirent) + namlen + 1);
1954
1955 buf->error = -EINVAL;
1956 if (reclen > buf->count)
1957 return -EINVAL;
1958 dirent = buf->previous;
1959 if (dirent)
1960 __put_user(offset, &dirent->d_off);
1961 dirent = buf->curr;
1962 buf->previous = dirent;
1963 __put_user(ino, &dirent->d_ino);
1964 __put_user(reclen, &dirent->d_reclen);
1965 __copy_to_user(dirent->d_name, name, namlen);
1966 __put_user(0, &dirent->d_name[namlen]);
1967 ((char *) dirent) += reclen;
1968 buf->curr = dirent;
1969 buf->count -= reclen;
1970
1971 return 0;
1972}
1973
1974asmlinkage int irix_getdents64(int fd, void *dirent, int cnt)
1975{
1976 struct file *file;
1977 struct irix_dirent64 *lastdirent;
1978 struct irix_dirent64_callback buf;
1979 int error;
1980
1981#ifdef DEBUG_GETDENTS
1982 printk("[%s:%d] getdents64(%d, %p, %d) ", current->comm,
1983 current->pid, fd, dirent, cnt);
1984#endif
1985 error = -EBADF;
1986 if (!(file = fget(fd)))
1987 goto out;
1988
1989 error = -EFAULT;
1990 if (!access_ok(VERIFY_WRITE, dirent, cnt))
1991 goto out_f;
1992
1993 error = -EINVAL;
1994 if (cnt < (sizeof(struct irix_dirent64) + 255))
1995 goto out_f;
1996
1997 buf.curr = (struct irix_dirent64 *) dirent;
1998 buf.previous = NULL;
1999 buf.count = cnt;
2000 buf.error = 0;
2001 error = vfs_readdir(file, irix_filldir64, &buf);
2002 if (error < 0)
2003 goto out_f;
2004 lastdirent = buf.previous;
2005 if (!lastdirent) {
2006 error = buf.error;
2007 goto out_f;
2008 }
2009 lastdirent->d_off = (u64) file->f_pos;
2010#ifdef DEBUG_GETDENTS
2011 printk("returning %d\n", cnt - buf.count);
2012#endif
2013 error = cnt - buf.count;
2014
2015out_f:
2016 fput(file);
2017out:
2018 return error;
2019}
2020
2021asmlinkage int irix_ngetdents64(int fd, void *dirent, int cnt, int *eob)
2022{
2023 struct file *file;
2024 struct irix_dirent64 *lastdirent;
2025 struct irix_dirent64_callback buf;
2026 int error;
2027
2028#ifdef DEBUG_GETDENTS
2029 printk("[%s:%d] ngetdents64(%d, %p, %d) ", current->comm,
2030 current->pid, fd, dirent, cnt);
2031#endif
2032 error = -EBADF;
2033 if (!(file = fget(fd)))
2034 goto out;
2035
2036 error = -EFAULT;
2037 if (!access_ok(VERIFY_WRITE, dirent, cnt) ||
2038 !access_ok(VERIFY_WRITE, eob, sizeof(*eob)))
2039 goto out_f;
2040
2041 error = -EINVAL;
2042 if (cnt < (sizeof(struct irix_dirent64) + 255))
2043 goto out_f;
2044
2045 *eob = 0;
2046 buf.curr = (struct irix_dirent64 *) dirent;
2047 buf.previous = NULL;
2048 buf.count = cnt;
2049 buf.error = 0;
2050 error = vfs_readdir(file, irix_filldir64, &buf);
2051 if (error < 0)
2052 goto out_f;
2053 lastdirent = buf.previous;
2054 if (!lastdirent) {
2055 error = buf.error;
2056 goto out_f;
2057 }
2058 lastdirent->d_off = (u64) file->f_pos;
2059#ifdef DEBUG_GETDENTS
2060 printk("eob=%d returning %d\n", *eob, cnt - buf.count);
2061#endif
2062 error = cnt - buf.count;
2063
2064out_f:
2065 fput(file);
2066out:
2067 return error;
2068}
2069
2070asmlinkage int irix_uadmin(unsigned long op, unsigned long func, unsigned long arg)
2071{
2072 int retval;
2073
2074 switch (op) {
2075 case 1:
2076
2077 printk("[%s:%d] irix_uadmin: Wants to reboot...\n",
2078 current->comm, current->pid);
2079 retval = -EINVAL;
2080 goto out;
2081
2082 case 2:
2083
2084 printk("[%s:%d] irix_uadmin: Wants to shutdown...\n",
2085 current->comm, current->pid);
2086 retval = -EINVAL;
2087 goto out;
2088
2089 case 4:
2090
2091 printk("[%s:%d] irix_uadmin: Wants to remount root...\n",
2092 current->comm, current->pid);
2093 retval = -EINVAL;
2094 goto out;
2095
2096 case 8:
2097
2098 printk("[%s:%d] irix_uadmin: Wants to kill all tasks...\n",
2099 current->comm, current->pid);
2100 retval = -EINVAL;
2101 goto out;
2102
2103 case 256:
2104
2105 printk("[%s:%d] irix_uadmin: Wants to set magic mushroom[%d]...\n",
2106 current->comm, current->pid, (int) func);
2107 retval = -EINVAL;
2108 goto out;
2109
2110 default:
2111 printk("[%s:%d] irix_uadmin: Unknown operation [%d]...\n",
2112 current->comm, current->pid, (int) op);
2113 retval = -EINVAL;
2114 goto out;
2115 };
2116
2117out:
2118 return retval;
2119}
2120
2121asmlinkage int irix_utssys(char *inbuf, int arg, int type, char *outbuf)
2122{
2123 int retval;
2124
2125 switch(type) {
2126 case 0:
2127
2128 retval = irix_uname((struct iuname *)inbuf);
2129 goto out;
2130
2131 case 2:
2132
2133 printk("[%s:%d] irix_utssys: Wants to do ustat()\n",
2134 current->comm, current->pid);
2135 retval = -EINVAL;
2136 goto out;
2137
2138 case 3:
2139
2140 printk("[%s:%d] irix_utssys: Wants to do fusers()\n",
2141 current->comm, current->pid);
2142 retval = -EINVAL;
2143 goto out;
2144
2145 default:
2146 printk("[%s:%d] irix_utssys: Wants to do unknown type[%d]\n",
2147 current->comm, current->pid, (int) type);
2148 retval = -EINVAL;
2149 goto out;
2150 }
2151
2152out:
2153 return retval;
2154}
2155
2156#undef DEBUG_FCNTL
2157
2158extern asmlinkage long sys_fcntl(unsigned int fd, unsigned int cmd,
2159 unsigned long arg);
2160
2161#define IRIX_F_ALLOCSP 10
2162
2163asmlinkage int irix_fcntl(int fd, int cmd, int arg)
2164{
2165 int retval;
2166
2167#ifdef DEBUG_FCNTL
2168 printk("[%s:%d] irix_fcntl(%d, %d, %d) ", current->comm,
2169 current->pid, fd, cmd, arg);
2170#endif
2171 if (cmd == IRIX_F_ALLOCSP){
2172 return 0;
2173 }
2174 retval = sys_fcntl(fd, cmd, arg);
2175#ifdef DEBUG_FCNTL
2176 printk("%d\n", retval);
2177#endif
2178 return retval;
2179}
2180
2181asmlinkage int irix_ulimit(int cmd, int arg)
2182{
2183 int retval;
2184
2185 switch(cmd) {
2186 case 1:
2187 printk("[%s:%d] irix_ulimit: Wants to get file size limit.\n",
2188 current->comm, current->pid);
2189 retval = -EINVAL;
2190 goto out;
2191
2192 case 2:
2193 printk("[%s:%d] irix_ulimit: Wants to set file size limit.\n",
2194 current->comm, current->pid);
2195 retval = -EINVAL;
2196 goto out;
2197
2198 case 3:
2199 printk("[%s:%d] irix_ulimit: Wants to get brk limit.\n",
2200 current->comm, current->pid);
2201 retval = -EINVAL;
2202 goto out;
2203
2204 case 4:
2205#if 0
2206 printk("[%s:%d] irix_ulimit: Wants to get fd limit.\n",
2207 current->comm, current->pid);
2208 retval = -EINVAL;
2209 goto out;
2210#endif
2211 retval = current->rlim[RLIMIT_NOFILE].rlim_cur;
2212 goto out;
2213
2214 case 5:
2215 printk("[%s:%d] irix_ulimit: Wants to get txt offset.\n",
2216 current->comm, current->pid);
2217 retval = -EINVAL;
2218 goto out;
2219
2220 default:
2221 printk("[%s:%d] irix_ulimit: Unknown command [%d].\n",
2222 current->comm, current->pid, cmd);
2223 retval = -EINVAL;
2224 goto out;
2225 }
2226out:
2227 return retval;
2228}
2229
2230asmlinkage int irix_unimp(struct pt_regs *regs)
2231{
2232 printk("irix_unimp [%s:%d] v0=%d v1=%d a0=%08lx a1=%08lx a2=%08lx "
2233 "a3=%08lx\n", current->comm, current->pid,
2234 (int) regs->regs[2], (int) regs->regs[3],
2235 regs->regs[4], regs->regs[5], regs->regs[6], regs->regs[7]);
2236
2237 return -ENOSYS;
2238}
2239