From patchwork Mon Sep 12 14:19:19 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kevin Wolf X-Patchwork-Id: 114347 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [140.186.70.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 2EE1CB70D6 for ; Tue, 13 Sep 2011 00:18:38 +1000 (EST) Received: from localhost ([::1]:41564 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1R37LH-0003t7-E4 for incoming@patchwork.ozlabs.org; Mon, 12 Sep 2011 10:18:35 -0400 Received: from eggs.gnu.org ([140.186.70.92]:38488) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1R37Js-0001Ve-Bt for qemu-devel@nongnu.org; Mon, 12 Sep 2011 10:17:13 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1R37Jq-000776-QM for qemu-devel@nongnu.org; Mon, 12 Sep 2011 10:17:08 -0400 Received: from mx1.redhat.com ([209.132.183.28]:13814) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1R37Jq-00076t-JC for qemu-devel@nongnu.org; Mon, 12 Sep 2011 10:17:06 -0400 Received: from int-mx01.intmail.prod.int.phx2.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id p8CEH4Y9023797 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Mon, 12 Sep 2011 10:17:04 -0400 Received: from dhcp-5-188.str.redhat.com (dhcp-5-175.str.redhat.com [10.32.5.175]) by int-mx01.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id p8CEGa2p030698; Mon, 12 Sep 2011 10:17:03 -0400 From: Kevin Wolf To: anthony@codemonkey.ws Date: Mon, 12 Sep 2011 16:19:19 +0200 Message-Id: <1315837174-15327-21-git-send-email-kwolf@redhat.com> In-Reply-To: <1315837174-15327-1-git-send-email-kwolf@redhat.com> References: <1315837174-15327-1-git-send-email-kwolf@redhat.com> X-Scanned-By: MIMEDefang 2.67 on 10.5.11.11 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 209.132.183.28 Cc: kwolf@redhat.com, qemu-devel@nongnu.org Subject: [Qemu-devel] [PATCH 20/35] scsi-disk: Fix START_STOP to fail when it can't eject X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org From: Markus Armbruster Don't fail when tray is already open. Signed-off-by: Markus Armbruster Signed-off-by: Kevin Wolf --- 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 59d6ada..0248294 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 */