Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 30 additions & 30 deletions plugins/microchip/switchtec-nvme-device.c
Original file line number Diff line number Diff line change
Expand Up @@ -54,13 +54,12 @@ struct switchtec_device_manage_nvme_rsp

struct switchtec_admin_passthru_nvme_req {
uint32_t nvme_sqe[16];
uint8_t nvme_data[SWITCHTEC_NVME_ADMIN_PASSTHRU_MAX_DATA_LEN -
(16 * 4)];
uint8_t nvme_data[];
};

struct switchtec_admin_passthru_nvme_rsp {
uint32_t nvme_cqe[4];
uint8_t nvme_data[4096];
uint8_t nvme_data[];
};

int pax_nvme_submit_admin_passthru_1k_rsp(int fd,
Expand Down Expand Up @@ -114,64 +113,65 @@ int pax_nvme_submit_admin_passthru_1k_rsp(int fd,
return status;
}

int pax_nvme_submit_admin_passthru_4k_rsp(int fd,
struct nvme_passthru_cmd *cmd)
int pax_nvme_submit_admin_passthru_var_rsp(int fd,
struct nvme_passthru_cmd *cmd)
{
int ret;

struct pax_nvme_device *pax;
struct switchtec_admin_passthru_nvme_req req;
struct switchtec_admin_passthru_nvme_rsp rsp;
size_t data_len = 0;
struct switchtec_admin_passthru_nvme_req *req;
struct switchtec_admin_passthru_nvme_rsp *rsp;
size_t req_len = 16 * 4;
size_t rsp_len;
int status;

memset(&req, 0, sizeof(req));
memset(&rsp, 0, sizeof(rsp));
pax = to_pax_nvme_device(global_device);

memcpy(&req.nvme_sqe, cmd, 16 * 4);
if (cmd->opcode & 0x1)
req_len += cmd->data_len;

req = (struct switchtec_admin_passthru_nvme_req *) malloc(req_len);
memset(req, 0, req_len);
memcpy(req->nvme_sqe, cmd, 16 * 4);
/* sqe[9] should be 0 per spec */
req.nvme_sqe[9] = 0;

if (cmd->opcode & 0x1) {
if (cmd->data_len > sizeof(req.nvme_data))
data_len = sizeof(req.nvme_data);
else
data_len = cmd->data_len;

memcpy(req.nvme_data, (void *)cmd->addr, data_len);
}
req->nvme_sqe[9] = 0;

data_len = data_len + 16 * 4;
if (cmd->opcode & 0x1)
memcpy(req->nvme_data, (void *)cmd->addr, cmd->data_len);

rsp_len = (sizeof(rsp.nvme_cqe) + cmd->data_len);
rsp_len = (sizeof(rsp->nvme_cqe) + cmd->data_len);
rsp = (struct switchtec_admin_passthru_nvme_rsp*) malloc(rsp_len);
memset(rsp, 0, rsp_len);

ret = switchtec_nvme_admin_passthru(pax->dev, pax->pdfid,
data_len, &req,
&rsp_len, &rsp);
if (ret)
req_len, req,
&rsp_len, rsp);
if (ret) {
free(req);
free(rsp);
return ret;
}

status = (rsp.nvme_cqe[3] & 0xfffe0000) >> 17;
status = (rsp->nvme_cqe[3] & 0xfffe0000) >> 17;
if (!status) {
cmd->result = rsp.nvme_cqe[0];
cmd->result = rsp->nvme_cqe[0];
if (cmd->addr) {
memcpy((uint64_t *)cmd->addr,
rsp.nvme_data,
rsp->nvme_data,
rsp_len - 4 * 4);
}
}

free(req);
free(rsp);
return status;
}

int pax_nvme_submit_admin_passthru(int fd, struct nvme_passthru_cmd *cmd)
{
int ret;

ret = pax_nvme_submit_admin_passthru_4k_rsp(fd, cmd);
ret = pax_nvme_submit_admin_passthru_var_rsp(fd, cmd);
if (ret && errno == INVALID_MRPC_CMD)
ret = pax_nvme_submit_admin_passthru_1k_rsp(fd, cmd);

Expand Down