From patchwork Mon Nov 22 10:15:35 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hannes Reinecke X-Patchwork-Id: 72541 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 8FD00B7105 for ; Mon, 22 Nov 2010 22:14:19 +1100 (EST) Received: from localhost ([127.0.0.1]:44048 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1PKTxX-0006Pq-W7 for incoming@patchwork.ozlabs.org; Mon, 22 Nov 2010 05:49:20 -0500 Received: from [140.186.70.92] (port=48118 helo=eggs.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1PKTOc-0002BW-FW for qemu-devel@nongnu.org; Mon, 22 Nov 2010 05:13:46 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1PKTON-0001AE-6n for qemu-devel@nongnu.org; Mon, 22 Nov 2010 05:13:14 -0500 Received: from cantor2.suse.de ([195.135.220.15]:58171 helo=mx2.suse.de) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1PKTOM-00019q-Fz for qemu-devel@nongnu.org; Mon, 22 Nov 2010 05:12:58 -0500 Received: from relay1.suse.de (charybdis-ext.suse.de [195.135.221.2]) by mx2.suse.de (Postfix) with ESMTP id 49A258980B; Mon, 22 Nov 2010 11:12:56 +0100 (CET) Date: Mon, 22 Nov 2010 11:15:35 +0100 To: qemu-devel@nongnu.org User-Agent: Heirloom mailx 12.2 01/07/07 MIME-Version: 1.0 Message-Id: <20101122101536.649BAF8D70@ochil.suse.de> From: hare@suse.de (Hannes Reinecke) 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] 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 | 17 +++++++++++++++++ hw/scsi.h | 1 + 3 files changed, 27 insertions(+), 0 deletions(-) diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c index d43c7ae..d1b7f74 100644 --- a/hw/scsi-disk.c +++ b/hw/scsi-disk.c @@ -360,6 +360,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); @@ -1205,6 +1213,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 40b1255..5c0f6ab 100644 --- a/hw/scsi-generic.c +++ b/hw/scsi-generic.c @@ -83,6 +83,22 @@ 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) { + if (len < SCSI_SENSE_BUF_SIZE) + size = len; + else + size = SCSI_SENSE_BUF_SIZE; + memcpy(outbuf, s->sensebuf, size); + } + + return size; +} + static SCSIRequest *scsi_new_request(SCSIDevice *d, uint32_t tag, uint32_t lun) { SCSIRequest *req; @@ -550,6 +566,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 25fda2f..0c467d1 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,