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(&current->real_timer)) {
652 		unsigned long now = jiffies;
653 		val = current->real_timer.expires;
654 		add_timer(&current->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(&current->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(&current->mm->mmap_sem);
1088 	retval = do_mmap(file, addr, len, prot, flags, offset);
1089 	up_write(&current->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(&current->mm->mmap_sem);
1648 	error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
1649 	up_write(&current->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