diff options
author | David Gwynne <dlg@cvs.openbsd.org> | 2011-07-08 07:15:32 +0000 |
---|---|---|
committer | David Gwynne <dlg@cvs.openbsd.org> | 2011-07-08 07:15:32 +0000 |
commit | 8208d534a5fd66215dd01ae6601b8eca84b6a12f (patch) | |
tree | 936dcda2a6ec002b4a348d756161386227067589 /sys/dev | |
parent | 52ef5ab1dce8f6bb318bc5bb5bdc751c22bbb181 (diff) |
some trim cleanups and additions.
use less magic numbers when check the block limits for trim. fill in the
block limits vpd page with some conservative numbers about how much
unmap we can do at a time (~32MB over 64 descriptors).
Diffstat (limited to 'sys/dev')
-rw-r--r-- | sys/dev/ata/atascsi.c | 26 |
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: |