Merge patch series "Returning FIS on success for CDL"

Igor Pylypiv <ipylypiv@google.com> says:

This patch series plumbs libata's request for a result taskfile
(ATA_QCFLAG_RESULT_TF) through libsas to pm80xx LLDD. Other libsas LLDDs
can start using the newly added return_fis_on_success as well, if needed.

For Command Duration Limits policy 0xD (command completes without an
error) libata needs FIS in order to detect the ATA_SENSE bit and read
the Sense Data for Successful NCQ Commands log (0Fh). pm80xx HBAs do
not return FIS on success by default, hence, the driver is updated to
set the RETFIS bit (Return FIS on good completion) when requested by
libsas.

Link: https://lore.kernel.org/r/20230819213040.1101044-1-ipylypiv@google.com
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
This commit is contained in:
Martin K. Petersen 2023-08-24 21:05:19 -04:00
commit ef5d681b4d
6 changed files with 23 additions and 18 deletions

View File

@ -207,6 +207,9 @@ static unsigned int sas_ata_qc_issue(struct ata_queued_cmd *qc)
task->ata_task.use_ncq = ata_is_ncq(qc->tf.protocol);
task->ata_task.dma_xfer = ata_is_dma(qc->tf.protocol);
if (qc->flags & ATA_QCFLAG_RESULT_TF)
task->ata_task.return_fis_on_success = 1;
if (qc->scsicmd)
ASSIGN_SAS_TASK(qc->scsicmd, task);

View File

@ -4095,7 +4095,7 @@ static int pm8001_chip_sata_req(struct pm8001_hba_info *pm8001_ha,
u32 hdr_tag, ncg_tag = 0;
u64 phys_addr;
u32 ATAP = 0x0;
u32 dir;
u32 dir, retfis = 0;
u32 opc = OPC_INB_SATA_HOST_OPSTART;
memset(&sata_cmd, 0, sizeof(sata_cmd));
@ -4124,8 +4124,11 @@ static int pm8001_chip_sata_req(struct pm8001_hba_info *pm8001_ha,
sata_cmd.tag = cpu_to_le32(tag);
sata_cmd.device_id = cpu_to_le32(pm8001_ha_dev->device_id);
sata_cmd.data_len = cpu_to_le32(task->total_xfer_len);
sata_cmd.ncqtag_atap_dir_m =
cpu_to_le32(((ncg_tag & 0xff)<<16)|((ATAP & 0x3f) << 10) | dir);
if (task->ata_task.return_fis_on_success)
retfis = 1;
sata_cmd.retfis_ncqtag_atap_dir_m =
cpu_to_le32((retfis << 24) | ((ncg_tag & 0xff) << 16) |
((ATAP & 0x3f) << 10) | dir);
sata_cmd.sata_fis = task->ata_task.fis;
if (likely(!task->ata_task.device_control_reg_update))
sata_cmd.sata_fis.flags |= 0x80;/* C=1: update ATA cmd reg */

View File

@ -515,7 +515,7 @@ struct sata_start_req {
__le32 tag;
__le32 device_id;
__le32 data_len;
__le32 ncqtag_atap_dir_m;
__le32 retfis_ncqtag_atap_dir_m;
struct host_to_dev_fis sata_fis;
u32 reserved1;
u32 reserved2;

View File

@ -4457,7 +4457,7 @@ static int pm80xx_chip_sata_req(struct pm8001_hba_info *pm8001_ha,
u64 phys_addr, end_addr;
u32 end_addr_high, end_addr_low;
u32 ATAP = 0x0;
u32 dir;
u32 dir, retfis = 0;
u32 opc = OPC_INB_SATA_HOST_OPSTART;
memset(&sata_cmd, 0, sizeof(sata_cmd));
@ -4487,7 +4487,8 @@ static int pm80xx_chip_sata_req(struct pm8001_hba_info *pm8001_ha,
sata_cmd.tag = cpu_to_le32(tag);
sata_cmd.device_id = cpu_to_le32(pm8001_ha_dev->device_id);
sata_cmd.data_len = cpu_to_le32(task->total_xfer_len);
if (task->ata_task.return_fis_on_success)
retfis = 1;
sata_cmd.sata_fis = task->ata_task.fis;
if (likely(!task->ata_task.device_control_reg_update))
sata_cmd.sata_fis.flags |= 0x80;/* C=1: update ATA cmd reg */
@ -4500,12 +4501,10 @@ static int pm80xx_chip_sata_req(struct pm8001_hba_info *pm8001_ha,
"Encryption enabled.Sending Encrypt SATA cmd 0x%x\n",
sata_cmd.sata_fis.command);
opc = OPC_INB_SATA_DIF_ENC_IO;
/* set encryption bit */
sata_cmd.ncqtag_atap_dir_m_dad =
cpu_to_le32(((ncg_tag & 0xff)<<16)|
((ATAP & 0x3f) << 10) | 0x20 | dir);
/* dad (bit 0-1) is 0 */
/* set encryption bit; dad (bits 0-1) is 0 */
sata_cmd.retfis_ncqtag_atap_dir_m_dad =
cpu_to_le32((retfis << 24) | ((ncg_tag & 0xff) << 16) |
((ATAP & 0x3f) << 10) | 0x20 | dir);
/* fill in PRD (scatter/gather) table, if any */
if (task->num_scatter > 1) {
pm8001_chip_make_sg(task->scatter,
@ -4568,11 +4567,10 @@ static int pm80xx_chip_sata_req(struct pm8001_hba_info *pm8001_ha,
pm8001_dbg(pm8001_ha, IO,
"Sending Normal SATA command 0x%x inb %x\n",
sata_cmd.sata_fis.command, q_index);
/* dad (bit 0-1) is 0 */
sata_cmd.ncqtag_atap_dir_m_dad =
cpu_to_le32(((ncg_tag & 0xff)<<16) |
((ATAP & 0x3f) << 10) | dir);
/* dad (bits 0-1) is 0 */
sata_cmd.retfis_ncqtag_atap_dir_m_dad =
cpu_to_le32((retfis << 24) | ((ncg_tag & 0xff) << 16) |
((ATAP & 0x3f) << 10) | dir);
/* fill in PRD (scatter/gather) table, if any */
if (task->num_scatter > 1) {
pm8001_chip_make_sg(task->scatter,

View File

@ -731,7 +731,7 @@ struct sata_start_req {
__le32 tag;
__le32 device_id;
__le32 data_len;
__le32 ncqtag_atap_dir_m_dad;
__le32 retfis_ncqtag_atap_dir_m_dad;
struct host_to_dev_fis sata_fis;
u32 reserved1;
u32 reserved2; /* dword 11. rsvd for normal I/O. */

View File

@ -550,6 +550,7 @@ struct sas_ata_task {
u8 use_ncq:1;
u8 set_affil_pol:1;
u8 stp_affil_pol:1;
u8 return_fis_on_success:1;
u8 device_control_reg_update:1;