Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F177570552
D61563.1794767838.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Authored By
Unknown
Size
6 KB
Referenced Files
None
Subscribers
None
D61563.1794767838.diff
View Options
diff --git a/sys/dev/nvmf/controller/nvmft_controller.c b/sys/dev/nvmf/controller/nvmft_controller.c
--- a/sys/dev/nvmf/controller/nvmft_controller.c
+++ b/sys/dev/nvmf/controller/nvmft_controller.c
@@ -70,6 +70,7 @@
memcpy(ctrlr->hostnqn, data->hostnqn, sizeof(ctrlr->hostnqn));
ctrlr->hip.power_cycles[0] = 1;
ctrlr->create_time = sbinuptime();
+ ctrlr->arb_burst = ctrlr->cdata.rab;
ctrlr->changed_ns = malloc(sizeof(*ctrlr->changed_ns), M_NVMFT,
M_WAITOK | M_ZERO);
@@ -826,6 +827,90 @@
fid = NVMEV(NVME_FEAT_SET_FID, le32toh(cmd->cdw10));
switch (fid) {
+ case NVME_FEAT_ARBITRATION:
+ {
+ uint32_t attr;
+
+ if (cmd->nsid != htole32(0))
+ goto not_ns_specifc;
+
+ attr = le32toh(cmd->cdw11);
+ if ((attr & 0xfffffff8) != 0)
+ goto error;
+
+ /*
+ * We don't actually honor this limit, just remember
+ * it so it can be returned later.
+ */
+ mtx_lock(&ctrlr->lock);
+ ctrlr->arb_burst = attr & 7;
+ mtx_unlock(&ctrlr->lock);
+
+ nvmft_send_success(ctrlr->admin, nc);
+ nvmf_free_capsule(nc);
+ return;
+ }
+ case NVME_FEAT_POWER_MANAGEMENT:
+ {
+ uint32_t val;
+
+ if (cmd->nsid != htole32(0))
+ goto not_ns_specifc;
+
+ val = le32toh(cmd->cdw11);
+ if ((val & 0xfffffff0) != 0)
+ goto error;
+
+ /* Only power state 0 is supported. */
+ if ((val & 0xf) != 0)
+ goto error;
+
+ nvmft_init_cqe(&cqe, nc, 0);
+ cqe.cdw0 = cmd->cdw11;
+ nvmft_send_response(ctrlr->admin, &cqe);
+ nvmf_free_capsule(nc);
+ return;
+ }
+ case NVME_FEAT_TEMPERATURE_THRESHOLD:
+ {
+ uint32_t val;
+
+ if (cmd->nsid != htole32(0))
+ goto not_ns_specifc;
+
+ val = le32toh(cmd->cdw11);
+ if ((val & 0xffc00000) != 0)
+ goto error;
+
+ /* Reserved THSEL. */
+ if ((val >> 20 & 0x3) >= 2)
+ goto error;
+
+ /* Treat the extra sensors as unimplemented. */
+ switch ((val >> 16) & 0xf) {
+ case 0:
+ case 0xf:
+ break;
+ default:
+ goto error;
+ }
+
+ nvmft_send_error(ctrlr->admin, nc, NVME_SCT_COMMAND_SPECIFIC,
+ NVME_SC_FEATURE_NOT_CHANGEABLE);
+ nvmf_free_capsule(nc);
+ return;
+ }
+ case NVME_FEAT_ERROR_RECOVERY:
+ {
+ uint32_t nsid;
+
+ nsid = le32toh(cmd->nsid);
+ if (nsid == NVME_GLOBAL_NAMESPACE_TAG)
+ goto error;
+
+ nvmft_dispatch_command(ctrlr->admin, nc, true);
+ return;
+ }
case NVME_FEAT_NUMBER_OF_QUEUES:
{
uint32_t num_queues;
@@ -870,6 +955,21 @@
nvmf_free_capsule(nc);
return;
}
+ case NVME_FEAT_WRITE_ATOMICITY:
+ {
+ uint32_t val;
+
+ if (cmd->nsid != htole32(0))
+ goto not_ns_specifc;
+
+ val = le32toh(cmd->cdw11);
+ if ((val & 0xfffffffe) != 0)
+ goto error;
+
+ nvmft_send_success(ctrlr->admin, nc);
+ nvmf_free_capsule(nc);
+ return;
+ }
case NVME_FEAT_ASYNC_EVENT_CONFIGURATION:
{
uint32_t aer_mask;
@@ -900,6 +1000,14 @@
nvmft_send_success(ctrlr->admin, nc);
nvmf_free_capsule(nc);
return;
+ case NVME_FEAT_HOST_IDENTIFIER:
+ if (cmd->nsid != htole32(0))
+ goto not_ns_specifc;
+
+ nvmft_send_generic_error(ctrlr->admin, nc,
+ NVME_SC_COMMAND_SEQUENCE_ERROR);
+ nvmf_free_capsule(nc);
+ return;
default:
nvmft_printf(ctrlr,
"Unsupported feature ID %u for SET_FEATURES\n", fid);
@@ -930,6 +1038,71 @@
fid = NVMEV(NVME_FEAT_GET_FID, le32toh(cmd->cdw10));
switch (fid) {
+ case NVME_FEAT_ARBITRATION:
+ if (cmd->nsid != htole32(0))
+ goto not_ns_specifc;
+
+ nvmft_init_cqe(&cqe, nc, 0);
+ cqe.cdw0 = htole32(ctrlr->arb_burst);
+ nvmft_send_response(ctrlr->admin, &cqe);
+ nvmf_free_capsule(nc);
+ return;
+ case NVME_FEAT_POWER_MANAGEMENT:
+ if (cmd->nsid != htole32(0))
+ goto not_ns_specifc;
+
+ nvmft_init_cqe(&cqe, nc, 0);
+ cqe.cdw0 = htole32(0);
+ nvmft_send_response(ctrlr->admin, &cqe);
+ nvmf_free_capsule(nc);
+ return;
+ case NVME_FEAT_TEMPERATURE_THRESHOLD:
+ {
+ uint32_t val;
+
+ if (cmd->nsid != htole32(0))
+ goto not_ns_specifc;
+
+ val = le32toh(cmd->cdw11);
+ if ((val & 0xffc00000) != 0)
+ goto error;
+
+ /* Reserved THSEL. */
+ if ((val >> 20 & 0x3) >= 2)
+ goto error;
+
+ /* Treat the extra sensors as unimplemented. */
+ switch ((val >> 16) & 0xf) {
+ case 0:
+ break;
+ default:
+ goto error;
+ }
+
+ /*
+ * Use 0 as the under threshold and cdata.wctemp as
+ * the over.
+ */
+ nvmft_init_cqe(&cqe, nc, 0);
+ if ((val >> 20 & 0x3) == 0)
+ cqe.cdw0 = htole32(le16toh(ctrlr->cdata.wctemp));
+ else
+ cqe.cdw0 = htole32(0);
+ nvmft_send_response(ctrlr->admin, &cqe);
+ nvmf_free_capsule(nc);
+ return;
+ }
+ case NVME_FEAT_ERROR_RECOVERY:
+ {
+ uint32_t nsid;
+
+ nsid = le32toh(cmd->nsid);
+ if (nsid == NVME_GLOBAL_NAMESPACE_TAG)
+ goto error;
+
+ nvmft_dispatch_command(ctrlr->admin, nc, true);
+ return;
+ }
case NVME_FEAT_NUMBER_OF_QUEUES:
{
uint32_t num_queues;
@@ -956,6 +1129,15 @@
nvmf_free_capsule(nc);
return;
}
+ case NVME_FEAT_WRITE_ATOMICITY:
+ if (cmd->nsid != htole32(0))
+ goto not_ns_specifc;
+
+ nvmft_init_cqe(&cqe, nc, 0);
+ cqe.cdw0 = htole32(0);
+ nvmft_send_response(ctrlr->admin, &cqe);
+ nvmf_free_capsule(nc);
+ return;
case NVME_FEAT_ASYNC_EVENT_CONFIGURATION:
if (cmd->nsid != htole32(0))
goto not_ns_specifc;
@@ -974,6 +1156,32 @@
nvmft_send_response(ctrlr->admin, &cqe);
nvmf_free_capsule(nc);
return;
+ case NVME_FEAT_HOST_IDENTIFIER:
+ {
+ struct mbuf *m;
+ u_int status;
+
+ if (cmd->nsid != htole32(0))
+ goto not_ns_specifc;
+
+ if (le32toh(cmd->cdw11) != 1)
+ goto error;
+
+ if (nvmf_capsule_data_len(nc) != sizeof(ctrlr->hostid))
+ goto error;
+
+ m = m_getml(sizeof(ctrlr->hostid), M_WAITOK);
+ m_copyback(m, 0, sizeof(ctrlr->hostid), ctrlr->hostid);
+ status = nvmf_send_controller_data(nc, 0, m,
+ sizeof(ctrlr->hostid));
+ MPASS(status != NVMF_MORE);
+ if (status == NVMF_SUCCESS_SENT)
+ nvmft_command_completed(ctrlr->admin, nc);
+ else
+ nvmft_send_generic_error(ctrlr->admin, nc, status);
+ nvmf_free_capsule(nc);
+ return;
+ }
default:
nvmft_printf(ctrlr,
"Unsupported feature ID %u for GET_FEATURES\n", fid);
diff --git a/sys/dev/nvmf/controller/nvmft_subr.c b/sys/dev/nvmf/controller/nvmft_subr.c
--- a/sys/dev/nvmf/controller/nvmft_subr.c
+++ b/sys/dev/nvmf/controller/nvmft_subr.c
@@ -153,6 +153,9 @@
if (cp != NULL)
memset(cp, ' ', sizeof(cdata->fr) - (cp - (char *)cdata->fr));
+ /* No arbitration limit. */
+ cdata->rab = 7;
+
/* FreeBSD OUI */
cdata->ieee[0] = 0xfc;
cdata->ieee[1] = 0x9c;
diff --git a/sys/dev/nvmf/controller/nvmft_var.h b/sys/dev/nvmf/controller/nvmft_var.h
--- a/sys/dev/nvmf/controller/nvmft_var.h
+++ b/sys/dev/nvmf/controller/nvmft_var.h
@@ -86,6 +86,7 @@
uint32_t pending_commands;
uint16_t pending_connects;
+ uint8_t arb_burst;
volatile int ka_active_traffic;
struct callout ka_timer;
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sun, Nov 15, 6:37 PM (23 h, 41 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
41746860
Default Alt Text
D61563.1794767838.diff (6 KB)
Attached To
Mode
D61563: nvmft: Implement missing mandatory NVMe features
Attached
Detach File
Event Timeline