[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 27/38] scsi-disk: support WRITE SAME (16) with unmap
From: |
Kevin Wolf |
Subject: |
[Qemu-devel] [PATCH 27/38] scsi-disk: support WRITE SAME (16) with unmap bit |
Date: |
Fri, 17 Dec 2010 18:44:42 +0100 |
From: Christoph Hellwig <address@hidden>
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 <address@hidden>
Signed-off-by: Kevin Wolf <address@hidden>
---
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:
--
1.7.2.3
- [Qemu-devel] [PATCH 19/38] qemu-img.c: Re-factor img_create(), (continued)
- [Qemu-devel] [PATCH 19/38] qemu-img.c: Re-factor img_create(), Kevin Wolf, 2010/12/17
- [Qemu-devel] [PATCH 25/38] ide: Register vm change state handler once only, Kevin Wolf, 2010/12/17
- [Qemu-devel] [PATCH 18/38] qemu-img: Call error_set_progname, Kevin Wolf, 2010/12/17
- [Qemu-devel] [PATCH 16/38] ahci: set SATA Mode Select, Kevin Wolf, 2010/12/17
- [Qemu-devel] [PATCH 28/38] qemu-io: Add discard command, Kevin Wolf, 2010/12/17
- [Qemu-devel] [PATCH 30/38] qemu-io: Fix typo in help texts, Kevin Wolf, 2010/12/17
- [Qemu-devel] [PATCH 17/38] ide: honor ncq for atapi, Kevin Wolf, 2010/12/17
- [Qemu-devel] [PATCH 31/38] docs: Add QED image format specification, Kevin Wolf, 2010/12/17
- [Qemu-devel] [PATCH 32/38] qed: Add QEMU Enhanced Disk image format, Kevin Wolf, 2010/12/17
- [Qemu-devel] [PATCH 38/38] docs: Fix missing carets in QED specification, Kevin Wolf, 2010/12/17
- [Qemu-devel] [PATCH 27/38] scsi-disk: support WRITE SAME (16) with unmap bit,
Kevin Wolf <=
- [Qemu-devel] [PATCH 23/38] qemu.img.c: Use error_report() instead of own error() implementation, Kevin Wolf, 2010/12/17
- [Qemu-devel] [PATCH 36/38] block/qcow2.c: rename qcow_ functions to qcow2_, Kevin Wolf, 2010/12/17
- [Qemu-devel] [PATCH 29/38] raw-posix: add discard support, Kevin Wolf, 2010/12/17
- [Qemu-devel] [PATCH 35/38] qed: Consistency check support, Kevin Wolf, 2010/12/17
- [Qemu-devel] [PATCH 34/38] qed: Read/write support, Kevin Wolf, 2010/12/17
- [Qemu-devel] [PATCH 37/38] Add proper -errno error return values to qcow2_open(), Kevin Wolf, 2010/12/17
- [Qemu-devel] [PATCH 15/38] config: add ahci for pci capable machines, Kevin Wolf, 2010/12/17
- [Qemu-devel] [PATCH 26/38] block: add discard support, Kevin Wolf, 2010/12/17
- [Qemu-devel] [PATCH 33/38] qed: Table, L2 cache, and cluster functions, Kevin Wolf, 2010/12/17
- [Qemu-devel] [PATCH 24/38] Remove NULL checks for bdrv_new return value, Kevin Wolf, 2010/12/17