|
10 | 10 | #include "suffix.h" |
11 | 11 | #include "common.h" |
12 | 12 |
|
| 13 | +static const uint8_t zero_uuid[16] = { |
| 14 | + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 |
| 15 | +}; |
| 16 | + |
| 17 | +static const uint8_t invalid_uuid[16] = { |
| 18 | + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF |
| 19 | +}; |
| 20 | + |
13 | 21 | static const char *nvme_ana_state_to_string(enum nvme_ana_state state) |
14 | 22 | { |
15 | 23 | switch (state) { |
@@ -102,6 +110,27 @@ static void format(char *formatter, size_t fmt_sz, char *tofmt, size_t tofmtsz) |
102 | 110 | } |
103 | 111 | } |
104 | 112 |
|
| 113 | +static const char *nvme_uuid_to_string(uuid_t uuid) |
| 114 | +{ |
| 115 | + /* large enough to hold uuid str (37) + null-termination byte */ |
| 116 | + static char uuid_str[40]; |
| 117 | +#ifdef LIBUUID |
| 118 | + uuid_unparse_lower(uuid, uuid_str); |
| 119 | +#else |
| 120 | + static const char *hex_digits = "0123456789abcdef"; |
| 121 | + char *p = &uuid_str[0]; |
| 122 | + int i; |
| 123 | + for (i = 0; i < 16; i++) { |
| 124 | + *p++ = hex_digits[(uuid.b[i] & 0xf0) >> 4]; |
| 125 | + *p++ = hex_digits[uuid.b[i] & 0x0f]; |
| 126 | + if (i == 3 || i == 5 || i == 7 || i == 9) |
| 127 | + *p++ = '-'; |
| 128 | + } |
| 129 | + *p = '\0'; |
| 130 | +#endif |
| 131 | + return uuid_str; |
| 132 | +} |
| 133 | + |
105 | 134 | static void show_nvme_id_ctrl_cmic(__u8 cmic) |
106 | 135 | { |
107 | 136 | __u8 rsvd = (cmic & 0xF0) >> 4; |
@@ -155,19 +184,29 @@ static void show_nvme_id_ctrl_oaes(__le32 ctrl_oaes) |
155 | 184 | static void show_nvme_id_ctrl_ctratt(__le32 ctrl_ctratt) |
156 | 185 | { |
157 | 186 | __u32 ctratt = le32_to_cpu(ctrl_ctratt); |
158 | | - __u32 rsvd0 = ctratt >> 8; |
| 187 | + __u32 rsvd = ctratt >> 10; |
159 | 188 | __u32 hostid128 = (ctratt & NVME_CTRL_CTRATT_128_ID) >> 0; |
160 | 189 | __u32 psp = (ctratt & NVME_CTRL_CTRATT_NON_OP_PSP) >> 1; |
161 | 190 | __u32 sets = (ctratt & NVME_CTRL_CTRATT_NVM_SETS) >> 2; |
162 | 191 | __u32 rrl = (ctratt & NVME_CTRL_CTRATT_READ_RECV_LVLS) >> 3; |
163 | 192 | __u32 eg = (ctratt & NVME_CTRL_CTRATT_ENDURANCE_GROUPS) >> 4; |
164 | 193 | __u32 iod = (ctratt & NVME_CTRL_CTRATT_PREDICTABLE_LAT) >> 5; |
165 | 194 | __u32 ng = (ctratt & NVME_CTRL_CTRATT_NAMESPACE_GRANULARITY) >> 7; |
| 195 | + __u32 uuidlist = (ctratt & NVME_CTRL_CTRATT_UUID_LIST) >> 9; |
| 196 | + __u32 rsvd6 = (ctratt & 0x00000040) >> 6; |
| 197 | + __u32 rsvd8 = (ctratt & 0x00000100) >> 8; |
166 | 198 |
|
167 | | - if (rsvd0) |
168 | | - printf(" [31:8] : %#x\tReserved\n", rsvd0); |
| 199 | + if (rsvd) |
| 200 | + printf(" [31:10] : %#x\tReserved\n", rsvd); |
| 201 | + |
| 202 | + printf(" [9:9] : %#x\tUUID List %sSupported\n", |
| 203 | + uuidlist, uuidlist ? "" : "Not "); |
| 204 | + if (rsvd8) |
| 205 | + printf(" [8:8] : %#x\tReserved\n", rsvd8); |
169 | 206 | printf(" [7:7] : %#x\tNamespace Granularity %sSupported\n", |
170 | 207 | ng, ng ? "" : "Not "); |
| 208 | + if (rsvd6) |
| 209 | + printf(" [6:6] : %#x\tReserved\n", rsvd6); |
171 | 210 | printf(" [5:5] : %#x\tPredictable Latency Mode %sSupported\n", |
172 | 211 | iod, iod ? "" : "Not "); |
173 | 212 | printf(" [4:4] : %#x\tEndurance Groups %sSupported\n", |
@@ -1316,6 +1355,69 @@ void json_nvme_id_ns_granularity_list(const struct nvme_id_ns_granularity_list * |
1316 | 1355 | json_free_object(root); |
1317 | 1356 | } |
1318 | 1357 |
|
| 1358 | +void show_nvme_id_uuid_list(const struct nvme_id_uuid_list *uuid_list, unsigned int flags) |
| 1359 | +{ |
| 1360 | + int i, human = flags & HUMAN; |
| 1361 | + /* The 0th entry is reserved */ |
| 1362 | + for (i = 1; i < NVME_MAX_UUID_ENTRIES; i++) { |
| 1363 | + uuid_t uuid; |
| 1364 | + char *association = ""; |
| 1365 | + uint8_t identifier_association = uuid_list->entry[i].header & 0x3; |
| 1366 | + /* The list is terminated by a zero UUID value */ |
| 1367 | + if (memcmp(uuid_list->entry[i].uuid, zero_uuid, sizeof(zero_uuid)) == 0) |
| 1368 | + break; |
| 1369 | + memcpy(&uuid, uuid_list->entry[i].uuid, sizeof(uuid)); |
| 1370 | + if (human) { |
| 1371 | + switch (identifier_association) { |
| 1372 | + case 0x0: |
| 1373 | + association = "No association reported"; |
| 1374 | + break; |
| 1375 | + case 0x1: |
| 1376 | + association = "associated with PCI Vendor ID"; |
| 1377 | + break; |
| 1378 | + case 0x2: |
| 1379 | + association = "associated with PCI Subsystem Vendor ID"; |
| 1380 | + break; |
| 1381 | + default: |
| 1382 | + association = "Reserved"; |
| 1383 | + break; |
| 1384 | + } |
| 1385 | + } |
| 1386 | + printf(" Entry[%3d]\n", i); |
| 1387 | + printf(".................\n"); |
| 1388 | + printf("association : 0x%x %s\n", identifier_association, association); |
| 1389 | + printf("UUID : %s", nvme_uuid_to_string(uuid)); |
| 1390 | + if (memcmp(uuid_list->entry[i].uuid, invalid_uuid, sizeof(zero_uuid)) == 0) |
| 1391 | + printf(" (Invalid UUID)"); |
| 1392 | + printf("\n.................\n"); |
| 1393 | + } |
| 1394 | +} |
| 1395 | + |
| 1396 | +void json_nvme_id_uuid_list(struct nvme_id_uuid_list *uuid_list) |
| 1397 | +{ |
| 1398 | + struct json_object *root; |
| 1399 | + struct json_array *entries; |
| 1400 | + int i; |
| 1401 | + root = json_create_object(); |
| 1402 | + entries = json_create_array(); |
| 1403 | + /* The 0th entry is reserved */ |
| 1404 | + for (i = 1; i < NVME_MAX_UUID_ENTRIES; i++) { |
| 1405 | + uuid_t uuid; |
| 1406 | + struct json_object *entry = json_create_object(); |
| 1407 | + /* The list is terminated by a zero UUID value */ |
| 1408 | + if (memcmp(uuid_list->entry[i].uuid, zero_uuid, sizeof(zero_uuid)) == 0) |
| 1409 | + break; |
| 1410 | + memcpy(&uuid, uuid_list->entry[i].uuid, sizeof(uuid)); |
| 1411 | + json_object_add_value_int(entry, "association", uuid_list->entry[i].header & 0x3); |
| 1412 | + json_object_add_value_string(entry, "uuid", nvme_uuid_to_string(uuid)); |
| 1413 | + json_array_add_value_object(entries, entry); |
| 1414 | + } |
| 1415 | + json_object_add_value_array(root, "UUID-list", entries); |
| 1416 | + json_print_object(root, NULL); |
| 1417 | + printf("\n"); |
| 1418 | + json_free_object(root); |
| 1419 | +} |
| 1420 | + |
1319 | 1421 | void show_error_log(struct nvme_error_log_page *err_log, int entries, const char *devname) |
1320 | 1422 | { |
1321 | 1423 | int i; |
@@ -1439,6 +1541,7 @@ static void show_effects_log_human(__u32 effect) |
1439 | 1541 | printf(" NCC%s", (effect & NVME_CMD_EFFECTS_NCC) ? set : clr); |
1440 | 1542 | printf(" NIC%s", (effect & NVME_CMD_EFFECTS_NIC) ? set : clr); |
1441 | 1543 | printf(" CCC%s", (effect & NVME_CMD_EFFECTS_CCC) ? set : clr); |
| 1544 | + printf(" USS%s", (effect & NVME_CMD_EFFECTS_UUID_SEL) ? set : clr); |
1442 | 1545 |
|
1443 | 1546 | if ((effect & NVME_CMD_EFFECTS_CSE_MASK) >> 16 == 0) |
1444 | 1547 | printf(" No command restriction\n"); |
|
0 commit comments