diff --git a/sys/dev/ufshci/ufshci_req_queue.c b/sys/dev/ufshci/ufshci_req_queue.c --- a/sys/dev/ufshci/ufshci_req_queue.c +++ b/sys/dev/ufshci/ufshci_req_queue.c @@ -371,7 +371,7 @@ BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); } -static void +static int ufshci_req_queue_prepare_prdt(struct ufshci_tracker *tr) { struct ufshci_request *req = tr->req; @@ -403,6 +403,8 @@ UFSHCI_RESPONSE_CODE_GENERAL_FAILURE); mtx_lock(&tr->hwq->qlock); } + + return (error); } static void @@ -716,9 +718,15 @@ memcpy(tr->ucd, &req->request_upiu, request_len); memset((uint8_t *)tr->ucd + response_off, 0, response_len); - /* Prepare PRDT */ - if (req->payload_valid) - ufshci_req_queue_prepare_prdt(tr); + /* + * Prepare PRDT. If the payload could not be mapped, the + * tracker has already been completed and released by the + * manual completion path, so the descriptor must not be + * built and the doorbell must not be rung. + */ + if (req->payload_valid && + ufshci_req_queue_prepare_prdt(tr) != 0) + return; /* Prepare UTP Transfer Request Descriptor. */ ucd_paddr = tr->ucd_bus_addr;