From patchwork Wed Nov 24 11:16:07 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hannes Reinecke X-Patchwork-Id: 72865 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 C892CB6F07 for ; Wed, 24 Nov 2010 23:28:14 +1100 (EST) Received: from localhost ([127.0.0.1]:42834 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1PLDXZ-0002ur-1p for incoming@patchwork.ozlabs.org; Wed, 24 Nov 2010 06:29:33 -0500 Received: from [140.186.70.92] (port=53521 helo=eggs.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1PLDI1-00067j-1E for qemu-devel@nongnu.org; Wed, 24 Nov 2010 06:13:35 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1PLDHw-0005oa-PV for qemu-devel@nongnu.org; Wed, 24 Nov 2010 06:13:28 -0500 Received: from cantor.suse.de ([195.135.220.2]:60541 helo=mx1.suse.de) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1PLDHw-0005o0-FH for qemu-devel@nongnu.org; Wed, 24 Nov 2010 06:13:24 -0500 Received: from relay1.suse.de (charybdis-ext.suse.de [195.135.221.2]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.suse.de (Postfix) with ESMTP id ECEEE94746; Wed, 24 Nov 2010 12:13:22 +0100 (CET) From: Hannes Reinecke To: qemu-devel@nongnu.org Date: Wed, 24 Nov 2010 12:16:07 +0100 Message-Id: <1290597370-21365-13-git-send-email-hare@suse.de> X-Mailer: git-send-email 1.7.1 In-Reply-To: <1290597370-21365-1-git-send-email-hare@suse.de> References: <1290597370-21365-1-git-send-email-hare@suse.de> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.4-2.6 Cc: stefanha@gmail.com, nab@linux-iscsi.org, kraxel@redhat.com Subject: [Qemu-devel] [PATCH 12/15] scsi: Implement 'get_sense' callback 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 The get_sense callback copies existing sense information into the provided buffer. This is required if sense information should be transferred together with the command response. Signed-off-by: Hannes Reinecke --- hw/scsi-disk.c | 9 +++++++++ hw/scsi-generic.c | 18 ++++++++++++++++++ hw/scsi.h | 1 + 3 files changed, 28 insertions(+), 0 deletions(-) diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c index a4f387d..68b8667 100644 --- a/hw/scsi-disk.c +++ b/hw/scsi-disk.c @@ -373,6 +373,14 @@ static uint8_t *scsi_get_buf(SCSIRequest *req) return r->iov_buf; } +/* Copy sense information into the provided buffer */ +static int scsi_get_sense(SCSIRequest *req, uint8_t *outbuf, int len) +{ + SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, req->dev); + + return scsi_build_sense(s->sense, outbuf, len, len > 14); +} + static int scsi_disk_emulate_inquiry(SCSIRequest *req, uint8_t *outbuf) { SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, req->dev); @@ -1218,6 +1226,7 @@ static SCSIDeviceInfo scsi_disk_info = { .write_data = scsi_write_data, .cancel_io = scsi_cancel_io, .get_buf = scsi_get_buf, + .get_sense = scsi_get_sense, .qdev.props = (Property[]) { DEFINE_BLOCK_PROPERTIES(SCSIDiskState, qdev.conf), DEFINE_PROP_STRING("ver", SCSIDiskState, version), diff --git a/hw/scsi-generic.c b/hw/scsi-generic.c index d4edc48..949b4cc 100644 --- a/hw/scsi-generic.c +++ b/hw/scsi-generic.c @@ -83,6 +83,23 @@ static void scsi_clear_sense(SCSIGenericState *s) s->driver_status = 0; } +static int scsi_get_sense(SCSIRequest *req, uint8_t *outbuf, int len) +{ + SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, req->dev); + int size = SCSI_SENSE_BUF_SIZE; + + if (!(s->driver_status & SG_ERR_DRIVER_SENSE)) { + size = scsi_build_sense(SENSE_CODE(NO_SENSE), s->sensebuf, + SCSI_SENSE_BUF_SIZE, 0); + } + if (size > len) { + size = len; + } + memcpy(outbuf, s->sensebuf, size); + + return size; +} + static SCSIRequest *scsi_new_request(SCSIDevice *d, uint32_t tag, uint32_t lun) { SCSIRequest *req; @@ -550,6 +567,7 @@ static SCSIDeviceInfo scsi_generic_info = { .write_data = scsi_write_data, .cancel_io = scsi_cancel_io, .get_buf = scsi_get_buf, + .get_sense = scsi_get_sense, .qdev.props = (Property[]) { DEFINE_BLOCK_PROPERTIES(SCSIGenericState, qdev.conf), DEFINE_PROP_END_OF_LIST(), diff --git a/hw/scsi.h b/hw/scsi.h index c2d3300..cc96f85 100644 --- a/hw/scsi.h +++ b/hw/scsi.h @@ -78,6 +78,7 @@ struct SCSIDeviceInfo { int (*write_data)(SCSIRequest *req); void (*cancel_io)(SCSIRequest *req); uint8_t *(*get_buf)(SCSIRequest *req); + int (*get_sense)(SCSIRequest *req, uint8_t *buf, int len); }; typedef void (*SCSIAttachFn)(DeviceState *host, BlockDriverState *bdrv,