summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjimharris <jimharris@FreeBSD.org>2013-03-26 21:00:18 +0000
committerjimharris <jimharris@FreeBSD.org>2013-03-26 21:00:18 +0000
commit3c0b8367a2ce30c62befa431e1720df65cfc1f49 (patch)
treead79338c72d5a2294eab91a297a57e1b956519e0
parentd0a775e7949e871c4beabbef339069ca9560c538 (diff)
downloadFreeBSD-src-3c0b8367a2ce30c62befa431e1720df65cfc1f49.zip
FreeBSD-src-3c0b8367a2ce30c62befa431e1720df65cfc1f49.tar.gz
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
-rw-r--r--sys/dev/nvd/nvd.c4
-rw-r--r--sys/dev/nvme/nvme.c4
-rw-r--r--sys/dev/nvme/nvme.h30
-rw-r--r--sys/dev/nvme/nvme_ctrlr.c12
-rw-r--r--sys/dev/nvme/nvme_ns.c8
-rw-r--r--sys/dev/nvme/nvme_qpair.c19
-rw-r--r--sys/dev/nvme/nvme_test.c4
-rw-r--r--sys/dev/nvme/nvme_uio.c4
8 files changed, 43 insertions, 42 deletions
diff --git a/sys/dev/nvd/nvd.c b/sys/dev/nvd/nvd.c
index 5072889..0eb1922 100644
--- a/sys/dev/nvd/nvd.c
+++ b/sys/dev/nvd/nvd.c
@@ -153,7 +153,7 @@ nvd_ioctl(struct disk *ndisk, u_long cmd, void *data, int fflag,
}
static void
-nvd_done(void *arg, const struct nvme_completion *status)
+nvd_done(void *arg, const struct nvme_completion *cpl)
{
struct bio *bp;
struct nvd_disk *ndisk;
@@ -168,7 +168,7 @@ nvd_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;
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);
OpenPOWER on IntegriCloud