This source file includes following definitions.
- osf_filldir
- osf_getdirentries
- sys_madvise
- sys_getxuid
- sys_getxgid
- sys_getxpid
- osf_mmap
- osf_statfs
- osf_fstatfs
- getdev
- putdev
- osf_ufs_mount
- osf_cdfs_mount
- osf_procfs_mount
- osf_mount
- osf_umount
- osf_usleep_thread
- osf_utsname
- osf_swapon
- sys_getpagesize
- sys_getdtablesize
- sys_pipe
- osf_getdomainname
- osf_shmat
- osf_proplist_syscall
- alpha_create_module
- osf_getsysinfo
- osf_setsysinfo
1
2
3
4
5
6
7
8
9
10
11
12
13 #include <linux/errno.h>
14 #include <linux/sched.h>
15 #include <linux/kernel.h>
16 #include <linux/mm.h>
17 #include <linux/stddef.h>
18 #include <linux/unistd.h>
19 #include <linux/ptrace.h>
20 #include <linux/malloc.h>
21 #include <linux/ldt.h>
22 #include <linux/user.h>
23 #include <linux/a.out.h>
24 #include <linux/utsname.h>
25 #include <linux/time.h>
26 #include <linux/major.h>
27 #include <linux/stat.h>
28 #include <linux/mman.h>
29 #include <linux/shm.h>
30
31 #include <asm/fpu.h>
32 #include <asm/io.h>
33 #include <asm/segment.h>
34 #include <asm/system.h>
35
36 extern int do_mount(kdev_t, const char *, const char *, char *, int, void *);
37 extern int do_pipe(int *);
38
39 extern struct file_operations * get_blkfops(unsigned int);
40 extern struct file_operations * get_chrfops(unsigned int);
41
42 extern kdev_t get_unnamed_dev(void);
43 extern void put_unnamed_dev(kdev_t);
44
45 extern asmlinkage int sys_umount(char *);
46 extern asmlinkage int sys_swapon(const char *specialfile, int swap_flags);
47
48
49
50
51
52
53
54
55 #define NAME_OFFSET(de) ((int) ((de)->d_name - (char *) (de)))
56 #define ROUND_UP(x) (((x)+3) & ~3)
57
58 struct osf_dirent {
59 unsigned int d_ino;
60 unsigned short d_reclen;
61 unsigned short d_namlen;
62 char d_name[1];
63 };
64
65 struct osf_dirent_callback {
66 struct osf_dirent * dirent;
67 long *basep;
68 int count;
69 int error;
70 };
71
72 static int osf_filldir(void * __buf, const char * name, int namlen, off_t offset, ino_t ino)
73 {
74 struct osf_dirent * dirent;
75 struct osf_dirent_callback * buf = (struct osf_dirent_callback *) __buf;
76 int reclen = ROUND_UP(NAME_OFFSET(dirent) + namlen + 1);
77
78 buf->error = -EINVAL;
79 if (reclen > buf->count)
80 return -EINVAL;
81 if (buf->basep) {
82 put_user(offset, buf->basep);
83 buf->basep = NULL;
84 }
85 dirent = buf->dirent;
86 put_user(ino, &dirent->d_ino);
87 put_user(namlen, &dirent->d_namlen);
88 put_user(reclen, &dirent->d_reclen);
89 memcpy_tofs(dirent->d_name, name, namlen);
90 put_fs_byte(0, dirent->d_name + namlen);
91 ((char *) dirent) += reclen;
92 buf->dirent = dirent;
93 buf->count -= reclen;
94 return 0;
95 }
96
97 asmlinkage int osf_getdirentries(unsigned int fd, struct osf_dirent * dirent,
98 unsigned int count, long *basep)
99 {
100 int error;
101 struct file * file;
102 struct osf_dirent_callback buf;
103
104 if (fd >= NR_OPEN || !(file = current->files->fd[fd]))
105 return -EBADF;
106 if (!file->f_op || !file->f_op->readdir)
107 return -ENOTDIR;
108 error = verify_area(VERIFY_WRITE, dirent, count);
109 if (error)
110 return error;
111 if (basep) {
112 error = verify_area(VERIFY_WRITE, basep, sizeof(long));
113 if (error)
114 return error;
115 }
116 buf.dirent = dirent;
117 buf.basep = basep;
118 buf.count = count;
119 buf.error = 0;
120 error = file->f_op->readdir(file->f_inode, file, &buf, osf_filldir);
121 if (error < 0)
122 return error;
123 if (count == buf.count)
124 return buf.error;
125 return count - buf.count;
126 }
127
128
129
130
131 asmlinkage unsigned long sys_madvise(void)
132 {
133 return 0;
134 }
135
136 asmlinkage unsigned long sys_getxuid(int a0, int a1, int a2, int a3, int a4, int a5,
137 struct pt_regs regs)
138 {
139 (®s)->r20 = current->euid;
140 return current->uid;
141 }
142
143 asmlinkage unsigned long sys_getxgid(int a0, int a1, int a2, int a3, int a4, int a5,
144 struct pt_regs regs)
145 {
146 (®s)->r20 = current->egid;
147 return current->gid;
148 }
149
150 asmlinkage unsigned long sys_getxpid(int a0, int a1, int a2, int a3, int a4, int a5,
151 struct pt_regs regs)
152 {
153 (®s)->r20 = current->p_opptr->pid;
154 return current->pid;
155 }
156
157 asmlinkage unsigned long osf_mmap(unsigned long addr, unsigned long len,
158 unsigned long prot, unsigned long flags, unsigned long fd,
159 unsigned long off)
160 {
161 struct file * file = NULL;
162
163 if (flags & (MAP_HASSEMAPHORE | MAP_INHERIT | MAP_UNALIGNED))
164 printk("%s: unimplemented OSF mmap flags %04lx\n", current->comm, flags);
165 if (!(flags & MAP_ANONYMOUS)) {
166 if (fd >= NR_OPEN || !(file = current->files->fd[fd]))
167 return -EBADF;
168 }
169 return do_mmap(file, addr, len, prot, flags, off);
170 }
171
172 asmlinkage int osf_statfs(char * path, struct statfs * buffer, unsigned long bufsiz)
173 {
174 struct inode * inode;
175 int retval;
176
177 if (bufsiz > sizeof(struct statfs))
178 bufsiz = sizeof(struct statfs);
179 retval = verify_area(VERIFY_WRITE, buffer, bufsiz);
180 if (retval)
181 return retval;
182 retval = namei(path, &inode);
183 if (retval)
184 return retval;
185 if (!inode->i_sb->s_op->statfs) {
186 iput(inode);
187 return -ENOSYS;
188 }
189 inode->i_sb->s_op->statfs(inode->i_sb, buffer, bufsiz);
190 iput(inode);
191 return 0;
192 }
193
194 asmlinkage int osf_fstatfs(unsigned long fd, struct statfs * buffer, unsigned long bufsiz)
195 {
196 struct file * file;
197 struct inode * inode;
198 int retval;
199
200 retval = verify_area(VERIFY_WRITE, buffer, bufsiz);
201 if (retval)
202 return retval;
203 if (bufsiz > sizeof(struct statfs))
204 bufsiz = sizeof(struct statfs);
205 if (fd >= NR_OPEN || !(file = current->files->fd[fd]))
206 return -EBADF;
207 if (!(inode = file->f_inode))
208 return -ENOENT;
209 if (!inode->i_sb->s_op->statfs)
210 return -ENOSYS;
211 inode->i_sb->s_op->statfs(inode->i_sb, buffer, bufsiz);
212 return 0;
213 }
214
215
216
217
218
219
220 struct ufs_args {
221 char * devname;
222 int flags;
223 uid_t exroot;
224 };
225
226 struct cdfs_args {
227 char * devname;
228 int flags;
229 uid_t exroot;
230
231
232
233
234 };
235
236 struct procfs_args {
237 char * devname;
238 int flags;
239 uid_t exroot;
240 };
241
242 static int getdev(const char * name, int rdonly, struct inode ** ino)
243 {
244 kdev_t dev;
245 struct inode * inode;
246 struct file_operations * fops;
247 int retval;
248
249 retval = namei(name, &inode);
250 if (retval)
251 return retval;
252 if (!S_ISBLK(inode->i_mode)) {
253 iput(inode);
254 return -ENOTBLK;
255 }
256 if (IS_NODEV(inode)) {
257 iput(inode);
258 return -EACCES;
259 }
260 dev = inode->i_rdev;
261 if (MAJOR(dev) >= MAX_BLKDEV) {
262 iput(inode);
263 return -ENXIO;
264 }
265 fops = get_blkfops(MAJOR(dev));
266 if (!fops) {
267 iput(inode);
268 return -ENODEV;
269 }
270 if (fops->open) {
271 struct file dummy;
272 memset(&dummy, 0, sizeof(dummy));
273 dummy.f_inode = inode;
274 dummy.f_mode = rdonly ? 1 : 3;
275 retval = fops->open(inode, &dummy);
276 if (retval) {
277 iput(inode);
278 return retval;
279 }
280 }
281 *ino = inode;
282 return 0;
283 }
284
285 static void putdev(struct inode * inode)
286 {
287 struct file_operations * fops;
288
289 fops = get_blkfops(MAJOR(inode->i_rdev));
290 if (fops->release)
291 fops->release(inode, NULL);
292 }
293
294
295
296
297
298
299 static int osf_ufs_mount(char * dirname, struct ufs_args * args, int flags)
300 {
301 int retval;
302 struct inode * inode;
303 struct cdfs_args tmp;
304
305 retval = verify_area(VERIFY_READ, args, sizeof(*args));
306 if (retval)
307 return retval;
308 memcpy_fromfs(&tmp, args, sizeof(tmp));
309 retval = getdev(tmp.devname, 0, &inode);
310 if (retval)
311 return retval;
312 retval = do_mount(inode->i_rdev, tmp.devname, dirname, "ext2", flags, NULL);
313 if (retval)
314 putdev(inode);
315 iput(inode);
316 return retval;
317 }
318
319 static int osf_cdfs_mount(char * dirname, struct cdfs_args * args, int flags)
320 {
321 int retval;
322 struct inode * inode;
323 struct cdfs_args tmp;
324
325 retval = verify_area(VERIFY_READ, args, sizeof(*args));
326 if (retval)
327 return retval;
328 memcpy_fromfs(&tmp, args, sizeof(tmp));
329 retval = getdev(tmp.devname, 1, &inode);
330 if (retval)
331 return retval;
332 retval = do_mount(inode->i_rdev, tmp.devname, dirname, "iso9660", flags, NULL);
333 if (retval)
334 putdev(inode);
335 iput(inode);
336 return retval;
337 }
338
339 static int osf_procfs_mount(char * dirname, struct procfs_args * args, int flags)
340 {
341 kdev_t dev;
342 int retval;
343 struct procfs_args tmp;
344
345 retval = verify_area(VERIFY_READ, args, sizeof(*args));
346 if (retval)
347 return retval;
348 memcpy_fromfs(&tmp, args, sizeof(tmp));
349 dev = get_unnamed_dev();
350 if (!dev)
351 return -ENODEV;
352 retval = do_mount(dev, "", dirname, "proc", flags, NULL);
353 if (retval)
354 put_unnamed_dev(dev);
355 return retval;
356 }
357
358 asmlinkage int osf_mount(unsigned long typenr, char * path, int flag, void * data)
359 {
360 int retval;
361
362 retval = -EINVAL;
363 switch (typenr) {
364 case 1:
365 retval = osf_ufs_mount(path, (struct ufs_args *) data, flag);
366 break;
367 case 6:
368 retval = osf_cdfs_mount(path, (struct cdfs_args *) data, flag);
369 break;
370 case 9:
371 retval = osf_procfs_mount(path, (struct procfs_args *) data, flag);
372 break;
373 default:
374 printk("osf_mount(%ld, %x)\n", typenr, flag);
375 }
376 return retval;
377 }
378
379 asmlinkage int osf_umount(char * path, int flag)
380 {
381 return sys_umount(path);
382 }
383
384
385
386
387
388
389 asmlinkage int osf_usleep_thread(struct timeval * sleep, struct timeval * remain)
390 {
391 struct timeval tmp;
392 unsigned long ticks;
393 int retval;
394
395 retval = verify_area(VERIFY_READ, sleep, sizeof(*sleep));
396 if (retval)
397 return retval;
398 if (remain && (retval = verify_area(VERIFY_WRITE, remain, sizeof(*remain))))
399 return retval;
400 memcpy_fromfs(&tmp, sleep, sizeof(*sleep));
401 ticks = tmp.tv_usec;
402 ticks = (ticks + (1000000 / HZ) - 1) / (1000000 / HZ);
403 ticks += tmp.tv_sec * HZ;
404 current->timeout = ticks + jiffies;
405 current->state = TASK_INTERRUPTIBLE;
406 schedule();
407 if (!remain)
408 return 0;
409 ticks = jiffies;
410 if (ticks < current->timeout)
411 ticks = current->timeout - ticks;
412 else
413 ticks = 0;
414 current->timeout = 0;
415 tmp.tv_sec = ticks / HZ;
416 tmp.tv_usec = ticks % HZ;
417 memcpy_tofs(remain, &tmp, sizeof(*remain));
418 return 0;
419 }
420
421 asmlinkage int osf_utsname(char * name)
422 {
423 int error = verify_area(VERIFY_WRITE, name, 5*32);
424 if (error)
425 return error;
426 memcpy_tofs(name + 0, system_utsname.sysname, 32);
427 memcpy_tofs(name + 32, system_utsname.nodename, 32);
428 memcpy_tofs(name + 64, system_utsname.release, 32);
429 memcpy_tofs(name + 96, system_utsname.version, 32);
430 memcpy_tofs(name + 128, system_utsname.machine, 32);
431 return 0;
432 }
433
434 asmlinkage int osf_swapon(const char * path, int flags, int lowat, int hiwat)
435 {
436
437 return sys_swapon(path, flags);
438 }
439
440 asmlinkage unsigned long sys_getpagesize(void)
441 {
442 return PAGE_SIZE;
443 }
444
445 asmlinkage unsigned long sys_getdtablesize(void)
446 {
447 return NR_OPEN;
448 }
449
450 asmlinkage int sys_pipe(int a0, int a1, int a2, int a3, int a4, int a5,
451 struct pt_regs regs)
452 {
453 int fd[2];
454 int error;
455
456 error = do_pipe(fd);
457 if (error)
458 return error;
459 (®s)->r20 = fd[1];
460 return fd[0];
461 }
462
463
464
465
466 asmlinkage int osf_getdomainname(char *name, int namelen)
467 {
468 unsigned len;
469 int i, error;
470
471 error = verify_area(VERIFY_WRITE, name, namelen);
472 if (error)
473 return error;
474
475 len = namelen;
476 if (namelen > 32)
477 len = 32;
478
479 for (i = 0; i < len; ++i) {
480 put_user(system_utsname.domainname[i], name + i);
481 if (system_utsname.domainname[i] == '\0')
482 break;
483 }
484 return 0;
485 }
486
487
488 asmlinkage long osf_shmat(int shmid, void *shmaddr, int shmflg)
489 {
490 unsigned long raddr;
491 int err;
492
493 err = sys_shmat(shmid, shmaddr, shmflg, &raddr);
494 if (err)
495 return err;
496
497
498
499
500 return raddr;
501 }
502
503
504
505
506
507
508
509
510
511
512
513
514 #define PLE_PROPAGATE_ON_COPY 0x1
515
516 #define PLE_FLAG_MASK 0x1
517 #define PLE_FLAG_ALL -1
518
519 struct proplistname_args {
520 unsigned int pl_mask;
521 unsigned int pl_numnames;
522 char **pl_names;
523 };
524
525 union pl_args {
526 struct setargs {
527 char *path;
528 long follow;
529 long nbytes;
530 char *buf;
531 } set;
532 struct fsetargs {
533 long fd;
534 long nbytes;
535 char *buf;
536 } fset;
537 struct getargs {
538 char *path;
539 long follow;
540 struct proplistname_args *name_args;
541 long nbytes;
542 char *buf;
543 int *min_buf_size;
544 } get;
545 struct fgetargs {
546 long fd;
547 struct proplistname_args *name_args;
548 long nbytes;
549 char *buf;
550 int *min_buf_size;
551 } fget;
552 struct delargs {
553 char *path;
554 long follow;
555 struct proplistname_args *name_args;
556 } del;
557 struct fdelargs {
558 long fd;
559 struct proplistname_args *name_args;
560 } fdel;
561 };
562
563 enum pl_code {
564 PL_SET = 1, PL_FSET = 2,
565 PL_GET = 3, PL_FGET = 4,
566 PL_DEL = 5, PL_FDEL = 6
567 };
568
569 asmlinkage long osf_proplist_syscall (enum pl_code code, union pl_args *args)
570 {
571 long error;
572 int *min_buf_size_ptr;
573
574 switch (code) {
575 case PL_SET:
576 error = verify_area(VERIFY_READ, &args->set.nbytes,
577 sizeof(args->set.nbytes));
578 if (error)
579 return error;
580 return args->set.nbytes;
581
582 case PL_FSET:
583 error = verify_area(VERIFY_READ, &args->fset.nbytes,
584 sizeof(args->fset.nbytes));
585 if (error)
586 return error;
587 return args->fset.nbytes;
588
589 case PL_GET:
590 error = verify_area(VERIFY_READ, &args->get.min_buf_size,
591 sizeof(args->get.min_buf_size));
592 if (error)
593 return error;
594 min_buf_size_ptr = get_user(&args->get.min_buf_size);
595 error = verify_area(VERIFY_WRITE, min_buf_size_ptr,
596 sizeof(*min_buf_size_ptr));
597 if (error)
598 return error;
599 put_user(0, min_buf_size_ptr);
600 return 0;
601
602 case PL_FGET:
603 error = verify_area(VERIFY_READ, &args->fget.min_buf_size,
604 sizeof(args->fget.min_buf_size));
605 if (error)
606 return error;
607 min_buf_size_ptr = get_user(&args->fget.min_buf_size);
608 error = verify_area(VERIFY_WRITE, min_buf_size_ptr,
609 sizeof(*min_buf_size_ptr));
610 if (error)
611 return error;
612 put_user(0, min_buf_size_ptr);
613 return 0;
614
615 case PL_DEL:
616 case PL_FDEL:
617 return 0;
618
619 default:
620 return -EOPNOTSUPP;
621 }
622 }
623
624
625
626
627
628
629
630
631 asmlinkage unsigned long
632 alpha_create_module (char * module_name, unsigned long size,
633 int a3, int a4, int a5, int a6,
634 struct pt_regs regs)
635 {
636 asmlinkage unsigned long sys_create_module (char *, unsigned long);
637 long retval;
638
639 retval = sys_create_module(module_name, size);
640
641
642
643
644
645
646 if (retval + 1000 > 0)
647 return retval;
648
649
650 regs.r0 = 0;
651 return retval;
652 }
653
654
655 asmlinkage unsigned long
656 osf_getsysinfo (unsigned long op, void * buffer, unsigned long nbytes,
657 int * start, void *arg)
658 {
659 extern unsigned long rdfpcr (void);
660 unsigned long fpcw;
661
662 switch (op) {
663 case 45:
664
665 fpcw = current->tss.flags & IEEE_TRAP_ENABLE_MASK;
666 fpcw |= ((rdfpcr() >> 52) << 17) & IEEE_STATUS_MASK;
667 put_user(fpcw, (unsigned long *) buffer);
668 return 0;
669
670 case 46:
671
672
673
674
675
676 break;
677
678 default:
679 break;
680 }
681 return -EOPNOTSUPP;
682 }
683
684
685 asmlinkage unsigned long
686 osf_setsysinfo (unsigned long op, void * buffer, unsigned long nbytes,
687 int * start, void *arg)
688 {
689 unsigned long fpcw;
690
691 switch (op) {
692 case 14:
693
694 fpcw = get_user((unsigned long *) buffer);
695 current->tss.flags &= ~IEEE_TRAP_ENABLE_MASK;
696 current->tss.flags |= (fpcw & IEEE_TRAP_ENABLE_MASK);
697 return 0;
698
699 case 15:
700 case 16:
701
702
703
704
705
706 default:
707 break;
708 }
709 return -EOPNOTSUPP;
710 }