From 3c0b8367a2ce30c62befa431e1720df65cfc1f49 Mon Sep 17 00:00:00 2001 From: jimharris Date: Tue, 26 Mar 2013 21:00:18 +0000 Subject: Create struct nvme_status. NVMe error log entries include status, so breaking this out into its own data structure allows it to be included in both the nvme_completion data structure as well as error log entry data structures. While here, expose nvme_completion_is_error(), and change all of the places that were explicitly looking at sc/sct bits to use this macro instead. Sponsored by: Intel Reviewed by: carl --- sys/dev/nvme/nvme.c | 4 ++-- sys/dev/nvme/nvme.h | 30 +++++++++++++++++++----------- sys/dev/nvme/nvme_ctrlr.c | 12 ++++++------ sys/dev/nvme/nvme_ns.c | 8 ++++---- sys/dev/nvme/nvme_qpair.c | 19 ++++++------------- sys/dev/nvme/nvme_test.c | 4 ++-- sys/dev/nvme/nvme_uio.c | 4 ++-- 7 files changed, 41 insertions(+), 40 deletions(-) (limited to 'sys/dev/nvme') diff --git a/sys/dev/nvme/nvme.c b/sys/dev/nvme/nvme.c index 7630a1d..b9fcb4c 100644 --- a/sys/dev/nvme/nvme.c +++ b/sys/dev/nvme/nvme.c @@ -223,8 +223,8 @@ nvme_dump_completion(struct nvme_completion *cpl) printf("cdw0:%08x sqhd:%04x sqid:%04x " "cid:%04x p:%x sc:%02x sct:%x m:%x dnr:%x\n", cpl->cdw0, cpl->sqhd, cpl->sqid, - cpl->cid, cpl->p, cpl->sf_sc, cpl->sf_sct, cpl->sf_m, - cpl->sf_dnr); + cpl->cid, cpl->status.p, cpl->status.sc, cpl->status.sct, + cpl->status.m, cpl->status.dnr); } void diff --git a/sys/dev/nvme/nvme.h b/sys/dev/nvme/nvme.h index f7653fc..748261f 100644 --- a/sys/dev/nvme/nvme.h +++ b/sys/dev/nvme/nvme.h @@ -223,26 +223,31 @@ struct nvme_command uint32_t cdw15; /* command-specific */ } __packed; +struct nvme_status { + + uint16_t p : 1; /* phase tag */ + uint16_t sc : 8; /* status code */ + uint16_t sct : 3; /* status code type */ + uint16_t rsvd2 : 2; + uint16_t m : 1; /* more */ + uint16_t dnr : 1; /* do not retry */ +} __packed; + struct nvme_completion { /* dword 0 */ - uint32_t cdw0; /* command-specific */ + uint32_t cdw0; /* command-specific */ /* dword 1 */ - uint32_t rsvd1; + uint32_t rsvd1; /* dword 2 */ - uint16_t sqhd; /* submission queue head pointer */ - uint16_t sqid; /* submission queue identifier */ + uint16_t sqhd; /* submission queue head pointer */ + uint16_t sqid; /* submission queue identifier */ /* dword 3 */ - uint16_t cid; /* command identifier */ - uint16_t p : 1; /* phase tag */ - uint16_t sf_sc : 8; /* status field - status code */ - uint16_t sf_sct : 3; /* status field - status code type */ - uint16_t rsvd2 : 2; - uint16_t sf_m : 1; /* status field - more */ - uint16_t sf_dnr : 1; /* status field - do not retry */ + uint16_t cid; /* command identifier */ + struct nvme_status status; } __packed; struct nvme_dsm_range { @@ -686,6 +691,9 @@ enum nvme_io_test_flags { NVME_TEST_FLAG_REFTHREAD = 0x1, }; +#define nvme_completion_is_error(cpl) \ + ((cpl)->status.sc != 0 || (cpl)->status.sct != 0) + #ifdef _KERNEL struct bio; diff --git a/sys/dev/nvme/nvme_ctrlr.c b/sys/dev/nvme/nvme_ctrlr.c index 762cfe6..345be9c 100644 --- a/sys/dev/nvme/nvme_ctrlr.c +++ b/sys/dev/nvme/nvme_ctrlr.c @@ -447,7 +447,7 @@ nvme_ctrlr_identify(struct nvme_controller *ctrlr) nvme_ctrlr_cb, &cpl); status = msleep(&cpl, mtx, PRIBIO, "nvme_start", hz*5); mtx_unlock(mtx); - if ((status != 0) || cpl.sf_sc || cpl.sf_sct) { + if ((status != 0) || nvme_completion_is_error(&cpl)) { printf("nvme_identify_controller failed!\n"); return (ENXIO); } @@ -474,7 +474,7 @@ nvme_ctrlr_set_num_qpairs(struct nvme_controller *ctrlr) nvme_ctrlr_cb, &cpl); status = msleep(&cpl, mtx, PRIBIO, "nvme_start", hz*5); mtx_unlock(mtx); - if ((status != 0) || cpl.sf_sc || cpl.sf_sct) { + if ((status != 0) || nvme_completion_is_error(&cpl)) { printf("nvme_set_num_queues failed!\n"); return (ENXIO); } @@ -522,7 +522,7 @@ nvme_ctrlr_create_qpairs(struct nvme_controller *ctrlr) nvme_ctrlr_cb, &cpl); status = msleep(&cpl, mtx, PRIBIO, "nvme_start", hz*5); mtx_unlock(mtx); - if ((status != 0) || cpl.sf_sc || cpl.sf_sct) { + if ((status != 0) || nvme_completion_is_error(&cpl)) { printf("nvme_create_io_cq failed!\n"); return (ENXIO); } @@ -532,7 +532,7 @@ nvme_ctrlr_create_qpairs(struct nvme_controller *ctrlr) nvme_ctrlr_cb, &cpl); status = msleep(&cpl, mtx, PRIBIO, "nvme_start", hz*5); mtx_unlock(mtx); - if ((status != 0) || cpl.sf_sc || cpl.sf_sct) { + if ((status != 0) || nvme_completion_is_error(&cpl)) { printf("nvme_create_io_sq failed!\n"); return (ENXIO); } @@ -562,7 +562,7 @@ nvme_ctrlr_async_event_cb(void *arg, const struct nvme_completion *cpl) { struct nvme_async_event_request *aer = arg; - if (cpl->sf_sc == NVME_SC_ABORTED_SQ_DELETION) { + if (cpl->status.sc == NVME_SC_ABORTED_SQ_DELETION) { /* * This is simulated when controller is being shut down, to * effectively abort outstanding asynchronous event requests @@ -783,7 +783,7 @@ nvme_ctrlr_ioctl(struct cdev *cdev, u_long cmd, caddr_t arg, int flag, nvme_ctrlr_cb, &cpl); msleep(&cpl, mtx, PRIBIO, "nvme_ioctl", 0); mtx_unlock(mtx); - if (cpl.sf_sc || cpl.sf_sct) + if (nvme_completion_is_error(&cpl)) return (ENXIO); memcpy(arg, &ctrlr->cdata, sizeof(ctrlr->cdata)); break; diff --git a/sys/dev/nvme/nvme_ns.c b/sys/dev/nvme/nvme_ns.c index ad3c38a..51cb1f9 100644 --- a/sys/dev/nvme/nvme_ns.c +++ b/sys/dev/nvme/nvme_ns.c @@ -90,7 +90,7 @@ nvme_ns_ioctl(struct cdev *cdev, u_long cmd, caddr_t arg, int flag, nvme_ns_cb, &cpl); msleep(&cpl, mtx, PRIBIO, "nvme_ioctl", 0); mtx_unlock(mtx); - if (cpl.sf_sc || cpl.sf_sct) + if (nvme_completion_is_error(&cpl)) return (ENXIO); memcpy(arg, &ns->data, sizeof(ns->data)); break; @@ -132,7 +132,7 @@ nvme_ns_close(struct cdev *dev __unused, int flags, int fmt __unused, } static void -nvme_ns_strategy_done(void *arg, const struct nvme_completion *status) +nvme_ns_strategy_done(void *arg, const struct nvme_completion *cpl) { struct bio *bp = arg; @@ -140,7 +140,7 @@ nvme_ns_strategy_done(void *arg, const struct nvme_completion *status) * TODO: add more extensive translation of NVMe status codes * to different bio error codes (i.e. EIO, EINVAL, etc.) */ - if (status->sf_sc || status->sf_sct) { + if (nvme_completion_is_error(cpl)) { bp->bio_error = EIO; bp->bio_flags |= BIO_ERROR; bp->bio_resid = bp->bio_bcount; @@ -338,7 +338,7 @@ nvme_ns_construct(struct nvme_namespace *ns, uint16_t id, nvme_ns_cb, &cpl); status = msleep(&cpl, mtx, PRIBIO, "nvme_start", hz*5); mtx_unlock(mtx); - if ((status != 0) || cpl.sf_sc || cpl.sf_sct) { + if ((status != 0) || nvme_completion_is_error(&cpl)) { printf("nvme_identify_namespace failed!\n"); return (ENXIO); } diff --git a/sys/dev/nvme/nvme_qpair.c b/sys/dev/nvme/nvme_qpair.c index b6a2633..3841095 100644 --- a/sys/dev/nvme/nvme_qpair.c +++ b/sys/dev/nvme/nvme_qpair.c @@ -38,13 +38,6 @@ static void _nvme_qpair_submit_request(struct nvme_qpair *qpair, struct nvme_request *req); static boolean_t -nvme_completion_is_error(struct nvme_completion *cpl) -{ - - return (cpl->sf_sc != 0 || cpl->sf_sct != 0); -} - -static boolean_t nvme_completion_is_retry(const struct nvme_completion *cpl) { /* @@ -53,13 +46,13 @@ nvme_completion_is_retry(const struct nvme_completion *cpl) * NAMESPACE_NOT_READY is the only case where we should * look at the DNR bit. */ - switch (cpl->sf_sct) { + switch (cpl->status.sct) { case NVME_SCT_GENERIC: - switch (cpl->sf_sc) { + switch (cpl->status.sc) { case NVME_SC_ABORTED_BY_REQUEST: return (1); case NVME_SC_NAMESPACE_NOT_READY: - if (cpl->sf_dnr) + if (cpl->status.dnr) return (0); else return (1); @@ -168,8 +161,8 @@ nvme_qpair_manual_complete_tracker(struct nvme_qpair *qpair, memset(&cpl, 0, sizeof(cpl)); cpl.sqid = qpair->id; cpl.cid = tr->cid; - cpl.sf_sct = sct; - cpl.sf_sc = sc; + cpl.status.sct = sct; + cpl.status.sc = sc; nvme_qpair_complete_tracker(qpair, tr, &cpl, print_on_error); } @@ -193,7 +186,7 @@ nvme_qpair_process_completions(struct nvme_qpair *qpair) while (1) { cpl = &qpair->cpl[qpair->cq_head]; - if (cpl->p != qpair->phase) + if (cpl->status.p != qpair->phase) break; tr = qpair->act_tr[cpl->cid]; diff --git a/sys/dev/nvme/nvme_test.c b/sys/dev/nvme/nvme_test.c index 4177227..93e2ed9 100644 --- a/sys/dev/nvme/nvme_test.c +++ b/sys/dev/nvme/nvme_test.c @@ -172,14 +172,14 @@ nvme_ns_bio_test(void *arg) } static void -nvme_ns_io_test_cb(void *arg, const struct nvme_completion *status) +nvme_ns_io_test_cb(void *arg, const struct nvme_completion *cpl) { struct nvme_io_test_thread *tth = arg; struct timeval t; tth->io_completed++; - if (status->sf_sc || status->sf_sct) { + if (nvme_completion_is_error(cpl)) { printf("%s: error occurred\n", __func__); wakeup_one(tth); return; diff --git a/sys/dev/nvme/nvme_uio.c b/sys/dev/nvme/nvme_uio.c index 55c3a6b..1379def 100644 --- a/sys/dev/nvme/nvme_uio.c +++ b/sys/dev/nvme/nvme_uio.c @@ -35,12 +35,12 @@ __FBSDID("$FreeBSD$"); #include "nvme_private.h" static void -nvme_uio_done(void *arg, const struct nvme_completion *status) +nvme_uio_done(void *arg, const struct nvme_completion *cpl) { struct mtx *mtx; struct uio *uio = arg; - if (status->sf_sc == 0 && status->sf_sct == 0) + if (!nvme_completion_is_error(cpl)) uio->uio_resid = 0; mtx = mtx_pool_find(mtxpool_sleep, arg); -- cgit v1.1