Existing callers of ufs_clear_req() only invoke it after requests are no longer in flight. In preparation for Task Management Request (TMR) task abort and MCQ queue cleanup support, where individual in-flight requests are aborted without purging the entire SCSI device, track the active SCSIRequest in UfsRequest and cancel any pending request via scsi_req_cancel() in ufs_clear_req().
Signed-off-by: Stanley Jhu <[email protected]> --- hw/ufs/lu.c | 8 ++++++++ hw/ufs/ufs.c | 6 ++++++ hw/ufs/ufs.h | 1 + 3 files changed, 15 insertions(+) diff --git a/hw/ufs/lu.c b/hw/ufs/lu.c index bdb165085..5905c49fa 100644 --- a/hw/ufs/lu.c +++ b/hw/ufs/lu.c @@ -173,6 +173,9 @@ static void ufs_scsi_command_complete(SCSIRequest *scsi_req, size_t resid) int16_t status = scsi_req->status; uint32_t transfered_len = scsi_req->cmd.xfer - resid; + assert(req != NULL); + req->sreq = NULL; + /* WB / HID accounting should only happen for successful commands */ if (status == GOOD) { ufs_wb_process_write_req(req, transfered_len); @@ -190,6 +193,10 @@ static void ufs_scsi_command_complete(SCSIRequest *scsi_req, size_t resid) static void ufs_scsi_command_cancelled(SCSIRequest *scsi_req) { + UfsRequest *req = scsi_req->hba_private; + + assert(req != NULL); + req->sreq = NULL; scsi_req->hba_private = NULL; scsi_req_unref(scsi_req); } @@ -389,6 +396,7 @@ static UfsReqResult ufs_process_scsi_cmd(UfsLu *lu, UfsRequest *req) SCSIRequest *scsi_req = scsi_req_new(lu->scsi_dev, task_tag, lu->lun, req->req_upiu.sc.cdb, UFS_CDB_SIZE, req); + req->sreq = scsi_req; uint32_t len = scsi_req_enqueue(scsi_req); if (len) { diff --git a/hw/ufs/ufs.c b/hw/ufs/ufs.c index 3c4d7424d..adae6639e 100644 --- a/hw/ufs/ufs.c +++ b/hw/ufs/ufs.c @@ -2221,6 +2221,12 @@ void ufs_complete_req(UfsRequest *req, UfsReqResult req_result) static void ufs_clear_req(UfsRequest *req) { + if (req->sreq != NULL) { + SCSIRequest *sreq = req->sreq; + req->sreq = NULL; + scsi_req_cancel(sreq); + } + if (req->sg != NULL) { qemu_sglist_destroy(req->sg); g_free(req->sg); diff --git a/hw/ufs/ufs.h b/hw/ufs/ufs.h index 6f2693b7c..265a43faa 100644 --- a/hw/ufs/ufs.h +++ b/hw/ufs/ufs.h @@ -60,6 +60,7 @@ typedef struct UfsRequest { UtpUpiuRsp rsp_upiu; /* for scsi command */ + SCSIRequest *sreq; QEMUSGList *sg; uint32_t data_len; -- 2.56.0.rc1.315.gc6ed9934b7-goog
