__le16 awun;
__le16 awupf;
__u8 nvscc;
- __u8 rsvd531;
+ __u8 nwpc;
__le16 acwu;
__u8 rsvd534[2];
__le32 sgls;
__le16 nabspf;
__le16 noiob;
__u8 nvmcap[16];
- __u8 rsvd64[36];
+ __u8 rsvd64[35];
+ __u8 nsattr;
__le16 nvmsetid;
__le16 endgid;
__u8 nguid[16];
__u8 rsvd64[448];
};
+/* NVMe Namespace Write Protect State */
+enum {
+ NVME_NS_NO_WRITE_PROTECT = 0,
+ NVME_NS_WRITE_PROTECT,
+ NVME_NS_WRITE_PROTECT_POWER_CYCLE,
+ NVME_NS_WRITE_PROTECT_PERMANENT,
+};
+
#define NVME_MAX_CHANGED_NAMESPACES 1024
struct nvme_changed_ns_list_log {
NVME_FEAT_HOST_ID = 0x81,
NVME_FEAT_RESV_MASK = 0x82,
NVME_FEAT_RESV_PERSIST = 0x83,
+ NVME_FEAT_WRITE_PROTECT = 0x84,
NVME_LOG_ERROR = 0x01,
NVME_LOG_SMART = 0x02,
NVME_LOG_FW_SLOT = 0x03,
NVME_SC_SANITIZE_FAILED = 0x1C,
NVME_SC_SANITIZE_IN_PROGRESS = 0x1D,
+ NVME_SC_NS_WRITE_PROTECTED = 0x20,
+
NVME_SC_LBA_RANGE = 0x80,
NVME_SC_CAP_EXCEEDED = 0x81,
NVME_SC_NS_NOT_READY = 0x82,
printf("\n");
}
+static void show_nvme_id_ctrl_nwpc(__u8 nwpc)
+{
+ __u8 no_wp_wp = (nwpc & 0x01);
+ __u8 wp_power_cycle = (nwpc & 0x02) >> 1;
+ __u8 wp_permanent = (nwpc & 0x04) >> 2;
+ __u8 rsvd = (nwpc & 0xF8) >> 3;
+
+ if (rsvd)
+ printf(" [7:3] : %#x\tReserved\n", rsvd);
+
+ printf(" [2:2] : %#x\tPermanent Write Protect %sSupported\n",
+ wp_permanent, wp_permanent ? "" : "Not ");
+ printf(" [1:1] : %#x\tWrite Protect Until Power Supply %sSupported\n",
+ wp_power_cycle, wp_power_cycle ? "" : "Not ");
+ printf(" [0:0] : %#x\tNo Write Protect and Write Protect Namespace %sSupported\n",
+ no_wp_wp, no_wp_wp ? "" : "Not ");
+ printf("\n");
+}
+
static void show_nvme_id_ctrl_sgls(__le32 ctrl_sgls)
{
__u32 sgls = le32_to_cpu(ctrl_sgls);
printf("nabspf : %d\n", le16_to_cpu(ns->nabspf));
printf("noiob : %d\n", le16_to_cpu(ns->noiob));
printf("nvmcap : %.0Lf\n", int128_to_double(ns->nvmcap));
+ printf("nsattr : %u\n", ns->nsattr);
printf("nvmsetid: %d\n", le16_to_cpu(ns->nvmsetid));
printf("endgid : %d\n", le16_to_cpu(ns->endgid));
printf("nvscc : %d\n", ctrl->nvscc);
if (human)
show_nvme_id_ctrl_nvscc(ctrl->nvscc);
+ printf("nwpc : %d\n", ctrl->nwpc);
+ if (human)
+ show_nvme_id_ctrl_nwpc(ctrl->nwpc);
printf("acwu : %d\n", le16_to_cpu(ctrl->acwu));
printf("sgls : %x\n", le32_to_cpu(ctrl->sgls));
if (human)
case NVME_FEAT_RESV_MASK: return "Reservation Notification Mask";
case NVME_FEAT_RESV_PERSIST: return "Reservation Persistence";
case NVME_FEAT_TIMESTAMP: return "Timestamp";
+ case NVME_FEAT_WRITE_PROTECT: return "Namespce Write Protect";
case NVME_FEAT_HCTM: return "Host Controlled Thermal Management";
default: return "Unknown";
}
case NVME_SC_SANITIZE_FAILED: return "SANITIZE_FAILED: The most recent sanitize operation failed and no recovery actions has been successfully completed";
case NVME_SC_SANITIZE_IN_PROGRESS: return "SANITIZE_IN_PROGRESS: The requested function is prohibited while a sanitize operation is in progress";
case NVME_SC_LBA_RANGE: return "LBA_RANGE: The command references a LBA that exceeds the size of the namespace";
+ case NVME_SC_NS_WRITE_PROTECTED: return "NS_WRITE_PROTECTED: The command is prohibited while the namespace is write protected by the host.";
case NVME_SC_CAP_EXCEEDED: return "CAP_EXCEEDED: The execution of the command has caused the capacity of the namespace to be exceeded";
case NVME_SC_NS_NOT_READY: return "NS_NOT_READY: The namespace is not ready to be accessed";
case NVME_SC_RESERVATION_CONFLICT: return "RESERVATION_CONFLICT: The command was aborted due to a conflict with a reservation held on the accessed namespace";
case NVME_FEAT_RESV_PERSIST:
printf("\tPersist Through Power Loss (PTPL): %s\n", (result & 0x00000001) ? "True":"False");
break;
+ case NVME_FEAT_WRITE_PROTECT:
+ printf("\tNamespace Write Protect: %s\n", result != NVME_NS_NO_WRITE_PROTECT ? "True" : "False");
+ break;
case NVME_FEAT_TIMESTAMP:
show_timestamp((struct nvme_timestamp *)buf);
break;
json_object_add_value_int(root, "nabspf", le16_to_cpu(ns->nabspf));
json_object_add_value_int(root, "noiob", le16_to_cpu(ns->noiob));
json_object_add_value_float(root, "nvmcap", nvmcap);
+ json_object_add_value_int(root, "nsattr", ns->nsattr);
json_object_add_value_int(root, "nvmsetid", le16_to_cpu(ns->nvmsetid));
json_object_add_value_int(root, "endgid", le16_to_cpu(ns->endgid));
json_object_add_value_int(root, "awun", le16_to_cpu(ctrl->awun));
json_object_add_value_int(root, "awupf", le16_to_cpu(ctrl->awupf));
json_object_add_value_int(root, "nvscc", ctrl->nvscc);
+ json_object_add_value_int(root, "nwpc", ctrl->nwpc);
json_object_add_value_int(root, "acwu", le16_to_cpu(ctrl->acwu));
json_object_add_value_int(root, "sgls", le32_to_cpu(ctrl->sgls));