static void bdev_vrdwt_cleanup(const message *m, iovec_s_t *gvec) { /* Clean up a vectored read/write request. */ cp_grant_id_t grant; int i; grant = m->BDEV_GRANT; cpf_revoke(grant); for (i = m->BDEV_COUNT - 1; i >= 0; i--) cpf_revoke(gvec[i].iov_grant); }
/*===========================================================================* * single_revoke * *===========================================================================*/ PRIVATE void single_revoke(cp_grant_id_t gid, const iovec_s_t vector[NR_IOREQS], int count) { /* Revoke all grants associated with a request to a single driver. * Modify the given size to reflect the actual I/O performed. */ int i; /* Revoke the grants for all the elements of the vector. */ for (i = 0; i < count; i++) cpf_revoke(vector[i].iov_grant); /* Then revoke the grant for the vector itself. */ cpf_revoke(gid); }
/* check the permissions of a socket file */ static int check_perms(int minor, struct sockaddr_un *addr) { int rc; message vfs_m; cp_grant_id_t grant_id; grant_id = cpf_grant_direct(VFS_PROC_NR, (vir_bytes) addr->sun_path, UNIX_PATH_MAX, CPF_READ | CPF_WRITE); /* ask the VFS to verify the permissions */ memset(&vfs_m, '\0', sizeof(message)); vfs_m.m_type = PFS_REQ_CHECK_PERMS; vfs_m.USER_ENDPT = uds_fd_table[minor].owner; vfs_m.IO_GRANT = (char *) grant_id; vfs_m.COUNT = UNIX_PATH_MAX; rc = sendrec(VFS_PROC_NR, &vfs_m); cpf_revoke(grant_id); if (OK != rc) { printf("(uds) sendrec error... req_nr: %d err: %d\n", vfs_m.m_type, rc); return EIO; } #if DEBUG == 1 printf("(uds) VFS reply => %d\n", vfs_m.m_type); printf("(uds) Canonical Path => %s\n", addr->sun_path); #endif return vfs_m.m_type; /* return reply code OK, ELOOP, etc. */ }
/*===========================================================================* * req_link * *===========================================================================*/ PUBLIC int req_link( endpoint_t fs_e, ino_t link_parent, char *lastc, ino_t linked_file ) { int r; cp_grant_id_t grant_id; const size_t len = strlen(lastc) + 1; message m; grant_id = cpf_grant_direct(fs_e, (vir_bytes)lastc, len, CPF_READ); if(grant_id == -1) panic("req_link: cpf_grant_direct failed"); /* Fill in request message */ m.m_type = REQ_LINK; m.REQ_INODE_NR = linked_file; m.REQ_DIR_INO = link_parent; m.REQ_GRANT = grant_id; m.REQ_PATH_LEN = len; /* Send/rec request */ r = fs_sendrec(fs_e, &m); cpf_revoke(grant_id); return(r); }
/*===========================================================================* * req_newdriver * *===========================================================================*/ PUBLIC int req_newdriver( endpoint_t fs_e, dev_t dev, char *label ) { cp_grant_id_t grant_id; size_t len; message m; int r; /* Grant access to label */ len = strlen(label) + 1; grant_id = cpf_grant_direct(fs_e, (vir_bytes) label, len, CPF_READ); if (grant_id == -1) panic("req_newdriver: cpf_grant_direct failed"); /* Fill in request message */ m.m_type = REQ_NEW_DRIVER; m.REQ_DEV = dev; m.REQ_GRANT = grant_id; m.REQ_PATH_LEN = len; /* Issue request */ r = fs_sendrec(fs_e, &m); cpf_revoke(grant_id); return(r); }
cp_grant_id_t cpf_grant_indirect(endpoint_t who_to, endpoint_t who_from, cp_grant_id_t gr) { /* Grant process A access into process B. B has granted us access as grant * id 'gr'. */ cp_grant_id_t g; int r; /* Obtain new slot. */ if((g = cpf_new_grantslot()) < 0) return -1; /* Basic sanity checks. */ assert(GRANT_VALID(g)); assert(g >= 0); assert(g < ngrants); assert(!(grants[g].cp_flags & CPF_USED)); /* Fill in new slot data. */ if((r=cpf_setgrant_indirect(g, who_to, who_from, gr)) < 0) { cpf_revoke(g); return GRANT_INVALID; } return g; }
/*===========================================================================* * req_mkdir * *===========================================================================*/ PUBLIC int req_mkdir( endpoint_t fs_e, ino_t inode_nr, char *lastc, uid_t uid, gid_t gid, mode_t dmode ) { int r; cp_grant_id_t grant_id; size_t len; message m; len = strlen(lastc) + 1; grant_id = cpf_grant_direct(fs_e, (vir_bytes)lastc, len, CPF_READ); if(grant_id == -1) panic("req_mkdir: cpf_grant_direct failed"); /* Fill in request message */ m.m_type = REQ_MKDIR; m.REQ_INODE_NR = inode_nr; m.REQ_MODE = dmode; m.REQ_UID = uid; m.REQ_GID = gid; m.REQ_GRANT = grant_id; m.REQ_PATH_LEN = len; /* Send/rec request */ r = fs_sendrec(fs_e, &m); cpf_revoke(grant_id); return(r); }
cp_grant_id_t cpf_grant_magic(endpoint_t who_to, endpoint_t who_from, vir_bytes addr, size_t bytes, int access) { /* Grant process A access into process B. Not everyone can do this. */ cp_grant_id_t g; int r; ACCESS_CHECK(access); /* Obtain new slot. */ if((g = cpf_new_grantslot()) < 0) return -1; /* Basic sanity checks. */ assert(GRANT_VALID(g)); assert(g >= 0); assert(g < ngrants); assert(!(grants[g].cp_flags & CPF_USED)); if((r=cpf_setgrant_magic(g, who_to, who_from, addr, bytes, access)) < 0) { cpf_revoke(g); return -1; } return g; }
/***************************************************************************** * _usb_urb_complete * ****************************************************************************/ static void _usb_urb_complete(struct usb_driver *ud, long urb_id) { /* find the corresponding URB in the urb_pending list. */ struct usb_urb * urb = NULL; if (pending_urbs != NULL) { if (pending_urbs->urb_id == urb_id) { urb = pending_urbs; pending_urbs = urb->next; } else { struct usb_urb *u = pending_urbs; while (u->next) { if (u->next->urb_id == urb_id) { urb = u->next; u->next = u->next->next; urb->next = NULL; break; } u = u->next; } } } /* Did we find a URB? */ if (urb != NULL) { /* revoke grant */ cpf_revoke(urb->gid); /* call completion handler */ #if 0 dump_urb(urb); #endif ud->urb_completion(urb); } else { printf("WARN: _usb_urb_complete: did not find URB with ID %ld", urb_id); } }
static void bdev_ioctl_cleanup(const message *m) { /* Clean up an I/O control request. */ cpf_revoke(m->BDEV_GRANT); }
PRIVATE int do_invoke_ds(int type, const char *ds_name) { cp_grant_id_t g_key; size_t len_key; int access, r; if(type == DS_CHECK || type == DS_RETRIEVE_LABEL) { len_key = DS_MAX_KEYLEN; access = CPF_WRITE; } else { len_key = strlen(ds_name)+1; access = CPF_READ; } /* Grant for key. */ g_key = cpf_grant_direct(DS_PROC_NR, (vir_bytes) ds_name, len_key, access); if(!GRANT_VALID(g_key)) return errno; m.DS_KEY_GRANT = g_key; m.DS_KEY_LEN = len_key; r = _taskcall(DS_PROC_NR, type, &m); cpf_revoke(g_key); return r; }
static void bdev_rdwt_cleanup(const message *m) { /* Clean up a single-buffer read/write request. */ cpf_revoke(m->BDEV_GRANT); }
/*===========================================================================* * do_gcov_flush * *===========================================================================*/ PUBLIC int do_gcov_flush() { /* A userland tool has requested the gcov data from another * process (possibly vfs itself). Grant the target process * access to the supplied buffer, and perform the call that * makes the target copy its buffer to the caller (incl vfs * itself). */ struct fproc *rfp; ssize_t size; cp_grant_id_t grantid; int r, n; pid_t target; message m; size = m_in.GCOV_BUFF_SZ; target = m_in.GCOV_PID; /* If the wrong process is sent to, the system hangs; so make this root-only. */ if (!super_user) return(EPERM); /* Find target gcov process. */ for(n = 0; n < NR_PROCS; n++) { if(fproc[n].fp_endpoint != NONE && fproc[n].fp_pid == target) break; } if(n >= NR_PROCS) { printf("VFS: gcov process %d not found\n", target); return(ESRCH); } rfp = &fproc[n]; /* Grant target process to requestor's buffer. */ if ((grantid = cpf_grant_magic(rfp->fp_endpoint, who_e, (vir_bytes) m_in.GCOV_BUFF_P, size, CPF_WRITE)) < 0) { printf("VFS: gcov_flush: grant failed\n"); return(ENOMEM); } if(rfp->fp_endpoint == VFS_PROC_NR) { /* Request is for VFS itself. */ r = gcov_flush(grantid, size); } else { /* Perform generic GCOV request. */ m.GCOV_GRANT = grantid; m.GCOV_BUFF_SZ = size; r = _taskcall(rfp->fp_endpoint, COMMON_REQ_GCOV_DATA, &m); } cpf_revoke(grantid); return(r); }
/*===========================================================================* * fbd_transfer_direct * *===========================================================================*/ static ssize_t fbd_transfer_direct(int do_write, u64_t position, endpoint_t endpt, iovec_t *iov, unsigned int count, int flags) { /* Forward the entire transfer request, without any intervention. */ iovec_s_t iovec[NR_IOREQS]; cp_grant_id_t grant; message m; int i, r; for (i = 0; i < count; i++) { iovec[i].iov_size = iov[i].iov_size; iovec[i].iov_grant = cpf_grant_indirect(driver_endpt, endpt, iov[i].iov_addr); assert(iovec[i].iov_grant != GRANT_INVALID); } grant = cpf_grant_direct(driver_endpt, (vir_bytes) iovec, count * sizeof(iovec[0]), CPF_READ); assert(grant != GRANT_INVALID); m.m_type = do_write ? BDEV_SCATTER : BDEV_GATHER; m.BDEV_MINOR = driver_minor; m.BDEV_COUNT = count; m.BDEV_GRANT = grant; m.BDEV_FLAGS = flags; m.BDEV_ID = 0; m.BDEV_POS_LO = ex64lo(position); m.BDEV_POS_HI = ex64hi(position); if ((r = sendrec(driver_endpt, &m)) != OK) panic("sendrec to driver failed (%d)\n", r); if (m.m_type != BDEV_REPLY) panic("invalid reply from driver (%d)\n", m.m_type); cpf_revoke(grant); for (i = 0; i < count; i++) cpf_revoke(iovec[i].iov_grant); return m.BDEV_STATUS; }
/*===========================================================================* * fbd_transfer_direct * *===========================================================================*/ static ssize_t fbd_transfer_direct(int do_write, u64_t position, endpoint_t endpt, iovec_t *iov, unsigned int count, int flags) { /* Forward the entire transfer request, without any intervention. */ iovec_s_t iovec[NR_IOREQS]; cp_grant_id_t grant; message m; int i, r; for (i = 0; i < count; i++) { iovec[i].iov_size = iov[i].iov_size; iovec[i].iov_grant = cpf_grant_indirect(driver_endpt, endpt, iov[i].iov_addr); assert(iovec[i].iov_grant != GRANT_INVALID); } grant = cpf_grant_direct(driver_endpt, (vir_bytes) iovec, count * sizeof(iovec[0]), CPF_READ); assert(grant != GRANT_INVALID); m.m_type = do_write ? BDEV_SCATTER : BDEV_GATHER; m.m_lbdev_lblockdriver_msg.minor = driver_minor; m.m_lbdev_lblockdriver_msg.count = count; m.m_lbdev_lblockdriver_msg.grant = grant; m.m_lbdev_lblockdriver_msg.flags = flags; m.m_lbdev_lblockdriver_msg.id = 0; m.m_lbdev_lblockdriver_msg.pos = position; if ((r = ipc_sendrec(driver_endpt, &m)) != OK) panic("ipc_sendrec to driver failed (%d)\n", r); if (m.m_type != BDEV_REPLY) panic("invalid reply from driver (%d)\n", m.m_type); cpf_revoke(grant); for (i = 0; i < count; i++) cpf_revoke(iovec[i].iov_grant); return m.m_lblockdriver_lbdev_reply.status; }
/*===========================================================================* * req_create * *===========================================================================*/ PUBLIC int req_create( int fs_e, ino_t inode_nr, int omode, uid_t uid, gid_t gid, char *path, node_details_t *res ) { int r; cp_grant_id_t grant_id; size_t len; message m; if (path[0] == '/') panic("req_create: filename starts with '/'"); len = strlen(path) + 1; grant_id = cpf_grant_direct(fs_e, (vir_bytes) path, len, CPF_READ); if (grant_id == -1) panic("req_create: cpf_grant_direct failed"); /* Fill in request message */ m.m_type = REQ_CREATE; m.REQ_INODE_NR = inode_nr; m.REQ_MODE = omode; m.REQ_UID = uid; m.REQ_GID = gid; m.REQ_GRANT = grant_id; m.REQ_PATH_LEN = len; /* Send/rec request */ r = fs_sendrec(fs_e, &m); cpf_revoke(grant_id); if (r != OK) return(r); /* Fill in response structure */ res->fs_e = m.m_source; res->inode_nr = m.RES_INODE_NR; res->fmode = m.RES_MODE; res->fsize = m.RES_FILE_SIZE_LO; res->uid = m.RES_UID; res->gid = m.RES_GID; res->dev = m.RES_DEV; return(OK); }
int ds_retrieve_map(const char *ds_name, char *vaddr, size_t *length, int nr_snapshot, int flags) { cp_grant_id_t gid; int r; /* Map a mapped memory range. */ if(flags & DSMF_MAP_MAPPED) { /* Request DS to grant. */ m.DS_FLAGS = DSF_TYPE_MAP | DSMF_MAP_MAPPED; r = do_invoke_ds(DS_RETRIEVE, ds_name); if(r != OK) return r; /* Do the safemap. */ if(*length > (size_t) m.DS_VAL_LEN) *length = (size_t) m.DS_VAL_LEN; *length = (size_t) CLICK_FLOOR(*length); r = sys_safemap(DS_PROC_NR, m.DS_VAL, 0, (vir_bytes)vaddr, *length, D, 0); /* Copy mapped memory range or a snapshot. */ } else if(flags & (DSMF_COPY_MAPPED|DSMF_COPY_SNAPSHOT)) { /* Grant for memory range first. */ gid = cpf_grant_direct(DS_PROC_NR, (vir_bytes)vaddr, *length, CPF_WRITE); if(!GRANT_VALID(gid)) return errno; m.DS_VAL = gid; m.DS_VAL_LEN = *length; if(flags & DSMF_COPY_MAPPED) { m.DS_FLAGS = DSF_TYPE_MAP | DSMF_COPY_MAPPED; } else { m.DS_NR_SNAPSHOT = nr_snapshot; m.DS_FLAGS = DSF_TYPE_MAP | DSMF_COPY_SNAPSHOT; } r = do_invoke_ds(DS_RETRIEVE, ds_name); *length = m.DS_VAL_LEN; cpf_revoke(gid); } else { return EINVAL; } return r; }
/*===========================================================================* * pci_dev_name * *===========================================================================*/ PUBLIC char *pci_dev_name(u16_t vid, u16_t did) { static char name[PCIINFO_ENTRY_SIZE]; /* We need a better interface for this */ int r; cp_grant_id_t gid; message m; gid= cpf_grant_direct(pci_procnr, (vir_bytes)name, sizeof(name), CPF_WRITE); if (gid == -1) { printf("pci_dev_name: cpf_grant_direct failed: %d\n", errno); return NULL; } m.m_type= BUSC_PCI_DEV_NAME_S; m.m7_i1= vid; m.m7_i2= did; m.m7_i3= sizeof(name); m.m7_i4= gid; r= sendrec(pci_procnr, &m); cpf_revoke(gid); if (r != 0) panic("pci_dev_name: can't talk to PCI: %d", r); if (m.m_type == ENOENT) { #if DEBUG printf("pci_dev_name: got no name\n"); #endif return NULL; /* No name for this device */ } if (m.m_type != 0) panic("pci_dev_name: got bad reply from PCI: %d", m.m_type); name[sizeof(name)-1]= '\0'; /* Make sure that the string is NUL * terminated. */ #if DEBUG printf("pci_dev_name: got name %s\n", name); #endif return name; }
/*===========================================================================* * bdev_ioctl * *===========================================================================*/ static int bdev_ioctl(dev_t dev, endpoint_t proc_e, int req, void *buf) { /* Perform an I/O control operation on a block device. */ struct dmap *dp; u32_t dummy; cp_grant_id_t gid; message dev_mess; int op, major_dev, minor_dev; major_dev = major(dev); minor_dev = minor(dev); /* Determine task dmap. */ dp = &dmap[major_dev]; if (dp->dmap_driver == NONE) { printf("VFS: dev_io: no driver for major %d\n", major_dev); return(ENXIO); } /* Set up a grant if necessary. */ op = VFS_DEV_IOCTL; (void) safe_io_conversion(dp->dmap_driver, &gid, &op, &proc_e, &buf, req, &dummy); /* Set up the message passed to the task. */ memset(&dev_mess, 0, sizeof(dev_mess)); dev_mess.m_type = BDEV_IOCTL; dev_mess.BDEV_MINOR = minor_dev; dev_mess.BDEV_REQUEST = req; dev_mess.BDEV_GRANT = gid; dev_mess.BDEV_ID = 0; /* Call the task. */ (*dp->dmap_io)(dp->dmap_driver, &dev_mess); /* Clean up. */ if (GRANT_VALID(gid)) cpf_revoke(gid); if (dp->dmap_driver == NONE) { printf("VFS: block driver gone!?\n"); return(EIO); } /* Return the result. */ return(dev_mess.BDEV_STATUS); }
int ds_publish_mem(const char *ds_name, void *vaddr, size_t length, int flags) { cp_grant_id_t gid; int r; /* Grant for memory range. */ gid = cpf_grant_direct(DS_PROC_NR, (vir_bytes)vaddr, length, CPF_READ); if(!GRANT_VALID(gid)) return errno; m.DS_VAL = gid; m.DS_VAL_LEN = length; m.DS_FLAGS = DSF_TYPE_MEM | flags; r = do_invoke_ds(DS_PUBLISH, ds_name); cpf_revoke(gid); return r; }
int ds_retrieve_mem(const char *ds_name, char *vaddr, size_t *length) { cp_grant_id_t gid; int r; /* Grant for memory range. */ gid = cpf_grant_direct(DS_PROC_NR, (vir_bytes)vaddr, *length, CPF_WRITE); if(!GRANT_VALID(gid)) return errno; m.DS_VAL = gid; m.DS_VAL_LEN = *length; m.DS_FLAGS = DSF_TYPE_MEM; r = do_invoke_ds(DS_RETRIEVE, ds_name); *length = m.DS_VAL_LEN; cpf_revoke(gid); return r; }
/*===========================================================================* * req_getdents * *===========================================================================*/ PUBLIC int req_getdents( endpoint_t fs_e, ino_t inode_nr, u64_t pos, char *buf, size_t size, u64_t *new_pos, int direct ) { int r; message m; cp_grant_id_t grant_id; if (direct) { grant_id = cpf_grant_direct(fs_e, (vir_bytes) buf, size, CPF_WRITE); } else { grant_id = cpf_grant_magic(fs_e, who_e, (vir_bytes) buf, size, CPF_WRITE); } if (grant_id < 0) panic("req_getdents: cpf_grant_direct/cpf_grant_magic failed: %d", grant_id); m.m_type = REQ_GETDENTS; m.REQ_INODE_NR = inode_nr; m.REQ_GRANT = grant_id; m.REQ_MEM_SIZE = size; m.REQ_SEEK_POS_LO = ex64lo(pos); m.REQ_SEEK_POS_HI = 0; /* Not used for now, so clear it. */ r = fs_sendrec(fs_e, &m); cpf_revoke(grant_id); if (r == OK) { *new_pos = cvul64(m.RES_SEEK_POS_LO); r = m.RES_NBYTES; } return(r); }
/*===========================================================================* * req_statvfs * *===========================================================================*/ int req_statvfs(endpoint_t fs_e, endpoint_t proc_e, vir_bytes buf) { int r; cp_grant_id_t grant_id; message m; grant_id = cpf_grant_magic(fs_e, proc_e, buf, sizeof(struct statvfs), CPF_WRITE); if(grant_id == GRANT_INVALID) panic("req_statvfs: cpf_grant_magic failed"); /* Fill in request message */ m.m_type = REQ_STATVFS; m.REQ_GRANT = grant_id; /* Send/rec request */ r = fs_sendrec(fs_e, &m); cpf_revoke(grant_id); return(r); }
/*===========================================================================* * req_statvfs * *===========================================================================*/ PUBLIC int req_statvfs(int fs_e, int who_e, char *buf) { int r; cp_grant_id_t grant_id; message m; grant_id = cpf_grant_magic(fs_e, who_e, (vir_bytes) buf, sizeof(struct statvfs), CPF_WRITE); if(grant_id == -1) panic("req_statvfs: cpf_grant_magic failed"); /* Fill in request message */ m.m_type = REQ_STATVFS; m.REQ_GRANT = grant_id; /* Send/rec request */ r = fs_sendrec(fs_e, &m); cpf_revoke(grant_id); return(r); }
/*===========================================================================* * req_breadwrite * *===========================================================================*/ PUBLIC int req_breadwrite( endpoint_t fs_e, endpoint_t user_e, dev_t dev, u64_t pos, unsigned int num_of_bytes, char *user_addr, int rw_flag, u64_t *new_posp, unsigned int *cum_iop ) { int r; cp_grant_id_t grant_id; message m; grant_id = cpf_grant_magic(fs_e, user_e, (vir_bytes) user_addr, num_of_bytes, (rw_flag == READING ? CPF_WRITE : CPF_READ)); if(grant_id == -1) panic("req_breadwrite: cpf_grant_magic failed"); /* Fill in request message */ m.m_type = rw_flag == READING ? REQ_BREAD : REQ_BWRITE; m.REQ_DEV2 = dev; m.REQ_GRANT = grant_id; m.REQ_SEEK_POS_LO = ex64lo(pos); m.REQ_SEEK_POS_HI = ex64hi(pos); m.REQ_NBYTES = num_of_bytes; /* Send/rec request */ r = fs_sendrec(fs_e, &m); cpf_revoke(grant_id); if (r != OK) return(r); /* Fill in response structure */ *new_posp = make64(m.RES_SEEK_POS_LO, m.RES_SEEK_POS_HI); *cum_iop = m.RES_NBYTES; return(OK); }
int checkperms(endpoint_t endpt, char *path, size_t size) { cp_grant_id_t grant; message m; int r; if ((grant = cpf_grant_direct(VFS_PROC_NR, (vir_bytes) path, size, CPF_READ | CPF_WRITE)) == GRANT_INVALID) return ENOMEM; memset(&m, 0, sizeof(m)); m.m_lsys_vfs_checkperms.endpt = endpt; m.m_lsys_vfs_checkperms.grant = grant; m.m_lsys_vfs_checkperms.count = size; r = _taskcall(VFS_PROC_NR, VFS_CHECKPERMS, &m); cpf_revoke(grant); return r; }
cp_grant_id_t cpf_grant_direct(endpoint_t who_to, vir_bytes addr, size_t bytes, int access) { cp_grant_id_t g; int r; /* Get new slot to put new grant in. */ if((g = cpf_new_grantslot()) < 0) return(GRANT_INVALID); assert(GRANT_VALID(g)); assert(g >= 0); assert(g < ngrants); assert(!(grants[g].cp_flags & CPF_USED)); if((r=cpf_setgrant_direct(g, who_to, addr, bytes, access)) < 0) { cpf_revoke(g); return(GRANT_INVALID); } return g; }
/*===========================================================================* * fbd_ioctl * *===========================================================================*/ static int fbd_ioctl(devminor_t UNUSED(minor), unsigned long request, endpoint_t endpt, cp_grant_id_t grant, endpoint_t UNUSED(user_endpt)) { /* Handle an I/O control request. */ cp_grant_id_t gid; message m; int r; /* We only handle the FBD requests, and pass on everything else. */ switch (request) { case FBDCADDRULE: case FBDCDELRULE: case FBDCGETRULE: return rule_ctl(request, endpt, grant); } assert(grant != GRANT_INVALID); gid = cpf_grant_indirect(driver_endpt, endpt, grant); assert(gid != GRANT_INVALID); memset(&m, 0, sizeof(m)); m.m_type = BDEV_IOCTL; m.m_lbdev_lblockdriver_msg.minor = driver_minor; m.m_lbdev_lblockdriver_msg.request = request; m.m_lbdev_lblockdriver_msg.grant = gid; m.m_lbdev_lblockdriver_msg.user = NONE; m.m_lbdev_lblockdriver_msg.id = 0; if ((r = ipc_sendrec(driver_endpt, &m)) != OK) panic("ipc_sendrec to driver failed (%d)\n", r); if (m.m_type != BDEV_REPLY) panic("invalid reply from driver (%d)\n", m.m_type); cpf_revoke(gid); return m.m_lblockdriver_lbdev_reply.status; }
/*===========================================================================* * fbd_ioctl * *===========================================================================*/ static int fbd_ioctl(dev_t UNUSED(minor), unsigned int request, endpoint_t endpt, cp_grant_id_t grant) { /* Handle an I/O control request. */ cp_grant_id_t gid; message m; int r; /* We only handle the FBD requests, and pass on everything else. */ switch (request) { case FBDCADDRULE: case FBDCDELRULE: case FBDCGETRULE: return rule_ctl(request, endpt, grant); } assert(grant != GRANT_INVALID); gid = cpf_grant_indirect(driver_endpt, endpt, grant); assert(gid != GRANT_INVALID); memset(&m, 0, sizeof(m)); m.m_type = BDEV_IOCTL; m.BDEV_MINOR = driver_minor; m.BDEV_REQUEST = request; m.BDEV_GRANT = gid; m.BDEV_ID = 0; if ((r = sendrec(driver_endpt, &m)) != OK) panic("sendrec to driver failed (%d)\n", r); if (m.m_type != BDEV_REPLY) panic("invalid reply from driver (%d)\n", m.m_type); cpf_revoke(gid); return m.BDEV_STATUS; }
int ds_publish_map(const char *ds_name, void *vaddr, size_t length, int flags) { cp_grant_id_t gid; int r; if(((vir_bytes)vaddr % CLICK_SIZE != 0) || (length % CLICK_SIZE != 0)) return EINVAL; /* Grant for mapped memory range. */ gid = cpf_grant_direct(DS_PROC_NR, (vir_bytes)vaddr, length, CPF_READ | CPF_MAP); if(!GRANT_VALID(gid)) return errno; m.DS_VAL = gid; m.DS_VAL_LEN = length; m.DS_FLAGS = DSF_TYPE_MAP | flags; r = do_invoke_ds(DS_PUBLISH, ds_name); cpf_revoke(gid); return r; }