Commit cd982c1a authored by Xingui Yang's avatar Xingui Yang Committed by Junhao He
Browse files

scsi: hisi_sas: Enable force phy when SATA disk directly connected

driver inclusion
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/IBCOG7


CVE: NA

----------------------------------------------------------------------

the SAS controller determines the disk to which I/Os are delivered based
on the port id in the DQ entry when SATA disk directly connected.

When many phys were disconnected immediately and connected again during
I/O sending and port id of phys were changed and used by other link, I/O
may be sent to incorrect disk and data inconsistency on the SATA disk may
occur during I/O retry with the old port id. So enable force phy, then
force the command to be executed in a certain phy, and if the actual phy
id of the port does not match the phy configured in the command, the chip
will stop delivering the I/O to disk.

Fixes: ce60689e ("scsi: hisi_sas: add v3 code to send ATA frame")
Signed-off-by: default avatarXingui Yang <yangxingui@huawei.com>
Signed-off-by: default avatarBing Xia <xiabing14@h-partners.com>
parent c949b128
Loading
Loading
Loading
Loading
+7 −2
Original line number Diff line number Diff line
@@ -2508,10 +2508,15 @@ static void prep_ata_v2_hw(struct hisi_hba *hisi_hba,
	/* create header */
	/* dw0 */
	dw0 = port->id << CMD_HDR_PORT_OFF;
	if (parent_dev && dev_is_expander(parent_dev->dev_type))
	if (parent_dev && dev_is_expander(parent_dev->dev_type)) {
		dw0 |= 3 << CMD_HDR_CMD_OFF;
	else
	} else {
		int phy_id = device->phy->identify.phy_identifier;

		dw0 |= (1U << phy_id) << CMD_HDR_PHY_ID_OFF;
		dw0 |= CMD_HDR_FORCE_PHY_MSK;
		dw0 |= 4 << CMD_HDR_CMD_OFF;
	}

	if (tmf && ata_task->force_phy) {
		dw0 |= CMD_HDR_FORCE_PHY_MSK;
+12 −2
Original line number Diff line number Diff line
@@ -359,6 +359,10 @@
#define CMD_HDR_RESP_REPORT_MSK		(0x1 << CMD_HDR_RESP_REPORT_OFF)
#define CMD_HDR_TLR_CTRL_OFF		6
#define CMD_HDR_TLR_CTRL_MSK		(0x3 << CMD_HDR_TLR_CTRL_OFF)
#define CMD_HDR_PHY_ID_OFF		8
#define CMD_HDR_PHY_ID_MSK		(0x1ff << CMD_HDR_PHY_ID_OFF)
#define CMD_HDR_FORCE_PHY_OFF		17
#define CMD_HDR_FORCE_PHY_MSK		(0x1U << CMD_HDR_FORCE_PHY_OFF)
#define CMD_HDR_PORT_OFF		18
#define CMD_HDR_PORT_MSK		(0xf << CMD_HDR_PORT_OFF)
#define CMD_HDR_PRIORITY_OFF		27
@@ -1434,10 +1438,16 @@ static void prep_ata_v3_hw(struct hisi_hba *hisi_hba,
	u32 dw1 = 0, dw2 = 0;

	hdr->dw0 = cpu_to_le32(port->id << CMD_HDR_PORT_OFF);
	if (parent_dev && dev_is_expander(parent_dev->dev_type))
	if (parent_dev && dev_is_expander(parent_dev->dev_type)) {
		hdr->dw0 |= cpu_to_le32(3 << CMD_HDR_CMD_OFF);
	else
	} else {
		int phy_id = device->phy->identify.phy_identifier;

		hdr->dw0 |= cpu_to_le32((1U << phy_id)
				<< CMD_HDR_PHY_ID_OFF);
		hdr->dw0 |= CMD_HDR_FORCE_PHY_MSK;
		hdr->dw0 |= cpu_to_le32(4U << CMD_HDR_CMD_OFF);
	}

	switch (task->data_dir) {
	case DMA_TO_DEVICE: