From 8208d534a5fd66215dd01ae6601b8eca84b6a12f Mon Sep 17 00:00:00 2001 From: David Gwynne Date: Fri, 8 Jul 2011 07:15:32 +0000 Subject: 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). --- sys/dev/ata/atascsi.c | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) (limited to 'sys/dev') 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 @@ -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: -- cgit v1.2.3