diff --git a/sys/dev/nvme/nvme.h b/sys/dev/nvme/nvme.h --- a/sys/dev/nvme/nvme.h +++ b/sys/dev/nvme/nvme.h @@ -433,6 +433,25 @@ #define NVME_CTRLR_DATA_VWC_ALL_NO (2) #define NVME_CTRLR_DATA_VWC_ALL_YES (3) +/** SGL Support */ +/* NVM command set SGL support */ +#define NVME_CTRLR_DATA_SGLS_NVM_COMMAND_SET_SHIFT (0) +#define NVME_CTRLR_DATA_SGLS_NVM_COMMAND_SET_MASK (0x3) +#define NVME_CTRLR_DATA_SGLS_KEYED_DATA_BLOCK_SHIFT (2) +#define NVME_CTRLR_DATA_SGLS_KEYED_DATA_BLOCK_MASK (0x1) +#define NVME_CTRLR_DATA_SGLS_BIT_BUCKET_SHIFT (16) +#define NVME_CTRLR_DATA_SGLS_BIT_BUCKET_MASK (0x1) +#define NVME_CTRLR_DATA_SGLS_CONTIG_MPTR_SHIFT (17) +#define NVME_CTRLR_DATA_SGLS_CONTIG_MPTR_MASK (0x1) +#define NVME_CTRLR_DATA_SGLS_OVERSIZED_SHIFT (18) +#define NVME_CTRLR_DATA_SGLS_OVERSIZED_MASK (0x1) +#define NVME_CTRLR_DATA_SGLS_MPTR_SGL_SHIFT (19) +#define NVME_CTRLR_DATA_SGLS_MPTR_SGL_MASK (0x1) +#define NVME_CTRLR_DATA_SGLS_ADDRESS_AS_OFFSET_SHIFT (20) +#define NVME_CTRLR_DATA_SGLS_ADDRESS_AS_OFFSET_MASK (0x1) +#define NVME_CTRLR_DATA_SGLS_TRANSPORT_DATA_BLOCK_SHIFT (21) +#define NVME_CTRLR_DATA_SGLS_TRANSPORT_DATA_BLOCK_MASK (0x1) + /** namespace features */ /* thin provisioning */ #define NVME_NS_DATA_NSFEAT_THIN_PROV_SHIFT (0) @@ -675,6 +694,38 @@ _Static_assert(sizeof(struct nvme_registers) == 0x1008, "bad size for nvme_registers"); +#define NVME_SGL_SUBTYPE_SHIFT (0) +#define NVME_SGL_SUBTYPE_MASK (0xF) +#define NVME_SGL_TYPE_SHIFT (4) +#define NVME_SGL_TYPE_MASK (0xF) + +#define NVME_SGL_TYPE(type, subtype) \ + ((subtype) << NVME_SGL_SUBTYPE_SHIFT | (type) << NVME_SGL_TYPE_SHIFT) + +enum nvme_sgl_type { + NVME_SGL_TYPE_DATA_BLOCK = 0x0, + NVME_SGL_TYPE_BIT_BUCKET = 0x1, + NVME_SGL_TYPE_SEGMENT = 0x2, + NVME_SGL_TYPE_LAST_SEGMENT = 0x3, + NVME_SGL_TYPE_KEYED_DATA_BLOCK = 0x4, + NVME_SGL_TYPE_TRANSPORT_DATA_BLOCK = 0x5, +}; + +enum nvme_sgl_subtype { + NVME_SGL_SUBTYPE_ADDRESS = 0x0, + NVME_SGL_SUBTYPE_OFFSET = 0x1, + NVME_SGL_SUBTYPE_TRANSPORT = 0xa, +}; + +struct nvme_sgl_descriptor { + uint64_t address; + uint32_t length; + uint8_t reserved[3]; + uint8_t type; +}; + +_Static_assert(sizeof(struct nvme_sgl_descriptor) == 16, "bad size for nvme_sgl_descriptor"); + struct nvme_command { /* dword 0 */ uint8_t opc; /* opcode */ @@ -691,11 +742,14 @@ /* dword 4-5 */ uint64_t mptr; /* metadata pointer */ - /* dword 6-7 */ - uint64_t prp1; /* prp entry 1 */ - - /* dword 8-9 */ - uint64_t prp2; /* prp entry 2 */ + /* dword 6-9 */ + union { + struct { + uint64_t prp1; /* prp entry 1 */ + uint64_t prp2; /* prp entry 2 */ + }; + struct nvme_sgl_descriptor sgl; + }; /* dword 10-15 */ uint32_t cdw10; /* command-specific */