summaryrefslogtreecommitdiff
path: root/sys/dev
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/ata/atascsi.c26
1 files changed, 17 insertions, 9 deletions
diff --git a/sys/dev/ata/atascsi.c b/sys/dev/ata/atascsi.c
index 8cac2939092..eedca3f6bd8 100644
--- a/sys/dev/ata/atascsi.c
+++ b/sys/dev/ata/atascsi.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: atascsi.c,v 1.108 2011/07/05 03:47:55 dlg Exp $ */
+/* $OpenBSD: atascsi.c,v 1.109 2011/07/08 07:15:31 dlg Exp $ */
/*
* Copyright (c) 2007 David Gwynne <dlg@openbsd.org>
@@ -832,6 +832,16 @@ atascsi_disk_vpd_limits(struct scsi_xfer *xs)
_lto2b(1 << ata_identify_block_l2p_exp(&ap->ap_identify),
pg.optimal_xfer_granularity);
+ if (ISSET(ap->ap_features, ATA_PORT_F_TRIM)) {
+ /*
+ * ATA only supports 65535 blocks per TRIM descriptor, so
+ * avoid having to split UNMAP descriptors and overflow the page
+ * limit by using that as a max.
+ */
+ _lto4b(ATA_DSM_TRIM_MAX_LEN, pg.max_unmap_lba_count);
+ _lto4b(512 / 8, pg.max_unmap_desc_count);
+ }
+
bcopy(&pg, xs->data, MIN(sizeof(pg), xs->datalen));
atascsi_done(xs, XS_NOERROR);
@@ -879,7 +889,7 @@ atascsi_disk_write_same_16(struct scsi_xfer *xs)
ap = atascsi_lookup_port(link);
cdb = (struct scsi_write_same_16 *)xs->cmd;
- if (cdb->flags != WRITE_SAME_F_UNMAP ||
+ if (!ISSET(cdb->flags, WRITE_SAME_F_UNMAP) ||
!ISSET(ap->ap_features, ATA_PORT_F_TRIM)) {
/* generate sense data */
atascsi_done(xs, XS_DRIVER_STUFFUP);
@@ -895,7 +905,7 @@ atascsi_disk_write_same_16(struct scsi_xfer *xs)
lba = _8btol(cdb->lba);
length = _4btol(cdb->length);
- if (length > 0xffff) {
+ if (length > ATA_DSM_TRIM_MAX_LEN) {
/* XXX we dont support requests over 65535 blocks */
atascsi_done(xs, XS_DRIVER_STUFFUP);
return;
@@ -913,7 +923,7 @@ atascsi_disk_write_same_16(struct scsi_xfer *xs)
/* TRIM sends a list of blocks to discard in the databuf. */
memset(xa->data, 0, xa->datalen);
- desc = htole64(((u_int64_t)length << 48) | lba);
+ desc = htole64(ATA_DSM_TRIM_DESC(lba, length));
memcpy(xa->data, &desc, sizeof(desc));
fis = xa->fis;
@@ -934,13 +944,11 @@ atascsi_disk_write_same_16_done(struct ata_xfer *xa)
case ATA_S_COMPLETE:
xs->error = XS_NOERROR;
break;
-
case ATA_S_ERROR:
+ xs->error = XS_DRIVER_STUFFUP;
+ break;
case ATA_S_TIMEOUT:
- printf("atascsi_disk_write_same_16_done: %s\n",
- xa->state == ATA_S_TIMEOUT ? "timeout" : "error");
- xs->error = (xa->state == ATA_S_TIMEOUT ? XS_TIMEOUT :
- XS_DRIVER_STUFFUP);
+ xs->error = XS_TIMEOUT;
break;
default: