From patchwork Tue Oct 27 15:29:07 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hannes Reinecke X-Patchwork-Id: 37000 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [199.232.76.165]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id E4905B7BF1 for ; Wed, 28 Oct 2009 02:37:48 +1100 (EST) Received: from localhost ([127.0.0.1]:39890 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1N2o7A-0006e9-6f for incoming@patchwork.ozlabs.org; Tue, 27 Oct 2009 11:37:40 -0400 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1N2nz2-0003Ks-68 for qemu-devel@nongnu.org; Tue, 27 Oct 2009 11:29:16 -0400 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1N2nyw-0003EA-Qx for qemu-devel@nongnu.org; Tue, 27 Oct 2009 11:29:15 -0400 Received: from [199.232.76.173] (port=39148 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1N2nyw-0003Dy-MU for qemu-devel@nongnu.org; Tue, 27 Oct 2009 11:29:10 -0400 Received: from cantor.suse.de ([195.135.220.2]:60816 helo=mx1.suse.de) by monty-python.gnu.org with esmtps (TLS-1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.60) (envelope-from ) id 1N2nyv-0007pB-Kk for qemu-devel@nongnu.org; Tue, 27 Oct 2009 11:29:10 -0400 Received: from relay1.suse.de (mail2.suse.de [195.135.221.8]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.suse.de (Postfix) with ESMTP id EECDB90847; Tue, 27 Oct 2009 16:29:07 +0100 (CET) Date: Tue, 27 Oct 2009 16:29:07 +0100 To: kvm@vger.kernel.org User-Agent: Heirloom mailx 12.2 01/07/07 MIME-Version: 1.0 Message-Id: <20091027152907.BD19239742@ochil.suse.de> From: hare@suse.de (Hannes Reinecke) X-detected-operating-system: by monty-python.gnu.org: GNU/Linux 2.4-2.6 Cc: qemu-devel@nongnu.org, virtualization@lists.linux-foundation.org Subject: [Qemu-devel] [PATCH 4/4] megasas: Add SCSI command emulation X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Now that we can use SCSI command emulation without using the SCSI disk abstraction we can easily add it to the megasas HBA. Signed-off-by: Hannes Reinecke --- hw/megasas.c | 88 +++++++++++++++++++++++++++++++++++----------------------- 1 files changed, 53 insertions(+), 35 deletions(-) diff --git a/hw/megasas.c b/hw/megasas.c index a57e8e0..f32b313 100644 --- a/hw/megasas.c +++ b/hw/megasas.c @@ -661,40 +661,55 @@ static int megasas_handle_scsi(MPTState *s, uint8_t fcmd, } } - memset(&cmd->hdr, 0, sizeof(struct sg_io_hdr)); - cmd->hdr.interface_id = 'S'; - cmd->hdr.cmd_len = cdb_len; - cmd->hdr.cmdp = cdb; - cmd->hdr.iovec_count = cmd->sge_count; - cmd->hdr.dxferp = cmd->iov; - for (n = 0; n < cmd->sge_count; n++) - cmd->hdr.dxfer_len += cmd->iov[n].iov_len; - if (cmd->sge_count) { - if (dir) - cmd->hdr.dxfer_direction = SG_DXFER_TO_DEV; - else - cmd->hdr.dxfer_direction = SG_DXFER_FROM_DEV; - } else { - cmd->hdr.dxfer_direction = SG_DXFER_NONE; - } - cmd->hdr.sbp = cmd->sense; - cmd->hdr.mx_sb_len = cmd->sense_len; + if (bdrv_is_sg(cmd->lun->bdrv)) { + memset(&cmd->hdr, 0, sizeof(struct sg_io_hdr)); + cmd->hdr.interface_id = 'S'; + cmd->hdr.cmd_len = cdb_len; + cmd->hdr.cmdp = cdb; + cmd->hdr.iovec_count = cmd->sge_count; + cmd->hdr.dxferp = cmd->iov; + for (n = 0; n < cmd->sge_count; n++) + cmd->hdr.dxfer_len += cmd->iov[n].iov_len; + if (cmd->sge_count) { + if (dir) + cmd->hdr.dxfer_direction = SG_DXFER_TO_DEV; + else + cmd->hdr.dxfer_direction = SG_DXFER_FROM_DEV; + } else { + cmd->hdr.dxfer_direction = SG_DXFER_NONE; + } + cmd->hdr.sbp = cmd->sense; + cmd->hdr.mx_sb_len = cmd->sense_len; - ret = bdrv_ioctl(cmd->lun->bdrv, SG_IO, &cmd->hdr); - if (ret) { - DPRINTF("SCSI pthru dev %x lun %x failed with %d\n", - target, lun, errno); - sense_len = scsi_build_sense(cmd->sense, SENSE_IO_ERROR); - cmd->sge_size = 0; - scsi_status = SAM_STAT_CHECK_CONDITION; - } else if (cmd->hdr.status) { - sense_len = cmd->hdr.sb_len_wr; - scsi_status = cmd->hdr.status; - cmd->sge_size = cmd->hdr.dxfer_len; - scsi_status = SAM_STAT_CHECK_CONDITION; + ret = bdrv_ioctl(cmd->lun->bdrv, SG_IO, &cmd->hdr); + if (ret) { + DPRINTF("SCSI pthru dev %x lun %x failed with %d\n", + target, lun, errno); + sense_len = scsi_build_sense(cmd->sense, SENSE_IO_ERROR); + cmd->sge_size = 0; + scsi_status = SAM_STAT_CHECK_CONDITION; + } else if (cmd->hdr.status) { + sense_len = cmd->hdr.sb_len_wr; + scsi_status = cmd->hdr.status; + cmd->sge_size = cmd->hdr.dxfer_len; + scsi_status = SAM_STAT_CHECK_CONDITION; + } else { + sense_len = 0; + cmd->sge_size = cmd->hdr.dxfer_len; + } } else { - sense_len = 0; - cmd->sge_size = cmd->hdr.dxfer_len; + uint32_t sense; + + DPRINTF("Emulate SCSI pthru cmd %x\n", cdb[0]); + sense = scsi_emulate_command(cmd->lun->bdrv, 0, cdb, + cmd->iov[0].iov_len, + cmd->iov[0].iov_base, + &cmd->sge_size); + sense_len = scsi_build_sense(cmd->sense, sense); + if (sense_len) + scsi_status = SAM_STAT_CHECK_CONDITION; + else + scsi_status = SAM_STAT_GOOD; } out: megasas_unmap_sense(cmd, sense_len); @@ -1105,13 +1120,16 @@ static int megasas_scsi_init(PCIDevice *dev) lun->bdrv = NULL; continue; } + bdrv_set_tcq(lun->bdrv, 1); /* check if we can use SG_IO */ ret = bdrv_ioctl(lun->bdrv, SG_IO, &hdr); if (ret) { - DPRINTF("SCSI cmd passthrough not available on dev %d (error %d)\n", + DPRINTF("Using SCSI cmd emulation on dev %d (error %d)\n", unit, ret); - lun->sdev = NULL; - lun->bdrv = NULL; + bdrv_set_sg(lun->bdrv, 0); + } else { + DPRINTF("Using SCSI cmd passthrough on dev %d\n", unit); + bdrv_set_sg(lun->bdrv, 1); } } register_savevm("megasas", -1, 0, megasas_scsi_save, megasas_scsi_load, s);