--- /dev/null
+nvme-id-ns(1)
+=============
+
+NAME
+----
+nvme-show-regs - Reads and shows the defined NVMe controller registers.
+
+SYNOPSIS
+--------
+[verse]
+'nvme show-regs' <device>
+
+DESCRIPTION
+-----------
+For the NVMe device given, sends an identify namespace command and
+provides the result and returned structure.
+
+The <device> parameter is mandatory and must be the nvme admin character
+device (ex: /dev/nvme0). The program uses knowledge of the sysfs layout
+to map the device to the pci resource stored there and mmaps the memory
+to get access to the registers.
+
+EXAMPLES
+--------
+* Has the program map the nvme pci controller registers and prints them
+in a human readable format:
++
+------------
+# nvme show-regs /dev/nvme0
+------------
+
+NVME
+----
+Part of the nvme-user suite
__u32 result;
};
+struct nvme_bar {
+ __u64 cap; /* Controller Capabilities */
+ __u32 vs; /* Version */
+ __u32 intms; /* Interrupt Mask Set */
+ __u32 intmc; /* Interrupt Mask Clear */
+ __u32 cc; /* Controller Configuration */
+ __u32 rsvd1; /* Reserved */
+ __u32 csts; /* Controller Status */
+ __u32 nssr; /* NVM Subsystem Reset */
+ __u32 aqa; /* Admin Queue Attributes */
+ __u64 asq; /* Admin SQ Base Address */
+ __u64 acq; /* Admin CQ Base Address */
+ __u32 cmbloc; /* Controller Memory Buffer Location */
+ __u32 cmbsz; /* Controller Memory Buffer Size */
+};
+
#define nvme_admin_cmd nvme_passthru_cmd
#define NVME_IOCTL_ID _IO('N', 0x40)
#include <linux/fs.h>
#include <sys/ioctl.h>
+#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
ENTRY(RESV_REPORT, "resv-report", "Submit a Reservation Report, return results", resv_report) \
ENTRY(FLUSH, "flush", "Submit a Flush command, return results", flush) \
ENTRY(COMPARE, "compare", "Submit a Comapre command, return results", compare) \
+ ENTRY(REGISTERS, "show-regs", "Shows the controller registers. Requires admin character device", show_registers) \
ENTRY(HELP, "help", "Display this help", help)
#define ENTRY(i, n, h, f) \
return err;
}
+static int show_registers(int argc, char **argv)
+{
+ int opt, long_index, pci_fd;
+ char *base, path[512];
+ void *membase;
+ struct nvme_bar *bar;
+ static struct option opts[] = {};
+
+ while ((opt = getopt_long(argc, (char **)argv, "", opts,
+ &long_index)) != -1);
+ get_dev(optind, argc, argv);
+
+ if (!S_ISCHR(nvme_stat.st_mode)) {
+ fprintf(stderr, "%s is not character device\n", devicename);
+ exit(ENODEV);
+ }
+
+ base = basename(devicename);
+ sprintf(path, "/sys/class/misc/%s/device/resource0", base);
+ pci_fd = open(path, O_RDONLY);
+ if (pci_fd < 0) {
+ fprintf(stderr, "%s did not find a pci resource\n", devicename);
+ exit(ENODEV);
+ }
+
+ membase = mmap(0, getpagesize(), PROT_READ, MAP_SHARED, pci_fd, 0);
+ if (!membase) {
+ fprintf(stderr, "%s failed to map\n", devicename);
+ exit(ENODEV);
+ }
+
+ bar = membase;
+ printf("cap : %"PRIx64"\n", (uint64_t)bar->cap);
+ printf("version : %x\n", bar->vs);
+ printf("intms : %x\n", bar->intms);
+ printf("intmc : %x\n", bar->intmc);
+ printf("cc : %x\n", bar->cc);
+ printf("csts : %x\n", bar->csts);
+ printf("nssr : %x\n", bar->nssr);
+ printf("aqa : %x\n", bar->aqa);
+ printf("asq : %"PRIx64"\n", (uint64_t)bar->asq);
+ printf("acq : %"PRIx64"\n", (uint64_t)bar->acq);
+ printf("cmbloc : %x\n", bar->cmbloc);
+ printf("cmbsz : %x\n", bar->cmbsz);
+
+ return 0;
+}
+
static int format(int argc, char **argv)
{
int opt, err, long_index;
while ((opt = getopt_long(argc, (char **)argv, "n:l:s:p:i:m:", opts,
&long_index)) != -1) {
-
switch (opt) {
case 'n': get_int(optarg, &nsid); break;
case 'l': get_byte(optarg, &lbaf); break;