OpenCores
URL https://opencores.org/ocsvn/or1k_soc_on_altera_embedded_dev_kit/or1k_soc_on_altera_embedded_dev_kit/trunk

Subversion Repositories or1k_soc_on_altera_embedded_dev_kit

[/] [or1k_soc_on_altera_embedded_dev_kit/] [trunk/] [linux-2.6/] [linux-2.6.24/] [arch/] [mips/] [kernel/] [sysirix.c] - Blame information for rev 3

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.