diff options
-rw-r--r-- | sys/dev/nvme/nvme.c | 8 | ||||
-rw-r--r-- | sys/dev/nvme/nvme_qpair.c | 25 |
2 files changed, 28 insertions, 5 deletions
diff --git a/sys/dev/nvme/nvme.c b/sys/dev/nvme/nvme.c index dfc4917..616b84c 100644 --- a/sys/dev/nvme/nvme.c +++ b/sys/dev/nvme/nvme.c @@ -235,7 +235,13 @@ nvme_payload_map(void *arg, bus_dma_segment_t *seg, int nseg, int error) struct nvme_tracker *tr = arg; uint32_t cur_nseg; - KASSERT(error == 0, ("nvme_payload_map error != 0\n")); + /* + * If the mapping operation failed, return immediately. The caller + * is responsible for detecting the error status and failing the + * tracker manually. + */ + if (error != 0) + return; /* * Note that we specified PAGE_SIZE for alignment and max diff --git a/sys/dev/nvme/nvme_qpair.c b/sys/dev/nvme/nvme_qpair.c index aa9f77b..9a73bd2 100644 --- a/sys/dev/nvme/nvme_qpair.c +++ b/sys/dev/nvme/nvme_qpair.c @@ -702,7 +702,7 @@ static void _nvme_qpair_submit_request(struct nvme_qpair *qpair, struct nvme_request *req) { struct nvme_tracker *tr; - int err; + int err = 0; mtx_assert(&qpair->lock, MA_OWNED); @@ -745,7 +745,8 @@ _nvme_qpair_submit_request(struct nvme_qpair *qpair, struct nvme_request *req) err = bus_dmamap_load(tr->qpair->dma_tag, tr->payload_dma_map, req->u.payload, req->payload_size, nvme_payload_map, tr, 0); if (err != 0) - panic("bus_dmamap_load returned non-zero!\n"); + nvme_printf(qpair->ctrlr, + "bus_dmamap_load returned 0x%x!\n", err); break; case NVME_REQUEST_NULL: nvme_qpair_submit_tracker(tr->qpair, tr); @@ -755,20 +756,36 @@ _nvme_qpair_submit_request(struct nvme_qpair *qpair, struct nvme_request *req) tr->payload_dma_map, req->u.uio, nvme_payload_map_uio, tr, 0); if (err != 0) - panic("bus_dmamap_load_uio returned non-zero!\n"); + nvme_printf(qpair->ctrlr, + "bus_dmamap_load_uio returned 0x%x!\n", err); break; #ifdef NVME_UNMAPPED_BIO_SUPPORT case NVME_REQUEST_BIO: err = bus_dmamap_load_bio(tr->qpair->dma_tag, tr->payload_dma_map, req->u.bio, nvme_payload_map, tr, 0); if (err != 0) - panic("bus_dmamap_load_bio returned non-zero!\n"); + nvme_printf(qpair->ctrlr, + "bus_dmamap_load_bio returned 0x%x!\n", err); break; #endif default: panic("unknown nvme request type 0x%x\n", req->type); break; } + + if (err != 0) { + /* + * The dmamap operation failed, so we manually fail the + * tracker here with DATA_TRANSFER_ERROR status. + * + * nvme_qpair_manual_complete_tracker must not be called + * with the qpair lock held. + */ + mtx_unlock(&qpair->lock); + nvme_qpair_manual_complete_tracker(qpair, tr, NVME_SCT_GENERIC, + NVME_SC_DATA_TRANSFER_ERROR, 1 /* do not retry */, TRUE); + mtx_lock(&qpair->lock); + } } void |