summaryrefslogtreecommitdiffstats
path: root/drivers/ata
diff options
context:
space:
mode:
authorMinwoo Im <dn3108@gmail.com>2017-06-23 14:41:10 -0400
committerTejun Heo <tj@kernel.org>2017-06-27 11:25:39 -0400
commitb1ffbf854e0887e2b828b9a3343264453662dec6 (patch)
tree71420dd08a9f22de9fd87fb5a477020657e97ccd /drivers/ata
parent0ce968f3825153d570f6d765f2c0c79bcb1f0949 (diff)
libata: Support for an ATA PASS-THROUGH(32) command.
SAT-4(SCSI/ATA Translation) supports for an ata pass-thru(32). This patch will allow to translate an ata pass-thru(32) SCSI cmd to an ATA cmd. Signed-off-by: Minwoo Im <dn3108@gmail.com> Reviewed-by: Bart Van Assche <bart.vanassche@wdc.com> Signed-off-by: Tejun Heo <tj@kernel.org>
Diffstat (limited to 'drivers/ata')
-rw-r--r--drivers/ata/libata-core.c2
-rw-r--r--drivers/ata/libata-scsi.c72
2 files changed, 68 insertions, 6 deletions
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index a846c29f3248..d1b2c6b5f680 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -2661,7 +2661,7 @@ int ata_dev_configure(struct ata_device *dev)
2661 ata_dev_config_sense_reporting(dev); 2661 ata_dev_config_sense_reporting(dev);
2662 ata_dev_config_zac(dev); 2662 ata_dev_config_zac(dev);
2663 ata_dev_config_trusted(dev); 2663 ata_dev_config_trusted(dev);
2664 dev->cdb_len = 16; 2664 dev->cdb_len = 32;
2665 } 2665 }
2666 2666
2667 /* ATAPI-specific feature tests */ 2667 /* ATAPI-specific feature tests */
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
index 4c300749aca5..815c6e240aea 100644
--- a/drivers/ata/libata-scsi.c
+++ b/drivers/ata/libata-scsi.c
@@ -3126,7 +3126,7 @@ ata_scsi_map_proto(u8 byte1)
3126 * ata_scsi_pass_thru - convert ATA pass-thru CDB to taskfile 3126 * ata_scsi_pass_thru - convert ATA pass-thru CDB to taskfile
3127 * @qc: command structure to be initialized 3127 * @qc: command structure to be initialized
3128 * 3128 *
3129 * Handles either 12 or 16-byte versions of the CDB. 3129 * Handles either 12, 16, or 32-byte versions of the CDB.
3130 * 3130 *
3131 * RETURNS: 3131 * RETURNS:
3132 * Zero on success, non-zero on failure. 3132 * Zero on success, non-zero on failure.
@@ -3138,13 +3138,19 @@ static unsigned int ata_scsi_pass_thru(struct ata_queued_cmd *qc)
3138 struct ata_device *dev = qc->dev; 3138 struct ata_device *dev = qc->dev;
3139 const u8 *cdb = scmd->cmnd; 3139 const u8 *cdb = scmd->cmnd;
3140 u16 fp; 3140 u16 fp;
3141 u16 cdb_offset = 0;
3141 3142
3142 if ((tf->protocol = ata_scsi_map_proto(cdb[1])) == ATA_PROT_UNKNOWN) { 3143 /* 7Fh variable length cmd means a ata pass-thru(32) */
3144 if (cdb[0] == VARIABLE_LENGTH_CMD)
3145 cdb_offset = 9;
3146
3147 tf->protocol = ata_scsi_map_proto(cdb[1 + cdb_offset]);
3148 if (tf->protocol == ATA_PROT_UNKNOWN) {
3143 fp = 1; 3149 fp = 1;
3144 goto invalid_fld; 3150 goto invalid_fld;
3145 } 3151 }
3146 3152
3147 if (ata_is_ncq(tf->protocol) && (cdb[2] & 0x3) == 0) 3153 if (ata_is_ncq(tf->protocol) && (cdb[2 + cdb_offset] & 0x3) == 0)
3148 tf->protocol = ATA_PROT_NCQ_NODATA; 3154 tf->protocol = ATA_PROT_NCQ_NODATA;
3149 3155
3150 /* enable LBA */ 3156 /* enable LBA */
@@ -3180,7 +3186,7 @@ static unsigned int ata_scsi_pass_thru(struct ata_queued_cmd *qc)
3180 tf->lbah = cdb[12]; 3186 tf->lbah = cdb[12];
3181 tf->device = cdb[13]; 3187 tf->device = cdb[13];
3182 tf->command = cdb[14]; 3188 tf->command = cdb[14];
3183 } else { 3189 } else if (cdb[0] == ATA_12) {
3184 /* 3190 /*
3185 * 12-byte CDB - incapable of extended commands. 3191 * 12-byte CDB - incapable of extended commands.
3186 */ 3192 */
@@ -3193,6 +3199,30 @@ static unsigned int ata_scsi_pass_thru(struct ata_queued_cmd *qc)
3193 tf->lbah = cdb[7]; 3199 tf->lbah = cdb[7];
3194 tf->device = cdb[8]; 3200 tf->device = cdb[8];
3195 tf->command = cdb[9]; 3201 tf->command = cdb[9];
3202 } else {
3203 /*
3204 * 32-byte CDB - may contain extended command fields.
3205 *
3206 * If that is the case, copy the upper byte register values.
3207 */
3208 if (cdb[10] & 0x01) {
3209 tf->hob_feature = cdb[20];
3210 tf->hob_nsect = cdb[22];
3211 tf->hob_lbal = cdb[16];
3212 tf->hob_lbam = cdb[15];
3213 tf->hob_lbah = cdb[14];
3214 tf->flags |= ATA_TFLAG_LBA48;
3215 } else
3216 tf->flags &= ~ATA_TFLAG_LBA48;
3217
3218 tf->feature = cdb[21];
3219 tf->nsect = cdb[23];
3220 tf->lbal = cdb[19];
3221 tf->lbam = cdb[18];
3222 tf->lbah = cdb[17];
3223 tf->device = cdb[24];
3224 tf->command = cdb[25];
3225 tf->auxiliary = get_unaligned_be32(&cdb[28]);
3196 } 3226 }
3197 3227
3198 /* For NCQ commands copy the tag value */ 3228 /* For NCQ commands copy the tag value */
@@ -4138,6 +4168,35 @@ static unsigned int ata_scsi_security_inout_xlat(struct ata_queued_cmd *qc)
4138} 4168}
4139 4169
4140/** 4170/**
4171 * ata_scsi_var_len_cdb_xlat - SATL variable length CDB to Handler
4172 * @qc: Command to be translated
4173 *
4174 * Translate a SCSI variable length CDB to specified commands.
4175 * It checks a service action value in CDB to call corresponding handler.
4176 *
4177 * RETURNS:
4178 * Zero on success, non-zero on failure
4179 *
4180 */
4181static unsigned int ata_scsi_var_len_cdb_xlat(struct ata_queued_cmd *qc)
4182{
4183 struct scsi_cmnd *scmd = qc->scsicmd;
4184 const u8 *cdb = scmd->cmnd;
4185 const u16 sa = get_unaligned_be16(&cdb[8]);
4186
4187 /*
4188 * if service action represents a ata pass-thru(32) command,
4189 * then pass it to ata_scsi_pass_thru handler.
4190 */
4191 if (sa == ATA_32)
4192 return ata_scsi_pass_thru(qc);
4193
4194unspprt_sa:
4195 /* unsupported service action */
4196 return 1;
4197}
4198
4199/**
4141 * ata_get_xlat_func - check if SCSI to ATA translation is possible 4200 * ata_get_xlat_func - check if SCSI to ATA translation is possible
4142 * @dev: ATA device 4201 * @dev: ATA device
4143 * @cmd: SCSI command opcode to consider 4202 * @cmd: SCSI command opcode to consider
@@ -4177,6 +4236,9 @@ static inline ata_xlat_func_t ata_get_xlat_func(struct ata_device *dev, u8 cmd)
4177 case ATA_16: 4236 case ATA_16:
4178 return ata_scsi_pass_thru; 4237 return ata_scsi_pass_thru;
4179 4238
4239 case VARIABLE_LENGTH_CMD:
4240 return ata_scsi_var_len_cdb_xlat;
4241
4180 case MODE_SELECT: 4242 case MODE_SELECT:
4181 case MODE_SELECT_10: 4243 case MODE_SELECT_10:
4182 return ata_scsi_mode_select_xlat; 4244 return ata_scsi_mode_select_xlat;
@@ -4461,7 +4523,7 @@ int ata_scsi_add_hosts(struct ata_host *host, struct scsi_host_template *sht)
4461 shost->max_id = 16; 4523 shost->max_id = 16;
4462 shost->max_lun = 1; 4524 shost->max_lun = 1;
4463 shost->max_channel = 1; 4525 shost->max_channel = 1;
4464 shost->max_cmd_len = 16; 4526 shost->max_cmd_len = 32;
4465 4527
4466 /* Schedule policy is determined by ->qc_defer() 4528 /* Schedule policy is determined by ->qc_defer()
4467 * callback and it needs to see every deferred qc. 4529 * callback and it needs to see every deferred qc.