/*===========================================================================* * 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; }
/*===========================================================================* * 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; }