Changeset View
Changeset View
Standalone View
Standalone View
usr.sbin/bhyve/pci_nvme.c
Show First 20 Lines • Show All 359 Lines • ▼ Show 20 Lines | pci_nvme_init_ctrldata(struct pci_nvme_softc *sc) | ||||
cd->sqes = (6 << NVME_CTRLR_DATA_SQES_MAX_SHIFT) | | cd->sqes = (6 << NVME_CTRLR_DATA_SQES_MAX_SHIFT) | | ||||
(6 << NVME_CTRLR_DATA_SQES_MIN_SHIFT); | (6 << NVME_CTRLR_DATA_SQES_MIN_SHIFT); | ||||
cd->cqes = (4 << NVME_CTRLR_DATA_CQES_MAX_SHIFT) | | cd->cqes = (4 << NVME_CTRLR_DATA_CQES_MAX_SHIFT) | | ||||
(4 << NVME_CTRLR_DATA_CQES_MIN_SHIFT); | (4 << NVME_CTRLR_DATA_CQES_MIN_SHIFT); | ||||
cd->nn = 1; /* number of namespaces */ | cd->nn = 1; /* number of namespaces */ | ||||
cd->oncs = (NVME_CTRLR_DATA_ONCS_DSM_MASK << NVME_CTRLR_DATA_ONCS_DSM_SHIFT); | cd->oncs = (NVME_CTRLR_DATA_ONCS_DSM_MASK << NVME_CTRLR_DATA_ONCS_DSM_SHIFT); | ||||
cd->fna = 0x03; | cd->fna = 0x03; | ||||
cd->vwc = 1 << NVME_CTRLR_DATA_VWC_PRESENT_SHIFT; | |||||
cd->power_state[0].mp = 10; | cd->power_state[0].mp = 10; | ||||
} | } | ||||
/* | /* | ||||
* Calculate the CRC-16 of the given buffer | * Calculate the CRC-16 of the given buffer | ||||
* See copyright attribution at top of file | * See copyright attribution at top of file | ||||
*/ | */ | ||||
static uint16_t | static uint16_t | ||||
▲ Show 20 Lines • Show All 598 Lines • ▼ Show 20 Lines | default: | ||||
return (1); | return (1); | ||||
} | } | ||||
break; | break; | ||||
case NVME_FEAT_ERROR_RECOVERY: | case NVME_FEAT_ERROR_RECOVERY: | ||||
DPRINTF((" error recovery\r\n")); | DPRINTF((" error recovery\r\n")); | ||||
break; | break; | ||||
case NVME_FEAT_VOLATILE_WRITE_CACHE: | case NVME_FEAT_VOLATILE_WRITE_CACHE: | ||||
DPRINTF((" volatile write cache\r\n")); | DPRINTF((" volatile write cache\r\n")); | ||||
compl->cdw0 = 1; | |||||
break; | break; | ||||
case NVME_FEAT_NUMBER_OF_QUEUES: | case NVME_FEAT_NUMBER_OF_QUEUES: | ||||
compl->cdw0 = NVME_FEATURE_NUM_QUEUES(sc); | compl->cdw0 = NVME_FEATURE_NUM_QUEUES(sc); | ||||
DPRINTF((" number of queues (submit %u, completion %u)\r\n", | DPRINTF((" number of queues (submit %u, completion %u)\r\n", | ||||
compl->cdw0 & 0xFFFF, | compl->cdw0 & 0xFFFF, | ||||
(compl->cdw0 >> 16) & 0xFFFF)); | (compl->cdw0 >> 16) & 0xFFFF)); | ||||
▲ Show 20 Lines • Show All 477 Lines • ▼ Show 20 Lines | if (err) | ||||
pci_nvme_status_genc(status, NVME_SC_INTERNAL_DEVICE_ERROR); | pci_nvme_status_genc(status, NVME_SC_INTERNAL_DEVICE_ERROR); | ||||
free(range); | free(range); | ||||
} | } | ||||
out: | out: | ||||
return (err); | return (err); | ||||
} | } | ||||
static int | |||||
nvme_opc_flush(struct pci_nvme_softc *sc, | |||||
struct nvme_command *cmd, | |||||
struct pci_nvme_blockstore *nvstore, | |||||
struct pci_nvme_ioreq *req, | |||||
uint16_t *status) | |||||
{ | |||||
int err; | |||||
/* Check if the given nsid in command is out-of-range */ | |||||
if ((!cmd->nsid || cmd->nsid > sc->ctrldata.nn) && | |||||
cmd->nsid != NVME_GLOBAL_NAMESPACE_TAG) { | |||||
pci_nvme_status_genc(status, | |||||
NVME_SC_INVALID_NAMESPACE_OR_FORMAT); | |||||
return (1); | |||||
} | |||||
if (nvstore->type == NVME_STOR_RAM) { | |||||
uint16_t status; | |||||
pci_nvme_status_genc(&status, NVME_SC_SUCCESS); | |||||
pci_nvme_set_completion(sc, req->nvme_sq, req->sqid, cmd->cid, 0, | |||||
status, 1); | |||||
return (0); | |||||
} | |||||
req->opc = cmd->opc; | |||||
req->cid = cmd->cid; | |||||
req->nsid = cmd->nsid; | |||||
req->io_req.br_iovcnt = 0; | |||||
req->io_req.br_offset = 0; | |||||
req->io_req.br_resid = 0; | |||||
req->io_req.br_callback = pci_nvme_io_done; | |||||
err = blockif_flush(sc->nvstore.ctx, &req->io_req); | |||||
if (err) | |||||
pci_nvme_status_genc(status, NVME_SC_INTERNAL_DEVICE_ERROR); | |||||
return (err); | |||||
} | |||||
static void | static void | ||||
pci_nvme_handle_io_cmd(struct pci_nvme_softc* sc, uint16_t idx) | pci_nvme_handle_io_cmd(struct pci_nvme_softc* sc, uint16_t idx) | ||||
{ | { | ||||
struct nvme_submission_queue *sq; | struct nvme_submission_queue *sq; | ||||
uint16_t status; | uint16_t status; | ||||
uint16_t sqhead; | uint16_t sqhead; | ||||
int err; | int err; | ||||
Show All 18 Lines | while (sqhead != atomic_load_acq_short(&sq->tail)) { | ||||
/* TODO: support scatter gather list handling */ | /* TODO: support scatter gather list handling */ | ||||
cmd = &sq->qbase[sqhead]; | cmd = &sq->qbase[sqhead]; | ||||
sqhead = (sqhead + 1) % sq->size; | sqhead = (sqhead + 1) % sq->size; | ||||
lba = ((uint64_t)cmd->cdw11 << 32) | cmd->cdw10; | lba = ((uint64_t)cmd->cdw11 << 32) | cmd->cdw10; | ||||
if (cmd->opc == NVME_OPC_FLUSH) { | if (cmd->opc == 0x08) { | ||||
pci_nvme_status_genc(&status, NVME_SC_SUCCESS); | |||||
pci_nvme_set_completion(sc, sq, idx, cmd->cid, 0, | |||||
status, 1); | |||||
continue; | |||||
} else if (cmd->opc == 0x08) { | |||||
/* TODO: write zeroes */ | /* TODO: write zeroes */ | ||||
WPRINTF(("%s write zeroes lba 0x%lx blocks %u\r\n", | WPRINTF(("%s write zeroes lba 0x%lx blocks %u\r\n", | ||||
__func__, lba, cmd->cdw12 & 0xFFFF)); | __func__, lba, cmd->cdw12 & 0xFFFF)); | ||||
pci_nvme_status_genc(&status, NVME_SC_SUCCESS); | pci_nvme_status_genc(&status, NVME_SC_SUCCESS); | ||||
pci_nvme_set_completion(sc, sq, idx, cmd->cid, 0, | pci_nvme_set_completion(sc, sq, idx, cmd->cid, 0, | ||||
status, 1); | status, 1); | ||||
continue; | continue; | ||||
} | } | ||||
if (sc->nvstore.type == NVME_STOR_BLOCKIF) { | if (sc->nvstore.type == NVME_STOR_BLOCKIF) { | ||||
req = pci_nvme_get_ioreq(sc); | req = pci_nvme_get_ioreq(sc); | ||||
req->nvme_sq = sq; | req->nvme_sq = sq; | ||||
req->sqid = idx; | req->sqid = idx; | ||||
} | } | ||||
if (cmd->opc == NVME_OPC_DATASET_MANAGEMENT) { | if (cmd->opc == NVME_OPC_FLUSH) { | ||||
if (nvme_opc_flush(sc, cmd, &sc->nvstore, req, | |||||
&status)) { | |||||
pci_nvme_set_completion(sc, sq, idx, cmd->cid, | |||||
0, status, 1); | |||||
pci_nvme_release_ioreq(sc, req); | |||||
} | |||||
continue; | |||||
} else if (cmd->opc == NVME_OPC_DATASET_MANAGEMENT) { | |||||
if (nvme_opc_dataset_mgmt(sc, cmd, &sc->nvstore, req, | if (nvme_opc_dataset_mgmt(sc, cmd, &sc->nvstore, req, | ||||
&status)) { | &status)) { | ||||
pci_nvme_set_completion(sc, sq, idx, cmd->cid, | pci_nvme_set_completion(sc, sq, idx, cmd->cid, | ||||
0, status, 1); | 0, status, 1); | ||||
pci_nvme_release_ioreq(sc, req); | pci_nvme_release_ioreq(sc, req); | ||||
} | } | ||||
continue; | continue; | ||||
} | } | ||||
▲ Show 20 Lines • Show All 633 Lines • Show Last 20 Lines |