Index: sys/dev/nvme/nvme.h =================================================================== --- sys/dev/nvme/nvme.h +++ sys/dev/nvme/nvme.h @@ -128,11 +128,11 @@ #define NVME_STATUS_DNR_SHIFT (15) #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_SC(st) (((st) >> NVME_STATUS_SC_SHIFT) & NVME_STATUS_SC_MASK) -#define NVME_STATUS_GET_SCT(st) (((st) >> NVME_STATUS_SCT_SHIFT) & NVME_STATUS_SCT_MASK) -#define NVME_STATUS_GET_M(st) (((st) >> NVME_STATUS_M_SHIFT) & NVME_STATUS_M_MASK) -#define NVME_STATUS_GET_DNR(st) (((st) >> NVME_STATUS_DNR_SHIFT) & NVME_STATUS_DNR_MASK) +#define NVME_STATUS_GET_P(st) (st.p) +#define NVME_STATUS_GET_SC(st) (st.sc) +#define NVME_STATUS_GET_SCT(st) (st.sct) +#define NVME_STATUS_GET_M(st) (st.m) +#define NVME_STATUS_GET_DNR(st) (st.dnr) #define NVME_PWR_ST_MPS_SHIFT (0) #define NVME_PWR_ST_MPS_MASK (0x1) @@ -428,7 +428,21 @@ struct nvme_command { /* dword 0 */ - uint16_t opc_fuse; /* opcode, fused operation */ + union { + 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 */ /* dword 1 */ @@ -458,6 +472,24 @@ _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 */ +#endif +} __packed; + struct nvme_completion { /* dword 0 */ @@ -472,7 +504,7 @@ /* dword 3 */ uint16_t cid; /* command identifier */ - uint16_t status; + struct nvme_status status; } __packed; _Static_assert(sizeof(struct nvme_completion) == 4 * 4, "bad size for nvme_completion"); @@ -1336,7 +1368,7 @@ s->sqhd = le16toh(s->sqhd); s->sqid = le16toh(s->sqid); /* omit cid */ - s->status = le16toh(s->status); +// s->status = le16toh(s->status); } static inline Index: sys/dev/nvme/nvme.c =================================================================== --- sys/dev/nvme/nvme.c +++ sys/dev/nvme/nvme.c @@ -240,9 +240,11 @@ nvme_dump_completion(struct nvme_completion *cpl) { uint8_t p, sc, sct, m, dnr; - uint16_t status; +// uint16_t status; + struct nvme_status status; - status = le16toh(cpl->status); +// status = le16toh(cpl->status); + status = cpl->status; p = NVME_STATUS_GET_P(status); sc = NVME_STATUS_GET_SC(status); Index: sys/dev/nvme/nvme_ctrlr.c =================================================================== --- sys/dev/nvme/nvme_ctrlr.c +++ sys/dev/nvme/nvme_ctrlr.c @@ -978,13 +978,13 @@ nvme_pt_done(void *arg, const struct nvme_completion *cpl) { struct nvme_pt_command *pt = arg; - uint16_t status; + struct nvme_status status; bzero(&pt->cpl, sizeof(pt->cpl)); pt->cpl.cdw0 = cpl->cdw0; status = cpl->status; - status &= ~NVME_STATUS_P_MASK; + status.p = 0; pt->cpl.status = status; mtx_lock(pt->driver_lock); Index: sys/dev/nvme/nvme_ns.c =================================================================== --- sys/dev/nvme/nvme_ns.c +++ sys/dev/nvme/nvme_ns.c @@ -272,10 +272,8 @@ inbed = atomic_fetchadd_int(&parent->bio_inbed, 1) + 1; if (inbed == children) { bzero(&parent_cpl, sizeof(parent_cpl)); - if (parent->bio_flags & BIO_ERROR) { - parent_cpl.status &= ~(NVME_STATUS_SC_MASK << NVME_STATUS_SC_SHIFT); - parent_cpl.status |= (NVME_SC_DATA_TRANSFER_ERROR) << NVME_STATUS_SC_SHIFT; - } + if (parent->bio_flags & BIO_ERROR) + parent_cpl.status.sc = NVME_SC_DATA_TRANSFER_ERROR; nvme_ns_bio_done(parent, &parent_cpl); } } Index: sys/dev/nvme/nvme_qpair.c =================================================================== --- sys/dev/nvme/nvme_qpair.c +++ sys/dev/nvme/nvme_qpair.c @@ -437,9 +437,9 @@ memset(&cpl, 0, sizeof(cpl)); cpl.sqid = qpair->id; cpl.cid = tr->cid; - cpl.status |= (sct & NVME_STATUS_SCT_MASK) << NVME_STATUS_SCT_SHIFT; - cpl.status |= (sc & NVME_STATUS_SC_MASK) << NVME_STATUS_SC_SHIFT; - cpl.status |= (dnr & NVME_STATUS_DNR_MASK) << NVME_STATUS_DNR_SHIFT; + cpl.status.sct = sct; + cpl.status.sc = sc; + cpl.status.dnr = dnr; nvme_qpair_complete_tracker(qpair, tr, &cpl, print_on_error); } @@ -453,8 +453,8 @@ memset(&cpl, 0, sizeof(cpl)); cpl.sqid = qpair->id; - cpl.status |= (sct & NVME_STATUS_SCT_MASK) << NVME_STATUS_SCT_SHIFT; - cpl.status |= (sc & NVME_STATUS_SC_MASK) << NVME_STATUS_SC_SHIFT; + cpl.status.sct = sct; + cpl.status.sc = sc; error = nvme_completion_is_error(&cpl);