|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
| 2 | + |
| 3 | +#include "lm-print.h" |
| 4 | + |
| 5 | +#include <inttypes.h> |
| 6 | + |
| 7 | +#include "common.h" |
| 8 | +#include "util/types.h" |
| 9 | + |
| 10 | +static struct lm_print_ops stdout_print_ops; |
| 11 | + |
| 12 | +static void stdout_controller_state_data(struct nvme_lm_controller_state_data *data, size_t len, |
| 13 | + __u32 offset) |
| 14 | +{ |
| 15 | + if (offset) { |
| 16 | + fprintf(stderr, "cannot understand non-zero offset\n"); |
| 17 | + return; |
| 18 | + } |
| 19 | + |
| 20 | + int human = stdout_print_ops.flags & VERBOSE; |
| 21 | + |
| 22 | + if (sizeof(struct nvme_lm_controller_state_data_header) <= len) { |
| 23 | + printf("Header:\n"); |
| 24 | + printf("%-45s: 0x%x\n", "Version (VER)", data->hdr.ver); |
| 25 | + printf("%-45s: 0x%x\n", "Controller State Attributes (CSATTR)", data->hdr.csattr); |
| 26 | + if (human) |
| 27 | + printf(" [0:0] : 0x%x Controller %sSuspended\n", |
| 28 | + data->hdr.csattr & 1, data->hdr.csattr & 1 ? "" : "NOT "); |
| 29 | + printf("%-45s: %s\n", "NVMe Controller State Size (NVMECSS)", |
| 30 | + uint128_t_to_string(le128_to_cpu(data->hdr.nvmecss))); |
| 31 | + printf("%-45s: %s\n", "Vendor Specific Size (VSS)", |
| 32 | + uint128_t_to_string(le128_to_cpu(data->hdr.vss))); |
| 33 | + |
| 34 | + len -= sizeof(struct nvme_lm_controller_state_data_header); |
| 35 | + } else { |
| 36 | + fprintf(stderr, "WARNING: Header truncated\n"); |
| 37 | + len = 0; |
| 38 | + } |
| 39 | + |
| 40 | + if (!len) |
| 41 | + return; |
| 42 | + |
| 43 | + if (sizeof(struct nvme_lm_nvme_controller_state_data_header) <= len) { |
| 44 | + int niosq = data->data.hdr.niosq; |
| 45 | + int niocq = data->data.hdr.niocq; |
| 46 | + |
| 47 | + printf("\nNVMe Controller State Data Structure:\n"); |
| 48 | + printf("%-45s: 0x%x\n", "Version (VER)", |
| 49 | + le16_to_cpu(data->data.hdr.ver)); |
| 50 | + printf("%-45s: %d\n", "Number of I/O Submission Queues (NIOSQ)", |
| 51 | + le16_to_cpu(niosq)); |
| 52 | + printf("%-45s: %d\n", "Number of I/O Completion Queues (NIOCQ)", |
| 53 | + le16_to_cpu(niocq)); |
| 54 | + |
| 55 | + len -= sizeof(struct nvme_lm_nvme_controller_state_data_header); |
| 56 | + |
| 57 | + if (len < niosq * sizeof(struct nvme_lm_io_submission_queue_data)) { |
| 58 | + fprintf(stderr, "WARNING: I/O Submission Queues truncated\n"); |
| 59 | + niosq = len / sizeof(struct nvme_lm_io_submission_queue_data); |
| 60 | + } |
| 61 | + |
| 62 | + for (int i = 0; i < niosq; ++i) { |
| 63 | + struct nvme_lm_io_submission_queue_data *sq = &(data->data.sqs[i]); |
| 64 | + __u16 iosqa = le16_to_cpu(sq->iosqa); |
| 65 | + |
| 66 | + printf("\nNVMe I/O Submission Queue Data [%d]:\n", i); |
| 67 | + printf("%-45s: 0x%"PRIu64"\n", "PRP Entry 1 (IOSQPRP1)", |
| 68 | + le64_to_cpu(sq->iosqprp1)); |
| 69 | + printf("%-45s: 0x%x\n", "Queue Size (IOSQQSIZE)", |
| 70 | + le16_to_cpu(sq->iosqqsize)); |
| 71 | + printf("%-45s: 0x%x\n", "Identifier (IOSQQID)", |
| 72 | + le16_to_cpu(sq->iosqqid)); |
| 73 | + printf("%-45s: 0x%x\n", "Completion Queue Identifier (IOSQCQID)", |
| 74 | + le16_to_cpu(sq->iosqcqid)); |
| 75 | + printf("%-45s: 0x%x\n", "Attributes (IOSQA)", iosqa); |
| 76 | + if (human) { |
| 77 | + printf(" [2:1] : 0x%x Queue Priority (IOSQQPRIO)\n", |
| 78 | + NVME_GET(iosqa, LM_IOSQPRIO)); |
| 79 | + printf(" [0:0] : 0x%x Queue %sPhysically Contiguous (IOSQPC)\n", |
| 80 | + NVME_GET(iosqa, LM_IOSQPC), |
| 81 | + NVME_GET(iosqa, LM_IOSQPC) ? "" : "NOT "); |
| 82 | + } |
| 83 | + printf("%-45s: 0x%x\n", "I/O Submission Queue Head Pointer (IOSQHP)", |
| 84 | + le16_to_cpu(sq->iosqhp)); |
| 85 | + printf("%-45s: 0x%x\n", "I/O Submission Queue Tail Pointer (IOSQTP)", |
| 86 | + le16_to_cpu(sq->iosqtp)); |
| 87 | + } |
| 88 | + |
| 89 | + len -= niosq * sizeof(struct nvme_lm_io_submission_queue_data); |
| 90 | + |
| 91 | + if (len < niocq * sizeof(struct nvme_lm_io_completion_queue_data)) { |
| 92 | + fprintf(stderr, "WARNING: I/O Completion Queues truncated\n"); |
| 93 | + niocq = len / sizeof(struct nvme_lm_io_completion_queue_data); |
| 94 | + } |
| 95 | + |
| 96 | + for (int i = 0; i < niocq; ++i) { |
| 97 | + struct nvme_lm_io_completion_queue_data *cq = &data->data.cqs[niosq + i]; |
| 98 | + __u32 iocqa = le32_to_cpu(cq->iocqa); |
| 99 | + |
| 100 | + printf("\nNVMe I/O Completion Queue Data [%d]:\n", i); |
| 101 | + printf("%-45s: 0x%"PRIu64"\n", "I/O Completion PRP Entry 1 (IOCQPRP1)", |
| 102 | + le64_to_cpu(cq->iocqprp1)); |
| 103 | + printf("%-45s: 0x%x\n", "I/O Completion Queue Size (IOCQQSIZE)", |
| 104 | + le16_to_cpu(cq->iocqqsize)); |
| 105 | + printf("%-45s: 0x%x\n", "I/O Completion Queue Identifier (IOCQQID)", |
| 106 | + le16_to_cpu(cq->iocqqid)); |
| 107 | + printf("%-45s: 0x%x\n", "I/O Completion Queue Head Pointer (IOSQHP)", |
| 108 | + le16_to_cpu(cq->iocqhp)); |
| 109 | + printf("%-45s: 0x%x\n", "I/O Completion Queue Tail Pointer (IOSQTP)", |
| 110 | + le16_to_cpu(cq->iocqtp)); |
| 111 | + printf("%-45s: 0x%x\n", "I/O Completion Queue Attributes (IOCQA)", iocqa); |
| 112 | + if (human) { |
| 113 | + printf(" [31:16] : 0x%x I/O Completion Queue Interrupt Vector " |
| 114 | + "(IOCQIV)\n", |
| 115 | + NVME_GET(iocqa, LM_IOCQIEN)); |
| 116 | + printf(" [2:2] : 0x%x Slot 0 Phase Tag (S0PT)\n", |
| 117 | + NVME_GET(iocqa, LM_S0PT)); |
| 118 | + printf(" [1:1] : 0x%x Interrupts %sEnabled (IOCQIEN)\n", |
| 119 | + NVME_GET(iocqa, LM_IOCQIEN), |
| 120 | + NVME_GET(iocqa, LM_IOCQIEN) ? "" : "NOT "); |
| 121 | + printf(" [0:0] : 0x%x Queue %sPhysically Contiguous (IOCQPC)\n", |
| 122 | + NVME_GET(iocqa, LM_IOCQPC), |
| 123 | + NVME_GET(iocqa, LM_IOCQPC) ? "" : "NOT "); |
| 124 | + } |
| 125 | + } |
| 126 | + } else |
| 127 | + fprintf(stderr, "WARNING: NVMe Controller State Data Structure truncated\n"); |
| 128 | +} |
| 129 | + |
| 130 | +static void stdout_show_controller_data_queue(struct nvme_lm_ctrl_data_queue_fid_data *data) |
| 131 | +{ |
| 132 | + printf("Head Pointer: 0x%x\n", le32_to_cpu(data->hp)); |
| 133 | + printf("Tail Pointer Trigger: 0x%x\n", le32_to_cpu(data->tpt)); |
| 134 | +} |
| 135 | + |
| 136 | +static struct lm_print_ops stdout_print_ops = { |
| 137 | + .controller_state_data = stdout_controller_state_data, |
| 138 | + .controller_data_queue = stdout_show_controller_data_queue |
| 139 | +}; |
| 140 | + |
| 141 | +struct lm_print_ops *lm_get_stdout_print_ops(nvme_print_flags_t flags) |
| 142 | +{ |
| 143 | + stdout_print_ops.flags = flags; |
| 144 | + return &stdout_print_ops; |
| 145 | +} |
0 commit comments