Changeset View
Changeset View
Standalone View
Standalone View
sys/dev/nvme/nvme.h
Show First 20 Lines • Show All 122 Lines • ▼ Show 20 Lines | |||||
#define NVME_STATUS_SC_MASK (0xFF) | #define NVME_STATUS_SC_MASK (0xFF) | ||||
#define NVME_STATUS_SCT_SHIFT (9) | #define NVME_STATUS_SCT_SHIFT (9) | ||||
#define NVME_STATUS_SCT_MASK (0x7) | #define NVME_STATUS_SCT_MASK (0x7) | ||||
#define NVME_STATUS_M_SHIFT (14) | #define NVME_STATUS_M_SHIFT (14) | ||||
#define NVME_STATUS_M_MASK (0x1) | #define NVME_STATUS_M_MASK (0x1) | ||||
#define NVME_STATUS_DNR_SHIFT (15) | #define NVME_STATUS_DNR_SHIFT (15) | ||||
#define NVME_STATUS_DNR_MASK (0x1) | #define NVME_STATUS_DNR_MASK (0x1) | ||||
#define NVME_STATUS_GET_P(st) (((st) >> NVME_STATUS_P_SHIFT) & NVME_STATUS_P_MASK) | #define NVME_STATUS_GET_P(st) (st.p) | ||||
#define NVME_STATUS_GET_SC(st) (((st) >> NVME_STATUS_SC_SHIFT) & NVME_STATUS_SC_MASK) | #define NVME_STATUS_GET_SC(st) (st.sc) | ||||
#define NVME_STATUS_GET_SCT(st) (((st) >> NVME_STATUS_SCT_SHIFT) & NVME_STATUS_SCT_MASK) | #define NVME_STATUS_GET_SCT(st) (st.sct) | ||||
#define NVME_STATUS_GET_M(st) (((st) >> NVME_STATUS_M_SHIFT) & NVME_STATUS_M_MASK) | #define NVME_STATUS_GET_M(st) (st.m) | ||||
#define NVME_STATUS_GET_DNR(st) (((st) >> NVME_STATUS_DNR_SHIFT) & NVME_STATUS_DNR_MASK) | #define NVME_STATUS_GET_DNR(st) (st.dnr) | ||||
mst_semihalf.com: These would work only on little-endian | |||||
#define NVME_PWR_ST_MPS_SHIFT (0) | #define NVME_PWR_ST_MPS_SHIFT (0) | ||||
#define NVME_PWR_ST_MPS_MASK (0x1) | #define NVME_PWR_ST_MPS_MASK (0x1) | ||||
#define NVME_PWR_ST_NOPS_SHIFT (1) | #define NVME_PWR_ST_NOPS_SHIFT (1) | ||||
#define NVME_PWR_ST_NOPS_MASK (0x1) | #define NVME_PWR_ST_NOPS_MASK (0x1) | ||||
#define NVME_PWR_ST_RRT_SHIFT (0) | #define NVME_PWR_ST_RRT_SHIFT (0) | ||||
#define NVME_PWR_ST_RRT_MASK (0x1F) | #define NVME_PWR_ST_RRT_MASK (0x1F) | ||||
#define NVME_PWR_ST_RRL_SHIFT (0) | #define NVME_PWR_ST_RRL_SHIFT (0) | ||||
▲ Show 20 Lines • Show All 279 Lines • ▼ Show 20 Lines | struct nvme_registers | ||||
} doorbell[1] __packed; | } doorbell[1] __packed; | ||||
} __packed; | } __packed; | ||||
_Static_assert(sizeof(struct nvme_registers) == 0x1008, "bad size for nvme_registers"); | _Static_assert(sizeof(struct nvme_registers) == 0x1008, "bad size for nvme_registers"); | ||||
struct nvme_command | struct nvme_command | ||||
{ | { | ||||
/* dword 0 */ | /* dword 0 */ | ||||
union { | |||||
uint16_t opc_fuse; /* opcode, fused operation */ | uint16_t opc_fuse; /* opcode, fused operation */ | ||||
/* Backward compatible API, only for userland */ | |||||
struct { | |||||
#if _BYTE_ORDER == _LITTLE_ENDIAN | |||||
uint16_t opc : 8, | |||||
fuse : 2, | |||||
rsvd1 : 6; | |||||
#else | |||||
uint16_t rsvd1 : 6, | |||||
fuse : 2, | |||||
opc : 8; | |||||
#endif | |||||
}; | |||||
}; | |||||
uint16_t cid; /* command identifier */ | uint16_t cid; /* command identifier */ | ||||
/* dword 1 */ | /* dword 1 */ | ||||
uint32_t nsid; /* namespace identifier */ | uint32_t nsid; /* namespace identifier */ | ||||
/* dword 2-3 */ | /* dword 2-3 */ | ||||
uint32_t rsvd2; | uint32_t rsvd2; | ||||
uint32_t rsvd3; | uint32_t rsvd3; | ||||
Show All 13 Lines | #endif | ||||
uint32_t cdw12; /* command-specific */ | uint32_t cdw12; /* command-specific */ | ||||
uint32_t cdw13; /* command-specific */ | uint32_t cdw13; /* command-specific */ | ||||
uint32_t cdw14; /* command-specific */ | uint32_t cdw14; /* command-specific */ | ||||
uint32_t cdw15; /* command-specific */ | uint32_t cdw15; /* command-specific */ | ||||
} __packed; | } __packed; | ||||
_Static_assert(sizeof(struct nvme_command) == 16 * 4, "bad size for nvme_command"); | _Static_assert(sizeof(struct nvme_command) == 16 * 4, "bad size for nvme_command"); | ||||
struct nvme_status { | |||||
#if _BYTE_ORDER == _LITTLE_ENDIAN | |||||
uint16_t p : 1, /* phase tag */ | |||||
sc : 8, /* status code */ | |||||
sct : 3, /* status code type */ | |||||
rsvd2 : 2, | |||||
m : 1, /* more */ | |||||
dnr : 1; /* do not retry */ | |||||
#else | |||||
uint16_t dnr : 1, /* do not retry */ | |||||
m : 1, /* more */ | |||||
rsvd2 : 2, | |||||
sct : 3, /* status code type */ | |||||
sc : 8, /* status code */ | |||||
p : 1; /* phase tag */ | |||||
mst_semihalf.comUnsubmitted Not Done Inline ActionsThis won't work on big endian. mst_semihalf.com: This won't work on big endian. | |||||
#endif | |||||
} __packed; | |||||
Not Done Inline ActionsIs there places where this used as uint16_t? Why the asymmetry between request and response representation style? mav: Is there places where this used as uint16_t? Why the asymmetry between request and response… | |||||
Not Done Inline ActionsI don't think so, and the asymmetry should be fixed. imp: I don't think so, and the asymmetry should be fixed. | |||||
struct nvme_completion { | struct nvme_completion { | ||||
/* dword 0 */ | /* dword 0 */ | ||||
uint32_t cdw0; /* command-specific */ | uint32_t cdw0; /* command-specific */ | ||||
/* dword 1 */ | /* dword 1 */ | ||||
uint32_t rsvd1; | uint32_t rsvd1; | ||||
/* dword 2 */ | /* dword 2 */ | ||||
uint16_t sqhd; /* submission queue head pointer */ | uint16_t sqhd; /* submission queue head pointer */ | ||||
uint16_t sqid; /* submission queue identifier */ | uint16_t sqid; /* submission queue identifier */ | ||||
/* dword 3 */ | /* dword 3 */ | ||||
uint16_t cid; /* command identifier */ | uint16_t cid; /* command identifier */ | ||||
uint16_t status; | struct nvme_status status; | ||||
} __packed; | } __packed; | ||||
_Static_assert(sizeof(struct nvme_completion) == 4 * 4, "bad size for nvme_completion"); | _Static_assert(sizeof(struct nvme_completion) == 4 * 4, "bad size for nvme_completion"); | ||||
struct nvme_dsm_range { | struct nvme_dsm_range { | ||||
uint32_t attributes; | uint32_t attributes; | ||||
uint32_t length; | uint32_t length; | ||||
▲ Show 20 Lines • Show All 847 Lines • ▼ Show 20 Lines | |||||
void nvme_completion_swapbytes(struct nvme_completion *s) | void nvme_completion_swapbytes(struct nvme_completion *s) | ||||
{ | { | ||||
s->cdw0 = le32toh(s->cdw0); | s->cdw0 = le32toh(s->cdw0); | ||||
/* omit rsvd1 */ | /* omit rsvd1 */ | ||||
s->sqhd = le16toh(s->sqhd); | s->sqhd = le16toh(s->sqhd); | ||||
s->sqid = le16toh(s->sqid); | s->sqid = le16toh(s->sqid); | ||||
/* omit cid */ | /* omit cid */ | ||||
s->status = le16toh(s->status); | // s->status = le16toh(s->status); | ||||
} | } | ||||
static inline | static inline | ||||
void nvme_power_state_swapbytes(struct nvme_power_state *s) | void nvme_power_state_swapbytes(struct nvme_power_state *s) | ||||
{ | { | ||||
s->mp = le16toh(s->mp); | s->mp = le16toh(s->mp); | ||||
s->enlat = le32toh(s->enlat); | s->enlat = le32toh(s->enlat); | ||||
▲ Show 20 Lines • Show All 141 Lines • Show Last 20 Lines |
These would work only on little-endian