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
irix_sysmp(struct pt_regs * regs)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
irix_prctl(struct pt_regs * regs)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
irix_syssgi(struct pt_regs * regs)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
irix_gtime(struct pt_regs * regs)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 */
irix_brk(unsigned long brk)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
irix_getpid(struct pt_regs * regs)599 asmlinkage int irix_getpid(struct pt_regs *regs)
600 {
601 regs->regs[3] = current->p_opptr->pid;
602 return current->pid;
603 }
604
irix_getuid(struct pt_regs * regs)605 asmlinkage int irix_getuid(struct pt_regs *regs)
606 {
607 regs->regs[3] = current->euid;
608 return current->uid;
609 }
610
irix_getgid(struct pt_regs * regs)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
irix_stime(int value)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_adjust = 0; /* stop active adjtime() */
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
636 extern int do_setitimer(int which, struct itimerval *value,
637 struct itimerval *ovalue);
638
jiffiestotv(unsigned long jiffies,struct timeval * value)639 static 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
getitimer_real(struct itimerval * value)645 static 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 /* look out for negative/zero itimer.. */
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
irix_alarm(unsigned int seconds)664 asmlinkage 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 * ehhh.. We can't return 0 if we have an alarm pending ...
681 * And we'd better return too much than too little anyway
682 */
683 if (it_old.it_value.tv_usec)
684 oldalarm++;
685
686 return oldalarm;
687 }
688
irix_pause(void)689 asmlinkage int irix_pause(void)
690 {
691 current->state = TASK_INTERRUPTIBLE;
692 schedule();
693
694 return -EINTR;
695 }
696
697 extern asmlinkage long sys_mount(char * dev_name, char * dir_name, char * type,
698 unsigned long new_flags, void * data);
699
700 /* XXX need more than this... */
irix_mount(char * dev_name,char * dir_name,unsigned long flags,char * type,void * data,int datalen)701 asmlinkage 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
711 struct 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
irix_statfs(const char * path,struct irix_statfs * buf,int len,int fs_type)717 asmlinkage 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 /* We don't support this feature yet. */
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
753 dput_and_out:
754 path_release(&nd);
755 out:
756 return error;
757 }
758
irix_fstatfs(unsigned int fd,struct irix_statfs * buf)759 asmlinkage 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
789 out_f:
790 fput(file);
791 out:
792 return error;
793 }
794
795 extern asmlinkage int sys_setpgid(pid_t pid, pid_t pgid);
796 extern asmlinkage int sys_setsid(void);
797
irix_setpgrp(int flags)798 asmlinkage 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
irix_times(struct tms * tbuf)816 asmlinkage 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
irix_exec(struct pt_regs * regs)833 asmlinkage 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
irix_exece(struct pt_regs * regs)852 asmlinkage 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
irix_gethostid(void)870 asmlinkage 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
irix_sethostid(unsigned long val)878 asmlinkage 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
886 extern asmlinkage int sys_socket(int family, int type, int protocol);
887
irix_socket(int family,int type,int protocol)888 asmlinkage 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; /* Invalid... */
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
irix_getdomainname(char * name,int len)922 asmlinkage 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
irix_getpagesize(void)941 asmlinkage unsigned long irix_getpagesize(void)
942 {
943 return PAGE_SIZE;
944 }
945
irix_msgsys(int opcode,unsigned long arg0,unsigned long arg1,unsigned long arg2,unsigned long arg3,unsigned long arg4)946 asmlinkage 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
irix_shmsys(int opcode,unsigned long arg0,unsigned long arg1,unsigned long arg2,unsigned long arg3)966 asmlinkage 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
irix_semsys(int opcode,unsigned long arg0,unsigned long arg1,unsigned long arg2,int arg3)984 asmlinkage 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
llseek(struct file * file,loff_t offset,int origin)1001 static 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
irix_lseek64(int fd,int _unused,int offhi,int offlow,int origin)1015 asmlinkage 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
1033 out_putf:
1034 fput(file);
1035 bad:
1036 return retval;
1037 }
1038
irix_sginap(int ticks)1039 asmlinkage int irix_sginap(int ticks)
1040 {
1041 current->state = TASK_INTERRUPTIBLE;
1042 schedule_timeout(ticks);
1043 return 0;
1044 }
1045
irix_sgikopt(char * istring,char * ostring,int len)1046 asmlinkage int irix_sgikopt(char *istring, char *ostring, int len)
1047 {
1048 return -EINVAL;
1049 }
1050
irix_gettimeofday(struct timeval * tv)1051 asmlinkage 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
irix_mmap32(unsigned long addr,size_t len,int prot,int flags,int fd,off_t offset)1061 asmlinkage 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 /* Ok, bad taste hack follows, try to think in something else
1072 * when reading this. */
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
irix_madvise(unsigned long addr,int len,int behavior)1096 asmlinkage 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
irix_pagelock(char * addr,int len,int op)1104 asmlinkage 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
irix_quotactl(struct pt_regs * regs)1112 asmlinkage 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
irix_BSDsetpgrp(int pid,int pgrp)1120 asmlinkage 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 /* Wheee, weird sysv thing... */
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
irix_systeminfo(int cmd,char * buf,int cnt)1144 asmlinkage 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
1152 struct 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
irix_uname(struct iuname * buf)1160 asmlinkage 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
1177 static inline u32
linux_to_irix_dev_t(dev_t t)1178 linux_to_irix_dev_t (dev_t t)
1179 {
1180 return MAJOR (t) << 18 | MINOR (t);
1181 }
1182
irix_xstat32_xlate(struct stat * kb,void * ubuf)1183 static 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
irix_xstat64_xlate(struct stat * sb)1217 static 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 /* XXX hackety hack... */
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 /* Now write it all back. */
1258 copy_to_user(sb, &ks, sizeof(struct xstat64));
1259 }
1260
1261 extern asmlinkage int sys_newstat(char * filename, struct stat * statbuf);
1262
irix_xstat(int version,char * filename,struct stat * statbuf)1263 asmlinkage 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
1306 out:
1307 return retval;
1308 }
1309
1310 extern asmlinkage int sys_newlstat(char * filename, struct stat * statbuf);
1311
irix_lxstat(int version,char * filename,struct stat * statbuf)1312 asmlinkage 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
1355 out:
1356 return error;
1357 }
1358
1359 extern asmlinkage int sys_newfstat(unsigned int fd, struct stat * statbuf);
1360
irix_fxstat(int version,int fd,struct stat * statbuf)1361 asmlinkage 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
1404 out:
1405 return error;
1406 }
1407
1408 extern asmlinkage int sys_mknod(const char * filename, int mode, dev_t dev);
1409
irix_xmknod(int ver,char * filename,int mode,dev_t dev)1410 asmlinkage 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
irix_swapctl(int cmd,char * arg)1430 asmlinkage 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
1438 struct 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
irix_statvfs(char * fname,struct irix_statvfs * buf)1446 asmlinkage 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); /* XXX hackety hack... */
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); /* XXX hackety hack... */
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
1486 dput_and_out:
1487 path_release(&nd);
1488 out:
1489 return error;
1490 }
1491
irix_fstatvfs(int fd,struct irix_statvfs * buf)1492 asmlinkage 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); /* XXX hackety hack... */
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); /* XXX hackety hack... */
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
1531 out_f:
1532 fput(file);
1533 out:
1534 return error;
1535 }
1536
irix_priocntl(struct pt_regs * regs)1537 asmlinkage 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
irix_sigqueue(int pid,int sig,int code,int val)1545 asmlinkage 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
1553 extern asmlinkage int sys_truncate(const char * path, unsigned long length);
1554 extern asmlinkage int sys_ftruncate(unsigned int fd, unsigned long length);
1555
irix_truncate64(char * name,int pad,int size1,int size2)1556 asmlinkage 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
1566 out:
1567 return retval;
1568 }
1569
irix_ftruncate64(int fd,int pad,int size1,int size2)1570 asmlinkage 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
1580 out:
1581 return retval;
1582 }
1583
1584 extern asmlinkage unsigned long
1585 sys_mmap(unsigned long addr, size_t len, int prot, int flags, int fd,
1586 off_t offset);
1587
irix_mmap64(struct pt_regs * regs)1588 asmlinkage 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 /* Ok, bad taste hack follows, try to think in something else
1632 when reading this */
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
1654 out:
1655 return error;
1656 }
1657
irix_dmi(struct pt_regs * regs)1658 asmlinkage 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
irix_pread(int fd,char * buf,int cnt,int off64,int off1,int off2)1666 asmlinkage 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
irix_pwrite(int fd,char * buf,int cnt,int off64,int off1,int off2)1675 asmlinkage 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
irix_sgifastpath(int cmd,unsigned long arg0,unsigned long arg1,unsigned long arg2,unsigned long arg3,unsigned long arg4,unsigned long arg5)1684 asmlinkage 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
1696 struct 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
irix_statvfs64(char * fname,struct irix_statvfs64 * buf)1707 asmlinkage 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); /* XXX hackety hack... */
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); /* XXX hackety hack... */
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
1747 dput_and_out:
1748 path_release(&nd);
1749 out:
1750 return error;
1751 }
1752
irix_fstatvfs64(int fd,struct irix_statvfs * buf)1753 asmlinkage 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); /* XXX hackety hack... */
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); /* XXX hackety hack... */
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
1792 out_f:
1793 fput(file);
1794 out:
1795 return error;
1796 }
1797
irix_getmountid(char * fname,unsigned long * midbuf)1798 asmlinkage 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 * The idea with this system call is that when trying to determine
1810 * 'pwd' and it's a toss-up for some reason, userland can use the
1811 * fsid of the filesystem to try and make the right decision, but
1812 * we don't have this so for now. XXX
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
irix_nsproc(unsigned long entry,unsigned long mask,unsigned long arg,unsigned long sp,int slen)1822 asmlinkage 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
1833 struct irix_dirent32 {
1834 u32 d_ino;
1835 u32 d_off;
1836 unsigned short d_reclen;
1837 char d_name[1];
1838 };
1839
1840 struct 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
irix_filldir32(void * __buf,const char * name,int namlen,loff_t offset,ino_t ino,unsigned int d_type)1850 static 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; /* only used if we fail.. */
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
irix_ngetdents(unsigned int fd,void * dirent,unsigned int count,int * eob)1881 asmlinkage 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
1924 out_putf:
1925 fput(file);
1926 out:
1927 return error;
1928 }
1929
1930 struct irix_dirent64 {
1931 u64 d_ino;
1932 u64 d_off;
1933 unsigned short d_reclen;
1934 char d_name[1];
1935 };
1936
1937 struct 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
irix_filldir64(void * __buf,const char * name,int namlen,loff_t offset,ino_t ino,unsigned int d_type)1947 static 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; /* only used if we fail.. */
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
irix_getdents64(int fd,void * dirent,int cnt)1974 asmlinkage 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
2015 out_f:
2016 fput(file);
2017 out:
2018 return error;
2019 }
2020
irix_ngetdents64(int fd,void * dirent,int cnt,int * eob)2021 asmlinkage 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
2064 out_f:
2065 fput(file);
2066 out:
2067 return error;
2068 }
2069
irix_uadmin(unsigned long op,unsigned long func,unsigned long arg)2070 asmlinkage int irix_uadmin(unsigned long op, unsigned long func, unsigned long arg)
2071 {
2072 int retval;
2073
2074 switch (op) {
2075 case 1:
2076 /* Reboot */
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 /* Shutdown */
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 /* Remount-root */
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 /* Kill all tasks. */
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 /* Set magic mushrooms... */
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
2117 out:
2118 return retval;
2119 }
2120
irix_utssys(char * inbuf,int arg,int type,char * outbuf)2121 asmlinkage int irix_utssys(char *inbuf, int arg, int type, char *outbuf)
2122 {
2123 int retval;
2124
2125 switch(type) {
2126 case 0:
2127 /* uname() */
2128 retval = irix_uname((struct iuname *)inbuf);
2129 goto out;
2130
2131 case 2:
2132 /* ustat() */
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 /* fusers() */
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
2152 out:
2153 return retval;
2154 }
2155
2156 #undef DEBUG_FCNTL
2157
2158 extern asmlinkage long sys_fcntl(unsigned int fd, unsigned int cmd,
2159 unsigned long arg);
2160
2161 #define IRIX_F_ALLOCSP 10
2162
irix_fcntl(int fd,int cmd,int arg)2163 asmlinkage 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
irix_ulimit(int cmd,int arg)2181 asmlinkage 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 }
2226 out:
2227 return retval;
2228 }
2229
irix_unimp(struct pt_regs * regs)2230 asmlinkage 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