3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld/*
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld * This file and its contents are supplied under the terms of the
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld * Common Development and Distribution License ("CDDL"), version 1.0.
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld * You may only use this file in accordance with the terms of version
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld * 1.0 of the CDDL.
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld *
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld * A full copy of the text of the CDDL should have accompanied this
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld * source. A copy of the CDDL is also available via the Internet at
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld * http://www.illumos.org/license/CDDL.
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld/*
62c767e5250dc15fcd09bd265883d3e2fe4b3c2dHans Rosenfeld * Copyright 2016 Nexenta Systems, Inc. All rights reserved.
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld/*
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld * NVMe hardware interface
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld#ifndef _NVME_REG_H
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld#define _NVME_REG_H
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld#pragma pack(1)
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld#ifdef __cplusplus
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeldextern "C" {
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld#endif
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld/*
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld * NVMe constants
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld#define NVME_MAX_ADMIN_QUEUE_LEN 4096
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld
24979ca36afa68d08e082148fcbf4c5dc73f7849Hans Rosenfeld/*
24979ca36afa68d08e082148fcbf4c5dc73f7849Hans Rosenfeld * NVMe version
24979ca36afa68d08e082148fcbf4c5dc73f7849Hans Rosenfeld */
24979ca36afa68d08e082148fcbf4c5dc73f7849Hans Rosenfeldtypedef struct {
24979ca36afa68d08e082148fcbf4c5dc73f7849Hans Rosenfeld uint16_t v_minor;
24979ca36afa68d08e082148fcbf4c5dc73f7849Hans Rosenfeld uint16_t v_major;
24979ca36afa68d08e082148fcbf4c5dc73f7849Hans Rosenfeld} nvme_version_t;
24979ca36afa68d08e082148fcbf4c5dc73f7849Hans Rosenfeld
24979ca36afa68d08e082148fcbf4c5dc73f7849Hans Rosenfeld#define NVME_VERSION_ATLEAST(v, maj, min) \
24979ca36afa68d08e082148fcbf4c5dc73f7849Hans Rosenfeld (((v)->v_major) > (maj) || \
24979ca36afa68d08e082148fcbf4c5dc73f7849Hans Rosenfeld ((v)->v_major == (maj) && (v)->v_minor >= (min)))
24979ca36afa68d08e082148fcbf4c5dc73f7849Hans Rosenfeld
24979ca36afa68d08e082148fcbf4c5dc73f7849Hans Rosenfeld#define NVME_VERSION_HIGHER(v, maj, min) \
24979ca36afa68d08e082148fcbf4c5dc73f7849Hans Rosenfeld (((v)->v_major) > (maj) || \
24979ca36afa68d08e082148fcbf4c5dc73f7849Hans Rosenfeld ((v)->v_major == (maj) && (v)->v_minor > (min)))
24979ca36afa68d08e082148fcbf4c5dc73f7849Hans Rosenfeld
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld/*
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld * NVMe registers and register fields
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld#define NVME_REG_CAP 0x0 /* Controller Capabilities */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld#define NVME_REG_VS 0x8 /* Version */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld#define NVME_REG_INTMS 0xc /* Interrupt Mask Set */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld#define NVME_REG_INTMC 0x10 /* Interrupt Mask Clear */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld#define NVME_REG_CC 0x14 /* Controller Configuration */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld#define NVME_REG_CSTS 0x1c /* Controller Status */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld#define NVME_REG_NSSR 0x20 /* NVM Subsystem Reset */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld#define NVME_REG_AQA 0x24 /* Admin Queue Attributes */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld#define NVME_REG_ASQ 0x28 /* Admin Submission Queue */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld#define NVME_REG_ACQ 0x30 /* Admin Completion Qeueu */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld#define NVME_REG_SQTDBL(nvme, n) \
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld (0x1000 + ((2 * (n)) * nvme->n_doorbell_stride))
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld#define NVME_REG_CQHDBL(nvme, n) \
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld (0x1000 + ((2 * (n) + 1) * nvme->n_doorbell_stride))
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld#define NVME_CAP_CSS_NVM 1 /* NVM Command Set */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld#define NVME_CAP_AMS_WRR 1 /* Weighted Round-Robin */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld/* CAP -- Controller Capabilities */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeldtypedef union {
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld struct {
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint16_t cap_mqes; /* Maximum Queue Entries Supported */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint8_t cap_cqr:1; /* Contiguous Queues Required */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint8_t cap_ams:2; /* Arbitration Mechanisms Supported */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint8_t cap_rsvd1:5;
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint8_t cap_to; /* Timeout */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint16_t cap_dstrd:4; /* Doorbell Stride */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint16_t cap_nssrs:1; /* NVM Subsystem Reset Supported */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint16_t cap_css:8; /* Command Sets Supported */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint16_t cap_rsvd2:3;
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint8_t cap_mpsmin:4; /* Memory Page Size Minimum */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint8_t cap_mpsmax:4; /* Memory Page Size Maximum */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint8_t cap_rsvd3;
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld } b;
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint64_t r;
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld} nvme_reg_cap_t;
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld/* VS -- Version */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeldtypedef union {
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld struct {
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint8_t vs_rsvd;
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint8_t vs_mnr; /* Minor Version Number */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint16_t vs_mjr; /* Major Version Number */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld } b;
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint32_t r;
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld} nvme_reg_vs_t;
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld/* CC -- Controller Configuration */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld#define NVME_CC_SHN_NORMAL 1 /* Normal Shutdown Notification */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld#define NVME_CC_SHN_ABRUPT 2 /* Abrupt Shutdown Notification */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeldtypedef union {
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld struct {
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint16_t cc_en:1; /* Enable */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint16_t cc_rsvd1:3;
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint16_t cc_css:3; /* I/O Command Set Selected */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint16_t cc_mps:4; /* Memory Page Size */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint16_t cc_ams:3; /* Arbitration Mechanism Selected */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint16_t cc_shn:2; /* Shutdown Notification */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint8_t cc_iosqes:4; /* I/O Submission Queue Entry Size */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint8_t cc_iocqes:4; /* I/O Completion Queue Entry Size */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint8_t cc_rsvd2;
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld } b;
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint32_t r;
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld} nvme_reg_cc_t;
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld/* CSTS -- Controller Status */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld#define NVME_CSTS_SHN_OCCURING 1 /* Shutdown Processing Occuring */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld#define NVME_CSTS_SHN_COMPLETE 2 /* Shutdown Processing Complete */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeldtypedef union {
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld struct {
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint32_t csts_rdy:1; /* Ready */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint32_t csts_cfs:1; /* Controller Fatal Status */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint32_t csts_shst:2; /* Shutdown Status */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint32_t csts_nssro:1; /* NVM Subsystem Reset Occured */
62c767e5250dc15fcd09bd265883d3e2fe4b3c2dHans Rosenfeld uint32_t csts_rsvd:27;
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld } b;
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint32_t r;
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld} nvme_reg_csts_t;
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld/* NSSR -- NVM Subsystem Reset */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld#define NVME_NSSR_NSSRC 0x4e564d65 /* NSSR magic value */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeldtypedef uint32_t nvme_reg_nssr_t;
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld/* AQA -- Admin Queue Attributes */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeldtypedef union {
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld struct {
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint16_t aqa_asqs:12; /* Admin Submission Queue Size */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint16_t aqa_rsvd1:4;
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint16_t aqa_acqs:12; /* Admin Completion Queue Size */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint16_t aqa_rsvd2:4;
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld } b;
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint32_t r;
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld} nvme_reg_aqa_t;
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld/*
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld * The spec specifies the lower 12 bits of ASQ and ACQ as reserved, which is
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld * probably a specification bug. The full 64bit regs are used as base address,
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld * and the lower bits must be zero to ensure alignment on the page size
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld * specified in CC.MPS.
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld/* ASQ -- Admin Submission Queue Base Address */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeldtypedef uint64_t nvme_reg_asq_t; /* Admin Submission Queue Base */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld/* ACQ -- Admin Completion Queue Base Address */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeldtypedef uint64_t nvme_reg_acq_t; /* Admin Completion Queue Base */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld/* SQyTDBL -- Submission Queue y Tail Doorbell */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeldtypedef union {
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld struct {
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint16_t sqtdbl_sqt; /* Submission Queue Tail */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint16_t sqtdbl_rsvd;
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld } b;
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint32_t r;
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld} nvme_reg_sqtdbl_t;
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld/* CQyHDBL -- Completion Queue y Head Doorbell */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeldtypedef union {
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld struct {
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint16_t cqhdbl_cqh; /* Completion Queue Head */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint16_t cqhdbl_rsvd;
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld } b;
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint32_t r;
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld} nvme_reg_cqhdbl_t;
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld/*
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld * NVMe submission queue entries
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld/* NVMe scatter/gather list descriptor */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeldtypedef struct {
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint64_t sgl_addr; /* Address */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint32_t sgl_len; /* Length */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint8_t sgl_rsvd[3];
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint8_t sgl_zero:4;
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint8_t sgl_type:4; /* SGL descriptor type */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld} nvme_sgl_t;
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld/* NVMe SGL descriptor type */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld#define NVME_SGL_DATA_BLOCK 0
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld#define NVME_SGL_BIT_BUCKET 1
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld#define NVME_SGL_SEGMENT 2
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld#define NVME_SGL_LAST_SEGMENT 3
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld#define NVME_SGL_VENDOR 0xf
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld/* NVMe submission queue entry */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeldtypedef struct {
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint8_t sqe_opc; /* Opcode */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint8_t sqe_fuse:2; /* Fused Operation */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint8_t sqe_rsvd:5;
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint8_t sqe_psdt:1; /* PRP or SGL for Data Transfer */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint16_t sqe_cid; /* Command Identifier */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint32_t sqe_nsid; /* Namespace Identifier */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint64_t sqe_rsvd1;
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld union {
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint64_t m_ptr; /* Metadata Pointer */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint64_t m_sglp; /* Metadata SGL Segment Pointer */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld } sqe_m;
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld union {
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint64_t d_prp[2]; /* Physical Page Region Entries 1 & 2 */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld nvme_sgl_t d_sgl; /* SGL Entry 1 */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld } sqe_dptr; /* Data Pointer */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint32_t sqe_cdw10; /* Number of Dwords in Data Transfer */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint32_t sqe_cdw11; /* Number of Dwords in Metadata Xfer */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint32_t sqe_cdw12;
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint32_t sqe_cdw13;
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint32_t sqe_cdw14;
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint32_t sqe_cdw15;
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld} nvme_sqe_t;
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld/* NVMe admin command opcodes */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld#define NVME_OPC_DELETE_SQUEUE 0x0
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld#define NVME_OPC_CREATE_SQUEUE 0x1
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld#define NVME_OPC_GET_LOG_PAGE 0x2
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld#define NVME_OPC_DELETE_CQUEUE 0x4
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld#define NVME_OPC_CREATE_CQUEUE 0x5
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld#define NVME_OPC_IDENTIFY 0x6
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld#define NVME_OPC_ABORT 0x8
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld#define NVME_OPC_SET_FEATURES 0x9
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld#define NVME_OPC_GET_FEATURES 0xa
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld#define NVME_OPC_ASYNC_EVENT 0xc
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld#define NVME_OPC_FW_ACTIVATE 0x10
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld#define NVME_OPC_FW_IMAGE_LOAD 0x11
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld/* NVMe NVM command set specific admin command opcodes */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld#define NVME_OPC_NVM_FORMAT 0x80
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld#define NVME_OPC_NVM_SEC_SEND 0x81
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld#define NVME_OPC_NVM_SEC_RECV 0x82
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld/* NVMe NVM command opcodes */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld#define NVME_OPC_NVM_FLUSH 0x0
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld#define NVME_OPC_NVM_WRITE 0x1
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld#define NVME_OPC_NVM_READ 0x2
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld#define NVME_OPC_NVM_WRITE_UNC 0x4
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld#define NVME_OPC_NVM_COMPARE 0x5
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld#define NVME_OPC_NVM_WRITE_ZERO 0x8
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld#define NVME_OPC_NVM_DSET_MGMT 0x9
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld#define NVME_OPC_NVM_RESV_REG 0xd
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld#define NVME_OPC_NVM_RESV_REPRT 0xe
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld#define NVME_OPC_NVM_RESV_ACQ 0x11
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld#define NVME_OPC_NVM_RESV_REL 0x12
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld/*
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld * NVMe completion queue entry
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeldtypedef struct {
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint16_t sf_p:1; /* Phase Tag */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint16_t sf_sc:8; /* Status Code */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint16_t sf_sct:3; /* Status Code Type */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint16_t sf_rsvd2:2;
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint16_t sf_m:1; /* More */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint16_t sf_dnr:1; /* Do Not Retry */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld} nvme_cqe_sf_t;
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeldtypedef struct {
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint32_t cqe_dw0; /* Command Specific */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint32_t cqe_rsvd1;
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint16_t cqe_sqhd; /* SQ Head Pointer */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint16_t cqe_sqid; /* SQ Identifier */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint16_t cqe_cid; /* Command Identifier */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld nvme_cqe_sf_t cqe_sf; /* Status Field */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld} nvme_cqe_t;
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld/* NVMe completion status code type */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld#define NVME_CQE_SCT_GENERIC 0 /* Generic Command Status */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld#define NVME_CQE_SCT_SPECIFIC 1 /* Command Specific Status */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld#define NVME_CQE_SCT_INTEGRITY 2 /* Media and Data Integrity Errors */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld#define NVME_CQE_SCT_VENDOR 7 /* Vendor Specific */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld/* NVMe completion status code (generic) */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld#define NVME_CQE_SC_GEN_SUCCESS 0x0 /* Successful Completion */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld#define NVME_CQE_SC_GEN_INV_OPC 0x1 /* Invalid Command Opcode */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld#define NVME_CQE_SC_GEN_INV_FLD 0x2 /* Invalid Field in Command */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld#define NVME_CQE_SC_GEN_ID_CNFL 0x3 /* Command ID Conflict */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld#define NVME_CQE_SC_GEN_DATA_XFR_ERR 0x4 /* Data Transfer Error */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld#define NVME_CQE_SC_GEN_ABORT_PWRLOSS 0x5 /* Cmds Aborted / Pwr Loss */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld#define NVME_CQE_SC_GEN_INTERNAL_ERR 0x6 /* Internal Error */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld#define NVME_CQE_SC_GEN_ABORT_REQUEST 0x7 /* Command Abort Requested */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld#define NVME_CQE_SC_GEN_ABORT_SQ_DEL 0x8 /* Cmd Aborted / SQ deletion */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld#define NVME_CQE_SC_GEN_ABORT_FUSE_FAIL 0x9 /* Cmd Aborted / Failed Fused */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld#define NVME_CQE_SC_GEN_ABORT_FUSE_MISS 0xa /* Cmd Aborted / Missing Fusd */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld#define NVME_CQE_SC_GEN_INV_NS 0xb /* Inval Namespace or Format */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld#define NVME_CQE_SC_GEN_CMD_SEQ_ERR 0xc /* Command Sequence Error */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld#define NVME_CQE_SC_GEN_INV_SGL_LAST 0xd /* Inval SGL Last Seg Desc */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld#define NVME_CQE_SC_GEN_INV_SGL_NUM 0xe /* Inval Number of SGL Desc */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld#define NVME_CQE_SC_GEN_INV_DSGL_LEN 0xf /* Data SGL Length Invalid */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld#define NVME_CQE_SC_GEN_INV_MSGL_LEN 0x10 /* Metadata SGL Length Inval */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld#define NVME_CQE_SC_GEN_INV_SGL_DESC 0x11 /* SGL Descriptor Type Inval */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld/* NVMe completion status code (generic NVM commands) */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld#define NVME_CQE_SC_GEN_NVM_LBA_RANGE 0x80 /* LBA Out Of Range */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld#define NVME_CQE_SC_GEN_NVM_CAP_EXC 0x81 /* Capacity Exceeded */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld#define NVME_CQE_SC_GEN_NVM_NS_NOTRDY 0x82 /* Namespace Not Ready */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld#define NVME_CQE_SC_GEN_NVM_RSV_CNFLCT 0x83 /* Reservation Conflict */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld/* NVMe completion status code (command specific) */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld#define NVME_CQE_SC_SPC_INV_CQ 0x0 /* Completion Queue Invalid */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld#define NVME_CQE_SC_SPC_INV_QID 0x1 /* Invalid Queue Identifier */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld#define NVME_CQE_SC_SPC_MAX_QSZ_EXC 0x2 /* Max Queue Size Exceeded */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld#define NVME_CQE_SC_SPC_ABRT_CMD_EXC 0x3 /* Abort Cmd Limit Exceeded */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld#define NVME_CQE_SC_SPC_ASYNC_EVREQ_EXC 0x5 /* Async Event Request Limit */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld#define NVME_CQE_SC_SPC_INV_FW_SLOT 0x6 /* Invalid Firmware Slot */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld#define NVME_CQE_SC_SPC_INV_FW_IMG 0x7 /* Invalid Firmware Image */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld#define NVME_CQE_SC_SPC_INV_INT_VECT 0x8 /* Invalid Interrupt Vector */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld#define NVME_CQE_SC_SPC_INV_LOG_PAGE 0x9 /* Invalid Log Page */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld#define NVME_CQE_SC_SPC_INV_FORMAT 0xa /* Invalid Format */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld#define NVME_CQE_SC_SPC_FW_RESET 0xb /* FW Application Reset Reqd */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld#define NVME_CQE_SC_SPC_INV_Q_DEL 0xc /* Invalid Queue Deletion */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld#define NVME_CQE_SC_SPC_FEAT_SAVE 0xd /* Feature Id Not Saveable */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld#define NVME_CQE_SC_SPC_FEAT_CHG 0xe /* Feature Not Changeable */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld#define NVME_CQE_SC_SPC_FEAT_NS_SPEC 0xf /* Feature Not Namespace Spec */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld#define NVME_CQE_SC_SPC_FW_NSSR 0x10 /* FW Application NSSR Reqd */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld/* NVMe completion status code (NVM command specific */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld#define NVME_CQE_SC_SPC_NVM_CNFL_ATTR 0x80 /* Conflicting Attributes */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld#define NVME_CQE_SC_SPC_NVM_INV_PROT 0x81 /* Invalid Protection */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld#define NVME_CQE_SC_SPC_NVM_READONLY 0x82 /* Write to Read Only Range */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld/* NVMe completion status code (data / metadata integrity) */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld#define NVME_CQE_SC_INT_NVM_WRITE 0x80 /* Write Fault */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld#define NVME_CQE_SC_INT_NVM_READ 0x81 /* Unrecovered Read Error */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld#define NVME_CQE_SC_INT_NVM_GUARD 0x82 /* Guard Check Error */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld#define NVME_CQE_SC_INT_NVM_APPL_TAG 0x83 /* Application Tag Check Err */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld#define NVME_CQE_SC_INT_NVM_REF_TAG 0x84 /* Reference Tag Check Err */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld#define NVME_CQE_SC_INT_NVM_COMPARE 0x85 /* Compare Failure */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld#define NVME_CQE_SC_INT_NVM_ACCESS 0x86 /* Access Denied */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld/*
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld * NVMe Asynchronous Event Request
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld#define NVME_ASYNC_TYPE_ERROR 0x0 /* Error Status */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld#define NVME_ASYNC_TYPE_HEALTH 0x1 /* SMART/Health Status */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld#define NVME_ASYNC_TYPE_VENDOR 0x7 /* vendor specific */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld#define NVME_ASYNC_ERROR_INV_SQ 0x0 /* Invalid Submission Queue */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld#define NVME_ASYNC_ERROR_INV_DBL 0x1 /* Invalid Doorbell Write */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld#define NVME_ASYNC_ERROR_DIAGFAIL 0x2 /* Diagnostic Failure */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld#define NVME_ASYNC_ERROR_PERSISTENT 0x3 /* Persistent Internal Error */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld#define NVME_ASYNC_ERROR_TRANSIENT 0x4 /* Transient Internal Error */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld#define NVME_ASYNC_ERROR_FW_LOAD 0x5 /* Firmware Image Load Error */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld#define NVME_ASYNC_HEALTH_RELIABILITY 0x0 /* Device Reliability */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld#define NVME_ASYNC_HEALTH_TEMPERATURE 0x1 /* Temp. Above Threshold */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld#define NVME_ASYNC_HEALTH_SPARE 0x2 /* Spare Below Threshold */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeldtypedef union {
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld struct {
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint8_t ae_type:3; /* Asynchronous Event Type */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint8_t ae_rsvd1:5;
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint8_t ae_info; /* Asynchronous Event Info */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint8_t ae_logpage; /* Associated Log Page */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint8_t ae_rsvd2;
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld } b;
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint32_t r;
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld} nvme_async_event_t;
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld/*
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld * NVMe Create Completion/Submission Queue
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeldtypedef union {
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld struct {
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint16_t q_qid; /* Queue Identifier */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint16_t q_qsize; /* Queue Size */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld } b;
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint32_t r;
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld} nvme_create_queue_dw10_t;
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeldtypedef union {
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld struct {
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint16_t cq_pc:1; /* Physically Contiguous */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint16_t cq_ien:1; /* Interrupts Enabled */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint16_t cq_rsvd:14;
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint16_t cq_iv; /* Interrupt Vector */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld } b;
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint32_t r;
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld} nvme_create_cq_dw11_t;
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeldtypedef union {
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld struct {
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint16_t sq_pc:1; /* Physically Contiguous */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint16_t sq_qprio:2; /* Queue Priority */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint16_t sq_rsvd:13;
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint16_t sq_cqid; /* Completion Queue ID */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld } b;
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint32_t r;
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld} nvme_create_sq_dw11_t;
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld/*
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld * NVMe Identify
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld/* NVMe Identify parameters (cdw10) */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld#define NVME_IDENTIFY_NSID 0x0 /* Identify Namespace */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld#define NVME_IDENTIFY_CTRL 0x1 /* Identify Controller */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld#define NVME_IDENTIFY_LIST 0x2 /* Identify List Namespaces */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld#define NVME_IDENTIFY_BUFSIZE 4096 /* buffer size for Identify */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld/* NVMe Queue Entry Size bitfield */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeldtypedef struct {
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint8_t qes_min:4; /* minimum entry size */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint8_t qes_max:4; /* maximum entry size */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld} nvme_idctl_qes_t;
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld/* NVMe Power State Descriptor */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeldtypedef struct {
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint16_t psd_mp; /* Maximum Power */
24979ca36afa68d08e082148fcbf4c5dc73f7849Hans Rosenfeld uint8_t psd_rsvd1;
24979ca36afa68d08e082148fcbf4c5dc73f7849Hans Rosenfeld uint8_t psd_mps:1; /* Max Power Scale (1.1) */
24979ca36afa68d08e082148fcbf4c5dc73f7849Hans Rosenfeld uint8_t psd_nops:1; /* Non-Operational State (1.1) */
24979ca36afa68d08e082148fcbf4c5dc73f7849Hans Rosenfeld uint8_t psd_rsvd2:6;
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint32_t psd_enlat; /* Entry Latency */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint32_t psd_exlat; /* Exit Latency */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint8_t psd_rrt:5; /* Relative Read Throughput */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint8_t psd_rsvd3:3;
24979ca36afa68d08e082148fcbf4c5dc73f7849Hans Rosenfeld uint8_t psd_rrl:5; /* Relative Read Latency */
24979ca36afa68d08e082148fcbf4c5dc73f7849Hans Rosenfeld uint8_t psd_rsvd4:3;
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint8_t psd_rwt:5; /* Relative Write Throughput */
24979ca36afa68d08e082148fcbf4c5dc73f7849Hans Rosenfeld uint8_t psd_rsvd5:3;
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint8_t psd_rwl:5; /* Relative Write Latency */
24979ca36afa68d08e082148fcbf4c5dc73f7849Hans Rosenfeld uint8_t psd_rsvd6:3;
24979ca36afa68d08e082148fcbf4c5dc73f7849Hans Rosenfeld uint8_t psd_rsvd7[16];
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld} nvme_idctl_psd_t;
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld/* NVMe Identify Controller Data Structure */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeldtypedef struct {
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld /* Controller Capabilities & Features */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint16_t id_vid; /* PCI vendor ID */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint16_t id_ssvid; /* PCI subsystem vendor ID */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld char id_serial[20]; /* Serial Number */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld char id_model[40]; /* Model Number */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld char id_fwrev[8]; /* Firmware Revision */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint8_t id_rab; /* Recommended Arbitration Burst */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint8_t id_oui[3]; /* vendor IEEE OUI */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld struct { /* Multi-Interface Capabilities */
24979ca36afa68d08e082148fcbf4c5dc73f7849Hans Rosenfeld uint8_t m_multi_pci:1; /* HW has multiple PCIe interfaces */
24979ca36afa68d08e082148fcbf4c5dc73f7849Hans Rosenfeld uint8_t m_multi_ctrl:1; /* HW has multiple controllers (1.1) */
24979ca36afa68d08e082148fcbf4c5dc73f7849Hans Rosenfeld uint8_t m_sr_iov:1; /* controller is SR-IOV virt fn (1.1) */
24979ca36afa68d08e082148fcbf4c5dc73f7849Hans Rosenfeld uint8_t m_rsvd:5;
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld } id_mic;
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint8_t id_mdts; /* Maximum Data Transfer Size */
24979ca36afa68d08e082148fcbf4c5dc73f7849Hans Rosenfeld uint16_t id_cntlid; /* Unique Controller Identifier (1.1) */
24979ca36afa68d08e082148fcbf4c5dc73f7849Hans Rosenfeld uint8_t id_rsvd_cc[256 - 80];
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld /* Admin Command Set Attributes */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld struct { /* Optional Admin Command Support */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint16_t oa_security:1; /* Security Send & Receive */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint16_t oa_format:1; /* Format NVM */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint16_t oa_firmare:1; /* Firmware Activate & Download */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint16_t oa_rsvd:13;
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld } id_oacs;
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint8_t id_acl; /* Abort Command Limit */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint8_t id_aerl; /* Asynchronous Event Request Limit */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld struct { /* Firmware Updates */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint8_t fw_readonly:1; /* Slot 1 is Read-Only */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint8_t fw_nslot:3; /* number of firmware slots */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint8_t fw_rsvd:4;
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld } id_frmw;
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld struct { /* Log Page Attributes */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint8_t lp_smart:1; /* SMART/Health information per NS */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint8_t lp_rsvd:7;
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld } id_lpa;
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint8_t id_elpe; /* Error Log Page Entries */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint8_t id_npss; /* Number of Power States */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld struct { /* Admin Vendor Specific Command Conf */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint8_t av_spec:1; /* use format from spec */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint8_t av_rsvd:7;
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld } id_avscc;
24979ca36afa68d08e082148fcbf4c5dc73f7849Hans Rosenfeld struct { /* Autonomous Power State Trans (1.1) */
24979ca36afa68d08e082148fcbf4c5dc73f7849Hans Rosenfeld uint8_t ap_sup:1; /* APST supported (1.1) */
24979ca36afa68d08e082148fcbf4c5dc73f7849Hans Rosenfeld uint8_t ap_rsvd:7;
24979ca36afa68d08e082148fcbf4c5dc73f7849Hans Rosenfeld } id_apsta;
24979ca36afa68d08e082148fcbf4c5dc73f7849Hans Rosenfeld uint8_t id_rsvd_ac[256 - 10];
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld /* NVM Command Set Attributes */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld nvme_idctl_qes_t id_sqes; /* Submission Queue Entry Size */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld nvme_idctl_qes_t id_cqes; /* Completion Queue Entry Size */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint16_t id_rsvd_nc_1;
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint32_t id_nn; /* Number of Namespaces */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld struct { /* Optional NVM Command Support */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint16_t on_compare:1; /* Compare */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint16_t on_wr_unc:1; /* Write Uncorrectable */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint16_t on_dset_mgmt:1; /* Dataset Management */
24979ca36afa68d08e082148fcbf4c5dc73f7849Hans Rosenfeld uint16_t on_wr_zero:1; /* Write Zeros (1.1) */
24979ca36afa68d08e082148fcbf4c5dc73f7849Hans Rosenfeld uint16_t on_save:1; /* Save/Select in Get/Set Feat (1.1) */
24979ca36afa68d08e082148fcbf4c5dc73f7849Hans Rosenfeld uint16_t on_reserve:1; /* Reservations (1.1) */
24979ca36afa68d08e082148fcbf4c5dc73f7849Hans Rosenfeld uint16_t on_rsvd:10;
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld } id_oncs;
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld struct { /* Fused Operation Support */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint16_t f_cmp_wr:1; /* Compare and Write */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint16_t f_rsvd:15;
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld } id_fuses;
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld struct { /* Format NVM Attributes */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint8_t fn_format:1; /* Format applies to all NS */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint8_t fn_sec_erase:1; /* Secure Erase applies to all NS */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint8_t fn_crypt_erase:1; /* Cryptographic Erase supported */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint8_t fn_rsvd:5;
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld } id_fna;
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld struct { /* Volatile Write Cache */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint8_t vwc_present:1; /* Volatile Write Cache present */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint8_t rsvd:7;
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld } id_vwc;
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint16_t id_awun; /* Atomic Write Unit Normal */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint16_t id_awupf; /* Atomic Write Unit Power Fail */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld struct { /* NVM Vendor Specific Command Conf */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint8_t nv_spec:1; /* use format from spec */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint8_t nv_rsvd:7;
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld } id_nvscc;
24979ca36afa68d08e082148fcbf4c5dc73f7849Hans Rosenfeld uint8_t id_rsvd_nc_2;
24979ca36afa68d08e082148fcbf4c5dc73f7849Hans Rosenfeld uint16_t id_acwu; /* Atomic Compare & Write Unit (1.1) */
24979ca36afa68d08e082148fcbf4c5dc73f7849Hans Rosenfeld uint16_t id_rsvd_nc_3;
24979ca36afa68d08e082148fcbf4c5dc73f7849Hans Rosenfeld struct { /* SGL Support (1.1) */
24979ca36afa68d08e082148fcbf4c5dc73f7849Hans Rosenfeld uint16_t sgl_sup:1; /* SGL Supported in NVM cmds (1.1) */
24979ca36afa68d08e082148fcbf4c5dc73f7849Hans Rosenfeld uint16_t sgl_rsvd1:15;
24979ca36afa68d08e082148fcbf4c5dc73f7849Hans Rosenfeld uint16_t sgl_bucket:1; /* SGL Bit Bucket supported (1.1) */
24979ca36afa68d08e082148fcbf4c5dc73f7849Hans Rosenfeld uint16_t sgl_rsvd2:15;
24979ca36afa68d08e082148fcbf4c5dc73f7849Hans Rosenfeld } id_sgls;
24979ca36afa68d08e082148fcbf4c5dc73f7849Hans Rosenfeld uint8_t id_rsvd_nc_4[192 - 28];
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld /* I/O Command Set Attributes */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint8_t id_rsvd_ioc[1344];
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld /* Power State Descriptors */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld nvme_idctl_psd_t id_psd[32];
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld /* Vendor Specific */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint8_t id_vs[1024];
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld} nvme_identify_ctrl_t;
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld/* NVMe Identify Namespace LBA Format */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeldtypedef struct {
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint16_t lbaf_ms; /* Metadata Size */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint8_t lbaf_lbads; /* LBA Data Size */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint8_t lbaf_rp:2; /* Relative Performance */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint8_t lbaf_rsvd1:6;
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld} nvme_idns_lbaf_t;
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld/* NVMe Identify Namespace Data Structure */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeldtypedef struct {
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint64_t id_nsize; /* Namespace Size */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint64_t id_ncap; /* Namespace Capacity */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint64_t id_nuse; /* Namespace Utilization */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld struct { /* Namespace Features */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint8_t f_thin:1; /* Thin Provisioning */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint8_t f_rsvd:7;
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld } id_nsfeat;
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint8_t id_nlbaf; /* Number of LBA formats */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld struct { /* Formatted LBA size */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint8_t lba_format:4; /* LBA format */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint8_t lba_extlba:1; /* extended LBA (includes metadata) */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint8_t lba_rsvd:3;
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld } id_flbas;
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld struct { /* Metadata Capabilities */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint8_t mc_extlba:1; /* extended LBA transfers */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint8_t mc_separate:1; /* separate metadata transfers */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint8_t mc_rsvd:6;
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld } id_mc;
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld struct { /* Data Protection Capabilities */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint8_t dp_type1:1; /* Protection Information Type 1 */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint8_t dp_type2:1; /* Protection Information Type 2 */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint8_t dp_type3:1; /* Protection Information Type 3 */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint8_t dp_first:1; /* first 8 bytes of metadata */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint8_t dp_last:1; /* last 8 bytes of metadata */
24979ca36afa68d08e082148fcbf4c5dc73f7849Hans Rosenfeld uint8_t dp_rsvd:3;
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld } id_dpc;
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld struct { /* Data Protection Settings */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint8_t dp_pinfo:3; /* Protection Information enabled */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint8_t dp_first:1; /* first 8 bytes of metadata */
24979ca36afa68d08e082148fcbf4c5dc73f7849Hans Rosenfeld uint8_t dp_rsvd:4;
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld } id_dps;
24979ca36afa68d08e082148fcbf4c5dc73f7849Hans Rosenfeld struct { /* NS Multi-Path/Sharing Cap (1.1) */
24979ca36afa68d08e082148fcbf4c5dc73f7849Hans Rosenfeld uint8_t nm_shared:1; /* NS is shared (1.1) */
24979ca36afa68d08e082148fcbf4c5dc73f7849Hans Rosenfeld uint8_t nm_rsvd:7;
24979ca36afa68d08e082148fcbf4c5dc73f7849Hans Rosenfeld } id_nmic;
24979ca36afa68d08e082148fcbf4c5dc73f7849Hans Rosenfeld struct { /* Reservation Capabilities (1.1) */
24979ca36afa68d08e082148fcbf4c5dc73f7849Hans Rosenfeld uint8_t rc_persist:1; /* Persist Through Power Loss (1.1) */
24979ca36afa68d08e082148fcbf4c5dc73f7849Hans Rosenfeld uint8_t rc_wr_excl:1; /* Write Exclusive (1.1) */
24979ca36afa68d08e082148fcbf4c5dc73f7849Hans Rosenfeld uint8_t rc_excl:1; /* Exclusive Access (1.1) */
24979ca36afa68d08e082148fcbf4c5dc73f7849Hans Rosenfeld uint8_t rc_wr_excl_r:1; /* Wr Excl - Registrants Only (1.1) */
24979ca36afa68d08e082148fcbf4c5dc73f7849Hans Rosenfeld uint8_t rc_excl_r:1; /* Excl Acc - Registrants Only (1.1) */
24979ca36afa68d08e082148fcbf4c5dc73f7849Hans Rosenfeld uint8_t rc_wr_excl_a:1; /* Wr Excl - All Registrants (1.1) */
24979ca36afa68d08e082148fcbf4c5dc73f7849Hans Rosenfeld uint8_t rc_excl_a:1; /* Excl Acc - All Registrants (1.1) */
24979ca36afa68d08e082148fcbf4c5dc73f7849Hans Rosenfeld uint8_t rc_rsvd:1;
24979ca36afa68d08e082148fcbf4c5dc73f7849Hans Rosenfeld } id_rescap;
24979ca36afa68d08e082148fcbf4c5dc73f7849Hans Rosenfeld uint8_t id_rsvd1[120 - 32];
24979ca36afa68d08e082148fcbf4c5dc73f7849Hans Rosenfeld uint8_t id_eui64[8]; /* IEEE Extended Unique Id (1.1) */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld nvme_idns_lbaf_t id_lbaf[16]; /* LBA Formats */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint8_t id_rsvd2[192];
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint8_t id_vs[3712]; /* Vendor Specific */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld} nvme_identify_nsid_t;
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld/*
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld * NVMe Abort Command
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeldtypedef union {
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld struct {
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint16_t ac_sqid; /* Submission Queue ID */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint16_t ac_cid; /* Command ID */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld } b;
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint32_t r;
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld} nvme_abort_cmd_t;
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld/*
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld * NVMe Get / Set Features
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld#define NVME_FEAT_ARBITRATION 0x1 /* Command Arbitration */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld#define NVME_FEAT_POWER_MGMT 0x2 /* Power Management */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld#define NVME_FEAT_LBA_RANGE 0x3 /* LBA Range Type */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld#define NVME_FEAT_TEMPERATURE 0x4 /* Temperature Threshold */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld#define NVME_FEAT_ERROR 0x5 /* Error Recovery */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld#define NVME_FEAT_WRITE_CACHE 0x6 /* Volatile Write Cache */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld#define NVME_FEAT_NQUEUES 0x7 /* Number of Queues */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld#define NVME_FEAT_INTR_COAL 0x8 /* Interrupt Coalescing */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld#define NVME_FEAT_INTR_VECT 0x9 /* Interrupt Vector Configuration */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld#define NVME_FEAT_WRITE_ATOM 0xa /* Write Atomicity */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld#define NVME_FEAT_ASYNC_EVENT 0xb /* Asynchronous Event Configuration */
24979ca36afa68d08e082148fcbf4c5dc73f7849Hans Rosenfeld#define NVME_FEAT_AUTO_PST 0xc /* Autonomous Power State Transition */
24979ca36afa68d08e082148fcbf4c5dc73f7849Hans Rosenfeld /* (1.1) */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld#define NVME_FEAT_PROGRESS 0x80 /* Software Progress Marker */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld/* Arbitration Feature */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeldtypedef struct {
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint8_t arb_ab:3; /* Arbitration Burst */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint8_t arb_rsvd:5;
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint8_t arb_lpw; /* Low Priority Weight */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint8_t arb_mpw; /* Medium Priority Weight */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint8_t arb_hpw; /* High Priority Weight */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld} nvme_arbitration_dw11_t;
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld/* LBA Range Type Feature */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeldtypedef struct {
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint32_t lr_num:6; /* Number of LBA ranges */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint32_t lr_rsvd:26;
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld} nvme_lba_range_type_dw11_t;
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeldtypedef struct {
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint8_t lr_type; /* Type */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld struct { /* Attributes */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint8_t lr_write:1; /* may be overwritten */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint8_t lr_hidden:1; /* hidden from OS/EFI/BIOS */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint8_t lr_rsvd1:6;
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld } lr_attr;
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint8_t lr_rsvd2[14];
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint64_t lr_slba; /* Starting LBA */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint64_t lr_nlb; /* Number of Logical Blocks */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint8_t lr_guid[16]; /* Unique Identifier */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint8_t lr_rsvd3[16];
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld} nvme_lba_range_type_t;
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld
d148d46e69709052e6d92205c98874f3e7cfd4c0Hans Rosenfeld/* Volatile Write Cache Feature */
d148d46e69709052e6d92205c98874f3e7cfd4c0Hans Rosenfeldtypedef union {
d148d46e69709052e6d92205c98874f3e7cfd4c0Hans Rosenfeld struct {
d148d46e69709052e6d92205c98874f3e7cfd4c0Hans Rosenfeld uint32_t wc_wce:1; /* Volatile Write Cache Enable */
d148d46e69709052e6d92205c98874f3e7cfd4c0Hans Rosenfeld uint32_t wc_rsvd:31;
d148d46e69709052e6d92205c98874f3e7cfd4c0Hans Rosenfeld } b;
d148d46e69709052e6d92205c98874f3e7cfd4c0Hans Rosenfeld uint32_t r;
d148d46e69709052e6d92205c98874f3e7cfd4c0Hans Rosenfeld} nvme_write_cache_t;
d148d46e69709052e6d92205c98874f3e7cfd4c0Hans Rosenfeld
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld/* Number of Queues */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeldtypedef union {
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld struct {
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint16_t nq_nsq; /* Number of Submission Queues */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint16_t nq_ncq; /* Number of Completion Queues */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld } b;
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint32_t r;
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld} nvme_nqueue_t;
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld/*
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld * NVMe Get Log Page
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld#define NVME_LOGPAGE_ERROR 0x1 /* Error Information */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld#define NVME_LOGPAGE_HEALTH 0x2 /* SMART/Health Information */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld#define NVME_LOGPAGE_FWSLOT 0x3 /* Firmware Slot Information */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeldtypedef union {
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld struct {
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint8_t lp_lid; /* Log Page Identifier */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint8_t lp_rsvd1;
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint16_t lp_numd:12; /* Number of Dwords */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint16_t lp_rsvd2:4;
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld } b;
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint32_t r;
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld} nvme_getlogpage_t;
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeldtypedef struct {
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint64_t el_count; /* Error Count */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint16_t el_sqid; /* Submission Queue ID */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint16_t el_cid; /* Command ID */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld nvme_cqe_sf_t el_sf; /* Status Field */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint8_t el_byte; /* Parameter Error Location byte */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint8_t el_bit:3; /* Parameter Error Location bit */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint8_t el_rsvd1:5;
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint64_t el_lba; /* Logical Block Address */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint32_t el_nsid; /* Namespace ID */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint8_t el_vendor; /* Vendor Specific Information avail */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint8_t el_rsvd2[64 - 29];
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld} nvme_error_log_entry_t;
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeldtypedef struct {
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint64_t lo;
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint64_t hi;
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld} nvme_uint128_t;
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeldtypedef struct {
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint8_t hl_crit_warn; /* Critical Warning */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint16_t hl_temp; /* Temperature */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint8_t hl_avail_spare; /* Available Spare */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint8_t hl_avail_spare_thr; /* Available Spare Threshold */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint8_t hl_used; /* Percentage Used */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint8_t hl_rsvd1[32 - 6];
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld nvme_uint128_t hl_data_read; /* Data Units Read */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld nvme_uint128_t hl_data_write; /* Data Units Written */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld nvme_uint128_t hl_host_read; /* Host Read Commands */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld nvme_uint128_t hl_host_write; /* Host Write Commands */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld nvme_uint128_t hl_ctrl_busy; /* Controller Busy Time */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld nvme_uint128_t hl_power_cycles; /* Power Cycles */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld nvme_uint128_t hl_power_on_hours; /* Power On Hours */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld nvme_uint128_t hl_unsafe_shutdn; /* Unsafe Shutdowns */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld nvme_uint128_t hl_media_errors; /* Media Errors */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld nvme_uint128_t hl_errors_logged; /* Number of errors logged */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint8_t hl_rsvd2[512 - 192];
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld} nvme_health_log_t;
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeldtypedef struct {
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint8_t fw_afi:3; /* Active Firmware Slot */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint8_t fw_rsvd1:5;
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint8_t fw_rsvd2[7];
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld char fw_frs[7][8]; /* Firmware Revision / Slot */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld uint8_t fw_rsvd3[512 - 64];
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld} nvme_fwslot_log_t;
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld#ifdef __cplusplus
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld}
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld#endif
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld#pragma pack() /* pack(1) */
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld
3c9168fa8e9c30d55b3aa2fde74bd7da46df53f5Hans Rosenfeld#endif /* _NVME_REG_H */