From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([140.186.70.92]:38098) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1R0yzO-0005c7-FZ for qemu-devel@nongnu.org; Tue, 06 Sep 2011 12:59:21 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1R0yzM-0004ag-4h for qemu-devel@nongnu.org; Tue, 06 Sep 2011 12:59:10 -0400 Received: from oxygen.pond.sub.org ([78.46.104.156]:55975) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1R0yzL-0004YP-CT for qemu-devel@nongnu.org; Tue, 06 Sep 2011 12:59:07 -0400 From: Markus Armbruster Date: Tue, 6 Sep 2011 18:58:49 +0200 Message-Id: <1315328340-6192-17-git-send-email-armbru@redhat.com> In-Reply-To: <1315328340-6192-1-git-send-email-armbru@redhat.com> References: <1315328340-6192-1-git-send-email-armbru@redhat.com> Subject: [Qemu-devel] [PATCH v3 16/27] scsi-disk: Fix START_STOP to fail when it can't eject List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: kwolf@redhat.com, stefano.stabellini@eu.citrix.com, lcapitulino@redhat.com, hare@suse.de, amit.shah@redhat.com, pbonzini@redhat.com, hch@lst.de Don't fail when tray is already open. Signed-off-by: Markus Armbruster --- hw/scsi-bus.c | 10 ++++++++++ hw/scsi-disk.c | 15 +++++++++++---- hw/scsi.h | 4 ++++ 3 files changed, 25 insertions(+), 4 deletions(-) diff --git a/hw/scsi-bus.c b/hw/scsi-bus.c index 160eaee..79cb29d 100644 --- a/hw/scsi-bus.c +++ b/hw/scsi-bus.c @@ -772,6 +772,11 @@ const struct SCSISense sense_code_NO_MEDIUM = { .key = NOT_READY, .asc = 0x3a, .ascq = 0x00 }; +/* LUN not ready, medium removal prevented */ +const struct SCSISense sense_code_NOT_READY_REMOVAL_PREVENTED = { + .key = NOT_READY, .asc = 0x53, .ascq = 0x00 +}; + /* Hardware error, internal target failure */ const struct SCSISense sense_code_TARGET_FAILURE = { .key = HARDWARE_ERROR, .asc = 0x44, .ascq = 0x00 @@ -807,6 +812,11 @@ const struct SCSISense sense_code_INCOMPATIBLE_MEDIUM = { .key = ILLEGAL_REQUEST, .asc = 0x30, .ascq = 0x00 }; +/* Illegal request, medium removal prevented */ +const struct SCSISense sense_code_ILLEGAL_REQ_REMOVAL_PREVENTED = { + .key = ILLEGAL_REQUEST, .asc = 0x53, .ascq = 0x00 +}; + /* Command aborted, I/O process terminated */ const struct SCSISense sense_code_IO_ERROR = { .key = ABORTED_COMMAND, .asc = 0x00, .ascq = 0x06 diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c index 4e89bb1..1a49217 100644 --- a/hw/scsi-disk.c +++ b/hw/scsi-disk.c @@ -822,7 +822,7 @@ static int scsi_disk_emulate_read_toc(SCSIRequest *req, uint8_t *outbuf) return toclen; } -static void scsi_disk_emulate_start_stop(SCSIDiskReq *r) +static int scsi_disk_emulate_start_stop(SCSIDiskReq *r) { SCSIRequest *req = &r->req; SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, req->dev); @@ -830,12 +830,17 @@ static void scsi_disk_emulate_start_stop(SCSIDiskReq *r) bool loej = req->cmd.buf[4] & 2; /* load on start, eject on !start */ if (s->qdev.type == TYPE_ROM && loej) { - if (!start && s->tray_locked) { - return; + if (!start && !s->tray_open && s->tray_locked) { + scsi_check_condition(r, + bdrv_is_inserted(s->bs) + ? SENSE_CODE(ILLEGAL_REQ_REMOVAL_PREVENTED) + : SENSE_CODE(NOT_READY_REMOVAL_PREVENTED)); + return -1; } bdrv_eject(s->bs, !start); s->tray_open = !start; } + return 0; } static int scsi_disk_emulate_command(SCSIDiskReq *r, uint8_t *outbuf) @@ -883,7 +888,9 @@ static int scsi_disk_emulate_command(SCSIDiskReq *r, uint8_t *outbuf) goto illegal_request; break; case START_STOP: - scsi_disk_emulate_start_stop(r); + if (scsi_disk_emulate_start_stop(r) < 0) { + return -1; + } break; case ALLOW_MEDIUM_REMOVAL: s->tray_locked = req->cmd.buf[4] & 1; diff --git a/hw/scsi.h b/hw/scsi.h index 98fd689..a28cd68 100644 --- a/hw/scsi.h +++ b/hw/scsi.h @@ -136,6 +136,8 @@ extern const struct SCSISense sense_code_NO_SENSE; extern const struct SCSISense sense_code_LUN_NOT_READY; /* LUN not ready, Medium not present */ extern const struct SCSISense sense_code_NO_MEDIUM; +/* LUN not ready, medium removal prevented */ +extern const struct SCSISense sense_code_NOT_READY_REMOVAL_PREVENTED; /* Hardware error, internal target failure */ extern const struct SCSISense sense_code_TARGET_FAILURE; /* Illegal request, invalid command operation code */ @@ -150,6 +152,8 @@ extern const struct SCSISense sense_code_LUN_NOT_SUPPORTED; extern const struct SCSISense sense_code_SAVING_PARAMS_NOT_SUPPORTED; /* Illegal request, Incompatible format */ extern const struct SCSISense sense_code_INCOMPATIBLE_FORMAT; +/* Illegal request, medium removal prevented */ +extern const struct SCSISense sense_code_ILLEGAL_REQ_REMOVAL_PREVENTED; /* Command aborted, I/O process terminated */ extern const struct SCSISense sense_code_IO_ERROR; /* Command aborted, I_T Nexus loss occurred */ -- 1.7.6