From patchwork Fri Dec 17 17:44:42 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kevin Wolf X-Patchwork-Id: 75954 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 0F0761007D3 for ; Sat, 18 Dec 2010 05:34:34 +1100 (EST) Received: from localhost ([127.0.0.1]:45648 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1PTf6s-0005hg-6q for incoming@patchwork.ozlabs.org; Fri, 17 Dec 2010 13:32:54 -0500 Received: from [140.186.70.92] (port=51963 helo=eggs.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1PTeNk-0001QE-7X for qemu-devel@nongnu.org; Fri, 17 Dec 2010 12:46:47 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1PTeMQ-0003AY-8N for qemu-devel@nongnu.org; Fri, 17 Dec 2010 12:46:13 -0500 Received: from mx1.redhat.com ([209.132.183.28]:42341) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1PTeMQ-0003AH-1D for qemu-devel@nongnu.org; Fri, 17 Dec 2010 12:44:54 -0500 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.13.8/8.13.8) with ESMTP id oBHHiotO023449 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Fri, 17 Dec 2010 12:44:51 -0500 Received: from dhcp-5-188.str.redhat.com (vpn1-5-143.ams2.redhat.com [10.36.5.143]) by int-mx01.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id oBHHhdMk031047; Fri, 17 Dec 2010 12:44:49 -0500 From: Kevin Wolf To: anthony@codemonkey.ws Date: Fri, 17 Dec 2010 18:44:42 +0100 Message-Id: <1292607893-13461-28-git-send-email-kwolf@redhat.com> In-Reply-To: <1292607893-13461-1-git-send-email-kwolf@redhat.com> References: <1292607893-13461-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. Cc: kwolf@redhat.com, qemu-devel@nongnu.org Subject: [Qemu-devel] [PATCH 27/38] scsi-disk: support WRITE SAME (16) with unmap bit 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 From: Christoph Hellwig Support discards via the WRITE SAME command with the unmap bit set, and tell the initiator about the support for it via the block limit and the new thin provisioning EVPD pages. Also fix the comment which incorrectly describedthe block limits EVPD page. Signed-off-by: Christoph Hellwig Signed-off-by: Kevin Wolf --- hw/scsi-defs.h | 1 + hw/scsi-disk.c | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 52 insertions(+), 2 deletions(-) diff --git a/hw/scsi-defs.h b/hw/scsi-defs.h index 1473ecb..413cce0 100644 --- a/hw/scsi-defs.h +++ b/hw/scsi-defs.h @@ -84,6 +84,7 @@ #define MODE_SENSE_10 0x5a #define PERSISTENT_RESERVE_IN 0x5e #define PERSISTENT_RESERVE_OUT 0x5f +#define WRITE_SAME_16 0x93 #define MAINTENANCE_IN 0xa3 #define MAINTENANCE_OUT 0xa4 #define MOVE_MEDIUM 0xa5 diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c index 87f9e86..6cb317c 100644 --- a/hw/scsi-disk.c +++ b/hw/scsi-disk.c @@ -424,7 +424,8 @@ static int scsi_disk_emulate_inquiry(SCSIRequest *req, uint8_t *outbuf) outbuf[buflen++] = 0x80; // unit serial number outbuf[buflen++] = 0x83; // device identification if (bdrv_get_type_hint(s->bs) != BDRV_TYPE_CDROM) { - outbuf[buflen++] = 0xb0; // block device characteristics + outbuf[buflen++] = 0xb0; // block limits + outbuf[buflen++] = 0xb2; // thin provisioning } outbuf[pages] = buflen - pages - 1; // number of pages break; @@ -466,8 +467,10 @@ static int scsi_disk_emulate_inquiry(SCSIRequest *req, uint8_t *outbuf) buflen += id_len; break; } - case 0xb0: /* block device characteristics */ + case 0xb0: /* block limits */ { + unsigned int unmap_sectors = + s->qdev.conf.discard_granularity / s->qdev.blocksize; unsigned int min_io_size = s->qdev.conf.min_io_size / s->qdev.blocksize; unsigned int opt_io_size = @@ -492,6 +495,21 @@ static int scsi_disk_emulate_inquiry(SCSIRequest *req, uint8_t *outbuf) outbuf[13] = (opt_io_size >> 16) & 0xff; outbuf[14] = (opt_io_size >> 8) & 0xff; outbuf[15] = opt_io_size & 0xff; + + /* optimal unmap granularity */ + outbuf[28] = (unmap_sectors >> 24) & 0xff; + outbuf[29] = (unmap_sectors >> 16) & 0xff; + outbuf[30] = (unmap_sectors >> 8) & 0xff; + outbuf[31] = unmap_sectors & 0xff; + break; + } + case 0xb2: /* thin provisioning */ + { + outbuf[3] = buflen = 8; + outbuf[4] = 0; + outbuf[5] = 0x40; /* write same with unmap supported */ + outbuf[6] = 0; + outbuf[7] = 0; break; } default: @@ -959,6 +977,12 @@ static int scsi_disk_emulate_command(SCSIDiskReq *r, uint8_t *outbuf) outbuf[11] = 0; outbuf[12] = 0; outbuf[13] = get_physical_block_exp(&s->qdev.conf); + + /* set TPE bit if the format supports discard */ + if (s->qdev.conf.discard_granularity) { + outbuf[14] = 0x80; + } + /* Protection, exponent and lowest lba field left blank. */ buflen = req->cmd.xfer; break; @@ -1123,6 +1147,31 @@ static int32_t scsi_send_command(SCSIDevice *d, uint32_t tag, goto illegal_lba; } break; + case WRITE_SAME_16: + len = r->req.cmd.xfer / d->blocksize; + + DPRINTF("WRITE SAME(16) (sector %" PRId64 ", count %d)\n", + r->req.cmd.lba, len); + + if (r->req.cmd.lba > s->max_lba) { + goto illegal_lba; + } + + /* + * We only support WRITE SAME with the unmap bit set for now. + */ + if (!(buf[1] & 0x8)) { + goto fail; + } + + rc = bdrv_discard(s->bs, r->req.cmd.lba * s->cluster_size, + len * s->cluster_size); + if (rc < 0) { + /* XXX: better error code ?*/ + goto fail; + } + + break; default: DPRINTF("Unknown SCSI command (%2.2x)\n", buf[0]); fail: