Commit 63ccc191 authored by Christoph Hellwig's avatar Christoph Hellwig Committed by Tejun Heo

libata: remove SCT WRITE SAME support

This was already disabled a while ago because it caused I/O errors,
and it's severly getting into the way of the discard / write zeroes
rework.
Signed-off-by: default avatarChristoph Hellwig <hch@lst.de>
Reviewed-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
Signed-off-by: default avatarTejun Heo <tj@kernel.org>
parent c6ade20f
...@@ -3392,46 +3392,6 @@ static size_t ata_format_dsm_trim_descr(struct scsi_cmnd *cmd, u32 trmax, ...@@ -3392,46 +3392,6 @@ static size_t ata_format_dsm_trim_descr(struct scsi_cmnd *cmd, u32 trmax,
return r; return r;
} }
/**
* ata_format_dsm_trim_descr() - SATL Write Same to ATA SCT Write Same
* @cmd: SCSI command being translated
* @lba: Starting sector
* @num: Number of sectors to be zero'd.
*
* Rewrite the WRITE SAME payload to be an SCT Write Same formatted
* descriptor.
* NOTE: Writes a pattern (0's) in the foreground.
*
* Return: Number of bytes copied into sglist.
*/
static size_t ata_format_sct_write_same(struct scsi_cmnd *cmd, u64 lba, u64 num)
{
struct scsi_device *sdp = cmd->device;
size_t len = sdp->sector_size;
size_t r;
u16 *buf;
unsigned long flags;
spin_lock_irqsave(&ata_scsi_rbuf_lock, flags);
buf = ((void *)ata_scsi_rbuf);
put_unaligned_le16(0x0002, &buf[0]); /* SCT_ACT_WRITE_SAME */
put_unaligned_le16(0x0101, &buf[1]); /* WRITE PTRN FG */
put_unaligned_le64(lba, &buf[2]);
put_unaligned_le64(num, &buf[6]);
put_unaligned_le32(0u, &buf[10]); /* pattern */
WARN_ON(len > ATA_SCSI_RBUF_SIZE);
if (len > ATA_SCSI_RBUF_SIZE)
len = ATA_SCSI_RBUF_SIZE;
r = sg_copy_from_buffer(scsi_sglist(cmd), scsi_sg_count(cmd), buf, len);
spin_unlock_irqrestore(&ata_scsi_rbuf_lock, flags);
return r;
}
/** /**
* ata_scsi_write_same_xlat() - SATL Write Same to ATA SCT Write Same * ata_scsi_write_same_xlat() - SATL Write Same to ATA SCT Write Same
* @qc: Command to be translated * @qc: Command to be translated
...@@ -3476,26 +3436,17 @@ static unsigned int ata_scsi_write_same_xlat(struct ata_queued_cmd *qc) ...@@ -3476,26 +3436,17 @@ static unsigned int ata_scsi_write_same_xlat(struct ata_queued_cmd *qc)
} }
scsi_16_lba_len(cdb, &block, &n_block); scsi_16_lba_len(cdb, &block, &n_block);
if (unmap) { if (!unmap ||
/* If trim is not enabled the cmd is invalid. */ (dev->horkage & ATA_HORKAGE_NOTRIM) ||
if ((dev->horkage & ATA_HORKAGE_NOTRIM) || !ata_id_has_trim(dev->id)) {
!ata_id_has_trim(dev->id)) { fp = 1;
fp = 1; bp = 3;
bp = 3; goto invalid_fld;
goto invalid_fld; }
} /* If the request is too large the cmd is invalid */
/* If the request is too large the cmd is invalid */ if (n_block > 0xffff * trmax) {
if (n_block > 0xffff * trmax) { fp = 2;
fp = 2; goto invalid_fld;
goto invalid_fld;
}
} else {
/* If write same is not available the cmd is invalid */
if (!ata_id_sct_write_same(dev->id)) {
fp = 1;
bp = 3;
goto invalid_fld;
}
} }
/* /*
...@@ -3510,49 +3461,28 @@ static unsigned int ata_scsi_write_same_xlat(struct ata_queued_cmd *qc) ...@@ -3510,49 +3461,28 @@ static unsigned int ata_scsi_write_same_xlat(struct ata_queued_cmd *qc)
* For DATA SET MANAGEMENT TRIM in ACS-2 nsect (aka count) * For DATA SET MANAGEMENT TRIM in ACS-2 nsect (aka count)
* is defined as number of 512 byte blocks to be transferred. * is defined as number of 512 byte blocks to be transferred.
*/ */
if (unmap) {
size = ata_format_dsm_trim_descr(scmd, trmax, block, n_block);
if (size != len)
goto invalid_param_len;
if (ata_ncq_enabled(dev) && ata_fpdma_dsm_supported(dev)) { size = ata_format_dsm_trim_descr(scmd, trmax, block, n_block);
/* Newer devices support queued TRIM commands */ if (size != len)
tf->protocol = ATA_PROT_NCQ; goto invalid_param_len;
tf->command = ATA_CMD_FPDMA_SEND;
tf->hob_nsect = ATA_SUBCMD_FPDMA_SEND_DSM & 0x1f;
tf->nsect = qc->tag << 3;
tf->hob_feature = (size / 512) >> 8;
tf->feature = size / 512;
tf->auxiliary = 1; if (ata_ncq_enabled(dev) && ata_fpdma_dsm_supported(dev)) {
} else { /* Newer devices support queued TRIM commands */
tf->protocol = ATA_PROT_DMA; tf->protocol = ATA_PROT_NCQ;
tf->hob_feature = 0; tf->command = ATA_CMD_FPDMA_SEND;
tf->feature = ATA_DSM_TRIM; tf->hob_nsect = ATA_SUBCMD_FPDMA_SEND_DSM & 0x1f;
tf->hob_nsect = (size / 512) >> 8; tf->nsect = qc->tag << 3;
tf->nsect = size / 512; tf->hob_feature = (size / 512) >> 8;
tf->command = ATA_CMD_DSM; tf->feature = size / 512;
}
} else {
size = ata_format_sct_write_same(scmd, block, n_block);
if (size != len)
goto invalid_param_len;
tf->hob_feature = 0; tf->auxiliary = 1;
tf->feature = 0; } else {
tf->hob_nsect = 0;
tf->nsect = 1;
tf->lbah = 0;
tf->lbam = 0;
tf->lbal = ATA_CMD_STANDBYNOW1;
tf->hob_lbah = 0;
tf->hob_lbam = 0;
tf->hob_lbal = 0;
tf->device = ATA_CMD_STANDBYNOW1;
tf->protocol = ATA_PROT_DMA; tf->protocol = ATA_PROT_DMA;
tf->command = ATA_CMD_WRITE_LOG_DMA_EXT; tf->hob_feature = 0;
if (unlikely(dev->flags & ATA_DFLAG_PIO)) tf->feature = ATA_DSM_TRIM;
tf->command = ATA_CMD_WRITE_LOG_EXT; tf->hob_nsect = (size / 512) >> 8;
tf->nsect = size / 512;
tf->command = ATA_CMD_DSM;
} }
tf->flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE | ATA_TFLAG_LBA48 | tf->flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE | ATA_TFLAG_LBA48 |
...@@ -3627,10 +3557,6 @@ static unsigned int ata_scsiop_maint_in(struct ata_scsi_args *args, u8 *rbuf) ...@@ -3627,10 +3557,6 @@ static unsigned int ata_scsiop_maint_in(struct ata_scsi_args *args, u8 *rbuf)
case START_STOP: case START_STOP:
supported = 3; supported = 3;
break; break;
case WRITE_SAME_16:
if (!ata_id_sct_write_same(dev->id))
break;
/* fallthrough: if SCT ... only enable for ZBC */
case ZBC_IN: case ZBC_IN:
case ZBC_OUT: case ZBC_OUT:
if (ata_id_zoned_cap(dev->id) || if (ata_id_zoned_cap(dev->id) ||
......
...@@ -817,11 +817,6 @@ static inline bool ata_id_sct_error_recovery_ctrl(const u16 *id) ...@@ -817,11 +817,6 @@ static inline bool ata_id_sct_error_recovery_ctrl(const u16 *id)
return id[ATA_ID_SCT_CMD_XPORT] & (1 << 3) ? true : false; return id[ATA_ID_SCT_CMD_XPORT] & (1 << 3) ? true : false;
} }
static inline bool ata_id_sct_write_same(const u16 *id)
{
return id[ATA_ID_SCT_CMD_XPORT] & (1 << 2) ? true : false;
}
static inline bool ata_id_sct_long_sector_access(const u16 *id) static inline bool ata_id_sct_long_sector_access(const u16 *id)
{ {
return id[ATA_ID_SCT_CMD_XPORT] & (1 << 1) ? true : false; return id[ATA_ID_SCT_CMD_XPORT] & (1 << 1) ? true : false;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment