aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ata/libata-scsi.c
diff options
context:
space:
mode:
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 512a3ee8caf..340a616d226 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;