diff options
Diffstat (limited to 'drivers/ata/libata-scsi.c')
-rw-r--r-- | drivers/ata/libata-scsi.c | 98 |
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 | ||
2089 | static 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 | |||
2087 | static unsigned int ata_scsiop_inq_b1(struct ata_scsi_args *args, u8 *rbuf) | 2124 | static 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 | ||
2938 | static 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; |