nvme/identify: add -x flag to dump data as hex
This allows identify to print the raw data so that the user can look up fields that aren't yet formatted in a human-readable way. Change-Id: If3db1fed85fee06c8b8c18246a2ea253b1e6ae13 Signed-off-by: Daniel Verkamp <daniel.verkamp@intel.com>
This commit is contained in:
parent
8fc1f41aba
commit
4e85224e3e
@ -32,6 +32,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
#include <pciaccess.h>
|
#include <pciaccess.h>
|
||||||
|
|
||||||
@ -56,6 +57,54 @@ static struct feature features[256];
|
|||||||
|
|
||||||
static struct nvme_health_information_page *health_page;
|
static struct nvme_health_information_page *health_page;
|
||||||
|
|
||||||
|
static bool g_hex_dump = false;
|
||||||
|
|
||||||
|
static void
|
||||||
|
hex_dump(const void *data, size_t size)
|
||||||
|
{
|
||||||
|
size_t offset = 0, i;
|
||||||
|
const uint8_t *bytes = data;
|
||||||
|
|
||||||
|
while (size) {
|
||||||
|
printf("%08zX:", offset);
|
||||||
|
|
||||||
|
for (i = 0; i < 16; i++) {
|
||||||
|
if (i == 8) {
|
||||||
|
printf("-");
|
||||||
|
} else {
|
||||||
|
printf(" ");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i < size) {
|
||||||
|
printf("%02X", bytes[offset + i]);
|
||||||
|
} else {
|
||||||
|
printf(" ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
printf(" ");
|
||||||
|
|
||||||
|
for (i = 0; i < 16; i++) {
|
||||||
|
if (i < size) {
|
||||||
|
if (bytes[offset + i] > 0x20 && bytes[offset + i] < 0x7F) {
|
||||||
|
printf("%c", bytes[offset + i]);
|
||||||
|
} else {
|
||||||
|
printf(".");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("\n");
|
||||||
|
|
||||||
|
offset += 16;
|
||||||
|
if (size > 16) {
|
||||||
|
size -= 16;
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
get_feature_completion(void *cb_arg, const struct nvme_completion *cpl)
|
get_feature_completion(void *cb_arg, const struct nvme_completion *cpl)
|
||||||
{
|
{
|
||||||
@ -198,6 +247,12 @@ print_namespace(struct nvme_namespace *ns)
|
|||||||
flags = nvme_ns_get_flags(ns);
|
flags = nvme_ns_get_flags(ns);
|
||||||
|
|
||||||
printf("Namespace ID:%d\n", nvme_ns_get_id(ns));
|
printf("Namespace ID:%d\n", nvme_ns_get_id(ns));
|
||||||
|
|
||||||
|
if (g_hex_dump) {
|
||||||
|
hex_dump(nsdata, sizeof(*nsdata));
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
|
||||||
printf("Deallocate: %s\n",
|
printf("Deallocate: %s\n",
|
||||||
(flags & NVME_NS_DEALLOCATE_SUPPORTED) ? "Supported" : "Not Supported");
|
(flags & NVME_NS_DEALLOCATE_SUPPORTED) ? "Supported" : "Not Supported");
|
||||||
printf("Flush: %s\n",
|
printf("Flush: %s\n",
|
||||||
@ -238,6 +293,12 @@ print_controller(struct nvme_controller *ctrlr, struct pci_device *pci_dev)
|
|||||||
printf("NVMe Controller at PCI bus %d, device %d, function %d\n",
|
printf("NVMe Controller at PCI bus %d, device %d, function %d\n",
|
||||||
pci_dev->bus, pci_dev->dev, pci_dev->func);
|
pci_dev->bus, pci_dev->dev, pci_dev->func);
|
||||||
printf("=====================================================\n");
|
printf("=====================================================\n");
|
||||||
|
|
||||||
|
if (g_hex_dump) {
|
||||||
|
hex_dump(cdata, sizeof(*cdata));
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
|
||||||
printf("Controller Capabilities/Features\n");
|
printf("Controller Capabilities/Features\n");
|
||||||
printf("================================\n");
|
printf("================================\n");
|
||||||
printf("Vendor ID: %04x\n", cdata->vid);
|
printf("Vendor ID: %04x\n", cdata->vid);
|
||||||
@ -379,6 +440,12 @@ print_controller(struct nvme_controller *ctrlr, struct pci_device *pci_dev)
|
|||||||
if (features[NVME_FEAT_TEMPERATURE_THRESHOLD].valid && health_page) {
|
if (features[NVME_FEAT_TEMPERATURE_THRESHOLD].valid && health_page) {
|
||||||
printf("Health Information\n");
|
printf("Health Information\n");
|
||||||
printf("==================\n");
|
printf("==================\n");
|
||||||
|
|
||||||
|
if (g_hex_dump) {
|
||||||
|
hex_dump(health_page, sizeof(*health_page));
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
|
||||||
printf("Critical Warnings:\n");
|
printf("Critical Warnings:\n");
|
||||||
printf(" Available Spare Space: %s\n",
|
printf(" Available Spare Space: %s\n",
|
||||||
health_page->critical_warning.bits.available_spare ? "WARNING" : "OK");
|
health_page->critical_warning.bits.available_spare ? "WARNING" : "OK");
|
||||||
@ -436,6 +503,36 @@ print_controller(struct nvme_controller *ctrlr, struct pci_device *pci_dev)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
usage(const char *program_name)
|
||||||
|
{
|
||||||
|
printf("%s [options]", program_name);
|
||||||
|
printf("\n");
|
||||||
|
printf("options:\n");
|
||||||
|
printf(" -x print hex dump of raw data\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
parse_args(int argc, char **argv)
|
||||||
|
{
|
||||||
|
int op;
|
||||||
|
|
||||||
|
while ((op = getopt(argc, argv, "x")) != -1) {
|
||||||
|
switch (op) {
|
||||||
|
case 'x':
|
||||||
|
g_hex_dump = true;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
usage(argv[0]);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
optind = 1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static const char *ealargs[] = {
|
static const char *ealargs[] = {
|
||||||
"identify",
|
"identify",
|
||||||
"-c 0x1",
|
"-c 0x1",
|
||||||
@ -449,6 +546,11 @@ int main(int argc, char **argv)
|
|||||||
struct pci_id_match match;
|
struct pci_id_match match;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
|
rc = parse_args(argc, argv);
|
||||||
|
if (rc != 0) {
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
rc = rte_eal_init(sizeof(ealargs) / sizeof(ealargs[0]),
|
rc = rte_eal_init(sizeof(ealargs) / sizeof(ealargs[0]),
|
||||||
(char **)(void *)(uintptr_t)ealargs);
|
(char **)(void *)(uintptr_t)ealargs);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user