From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([140.186.70.92]:45700) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QobRS-0004I4-3H for qemu-devel@nongnu.org; Wed, 03 Aug 2011 09:24:59 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1QobRN-0004tk-LV for qemu-devel@nongnu.org; Wed, 03 Aug 2011 09:24:57 -0400 Received: from oxygen.pond.sub.org ([78.46.104.156]:50170) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QobRM-0004st-Vb for qemu-devel@nongnu.org; Wed, 03 Aug 2011 09:24:53 -0400 From: Markus Armbruster Date: Wed, 3 Aug 2011 15:08:02 +0200 Message-Id: <1312376904-16115-24-git-send-email-armbru@redhat.com> In-Reply-To: <1312376904-16115-1-git-send-email-armbru@redhat.com> References: <1312376904-16115-1-git-send-email-armbru@redhat.com> Subject: [Qemu-devel] [PATCH v2 23/45] 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, quintela@redhat.com, stefano.stabellini@eu.citrix.com, lcapitulino@redhat.com, hare@suse.de, amit.shah@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 0b0344c..1c5fe7f 100644 --- a/hw/scsi-bus.c +++ b/hw/scsi-bus.c @@ -441,6 +441,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_MEDIUM_REMOVAL_PREVENTED_NR = { + .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 @@ -466,6 +471,11 @@ const struct SCSISense sense_code_LUN_NOT_SUPPORTED = { .key = ILLEGAL_REQUEST, .asc = 0x25, .ascq = 0x00 }; +/* Illegal request, medium removal prevented */ +const struct SCSISense sense_code_MEDIUM_REMOVAL_PREVENTED_ILL = { + .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 79d7737..19a1843 100644 --- a/hw/scsi-disk.c +++ b/hw/scsi-disk.c @@ -828,7 +828,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); @@ -836,12 +836,17 @@ static void scsi_disk_emulate_start_stop(SCSIDiskReq *r) bool loej = req->cmd.buf[4] & 2; if (s->qdev.type == TYPE_ROM && loej) { - if (!start && s->tray_locked) { - return; + if (!start && !s->tray_open && s->tray_locked) { + scsi_command_complete(r, CHECK_CONDITION, + bdrv_is_inserted(s->bs) + ? SENSE_CODE(MEDIUM_REMOVAL_PREVENTED_ILL) + : SENSE_CODE(MEDIUM_REMOVAL_PREVENTED_NR)); + return -1; } bdrv_eject(s->bs, !start); s->tray_open = !start; } + return 0; } static int scsi_disk_emulate_command(SCSIDiskReq *r, uint8_t *outbuf) @@ -897,7 +902,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 6b15bbc..63442c6 100644 --- a/hw/scsi.h +++ b/hw/scsi.h @@ -118,6 +118,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 readt, medium removal prevented */ +extern const struct SCSISense sense_code_MEDIUM_REMOVAL_PREVENTED_NR; /* Hardware error, internal target failure */ extern const struct SCSISense sense_code_TARGET_FAILURE; /* Illegal request, invalid command operation code */ @@ -128,6 +130,8 @@ extern const struct SCSISense sense_code_LBA_OUT_OF_RANGE; extern const struct SCSISense sense_code_INVALID_FIELD; /* Illegal request, LUN not supported */ extern const struct SCSISense sense_code_LUN_NOT_SUPPORTED; +/* Illegal request, medium removal prevented */ +extern const struct SCSISense sense_code_MEDIUM_REMOVAL_PREVENTED_ILL; /* Command aborted, I/O process terminated */ extern const struct SCSISense sense_code_IO_ERROR; /* Command aborted, I_T Nexus loss occurred */ -- 1.7.6