summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYuri Pankov <yuri.pankov@nexenta.com>2018-02-23 05:46:16 +0300
committerGordon Ross <gwr@nexenta.com>2018-03-14 16:08:18 -0400
commitf313c178df05fb723db8426641b6f443f90f5f45 (patch)
treef8f1ac47b13b19d88c639376d0a1f3cdbd792d78
parent026e699f086745296cda4664068f50ace71e32e2 (diff)
downloadillumos-joyent-f313c178df05fb723db8426641b6f443f90f5f45.tar.gz
8808 nvme: Software Progress Marker feature is optional
Reviewed by: Hans Rosenfeld <rosenfeld@grumpf.hope-2000.org> Reviewed by: Robert Mustacchi <rm@joyent.com> Reviewed by: Dan Fields <dan.fields@nexenta.com> Reviewed by: Cynthia Eastham <cynthia.eastham@nexenta.com> Approved by: Gordon Ross <gwr@nexenta.com>
-rw-r--r--usr/src/uts/common/io/nvme/nvme.c62
-rw-r--r--usr/src/uts/common/io/nvme/nvme_var.h3
2 files changed, 48 insertions, 17 deletions
diff --git a/usr/src/uts/common/io/nvme/nvme.c b/usr/src/uts/common/io/nvme/nvme.c
index 2046d38a07..dded3186da 100644
--- a/usr/src/uts/common/io/nvme/nvme.c
+++ b/usr/src/uts/common/io/nvme/nvme.c
@@ -10,7 +10,7 @@
*/
/*
- * Copyright 2016 Nexenta Systems, Inc. All rights reserved.
+ * Copyright 2018 Nexenta Systems, Inc.
* Copyright 2016 Tegile Systems, Inc. All rights reserved.
* Copyright (c) 2016 The MathWorks, Inc. All rights reserved.
* Copyright 2017 Joyent, Inc.
@@ -1084,7 +1084,7 @@ nvme_check_generic_cmd_status(nvme_cmd_t *cmd)
/* Invalid Namespace or Format */
if (!cmd->nc_dontpanic)
dev_err(cmd->nc_nvme->n_dip, CE_PANIC,
- "programming error: " "invalid NS/format in cmd %p",
+ "programming error: invalid NS/format in cmd %p",
(void *)cmd);
return (EINVAL);
@@ -1855,6 +1855,13 @@ nvme_get_features(nvme_t *nvme, uint32_t nsid, uint8_t feature, uint32_t *res,
cmd->nc_sqe.sqe_cdw10 = feature;
cmd->nc_sqe.sqe_cdw11 = *res;
+ /*
+ * For some of the optional features there doesn't seem to be a method
+ * of detecting whether it is supported other than using it. This will
+ * cause "Invalid Field in Command" error, which is normally considered
+ * a programming error. Set the nc_dontpanic flag to override the panic
+ * in nvme_check_generic_cmd_status().
+ */
switch (feature) {
case NVME_FEAT_ARBITRATION:
case NVME_FEAT_POWER_MGMT:
@@ -1865,7 +1872,6 @@ nvme_get_features(nvme_t *nvme, uint32_t nsid, uint8_t feature, uint32_t *res,
case NVME_FEAT_INTR_VECT:
case NVME_FEAT_WRITE_ATOM:
case NVME_FEAT_ASYNC_EVENT:
- case NVME_FEAT_PROGRESS:
break;
case NVME_FEAT_WRITE_CACHE:
@@ -1877,18 +1883,10 @@ nvme_get_features(nvme_t *nvme, uint32_t nsid, uint8_t feature, uint32_t *res,
if (!nvme->n_lba_range_supported)
goto fail;
- /*
- * The LBA Range Type feature is optional. There doesn't seem
- * be a method of detecting whether it is supported other than
- * using it. This will cause a "invalid field in command" error,
- * which is normally considered a programming error and causes
- * panic in nvme_check_generic_cmd_status().
- */
cmd->nc_dontpanic = B_TRUE;
cmd->nc_sqe.sqe_nsid = nsid;
ASSERT(bufsize != NULL);
*bufsize = NVME_LBA_RANGE_BUFSIZE;
-
break;
case NVME_FEAT_AUTO_PST:
@@ -1899,6 +1897,13 @@ nvme_get_features(nvme_t *nvme, uint32_t nsid, uint8_t feature, uint32_t *res,
*bufsize = NVME_AUTO_PST_BUFSIZE;
break;
+ case NVME_FEAT_PROGRESS:
+ if (!nvme->n_progress_supported)
+ goto fail;
+
+ cmd->nc_dontpanic = B_TRUE;
+ break;
+
default:
goto fail;
}
@@ -1933,15 +1938,34 @@ nvme_get_features(nvme_t *nvme, uint32_t nsid, uint8_t feature, uint32_t *res,
nvme_admin_cmd(cmd, nvme_admin_cmd_timeout);
if ((ret = nvme_check_cmd_status(cmd)) != 0) {
- if (feature == NVME_FEAT_LBA_RANGE &&
- cmd->nc_cqe.cqe_sf.sf_sct == NVME_CQE_SCT_GENERIC &&
- cmd->nc_cqe.cqe_sf.sf_sc == NVME_CQE_SC_GEN_INV_FLD)
- nvme->n_lba_range_supported = B_FALSE;
- else
+ boolean_t known = B_TRUE;
+
+ /* Check if this is unsupported optional feature */
+ if (cmd->nc_cqe.cqe_sf.sf_sct == NVME_CQE_SCT_GENERIC &&
+ cmd->nc_cqe.cqe_sf.sf_sc == NVME_CQE_SC_GEN_INV_FLD) {
+ switch (feature) {
+ case NVME_FEAT_LBA_RANGE:
+ nvme->n_lba_range_supported = B_FALSE;
+ break;
+ case NVME_FEAT_PROGRESS:
+ nvme->n_progress_supported = B_FALSE;
+ break;
+ default:
+ known = B_FALSE;
+ break;
+ }
+ } else {
+ known = B_FALSE;
+ }
+
+ /* Report the error otherwise */
+ if (!known) {
dev_err(nvme->n_dip, CE_WARN,
"!GET FEATURES %d failed with sct = %x, sc = %x",
feature, cmd->nc_cqe.cqe_sf.sf_sct,
cmd->nc_cqe.cqe_sf.sf_sc);
+ }
+
goto fail;
}
@@ -2521,6 +2545,12 @@ nvme_init(nvme_t *nvme)
nvme->n_idctl->id_apsta.ap_sup == 0 ? B_FALSE : B_TRUE;
/*
+ * Assume Software Progress Marker feature is supported. If it isn't
+ * this will be set to B_FALSE by nvme_get_features().
+ */
+ nvme->n_progress_supported = B_TRUE;
+
+ /*
* Identify Namespaces
*/
nvme->n_namespace_count = nvme->n_idctl->id_nn;
diff --git a/usr/src/uts/common/io/nvme/nvme_var.h b/usr/src/uts/common/io/nvme/nvme_var.h
index b60febeabb..49d900040e 100644
--- a/usr/src/uts/common/io/nvme/nvme_var.h
+++ b/usr/src/uts/common/io/nvme/nvme_var.h
@@ -10,7 +10,7 @@
*/
/*
- * Copyright 2016 Nexenta Systems, Inc. All rights reserved.
+ * Copyright 2018 Nexenta Systems, Inc.
* Copyright 2016 The MathWorks, Inc. All rights reserved.
* Copyright 2017 Joyent, Inc.
*/
@@ -153,6 +153,7 @@ struct nvme {
boolean_t n_lba_range_supported;
boolean_t n_auto_pst_supported;
boolean_t n_async_event_supported;
+ boolean_t n_progress_supported;
int n_nssr_supported;
int n_doorbell_stride;