From 0a784c45a7b7ee32c36bf86eebb24c8431a89f49 Mon Sep 17 00:00:00 2001 From: Stefano Garzarella Date: Wed, 12 Jul 2023 15:43:52 +0200 Subject: [PATCH 03/12] scsi: clear unit attention only for REPORT LUNS commands RH-Author: Stefano Garzarella RH-MergeRequest: 184: scsi: fix issue with Linux guest and unit attention RH-Bugzilla: 2176702 RH-Acked-by: Thomas Huth RH-Acked-by: Paolo Bonzini RH-Acked-by: Stefan Hajnoczi RH-Commit: [3/3] 01d5e112ef9ae204d96ceb01b4a453fdb4e8b669 (sgarzarella/qemu-kvm-c-9-s) scsi_clear_unit_attention() now only handles REPORTED LUNS DATA HAS CHANGED. This only happens when we handle REPORT LUNS commands, so let's rename the function in scsi_clear_reported_luns_changed() and call it only in scsi_target_emulate_report_luns(). Suggested-by: Paolo Bonzini Signed-off-by: Stefano Garzarella Message-ID: <20230712134352.118655-4-sgarzare@redhat.com> Signed-off-by: Paolo Bonzini (cherry picked from commit 2eb5599e8a73e70a9e86a97120818ff95a43a23a) Signed-off-by: Stefano Garzarella --- hw/scsi/scsi-bus.c | 34 +++++++++++----------------------- 1 file changed, 11 insertions(+), 23 deletions(-) diff --git a/hw/scsi/scsi-bus.c b/hw/scsi/scsi-bus.c index cecd26479e..9542410800 100644 --- a/hw/scsi/scsi-bus.c +++ b/hw/scsi/scsi-bus.c @@ -22,6 +22,7 @@ static char *scsibus_get_fw_dev_path(DeviceState *dev); static void scsi_req_dequeue(SCSIRequest *req); static uint8_t *scsi_target_alloc_buf(SCSIRequest *req, size_t len); static void scsi_target_free_buf(SCSIRequest *req); +static void scsi_clear_reported_luns_changed(SCSIRequest *req); static int next_scsi_bus; @@ -518,6 +519,14 @@ static bool scsi_target_emulate_report_luns(SCSITargetReq *r) /* store the LUN list length */ stl_be_p(&r->buf[0], len - 8); + + /* + * If a REPORT LUNS command enters the enabled command state, [...] + * the device server shall clear any pending unit attention condition + * with an additional sense code of REPORTED LUNS DATA HAS CHANGED. + */ + scsi_clear_reported_luns_changed(&r->req); + return true; } @@ -816,18 +825,10 @@ uint8_t *scsi_req_get_buf(SCSIRequest *req) return req->ops->get_buf(req); } -static void scsi_clear_unit_attention(SCSIRequest *req) +static void scsi_clear_reported_luns_changed(SCSIRequest *req) { SCSISense *ua; - /* - * scsi_fetch_unit_attention_sense() already cleaned the unit attention - * in this case. - */ - if (req->ops == &reqops_unit_attention) { - return; - } - if (req->dev->unit_attention.key == UNIT_ATTENTION) { ua = &req->dev->unit_attention; } else if (req->bus->unit_attention.key == UNIT_ATTENTION) { @@ -836,13 +837,7 @@ static void scsi_clear_unit_attention(SCSIRequest *req) return; } - /* - * If a REPORT LUNS command enters the enabled command state, [...] - * the device server shall clear any pending unit attention condition - * with an additional sense code of REPORTED LUNS DATA HAS CHANGED. - */ - if (req->cmd.buf[0] == REPORT_LUNS && - ua->asc == SENSE_CODE(REPORTED_LUNS_CHANGED).asc && + if (ua->asc == SENSE_CODE(REPORTED_LUNS_CHANGED).asc && ua->ascq == SENSE_CODE(REPORTED_LUNS_CHANGED).ascq) { *ua = SENSE_CODE(NO_SENSE); } @@ -1528,13 +1523,6 @@ void scsi_req_complete(SCSIRequest *req, int status) req->dev->sense_is_ua = false; } - /* - * Unit attention state is now stored in the device's sense buffer - * if the HBA didn't do autosense. Clear the pending unit attention - * flags. - */ - scsi_clear_unit_attention(req); - scsi_req_ref(req); scsi_req_dequeue(req); req->bus->info->complete(req, req->residual); -- 2.39.3