Changeset View
Changeset View
Standalone View
Standalone View
usr.sbin/bhyve/pci_nvme.c
Show First 20 Lines • Show All 2,606 Lines • ▼ Show 20 Lines | pci_nvme_read(struct vmctx *ctx, int vcpu, struct pci_devinst *pi, int baridx, | ||||
default: | default: | ||||
DPRINTF("unknown bar %d, 0x%lx", baridx, offset); | DPRINTF("unknown bar %d, 0x%lx", baridx, offset); | ||||
} | } | ||||
return (0); | return (0); | ||||
} | } | ||||
static int | static int | ||||
pci_nvme_parse_config(struct pci_nvme_softc *sc, nvlist_t *nvl) | pci_nvme_parse_config(struct pci_nvme_softc *sc, config_node_t *node) | ||||
{ | { | ||||
char bident[sizeof("XX:X:X")]; | char bident[sizeof("XX:X:X")]; | ||||
const char *value; | const char *value; | ||||
uint32_t sectsz; | uint32_t sectsz; | ||||
sc->max_queues = NVME_QUEUES; | sc->max_queues = NVME_QUEUES; | ||||
sc->max_qentries = NVME_MAX_QENTRIES; | sc->max_qentries = NVME_MAX_QENTRIES; | ||||
sc->ioslots = NVME_IOSLOTS; | sc->ioslots = NVME_IOSLOTS; | ||||
sc->num_squeues = sc->max_queues; | sc->num_squeues = sc->max_queues; | ||||
sc->num_cqueues = sc->max_queues; | sc->num_cqueues = sc->max_queues; | ||||
sc->dataset_management = NVME_DATASET_MANAGEMENT_AUTO; | sc->dataset_management = NVME_DATASET_MANAGEMENT_AUTO; | ||||
sectsz = 0; | sectsz = 0; | ||||
snprintf(sc->ctrldata.sn, sizeof(sc->ctrldata.sn), | snprintf(sc->ctrldata.sn, sizeof(sc->ctrldata.sn), | ||||
"NVME-%d-%d", sc->nsc_pi->pi_slot, sc->nsc_pi->pi_func); | "NVME-%d-%d", sc->nsc_pi->pi_slot, sc->nsc_pi->pi_func); | ||||
value = get_config_value_node(nvl, "maxq"); | value = get_config_value_node(node, "maxq"); | ||||
if (value != NULL) | if (value != NULL) | ||||
sc->max_queues = atoi(value); | sc->max_queues = atoi(value); | ||||
value = get_config_value_node(nvl, "qsz"); | value = get_config_value_node(node, "qsz"); | ||||
if (value != NULL) { | if (value != NULL) { | ||||
sc->max_qentries = atoi(value); | sc->max_qentries = atoi(value); | ||||
if (sc->max_qentries <= 0) { | if (sc->max_qentries <= 0) { | ||||
EPRINTLN("nvme: Invalid qsz option %d", | EPRINTLN("nvme: Invalid qsz option %d", | ||||
sc->max_qentries); | sc->max_qentries); | ||||
return (-1); | return (-1); | ||||
} | } | ||||
} | } | ||||
value = get_config_value_node(nvl, "ioslots"); | value = get_config_value_node(node, "ioslots"); | ||||
if (value != NULL) { | if (value != NULL) { | ||||
sc->ioslots = atoi(value); | sc->ioslots = atoi(value); | ||||
if (sc->ioslots <= 0) { | if (sc->ioslots <= 0) { | ||||
EPRINTLN("Invalid ioslots option %d", sc->ioslots); | EPRINTLN("Invalid ioslots option %d", sc->ioslots); | ||||
return (-1); | return (-1); | ||||
} | } | ||||
} | } | ||||
value = get_config_value_node(nvl, "sectsz"); | value = get_config_value_node(node, "sectsz"); | ||||
if (value != NULL) | if (value != NULL) | ||||
sectsz = atoi(value); | sectsz = atoi(value); | ||||
value = get_config_value_node(nvl, "ser"); | value = get_config_value_node(node, "ser"); | ||||
if (value != NULL) { | if (value != NULL) { | ||||
/* | /* | ||||
* This field indicates the Product Serial Number in | * This field indicates the Product Serial Number in | ||||
* 7-bit ASCII, unused bytes should be space characters. | * 7-bit ASCII, unused bytes should be space characters. | ||||
* Ref: NVMe v1.3c. | * Ref: NVMe v1.3c. | ||||
*/ | */ | ||||
cpywithpad((char *)sc->ctrldata.sn, | cpywithpad((char *)sc->ctrldata.sn, | ||||
sizeof(sc->ctrldata.sn), value, ' '); | sizeof(sc->ctrldata.sn), value, ' '); | ||||
} | } | ||||
value = get_config_value_node(nvl, "eui64"); | value = get_config_value_node(node, "eui64"); | ||||
if (value != NULL) | if (value != NULL) | ||||
sc->nvstore.eui64 = htobe64(strtoull(value, NULL, 0)); | sc->nvstore.eui64 = htobe64(strtoull(value, NULL, 0)); | ||||
value = get_config_value_node(nvl, "dsm"); | value = get_config_value_node(node, "dsm"); | ||||
if (value != NULL) { | if (value != NULL) { | ||||
if (strcmp(value, "auto") == 0) | if (strcmp(value, "auto") == 0) | ||||
sc->dataset_management = NVME_DATASET_MANAGEMENT_AUTO; | sc->dataset_management = NVME_DATASET_MANAGEMENT_AUTO; | ||||
else if (strcmp(value, "enable") == 0) | else if (strcmp(value, "enable") == 0) | ||||
sc->dataset_management = NVME_DATASET_MANAGEMENT_ENABLE; | sc->dataset_management = NVME_DATASET_MANAGEMENT_ENABLE; | ||||
else if (strcmp(value, "disable") == 0) | else if (strcmp(value, "disable") == 0) | ||||
sc->dataset_management = NVME_DATASET_MANAGEMENT_DISABLE; | sc->dataset_management = NVME_DATASET_MANAGEMENT_DISABLE; | ||||
} | } | ||||
value = get_config_value_node(nvl, "ram"); | value = get_config_value_node(node, "ram"); | ||||
if (value != NULL) { | if (value != NULL) { | ||||
uint64_t sz = strtoull(value, NULL, 10); | uint64_t sz = strtoull(value, NULL, 10); | ||||
sc->nvstore.type = NVME_STOR_RAM; | sc->nvstore.type = NVME_STOR_RAM; | ||||
sc->nvstore.size = sz * 1024 * 1024; | sc->nvstore.size = sz * 1024 * 1024; | ||||
sc->nvstore.ctx = calloc(1, sc->nvstore.size); | sc->nvstore.ctx = calloc(1, sc->nvstore.size); | ||||
sc->nvstore.sectsz = 4096; | sc->nvstore.sectsz = 4096; | ||||
sc->nvstore.sectsz_bits = 12; | sc->nvstore.sectsz_bits = 12; | ||||
if (sc->nvstore.ctx == NULL) { | if (sc->nvstore.ctx == NULL) { | ||||
EPRINTLN("nvme: Unable to allocate RAM"); | EPRINTLN("nvme: Unable to allocate RAM"); | ||||
return (-1); | return (-1); | ||||
} | } | ||||
} else { | } else { | ||||
snprintf(bident, sizeof(bident), "%d:%d", | snprintf(bident, sizeof(bident), "%d:%d", | ||||
sc->nsc_pi->pi_slot, sc->nsc_pi->pi_func); | sc->nsc_pi->pi_slot, sc->nsc_pi->pi_func); | ||||
sc->nvstore.ctx = blockif_open(nvl, bident); | sc->nvstore.ctx = blockif_open(node, bident); | ||||
if (sc->nvstore.ctx == NULL) { | if (sc->nvstore.ctx == NULL) { | ||||
EPRINTLN("nvme: Could not open backing file: %s", | EPRINTLN("nvme: Could not open backing file: %s", | ||||
strerror(errno)); | strerror(errno)); | ||||
return (-1); | return (-1); | ||||
} | } | ||||
sc->nvstore.type = NVME_STOR_BLOCKIF; | sc->nvstore.type = NVME_STOR_BLOCKIF; | ||||
sc->nvstore.size = blockif_size(sc->nvstore.ctx); | sc->nvstore.size = blockif_size(sc->nvstore.ctx); | ||||
} | } | ||||
if (sectsz == 512 || sectsz == 4096 || sectsz == 8192) | if (sectsz == 512 || sectsz == 4096 || sectsz == 8192) | ||||
sc->nvstore.sectsz = sectsz; | sc->nvstore.sectsz = sectsz; | ||||
else if (sc->nvstore.type != NVME_STOR_RAM) | else if (sc->nvstore.type != NVME_STOR_RAM) | ||||
sc->nvstore.sectsz = blockif_sectsz(sc->nvstore.ctx); | sc->nvstore.sectsz = blockif_sectsz(sc->nvstore.ctx); | ||||
for (sc->nvstore.sectsz_bits = 9; | for (sc->nvstore.sectsz_bits = 9; | ||||
(1 << sc->nvstore.sectsz_bits) < sc->nvstore.sectsz; | (1 << sc->nvstore.sectsz_bits) < sc->nvstore.sectsz; | ||||
sc->nvstore.sectsz_bits++); | sc->nvstore.sectsz_bits++); | ||||
if (sc->max_queues <= 0 || sc->max_queues > NVME_QUEUES) | if (sc->max_queues <= 0 || sc->max_queues > NVME_QUEUES) | ||||
sc->max_queues = NVME_QUEUES; | sc->max_queues = NVME_QUEUES; | ||||
return (0); | return (0); | ||||
} | } | ||||
static int | static int | ||||
pci_nvme_init(struct vmctx *ctx, struct pci_devinst *pi, nvlist_t *nvl) | pci_nvme_init(struct vmctx *ctx, struct pci_devinst *pi, config_node_t *node) | ||||
{ | { | ||||
struct pci_nvme_softc *sc; | struct pci_nvme_softc *sc; | ||||
uint32_t pci_membar_sz; | uint32_t pci_membar_sz; | ||||
int error; | int error; | ||||
error = 0; | error = 0; | ||||
sc = calloc(1, sizeof(struct pci_nvme_softc)); | sc = calloc(1, sizeof(struct pci_nvme_softc)); | ||||
pi->pi_arg = sc; | pi->pi_arg = sc; | ||||
sc->nsc_pi = pi; | sc->nsc_pi = pi; | ||||
error = pci_nvme_parse_config(sc, nvl); | error = pci_nvme_parse_config(sc, node); | ||||
if (error < 0) | if (error < 0) | ||||
goto done; | goto done; | ||||
else | else | ||||
error = 0; | error = 0; | ||||
STAILQ_INIT(&sc->ioreqs_free); | STAILQ_INIT(&sc->ioreqs_free); | ||||
sc->ioreqs = calloc(sc->ioslots, sizeof(struct pci_nvme_ioreq)); | sc->ioreqs = calloc(sc->ioslots, sizeof(struct pci_nvme_ioreq)); | ||||
for (int i = 0; i < sc->ioslots; i++) { | for (int i = 0; i < sc->ioslots; i++) { | ||||
▲ Show 20 Lines • Show All 73 Lines • Show Last 20 Lines |