212 lines
4.6 KiB
C
212 lines
4.6 KiB
C
// NVMe datastructures and constants
|
|
//
|
|
// Copyright 2017 Amazon.com, Inc. or its affiliates.
|
|
//
|
|
// This file may be distributed under the terms of the GNU LGPLv3 license.
|
|
|
|
#ifndef __NVME_INT_H
|
|
#define __NVME_INT_H
|
|
|
|
#include "types.h" // u32
|
|
#include "pcidevice.h" // struct pci_device
|
|
|
|
#define NVME_MAX_PRPL_ENTRIES 15 /* Allows requests up to 64kb */
|
|
|
|
/* Data structures */
|
|
|
|
/* The register file of a NVMe host controller. This struct follows the naming
|
|
scheme in the NVMe specification. */
|
|
struct nvme_reg {
|
|
u64 cap; /* controller capabilities */
|
|
u32 vs; /* version */
|
|
u32 intms; /* interrupt mask set */
|
|
u32 intmc; /* interrupt mask clear */
|
|
u32 cc; /* controller configuration */
|
|
u32 _res0;
|
|
u32 csts; /* controller status */
|
|
u32 _res1;
|
|
u32 aqa; /* admin queue attributes */
|
|
u64 asq; /* admin submission queue base address */
|
|
u64 acq; /* admin completion queue base address */
|
|
};
|
|
|
|
/* Submission queue entry */
|
|
struct nvme_sqe {
|
|
union {
|
|
u32 dword[16];
|
|
struct {
|
|
u32 cdw0; /* Command DWORD 0 */
|
|
u32 nsid; /* Namespace ID */
|
|
u64 _res0;
|
|
u64 mptr; /* metadata ptr */
|
|
|
|
u64 dptr_prp1;
|
|
u64 dptr_prp2;
|
|
};
|
|
};
|
|
};
|
|
|
|
/* Completion queue entry */
|
|
struct nvme_cqe {
|
|
union {
|
|
u32 dword[4];
|
|
struct {
|
|
u32 cdw0;
|
|
u32 _res0;
|
|
u16 sq_head;
|
|
u16 sq_id;
|
|
u16 cid;
|
|
u16 status;
|
|
};
|
|
};
|
|
};
|
|
|
|
/* The common part of every submission or completion queue. */
|
|
struct nvme_queue {
|
|
u32 *dbl; /* doorbell */
|
|
u16 mask; /* length - 1 */
|
|
};
|
|
|
|
struct nvme_cq {
|
|
struct nvme_queue common;
|
|
struct nvme_cqe *cqe;
|
|
|
|
/* We have read upto (but not including) this entry in the queue. */
|
|
u16 head;
|
|
|
|
/* The current phase bit the controller uses to indicate that it has written
|
|
a new entry. This is inverted after each wrap. */
|
|
unsigned phase : 1;
|
|
};
|
|
|
|
struct nvme_sq {
|
|
struct nvme_queue common;
|
|
struct nvme_sqe *sqe;
|
|
|
|
/* Corresponding completion queue. We only support a single SQ per CQ. */
|
|
struct nvme_cq *cq;
|
|
|
|
/* The last entry the controller has fetched. */
|
|
u16 head;
|
|
|
|
/* The last value we have written to the tail doorbell. */
|
|
u16 tail;
|
|
};
|
|
|
|
struct nvme_ctrl {
|
|
struct pci_device *pci;
|
|
struct nvme_reg volatile *reg;
|
|
|
|
u32 doorbell_stride; /* in bytes */
|
|
|
|
struct nvme_sq admin_sq;
|
|
struct nvme_cq admin_cq;
|
|
|
|
u32 ns_count;
|
|
|
|
struct nvme_sq io_sq;
|
|
struct nvme_cq io_cq;
|
|
};
|
|
|
|
struct nvme_namespace {
|
|
struct drive_s drive;
|
|
struct nvme_ctrl *ctrl;
|
|
|
|
u32 ns_id;
|
|
|
|
u64 lba_count; /* The total amount of sectors. */
|
|
|
|
u32 block_size;
|
|
u32 metadata_size;
|
|
u32 max_req_size;
|
|
|
|
/* Page aligned buffer of size NVME_PAGE_SIZE. */
|
|
char *dma_buffer;
|
|
|
|
/* Page List */
|
|
u32 prpl_len;
|
|
u64 prpl[NVME_MAX_PRPL_ENTRIES];
|
|
};
|
|
|
|
/* Data structures for NVMe admin identify commands */
|
|
|
|
struct nvme_identify_ctrl {
|
|
u16 vid;
|
|
u16 ssvid;
|
|
char sn[20];
|
|
char mn[40];
|
|
char fr[8];
|
|
|
|
u8 rab;
|
|
u8 ieee[3];
|
|
u8 cmic;
|
|
u8 mdts;
|
|
|
|
char _boring[516 - 78];
|
|
|
|
u32 nn; /* number of namespaces */
|
|
};
|
|
|
|
struct nvme_identify_ns_list {
|
|
u32 ns_id[1024];
|
|
};
|
|
|
|
struct nvme_lba_format {
|
|
u16 ms;
|
|
u8 lbads;
|
|
u8 rp;
|
|
u8 res;
|
|
};
|
|
|
|
struct nvme_identify_ns {
|
|
u64 nsze;
|
|
u64 ncap;
|
|
u64 nuse;
|
|
u8 nsfeat;
|
|
u8 nlbaf;
|
|
u8 flbas;
|
|
|
|
char _boring[128 - 27];
|
|
|
|
struct nvme_lba_format lbaf[16];
|
|
};
|
|
|
|
union nvme_identify {
|
|
struct nvme_identify_ns ns;
|
|
struct nvme_identify_ctrl ctrl;
|
|
struct nvme_identify_ns_list ns_list;
|
|
};
|
|
|
|
/* NVMe constants */
|
|
|
|
#define NVME_CAP_CSS_NVME (1ULL << 37)
|
|
|
|
#define NVME_CSTS_FATAL (1U << 1)
|
|
#define NVME_CSTS_RDY (1U << 0)
|
|
|
|
#define NVME_CC_EN (1U << 0)
|
|
|
|
#define NVME_SQE_OPC_ADMIN_CREATE_IO_SQ 1U
|
|
#define NVME_SQE_OPC_ADMIN_CREATE_IO_CQ 5U
|
|
#define NVME_SQE_OPC_ADMIN_IDENTIFY 6U
|
|
|
|
#define NVME_SQE_OPC_IO_WRITE 1U
|
|
#define NVME_SQE_OPC_IO_READ 2U
|
|
|
|
#define NVME_ADMIN_IDENTIFY_CNS_ID_NS 0U
|
|
#define NVME_ADMIN_IDENTIFY_CNS_ID_CTRL 1U
|
|
#define NVME_ADMIN_IDENTIFY_CNS_GET_NS_LIST 2U
|
|
|
|
#define NVME_CQE_DW3_P (1U << 16)
|
|
|
|
#define NVME_PAGE_SIZE 4096
|
|
#define NVME_PAGE_MASK ~(NVME_PAGE_SIZE - 1)
|
|
|
|
/* Length for the queue entries. */
|
|
#define NVME_SQE_SIZE_LOG 6
|
|
#define NVME_CQE_SIZE_LOG 4
|
|
|
|
#endif
|
|
|
|
/* EOF */
|