diff options
author | jimharris <jimharris@FreeBSD.org> | 2013-03-26 22:09:51 +0000 |
---|---|---|
committer | jimharris <jimharris@FreeBSD.org> | 2013-03-26 22:09:51 +0000 |
commit | 5242be57d3d5eddc6859707cd02c511befa48366 (patch) | |
tree | 725967903e5c9ed2b6a4a7806d1dd92c05c26182 /sys/dev/nvme/nvme_ctrlr.c | |
parent | ff567ee3e1dfdf36fd8473b02ec9e68996b6c960 (diff) | |
download | FreeBSD-src-5242be57d3d5eddc6859707cd02c511befa48366.zip FreeBSD-src-5242be57d3d5eddc6859707cd02c511befa48366.tar.gz |
Replace usages of mtx_pool_find used for admin commands with a polling
mechanism.
Now that all requests are timed, we are guaranteed to get a completion
notification, even if it is an abort status due to a timed out admin
command.
This has the effect of simplifying the controller and namespace setup
code, so that it reads straight through rather than broken up into
a bunch of different callback functions.
Sponsored by: Intel
Reviewed by: carl
Diffstat (limited to 'sys/dev/nvme/nvme_ctrlr.c')
-rw-r--r-- | sys/dev/nvme/nvme_ctrlr.c | 100 |
1 files changed, 35 insertions, 65 deletions
diff --git a/sys/dev/nvme/nvme_ctrlr.c b/sys/dev/nvme/nvme_ctrlr.c index 19c06e5..ff7a741 100644 --- a/sys/dev/nvme/nvme_ctrlr.c +++ b/sys/dev/nvme/nvme_ctrlr.c @@ -41,24 +41,6 @@ __FBSDID("$FreeBSD$"); static void nvme_ctrlr_construct_and_submit_aer(struct nvme_controller *ctrlr, struct nvme_async_event_request *aer); -static void -nvme_ctrlr_cb(void *arg, const struct nvme_completion *status) -{ - struct nvme_completion *cpl = arg; - struct mtx *mtx; - - /* - * Copy status into the argument passed by the caller, so that - * the caller can check the status to determine if the - * the request passed or failed. - */ - memcpy(cpl, status, sizeof(*cpl)); - mtx = mtx_pool_find(mtxpool_sleep, cpl); - mtx_lock(mtx); - wakeup(cpl); - mtx_unlock(mtx); -} - static int nvme_ctrlr_allocate_bar(struct nvme_controller *ctrlr) { @@ -479,18 +461,14 @@ nvme_ctrlr_reset(struct nvme_controller *ctrlr) static int nvme_ctrlr_identify(struct nvme_controller *ctrlr) { - struct mtx *mtx; - struct nvme_completion cpl; - int status; - - mtx = mtx_pool_find(mtxpool_sleep, &cpl); + struct nvme_completion_poll_status status; - mtx_lock(mtx); + status.done = FALSE; nvme_ctrlr_cmd_identify_controller(ctrlr, &ctrlr->cdata, - nvme_ctrlr_cb, &cpl); - status = msleep(&cpl, mtx, PRIBIO, "nvme_start", hz*5); - mtx_unlock(mtx); - if ((status != 0) || nvme_completion_is_error(&cpl)) { + nvme_completion_poll_cb, &status); + while (status.done == FALSE) + DELAY(5); + if (nvme_completion_is_error(&status.cpl)) { printf("nvme_identify_controller failed!\n"); return (ENXIO); } @@ -514,18 +492,15 @@ nvme_ctrlr_identify(struct nvme_controller *ctrlr) static int nvme_ctrlr_set_num_qpairs(struct nvme_controller *ctrlr) { - struct mtx *mtx; - struct nvme_completion cpl; - int cq_allocated, sq_allocated, status; - - mtx = mtx_pool_find(mtxpool_sleep, &cpl); + struct nvme_completion_poll_status status; + int cq_allocated, sq_allocated; - mtx_lock(mtx); + status.done = FALSE; nvme_ctrlr_cmd_set_num_queues(ctrlr, ctrlr->num_io_queues, - nvme_ctrlr_cb, &cpl); - status = msleep(&cpl, mtx, PRIBIO, "nvme_start", hz*5); - mtx_unlock(mtx); - if ((status != 0) || nvme_completion_is_error(&cpl)) { + nvme_completion_poll_cb, &status); + while (status.done == FALSE) + DELAY(5); + if (nvme_completion_is_error(&status.cpl)) { printf("nvme_set_num_queues failed!\n"); return (ENXIO); } @@ -535,8 +510,8 @@ nvme_ctrlr_set_num_qpairs(struct nvme_controller *ctrlr) * Lower 16-bits indicate number of submission queues allocated. * Upper 16-bits indicate number of completion queues allocated. */ - sq_allocated = (cpl.cdw0 & 0xFFFF) + 1; - cq_allocated = (cpl.cdw0 >> 16) + 1; + sq_allocated = (status.cpl.cdw0 & 0xFFFF) + 1; + cq_allocated = (status.cpl.cdw0 >> 16) + 1; /* * Check that the controller was able to allocate the number of @@ -558,32 +533,29 @@ nvme_ctrlr_set_num_qpairs(struct nvme_controller *ctrlr) static int nvme_ctrlr_create_qpairs(struct nvme_controller *ctrlr) { - struct mtx *mtx; - struct nvme_qpair *qpair; - struct nvme_completion cpl; - int i, status; - - mtx = mtx_pool_find(mtxpool_sleep, &cpl); + struct nvme_completion_poll_status status; + struct nvme_qpair *qpair; + int i; for (i = 0; i < ctrlr->num_io_queues; i++) { qpair = &ctrlr->ioq[i]; - mtx_lock(mtx); + status.done = FALSE; nvme_ctrlr_cmd_create_io_cq(ctrlr, qpair, qpair->vector, - nvme_ctrlr_cb, &cpl); - status = msleep(&cpl, mtx, PRIBIO, "nvme_start", hz*5); - mtx_unlock(mtx); - if ((status != 0) || nvme_completion_is_error(&cpl)) { + nvme_completion_poll_cb, &status); + while (status.done == FALSE) + DELAY(5); + if (nvme_completion_is_error(&status.cpl)) { printf("nvme_create_io_cq failed!\n"); return (ENXIO); } - mtx_lock(mtx); + status.done = FALSE; nvme_ctrlr_cmd_create_io_sq(qpair->ctrlr, qpair, - nvme_ctrlr_cb, &cpl); - status = msleep(&cpl, mtx, PRIBIO, "nvme_start", hz*5); - mtx_unlock(mtx); - if ((status != 0) || nvme_completion_is_error(&cpl)) { + nvme_completion_poll_cb, &status); + while (status.done == FALSE) + DELAY(5); + if (nvme_completion_is_error(&status.cpl)) { printf("nvme_create_io_sq failed!\n"); return (ENXIO); } @@ -906,9 +878,8 @@ static int nvme_ctrlr_ioctl(struct cdev *cdev, u_long cmd, caddr_t arg, int flag, struct thread *td) { - struct nvme_controller *ctrlr; - struct nvme_completion cpl; - struct mtx *mtx; + struct nvme_completion_poll_status status; + struct nvme_controller *ctrlr; ctrlr = cdev->si_drv1; @@ -925,13 +896,12 @@ nvme_ctrlr_ioctl(struct cdev *cdev, u_long cmd, caddr_t arg, int flag, } #endif /* Refresh data before returning to user. */ - mtx = mtx_pool_find(mtxpool_sleep, &cpl); - mtx_lock(mtx); + status.done = FALSE; nvme_ctrlr_cmd_identify_controller(ctrlr, &ctrlr->cdata, - nvme_ctrlr_cb, &cpl); - msleep(&cpl, mtx, PRIBIO, "nvme_ioctl", 0); - mtx_unlock(mtx); - if (nvme_completion_is_error(&cpl)) + nvme_completion_poll_cb, &status); + while (status.done == FALSE) + DELAY(5); + if (nvme_completion_is_error(&status.cpl)) return (ENXIO); memcpy(arg, &ctrlr->cdata, sizeof(ctrlr->cdata)); break; |