int nvme_ns_cmd_read_bio(struct nvme_namespace *ns, struct bio *bp, nvme_cb_fn_t cb_fn, void *cb_arg) { struct nvme_request *req; struct nvme_command *cmd; uint64_t lba; uint64_t lba_count; req = nvme_allocate_request_bio(bp, cb_fn, cb_arg); if (req == NULL) return (ENOMEM); cmd = &req->cmd; cmd->opc = NVME_OPC_READ; cmd->nsid = ns->id; lba = bp->bio_offset / nvme_ns_get_sector_size(ns); lba_count = bp->bio_bcount / nvme_ns_get_sector_size(ns); /* TODO: create a read command data structure */ *(uint64_t *)&cmd->cdw10 = lba; cmd->cdw12 = lba_count-1; nvme_ctrlr_submit_io_request(ns->ctrlr, req); return (0); }
static void nvme_sim_nvmeio(struct cam_sim *sim, union ccb *ccb) { struct ccb_nvmeio *nvmeio = &ccb->nvmeio; struct nvme_request *req; void *payload; uint32_t size; struct nvme_controller *ctrlr; ctrlr = sim2ctrlr(sim); payload = nvmeio->data_ptr; size = nvmeio->dxfer_len; /* SG LIST ??? */ if ((nvmeio->ccb_h.flags & CAM_DATA_MASK) == CAM_DATA_BIO) req = nvme_allocate_request_bio((struct bio *)payload, nvme_sim_nvmeio_done, ccb); else if (payload == NULL) req = nvme_allocate_request_null(nvme_sim_nvmeio_done, ccb); else req = nvme_allocate_request_vaddr(payload, size, nvme_sim_nvmeio_done, ccb); if (req == NULL) { nvmeio->ccb_h.status = CAM_RESRC_UNAVAIL; xpt_done(ccb); return; } memcpy(&req->cmd, &ccb->nvmeio.cmd, sizeof(ccb->nvmeio.cmd)); nvme_ctrlr_submit_io_request(ctrlr, req); ccb->ccb_h.status |= CAM_SIM_QUEUED; }