Changeset View
Changeset View
Standalone View
Standalone View
sbin/nvmecontrol/nvmecontrol.c
Show First 20 Lines • Show All 170 Lines • ▼ Show 20 Lines | get_nsid(int fd, char **ctrlr_str, uint32_t *nsid) | ||||
if (ioctl(fd, NVME_GET_NSID, &gnsid) < 0) | if (ioctl(fd, NVME_GET_NSID, &gnsid) < 0) | ||||
err(EX_OSERR, "NVME_GET_NSID ioctl failed"); | err(EX_OSERR, "NVME_GET_NSID ioctl failed"); | ||||
if (ctrlr_str != NULL) | if (ctrlr_str != NULL) | ||||
*ctrlr_str = strndup(gnsid.cdev, sizeof(gnsid.cdev)); | *ctrlr_str = strndup(gnsid.cdev, sizeof(gnsid.cdev)); | ||||
if (nsid != NULL) | if (nsid != NULL) | ||||
*nsid = gnsid.nsid; | *nsid = gnsid.nsid; | ||||
} | } | ||||
struct nvme_status_string { | |||||
uint16_t sc; | |||||
const char * str; | |||||
}; | |||||
static struct nvme_status_string generic_status[] = { | |||||
{ NVME_SC_SUCCESS, "SUCCESS" }, | |||||
imp: Would these be better as an array? Or as an array of value string pairs? I forget of these are… | |||||
Done Inline ActionsRight, you are correct. static const char * get_status_string(uint16_t sct, uint16_t sc) { struct nvme_status_string *entry; switch (sct) { case NVME_SCT_GENERIC: entry = generic_status; break; case NVME_SCT_COMMAND_SPECIFIC: entry = command_specific_status; break; case NVME_SCT_MEDIA_ERROR: entry = media_error_status; break; case NVME_SCT_PATH_RELATED: entry = path_related_status; break; case NVME_SCT_VENDOR_SPECIFIC: return ("VENDOR SPECIFIC"); default: return ("RESERVED"); } while (entry->sc != 0xFFFF) { if (entry->sc == sc) return (entry->str); entry++; } return (entry->str); } Can I make it non-static? wanpengqian_gmail.com: Right, you are correct.
Actually, I found the `sys/dev/nvme/nvme_qpair.c` has already have… | |||||
{ NVME_SC_INVALID_OPCODE, "INVALID OPCODE" }, | |||||
{ NVME_SC_INVALID_FIELD, "INVALID_FIELD" }, | |||||
{ NVME_SC_COMMAND_ID_CONFLICT, "COMMAND ID CONFLICT" }, | |||||
{ NVME_SC_DATA_TRANSFER_ERROR, "DATA TRANSFER ERROR" }, | |||||
{ NVME_SC_ABORTED_POWER_LOSS, "ABORTED - POWER LOSS" }, | |||||
{ NVME_SC_INTERNAL_DEVICE_ERROR, "INTERNAL DEVICE ERROR" }, | |||||
{ NVME_SC_ABORTED_BY_REQUEST, "ABORTED - BY REQUEST" }, | |||||
{ NVME_SC_ABORTED_SQ_DELETION, "ABORTED - SQ DELETION" }, | |||||
{ NVME_SC_ABORTED_FAILED_FUSED, "ABORTED - FAILED FUSED" }, | |||||
{ NVME_SC_ABORTED_MISSING_FUSED, "ABORTED - MISSING FUSED" }, | |||||
{ NVME_SC_INVALID_NAMESPACE_OR_FORMAT, "INVALID NAMESPACE OR FORMAT" }, | |||||
{ NVME_SC_COMMAND_SEQUENCE_ERROR, "COMMAND SEQUENCE ERROR" }, | |||||
{ NVME_SC_INVALID_SGL_SEGMENT_DESCR, "INVALID SGL SEGMENT DESCRIPTOR" }, | |||||
{ NVME_SC_INVALID_NUMBER_OF_SGL_DESCR, "INVALID NUMBER OF SGL DESCRIPTORS" }, | |||||
{ NVME_SC_DATA_SGL_LENGTH_INVALID, "DATA SGL LENGTH INVALID" }, | |||||
{ NVME_SC_METADATA_SGL_LENGTH_INVALID, "METADATA SGL LENGTH INVALID" }, | |||||
{ NVME_SC_SGL_DESCRIPTOR_TYPE_INVALID, "SGL DESCRIPTOR TYPE INVALID" }, | |||||
{ NVME_SC_INVALID_USE_OF_CMB, "INVALID USE OF CONTROLLER MEMORY BUFFER" }, | |||||
{ NVME_SC_PRP_OFFET_INVALID, "PRP OFFET INVALID" }, | |||||
{ NVME_SC_ATOMIC_WRITE_UNIT_EXCEEDED, "ATOMIC WRITE UNIT EXCEEDED" }, | |||||
{ NVME_SC_OPERATION_DENIED, "OPERATION DENIED" }, | |||||
{ NVME_SC_SGL_OFFSET_INVALID, "SGL OFFSET INVALID" }, | |||||
{ NVME_SC_HOST_ID_INCONSISTENT_FORMAT, "HOST IDENTIFIER INCONSISTENT FORMAT" }, | |||||
{ NVME_SC_KEEP_ALIVE_TIMEOUT_EXPIRED, "KEEP ALIVE TIMEOUT EXPIRED" }, | |||||
{ NVME_SC_KEEP_ALIVE_TIMEOUT_INVALID, "KEEP ALIVE TIMEOUT INVALID" }, | |||||
{ NVME_SC_ABORTED_DUE_TO_PREEMPT, "COMMAND ABORTED DUE TO PREEMPT AND ABORT" }, | |||||
{ NVME_SC_SANITIZE_FAILED, "SANITIZE FAILED" }, | |||||
{ NVME_SC_SANITIZE_IN_PROGRESS, "SANITIZE IN PROGRESS" }, | |||||
{ NVME_SC_SGL_DATA_BLOCK_GRAN_INVALID, "SGL_DATA_BLOCK_GRANULARITY_INVALID" }, | |||||
{ NVME_SC_NOT_SUPPORTED_IN_CMB, "COMMAND NOT SUPPORTED FOR QUEUE IN CMB" }, | |||||
{ NVME_SC_NAMESPACE_IS_WRITE_PROTECTED, "NAMESPACE IS WRITE PROTECTED" }, | |||||
{ NVME_SC_COMMAND_INTERRUPTED, "COMMAND INTERRUPTED" }, | |||||
{ NVME_SC_TRANSIENT_TRANSPORT_ERROR, "TRANSIENT TRANSPORT ERROR" }, | |||||
{ NVME_SC_LBA_OUT_OF_RANGE, "LBA OUT OF RANGE" }, | |||||
{ NVME_SC_CAPACITY_EXCEEDED, "CAPACITY EXCEEDED" }, | |||||
{ NVME_SC_NAMESPACE_NOT_READY, "NAMESPACE NOT READY" }, | |||||
{ NVME_SC_RESERVATION_CONFLICT, "RESERVATION CONFLICT" }, | |||||
{ NVME_SC_FORMAT_IN_PROGRESS, "FORMAT IN PROGRESS" }, | |||||
{ 0xFFFF, "GENERIC" } | |||||
}; | |||||
static struct nvme_status_string command_specific_status[] = { | |||||
{ NVME_SC_COMPLETION_QUEUE_INVALID, "INVALID COMPLETION QUEUE" }, | |||||
{ NVME_SC_INVALID_QUEUE_IDENTIFIER, "INVALID QUEUE IDENTIFIER" }, | |||||
{ NVME_SC_MAXIMUM_QUEUE_SIZE_EXCEEDED, "MAX QUEUE SIZE EXCEEDED" }, | |||||
{ NVME_SC_ABORT_COMMAND_LIMIT_EXCEEDED, "ABORT CMD LIMIT EXCEEDED" }, | |||||
{ NVME_SC_ASYNC_EVENT_REQUEST_LIMIT_EXCEEDED, "ASYNC LIMIT EXCEEDED" }, | |||||
{ NVME_SC_INVALID_FIRMWARE_SLOT, "INVALID FIRMWARE SLOT" }, | |||||
{ NVME_SC_INVALID_FIRMWARE_IMAGE, "INVALID FIRMWARE IMAGE" }, | |||||
{ NVME_SC_INVALID_INTERRUPT_VECTOR, "INVALID INTERRUPT VECTOR" }, | |||||
{ NVME_SC_INVALID_LOG_PAGE, "INVALID LOG PAGE" }, | |||||
{ NVME_SC_INVALID_FORMAT, "INVALID FORMAT" }, | |||||
{ NVME_SC_FIRMWARE_REQUIRES_RESET, "FIRMWARE REQUIRES RESET" }, | |||||
{ NVME_SC_INVALID_QUEUE_DELETION, "INVALID QUEUE DELETION" }, | |||||
{ NVME_SC_FEATURE_NOT_SAVEABLE, "FEATURE IDENTIFIER NOT SAVEABLE" }, | |||||
{ NVME_SC_FEATURE_NOT_CHANGEABLE, "FEATURE NOT CHANGEABLE" }, | |||||
{ NVME_SC_FEATURE_NOT_NS_SPECIFIC, "FEATURE NOT NAMESPACE SPECIFIC" }, | |||||
{ NVME_SC_FW_ACT_REQUIRES_NVMS_RESET, "FIRMWARE ACTIVATION REQUIRES NVM SUBSYSTEM RESET" }, | |||||
{ NVME_SC_FW_ACT_REQUIRES_RESET, "FIRMWARE ACTIVATION REQUIRES RESET" }, | |||||
{ NVME_SC_FW_ACT_REQUIRES_TIME, "FIRMWARE ACTIVATION REQUIRES MAXIMUM TIME VIOLATION" }, | |||||
{ NVME_SC_FW_ACT_PROHIBITED, "FIRMWARE ACTIVATION PROHIBITED" }, | |||||
{ NVME_SC_OVERLAPPING_RANGE, "OVERLAPPING RANGE" }, | |||||
{ NVME_SC_NS_INSUFFICIENT_CAPACITY, "NAMESPACE INSUFFICIENT CAPACITY" }, | |||||
{ NVME_SC_NS_ID_UNAVAILABLE, "NAMESPACE IDENTIFIER UNAVAILABLE" }, | |||||
{ NVME_SC_NS_ALREADY_ATTACHED, "NAMESPACE ALREADY ATTACHED" }, | |||||
{ NVME_SC_NS_IS_PRIVATE, "NAMESPACE IS PRIVATE" }, | |||||
{ NVME_SC_NS_NOT_ATTACHED, "NS NOT ATTACHED" }, | |||||
{ NVME_SC_THIN_PROV_NOT_SUPPORTED, "THIN PROVISIONING NOT SUPPORTED" }, | |||||
{ NVME_SC_CTRLR_LIST_INVALID, "CONTROLLER LIST INVALID" }, | |||||
{ NVME_SC_SELF_TEST_IN_PROGRESS, "DEVICE SELF-TEST IN PROGRESS" }, | |||||
{ NVME_SC_BOOT_PART_WRITE_PROHIB, "BOOT PARTITION WRITE PROHIBITED" }, | |||||
{ NVME_SC_INVALID_CTRLR_ID, "INVALID CONTROLLER IDENTIFIER" }, | |||||
{ NVME_SC_INVALID_SEC_CTRLR_STATE, "INVALID SECONDARY CONTROLLER STATE" }, | |||||
{ NVME_SC_INVALID_NUM_OF_CTRLR_RESRC, "INVALID NUMBER OF CONTROLLER RESOURCES" }, | |||||
{ NVME_SC_INVALID_RESOURCE_ID, "INVALID RESOURCE IDENTIFIER" }, | |||||
{ NVME_SC_SANITIZE_PROHIBITED_WPMRE, "SANITIZE PROHIBITED WRITE PERSISTENT MEMORY REGION ENABLED" }, | |||||
{ NVME_SC_ANA_GROUP_ID_INVALID, "ANA GROUP IDENTIFIED INVALID" }, | |||||
{ NVME_SC_ANA_ATTACH_FAILED, "ANA ATTACH FAILED" }, | |||||
{ NVME_SC_CONFLICTING_ATTRIBUTES, "CONFLICTING ATTRIBUTES" }, | |||||
{ NVME_SC_INVALID_PROTECTION_INFO, "INVALID PROTECTION INFO" }, | |||||
{ NVME_SC_ATTEMPTED_WRITE_TO_RO_PAGE, "WRITE TO RO PAGE" }, | |||||
{ 0xFFFF, "COMMAND SPECIFIC" } | |||||
}; | |||||
static struct nvme_status_string media_error_status[] = { | |||||
{ NVME_SC_WRITE_FAULTS, "WRITE FAULTS" }, | |||||
{ NVME_SC_UNRECOVERED_READ_ERROR, "UNRECOVERED READ ERROR" }, | |||||
{ NVME_SC_GUARD_CHECK_ERROR, "GUARD CHECK ERROR" }, | |||||
{ NVME_SC_APPLICATION_TAG_CHECK_ERROR, "APPLICATION TAG CHECK ERROR" }, | |||||
{ NVME_SC_REFERENCE_TAG_CHECK_ERROR, "REFERENCE TAG CHECK ERROR" }, | |||||
{ NVME_SC_COMPARE_FAILURE, "COMPARE FAILURE" }, | |||||
{ NVME_SC_ACCESS_DENIED, "ACCESS DENIED" }, | |||||
{ NVME_SC_DEALLOCATED_OR_UNWRITTEN, "DEALLOCATED OR UNWRITTEN LOGICAL BLOCK" }, | |||||
{ 0xFFFF, "MEDIA ERROR" } | |||||
}; | |||||
static struct nvme_status_string path_related_status[] = { | |||||
{ NVME_SC_INTERNAL_PATH_ERROR, "INTERNAL PATH ERROR" }, | |||||
{ NVME_SC_ASYMMETRIC_ACCESS_PERSISTENT_LOSS, "ASYMMETRIC ACCESS PERSISTENT LOSS" }, | |||||
{ NVME_SC_ASYMMETRIC_ACCESS_INACCESSIBLE, "ASYMMETRIC ACCESS INACCESSIBLE" }, | |||||
{ NVME_SC_ASYMMETRIC_ACCESS_TRANSITION, "ASYMMETRIC ACCESS TRANSITION" }, | |||||
{ NVME_SC_CONTROLLER_PATHING_ERROR, "CONTROLLER PATHING ERROR" }, | |||||
{ NVME_SC_HOST_PATHING_ERROR, "HOST PATHING ERROR" }, | |||||
{ NVME_SC_COMMAND_ABOTHED_BY_HOST, "COMMAND ABOTHED BY HOST" }, | |||||
Not Done Inline ActionsSame comment as above. imp: Same comment as above. | |||||
{ 0xFFFF, "PATH RELATED" }, | |||||
}; | |||||
const char * | |||||
get_status_string(uint16_t sct, uint16_t sc) | |||||
{ | |||||
struct nvme_status_string *entry; | |||||
switch (sct) { | |||||
case NVME_SCT_GENERIC: | |||||
entry = generic_status; | |||||
break; | |||||
case NVME_SCT_COMMAND_SPECIFIC: | |||||
entry = command_specific_status; | |||||
break; | |||||
case NVME_SCT_MEDIA_ERROR: | |||||
entry = media_error_status; | |||||
break; | |||||
case NVME_SCT_PATH_RELATED: | |||||
entry = path_related_status; | |||||
break; | |||||
case NVME_SCT_VENDOR_SPECIFIC: | |||||
return ("VENDOR SPECIFIC"); | |||||
default: | |||||
return ("RESERVED"); | |||||
} | |||||
while (entry->sc != 0xFFFF) { | |||||
if (entry->sc == sc) | |||||
return (entry->str); | |||||
entry++; | |||||
} | |||||
return (entry->str); | |||||
} | |||||
int | int | ||||
main(int argc, char *argv[]) | main(int argc, char *argv[]) | ||||
{ | { | ||||
static char dir[MAXPATHLEN]; | static char dir[MAXPATHLEN]; | ||||
cmd_init(); | cmd_init(); | ||||
cmd_load_dir("/lib/nvmecontrol", NULL, NULL); | cmd_load_dir("/lib/nvmecontrol", NULL, NULL); | ||||
snprintf(dir, MAXPATHLEN, "%s/lib/nvmecontrol", getlocalbase()); | snprintf(dir, MAXPATHLEN, "%s/lib/nvmecontrol", getlocalbase()); | ||||
cmd_load_dir(dir, NULL, NULL); | cmd_load_dir(dir, NULL, NULL); | ||||
cmd_dispatch(argc, argv, NULL); | cmd_dispatch(argc, argv, NULL); | ||||
return (0); | return (0); | ||||
} | } |
Would these be better as an array? Or as an array of value string pairs? I forget of these are a 'dense' set of numbers or 'sparse'. A simple array would be better for the former, and a list for the latter.