1 /*
2 * This file contains a number of device-type independent device routines.
3 *
4 * The entry points in this file are:
5 * do_ioctl: perform the IOCTL system call
6 * make_ioctl_grant: make a grant for an IOCTL request to a device
7 */
8
9 #include "fs.h"
10 #include "vnode.h"
11 #include "file.h"
12 #include <sys/ioctl.h>
13
14 /*
15 * Perform the ioctl(2) system call.
16 */
17 int
do_ioctl(void)18 do_ioctl(void)
19 {
20 unsigned long request;
21 struct filp *f;
22 register struct vnode *vp;
23 vir_bytes arg;
24 int r, fd;
25
26 fd = job_m_in.m_lc_vfs_ioctl.fd;
27 request = job_m_in.m_lc_vfs_ioctl.req;
28 arg = (vir_bytes)job_m_in.m_lc_vfs_ioctl.arg;
29
30 if ((f = get_filp(fd, VNODE_READ)) == NULL)
31 return(err_code);
32 vp = f->filp_vno; /* get vnode pointer */
33
34 switch (vp->v_mode & S_IFMT) {
35 case S_IFBLK:
36 f->filp_ioctl_fp = fp;
37
38 r = bdev_ioctl(vp->v_sdev, who_e, request, arg);
39
40 f->filp_ioctl_fp = NULL;
41 break;
42
43 case S_IFCHR:
44 r = cdev_io(CDEV_IOCTL, vp->v_sdev, who_e, arg, 0, request,
45 f->filp_flags);
46 break;
47
48 case S_IFSOCK:
49 r = sdev_ioctl(vp->v_sdev, request, arg, f->filp_flags);
50 break;
51
52 default:
53 r = ENOTTY;
54 }
55
56 unlock_filp(f);
57
58 return r;
59 }
60
61 /*
62 * Create a magic grant for the given IOCTL request.
63 */
64 cp_grant_id_t
make_ioctl_grant(endpoint_t driver_e,endpoint_t user_e,vir_bytes buf,unsigned long request)65 make_ioctl_grant(endpoint_t driver_e, endpoint_t user_e, vir_bytes buf,
66 unsigned long request)
67 {
68 cp_grant_id_t grant;
69 int access;
70 size_t size;
71
72 /*
73 * For IOCTLs, the bytes parameter contains the IOCTL request.
74 * This request encodes the requested access method and buffer size.
75 */
76 access = 0;
77 if (_MINIX_IOCTL_IOR(request)) access |= CPF_WRITE;
78 if (_MINIX_IOCTL_IOW(request)) access |= CPF_READ;
79 if (_MINIX_IOCTL_BIG(request))
80 size = _MINIX_IOCTL_SIZE_BIG(request);
81 else
82 size = _MINIX_IOCTL_SIZE(request);
83
84 /*
85 * Grant access to the buffer even if no I/O happens with the ioctl,
86 * although now that we no longer identify responses based on grants,
87 * this is not strictly necessary.
88 */
89 grant = cpf_grant_magic(driver_e, user_e, buf, size, access);
90
91 if (!GRANT_VALID(grant))
92 panic("VFS: cpf_grant_magic failed");
93
94 return grant;
95 }
96