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 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 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