Do not panic when a busdma mapping operation fails.

Instead, print an error message and fail the associated command with
DATA_TRANSFER_ERROR NVMe completion status.

Sponsored by:	Intel
This commit is contained in:
jimharris 2013-04-12 17:34:49 +00:00
parent ad2a2fb3b7
commit 92ebbf5a66
2 changed files with 28 additions and 5 deletions

View File

@ -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

View File

@ -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