Make NVMe compatible with the original API
The original NVMe API used bit-fields to represent fields in data structures defined by the specification (e.g. the op-code in the command data structure). The implementation targeted x86_64 processors and defined the bit fields for little endian dwords (i.e. 32 bits). This approach does not work as-is for big endian architectures and was changed to use a combination of bit shifts and masks to support PowerPC. Unfortunately, this changed the NVMe API and forces #ifdef's based on the OS revision level in user space code. This change reverts to something that looks like the original API, but it uses bytes instead of bit-fields inside the packed command structure. As a bonus, this works as-is for both big and little endian CPU architectures. Bump __FreeBSD_version to 1200081 due to API change Reviewed by: imp, kbowling, smh, mav Approved by: imp (mentor) Differential Revision: https://reviews.freebsd.org/D16404
This commit is contained in:
parent
47fa74161c
commit
fa895cb8d2
@ -125,7 +125,7 @@ update_firmware(int fd, uint8_t *payload, int32_t payload_size)
|
||||
memcpy(chunk, payload + off, size);
|
||||
|
||||
memset(&pt, 0, sizeof(pt));
|
||||
pt.cmd.opc_fuse = NVME_CMD_SET_OPC(NVME_OPC_FIRMWARE_IMAGE_DOWNLOAD);
|
||||
pt.cmd.opc = NVME_OPC_FIRMWARE_IMAGE_DOWNLOAD;
|
||||
pt.cmd.cdw10 = htole32((size / sizeof(uint32_t)) - 1);
|
||||
pt.cmd.cdw11 = htole32(off / sizeof(uint32_t));
|
||||
pt.buf = chunk;
|
||||
@ -150,7 +150,7 @@ activate_firmware(int fd, int slot, int activate_action)
|
||||
uint16_t sct, sc;
|
||||
|
||||
memset(&pt, 0, sizeof(pt));
|
||||
pt.cmd.opc_fuse = NVME_CMD_SET_OPC(NVME_OPC_FIRMWARE_ACTIVATE);
|
||||
pt.cmd.opc = NVME_OPC_FIRMWARE_ACTIVATE;
|
||||
pt.cmd.cdw10 = htole32((activate_action << 3) | slot);
|
||||
pt.is_read = 0;
|
||||
|
||||
|
@ -172,7 +172,7 @@ format(int argc, char *argv[])
|
||||
}
|
||||
|
||||
memset(&pt, 0, sizeof(pt));
|
||||
pt.cmd.opc_fuse = NVME_CMD_SET_OPC(NVME_OPC_FORMAT_NVM);
|
||||
pt.cmd.opc = NVME_OPC_FORMAT_NVM;
|
||||
pt.cmd.nsid = htole32(nsid);
|
||||
pt.cmd.cdw10 = htole32((ses << 9) + (pil << 8) + (pi << 5) +
|
||||
(mset << 4) + lbaf);
|
||||
|
@ -107,7 +107,7 @@ read_logpage(int fd, uint8_t log_page, uint32_t nsid, void *payload,
|
||||
int i, err_pages;
|
||||
|
||||
memset(&pt, 0, sizeof(pt));
|
||||
pt.cmd.opc_fuse = NVME_CMD_SET_OPC(NVME_OPC_GET_LOG_PAGE);
|
||||
pt.cmd.opc = NVME_OPC_GET_LOG_PAGE;
|
||||
pt.cmd.nsid = htole32(nsid);
|
||||
pt.cmd.cdw10 = ((payload_size/sizeof(uint32_t)) - 1) << 16;
|
||||
pt.cmd.cdw10 |= log_page;
|
||||
|
@ -216,7 +216,7 @@ nscreate(int argc, char *argv[])
|
||||
nvme_namespace_data_swapbytes(&nsdata);
|
||||
|
||||
memset(&pt, 0, sizeof(pt));
|
||||
pt.cmd.opc_fuse = NVME_CMD_SET_OPC(NVME_OPC_NAMESPACE_MANAGEMENT);
|
||||
pt.cmd.opc = NVME_OPC_NAMESPACE_MANAGEMENT;
|
||||
|
||||
pt.cmd.cdw10 = 0; /* create */
|
||||
pt.buf = &nsdata;
|
||||
@ -267,7 +267,7 @@ nsdelete(int argc, char *argv[])
|
||||
errx(1, "controller does not support namespace management");
|
||||
|
||||
memset(&pt, 0, sizeof(pt));
|
||||
pt.cmd.opc_fuse = NVME_CMD_SET_OPC(NVME_OPC_NAMESPACE_MANAGEMENT);
|
||||
pt.cmd.opc = NVME_OPC_NAMESPACE_MANAGEMENT;
|
||||
pt.cmd.cdw10 = 1; /* delete */
|
||||
pt.buf = buf;
|
||||
pt.len = sizeof(buf);
|
||||
@ -343,7 +343,7 @@ nsattach(int argc, char *argv[])
|
||||
if (ctrlrid == -1) {
|
||||
/* Get full list of controllers to attach to. */
|
||||
memset(&pt, 0, sizeof(pt));
|
||||
pt.cmd.opc_fuse = NVME_CMD_SET_OPC(NVME_OPC_IDENTIFY);
|
||||
pt.cmd.opc = NVME_OPC_IDENTIFY;
|
||||
pt.cmd.cdw10 = htole32(0x13);
|
||||
pt.buf = clist;
|
||||
pt.len = sizeof(clist);
|
||||
@ -362,7 +362,7 @@ nsattach(int argc, char *argv[])
|
||||
}
|
||||
|
||||
memset(&pt, 0, sizeof(pt));
|
||||
pt.cmd.opc_fuse = NVME_CMD_SET_OPC(NVME_OPC_NAMESPACE_ATTACHMENT);
|
||||
pt.cmd.opc = NVME_OPC_NAMESPACE_ATTACHMENT;
|
||||
pt.cmd.cdw10 = 0; /* attach */
|
||||
pt.cmd.nsid = (uint32_t)nsid;
|
||||
pt.buf = &clist;
|
||||
@ -422,7 +422,7 @@ nsdetach(int argc, char *argv[])
|
||||
if (ctrlrid == -1) {
|
||||
/* Get list of controllers this namespace attached to. */
|
||||
memset(&pt, 0, sizeof(pt));
|
||||
pt.cmd.opc_fuse = NVME_CMD_SET_OPC(NVME_OPC_IDENTIFY);
|
||||
pt.cmd.opc = NVME_OPC_IDENTIFY;
|
||||
pt.cmd.nsid = htole32(nsid);
|
||||
pt.cmd.cdw10 = htole32(0x12);
|
||||
pt.buf = clist;
|
||||
@ -448,7 +448,7 @@ nsdetach(int argc, char *argv[])
|
||||
}
|
||||
|
||||
memset(&pt, 0, sizeof(pt));
|
||||
pt.cmd.opc_fuse = NVME_CMD_SET_OPC(NVME_OPC_NAMESPACE_ATTACHMENT);
|
||||
pt.cmd.opc = NVME_OPC_NAMESPACE_ATTACHMENT;
|
||||
pt.cmd.cdw10 = 1; /* detach */
|
||||
pt.cmd.nsid = (uint32_t)nsid;
|
||||
pt.buf = &clist;
|
||||
|
@ -148,7 +148,7 @@ read_controller_data(int fd, struct nvme_controller_data *cdata)
|
||||
struct nvme_pt_command pt;
|
||||
|
||||
memset(&pt, 0, sizeof(pt));
|
||||
pt.cmd.opc_fuse = NVME_CMD_SET_OPC(NVME_OPC_IDENTIFY);
|
||||
pt.cmd.opc = NVME_OPC_IDENTIFY;
|
||||
pt.cmd.cdw10 = htole32(1);
|
||||
pt.buf = cdata;
|
||||
pt.len = sizeof(*cdata);
|
||||
@ -170,7 +170,7 @@ read_namespace_data(int fd, uint32_t nsid, struct nvme_namespace_data *nsdata)
|
||||
struct nvme_pt_command pt;
|
||||
|
||||
memset(&pt, 0, sizeof(pt));
|
||||
pt.cmd.opc_fuse = NVME_CMD_SET_OPC(NVME_OPC_IDENTIFY);
|
||||
pt.cmd.opc = NVME_OPC_IDENTIFY;
|
||||
pt.cmd.nsid = htole32(nsid);
|
||||
pt.buf = nsdata;
|
||||
pt.len = sizeof(*nsdata);
|
||||
|
@ -104,7 +104,7 @@ power_set(int fd, int power_val, int workload, int perm)
|
||||
|
||||
p = perm ? (1u << 31) : 0;
|
||||
memset(&pt, 0, sizeof(pt));
|
||||
pt.cmd.opc_fuse = NVME_CMD_SET_OPC(NVME_OPC_SET_FEATURES);
|
||||
pt.cmd.opc = NVME_OPC_SET_FEATURES;
|
||||
pt.cmd.cdw10 = htole32(NVME_FEAT_POWER_MANAGEMENT | p);
|
||||
pt.cmd.cdw11 = htole32(power_val | (workload << 5));
|
||||
|
||||
@ -121,7 +121,7 @@ power_show(int fd)
|
||||
struct nvme_pt_command pt;
|
||||
|
||||
memset(&pt, 0, sizeof(pt));
|
||||
pt.cmd.opc_fuse = NVME_CMD_SET_OPC(NVME_OPC_GET_FEATURES);
|
||||
pt.cmd.opc = NVME_OPC_GET_FEATURES;
|
||||
pt.cmd.cdw10 = htole32(NVME_FEAT_POWER_MANAGEMENT);
|
||||
|
||||
if (ioctl(fd, NVME_PASSTHROUGH_CMD, &pt) < 0)
|
||||
|
@ -81,7 +81,7 @@ wdc_get_data(int fd, uint32_t opcode, uint32_t len, uint32_t off, uint32_t cmd,
|
||||
struct nvme_pt_command pt;
|
||||
|
||||
memset(&pt, 0, sizeof(pt));
|
||||
pt.cmd.opc_fuse = NVME_CMD_SET_OPC(opcode);
|
||||
pt.cmd.opc = opcode;
|
||||
pt.cmd.cdw10 = htole32(len / sizeof(uint32_t)); /* - 1 like all the others ??? */
|
||||
pt.cmd.cdw11 = htole32(off / sizeof(uint32_t));
|
||||
pt.cmd.cdw12 = htole32(cmd);
|
||||
|
@ -69,7 +69,7 @@ nvme_ns_cmd(struct ccb_nvmeio *nvmeio, uint8_t cmd, uint32_t nsid,
|
||||
uint32_t cdw14, uint32_t cdw15)
|
||||
{
|
||||
bzero(&nvmeio->cmd, sizeof(struct nvme_command));
|
||||
nvmeio->cmd.opc_fuse = NVME_CMD_SET_OPC(cmd);
|
||||
nvmeio->cmd.opc = cmd;
|
||||
nvmeio->cmd.nsid = htole32(nsid);
|
||||
nvmeio->cmd.cdw10 = htole32(cdw10);
|
||||
nvmeio->cmd.cdw11 = htole32(cdw11);
|
||||
@ -117,29 +117,24 @@ nvme_opc2str[] = {
|
||||
const char *
|
||||
nvme_op_string(const struct nvme_command *cmd)
|
||||
{
|
||||
uint8_t opc;
|
||||
|
||||
opc = (cmd->opc_fuse >> NVME_CMD_OPC_SHIFT) & NVME_CMD_OPC_MASK;
|
||||
if (opc >= nitems(nvme_opc2str))
|
||||
if (cmd->opc >= nitems(nvme_opc2str))
|
||||
return "UNKNOWN";
|
||||
|
||||
return nvme_opc2str[opc];
|
||||
return nvme_opc2str[cmd->opc];
|
||||
}
|
||||
|
||||
const char *
|
||||
nvme_cmd_string(const struct nvme_command *cmd, char *cmd_string, size_t len)
|
||||
{
|
||||
uint8_t opc, fuse;
|
||||
|
||||
opc = (cmd->opc_fuse >> NVME_CMD_OPC_SHIFT) & NVME_CMD_OPC_MASK;
|
||||
fuse = (cmd->opc_fuse >> NVME_CMD_FUSE_SHIFT) & NVME_CMD_FUSE_MASK;
|
||||
/*
|
||||
* cid, rsvd areas and mptr not printed, since they are used
|
||||
* only internally by the SIM.
|
||||
*/
|
||||
snprintf(cmd_string, len,
|
||||
"opc=%x fuse=%x nsid=%x prp1=%llx prp2=%llx cdw=%x %x %x %x %x %x",
|
||||
opc, fuse, cmd->nsid,
|
||||
cmd->opc, cmd->fuse, cmd->nsid,
|
||||
(unsigned long long)cmd->prp1, (unsigned long long)cmd->prp2,
|
||||
cmd->cdw10, cmd->cdw11, cmd->cdw12,
|
||||
cmd->cdw13, cmd->cdw14, cmd->cdw15);
|
||||
|
@ -1840,7 +1840,7 @@ mprsas_build_nvme_unmap(struct mpr_softc *sc, struct mpr_command *cm,
|
||||
|
||||
/* Build NVMe DSM command */
|
||||
c = (struct nvme_command *) req->NVMe_Command;
|
||||
c->opc_fuse = NVME_CMD_SET_OPC(NVME_OPC_DATASET_MANAGEMENT);
|
||||
c->opc = NVME_OPC_DATASET_MANAGEMENT;
|
||||
c->nsid = htole32(csio->ccb_h.target_lun + 1);
|
||||
c->cdw10 = htole32(ndesc - 1);
|
||||
c->cdw11 = htole32(NVME_DSM_ATTR_DEALLOCATE);
|
||||
|
@ -222,14 +222,10 @@ nvme_modevent(module_t mod, int type, void *arg)
|
||||
void
|
||||
nvme_dump_command(struct nvme_command *cmd)
|
||||
{
|
||||
uint8_t opc, fuse;
|
||||
|
||||
opc = (cmd->opc_fuse >> NVME_CMD_OPC_SHIFT) & NVME_CMD_OPC_MASK;
|
||||
fuse = (cmd->opc_fuse >> NVME_CMD_FUSE_SHIFT) & NVME_CMD_FUSE_MASK;
|
||||
|
||||
printf(
|
||||
"opc:%x f:%x cid:%x nsid:%x r2:%x r3:%x mptr:%jx prp1:%jx prp2:%jx cdw:%x %x %x %x %x %x\n",
|
||||
opc, fuse, cmd->cid, le32toh(cmd->nsid),
|
||||
cmd->opc, cmd->fuse, cmd->cid, le32toh(cmd->nsid),
|
||||
cmd->rsvd2, cmd->rsvd3,
|
||||
(uintmax_t)le64toh(cmd->mptr), (uintmax_t)le64toh(cmd->prp1), (uintmax_t)le64toh(cmd->prp2),
|
||||
le32toh(cmd->cdw10), le32toh(cmd->cdw11), le32toh(cmd->cdw12),
|
||||
|
@ -110,13 +110,9 @@
|
||||
|
||||
/* Command field definitions */
|
||||
|
||||
#define NVME_CMD_OPC_SHIFT (0)
|
||||
#define NVME_CMD_OPC_MASK (0xFF)
|
||||
#define NVME_CMD_FUSE_SHIFT (8)
|
||||
#define NVME_CMD_FUSE_MASK (0x3)
|
||||
|
||||
#define NVME_CMD_SET_OPC(opc) (htole16(((uint16_t)(opc) & NVME_CMD_OPC_MASK) << NVME_CMD_OPC_SHIFT))
|
||||
|
||||
#define NVME_STATUS_P_SHIFT (0)
|
||||
#define NVME_STATUS_P_MASK (0x1)
|
||||
#define NVME_STATUS_SC_SHIFT (1)
|
||||
@ -428,7 +424,8 @@ _Static_assert(sizeof(struct nvme_registers) == 0x1008, "bad size for nvme_regis
|
||||
struct nvme_command
|
||||
{
|
||||
/* dword 0 */
|
||||
uint16_t opc_fuse; /* opcode, fused operation */
|
||||
uint8_t opc; /* opcode */
|
||||
uint8_t fuse; /* fused operation */
|
||||
uint16_t cid; /* command identifier */
|
||||
|
||||
/* dword 1 */
|
||||
@ -1288,7 +1285,7 @@ static inline
|
||||
void nvme_ns_flush_cmd(struct nvme_command *cmd, uint32_t nsid)
|
||||
{
|
||||
|
||||
cmd->opc_fuse = NVME_CMD_SET_OPC(NVME_OPC_FLUSH);
|
||||
cmd->opc = NVME_OPC_FLUSH;
|
||||
cmd->nsid = htole32(nsid);
|
||||
}
|
||||
|
||||
@ -1296,7 +1293,7 @@ static inline
|
||||
void nvme_ns_rw_cmd(struct nvme_command *cmd, uint32_t rwcmd, uint32_t nsid,
|
||||
uint64_t lba, uint32_t count)
|
||||
{
|
||||
cmd->opc_fuse = NVME_CMD_SET_OPC(rwcmd);
|
||||
cmd->opc = rwcmd;
|
||||
cmd->nsid = htole32(nsid);
|
||||
cmd->cdw10 = htole32(lba & 0xffffffffu);
|
||||
cmd->cdw11 = htole32(lba >> 32);
|
||||
@ -1321,7 +1318,7 @@ static inline
|
||||
void nvme_ns_trim_cmd(struct nvme_command *cmd, uint32_t nsid,
|
||||
uint32_t num_ranges)
|
||||
{
|
||||
cmd->opc_fuse = NVME_CMD_SET_OPC(NVME_OPC_DATASET_MANAGEMENT);
|
||||
cmd->opc = NVME_OPC_DATASET_MANAGEMENT;
|
||||
cmd->nsid = htole32(nsid);
|
||||
cmd->cdw10 = htole32(num_ranges - 1);
|
||||
cmd->cdw11 = htole32(NVME_DSM_ATTR_DEALLOCATE);
|
||||
|
@ -769,7 +769,7 @@ nvme_ctrlr_construct_and_submit_aer(struct nvme_controller *ctrlr,
|
||||
* nature never be timed out.
|
||||
*/
|
||||
req->timeout = FALSE;
|
||||
req->cmd.opc_fuse = NVME_CMD_SET_OPC(NVME_OPC_ASYNC_EVENT_REQUEST);
|
||||
req->cmd.opc = NVME_OPC_ASYNC_EVENT_REQUEST;
|
||||
nvme_ctrlr_submit_admin_request(ctrlr, req);
|
||||
}
|
||||
|
||||
@ -1073,7 +1073,8 @@ nvme_ctrlr_passthrough_cmd(struct nvme_controller *ctrlr,
|
||||
req = nvme_allocate_request_null(nvme_pt_done, pt);
|
||||
|
||||
/* Assume userspace already converted to little-endian */
|
||||
req->cmd.opc_fuse = pt->cmd.opc_fuse;
|
||||
req->cmd.opc = pt->cmd.opc;
|
||||
req->cmd.fuse = pt->cmd.fuse;
|
||||
req->cmd.cdw10 = pt->cmd.cdw10;
|
||||
req->cmd.cdw11 = pt->cmd.cdw11;
|
||||
req->cmd.cdw12 = pt->cmd.cdw12;
|
||||
|
@ -42,7 +42,7 @@ nvme_ctrlr_cmd_identify_controller(struct nvme_controller *ctrlr, void *payload,
|
||||
sizeof(struct nvme_controller_data), cb_fn, cb_arg);
|
||||
|
||||
cmd = &req->cmd;
|
||||
cmd->opc_fuse = NVME_CMD_SET_OPC(NVME_OPC_IDENTIFY);
|
||||
cmd->opc = NVME_OPC_IDENTIFY;
|
||||
|
||||
/*
|
||||
* TODO: create an identify command data structure, which
|
||||
@ -64,7 +64,7 @@ nvme_ctrlr_cmd_identify_namespace(struct nvme_controller *ctrlr, uint32_t nsid,
|
||||
sizeof(struct nvme_namespace_data), cb_fn, cb_arg);
|
||||
|
||||
cmd = &req->cmd;
|
||||
cmd->opc_fuse = NVME_CMD_SET_OPC(NVME_OPC_IDENTIFY);
|
||||
cmd->opc = NVME_OPC_IDENTIFY;
|
||||
|
||||
/*
|
||||
* TODO: create an identify command data structure
|
||||
@ -85,7 +85,7 @@ nvme_ctrlr_cmd_create_io_cq(struct nvme_controller *ctrlr,
|
||||
req = nvme_allocate_request_null(cb_fn, cb_arg);
|
||||
|
||||
cmd = &req->cmd;
|
||||
cmd->opc_fuse = NVME_CMD_SET_OPC(NVME_OPC_CREATE_IO_CQ);
|
||||
cmd->opc = NVME_OPC_CREATE_IO_CQ;
|
||||
|
||||
/*
|
||||
* TODO: create a create io completion queue command data
|
||||
@ -109,7 +109,7 @@ nvme_ctrlr_cmd_create_io_sq(struct nvme_controller *ctrlr,
|
||||
req = nvme_allocate_request_null(cb_fn, cb_arg);
|
||||
|
||||
cmd = &req->cmd;
|
||||
cmd->opc_fuse = NVME_CMD_SET_OPC(NVME_OPC_CREATE_IO_SQ);
|
||||
cmd->opc = NVME_OPC_CREATE_IO_SQ;
|
||||
|
||||
/*
|
||||
* TODO: create a create io submission queue command data
|
||||
@ -133,7 +133,7 @@ nvme_ctrlr_cmd_delete_io_cq(struct nvme_controller *ctrlr,
|
||||
req = nvme_allocate_request_null(cb_fn, cb_arg);
|
||||
|
||||
cmd = &req->cmd;
|
||||
cmd->opc_fuse = NVME_CMD_SET_OPC(NVME_OPC_DELETE_IO_CQ);
|
||||
cmd->opc = NVME_OPC_DELETE_IO_CQ;
|
||||
|
||||
/*
|
||||
* TODO: create a delete io completion queue command data
|
||||
@ -154,7 +154,7 @@ nvme_ctrlr_cmd_delete_io_sq(struct nvme_controller *ctrlr,
|
||||
req = nvme_allocate_request_null(cb_fn, cb_arg);
|
||||
|
||||
cmd = &req->cmd;
|
||||
cmd->opc_fuse = NVME_CMD_SET_OPC(NVME_OPC_DELETE_IO_SQ);
|
||||
cmd->opc = NVME_OPC_DELETE_IO_SQ;
|
||||
|
||||
/*
|
||||
* TODO: create a delete io submission queue command data
|
||||
@ -176,7 +176,7 @@ nvme_ctrlr_cmd_set_feature(struct nvme_controller *ctrlr, uint8_t feature,
|
||||
req = nvme_allocate_request_null(cb_fn, cb_arg);
|
||||
|
||||
cmd = &req->cmd;
|
||||
cmd->opc_fuse = NVME_CMD_SET_OPC(NVME_OPC_SET_FEATURES);
|
||||
cmd->opc = NVME_OPC_SET_FEATURES;
|
||||
cmd->cdw10 = htole32(feature);
|
||||
cmd->cdw11 = htole32(cdw11);
|
||||
|
||||
@ -194,7 +194,7 @@ nvme_ctrlr_cmd_get_feature(struct nvme_controller *ctrlr, uint8_t feature,
|
||||
req = nvme_allocate_request_null(cb_fn, cb_arg);
|
||||
|
||||
cmd = &req->cmd;
|
||||
cmd->opc_fuse = NVME_CMD_SET_OPC(NVME_OPC_GET_FEATURES);
|
||||
cmd->opc = NVME_OPC_GET_FEATURES;
|
||||
cmd->cdw10 = htole32(feature);
|
||||
cmd->cdw11 = htole32(cdw11);
|
||||
|
||||
@ -260,7 +260,7 @@ nvme_ctrlr_cmd_get_log_page(struct nvme_controller *ctrlr, uint8_t log_page,
|
||||
req = nvme_allocate_request_vaddr(payload, payload_size, cb_fn, cb_arg);
|
||||
|
||||
cmd = &req->cmd;
|
||||
cmd->opc_fuse = NVME_CMD_SET_OPC(NVME_OPC_GET_LOG_PAGE);
|
||||
cmd->opc = NVME_OPC_GET_LOG_PAGE;
|
||||
cmd->nsid = htole32(nsid);
|
||||
cmd->cdw10 = ((payload_size/sizeof(uint32_t)) - 1) << 16;
|
||||
cmd->cdw10 |= log_page;
|
||||
@ -320,7 +320,7 @@ nvme_ctrlr_cmd_abort(struct nvme_controller *ctrlr, uint16_t cid,
|
||||
req = nvme_allocate_request_null(cb_fn, cb_arg);
|
||||
|
||||
cmd = &req->cmd;
|
||||
cmd->opc_fuse = NVME_CMD_SET_OPC(NVME_OPC_ABORT);
|
||||
cmd->opc = NVME_OPC_ABORT;
|
||||
cmd->cdw10 = htole32((cid << 16) | sqid);
|
||||
|
||||
nvme_ctrlr_submit_admin_request(ctrlr, req);
|
||||
|
@ -126,7 +126,7 @@ nvme_ns_cmd_deallocate(struct nvme_namespace *ns, void *payload,
|
||||
return (ENOMEM);
|
||||
|
||||
cmd = &req->cmd;
|
||||
cmd->opc_fuse = NVME_CMD_SET_OPC(NVME_OPC_DATASET_MANAGEMENT);
|
||||
cmd->opc = NVME_OPC_DATASET_MANAGEMENT;
|
||||
cmd->nsid = htole32(ns->id);
|
||||
|
||||
/* TODO: create a delete command data structure */
|
||||
|
@ -125,12 +125,10 @@ static void
|
||||
nvme_admin_qpair_print_command(struct nvme_qpair *qpair,
|
||||
struct nvme_command *cmd)
|
||||
{
|
||||
uint16_t opc;
|
||||
|
||||
opc = le16toh(cmd->opc_fuse) & NVME_CMD_OPC_MASK;
|
||||
nvme_printf(qpair->ctrlr, "%s (%02x) sqid:%d cid:%d nsid:%x "
|
||||
"cdw10:%08x cdw11:%08x\n",
|
||||
get_admin_opcode_string(opc), opc, qpair->id, cmd->cid,
|
||||
get_admin_opcode_string(cmd->opc), cmd->opc, qpair->id, cmd->cid,
|
||||
le32toh(cmd->nsid), le32toh(cmd->cdw10), le32toh(cmd->cdw11));
|
||||
}
|
||||
|
||||
@ -138,10 +136,8 @@ static void
|
||||
nvme_io_qpair_print_command(struct nvme_qpair *qpair,
|
||||
struct nvme_command *cmd)
|
||||
{
|
||||
uint16_t opc;
|
||||
|
||||
opc = le16toh(cmd->opc_fuse) & NVME_CMD_OPC_MASK;
|
||||
switch (opc) {
|
||||
switch (cmd->opc) {
|
||||
case NVME_OPC_WRITE:
|
||||
case NVME_OPC_READ:
|
||||
case NVME_OPC_WRITE_UNCORRECTABLE:
|
||||
@ -149,7 +145,7 @@ nvme_io_qpair_print_command(struct nvme_qpair *qpair,
|
||||
case NVME_OPC_WRITE_ZEROES:
|
||||
nvme_printf(qpair->ctrlr, "%s sqid:%d cid:%d nsid:%d "
|
||||
"lba:%llu len:%d\n",
|
||||
get_io_opcode_string(opc), qpair->id, cmd->cid, le32toh(cmd->nsid),
|
||||
get_io_opcode_string(cmd->opc), qpair->id, cmd->cid, le32toh(cmd->nsid),
|
||||
((unsigned long long)le32toh(cmd->cdw11) << 32) + le32toh(cmd->cdw10),
|
||||
(le32toh(cmd->cdw12) & 0xFFFF) + 1);
|
||||
break;
|
||||
@ -160,11 +156,11 @@ nvme_io_qpair_print_command(struct nvme_qpair *qpair,
|
||||
case NVME_OPC_RESERVATION_ACQUIRE:
|
||||
case NVME_OPC_RESERVATION_RELEASE:
|
||||
nvme_printf(qpair->ctrlr, "%s sqid:%d cid:%d nsid:%d\n",
|
||||
get_io_opcode_string(opc), qpair->id, cmd->cid, le32toh(cmd->nsid));
|
||||
get_io_opcode_string(cmd->opc), qpair->id, cmd->cid, le32toh(cmd->nsid));
|
||||
break;
|
||||
default:
|
||||
nvme_printf(qpair->ctrlr, "%s (%02x) sqid:%d cid:%d nsid:%d\n",
|
||||
get_io_opcode_string(opc), opc, qpair->id,
|
||||
get_io_opcode_string(cmd->opc), cmd->opc, qpair->id,
|
||||
cmd->cid, le32toh(cmd->nsid));
|
||||
break;
|
||||
}
|
||||
@ -721,7 +717,7 @@ nvme_admin_qpair_abort_aers(struct nvme_qpair *qpair)
|
||||
|
||||
tr = TAILQ_FIRST(&qpair->outstanding_tr);
|
||||
while (tr != NULL) {
|
||||
if ((le16toh(tr->req->cmd.opc_fuse) & NVME_CMD_OPC_MASK) == NVME_OPC_ASYNC_EVENT_REQUEST) {
|
||||
if (tr->req->cmd.opc == NVME_OPC_ASYNC_EVENT_REQUEST) {
|
||||
nvme_qpair_manual_complete_tracker(qpair, tr,
|
||||
NVME_SCT_GENERIC, NVME_SC_ABORTED_SQ_DELETION, 0,
|
||||
FALSE);
|
||||
|
@ -60,7 +60,7 @@
|
||||
* in the range 5 to 9.
|
||||
*/
|
||||
#undef __FreeBSD_version
|
||||
#define __FreeBSD_version 1200080 /* Master, propagated to newvers */
|
||||
#define __FreeBSD_version 1200081 /* Master, propagated to newvers */
|
||||
|
||||
/*
|
||||
* __FreeBSD_kernel__ indicates that this system uses the kernel of FreeBSD,
|
||||
|
@ -117,9 +117,6 @@ enum nvme_cmd_cdw11 {
|
||||
NVME_CMD_CDW11_IV = 0xFFFF0000,
|
||||
};
|
||||
|
||||
#define NVME_CMD_GET_OPC(opc) \
|
||||
((opc) >> NVME_CMD_OPC_SHIFT & NVME_CMD_OPC_MASK)
|
||||
|
||||
#define NVME_CQ_INTEN 0x01
|
||||
#define NVME_CQ_INTCOAL 0x02
|
||||
|
||||
@ -892,7 +889,7 @@ pci_nvme_handle_admin_cmd(struct pci_nvme_softc* sc, uint64_t value)
|
||||
cmd = &(sq->qbase)[sqhead];
|
||||
compl.status = 0;
|
||||
|
||||
switch (NVME_CMD_GET_OPC(cmd->opc_fuse)) {
|
||||
switch (cmd->opc) {
|
||||
case NVME_OPC_DELETE_IO_SQ:
|
||||
DPRINTF(("%s command DELETE_IO_SQ\r\n", __func__));
|
||||
do_intr |= nvme_opc_delete_io_sq(sc, cmd, &compl);
|
||||
@ -937,12 +934,11 @@ pci_nvme_handle_admin_cmd(struct pci_nvme_softc* sc, uint64_t value)
|
||||
break;
|
||||
default:
|
||||
WPRINTF(("0x%x command is not implemented\r\n",
|
||||
NVME_CMD_GET_OPC(cmd->opc_fuse)));
|
||||
cmd->opc));
|
||||
}
|
||||
|
||||
/* for now skip async event generation */
|
||||
if (NVME_CMD_GET_OPC(cmd->opc_fuse) !=
|
||||
NVME_OPC_ASYNC_EVENT_REQUEST) {
|
||||
if (cmd->opc != NVME_OPC_ASYNC_EVENT_REQUEST) {
|
||||
struct nvme_completion *cp;
|
||||
int phase;
|
||||
|
||||
@ -1211,13 +1207,13 @@ pci_nvme_handle_io_cmd(struct pci_nvme_softc* sc, uint16_t idx)
|
||||
|
||||
lba = ((uint64_t)cmd->cdw11 << 32) | cmd->cdw10;
|
||||
|
||||
if (NVME_CMD_GET_OPC(cmd->opc_fuse) == NVME_OPC_FLUSH) {
|
||||
if (cmd->opc == NVME_OPC_FLUSH) {
|
||||
pci_nvme_status_genc(&status, NVME_SC_SUCCESS);
|
||||
pci_nvme_set_completion(sc, sq, idx, cmd->cid, 0,
|
||||
status, 1);
|
||||
|
||||
continue;
|
||||
} else if (NVME_CMD_GET_OPC(cmd->opc_fuse) == 0x08) {
|
||||
} else if (cmd->opc == 0x08) {
|
||||
/* TODO: write zeroes */
|
||||
WPRINTF(("%s write zeroes lba 0x%lx blocks %u\r\n",
|
||||
__func__, lba, cmd->cdw12 & 0xFFFF));
|
||||
@ -1246,7 +1242,7 @@ pci_nvme_handle_io_cmd(struct pci_nvme_softc* sc, uint16_t idx)
|
||||
DPRINTF(("[h%u:t%u:n%u] %s starting LBA 0x%lx blocks %lu "
|
||||
"(%lu-bytes)\r\n",
|
||||
sqhead==0 ? sq->size-1 : sqhead-1, sq->tail, sq->size,
|
||||
NVME_CMD_GET_OPC(cmd->opc_fuse) == NVME_OPC_WRITE ?
|
||||
cmd->opc == NVME_OPC_WRITE ?
|
||||
"WRITE" : "READ",
|
||||
lba, nblocks, bytes));
|
||||
|
||||
@ -1266,13 +1262,13 @@ pci_nvme_handle_io_cmd(struct pci_nvme_softc* sc, uint16_t idx)
|
||||
if (req != NULL) {
|
||||
req->io_req.br_offset = ((uint64_t)cmd->cdw11 << 32) |
|
||||
cmd->cdw10;
|
||||
req->opc = NVME_CMD_GET_OPC(cmd->opc_fuse);
|
||||
req->opc = cmd->opc;
|
||||
req->cid = cmd->cid;
|
||||
req->nsid = cmd->nsid;
|
||||
}
|
||||
|
||||
err = pci_nvme_append_iov_req(sc, req, cmd->prp1, cpsz,
|
||||
NVME_CMD_GET_OPC(cmd->opc_fuse) == NVME_OPC_WRITE, lba);
|
||||
cmd->opc == NVME_OPC_WRITE, lba);
|
||||
lba += cpsz;
|
||||
size -= cpsz;
|
||||
|
||||
@ -1284,7 +1280,7 @@ pci_nvme_handle_io_cmd(struct pci_nvme_softc* sc, uint16_t idx)
|
||||
|
||||
err = pci_nvme_append_iov_req(sc, req, cmd->prp2,
|
||||
size,
|
||||
NVME_CMD_GET_OPC(cmd->opc_fuse) == NVME_OPC_WRITE,
|
||||
cmd->opc == NVME_OPC_WRITE,
|
||||
lba);
|
||||
} else {
|
||||
uint64_t *prp_list;
|
||||
@ -1318,8 +1314,7 @@ pci_nvme_handle_io_cmd(struct pci_nvme_softc* sc, uint16_t idx)
|
||||
|
||||
err = pci_nvme_append_iov_req(sc, req,
|
||||
prp_list[i], cpsz,
|
||||
NVME_CMD_GET_OPC(cmd->opc_fuse) ==
|
||||
NVME_OPC_WRITE, lba);
|
||||
cmd->opc == NVME_OPC_WRITE, lba);
|
||||
if (err)
|
||||
break;
|
||||
|
||||
@ -1350,7 +1345,7 @@ pci_nvme_handle_io_cmd(struct pci_nvme_softc* sc, uint16_t idx)
|
||||
req->io_req.br_callback = pci_nvme_io_done;
|
||||
|
||||
err = 0;
|
||||
switch (NVME_CMD_GET_OPC(cmd->opc_fuse)) {
|
||||
switch (cmd->opc) {
|
||||
case NVME_OPC_READ:
|
||||
err = blockif_read(sc->nvstore.ctx, &req->io_req);
|
||||
break;
|
||||
@ -1359,7 +1354,7 @@ pci_nvme_handle_io_cmd(struct pci_nvme_softc* sc, uint16_t idx)
|
||||
break;
|
||||
default:
|
||||
WPRINTF(("%s unhandled io command 0x%x\r\n",
|
||||
__func__, NVME_CMD_GET_OPC(cmd->opc_fuse)));
|
||||
__func__, cmd->opc));
|
||||
err = 1;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user