static int nvmf_direct_ctrlr_process_io_cmd(struct spdk_nvmf_request *req) { struct spdk_nvmf_subsystem *subsystem = req->conn->sess->subsys; int rc; rc = spdk_nvme_ctrlr_cmd_io_raw(subsystem->dev.direct.ctrlr, subsystem->dev.direct.io_qpair, &req->cmd->nvme_cmd, req->data, req->length, nvmf_direct_ctrlr_complete_cmd, req); if (rc) { SPDK_ERRLOG("Failed to submit request %p\n", req); req->rsp->nvme_cpl.status.sc = SPDK_NVME_SC_INTERNAL_DEVICE_ERROR; return SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE; } return SPDK_NVMF_REQUEST_EXEC_STATUS_ASYNCHRONOUS; }
static bool nvmf_process_io_cmd(struct spdk_nvmf_request *req) { struct nvmf_session *session = req->conn->sess; struct spdk_nvme_cmd *cmd = &req->cmd->nvme_cmd; struct spdk_nvme_cpl *response; struct spdk_nvmf_subsystem *subsystem = session->subsys; struct spdk_nvmf_namespace *nvmf_ns; struct spdk_nvme_ctrlr *ctrlr = NULL; struct spdk_nvme_ns *ns = NULL; struct spdk_nvme_qpair *qpair; uint32_t nsid = 0; struct nvme_read_cdw12 *cdw12; uint64_t lba_address; uint32_t lba_count; uint32_t io_flags; int rc = 0; /* pre-set response details for this command */ response = &req->rsp->nvme_cpl; response->status.sc = SPDK_NVME_SC_SUCCESS; response->cid = cmd->cid; /* verify subsystem */ if (subsystem == NULL) { SPDK_ERRLOG("Subsystem Not Initialized!\n"); response->status.sc = SPDK_NVME_SC_INTERNAL_DEVICE_ERROR; return true; } /* verify that the contoller is ready to process commands */ if (session->vcprop.csts.bits.rdy == 0) { SPDK_ERRLOG("Subsystem Controller Not Ready!\n"); response->status.sc = SPDK_NVME_SC_NAMESPACE_NOT_READY; return true; } /* verify namespace id */ if (cmd->nsid == 0 || cmd->nsid > MAX_PER_SUBSYSTEM_NAMESPACES) { SPDK_ERRLOG("Invalid NS_ID %u\n", cmd->nsid); response->status.sc = SPDK_NVME_SC_INVALID_NAMESPACE_OR_FORMAT; return true; } nvmf_ns = &subsystem->ns_list_map[cmd->nsid - 1]; ctrlr = nvmf_ns->ctrlr; nsid = nvmf_ns->nvme_ns_id; ns = nvmf_ns->ns; qpair = nvmf_ns->qpair; switch (cmd->opc) { case SPDK_NVME_OPC_READ: case SPDK_NVME_OPC_WRITE: cdw12 = (struct nvme_read_cdw12 *)&cmd->cdw12; /* NVMe library read/write interface expects non-0based lba_count value */ lba_count = cdw12->nlb + 1; lba_address = cmd->cdw11; lba_address = (lba_address << 32) + cmd->cdw10; io_flags = cmd->cdw12 & 0xFFFF0000U; if (cmd->opc == SPDK_NVME_OPC_READ) { SPDK_TRACELOG(SPDK_TRACE_NVMF, "Read LBA 0x%" PRIx64 ", 0x%x blocks\n", lba_address, lba_count); spdk_trace_record(TRACE_NVMF_LIB_READ_START, 0, 0, (uint64_t)req, 0); rc = spdk_nvme_ns_cmd_read(ns, qpair, req->data, lba_address, lba_count, nvmf_complete_cmd, req, io_flags); } else { SPDK_TRACELOG(SPDK_TRACE_NVMF, "Write LBA 0x%" PRIx64 ", 0x%x blocks\n", lba_address, lba_count); spdk_trace_record(TRACE_NVMF_LIB_WRITE_START, 0, 0, (uint64_t)req, 0); rc = spdk_nvme_ns_cmd_write(ns, qpair, req->data, lba_address, lba_count, nvmf_complete_cmd, req, io_flags); } break; default: SPDK_TRACELOG(SPDK_TRACE_NVMF, "io_cmd passthrough: opc 0x%02x\n", cmd->opc); cmd->nsid = nsid; rc = spdk_nvme_ctrlr_cmd_io_raw(ctrlr, qpair, cmd, req->data, req->length, nvmf_complete_cmd, req); break; } if (rc) { SPDK_ERRLOG("Failed to submit Opcode 0x%02x\n", cmd->opc); response->status.sc = SPDK_NVME_SC_INTERNAL_DEVICE_ERROR; return true; } return false; }