aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ata/libata-scsi.c
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@infradead.org>2009-11-17 10:00:47 -0500
committerJeff Garzik <jgarzik@redhat.com>2009-12-03 02:46:35 -0500
commit18f0f97850059303ed73b1f02084f55ca330a80c (patch)
tree6b3f91f521d3d35f864138bd7e8962eb346a09c4 /drivers/ata/libata-scsi.c
parent6013efd8860bf15c1f86f365332642cfe557152f (diff)
libata: add translation for SCSI WRITE SAME (aka TRIM support)
Add support for the ATA TRIM command in libata. We translate a WRITE SAME 16 command with the unmap bit set into an ATA TRIM command and export enough information in READ CAPACITY 16 and the block limits EVPD page so that the new SCSI layer discard support will driver this for us. Note that I hardcode the WRITE_SAME_16 opcode for now as the patch to introduce the symbolic is not in 2.6.32 yet but only in the SCSI tree - as soon as it is merged we can fix it up to properly use the symbolic name. Signed-off-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
Diffstat (limited to 'drivers/ata/libata-scsi.c')
-rw-r--r--drivers/ata/libata-scsi.c98
1 files changed, 98 insertions, 0 deletions
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
index 512a3ee8caf6..340a616d226b 100644
--- a/drivers/ata/libata-scsi.c
+++ b/drivers/ata/libata-scsi.c
@@ -47,6 +47,7 @@
47#include <linux/hdreg.h> 47#include <linux/hdreg.h>
48#include <linux/uaccess.h> 48#include <linux/uaccess.h>
49#include <linux/suspend.h> 49#include <linux/suspend.h>
50#include <asm/unaligned.h>
50 51
51#include "libata.h" 52#include "libata.h"
52 53
@@ -1963,6 +1964,7 @@ static unsigned int ata_scsiop_inq_00(struct ata_scsi_args *args, u8 *rbuf)
1963 0x80, /* page 0x80, unit serial no page */ 1964 0x80, /* page 0x80, unit serial no page */
1964 0x83, /* page 0x83, device ident page */ 1965 0x83, /* page 0x83, device ident page */
1965 0x89, /* page 0x89, ata info page */ 1966 0x89, /* page 0x89, ata info page */
1967 0xb0, /* page 0xb0, block limits page */
1966 0xb1, /* page 0xb1, block device characteristics page */ 1968 0xb1, /* page 0xb1, block device characteristics page */
1967 }; 1969 };
1968 1970
@@ -2084,6 +2086,41 @@ static unsigned int ata_scsiop_inq_89(struct ata_scsi_args *args, u8 *rbuf)
2084 return 0; 2086 return 0;
2085} 2087}
2086 2088
2089static unsigned int ata_scsiop_inq_b0(struct ata_scsi_args *args, u8 *rbuf)
2090{
2091 u32 min_io_sectors;
2092
2093 rbuf[1] = 0xb0;
2094 rbuf[3] = 0x3c; /* required VPD size with unmap support */
2095
2096 /*
2097 * Optimal transfer length granularity.
2098 *
2099 * This is always one physical block, but for disks with a smaller
2100 * logical than physical sector size we need to figure out what the
2101 * latter is.
2102 */
2103 if (ata_id_has_large_logical_sectors(args->id))
2104 min_io_sectors = ata_id_logical_per_physical_sectors(args->id);
2105 else
2106 min_io_sectors = 1;
2107 put_unaligned_be16(min_io_sectors, &rbuf[6]);
2108
2109 /*
2110 * Optimal unmap granularity.
2111 *
2112 * The ATA spec doesn't even know about a granularity or alignment
2113 * for the TRIM command. We can leave away most of the unmap related
2114 * VPD page entries, but we have specifify a granularity to signal
2115 * that we support some form of unmap - in thise case via WRITE SAME
2116 * with the unmap bit set.
2117 */
2118 if (ata_id_has_trim(args->id))
2119 put_unaligned_be32(1, &rbuf[28]);
2120
2121 return 0;
2122}
2123
2087static unsigned int ata_scsiop_inq_b1(struct ata_scsi_args *args, u8 *rbuf) 2124static unsigned int ata_scsiop_inq_b1(struct ata_scsi_args *args, u8 *rbuf)
2088{ 2125{
2089 int form_factor = ata_id_form_factor(args->id); 2126 int form_factor = ata_id_form_factor(args->id);
@@ -2373,6 +2410,9 @@ static unsigned int ata_scsiop_read_cap(struct ata_scsi_args *args, u8 *rbuf)
2373 rbuf[13] = log_per_phys; 2410 rbuf[13] = log_per_phys;
2374 rbuf[14] = (lowest_aligned >> 8) & 0x3f; 2411 rbuf[14] = (lowest_aligned >> 8) & 0x3f;
2375 rbuf[15] = lowest_aligned; 2412 rbuf[15] = lowest_aligned;
2413
2414 if (ata_id_has_trim(args->id))
2415 rbuf[14] |= 0x80;
2376 } 2416 }
2377 2417
2378 return 0; 2418 return 0;
@@ -2895,6 +2935,58 @@ static unsigned int ata_scsi_pass_thru(struct ata_queued_cmd *qc)
2895 return 1; 2935 return 1;
2896} 2936}
2897 2937
2938static unsigned int ata_scsi_write_same_xlat(struct ata_queued_cmd *qc)
2939{
2940 struct ata_taskfile *tf = &qc->tf;
2941 struct scsi_cmnd *scmd = qc->scsicmd;
2942 struct ata_device *dev = qc->dev;
2943 const u8 *cdb = scmd->cmnd;
2944 u64 block;
2945 u32 n_block;
2946 u32 size;
2947 void *buf;
2948
2949 /* we may not issue DMA commands if no DMA mode is set */
2950 if (unlikely(!dev->dma_mode))
2951 goto invalid_fld;
2952
2953 if (unlikely(scmd->cmd_len < 16))
2954 goto invalid_fld;
2955 scsi_16_lba_len(cdb, &block, &n_block);
2956
2957 /* for now we only support WRITE SAME with the unmap bit set */
2958 if (unlikely(!(cdb[1] & 0x8)))
2959 goto invalid_fld;
2960
2961 /*
2962 * WRITE SAME always has a sector sized buffer as payload, this
2963 * should never be a multiple entry S/G list.
2964 */
2965 if (!scsi_sg_count(scmd))
2966 goto invalid_fld;
2967
2968 buf = page_address(sg_page(scsi_sglist(scmd)));
2969 size = ata_set_lba_range_entries(buf, 512 / 8, block, n_block);
2970
2971 tf->protocol = ATA_PROT_DMA;
2972 tf->hob_feature = 0;
2973 tf->feature = ATA_DSM_TRIM;
2974 tf->hob_nsect = (size / 512) >> 8;
2975 tf->nsect = size / 512;
2976 tf->command = ATA_CMD_DSM;
2977 tf->flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE | ATA_TFLAG_LBA48 |
2978 ATA_TFLAG_WRITE;
2979
2980 ata_qc_set_pc_nbytes(qc);
2981
2982 return 0;
2983
2984 invalid_fld:
2985 ata_scsi_set_sense(scmd, ILLEGAL_REQUEST, 0x24, 0x00);
2986 /* "Invalid field in cdb" */
2987 return 1;
2988}
2989
2898/** 2990/**
2899 * ata_get_xlat_func - check if SCSI to ATA translation is possible 2991 * ata_get_xlat_func - check if SCSI to ATA translation is possible
2900 * @dev: ATA device 2992 * @dev: ATA device
@@ -2919,6 +3011,9 @@ static inline ata_xlat_func_t ata_get_xlat_func(struct ata_device *dev, u8 cmd)
2919 case WRITE_16: 3011 case WRITE_16:
2920 return ata_scsi_rw_xlat; 3012 return ata_scsi_rw_xlat;
2921 3013
3014 case 0x93 /*WRITE_SAME_16*/:
3015 return ata_scsi_write_same_xlat;
3016
2922 case SYNCHRONIZE_CACHE: 3017 case SYNCHRONIZE_CACHE:
2923 if (ata_try_flush_cache(dev)) 3018 if (ata_try_flush_cache(dev))
2924 return ata_scsi_flush_xlat; 3019 return ata_scsi_flush_xlat;
@@ -3108,6 +3203,9 @@ void ata_scsi_simulate(struct ata_device *dev, struct scsi_cmnd *cmd,
3108 case 0x89: 3203 case 0x89:
3109 ata_scsi_rbuf_fill(&args, ata_scsiop_inq_89); 3204 ata_scsi_rbuf_fill(&args, ata_scsiop_inq_89);
3110 break; 3205 break;
3206 case 0xb0:
3207 ata_scsi_rbuf_fill(&args, ata_scsiop_inq_b0);
3208 break;
3111 case 0xb1: 3209 case 0xb1:
3112 ata_scsi_rbuf_fill(&args, ata_scsiop_inq_b1); 3210 ata_scsi_rbuf_fill(&args, ata_scsiop_inq_b1);
3113 break; 3211 break;