All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v4 00/31] libsas and pm8001 fixes
@ 2022-02-17 13:29 Damien Le Moal
  2022-02-17 13:29 ` [PATCH v4 01/31] scsi: libsas: Fix sas_ata_qc_issue() handling of NCQ NON DATA commands Damien Le Moal
                   ` (30 more replies)
  0 siblings, 31 replies; 65+ messages in thread
From: Damien Le Moal @ 2022-02-17 13:29 UTC (permalink / raw)
  To: linux-scsi, Martin K . Petersen, Jack Wang, John Garry
  Cc: Xiang Chen, Jason Yan, Luo Jiaxing

This first part of this series (patches 1 to 24) fixes handling of NCQ
NON DATA commands in libsas and many bugs in the pm8001 driver.

The fixes for the pm8001 driver include:
* Suppression of all sparse warnings, fixing along the way many le32
  handling bugs for big-endian architectures
* Fix handling of NCQ NON DATA commands
* Fix of tag values handling (0 *is* a valid tag value)
* Fix many tag iand memory leaks in error path
* Fix NCQ error recovery (abort all task execution) that was causing a
  crash

The second part of the series (patches 24 to 31) add a small cleanup of
libsas code and many simplifications and iomprovements of the pm8001
driver code.

With these fixes, libzbc test suite passes all test case. This test
suite was used with an SMR drive for testing because it generates many
NCQ NON DATA commands (for zone management commands) and also generates
many NCQ command errors to check ASC/ASCQ returned by the device. With
the test suite, the error recovery path was extensively exercised. The
same tests were also executed with a SAS SMR drives to exercise the
error path.

The patches are based on the latest 5.18/scsi-staging tree.

Changes from v3:
* Rebase on latest 5.18/scsi-staging tree
* Dropped former patch 24 (kdoc comment fixed upstream already)
* Merged former patch 27 and 30
* Fixed patch 26 commit message
* Added patches 30 and 31
* Added reviewed-by tags

Changes from v2:
* Reorganized the series: fixes first, cleanups second.
* Added more bug/leaks fix patches
* Addressed Gary's comment for the ccb alloc helper (patch 28)
* Rebased (and tested) all patches on 5.18/scsi-staging

Changes from v1:
* Added reviewed-by tags
* Addressed Christoph's comments on patch 4 and 8
* Added patches 21 and 22 to fix 2 additional problems found while
  preparing this v2 series
* Added patch 23 and 24 to cleanup the code further.

Damien Le Moal (31):
  scsi: libsas: Fix sas_ata_qc_issue() handling of NCQ NON DATA commands
  scsi: pm8001: Fix __iomem pointer use in pm8001_phy_control()
  scsi: pm8001: Fix pm8001_update_flash() local variable type
  scsi: pm8001: Fix command initialization in pm80XX_send_read_log()
  scsi: pm8001: Fix pm80xx_pci_mem_copy() interface
  scsi: pm8001: Fix command initialization in pm8001_chip_ssp_tm_req()
  scsi: pm8001: Fix payload initialization in pm80xx_set_thermal_config()
  scsi: pm8001: Fix le32 values handling in pm80xx_set_sas_protocol_timer_config()
  scsi: pm8001: Fix payload initialization in pm80xx_encrypt_update()
  scsi: pm8001: Fix le32 values handling in pm80xx_chip_ssp_io_req()
  scsi: pm8001: Fix le32 values handling in pm80xx_chip_sata_req()
  scsi: pm8001: Fix use of struct set_phy_profile_req fields
  scsi: pm8001: Remove local variable in pm8001_pci_resume()
  scsi: pm8001: Fix NCQ NON DATA command task initialization
  scsi: pm8001: Fix NCQ NON DATA command completion handling
  scsi: pm8001: Fix abort all task initialization
  scsi: pm8001: Fix pm8001_tag_alloc() failures handling
  scsi: pm8001: Fix pm80xx_chip_phy_ctl_req()
  scsi: pm8001: Fix pm8001_mpi_task_abort_resp()
  scsi: pm8001: Fix tag values handling
  scsi: pm8001: Fix task leak in pm8001_send_abort_all()
  scsi: pm8001: Fix tag leaks on error
  scsi: pm8001: fix memory leak in pm8001_chip_fw_flash_update_req()
  scsi: libsas: Simplify sas_ata_qc_issue() detection of NCQ commands
  scsi: pm8001: Simplify pm8001_get_ncq_tag()
  scsi: pm8001: Introduce ccb alloc/free helpers
  scsi: pm8001: Simplify pm8001_mpi_build_cmd() interface
  scsi: pm8001: Simplify pm8001_task_exec()
  scsi: pm8001: Simplify pm8001_ccb_task_free()
  scsi: pm8001: improve pm80XX_send_abort_all()
  scsi: pm8001: Fix pm8001_info() message format

 drivers/scsi/libsas/sas_ata.c     |  11 +-
 drivers/scsi/pm8001/pm8001_ctl.c  |   5 +-
 drivers/scsi/pm8001/pm8001_hwi.c  | 458 ++++++++++++-----------------
 drivers/scsi/pm8001/pm8001_init.c |  11 +-
 drivers/scsi/pm8001/pm8001_sas.c  | 296 +++++++++----------
 drivers/scsi/pm8001/pm8001_sas.h  |  66 ++++-
 drivers/scsi/pm8001/pm80xx_hwi.c  | 467 ++++++++++++++----------------
 drivers/scsi/pm8001/pm80xx_hwi.h  |   2 +-
 8 files changed, 608 insertions(+), 708 deletions(-)

-- 
2.34.1


^ permalink raw reply	[flat|nested] 65+ messages in thread

* [PATCH v4 01/31] scsi: libsas: Fix sas_ata_qc_issue() handling of NCQ NON DATA commands
  2022-02-17 13:29 [PATCH v4 00/31] libsas and pm8001 fixes Damien Le Moal
@ 2022-02-17 13:29 ` Damien Le Moal
  2022-02-17 18:56   ` Jinpu Wang
  2022-02-17 13:29 ` [PATCH v4 02/31] scsi: pm8001: Fix __iomem pointer use in pm8001_phy_control() Damien Le Moal
                   ` (29 subsequent siblings)
  30 siblings, 1 reply; 65+ messages in thread
From: Damien Le Moal @ 2022-02-17 13:29 UTC (permalink / raw)
  To: linux-scsi, Martin K . Petersen, Jack Wang, John Garry
  Cc: Xiang Chen, Jason Yan, Luo Jiaxing

To detect for the DMA_NONE (no data transfer) DMA direction,
sas_ata_qc_issue() tests if the command protocol is ATA_PROT_NODATA.
This test does not include the ATA_CMD_NCQ_NON_DATA command as this
command protocol is defined as ATA_PROT_NCQ_NODATA (equal to
ATA_PROT_FLAG_NCQ) and not as ATA_PROT_NODATA.

To include both NCQ and non-NCQ commands when testing for the DMA_NONE
DMA direction, use "!ata_is_data()".

Fixes: 176ddd89171d ("scsi: libsas: Reset num_scatter if libata marks qc as NODATA")
Cc: stable@vger.kernel.org
Signed-off-by: Damien Le Moal <damien.lemoal@opensource.wdc.com>
Reviewed-by: John Garry <john.garry@huawei.com>
---
 drivers/scsi/libsas/sas_ata.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/scsi/libsas/sas_ata.c b/drivers/scsi/libsas/sas_ata.c
index e0030a093994..50f779088b6e 100644
--- a/drivers/scsi/libsas/sas_ata.c
+++ b/drivers/scsi/libsas/sas_ata.c
@@ -197,7 +197,7 @@ static unsigned int sas_ata_qc_issue(struct ata_queued_cmd *qc)
 		task->total_xfer_len = qc->nbytes;
 		task->num_scatter = qc->n_elem;
 		task->data_dir = qc->dma_dir;
-	} else if (qc->tf.protocol == ATA_PROT_NODATA) {
+	} else if (!ata_is_data(qc->tf.protocol)) {
 		task->data_dir = DMA_NONE;
 	} else {
 		for_each_sg(qc->sg, sg, qc->n_elem, si)
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 65+ messages in thread

* [PATCH v4 02/31] scsi: pm8001: Fix __iomem pointer use in pm8001_phy_control()
  2022-02-17 13:29 [PATCH v4 00/31] libsas and pm8001 fixes Damien Le Moal
  2022-02-17 13:29 ` [PATCH v4 01/31] scsi: libsas: Fix sas_ata_qc_issue() handling of NCQ NON DATA commands Damien Le Moal
@ 2022-02-17 13:29 ` Damien Le Moal
  2022-02-17 19:01   ` Jinpu Wang
  2022-02-17 13:29 ` [PATCH v4 03/31] scsi: pm8001: Fix pm8001_update_flash() local variable type Damien Le Moal
                   ` (28 subsequent siblings)
  30 siblings, 1 reply; 65+ messages in thread
From: Damien Le Moal @ 2022-02-17 13:29 UTC (permalink / raw)
  To: linux-scsi, Martin K . Petersen, Jack Wang, John Garry
  Cc: Xiang Chen, Jason Yan, Luo Jiaxing

Avoid the sparse warning "warning: cast removes address space '__iomem'
of expression" by declaring the qp pointer as "u32 __iomem *".
Accordingly, change the accesses to the qp array to use readl().

Signed-off-by: Damien Le Moal <damien.lemoal@opensource.wdc.com>
---
 drivers/scsi/pm8001/pm8001_sas.c | 15 +++++++--------
 1 file changed, 7 insertions(+), 8 deletions(-)

diff --git a/drivers/scsi/pm8001/pm8001_sas.c b/drivers/scsi/pm8001/pm8001_sas.c
index 8c12fbb9c476..4ab0ea9483f2 100644
--- a/drivers/scsi/pm8001/pm8001_sas.c
+++ b/drivers/scsi/pm8001/pm8001_sas.c
@@ -234,14 +234,13 @@ int pm8001_phy_control(struct asd_sas_phy *sas_phy, enum phy_func func,
 		}
 		{
 			struct sas_phy *phy = sas_phy->phy;
-			uint32_t *qp = (uint32_t *)(((char *)
-				pm8001_ha->io_mem[2].memvirtaddr)
-				+ 0x1034 + (0x4000 * (phy_id & 3)));
-
-			phy->invalid_dword_count = qp[0];
-			phy->running_disparity_error_count = qp[1];
-			phy->loss_of_dword_sync_count = qp[3];
-			phy->phy_reset_problem_count = qp[4];
+			u32 __iomem *qp = pm8001_ha->io_mem[2].memvirtaddr
+				+ 0x1034 + (0x4000 * (phy_id & 3));
+
+			phy->invalid_dword_count = readl(qp);
+			phy->running_disparity_error_count = readl(&qp[1]);
+			phy->loss_of_dword_sync_count = readl(&qp[3]);
+			phy->phy_reset_problem_count = readl(&qp[4]);
 		}
 		if (pm8001_ha->chip_id == chip_8001)
 			pm8001_bar4_shift(pm8001_ha, 0);
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 65+ messages in thread

* [PATCH v4 03/31] scsi: pm8001: Fix pm8001_update_flash() local variable type
  2022-02-17 13:29 [PATCH v4 00/31] libsas and pm8001 fixes Damien Le Moal
  2022-02-17 13:29 ` [PATCH v4 01/31] scsi: libsas: Fix sas_ata_qc_issue() handling of NCQ NON DATA commands Damien Le Moal
  2022-02-17 13:29 ` [PATCH v4 02/31] scsi: pm8001: Fix __iomem pointer use in pm8001_phy_control() Damien Le Moal
@ 2022-02-17 13:29 ` Damien Le Moal
  2022-02-17 19:03   ` Jinpu Wang
  2022-02-17 13:29 ` [PATCH v4 04/31] scsi: pm8001: Fix command initialization in pm80XX_send_read_log() Damien Le Moal
                   ` (27 subsequent siblings)
  30 siblings, 1 reply; 65+ messages in thread
From: Damien Le Moal @ 2022-02-17 13:29 UTC (permalink / raw)
  To: linux-scsi, Martin K . Petersen, Jack Wang, John Garry
  Cc: Xiang Chen, Jason Yan, Luo Jiaxing

Change the type of partitionSizeTmp from u32 to __be32 to suppress the
sparse warning:

warning: cast to restricted __be32

Signed-off-by: Damien Le Moal <damien.lemoal@opensource.wdc.com>
---
 drivers/scsi/pm8001/pm8001_ctl.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/scsi/pm8001/pm8001_ctl.c b/drivers/scsi/pm8001/pm8001_ctl.c
index 66307783c73c..73f036bed128 100644
--- a/drivers/scsi/pm8001/pm8001_ctl.c
+++ b/drivers/scsi/pm8001/pm8001_ctl.c
@@ -721,7 +721,8 @@ static int pm8001_update_flash(struct pm8001_hba_info *pm8001_ha)
 	DECLARE_COMPLETION_ONSTACK(completion);
 	u8		*ioctlbuffer;
 	struct fw_control_info	*fwControl;
-	u32		partitionSize, partitionSizeTmp;
+	__be32		partitionSizeTmp;
+	u32		partitionSize;
 	u32		loopNumber, loopcount;
 	struct pm8001_fw_image_header *image_hdr;
 	u32		sizeRead = 0;
@@ -742,7 +743,7 @@ static int pm8001_update_flash(struct pm8001_hba_info *pm8001_ha)
 	image_hdr = (struct pm8001_fw_image_header *)pm8001_ha->fw_image->data;
 	while (sizeRead < pm8001_ha->fw_image->size) {
 		partitionSizeTmp =
-			*(u32 *)((u8 *)&image_hdr->image_length + sizeRead);
+			*(__be32 *)((u8 *)&image_hdr->image_length + sizeRead);
 		partitionSize = be32_to_cpu(partitionSizeTmp);
 		loopcount = DIV_ROUND_UP(partitionSize + HEADER_LEN,
 					IOCTL_BUF_SIZE);
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 65+ messages in thread

* [PATCH v4 04/31] scsi: pm8001: Fix command initialization in pm80XX_send_read_log()
  2022-02-17 13:29 [PATCH v4 00/31] libsas and pm8001 fixes Damien Le Moal
                   ` (2 preceding siblings ...)
  2022-02-17 13:29 ` [PATCH v4 03/31] scsi: pm8001: Fix pm8001_update_flash() local variable type Damien Le Moal
@ 2022-02-17 13:29 ` Damien Le Moal
  2022-02-17 19:05   ` Jinpu Wang
  2022-02-17 13:29 ` [PATCH v4 05/31] scsi: pm8001: Fix pm80xx_pci_mem_copy() interface Damien Le Moal
                   ` (26 subsequent siblings)
  30 siblings, 1 reply; 65+ messages in thread
From: Damien Le Moal @ 2022-02-17 13:29 UTC (permalink / raw)
  To: linux-scsi, Martin K . Petersen, Jack Wang, John Garry
  Cc: Xiang Chen, Jason Yan, Luo Jiaxing

Since the sata_cmd struct is zeroed out before its fields are
initialized, there is no need for using "|=" to initialize the
ncqtag_atap_dir_m field. Using a standard assignment removes the sparse
warning:

warning: invalid assignment: |=

Also, since the ncqtag_atap_dir_m field has type __le32, use
cpu_to_le32() to generate the assigned value.

Fixes: c6b9ef5779c3 ("[SCSI] pm80xx: NCQ error handling changes")
Reviewed-by: John Garry <john.garry@huawei.com>
Signed-off-by: Damien Le Moal <damien.lemoal@opensource.wdc.com>
---
 drivers/scsi/pm8001/pm8001_hwi.c | 2 +-
 drivers/scsi/pm8001/pm80xx_hwi.c | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/scsi/pm8001/pm8001_hwi.c b/drivers/scsi/pm8001/pm8001_hwi.c
index 4683fee87b84..817bba65feb3 100644
--- a/drivers/scsi/pm8001/pm8001_hwi.c
+++ b/drivers/scsi/pm8001/pm8001_hwi.c
@@ -1864,7 +1864,7 @@ static void pm8001_send_read_log(struct pm8001_hba_info *pm8001_ha,
 
 	sata_cmd.tag = cpu_to_le32(ccb_tag);
 	sata_cmd.device_id = cpu_to_le32(pm8001_ha_dev->device_id);
-	sata_cmd.ncqtag_atap_dir_m |= ((0x1 << 7) | (0x5 << 9));
+	sata_cmd.ncqtag_atap_dir_m = cpu_to_le32((0x1 << 7) | (0x5 << 9));
 	memcpy(&sata_cmd.sata_fis, &fis, sizeof(struct host_to_dev_fis));
 
 	res = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &sata_cmd,
diff --git a/drivers/scsi/pm8001/pm80xx_hwi.c b/drivers/scsi/pm8001/pm80xx_hwi.c
index b83500ef3d86..f1663a10693a 100644
--- a/drivers/scsi/pm8001/pm80xx_hwi.c
+++ b/drivers/scsi/pm8001/pm80xx_hwi.c
@@ -1882,7 +1882,7 @@ static void pm80xx_send_read_log(struct pm8001_hba_info *pm8001_ha,
 
 	sata_cmd.tag = cpu_to_le32(ccb_tag);
 	sata_cmd.device_id = cpu_to_le32(pm8001_ha_dev->device_id);
-	sata_cmd.ncqtag_atap_dir_m_dad |= ((0x1 << 7) | (0x5 << 9));
+	sata_cmd.ncqtag_atap_dir_m_dad = cpu_to_le32(((0x1 << 7) | (0x5 << 9)));
 	memcpy(&sata_cmd.sata_fis, &fis, sizeof(struct host_to_dev_fis));
 
 	res = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &sata_cmd,
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 65+ messages in thread

* [PATCH v4 05/31] scsi: pm8001: Fix pm80xx_pci_mem_copy() interface
  2022-02-17 13:29 [PATCH v4 00/31] libsas and pm8001 fixes Damien Le Moal
                   ` (3 preceding siblings ...)
  2022-02-17 13:29 ` [PATCH v4 04/31] scsi: pm8001: Fix command initialization in pm80XX_send_read_log() Damien Le Moal
@ 2022-02-17 13:29 ` Damien Le Moal
  2022-02-17 19:06   ` Jinpu Wang
  2022-02-17 13:29 ` [PATCH v4 06/31] scsi: pm8001: Fix command initialization in pm8001_chip_ssp_tm_req() Damien Le Moal
                   ` (25 subsequent siblings)
  30 siblings, 1 reply; 65+ messages in thread
From: Damien Le Moal @ 2022-02-17 13:29 UTC (permalink / raw)
  To: linux-scsi, Martin K . Petersen, Jack Wang, John Garry
  Cc: Xiang Chen, Jason Yan, Luo Jiaxing

The declaration of the local variable destination1 in
pm80xx_pci_mem_copy() as a pointer to a u32 results in the sparse
warning:

warning: incorrect type in assignment (different base types)
    expected unsigned int [usertype]
    got restricted __le32 [usertype]

Furthermore, the destination" argument of pm80xx_pci_mem_copy() is
wrongly declared with the const attribute.

Fix both problems by changing the type of the "destination" argument
to "__le32 *" and use this argument directly inside the
pm80xx_pci_mem_copy() function, thus removing the need for the
destination1 local variable.

Signed-off-by: Damien Le Moal <damien.lemoal@opensource.wdc.com>
---
 drivers/scsi/pm8001/pm80xx_hwi.c | 8 +++-----
 1 file changed, 3 insertions(+), 5 deletions(-)

diff --git a/drivers/scsi/pm8001/pm80xx_hwi.c b/drivers/scsi/pm8001/pm80xx_hwi.c
index f1663a10693a..0b3386a3c508 100644
--- a/drivers/scsi/pm8001/pm80xx_hwi.c
+++ b/drivers/scsi/pm8001/pm80xx_hwi.c
@@ -67,18 +67,16 @@ int pm80xx_bar4_shift(struct pm8001_hba_info *pm8001_ha, u32 shift_value)
 }
 
 static void pm80xx_pci_mem_copy(struct pm8001_hba_info  *pm8001_ha, u32 soffset,
-				const void *destination,
+				__le32 *destination,
 				u32 dw_count, u32 bus_base_number)
 {
 	u32 index, value, offset;
-	u32 *destination1;
-	destination1 = (u32 *)destination;
 
-	for (index = 0; index < dw_count; index += 4, destination1++) {
+	for (index = 0; index < dw_count; index += 4, destination++) {
 		offset = (soffset + index);
 		if (offset < (64 * 1024)) {
 			value = pm8001_cr32(pm8001_ha, bus_base_number, offset);
-			*destination1 =  cpu_to_le32(value);
+			*destination = cpu_to_le32(value);
 		}
 	}
 	return;
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 65+ messages in thread

* [PATCH v4 06/31] scsi: pm8001: Fix command initialization in pm8001_chip_ssp_tm_req()
  2022-02-17 13:29 [PATCH v4 00/31] libsas and pm8001 fixes Damien Le Moal
                   ` (4 preceding siblings ...)
  2022-02-17 13:29 ` [PATCH v4 05/31] scsi: pm8001: Fix pm80xx_pci_mem_copy() interface Damien Le Moal
@ 2022-02-17 13:29 ` Damien Le Moal
  2022-02-17 19:07   ` Jinpu Wang
  2022-02-17 13:29 ` [PATCH v4 07/31] scsi: pm8001: Fix payload initialization in pm80xx_set_thermal_config() Damien Le Moal
                   ` (24 subsequent siblings)
  30 siblings, 1 reply; 65+ messages in thread
From: Damien Le Moal @ 2022-02-17 13:29 UTC (permalink / raw)
  To: linux-scsi, Martin K . Petersen, Jack Wang, John Garry
  Cc: Xiang Chen, Jason Yan, Luo Jiaxing

The ds_ads_m field of struct ssp_ini_tm_start_req has the type __le32.
Assigning a value to it should thus use cpu_to_le32(). This fixes the
sparse warning:

warning: incorrect type in assignment (different base types)
   expected restricted __le32 [addressable] [assigned] [usertype] ds_ads_m
   got int

Fixes: dbf9bfe61571 ("[SCSI] pm8001: add SAS/SATA HBA driver")
Signed-off-by: Damien Le Moal <damien.lemoal@opensource.wdc.com>
---
 drivers/scsi/pm8001/pm8001_hwi.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/scsi/pm8001/pm8001_hwi.c b/drivers/scsi/pm8001/pm8001_hwi.c
index 817bba65feb3..e20a1d4db026 100644
--- a/drivers/scsi/pm8001/pm8001_hwi.c
+++ b/drivers/scsi/pm8001/pm8001_hwi.c
@@ -4619,7 +4619,7 @@ int pm8001_chip_ssp_tm_req(struct pm8001_hba_info *pm8001_ha,
 	memcpy(sspTMCmd.lun, task->ssp_task.LUN, 8);
 	sspTMCmd.tag = cpu_to_le32(ccb->ccb_tag);
 	if (pm8001_ha->chip_id != chip_8001)
-		sspTMCmd.ds_ads_m = 0x08;
+		sspTMCmd.ds_ads_m = cpu_to_le32(0x08);
 	circularQ = &pm8001_ha->inbnd_q_tbl[0];
 	ret = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &sspTMCmd,
 			sizeof(sspTMCmd), 0);
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 65+ messages in thread

* [PATCH v4 07/31] scsi: pm8001: Fix payload initialization in pm80xx_set_thermal_config()
  2022-02-17 13:29 [PATCH v4 00/31] libsas and pm8001 fixes Damien Le Moal
                   ` (5 preceding siblings ...)
  2022-02-17 13:29 ` [PATCH v4 06/31] scsi: pm8001: Fix command initialization in pm8001_chip_ssp_tm_req() Damien Le Moal
@ 2022-02-17 13:29 ` Damien Le Moal
  2022-02-17 19:09   ` Jinpu Wang
  2022-02-17 13:29 ` [PATCH v4 08/31] scsi: pm8001: Fix le32 values handling in pm80xx_set_sas_protocol_timer_config() Damien Le Moal
                   ` (23 subsequent siblings)
  30 siblings, 1 reply; 65+ messages in thread
From: Damien Le Moal @ 2022-02-17 13:29 UTC (permalink / raw)
  To: linux-scsi, Martin K . Petersen, Jack Wang, John Garry
  Cc: Xiang Chen, Jason Yan, Luo Jiaxing

The fields of the set_ctrl_cfg_req structure have the __le32 type, so
use cpu_to_le32() to assign them. This removes the sparse warnings:

warning: incorrect type in assignment (different base types)
    expected restricted __le32
    got unsigned int

Fixes: 842784e0d15b ("pm80xx: Update For Thermal Page Code")
Fixes: f5860992db55 ("[SCSI] pm80xx: Added SPCv/ve specific hardware functionalities and relevant changes in common files")
Signed-off-by: Damien Le Moal <damien.lemoal@opensource.wdc.com>
Reviewed-by: John Garry <john.garry@huawei.com>
---
 drivers/scsi/pm8001/pm80xx_hwi.c | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/drivers/scsi/pm8001/pm80xx_hwi.c b/drivers/scsi/pm8001/pm80xx_hwi.c
index 0b3386a3c508..b303bc347f3d 100644
--- a/drivers/scsi/pm8001/pm80xx_hwi.c
+++ b/drivers/scsi/pm8001/pm80xx_hwi.c
@@ -1201,9 +1201,11 @@ pm80xx_set_thermal_config(struct pm8001_hba_info *pm8001_ha)
 	else
 		page_code = THERMAL_PAGE_CODE_8H;
 
-	payload.cfg_pg[0] = (THERMAL_LOG_ENABLE << 9) |
-				(THERMAL_ENABLE << 8) | page_code;
-	payload.cfg_pg[1] = (LTEMPHIL << 24) | (RTEMPHIL << 8);
+	payload.cfg_pg[0] =
+		cpu_to_le32((THERMAL_LOG_ENABLE << 9) |
+			    (THERMAL_ENABLE << 8) | page_code);
+	payload.cfg_pg[1] =
+		cpu_to_le32((LTEMPHIL << 24) | (RTEMPHIL << 8));
 
 	pm8001_dbg(pm8001_ha, DEV,
 		   "Setting up thermal config. cfg_pg 0 0x%x cfg_pg 1 0x%x\n",
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 65+ messages in thread

* [PATCH v4 08/31] scsi: pm8001: Fix le32 values handling in pm80xx_set_sas_protocol_timer_config()
  2022-02-17 13:29 [PATCH v4 00/31] libsas and pm8001 fixes Damien Le Moal
                   ` (6 preceding siblings ...)
  2022-02-17 13:29 ` [PATCH v4 07/31] scsi: pm8001: Fix payload initialization in pm80xx_set_thermal_config() Damien Le Moal
@ 2022-02-17 13:29 ` Damien Le Moal
  2022-02-17 19:08   ` Jinpu Wang
  2022-02-17 13:29 ` [PATCH v4 09/31] scsi: pm8001: Fix payload initialization in pm80xx_encrypt_update() Damien Le Moal
                   ` (22 subsequent siblings)
  30 siblings, 1 reply; 65+ messages in thread
From: Damien Le Moal @ 2022-02-17 13:29 UTC (permalink / raw)
  To: linux-scsi, Martin K . Petersen, Jack Wang, John Garry
  Cc: Xiang Chen, Jason Yan, Luo Jiaxing

All fields of the SASProtocolTimerConfig structure have the __le32 type.
As such, use cpu_to_le32() to initialize them. This change suppresses
many sparse warnings:

warning: incorrect type in assignment (different base types)
   expected restricted __le32 [addressable] [usertype] pageCode
   got int

Note that the check to limit the value of the STP_IDLE_TMO field is
removed as this field is initialized using the fixed (and small) value
defined by the STP_IDLE_TIME macro.

The pm8001_dbg() calls printing the values of the SASProtocolTimerConfig
structure fileds are changed to use le32_to_cpu() to present the values
in human readable form.

Fixes: a6cb3d012b98 ("[SCSI] pm80xx: thermal, sas controller config and error handling update")
Signed-off-by: Damien Le Moal <damien.lemoal@opensource.wdc.com>
---
 drivers/scsi/pm8001/pm80xx_hwi.c | 52 +++++++++++++++-----------------
 1 file changed, 25 insertions(+), 27 deletions(-)

diff --git a/drivers/scsi/pm8001/pm80xx_hwi.c b/drivers/scsi/pm8001/pm80xx_hwi.c
index b303bc347f3d..e6fb89138030 100644
--- a/drivers/scsi/pm8001/pm80xx_hwi.c
+++ b/drivers/scsi/pm8001/pm80xx_hwi.c
@@ -1245,43 +1245,41 @@ pm80xx_set_sas_protocol_timer_config(struct pm8001_hba_info *pm8001_ha)
 	circularQ = &pm8001_ha->inbnd_q_tbl[0];
 	payload.tag = cpu_to_le32(tag);
 
-	SASConfigPage.pageCode        =  SAS_PROTOCOL_TIMER_CONFIG_PAGE;
-	SASConfigPage.MST_MSI         =  3 << 15;
-	SASConfigPage.STP_SSP_MCT_TMO =  (STP_MCT_TMO << 16) | SSP_MCT_TMO;
-	SASConfigPage.STP_FRM_TMO     = (SAS_MAX_OPEN_TIME << 24) |
-				(SMP_MAX_CONN_TIMER << 16) | STP_FRM_TIMER;
-	SASConfigPage.STP_IDLE_TMO    =  STP_IDLE_TIME;
-
-	if (SASConfigPage.STP_IDLE_TMO > 0x3FFFFFF)
-		SASConfigPage.STP_IDLE_TMO = 0x3FFFFFF;
-
-
-	SASConfigPage.OPNRJT_RTRY_INTVL =         (SAS_MFD << 16) |
-						SAS_OPNRJT_RTRY_INTVL;
-	SASConfigPage.Data_Cmd_OPNRJT_RTRY_TMO =  (SAS_DOPNRJT_RTRY_TMO << 16)
-						| SAS_COPNRJT_RTRY_TMO;
-	SASConfigPage.Data_Cmd_OPNRJT_RTRY_THR =  (SAS_DOPNRJT_RTRY_THR << 16)
-						| SAS_COPNRJT_RTRY_THR;
-	SASConfigPage.MAX_AIP =  SAS_MAX_AIP;
+	SASConfigPage.pageCode = cpu_to_le32(SAS_PROTOCOL_TIMER_CONFIG_PAGE);
+	SASConfigPage.MST_MSI = cpu_to_le32(3 << 15);
+	SASConfigPage.STP_SSP_MCT_TMO =
+		cpu_to_le32((STP_MCT_TMO << 16) | SSP_MCT_TMO);
+	SASConfigPage.STP_FRM_TMO =
+		cpu_to_le32((SAS_MAX_OPEN_TIME << 24) |
+			    (SMP_MAX_CONN_TIMER << 16) | STP_FRM_TIMER);
+	SASConfigPage.STP_IDLE_TMO = cpu_to_le32(STP_IDLE_TIME);
+
+	SASConfigPage.OPNRJT_RTRY_INTVL =
+		cpu_to_le32((SAS_MFD << 16) | SAS_OPNRJT_RTRY_INTVL);
+	SASConfigPage.Data_Cmd_OPNRJT_RTRY_TMO =
+		cpu_to_le32((SAS_DOPNRJT_RTRY_TMO << 16) | SAS_COPNRJT_RTRY_TMO);
+	SASConfigPage.Data_Cmd_OPNRJT_RTRY_THR =
+		cpu_to_le32((SAS_DOPNRJT_RTRY_THR << 16) | SAS_COPNRJT_RTRY_THR);
+	SASConfigPage.MAX_AIP = cpu_to_le32(SAS_MAX_AIP);
 
 	pm8001_dbg(pm8001_ha, INIT, "SASConfigPage.pageCode 0x%08x\n",
-		   SASConfigPage.pageCode);
+		   le32_to_cpu(SASConfigPage.pageCode));
 	pm8001_dbg(pm8001_ha, INIT, "SASConfigPage.MST_MSI  0x%08x\n",
-		   SASConfigPage.MST_MSI);
+		   le32_to_cpu(SASConfigPage.MST_MSI));
 	pm8001_dbg(pm8001_ha, INIT, "SASConfigPage.STP_SSP_MCT_TMO  0x%08x\n",
-		   SASConfigPage.STP_SSP_MCT_TMO);
+		   le32_to_cpu(SASConfigPage.STP_SSP_MCT_TMO));
 	pm8001_dbg(pm8001_ha, INIT, "SASConfigPage.STP_FRM_TMO  0x%08x\n",
-		   SASConfigPage.STP_FRM_TMO);
+		   le32_to_cpu(SASConfigPage.STP_FRM_TMO));
 	pm8001_dbg(pm8001_ha, INIT, "SASConfigPage.STP_IDLE_TMO  0x%08x\n",
-		   SASConfigPage.STP_IDLE_TMO);
+		   le32_to_cpu(SASConfigPage.STP_IDLE_TMO));
 	pm8001_dbg(pm8001_ha, INIT, "SASConfigPage.OPNRJT_RTRY_INTVL  0x%08x\n",
-		   SASConfigPage.OPNRJT_RTRY_INTVL);
+		   le32_to_cpu(SASConfigPage.OPNRJT_RTRY_INTVL));
 	pm8001_dbg(pm8001_ha, INIT, "SASConfigPage.Data_Cmd_OPNRJT_RTRY_TMO  0x%08x\n",
-		   SASConfigPage.Data_Cmd_OPNRJT_RTRY_TMO);
+		   le32_to_cpu(SASConfigPage.Data_Cmd_OPNRJT_RTRY_TMO));
 	pm8001_dbg(pm8001_ha, INIT, "SASConfigPage.Data_Cmd_OPNRJT_RTRY_THR  0x%08x\n",
-		   SASConfigPage.Data_Cmd_OPNRJT_RTRY_THR);
+		   le32_to_cpu(SASConfigPage.Data_Cmd_OPNRJT_RTRY_THR));
 	pm8001_dbg(pm8001_ha, INIT, "SASConfigPage.MAX_AIP  0x%08x\n",
-		   SASConfigPage.MAX_AIP);
+		   le32_to_cpu(SASConfigPage.MAX_AIP));
 
 	memcpy(&payload.cfg_pg, &SASConfigPage,
 			 sizeof(SASProtocolTimerConfig_t));
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 65+ messages in thread

* [PATCH v4 09/31] scsi: pm8001: Fix payload initialization in pm80xx_encrypt_update()
  2022-02-17 13:29 [PATCH v4 00/31] libsas and pm8001 fixes Damien Le Moal
                   ` (7 preceding siblings ...)
  2022-02-17 13:29 ` [PATCH v4 08/31] scsi: pm8001: Fix le32 values handling in pm80xx_set_sas_protocol_timer_config() Damien Le Moal
@ 2022-02-17 13:29 ` Damien Le Moal
  2022-02-17 19:08   ` Jinpu Wang
  2022-02-17 13:29 ` [PATCH v4 10/31] scsi: pm8001: Fix le32 values handling in pm80xx_chip_ssp_io_req() Damien Le Moal
                   ` (21 subsequent siblings)
  30 siblings, 1 reply; 65+ messages in thread
From: Damien Le Moal @ 2022-02-17 13:29 UTC (permalink / raw)
  To: linux-scsi, Martin K . Petersen, Jack Wang, John Garry
  Cc: Xiang Chen, Jason Yan, Luo Jiaxing

All fields of the kek_mgmt_req structure have the type __le32. So make
sure to use cpu_to_le32() to initialize them. This suppresses the sparse
warning:

warning: incorrect type in assignment (different base types)
   expected restricted __le32 [addressable] [assigned] [usertype] new_curidx_ksop
   got int

Fixes: 5860992db55c ("[SCSI] pm80xx: Added SPCv/ve specific hardware functionalities and relevant changes in common files")
Signed-off-by: Damien Le Moal <damien.lemoal@opensource.wdc.com>
---
 drivers/scsi/pm8001/pm80xx_hwi.c | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/drivers/scsi/pm8001/pm80xx_hwi.c b/drivers/scsi/pm8001/pm80xx_hwi.c
index e6fb89138030..b06d5ded45ca 100644
--- a/drivers/scsi/pm8001/pm80xx_hwi.c
+++ b/drivers/scsi/pm8001/pm80xx_hwi.c
@@ -1405,12 +1405,13 @@ static int pm80xx_encrypt_update(struct pm8001_hba_info *pm8001_ha)
 	/* Currently only one key is used. New KEK index is 1.
 	 * Current KEK index is 1. Store KEK to NVRAM is 1.
 	 */
-	payload.new_curidx_ksop = ((1 << 24) | (1 << 16) | (1 << 8) |
-					KEK_MGMT_SUBOP_KEYCARDUPDATE);
+	payload.new_curidx_ksop =
+		cpu_to_le32(((1 << 24) | (1 << 16) | (1 << 8) |
+			     KEK_MGMT_SUBOP_KEYCARDUPDATE));
 
 	pm8001_dbg(pm8001_ha, DEV,
 		   "Saving Encryption info to flash. payload 0x%x\n",
-		   payload.new_curidx_ksop);
+		   le32_to_cpu(payload.new_curidx_ksop));
 
 	rc = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &payload,
 			sizeof(payload), 0);
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 65+ messages in thread

* [PATCH v4 10/31] scsi: pm8001: Fix le32 values handling in pm80xx_chip_ssp_io_req()
  2022-02-17 13:29 [PATCH v4 00/31] libsas and pm8001 fixes Damien Le Moal
                   ` (8 preceding siblings ...)
  2022-02-17 13:29 ` [PATCH v4 09/31] scsi: pm8001: Fix payload initialization in pm80xx_encrypt_update() Damien Le Moal
@ 2022-02-17 13:29 ` Damien Le Moal
  2022-02-17 19:11   ` Jinpu Wang
  2022-02-17 13:29 ` [PATCH v4 11/31] scsi: pm8001: Fix le32 values handling in pm80xx_chip_sata_req() Damien Le Moal
                   ` (20 subsequent siblings)
  30 siblings, 1 reply; 65+ messages in thread
From: Damien Le Moal @ 2022-02-17 13:29 UTC (permalink / raw)
  To: linux-scsi, Martin K . Petersen, Jack Wang, John Garry
  Cc: Xiang Chen, Jason Yan, Luo Jiaxing

Make sure that the __le32 fields of struct ssp_ini_io_start_req are
manipulated after applying the correct endian conversion. That is, use
cpu_to_le32() for assigning values and le32_to_cpu() for consulting a
field value. In particular, make sure that the calculations for the 4G
boundary check are done using CPU endianness and *not* little endian
values. With these fixes, many sparse warnings are removed.

While at it, add blank lines after variable declarations and in some
other places to make this code more readable.

Fixes: 0ecdf00ba6e5 ("[SCSI] pm80xx: 4G boundary fix.")
Signed-off-by: Damien Le Moal <damien.lemoal@opensource.wdc.com>
---
 drivers/scsi/pm8001/pm80xx_hwi.c | 41 +++++++++++++++++++-------------
 1 file changed, 25 insertions(+), 16 deletions(-)

diff --git a/drivers/scsi/pm8001/pm80xx_hwi.c b/drivers/scsi/pm8001/pm80xx_hwi.c
index b06d5ded45ca..130747b5a70a 100644
--- a/drivers/scsi/pm8001/pm80xx_hwi.c
+++ b/drivers/scsi/pm8001/pm80xx_hwi.c
@@ -4374,13 +4374,15 @@ static int pm80xx_chip_ssp_io_req(struct pm8001_hba_info *pm8001_ha,
 	struct ssp_ini_io_start_req ssp_cmd;
 	u32 tag = ccb->ccb_tag;
 	int ret;
-	u64 phys_addr, start_addr, end_addr;
+	u64 phys_addr, end_addr;
 	u32 end_addr_high, end_addr_low;
 	struct inbound_queue_table *circularQ;
 	u32 q_index, cpu_id;
 	u32 opc = OPC_INB_SSPINIIOSTART;
+
 	memset(&ssp_cmd, 0, sizeof(ssp_cmd));
 	memcpy(ssp_cmd.ssp_iu.lun, task->ssp_task.LUN, 8);
+
 	/* data address domain added for spcv; set to 0 by host,
 	 * used internally by controller
 	 * 0 for SAS 1.1 and SAS 2.0 compatible TLR
@@ -4391,7 +4393,7 @@ static int pm80xx_chip_ssp_io_req(struct pm8001_hba_info *pm8001_ha,
 	ssp_cmd.device_id = cpu_to_le32(pm8001_dev->device_id);
 	ssp_cmd.tag = cpu_to_le32(tag);
 	if (task->ssp_task.enable_first_burst)
-		ssp_cmd.ssp_iu.efb_prio_attr |= 0x80;
+		ssp_cmd.ssp_iu.efb_prio_attr = 0x80;
 	ssp_cmd.ssp_iu.efb_prio_attr |= (task->ssp_task.task_prio << 3);
 	ssp_cmd.ssp_iu.efb_prio_attr |= (task->ssp_task.task_attr & 7);
 	memcpy(ssp_cmd.ssp_iu.cdb, task->ssp_task.cmd->cmnd,
@@ -4423,21 +4425,24 @@ static int pm80xx_chip_ssp_io_req(struct pm8001_hba_info *pm8001_ha,
 			ssp_cmd.enc_esgl = cpu_to_le32(1<<31);
 		} else if (task->num_scatter == 1) {
 			u64 dma_addr = sg_dma_address(task->scatter);
+
 			ssp_cmd.enc_addr_low =
 				cpu_to_le32(lower_32_bits(dma_addr));
 			ssp_cmd.enc_addr_high =
 				cpu_to_le32(upper_32_bits(dma_addr));
 			ssp_cmd.enc_len = cpu_to_le32(task->total_xfer_len);
 			ssp_cmd.enc_esgl = 0;
+
 			/* Check 4G Boundary */
-			start_addr = cpu_to_le64(dma_addr);
-			end_addr = (start_addr + ssp_cmd.enc_len) - 1;
-			end_addr_low = cpu_to_le32(lower_32_bits(end_addr));
-			end_addr_high = cpu_to_le32(upper_32_bits(end_addr));
-			if (end_addr_high != ssp_cmd.enc_addr_high) {
+			end_addr = dma_addr + le32_to_cpu(ssp_cmd.enc_len) - 1;
+			end_addr_low = lower_32_bits(end_addr);
+			end_addr_high = upper_32_bits(end_addr);
+
+			if (end_addr_high != le32_to_cpu(ssp_cmd.enc_addr_high)) {
 				pm8001_dbg(pm8001_ha, FAIL,
 					   "The sg list address start_addr=0x%016llx data_len=0x%x end_addr_high=0x%08x end_addr_low=0x%08x has crossed 4G boundary\n",
-					   start_addr, ssp_cmd.enc_len,
+					   dma_addr,
+					   le32_to_cpu(ssp_cmd.enc_len),
 					   end_addr_high, end_addr_low);
 				pm8001_chip_make_sg(task->scatter, 1,
 					ccb->buf_prd);
@@ -4446,7 +4451,7 @@ static int pm80xx_chip_ssp_io_req(struct pm8001_hba_info *pm8001_ha,
 					cpu_to_le32(lower_32_bits(phys_addr));
 				ssp_cmd.enc_addr_high =
 					cpu_to_le32(upper_32_bits(phys_addr));
-				ssp_cmd.enc_esgl = cpu_to_le32(1<<31);
+				ssp_cmd.enc_esgl = cpu_to_le32(1U<<31);
 			}
 		} else if (task->num_scatter == 0) {
 			ssp_cmd.enc_addr_low = 0;
@@ -4454,8 +4459,10 @@ static int pm80xx_chip_ssp_io_req(struct pm8001_hba_info *pm8001_ha,
 			ssp_cmd.enc_len = cpu_to_le32(task->total_xfer_len);
 			ssp_cmd.enc_esgl = 0;
 		}
+
 		/* XTS mode. All other fields are 0 */
-		ssp_cmd.key_cmode = 0x6 << 4;
+		ssp_cmd.key_cmode = cpu_to_le32(0x6 << 4);
+
 		/* set tweak values. Should be the start lba */
 		ssp_cmd.twk_val0 = cpu_to_le32((task->ssp_task.cmd->cmnd[2] << 24) |
 						(task->ssp_task.cmd->cmnd[3] << 16) |
@@ -4477,20 +4484,22 @@ static int pm80xx_chip_ssp_io_req(struct pm8001_hba_info *pm8001_ha,
 			ssp_cmd.esgl = cpu_to_le32(1<<31);
 		} else if (task->num_scatter == 1) {
 			u64 dma_addr = sg_dma_address(task->scatter);
+
 			ssp_cmd.addr_low = cpu_to_le32(lower_32_bits(dma_addr));
 			ssp_cmd.addr_high =
 				cpu_to_le32(upper_32_bits(dma_addr));
 			ssp_cmd.len = cpu_to_le32(task->total_xfer_len);
 			ssp_cmd.esgl = 0;
+
 			/* Check 4G Boundary */
-			start_addr = cpu_to_le64(dma_addr);
-			end_addr = (start_addr + ssp_cmd.len) - 1;
-			end_addr_low = cpu_to_le32(lower_32_bits(end_addr));
-			end_addr_high = cpu_to_le32(upper_32_bits(end_addr));
-			if (end_addr_high != ssp_cmd.addr_high) {
+			end_addr = dma_addr + le32_to_cpu(ssp_cmd.len) - 1;
+			end_addr_low = lower_32_bits(end_addr);
+			end_addr_high = upper_32_bits(end_addr);
+			if (end_addr_high != le32_to_cpu(ssp_cmd.addr_high)) {
 				pm8001_dbg(pm8001_ha, FAIL,
 					   "The sg list address start_addr=0x%016llx data_len=0x%x end_addr_high=0x%08x end_addr_low=0x%08x has crossed 4G boundary\n",
-					   start_addr, ssp_cmd.len,
+					   dma_addr,
+					   le32_to_cpu(ssp_cmd.len),
 					   end_addr_high, end_addr_low);
 				pm8001_chip_make_sg(task->scatter, 1,
 					ccb->buf_prd);
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 65+ messages in thread

* [PATCH v4 11/31] scsi: pm8001: Fix le32 values handling in pm80xx_chip_sata_req()
  2022-02-17 13:29 [PATCH v4 00/31] libsas and pm8001 fixes Damien Le Moal
                   ` (9 preceding siblings ...)
  2022-02-17 13:29 ` [PATCH v4 10/31] scsi: pm8001: Fix le32 values handling in pm80xx_chip_ssp_io_req() Damien Le Moal
@ 2022-02-17 13:29 ` Damien Le Moal
  2022-02-17 19:13   ` Jinpu Wang
  2022-02-17 13:29 ` [PATCH v4 12/31] scsi: pm8001: Fix use of struct set_phy_profile_req fields Damien Le Moal
                   ` (19 subsequent siblings)
  30 siblings, 1 reply; 65+ messages in thread
From: Damien Le Moal @ 2022-02-17 13:29 UTC (permalink / raw)
  To: linux-scsi, Martin K . Petersen, Jack Wang, John Garry
  Cc: Xiang Chen, Jason Yan, Luo Jiaxing

Make sure that the __le32 fields of struct sata_cmd are manipulated
after applying the correct endian conversion. That is, use cpu_to_le32()
for assigning values and le32_to_cpu() for consulting a field value.
In particular, make sure that the calculations for the 4G boundary check
are done using CPU endianness and *not* little endian values. With these
fixes, many sparse warnings are removed.

While at it, fix some code identation and add blank lines after
variable declarations and in some other places to make this code more
readable.

Fixes: 0ecdf00ba6e5 ("[SCSI] pm80xx: 4G boundary fix.")
Signed-off-by: Damien Le Moal <damien.lemoal@opensource.wdc.com>
---
 drivers/scsi/pm8001/pm80xx_hwi.c | 82 ++++++++++++++++++--------------
 1 file changed, 45 insertions(+), 37 deletions(-)

diff --git a/drivers/scsi/pm8001/pm80xx_hwi.c b/drivers/scsi/pm8001/pm80xx_hwi.c
index 130747b5a70a..1f3b01c70f24 100644
--- a/drivers/scsi/pm8001/pm80xx_hwi.c
+++ b/drivers/scsi/pm8001/pm80xx_hwi.c
@@ -4534,7 +4534,7 @@ static int pm80xx_chip_sata_req(struct pm8001_hba_info *pm8001_ha,
 	u32 q_index, cpu_id;
 	struct sata_start_req sata_cmd;
 	u32 hdr_tag, ncg_tag = 0;
-	u64 phys_addr, start_addr, end_addr;
+	u64 phys_addr, end_addr;
 	u32 end_addr_high, end_addr_low;
 	u32 ATAP = 0x0;
 	u32 dir;
@@ -4595,32 +4595,38 @@ static int pm80xx_chip_sata_req(struct pm8001_hba_info *pm8001_ha,
 			pm8001_chip_make_sg(task->scatter,
 						ccb->n_elem, ccb->buf_prd);
 			phys_addr = ccb->ccb_dma_handle;
-			sata_cmd.enc_addr_low = lower_32_bits(phys_addr);
-			sata_cmd.enc_addr_high = upper_32_bits(phys_addr);
+			sata_cmd.enc_addr_low =
+				cpu_to_le32(lower_32_bits(phys_addr));
+			sata_cmd.enc_addr_high =
+				cpu_to_le32(upper_32_bits(phys_addr));
 			sata_cmd.enc_esgl = cpu_to_le32(1 << 31);
 		} else if (task->num_scatter == 1) {
 			u64 dma_addr = sg_dma_address(task->scatter);
-			sata_cmd.enc_addr_low = lower_32_bits(dma_addr);
-			sata_cmd.enc_addr_high = upper_32_bits(dma_addr);
+
+			sata_cmd.enc_addr_low =
+				cpu_to_le32(lower_32_bits(dma_addr));
+			sata_cmd.enc_addr_high =
+				cpu_to_le32(upper_32_bits(dma_addr));
 			sata_cmd.enc_len = cpu_to_le32(task->total_xfer_len);
 			sata_cmd.enc_esgl = 0;
+
 			/* Check 4G Boundary */
-			start_addr = cpu_to_le64(dma_addr);
-			end_addr = (start_addr + sata_cmd.enc_len) - 1;
-			end_addr_low = cpu_to_le32(lower_32_bits(end_addr));
-			end_addr_high = cpu_to_le32(upper_32_bits(end_addr));
-			if (end_addr_high != sata_cmd.enc_addr_high) {
+			end_addr = dma_addr + le32_to_cpu(sata_cmd.enc_len) - 1;
+			end_addr_low = lower_32_bits(end_addr);
+			end_addr_high = upper_32_bits(end_addr);
+			if (end_addr_high != le32_to_cpu(sata_cmd.enc_addr_high)) {
 				pm8001_dbg(pm8001_ha, FAIL,
 					   "The sg list address start_addr=0x%016llx data_len=0x%x end_addr_high=0x%08x end_addr_low=0x%08x has crossed 4G boundary\n",
-					   start_addr, sata_cmd.enc_len,
+					   dma_addr,
+					   le32_to_cpu(sata_cmd.enc_len),
 					   end_addr_high, end_addr_low);
 				pm8001_chip_make_sg(task->scatter, 1,
 					ccb->buf_prd);
 				phys_addr = ccb->ccb_dma_handle;
 				sata_cmd.enc_addr_low =
-					lower_32_bits(phys_addr);
+					cpu_to_le32(lower_32_bits(phys_addr));
 				sata_cmd.enc_addr_high =
-					upper_32_bits(phys_addr);
+					cpu_to_le32(upper_32_bits(phys_addr));
 				sata_cmd.enc_esgl =
 					cpu_to_le32(1 << 31);
 			}
@@ -4631,7 +4637,8 @@ static int pm80xx_chip_sata_req(struct pm8001_hba_info *pm8001_ha,
 			sata_cmd.enc_esgl = 0;
 		}
 		/* XTS mode. All other fields are 0 */
-		sata_cmd.key_index_mode = 0x6 << 4;
+		sata_cmd.key_index_mode = cpu_to_le32(0x6 << 4);
+
 		/* set tweak values. Should be the start lba */
 		sata_cmd.twk_val0 =
 			cpu_to_le32((sata_cmd.sata_fis.lbal_exp << 24) |
@@ -4657,31 +4664,31 @@ static int pm80xx_chip_sata_req(struct pm8001_hba_info *pm8001_ha,
 			phys_addr = ccb->ccb_dma_handle;
 			sata_cmd.addr_low = lower_32_bits(phys_addr);
 			sata_cmd.addr_high = upper_32_bits(phys_addr);
-			sata_cmd.esgl = cpu_to_le32(1 << 31);
+			sata_cmd.esgl = cpu_to_le32(1U << 31);
 		} else if (task->num_scatter == 1) {
 			u64 dma_addr = sg_dma_address(task->scatter);
+
 			sata_cmd.addr_low = lower_32_bits(dma_addr);
 			sata_cmd.addr_high = upper_32_bits(dma_addr);
 			sata_cmd.len = cpu_to_le32(task->total_xfer_len);
 			sata_cmd.esgl = 0;
+
 			/* Check 4G Boundary */
-			start_addr = cpu_to_le64(dma_addr);
-			end_addr = (start_addr + sata_cmd.len) - 1;
-			end_addr_low = cpu_to_le32(lower_32_bits(end_addr));
-			end_addr_high = cpu_to_le32(upper_32_bits(end_addr));
+			end_addr = dma_addr + le32_to_cpu(sata_cmd.len) - 1;
+			end_addr_low = lower_32_bits(end_addr);
+			end_addr_high = upper_32_bits(end_addr);
 			if (end_addr_high != sata_cmd.addr_high) {
 				pm8001_dbg(pm8001_ha, FAIL,
 					   "The sg list address start_addr=0x%016llx data_len=0x%xend_addr_high=0x%08x end_addr_low=0x%08x has crossed 4G boundary\n",
-					   start_addr, sata_cmd.len,
+					   dma_addr,
+					   le32_to_cpu(sata_cmd.len),
 					   end_addr_high, end_addr_low);
 				pm8001_chip_make_sg(task->scatter, 1,
 					ccb->buf_prd);
 				phys_addr = ccb->ccb_dma_handle;
-				sata_cmd.addr_low =
-					lower_32_bits(phys_addr);
-				sata_cmd.addr_high =
-					upper_32_bits(phys_addr);
-				sata_cmd.esgl = cpu_to_le32(1 << 31);
+				sata_cmd.addr_low = lower_32_bits(phys_addr);
+				sata_cmd.addr_high = upper_32_bits(phys_addr);
+				sata_cmd.esgl = cpu_to_le32(1U << 31);
 			}
 		} else if (task->num_scatter == 0) {
 			sata_cmd.addr_low = 0;
@@ -4689,27 +4696,28 @@ static int pm80xx_chip_sata_req(struct pm8001_hba_info *pm8001_ha,
 			sata_cmd.len = cpu_to_le32(task->total_xfer_len);
 			sata_cmd.esgl = 0;
 		}
+
 		/* scsi cdb */
 		sata_cmd.atapi_scsi_cdb[0] =
 			cpu_to_le32(((task->ata_task.atapi_packet[0]) |
-			(task->ata_task.atapi_packet[1] << 8) |
-			(task->ata_task.atapi_packet[2] << 16) |
-			(task->ata_task.atapi_packet[3] << 24)));
+				     (task->ata_task.atapi_packet[1] << 8) |
+				     (task->ata_task.atapi_packet[2] << 16) |
+				     (task->ata_task.atapi_packet[3] << 24)));
 		sata_cmd.atapi_scsi_cdb[1] =
 			cpu_to_le32(((task->ata_task.atapi_packet[4]) |
-			(task->ata_task.atapi_packet[5] << 8) |
-			(task->ata_task.atapi_packet[6] << 16) |
-			(task->ata_task.atapi_packet[7] << 24)));
+				     (task->ata_task.atapi_packet[5] << 8) |
+				     (task->ata_task.atapi_packet[6] << 16) |
+				     (task->ata_task.atapi_packet[7] << 24)));
 		sata_cmd.atapi_scsi_cdb[2] =
 			cpu_to_le32(((task->ata_task.atapi_packet[8]) |
-			(task->ata_task.atapi_packet[9] << 8) |
-			(task->ata_task.atapi_packet[10] << 16) |
-			(task->ata_task.atapi_packet[11] << 24)));
+				     (task->ata_task.atapi_packet[9] << 8) |
+				     (task->ata_task.atapi_packet[10] << 16) |
+				     (task->ata_task.atapi_packet[11] << 24)));
 		sata_cmd.atapi_scsi_cdb[3] =
 			cpu_to_le32(((task->ata_task.atapi_packet[12]) |
-			(task->ata_task.atapi_packet[13] << 8) |
-			(task->ata_task.atapi_packet[14] << 16) |
-			(task->ata_task.atapi_packet[15] << 24)));
+				     (task->ata_task.atapi_packet[13] << 8) |
+				     (task->ata_task.atapi_packet[14] << 16) |
+				     (task->ata_task.atapi_packet[15] << 24)));
 	}
 
 	/* Check for read log for failed drive and return */
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 65+ messages in thread

* [PATCH v4 12/31] scsi: pm8001: Fix use of struct set_phy_profile_req fields
  2022-02-17 13:29 [PATCH v4 00/31] libsas and pm8001 fixes Damien Le Moal
                   ` (10 preceding siblings ...)
  2022-02-17 13:29 ` [PATCH v4 11/31] scsi: pm8001: Fix le32 values handling in pm80xx_chip_sata_req() Damien Le Moal
@ 2022-02-17 13:29 ` Damien Le Moal
  2022-02-17 19:14   ` Jinpu Wang
  2022-02-17 13:29 ` [PATCH v4 13/31] scsi: pm8001: Remove local variable in pm8001_pci_resume() Damien Le Moal
                   ` (18 subsequent siblings)
  30 siblings, 1 reply; 65+ messages in thread
From: Damien Le Moal @ 2022-02-17 13:29 UTC (permalink / raw)
  To: linux-scsi, Martin K . Petersen, Jack Wang, John Garry
  Cc: Xiang Chen, Jason Yan, Luo Jiaxing

In mpi_set_phy_profile_req() and pm8001_set_phy_profile_single(), use
cpu_to_le32() to initialize the ppc_phyid field of struct
set_phy_profile_req. Furthermore, fix the definition of the reserved
field of this structure to be an array of __le32, to match the use of
cpu_to_le32() when assigning values. These changes remove several sparse
type warnings.

Signed-off-by: Damien Le Moal <damien.lemoal@opensource.wdc.com>
---
 drivers/scsi/pm8001/pm80xx_hwi.c | 12 +++++++-----
 drivers/scsi/pm8001/pm80xx_hwi.h |  2 +-
 2 files changed, 8 insertions(+), 6 deletions(-)

diff --git a/drivers/scsi/pm8001/pm80xx_hwi.c b/drivers/scsi/pm8001/pm80xx_hwi.c
index 1f3b01c70f24..60c305f987b5 100644
--- a/drivers/scsi/pm8001/pm80xx_hwi.c
+++ b/drivers/scsi/pm8001/pm80xx_hwi.c
@@ -4970,12 +4970,13 @@ static void mpi_set_phy_profile_req(struct pm8001_hba_info *pm8001_ha,
 		pm8001_dbg(pm8001_ha, FAIL, "Invalid tag\n");
 	circularQ = &pm8001_ha->inbnd_q_tbl[0];
 	payload.tag = cpu_to_le32(tag);
-	payload.ppc_phyid = (((operation & 0xF) << 8) | (phyid  & 0xFF));
+	payload.ppc_phyid =
+		cpu_to_le32(((operation & 0xF) << 8) | (phyid  & 0xFF));
 	pm8001_dbg(pm8001_ha, INIT,
 		   " phy profile command for phy %x ,length is %d\n",
-		   payload.ppc_phyid, length);
+		   le32_to_cpu(payload.ppc_phyid), length);
 	for (i = length; i < (length + PHY_DWORD_LENGTH - 1); i++) {
-		payload.reserved[j] =  cpu_to_le32(*((u32 *)buf + i));
+		payload.reserved[j] = cpu_to_le32(*((u32 *)buf + i));
 		j++;
 	}
 	rc = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &payload,
@@ -5015,8 +5016,9 @@ void pm8001_set_phy_profile_single(struct pm8001_hba_info *pm8001_ha,
 	opc = OPC_INB_SET_PHY_PROFILE;
 
 	payload.tag = cpu_to_le32(tag);
-	payload.ppc_phyid = (((SAS_PHY_ANALOG_SETTINGS_PAGE & 0xF) << 8)
-				| (phy & 0xFF));
+	payload.ppc_phyid =
+		cpu_to_le32(((SAS_PHY_ANALOG_SETTINGS_PAGE & 0xF) << 8)
+			    | (phy & 0xFF));
 
 	for (i = 0; i < length; i++)
 		payload.reserved[i] = cpu_to_le32(*(buf + i));
diff --git a/drivers/scsi/pm8001/pm80xx_hwi.h b/drivers/scsi/pm8001/pm80xx_hwi.h
index c41ed039c92a..d66b49323d49 100644
--- a/drivers/scsi/pm8001/pm80xx_hwi.h
+++ b/drivers/scsi/pm8001/pm80xx_hwi.h
@@ -972,7 +972,7 @@ struct dek_mgmt_req {
 struct set_phy_profile_req {
 	__le32	tag;
 	__le32	ppc_phyid;
-	u32	reserved[29];
+	__le32	reserved[29];
 } __attribute__((packed, aligned(4)));
 
 /**
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 65+ messages in thread

* [PATCH v4 13/31] scsi: pm8001: Remove local variable in pm8001_pci_resume()
  2022-02-17 13:29 [PATCH v4 00/31] libsas and pm8001 fixes Damien Le Moal
                   ` (11 preceding siblings ...)
  2022-02-17 13:29 ` [PATCH v4 12/31] scsi: pm8001: Fix use of struct set_phy_profile_req fields Damien Le Moal
@ 2022-02-17 13:29 ` Damien Le Moal
  2022-02-17 19:15   ` Jinpu Wang
  2022-02-17 13:29 ` [PATCH v4 14/31] scsi: pm8001: Fix NCQ NON DATA command task initialization Damien Le Moal
                   ` (17 subsequent siblings)
  30 siblings, 1 reply; 65+ messages in thread
From: Damien Le Moal @ 2022-02-17 13:29 UTC (permalink / raw)
  To: linux-scsi, Martin K . Petersen, Jack Wang, John Garry
  Cc: Xiang Chen, Jason Yan, Luo Jiaxing

In pm8001_pci_resume(), the use of the u32 type for the local variable
device_state causes a sparse warning:

warning: incorrect type in assignment (different base types)
    expected unsigned int [usertype] device_state
    got restricted pci_power_t [usertype] current_state

Since this variable is used only once in the function, remove it and
use pdev->current_state directly. While at it, also add a blank line
after the last local variable declaration.

Reviewed-by: John Garry <john.garry@huawei.com>
Signed-off-by: Damien Le Moal <damien.lemoal@opensource.wdc.com>
---
 drivers/scsi/pm8001/pm8001_init.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/scsi/pm8001/pm8001_init.c b/drivers/scsi/pm8001/pm8001_init.c
index d8a2121cb8d9..4b9a26f008a9 100644
--- a/drivers/scsi/pm8001/pm8001_init.c
+++ b/drivers/scsi/pm8001/pm8001_init.c
@@ -1335,13 +1335,13 @@ static int __maybe_unused pm8001_pci_resume(struct device *dev)
 	struct pm8001_hba_info *pm8001_ha;
 	int rc;
 	u8 i = 0, j;
-	u32 device_state;
 	DECLARE_COMPLETION_ONSTACK(completion);
+
 	pm8001_ha = sha->lldd_ha;
-	device_state = pdev->current_state;
 
-	pm8001_info(pm8001_ha, "pdev=0x%p, slot=%s, resuming from previous operating state [D%d]\n",
-		      pdev, pm8001_ha->name, device_state);
+	pm8001_info(pm8001_ha,
+		    "pdev=0x%p, slot=%s, resuming from previous operating state [D%d]\n",
+		    pdev, pm8001_ha->name, pdev->current_state);
 
 	rc = pci_go_44(pdev);
 	if (rc)
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 65+ messages in thread

* [PATCH v4 14/31] scsi: pm8001: Fix NCQ NON DATA command task initialization
  2022-02-17 13:29 [PATCH v4 00/31] libsas and pm8001 fixes Damien Le Moal
                   ` (12 preceding siblings ...)
  2022-02-17 13:29 ` [PATCH v4 13/31] scsi: pm8001: Remove local variable in pm8001_pci_resume() Damien Le Moal
@ 2022-02-17 13:29 ` Damien Le Moal
  2022-02-17 19:25   ` Jinpu Wang
  2022-02-17 13:29 ` [PATCH v4 15/31] scsi: pm8001: Fix NCQ NON DATA command completion handling Damien Le Moal
                   ` (16 subsequent siblings)
  30 siblings, 1 reply; 65+ messages in thread
From: Damien Le Moal @ 2022-02-17 13:29 UTC (permalink / raw)
  To: linux-scsi, Martin K . Petersen, Jack Wang, John Garry
  Cc: Xiang Chen, Jason Yan, Luo Jiaxing

In the pm8001_chip_sata_req() and pm80xx_chip_sata_req() functions, all
tasks with a DMA direction of DMA_NONE (no data transfer) are
initialized using the ATAP value 0x04. However, NCQ NON DATA commands,
while being DMA_NONE commands are NCQ commands and need to be
initialized using the value 0x07 for ATAP, similarly to other NCQ
commands.

Make sure that NCQ NON DATA command tasks are initialized similarly to
other NCQ commands by also testing the task "use_ncq" field in addition
to the DMA direction. While at it, reorganize the code into a chain of
if - else if - else to avoid useless affectations and debug messages.

Fixes: dbf9bfe61571 ("[SCSI] pm8001: add SAS/SATA HBA driver")
Signed-off-by: Damien Le Moal <damien.lemoal@opensource.wdc.com>
---
 drivers/scsi/pm8001/pm8001_hwi.c | 14 +++++++-------
 drivers/scsi/pm8001/pm80xx_hwi.c | 13 ++++++-------
 2 files changed, 13 insertions(+), 14 deletions(-)

diff --git a/drivers/scsi/pm8001/pm8001_hwi.c b/drivers/scsi/pm8001/pm8001_hwi.c
index e20a1d4db026..c0215a35a7b5 100644
--- a/drivers/scsi/pm8001/pm8001_hwi.c
+++ b/drivers/scsi/pm8001/pm8001_hwi.c
@@ -4265,22 +4265,22 @@ static int pm8001_chip_sata_req(struct pm8001_hba_info *pm8001_ha,
 	u32  opc = OPC_INB_SATA_HOST_OPSTART;
 	memset(&sata_cmd, 0, sizeof(sata_cmd));
 	circularQ = &pm8001_ha->inbnd_q_tbl[0];
-	if (task->data_dir == DMA_NONE) {
+
+	if (task->data_dir == DMA_NONE && !task->ata_task.use_ncq) {
 		ATAP = 0x04;  /* no data*/
 		pm8001_dbg(pm8001_ha, IO, "no data\n");
 	} else if (likely(!task->ata_task.device_control_reg_update)) {
-		if (task->ata_task.dma_xfer) {
+		if (task->ata_task.use_ncq &&
+		    dev->sata_dev.class != ATA_DEV_ATAPI) {
+			ATAP = 0x07; /* FPDMA */
+			pm8001_dbg(pm8001_ha, IO, "FPDMA\n");
+		} else if (task->ata_task.dma_xfer) {
 			ATAP = 0x06; /* DMA */
 			pm8001_dbg(pm8001_ha, IO, "DMA\n");
 		} else {
 			ATAP = 0x05; /* PIO*/
 			pm8001_dbg(pm8001_ha, IO, "PIO\n");
 		}
-		if (task->ata_task.use_ncq &&
-			dev->sata_dev.class != ATA_DEV_ATAPI) {
-			ATAP = 0x07; /* FPDMA */
-			pm8001_dbg(pm8001_ha, IO, "FPDMA\n");
-		}
 	}
 	if (task->ata_task.use_ncq && pm8001_get_ncq_tag(task, &hdr_tag)) {
 		task->ata_task.fis.sector_count |= (u8) (hdr_tag << 3);
diff --git a/drivers/scsi/pm8001/pm80xx_hwi.c b/drivers/scsi/pm8001/pm80xx_hwi.c
index 60c305f987b5..3deb89b11d2f 100644
--- a/drivers/scsi/pm8001/pm80xx_hwi.c
+++ b/drivers/scsi/pm8001/pm80xx_hwi.c
@@ -4546,22 +4546,21 @@ static int pm80xx_chip_sata_req(struct pm8001_hba_info *pm8001_ha,
 	q_index = (u32) (cpu_id) % (pm8001_ha->max_q_num);
 	circularQ = &pm8001_ha->inbnd_q_tbl[q_index];
 
-	if (task->data_dir == DMA_NONE) {
+	if (task->data_dir == DMA_NONE && !task->ata_task.use_ncq) {
 		ATAP = 0x04; /* no data*/
 		pm8001_dbg(pm8001_ha, IO, "no data\n");
 	} else if (likely(!task->ata_task.device_control_reg_update)) {
-		if (task->ata_task.dma_xfer) {
+		if (task->ata_task.use_ncq &&
+		    dev->sata_dev.class != ATA_DEV_ATAPI) {
+			ATAP = 0x07; /* FPDMA */
+			pm8001_dbg(pm8001_ha, IO, "FPDMA\n");
+		} else if (task->ata_task.dma_xfer) {
 			ATAP = 0x06; /* DMA */
 			pm8001_dbg(pm8001_ha, IO, "DMA\n");
 		} else {
 			ATAP = 0x05; /* PIO*/
 			pm8001_dbg(pm8001_ha, IO, "PIO\n");
 		}
-		if (task->ata_task.use_ncq &&
-		    dev->sata_dev.class != ATA_DEV_ATAPI) {
-			ATAP = 0x07; /* FPDMA */
-			pm8001_dbg(pm8001_ha, IO, "FPDMA\n");
-		}
 	}
 	if (task->ata_task.use_ncq && pm8001_get_ncq_tag(task, &hdr_tag)) {
 		task->ata_task.fis.sector_count |= (u8) (hdr_tag << 3);
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 65+ messages in thread

* [PATCH v4 15/31] scsi: pm8001: Fix NCQ NON DATA command completion handling
  2022-02-17 13:29 [PATCH v4 00/31] libsas and pm8001 fixes Damien Le Moal
                   ` (13 preceding siblings ...)
  2022-02-17 13:29 ` [PATCH v4 14/31] scsi: pm8001: Fix NCQ NON DATA command task initialization Damien Le Moal
@ 2022-02-17 13:29 ` Damien Le Moal
  2022-02-17 19:28   ` Jinpu Wang
  2022-02-17 13:29 ` [PATCH v4 16/31] scsi: pm8001: Fix abort all task initialization Damien Le Moal
                   ` (15 subsequent siblings)
  30 siblings, 1 reply; 65+ messages in thread
From: Damien Le Moal @ 2022-02-17 13:29 UTC (permalink / raw)
  To: linux-scsi, Martin K . Petersen, Jack Wang, John Garry
  Cc: Xiang Chen, Jason Yan, Luo Jiaxing

NCQ NON DATA is an NCQ command with the DMA_NONE DMA direction and so a
register-device-to-host-FIS response is expected for it.

However, for an IO_SUCCESS case, mpi_sata_completion() expects a
set-device-bits-FIS for any ata task with an use_ncq field true, which
includes NCQ NON DATA commands.

Fix this to correctly treat NCQ NON DATA commands as non-data by also
testing for the DMA_NONE DMA direction.

Fixes: dbf9bfe61571 ("[SCSI] pm8001: add SAS/SATA HBA driver")
Signed-off-by: Damien Le Moal <damien.lemoal@opensource.wdc.com>
---
 drivers/scsi/pm8001/pm8001_hwi.c | 3 ++-
 drivers/scsi/pm8001/pm80xx_hwi.c | 3 ++-
 2 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/scsi/pm8001/pm8001_hwi.c b/drivers/scsi/pm8001/pm8001_hwi.c
index c0215a35a7b5..8149cc0d1ecd 100644
--- a/drivers/scsi/pm8001/pm8001_hwi.c
+++ b/drivers/scsi/pm8001/pm8001_hwi.c
@@ -2415,7 +2415,8 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb)
 				len = sizeof(struct pio_setup_fis);
 				pm8001_dbg(pm8001_ha, IO,
 					   "PIO read len = %d\n", len);
-			} else if (t->ata_task.use_ncq) {
+			} else if (t->ata_task.use_ncq &&
+				   t->data_dir != DMA_NONE) {
 				len = sizeof(struct set_dev_bits_fis);
 				pm8001_dbg(pm8001_ha, IO, "FPDMA len = %d\n",
 					   len);
diff --git a/drivers/scsi/pm8001/pm80xx_hwi.c b/drivers/scsi/pm8001/pm80xx_hwi.c
index 3deb89b11d2f..ac2178a13e4c 100644
--- a/drivers/scsi/pm8001/pm80xx_hwi.c
+++ b/drivers/scsi/pm8001/pm80xx_hwi.c
@@ -2507,7 +2507,8 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha,
 				len = sizeof(struct pio_setup_fis);
 				pm8001_dbg(pm8001_ha, IO,
 					   "PIO read len = %d\n", len);
-			} else if (t->ata_task.use_ncq) {
+			} else if (t->ata_task.use_ncq &&
+				   t->data_dir != DMA_NONE) {
 				len = sizeof(struct set_dev_bits_fis);
 				pm8001_dbg(pm8001_ha, IO, "FPDMA len = %d\n",
 					   len);
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 65+ messages in thread

* [PATCH v4 16/31] scsi: pm8001: Fix abort all task initialization
  2022-02-17 13:29 [PATCH v4 00/31] libsas and pm8001 fixes Damien Le Moal
                   ` (14 preceding siblings ...)
  2022-02-17 13:29 ` [PATCH v4 15/31] scsi: pm8001: Fix NCQ NON DATA command completion handling Damien Le Moal
@ 2022-02-17 13:29 ` Damien Le Moal
  2022-02-17 19:30   ` Jinpu Wang
  2022-02-17 13:29 ` [PATCH v4 17/31] scsi: pm8001: Fix pm8001_tag_alloc() failures handling Damien Le Moal
                   ` (14 subsequent siblings)
  30 siblings, 1 reply; 65+ messages in thread
From: Damien Le Moal @ 2022-02-17 13:29 UTC (permalink / raw)
  To: linux-scsi, Martin K . Petersen, Jack Wang, John Garry
  Cc: Xiang Chen, Jason Yan, Luo Jiaxing

In pm80xx_send_abort_all(), the n_elem field of the ccb used is not
initialized to 0. This missing initialization sometimes lead to the
task completion path seeing the ccb with a non-zero n_elem resulting in
the execution of invalid dma_unmap_sg() calls in pm8001_ccb_task_free(),
causing a crash such as:

[  197.676341] RIP: 0010:iommu_dma_unmap_sg+0x6d/0x280
[  197.700204] RSP: 0018:ffff889bbcf89c88 EFLAGS: 00010012
[  197.705485] RAX: dffffc0000000000 RBX: 0000000000000000 RCX: ffffffff83d0bda0
[  197.712687] RDX: 0000000000000002 RSI: 0000000000000000 RDI: ffff88810dffc0d0
[  197.719887] RBP: 0000000000000000 R08: 0000000000000000 R09: ffff8881c790098b
[  197.727089] R10: ffffed1038f20131 R11: 0000000000000001 R12: 0000000000000000
[  197.734296] R13: ffff88810dffc0d0 R14: 0000000000000010 R15: 0000000000000000
[  197.741493] FS:  0000000000000000(0000) GS:ffff889bbcf80000(0000) knlGS:0000000000000000
[  197.749659] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[  197.755459] CR2: 00007f16c1b42734 CR3: 0000000004814000 CR4: 0000000000350ee0
[  197.762656] Call Trace:
[  197.765127]  <IRQ>
[  197.767162]  pm8001_ccb_task_free+0x5f1/0x820 [pm80xx]
[  197.772364]  ? do_raw_spin_unlock+0x54/0x220
[  197.776680]  pm8001_mpi_task_abort_resp+0x2ce/0x4f0 [pm80xx]
[  197.782406]  process_oq+0xe85/0x7890 [pm80xx]
[  197.786817]  ? lock_acquire+0x194/0x490
[  197.790697]  ? handle_irq_event+0x10e/0x1b0
[  197.794920]  ? mpi_sata_completion+0x2d70/0x2d70 [pm80xx]
[  197.800378]  ? __wake_up_bit+0x100/0x100
[  197.804340]  ? lock_is_held_type+0x98/0x110
[  197.808565]  pm80xx_chip_isr+0x94/0x130 [pm80xx]
[  197.813243]  tasklet_action_common.constprop.0+0x24b/0x2f0
[  197.818785]  __do_softirq+0x1b5/0x82d
[  197.822485]  ? do_raw_spin_unlock+0x54/0x220
[  197.826799]  __irq_exit_rcu+0x17e/0x1e0
[  197.830678]  irq_exit_rcu+0xa/0x20
[  197.834114]  common_interrupt+0x78/0x90
[  197.840051]  </IRQ>
[  197.844236]  <TASK>
[  197.848397]  asm_common_interrupt+0x1e/0x40

Avoid this issue by always initializing the ccb n_elem field to 0 in
pm8001_send_abort_all(), pm8001_send_read_log() and
pm80xx_send_abort_all().

Fixes: c6b9ef5779c3 ("[SCSI] pm80xx: NCQ error handling changes")
Signed-off-by: Damien Le Moal <damien.lemoal@opensource.wdc.com>
---
 drivers/scsi/pm8001/pm8001_hwi.c | 2 ++
 drivers/scsi/pm8001/pm80xx_hwi.c | 1 +
 2 files changed, 3 insertions(+)

diff --git a/drivers/scsi/pm8001/pm8001_hwi.c b/drivers/scsi/pm8001/pm8001_hwi.c
index 8149cc0d1ecd..35d62e5c9200 100644
--- a/drivers/scsi/pm8001/pm8001_hwi.c
+++ b/drivers/scsi/pm8001/pm8001_hwi.c
@@ -1787,6 +1787,7 @@ static void pm8001_send_abort_all(struct pm8001_hba_info *pm8001_ha,
 	ccb->device = pm8001_ha_dev;
 	ccb->ccb_tag = ccb_tag;
 	ccb->task = task;
+	ccb->n_elem = 0;
 
 	circularQ = &pm8001_ha->inbnd_q_tbl[0];
 
@@ -1848,6 +1849,7 @@ static void pm8001_send_read_log(struct pm8001_hba_info *pm8001_ha,
 	ccb->device = pm8001_ha_dev;
 	ccb->ccb_tag = ccb_tag;
 	ccb->task = task;
+	ccb->n_elem = 0;
 	pm8001_ha_dev->id |= NCQ_READ_LOG_FLAG;
 	pm8001_ha_dev->id |= NCQ_2ND_RLE_FLAG;
 
diff --git a/drivers/scsi/pm8001/pm80xx_hwi.c b/drivers/scsi/pm8001/pm80xx_hwi.c
index ac2178a13e4c..8fd38e54f07c 100644
--- a/drivers/scsi/pm8001/pm80xx_hwi.c
+++ b/drivers/scsi/pm8001/pm80xx_hwi.c
@@ -1800,6 +1800,7 @@ static void pm80xx_send_abort_all(struct pm8001_hba_info *pm8001_ha,
 	ccb->device = pm8001_ha_dev;
 	ccb->ccb_tag = ccb_tag;
 	ccb->task = task;
+	ccb->n_elem = 0;
 
 	circularQ = &pm8001_ha->inbnd_q_tbl[0];
 
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 65+ messages in thread

* [PATCH v4 17/31] scsi: pm8001: Fix pm8001_tag_alloc() failures handling
  2022-02-17 13:29 [PATCH v4 00/31] libsas and pm8001 fixes Damien Le Moal
                   ` (15 preceding siblings ...)
  2022-02-17 13:29 ` [PATCH v4 16/31] scsi: pm8001: Fix abort all task initialization Damien Le Moal
@ 2022-02-17 13:29 ` Damien Le Moal
  2022-02-17 19:31   ` Jinpu Wang
  2022-02-17 13:29 ` [PATCH v4 18/31] scsi: pm8001: Fix pm80xx_chip_phy_ctl_req() Damien Le Moal
                   ` (13 subsequent siblings)
  30 siblings, 1 reply; 65+ messages in thread
From: Damien Le Moal @ 2022-02-17 13:29 UTC (permalink / raw)
  To: linux-scsi, Martin K . Petersen, Jack Wang, John Garry
  Cc: Xiang Chen, Jason Yan, Luo Jiaxing

In mpi_set_phy_profile_req() and in pm8001_set_phy_profile_single(), if
pm8001_tag_alloc() fails to allocate a new tag, a warning message is
issued but the uninitialized tag variable is still used to build a
command. Avoid this by returning early in case of tag allocation
failure.

Also make sure to always return the error code returned by
pm8001_tag_alloc() when this function fails instead of an arbitrary
value.

Signed-off-by: Damien Le Moal <damien.lemoal@opensource.wdc.com>
Reviewed-by: John Garry <john.garry@huawei.com>
---
 drivers/scsi/pm8001/pm80xx_hwi.c | 15 ++++++++++-----
 1 file changed, 10 insertions(+), 5 deletions(-)

diff --git a/drivers/scsi/pm8001/pm80xx_hwi.c b/drivers/scsi/pm8001/pm80xx_hwi.c
index 8fd38e54f07c..76260d06b6be 100644
--- a/drivers/scsi/pm8001/pm80xx_hwi.c
+++ b/drivers/scsi/pm8001/pm80xx_hwi.c
@@ -1191,7 +1191,7 @@ pm80xx_set_thermal_config(struct pm8001_hba_info *pm8001_ha)
 	memset(&payload, 0, sizeof(struct set_ctrl_cfg_req));
 	rc = pm8001_tag_alloc(pm8001_ha, &tag);
 	if (rc)
-		return -1;
+		return rc;
 
 	circularQ = &pm8001_ha->inbnd_q_tbl[0];
 	payload.tag = cpu_to_le32(tag);
@@ -1240,7 +1240,7 @@ pm80xx_set_sas_protocol_timer_config(struct pm8001_hba_info *pm8001_ha)
 	rc = pm8001_tag_alloc(pm8001_ha, &tag);
 
 	if (rc)
-		return -1;
+		return rc;
 
 	circularQ = &pm8001_ha->inbnd_q_tbl[0];
 	payload.tag = cpu_to_le32(tag);
@@ -1398,7 +1398,7 @@ static int pm80xx_encrypt_update(struct pm8001_hba_info *pm8001_ha)
 	memset(&payload, 0, sizeof(struct kek_mgmt_req));
 	rc = pm8001_tag_alloc(pm8001_ha, &tag);
 	if (rc)
-		return -1;
+		return rc;
 
 	circularQ = &pm8001_ha->inbnd_q_tbl[0];
 	payload.tag = cpu_to_le32(tag);
@@ -4967,8 +4967,11 @@ static void mpi_set_phy_profile_req(struct pm8001_hba_info *pm8001_ha,
 
 	memset(&payload, 0, sizeof(payload));
 	rc = pm8001_tag_alloc(pm8001_ha, &tag);
-	if (rc)
+	if (rc) {
 		pm8001_dbg(pm8001_ha, FAIL, "Invalid tag\n");
+		return;
+	}
+
 	circularQ = &pm8001_ha->inbnd_q_tbl[0];
 	payload.tag = cpu_to_le32(tag);
 	payload.ppc_phyid =
@@ -5010,8 +5013,10 @@ void pm8001_set_phy_profile_single(struct pm8001_hba_info *pm8001_ha,
 	memset(&payload, 0, sizeof(payload));
 
 	rc = pm8001_tag_alloc(pm8001_ha, &tag);
-	if (rc)
+	if (rc) {
 		pm8001_dbg(pm8001_ha, INIT, "Invalid tag\n");
+		return;
+	}
 
 	circularQ = &pm8001_ha->inbnd_q_tbl[0];
 	opc = OPC_INB_SET_PHY_PROFILE;
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 65+ messages in thread

* [PATCH v4 18/31] scsi: pm8001: Fix pm80xx_chip_phy_ctl_req()
  2022-02-17 13:29 [PATCH v4 00/31] libsas and pm8001 fixes Damien Le Moal
                   ` (16 preceding siblings ...)
  2022-02-17 13:29 ` [PATCH v4 17/31] scsi: pm8001: Fix pm8001_tag_alloc() failures handling Damien Le Moal
@ 2022-02-17 13:29 ` Damien Le Moal
  2022-02-17 19:33   ` Jinpu Wang
  2022-02-17 13:29 ` [PATCH v4 19/31] scsi: pm8001: Fix pm8001_mpi_task_abort_resp() Damien Le Moal
                   ` (12 subsequent siblings)
  30 siblings, 1 reply; 65+ messages in thread
From: Damien Le Moal @ 2022-02-17 13:29 UTC (permalink / raw)
  To: linux-scsi, Martin K . Petersen, Jack Wang, John Garry
  Cc: Xiang Chen, Jason Yan, Luo Jiaxing

If pm8001_mpi_build_cmd() fails, the allocated tag should be freed.

Signed-off-by: Damien Le Moal <damien.lemoal@opensource.wdc.com>
---
 drivers/scsi/pm8001/pm80xx_hwi.c | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/drivers/scsi/pm8001/pm80xx_hwi.c b/drivers/scsi/pm8001/pm80xx_hwi.c
index 76260d06b6be..a5a99d23cfbe 100644
--- a/drivers/scsi/pm8001/pm80xx_hwi.c
+++ b/drivers/scsi/pm8001/pm80xx_hwi.c
@@ -4920,8 +4920,13 @@ static int pm80xx_chip_phy_ctl_req(struct pm8001_hba_info *pm8001_ha,
 	payload.tag = cpu_to_le32(tag);
 	payload.phyop_phyid =
 		cpu_to_le32(((phy_op & 0xFF) << 8) | (phyId & 0xFF));
-	return pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &payload,
-			sizeof(payload), 0);
+
+	rc = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &payload,
+				  sizeof(payload), 0);
+	if (rc)
+		pm8001_tag_free(pm8001_ha, tag);
+
+	return rc;
 }
 
 static u32 pm80xx_chip_is_our_interrupt(struct pm8001_hba_info *pm8001_ha)
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 65+ messages in thread

* [PATCH v4 19/31] scsi: pm8001: Fix pm8001_mpi_task_abort_resp()
  2022-02-17 13:29 [PATCH v4 00/31] libsas and pm8001 fixes Damien Le Moal
                   ` (17 preceding siblings ...)
  2022-02-17 13:29 ` [PATCH v4 18/31] scsi: pm8001: Fix pm80xx_chip_phy_ctl_req() Damien Le Moal
@ 2022-02-17 13:29 ` Damien Le Moal
  2022-02-17 19:35   ` Jinpu Wang
  2022-02-17 13:29 ` [PATCH v4 20/31] scsi: pm8001: Fix tag values handling Damien Le Moal
                   ` (11 subsequent siblings)
  30 siblings, 1 reply; 65+ messages in thread
From: Damien Le Moal @ 2022-02-17 13:29 UTC (permalink / raw)
  To: linux-scsi, Martin K . Petersen, Jack Wang, John Garry
  Cc: Xiang Chen, Jason Yan, Luo Jiaxing

The call to pm8001_ccb_task_free() at the end of
pm8001_mpi_task_abort_resp() already frees the ccb tag. So when the
device NCQ_ABORT_ALL_FLAG is set, the tag should not be freed again.
Also change the hardcoded 0xBFFFFFFF value to ~NCQ_ABORT_ALL_FLAG as it
ought to be.

Signed-off-by: Damien Le Moal <damien.lemoal@opensource.wdc.com>
---
 drivers/scsi/pm8001/pm8001_hwi.c | 7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/drivers/scsi/pm8001/pm8001_hwi.c b/drivers/scsi/pm8001/pm8001_hwi.c
index 35d62e5c9200..5cad5504301e 100644
--- a/drivers/scsi/pm8001/pm8001_hwi.c
+++ b/drivers/scsi/pm8001/pm8001_hwi.c
@@ -3700,12 +3700,11 @@ int pm8001_mpi_task_abort_resp(struct pm8001_hba_info *pm8001_ha, void *piomb)
 	mb();
 
 	if (pm8001_dev->id & NCQ_ABORT_ALL_FLAG) {
-		pm8001_tag_free(pm8001_ha, tag);
 		sas_free_task(t);
-		/* clear the flag */
-		pm8001_dev->id &= 0xBFFFFFFF;
-	} else
+		pm8001_dev->id &= ~NCQ_ABORT_ALL_FLAG;
+	} else {
 		t->task_done(t);
+	}
 
 	return 0;
 }
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 65+ messages in thread

* [PATCH v4 20/31] scsi: pm8001: Fix tag values handling
  2022-02-17 13:29 [PATCH v4 00/31] libsas and pm8001 fixes Damien Le Moal
                   ` (18 preceding siblings ...)
  2022-02-17 13:29 ` [PATCH v4 19/31] scsi: pm8001: Fix pm8001_mpi_task_abort_resp() Damien Le Moal
@ 2022-02-17 13:29 ` Damien Le Moal
  2022-02-17 19:39   ` Jinpu Wang
  2022-02-17 13:29 ` [PATCH v4 21/31] scsi: pm8001: Fix task leak in pm8001_send_abort_all() Damien Le Moal
                   ` (10 subsequent siblings)
  30 siblings, 1 reply; 65+ messages in thread
From: Damien Le Moal @ 2022-02-17 13:29 UTC (permalink / raw)
  To: linux-scsi, Martin K . Petersen, Jack Wang, John Garry
  Cc: Xiang Chen, Jason Yan, Luo Jiaxing

The function pm8001_tag_alloc() determines free tags using the function
find_first_zero_bit() which can return 0 when the first bit of the
bitmap being inspected is 0. As such, tag 0 is a valid tag value that
should not be dismissed as invalid. Fix the functions pm8001_work_fn(),
mpi_sata_completion(), pm8001_mpi_task_abort_resp() and
pm8001_open_reject_retry() to not dismiss 0 tags as invalid.

The value 0xffffffff is used for invalid tags for unused ccb
information structures. Add the macro definition PM8001_INVALID_TAG to
define this value.

Signed-off-by: Damien Le Moal <damien.lemoal@opensource.wdc.com>
---
 drivers/scsi/pm8001/pm8001_hwi.c  | 52 +++++++++++--------------------
 drivers/scsi/pm8001/pm8001_init.c |  3 +-
 drivers/scsi/pm8001/pm8001_sas.c  | 13 ++++----
 drivers/scsi/pm8001/pm8001_sas.h  |  2 ++
 drivers/scsi/pm8001/pm80xx_hwi.c  |  5 ---
 5 files changed, 28 insertions(+), 47 deletions(-)

diff --git a/drivers/scsi/pm8001/pm8001_hwi.c b/drivers/scsi/pm8001/pm8001_hwi.c
index 5cad5504301e..3dc628b0384d 100644
--- a/drivers/scsi/pm8001/pm8001_hwi.c
+++ b/drivers/scsi/pm8001/pm8001_hwi.c
@@ -1522,7 +1522,6 @@ void pm8001_work_fn(struct work_struct *work)
 	case IO_XFER_ERROR_BREAK:
 	{	/* This one stashes the sas_task instead */
 		struct sas_task *t = (struct sas_task *)pm8001_dev;
-		u32 tag;
 		struct pm8001_ccb_info *ccb;
 		struct pm8001_hba_info *pm8001_ha = pw->pm8001_ha;
 		unsigned long flags, flags1;
@@ -1544,8 +1543,8 @@ void pm8001_work_fn(struct work_struct *work)
 		/* Search for a possible ccb that matches the task */
 		for (i = 0; ccb = NULL, i < PM8001_MAX_CCB; i++) {
 			ccb = &pm8001_ha->ccb_info[i];
-			tag = ccb->ccb_tag;
-			if ((tag != 0xFFFFFFFF) && (ccb->task == t))
+			if ((ccb->ccb_tag != PM8001_INVALID_TAG) &&
+			    (ccb->task == t))
 				break;
 		}
 		if (!ccb) {
@@ -1566,11 +1565,11 @@ void pm8001_work_fn(struct work_struct *work)
 			spin_unlock_irqrestore(&t->task_state_lock, flags1);
 			pm8001_dbg(pm8001_ha, FAIL, "task 0x%p done with event 0x%x resp 0x%x stat 0x%x but aborted by upper layer!\n",
 				   t, pw->handler, ts->resp, ts->stat);
-			pm8001_ccb_task_free(pm8001_ha, t, ccb, tag);
+			pm8001_ccb_task_free(pm8001_ha, t, ccb, ccb->ccb_tag);
 			spin_unlock_irqrestore(&pm8001_ha->lock, flags);
 		} else {
 			spin_unlock_irqrestore(&t->task_state_lock, flags1);
-			pm8001_ccb_task_free(pm8001_ha, t, ccb, tag);
+			pm8001_ccb_task_free(pm8001_ha, t, ccb, ccb->ccb_tag);
 			mb();/* in order to force CPU ordering */
 			spin_unlock_irqrestore(&pm8001_ha->lock, flags);
 			t->task_done(t);
@@ -1579,7 +1578,6 @@ void pm8001_work_fn(struct work_struct *work)
 	case IO_XFER_OPEN_RETRY_TIMEOUT:
 	{	/* This one stashes the sas_task instead */
 		struct sas_task *t = (struct sas_task *)pm8001_dev;
-		u32 tag;
 		struct pm8001_ccb_info *ccb;
 		struct pm8001_hba_info *pm8001_ha = pw->pm8001_ha;
 		unsigned long flags, flags1;
@@ -1613,8 +1611,8 @@ void pm8001_work_fn(struct work_struct *work)
 		/* Search for a possible ccb that matches the task */
 		for (i = 0; ccb = NULL, i < PM8001_MAX_CCB; i++) {
 			ccb = &pm8001_ha->ccb_info[i];
-			tag = ccb->ccb_tag;
-			if ((tag != 0xFFFFFFFF) && (ccb->task == t))
+			if ((ccb->ccb_tag != PM8001_INVALID_TAG) &&
+			    (ccb->task == t))
 				break;
 		}
 		if (!ccb) {
@@ -1685,19 +1683,13 @@ void pm8001_work_fn(struct work_struct *work)
 		struct task_status_struct *ts;
 		struct sas_task *task;
 		int i;
-		u32 tag, device_id;
+		u32 device_id;
 
 		for (i = 0; ccb = NULL, i < PM8001_MAX_CCB; i++) {
 			ccb = &pm8001_ha->ccb_info[i];
 			task = ccb->task;
 			ts = &task->task_status;
-			tag = ccb->ccb_tag;
-			/* check if tag is NULL */
-			if (!tag) {
-				pm8001_dbg(pm8001_ha, FAIL,
-					"tag Null\n");
-				continue;
-			}
+
 			if (task != NULL) {
 				dev = task->dev;
 				if (!dev) {
@@ -1706,10 +1698,11 @@ void pm8001_work_fn(struct work_struct *work)
 					continue;
 				}
 				/*complete sas task and update to top layer */
-				pm8001_ccb_task_free(pm8001_ha, task, ccb, tag);
+				pm8001_ccb_task_free(pm8001_ha, task, ccb,
+						     ccb->ccb_tag);
 				ts->resp = SAS_TASK_COMPLETE;
 				task->task_done(task);
-			} else if (tag != 0xFFFFFFFF) {
+			} else if (ccb->ccb_tag != PM8001_INVALID_TAG) {
 				/* complete the internal commands/non-sas task */
 				pm8001_dev = ccb->device;
 				if (pm8001_dev->dcompletion) {
@@ -1717,7 +1710,7 @@ void pm8001_work_fn(struct work_struct *work)
 					pm8001_dev->dcompletion = NULL;
 				}
 				complete(pm8001_ha->nvmd_completion);
-				pm8001_tag_free(pm8001_ha, tag);
+				pm8001_tag_free(pm8001_ha, ccb->ccb_tag);
 			}
 		}
 		/* Deregister all the device ids  */
@@ -2313,11 +2306,6 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb)
 	param = le32_to_cpu(psataPayload->param);
 	tag = le32_to_cpu(psataPayload->tag);
 
-	if (!tag) {
-		pm8001_dbg(pm8001_ha, FAIL, "tag null\n");
-		return;
-	}
-
 	ccb = &pm8001_ha->ccb_info[tag];
 	t = ccb->task;
 	pm8001_dev = ccb->device;
@@ -3051,7 +3039,7 @@ void pm8001_mpi_set_dev_state_resp(struct pm8001_hba_info *pm8001_ha,
 		   device_id, pds, nds, status);
 	complete(pm8001_dev->setds_completion);
 	ccb->task = NULL;
-	ccb->ccb_tag = 0xFFFFFFFF;
+	ccb->ccb_tag = PM8001_INVALID_TAG;
 	pm8001_tag_free(pm8001_ha, tag);
 }
 
@@ -3069,7 +3057,7 @@ void pm8001_mpi_set_nvmd_resp(struct pm8001_hba_info *pm8001_ha, void *piomb)
 				dlen_status);
 	}
 	ccb->task = NULL;
-	ccb->ccb_tag = 0xFFFFFFFF;
+	ccb->ccb_tag = PM8001_INVALID_TAG;
 	pm8001_tag_free(pm8001_ha, tag);
 }
 
@@ -3096,7 +3084,7 @@ pm8001_mpi_get_nvmd_resp(struct pm8001_hba_info *pm8001_ha, void *piomb)
 		 * freed by requesting path anywhere.
 		 */
 		ccb->task = NULL;
-		ccb->ccb_tag = 0xFFFFFFFF;
+		ccb->ccb_tag = PM8001_INVALID_TAG;
 		pm8001_tag_free(pm8001_ha, tag);
 		return;
 	}
@@ -3142,7 +3130,7 @@ pm8001_mpi_get_nvmd_resp(struct pm8001_hba_info *pm8001_ha, void *piomb)
 	complete(pm8001_ha->nvmd_completion);
 	pm8001_dbg(pm8001_ha, MSG, "Get nvmd data complete!\n");
 	ccb->task = NULL;
-	ccb->ccb_tag = 0xFFFFFFFF;
+	ccb->ccb_tag = PM8001_INVALID_TAG;
 	pm8001_tag_free(pm8001_ha, tag);
 }
 
@@ -3555,7 +3543,7 @@ int pm8001_mpi_reg_resp(struct pm8001_hba_info *pm8001_ha, void *piomb)
 	}
 	complete(pm8001_dev->dcompletion);
 	ccb->task = NULL;
-	ccb->ccb_tag = 0xFFFFFFFF;
+	ccb->ccb_tag = PM8001_INVALID_TAG;
 	pm8001_tag_free(pm8001_ha, htag);
 	return 0;
 }
@@ -3627,7 +3615,7 @@ int pm8001_mpi_fw_flash_update_resp(struct pm8001_hba_info *pm8001_ha,
 	}
 	kfree(ccb->fw_control_context);
 	ccb->task = NULL;
-	ccb->ccb_tag = 0xFFFFFFFF;
+	ccb->ccb_tag = PM8001_INVALID_TAG;
 	pm8001_tag_free(pm8001_ha, tag);
 	complete(pm8001_ha->nvmd_completion);
 	return 0;
@@ -3663,10 +3651,6 @@ int pm8001_mpi_task_abort_resp(struct pm8001_hba_info *pm8001_ha, void *piomb)
 
 	status = le32_to_cpu(pPayload->status);
 	tag = le32_to_cpu(pPayload->tag);
-	if (!tag) {
-		pm8001_dbg(pm8001_ha, FAIL, " TAG NULL. RETURNING !!!\n");
-		return -1;
-	}
 
 	scp = le32_to_cpu(pPayload->scp);
 	ccb = &pm8001_ha->ccb_info[tag];
diff --git a/drivers/scsi/pm8001/pm8001_init.c b/drivers/scsi/pm8001/pm8001_init.c
index 4b9a26f008a9..8f44be8364dc 100644
--- a/drivers/scsi/pm8001/pm8001_init.c
+++ b/drivers/scsi/pm8001/pm8001_init.c
@@ -1216,10 +1216,11 @@ pm8001_init_ccb_tag(struct pm8001_hba_info *pm8001_ha, struct Scsi_Host *shost,
 			goto err_out;
 		}
 		pm8001_ha->ccb_info[i].task = NULL;
-		pm8001_ha->ccb_info[i].ccb_tag = 0xffffffff;
+		pm8001_ha->ccb_info[i].ccb_tag = PM8001_INVALID_TAG;
 		pm8001_ha->ccb_info[i].device = NULL;
 		++pm8001_ha->tags_num;
 	}
+
 	return 0;
 
 err_out_noccb:
diff --git a/drivers/scsi/pm8001/pm8001_sas.c b/drivers/scsi/pm8001/pm8001_sas.c
index 4ab0ea9483f2..d0f5feb4f2d3 100644
--- a/drivers/scsi/pm8001/pm8001_sas.c
+++ b/drivers/scsi/pm8001/pm8001_sas.c
@@ -563,7 +563,7 @@ void pm8001_ccb_task_free(struct pm8001_hba_info *pm8001_ha,
 
 	task->lldd_task = NULL;
 	ccb->task = NULL;
-	ccb->ccb_tag = 0xFFFFFFFF;
+	ccb->ccb_tag = PM8001_INVALID_TAG;
 	ccb->open_retry = 0;
 	pm8001_tag_free(pm8001_ha, ccb_idx);
 }
@@ -948,9 +948,11 @@ void pm8001_open_reject_retry(
 		struct task_status_struct *ts;
 		struct pm8001_device *pm8001_dev;
 		unsigned long flags1;
-		u32 tag;
 		struct pm8001_ccb_info *ccb = &pm8001_ha->ccb_info[i];
 
+		if (ccb->ccb_tag == PM8001_INVALID_TAG)
+			continue;
+
 		pm8001_dev = ccb->device;
 		if (!pm8001_dev || (pm8001_dev->dev_type == SAS_PHY_UNUSED))
 			continue;
@@ -962,9 +964,6 @@ void pm8001_open_reject_retry(
 				continue;
 		} else if (pm8001_dev != device_to_close)
 			continue;
-		tag = ccb->ccb_tag;
-		if (!tag || (tag == 0xFFFFFFFF))
-			continue;
 		task = ccb->task;
 		if (!task || !task->task_done)
 			continue;
@@ -984,11 +983,11 @@ void pm8001_open_reject_retry(
 				& SAS_TASK_STATE_ABORTED))) {
 			spin_unlock_irqrestore(&task->task_state_lock,
 				flags1);
-			pm8001_ccb_task_free(pm8001_ha, task, ccb, tag);
+			pm8001_ccb_task_free(pm8001_ha, task, ccb, ccb->ccb_tag);
 		} else {
 			spin_unlock_irqrestore(&task->task_state_lock,
 				flags1);
-			pm8001_ccb_task_free(pm8001_ha, task, ccb, tag);
+			pm8001_ccb_task_free(pm8001_ha, task, ccb, ccb->ccb_tag);
 			mb();/* in order to force CPU ordering */
 			spin_unlock_irqrestore(&pm8001_ha->lock, flags);
 			task->task_done(task);
diff --git a/drivers/scsi/pm8001/pm8001_sas.h b/drivers/scsi/pm8001/pm8001_sas.h
index a17da1cebce1..1791cdf30276 100644
--- a/drivers/scsi/pm8001/pm8001_sas.h
+++ b/drivers/scsi/pm8001/pm8001_sas.h
@@ -738,6 +738,8 @@ void pm8001_free_dev(struct pm8001_device *pm8001_dev);
 /* ctl shared API */
 extern const struct attribute_group *pm8001_host_groups[];
 
+#define PM8001_INVALID_TAG	((u32)-1)
+
 static inline void
 pm8001_ccb_task_free_done(struct pm8001_hba_info *pm8001_ha,
 			struct sas_task *task, struct pm8001_ccb_info *ccb,
diff --git a/drivers/scsi/pm8001/pm80xx_hwi.c b/drivers/scsi/pm8001/pm80xx_hwi.c
index a5a99d23cfbe..4419fdb0db78 100644
--- a/drivers/scsi/pm8001/pm80xx_hwi.c
+++ b/drivers/scsi/pm8001/pm80xx_hwi.c
@@ -2402,11 +2402,6 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha,
 	param = le32_to_cpu(psataPayload->param);
 	tag = le32_to_cpu(psataPayload->tag);
 
-	if (!tag) {
-		pm8001_dbg(pm8001_ha, FAIL, "tag null\n");
-		return;
-	}
-
 	ccb = &pm8001_ha->ccb_info[tag];
 	t = ccb->task;
 	pm8001_dev = ccb->device;
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 65+ messages in thread

* [PATCH v4 21/31] scsi: pm8001: Fix task leak in pm8001_send_abort_all()
  2022-02-17 13:29 [PATCH v4 00/31] libsas and pm8001 fixes Damien Le Moal
                   ` (19 preceding siblings ...)
  2022-02-17 13:29 ` [PATCH v4 20/31] scsi: pm8001: Fix tag values handling Damien Le Moal
@ 2022-02-17 13:29 ` Damien Le Moal
  2022-02-17 17:42   ` John Garry
  2022-02-17 13:29 ` [PATCH v4 22/31] scsi: pm8001: Fix tag leaks on error Damien Le Moal
                   ` (9 subsequent siblings)
  30 siblings, 1 reply; 65+ messages in thread
From: Damien Le Moal @ 2022-02-17 13:29 UTC (permalink / raw)
  To: linux-scsi, Martin K . Petersen, Jack Wang, John Garry
  Cc: Xiang Chen, Jason Yan, Luo Jiaxing

In pm8001_send_abort_all(), make sure to free the allocated sas task
if pm8001_tag_alloc() or pm8001_mpi_build_cmd() fail.

Signed-off-by: Damien Le Moal <damien.lemoal@opensource.wdc.com>
---
 drivers/scsi/pm8001/pm8001_hwi.c | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/drivers/scsi/pm8001/pm8001_hwi.c b/drivers/scsi/pm8001/pm8001_hwi.c
index 3dc628b0384d..cc96e58454c8 100644
--- a/drivers/scsi/pm8001/pm8001_hwi.c
+++ b/drivers/scsi/pm8001/pm8001_hwi.c
@@ -1764,7 +1764,6 @@ static void pm8001_send_abort_all(struct pm8001_hba_info *pm8001_ha,
 	}
 
 	task = sas_alloc_slow_task(GFP_ATOMIC);
-
 	if (!task) {
 		pm8001_dbg(pm8001_ha, FAIL, "cannot allocate task\n");
 		return;
@@ -1773,8 +1772,10 @@ static void pm8001_send_abort_all(struct pm8001_hba_info *pm8001_ha,
 	task->task_done = pm8001_task_done;
 
 	res = pm8001_tag_alloc(pm8001_ha, &ccb_tag);
-	if (res)
+	if (res) {
+		sas_free_task(task);
 		return;
+	}
 
 	ccb = &pm8001_ha->ccb_info[ccb_tag];
 	ccb->device = pm8001_ha_dev;
@@ -1791,8 +1792,10 @@ static void pm8001_send_abort_all(struct pm8001_hba_info *pm8001_ha,
 
 	ret = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &task_abort,
 			sizeof(task_abort), 0);
-	if (ret)
+	if (ret) {
+		sas_free_task(task);
 		pm8001_tag_free(pm8001_ha, ccb_tag);
+	}
 
 }
 
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 65+ messages in thread

* [PATCH v4 22/31] scsi: pm8001: Fix tag leaks on error
  2022-02-17 13:29 [PATCH v4 00/31] libsas and pm8001 fixes Damien Le Moal
                   ` (20 preceding siblings ...)
  2022-02-17 13:29 ` [PATCH v4 21/31] scsi: pm8001: Fix task leak in pm8001_send_abort_all() Damien Le Moal
@ 2022-02-17 13:29 ` Damien Le Moal
  2022-02-17 17:41   ` John Garry
  2022-02-17 13:29 ` [PATCH v4 23/31] scsi: pm8001: fix memory leak in pm8001_chip_fw_flash_update_req() Damien Le Moal
                   ` (8 subsequent siblings)
  30 siblings, 1 reply; 65+ messages in thread
From: Damien Le Moal @ 2022-02-17 13:29 UTC (permalink / raw)
  To: linux-scsi, Martin K . Petersen, Jack Wang, John Garry
  Cc: Xiang Chen, Jason Yan, Luo Jiaxing

In pm8001_chip_set_dev_state_req(), pm8001_chip_fw_flash_update_req()
and pm8001_chip_reg_dev_req() add missing calls to pm8001_tag_free() to
free the allocated tag when pm8001_mpi_build_cmd() fails.

Similarly, in pm8001_exec_internal_task_abort(), if the chip
->task_abort method fails, the tag allocated for the abort request task
must be freed. Add the missing call to pm8001_tag_free(). Also remove
the useless ex_err label and use "break" instead of "goto" statements
in the retry loop.

Signed-off-by: Damien Le Moal <damien.lemoal@opensource.wdc.com>
---
 drivers/scsi/pm8001/pm8001_hwi.c |  9 +++++++++
 drivers/scsi/pm8001/pm8001_sas.c | 33 +++++++++++++++++---------------
 2 files changed, 27 insertions(+), 15 deletions(-)

diff --git a/drivers/scsi/pm8001/pm8001_hwi.c b/drivers/scsi/pm8001/pm8001_hwi.c
index cc96e58454c8..431fc9160637 100644
--- a/drivers/scsi/pm8001/pm8001_hwi.c
+++ b/drivers/scsi/pm8001/pm8001_hwi.c
@@ -4458,6 +4458,9 @@ static int pm8001_chip_reg_dev_req(struct pm8001_hba_info *pm8001_ha,
 		SAS_ADDR_SIZE);
 	rc = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &payload,
 			sizeof(payload), 0);
+	if (rc)
+		pm8001_tag_free(pm8001_ha, tag);
+
 	return rc;
 }
 
@@ -4870,6 +4873,9 @@ pm8001_chip_fw_flash_update_req(struct pm8001_hba_info *pm8001_ha,
 	ccb->ccb_tag = tag;
 	rc = pm8001_chip_fw_flash_update_build(pm8001_ha, &flash_update_info,
 		tag);
+	if (rc)
+		pm8001_tag_free(pm8001_ha, tag);
+
 	return rc;
 }
 
@@ -4974,6 +4980,9 @@ pm8001_chip_set_dev_state_req(struct pm8001_hba_info *pm8001_ha,
 	payload.nds = cpu_to_le32(state);
 	rc = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &payload,
 			sizeof(payload), 0);
+	if (rc)
+		pm8001_tag_free(pm8001_ha, tag);
+
 	return rc;
 
 }
diff --git a/drivers/scsi/pm8001/pm8001_sas.c b/drivers/scsi/pm8001/pm8001_sas.c
index d0f5feb4f2d3..0440777a9135 100644
--- a/drivers/scsi/pm8001/pm8001_sas.c
+++ b/drivers/scsi/pm8001/pm8001_sas.c
@@ -834,7 +834,8 @@ pm8001_exec_internal_task_abort(struct pm8001_hba_info *pm8001_ha,
 
 		res = pm8001_tag_alloc(pm8001_ha, &ccb_tag);
 		if (res)
-			goto ex_err;
+			break;
+
 		ccb = &pm8001_ha->ccb_info[ccb_tag];
 		ccb->device = pm8001_dev;
 		ccb->ccb_tag = ccb_tag;
@@ -843,36 +844,38 @@ pm8001_exec_internal_task_abort(struct pm8001_hba_info *pm8001_ha,
 
 		res = PM8001_CHIP_DISP->task_abort(pm8001_ha,
 			pm8001_dev, flag, task_tag, ccb_tag);
-
 		if (res) {
 			del_timer(&task->slow_task->timer);
-			pm8001_dbg(pm8001_ha, FAIL, "Executing internal task failed\n");
-			goto ex_err;
+			pm8001_dbg(pm8001_ha, FAIL,
+				   "Executing internal task failed\n");
+			pm8001_tag_free(pm8001_ha, ccb_tag);
+			break;
 		}
+
 		wait_for_completion(&task->slow_task->completion);
 		res = TMF_RESP_FUNC_FAILED;
+
 		/* Even TMF timed out, return direct. */
 		if (task->task_state_flags & SAS_TASK_STATE_ABORTED) {
 			pm8001_dbg(pm8001_ha, FAIL, "TMF task timeout.\n");
-			goto ex_err;
+			break;
 		}
 
 		if (task->task_status.resp == SAS_TASK_COMPLETE &&
 			task->task_status.stat == SAS_SAM_STAT_GOOD) {
 			res = TMF_RESP_FUNC_COMPLETE;
 			break;
-
-		} else {
-			pm8001_dbg(pm8001_ha, EH,
-				   " Task to dev %016llx response: 0x%x status 0x%x\n",
-				   SAS_ADDR(dev->sas_addr),
-				   task->task_status.resp,
-				   task->task_status.stat);
-			sas_free_task(task);
-			task = NULL;
 		}
+
+		pm8001_dbg(pm8001_ha, EH,
+			   " Task to dev %016llx response: 0x%x status 0x%x\n",
+			   SAS_ADDR(dev->sas_addr),
+			   task->task_status.resp,
+			   task->task_status.stat);
+		sas_free_task(task);
+		task = NULL;
 	}
-ex_err:
+
 	BUG_ON(retry == 3 && task != NULL);
 	sas_free_task(task);
 	return res;
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 65+ messages in thread

* [PATCH v4 23/31] scsi: pm8001: fix memory leak in pm8001_chip_fw_flash_update_req()
  2022-02-17 13:29 [PATCH v4 00/31] libsas and pm8001 fixes Damien Le Moal
                   ` (21 preceding siblings ...)
  2022-02-17 13:29 ` [PATCH v4 22/31] scsi: pm8001: Fix tag leaks on error Damien Le Moal
@ 2022-02-17 13:29 ` Damien Le Moal
  2022-02-17 19:42   ` Jinpu Wang
  2022-02-17 13:29 ` [PATCH v4 24/31] scsi: libsas: Simplify sas_ata_qc_issue() detection of NCQ commands Damien Le Moal
                   ` (7 subsequent siblings)
  30 siblings, 1 reply; 65+ messages in thread
From: Damien Le Moal @ 2022-02-17 13:29 UTC (permalink / raw)
  To: linux-scsi, Martin K . Petersen, Jack Wang, John Garry
  Cc: Xiang Chen, Jason Yan, Luo Jiaxing

In pm8001_chip_fw_flash_update_build(), if
pm8001_chip_fw_flash_update_build() fails, the struct fw_control_ex
allocated must be freed.

Signed-off-by: Damien Le Moal <damien.lemoal@opensource.wdc.com>
---
 drivers/scsi/pm8001/pm8001_hwi.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/scsi/pm8001/pm8001_hwi.c b/drivers/scsi/pm8001/pm8001_hwi.c
index 431fc9160637..41077c84eec9 100644
--- a/drivers/scsi/pm8001/pm8001_hwi.c
+++ b/drivers/scsi/pm8001/pm8001_hwi.c
@@ -4873,8 +4873,10 @@ pm8001_chip_fw_flash_update_req(struct pm8001_hba_info *pm8001_ha,
 	ccb->ccb_tag = tag;
 	rc = pm8001_chip_fw_flash_update_build(pm8001_ha, &flash_update_info,
 		tag);
-	if (rc)
+	if (rc) {
+		kfree(fw_control_context);
 		pm8001_tag_free(pm8001_ha, tag);
+	}
 
 	return rc;
 }
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 65+ messages in thread

* [PATCH v4 24/31] scsi: libsas: Simplify sas_ata_qc_issue() detection of NCQ commands
  2022-02-17 13:29 [PATCH v4 00/31] libsas and pm8001 fixes Damien Le Moal
                   ` (22 preceding siblings ...)
  2022-02-17 13:29 ` [PATCH v4 23/31] scsi: pm8001: fix memory leak in pm8001_chip_fw_flash_update_req() Damien Le Moal
@ 2022-02-17 13:29 ` Damien Le Moal
  2022-02-17 19:43   ` Jinpu Wang
  2022-02-17 13:29 ` [PATCH v4 25/31] scsi: pm8001: Simplify pm8001_get_ncq_tag() Damien Le Moal
                   ` (6 subsequent siblings)
  30 siblings, 1 reply; 65+ messages in thread
From: Damien Le Moal @ 2022-02-17 13:29 UTC (permalink / raw)
  To: linux-scsi, Martin K . Petersen, Jack Wang, John Garry
  Cc: Xiang Chen, Jason Yan, Luo Jiaxing

To detect if a command is NCQ, there is no need to test all possible NCQ
command codes. Instead, use ata_is_ncq() to test the command protocol.

Signed-off-by: Damien Le Moal <damien.lemoal@opensource.wdc.com>
---
 drivers/scsi/libsas/sas_ata.c | 9 ++-------
 1 file changed, 2 insertions(+), 7 deletions(-)

diff --git a/drivers/scsi/libsas/sas_ata.c b/drivers/scsi/libsas/sas_ata.c
index 50f779088b6e..fcfc8fd4b14f 100644
--- a/drivers/scsi/libsas/sas_ata.c
+++ b/drivers/scsi/libsas/sas_ata.c
@@ -181,14 +181,9 @@ static unsigned int sas_ata_qc_issue(struct ata_queued_cmd *qc)
 	task->task_proto = SAS_PROTOCOL_STP;
 	task->task_done = sas_ata_task_done;
 
-	if (qc->tf.command == ATA_CMD_FPDMA_WRITE ||
-	    qc->tf.command == ATA_CMD_FPDMA_READ ||
-	    qc->tf.command == ATA_CMD_FPDMA_RECV ||
-	    qc->tf.command == ATA_CMD_FPDMA_SEND ||
-	    qc->tf.command == ATA_CMD_NCQ_NON_DATA) {
-		/* Need to zero out the tag libata assigned us */
+	/* For NCQ commands, zero out the tag libata assigned us */
+	if (ata_is_ncq(qc->tf.protocol))
 		qc->tf.nsect = 0;
-	}
 
 	ata_tf_to_fis(&qc->tf, qc->dev->link->pmp, 1, (u8 *)&task->ata_task.fis);
 	task->uldd_task = qc;
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 65+ messages in thread

* [PATCH v4 25/31] scsi: pm8001: Simplify pm8001_get_ncq_tag()
  2022-02-17 13:29 [PATCH v4 00/31] libsas and pm8001 fixes Damien Le Moal
                   ` (23 preceding siblings ...)
  2022-02-17 13:29 ` [PATCH v4 24/31] scsi: libsas: Simplify sas_ata_qc_issue() detection of NCQ commands Damien Le Moal
@ 2022-02-17 13:29 ` Damien Le Moal
  2022-02-17 19:43   ` Jinpu Wang
  2022-02-17 13:29 ` [PATCH v4 26/31] scsi: pm8001: Introduce ccb alloc/free helpers Damien Le Moal
                   ` (5 subsequent siblings)
  30 siblings, 1 reply; 65+ messages in thread
From: Damien Le Moal @ 2022-02-17 13:29 UTC (permalink / raw)
  To: linux-scsi, Martin K . Petersen, Jack Wang, John Garry
  Cc: Xiang Chen, Jason Yan, Luo Jiaxing

To detect if a command is NCQ, there is no need to test all possible NCQ
command codes. Instead, use ata_is_ncq() to test the command protocol.

Reviewed-by: John Garry <john.garry@huawei.com>
Signed-off-by: Damien Le Moal <damien.lemoal@opensource.wdc.com>
---
 drivers/scsi/pm8001/pm8001_sas.c | 14 +++++---------
 1 file changed, 5 insertions(+), 9 deletions(-)

diff --git a/drivers/scsi/pm8001/pm8001_sas.c b/drivers/scsi/pm8001/pm8001_sas.c
index 0440777a9135..1e60ad82635e 100644
--- a/drivers/scsi/pm8001/pm8001_sas.c
+++ b/drivers/scsi/pm8001/pm8001_sas.c
@@ -304,16 +304,12 @@ static int pm8001_task_prep_smp(struct pm8001_hba_info *pm8001_ha,
 u32 pm8001_get_ncq_tag(struct sas_task *task, u32 *tag)
 {
 	struct ata_queued_cmd *qc = task->uldd_task;
-	if (qc) {
-		if (qc->tf.command == ATA_CMD_FPDMA_WRITE ||
-		    qc->tf.command == ATA_CMD_FPDMA_READ ||
-		    qc->tf.command == ATA_CMD_FPDMA_RECV ||
-		    qc->tf.command == ATA_CMD_FPDMA_SEND ||
-		    qc->tf.command == ATA_CMD_NCQ_NON_DATA) {
-			*tag = qc->tag;
-			return 1;
-		}
+
+	if (qc && ata_is_ncq(qc->tf.protocol)) {
+		*tag = qc->tag;
+		return 1;
 	}
+
 	return 0;
 }
 
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 65+ messages in thread

* [PATCH v4 26/31] scsi: pm8001: Introduce ccb alloc/free helpers
  2022-02-17 13:29 [PATCH v4 00/31] libsas and pm8001 fixes Damien Le Moal
                   ` (24 preceding siblings ...)
  2022-02-17 13:29 ` [PATCH v4 25/31] scsi: pm8001: Simplify pm8001_get_ncq_tag() Damien Le Moal
@ 2022-02-17 13:29 ` Damien Le Moal
  2022-02-17 19:45   ` Jinpu Wang
  2022-02-17 13:29 ` [PATCH v4 27/31] scsi: pm8001: Simplify pm8001_mpi_build_cmd() interface Damien Le Moal
                   ` (4 subsequent siblings)
  30 siblings, 1 reply; 65+ messages in thread
From: Damien Le Moal @ 2022-02-17 13:29 UTC (permalink / raw)
  To: linux-scsi, Martin K . Petersen, Jack Wang, John Garry
  Cc: Xiang Chen, Jason Yan, Luo Jiaxing

Introduce the pm8001_ccb_alloc() and pm8001_ccb_free() helpers to
replace the typical code patterns:

	res = pm8001_tag_alloc(pm8001_ha, &ccb_tag);
	if (res)
		...
	ccb = &pm8001_ha->ccb_info[ccb_tag];
	ccb->device = pm8001_ha_dev;
	ccb->ccb_tag = ccb_tag;
	ccb->task = task;
	ccb->n_elem = 0;

and

	ccb->task = NULL;
	ccb->ccb_tag = PM8001_INVALID_TAG;
	pm8001_tag_free(pm8001_ha, tag);

With the simpler function calls:

	ccb = pm8001_ccb_alloc(pm8001_ha, pm8001_ha_dev, task);
	if (!ccb)
		...

and

	pm8001_ccb_free(pm8001_ha, ccb);

The pm8001_ccb_alloc() helper ensures that all fields of the ccb info
structure for the newly allocated tag are all initialized, except the
buf_prd field. The pm8001_ccb_free() helper clears the initialized
fields and the ccb tag to ensure that iteration over the adapter
ccb_info array detects ccbs that are in use.

All call site of the pm8001_tag_alloc() function that use a ccb info
associated with an allocated tag are converted to use the new helpers.

Signed-off-by: Damien Le Moal <damien.lemoal@opensource.wdc.com>
Reviewed-by: John Garry <john.garry@huawei.com>
---
 drivers/scsi/pm8001/pm8001_hwi.c | 180 +++++++++++++------------------
 drivers/scsi/pm8001/pm8001_sas.c |  46 ++++----
 drivers/scsi/pm8001/pm8001_sas.h |  47 ++++++++
 drivers/scsi/pm8001/pm80xx_hwi.c |  64 +++++------
 4 files changed, 166 insertions(+), 171 deletions(-)

diff --git a/drivers/scsi/pm8001/pm8001_hwi.c b/drivers/scsi/pm8001/pm8001_hwi.c
index 41077c84eec9..699fecc09267 100644
--- a/drivers/scsi/pm8001/pm8001_hwi.c
+++ b/drivers/scsi/pm8001/pm8001_hwi.c
@@ -1710,7 +1710,7 @@ void pm8001_work_fn(struct work_struct *work)
 					pm8001_dev->dcompletion = NULL;
 				}
 				complete(pm8001_ha->nvmd_completion);
-				pm8001_tag_free(pm8001_ha, ccb->ccb_tag);
+				pm8001_ccb_free(pm8001_ha, ccb);
 			}
 		}
 		/* Deregister all the device ids  */
@@ -1749,8 +1749,6 @@ int pm8001_handle_event(struct pm8001_hba_info *pm8001_ha, void *data,
 static void pm8001_send_abort_all(struct pm8001_hba_info *pm8001_ha,
 		struct pm8001_device *pm8001_ha_dev)
 {
-	int res;
-	u32 ccb_tag;
 	struct pm8001_ccb_info *ccb;
 	struct sas_task *task = NULL;
 	struct task_abort_req task_abort;
@@ -1771,32 +1769,25 @@ static void pm8001_send_abort_all(struct pm8001_hba_info *pm8001_ha,
 
 	task->task_done = pm8001_task_done;
 
-	res = pm8001_tag_alloc(pm8001_ha, &ccb_tag);
-	if (res) {
+	ccb = pm8001_ccb_alloc(pm8001_ha, pm8001_ha_dev, task);
+	if (!ccb) {
 		sas_free_task(task);
 		return;
 	}
 
-	ccb = &pm8001_ha->ccb_info[ccb_tag];
-	ccb->device = pm8001_ha_dev;
-	ccb->ccb_tag = ccb_tag;
-	ccb->task = task;
-	ccb->n_elem = 0;
-
 	circularQ = &pm8001_ha->inbnd_q_tbl[0];
 
 	memset(&task_abort, 0, sizeof(task_abort));
 	task_abort.abort_all = cpu_to_le32(1);
 	task_abort.device_id = cpu_to_le32(pm8001_ha_dev->device_id);
-	task_abort.tag = cpu_to_le32(ccb_tag);
+	task_abort.tag = cpu_to_le32(ccb->ccb_tag);
 
 	ret = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &task_abort,
 			sizeof(task_abort), 0);
 	if (ret) {
 		sas_free_task(task);
-		pm8001_tag_free(pm8001_ha, ccb_tag);
+		pm8001_ccb_free(pm8001_ha, ccb);
 	}
-
 }
 
 static void pm8001_send_read_log(struct pm8001_hba_info *pm8001_ha,
@@ -1804,7 +1795,6 @@ static void pm8001_send_read_log(struct pm8001_hba_info *pm8001_ha,
 {
 	struct sata_start_req sata_cmd;
 	int res;
-	u32 ccb_tag;
 	struct pm8001_ccb_info *ccb;
 	struct sas_task *task = NULL;
 	struct host_to_dev_fis fis;
@@ -1820,20 +1810,13 @@ static void pm8001_send_read_log(struct pm8001_hba_info *pm8001_ha,
 	}
 	task->task_done = pm8001_task_done;
 
-	res = pm8001_tag_alloc(pm8001_ha, &ccb_tag);
-	if (res) {
-		sas_free_task(task);
-		pm8001_dbg(pm8001_ha, FAIL, "cannot allocate tag !!!\n");
-		return;
-	}
-
-	/* allocate domain device by ourselves as libsas
-	 * is not going to provide any
-	*/
+	/*
+	 * Allocate domain device by ourselves as libsas is not going to
+	 * provide any.
+	 */
 	dev = kzalloc(sizeof(struct domain_device), GFP_ATOMIC);
 	if (!dev) {
 		sas_free_task(task);
-		pm8001_tag_free(pm8001_ha, ccb_tag);
 		pm8001_dbg(pm8001_ha, FAIL,
 			   "Domain device cannot be allocated\n");
 		return;
@@ -1841,11 +1824,13 @@ static void pm8001_send_read_log(struct pm8001_hba_info *pm8001_ha,
 	task->dev = dev;
 	task->dev->lldd_dev = pm8001_ha_dev;
 
-	ccb = &pm8001_ha->ccb_info[ccb_tag];
-	ccb->device = pm8001_ha_dev;
-	ccb->ccb_tag = ccb_tag;
-	ccb->task = task;
-	ccb->n_elem = 0;
+	ccb = pm8001_ccb_alloc(pm8001_ha, pm8001_ha_dev, task);
+	if (!ccb) {
+		sas_free_task(task);
+		kfree(dev);
+		return;
+	}
+
 	pm8001_ha_dev->id |= NCQ_READ_LOG_FLAG;
 	pm8001_ha_dev->id |= NCQ_2ND_RLE_FLAG;
 
@@ -1860,7 +1845,7 @@ static void pm8001_send_read_log(struct pm8001_hba_info *pm8001_ha,
 	fis.lbal = 0x10;
 	fis.sector_count = 0x1;
 
-	sata_cmd.tag = cpu_to_le32(ccb_tag);
+	sata_cmd.tag = cpu_to_le32(ccb->ccb_tag);
 	sata_cmd.device_id = cpu_to_le32(pm8001_ha_dev->device_id);
 	sata_cmd.ncqtag_atap_dir_m = cpu_to_le32((0x1 << 7) | (0x5 << 9));
 	memcpy(&sata_cmd.sata_fis, &fis, sizeof(struct host_to_dev_fis));
@@ -1869,7 +1854,7 @@ static void pm8001_send_read_log(struct pm8001_hba_info *pm8001_ha,
 			sizeof(sata_cmd), 0);
 	if (res) {
 		sas_free_task(task);
-		pm8001_tag_free(pm8001_ha, ccb_tag);
+		pm8001_ccb_free(pm8001_ha, ccb);
 		kfree(dev);
 	}
 }
@@ -3038,12 +3023,12 @@ void pm8001_mpi_set_dev_state_resp(struct pm8001_hba_info *pm8001_ha,
 	u32 device_id = le32_to_cpu(pPayload->device_id);
 	u8 pds = le32_to_cpu(pPayload->pds_nds) & PDS_BITS;
 	u8 nds = le32_to_cpu(pPayload->pds_nds) & NDS_BITS;
-	pm8001_dbg(pm8001_ha, MSG, "Set device id = 0x%x state from 0x%x to 0x%x status = 0x%x!\n",
+
+	pm8001_dbg(pm8001_ha, MSG,
+		   "Set device id = 0x%x state from 0x%x to 0x%x status = 0x%x!\n",
 		   device_id, pds, nds, status);
 	complete(pm8001_dev->setds_completion);
-	ccb->task = NULL;
-	ccb->ccb_tag = PM8001_INVALID_TAG;
-	pm8001_tag_free(pm8001_ha, tag);
+	pm8001_ccb_free(pm8001_ha, ccb);
 }
 
 void pm8001_mpi_set_nvmd_resp(struct pm8001_hba_info *pm8001_ha, void *piomb)
@@ -3053,15 +3038,14 @@ void pm8001_mpi_set_nvmd_resp(struct pm8001_hba_info *pm8001_ha, void *piomb)
 	u32 tag = le32_to_cpu(pPayload->tag);
 	struct pm8001_ccb_info *ccb = &pm8001_ha->ccb_info[tag];
 	u32 dlen_status = le32_to_cpu(pPayload->dlen_status);
+
 	complete(pm8001_ha->nvmd_completion);
 	pm8001_dbg(pm8001_ha, MSG, "Set nvm data complete!\n");
 	if ((dlen_status & NVMD_STAT) != 0) {
 		pm8001_dbg(pm8001_ha, FAIL, "Set nvm data error %x\n",
 				dlen_status);
 	}
-	ccb->task = NULL;
-	ccb->ccb_tag = PM8001_INVALID_TAG;
-	pm8001_tag_free(pm8001_ha, tag);
+	pm8001_ccb_free(pm8001_ha, ccb);
 }
 
 void
@@ -3086,9 +3070,7 @@ pm8001_mpi_get_nvmd_resp(struct pm8001_hba_info *pm8001_ha, void *piomb)
 		/* We should free tag during failure also, the tag is not being
 		 * freed by requesting path anywhere.
 		 */
-		ccb->task = NULL;
-		ccb->ccb_tag = PM8001_INVALID_TAG;
-		pm8001_tag_free(pm8001_ha, tag);
+		pm8001_ccb_free(pm8001_ha, ccb);
 		return;
 	}
 	if (ir_tds_bn_dps_das_nvm & IPMode) {
@@ -3132,9 +3114,7 @@ pm8001_mpi_get_nvmd_resp(struct pm8001_hba_info *pm8001_ha, void *piomb)
 	 */
 	complete(pm8001_ha->nvmd_completion);
 	pm8001_dbg(pm8001_ha, MSG, "Get nvmd data complete!\n");
-	ccb->task = NULL;
-	ccb->ccb_tag = PM8001_INVALID_TAG;
-	pm8001_tag_free(pm8001_ha, tag);
+	pm8001_ccb_free(pm8001_ha, ccb);
 }
 
 int pm8001_mpi_local_phy_ctl(struct pm8001_hba_info *pm8001_ha, void *piomb)
@@ -3545,9 +3525,7 @@ int pm8001_mpi_reg_resp(struct pm8001_hba_info *pm8001_ha, void *piomb)
 		break;
 	}
 	complete(pm8001_dev->dcompletion);
-	ccb->task = NULL;
-	ccb->ccb_tag = PM8001_INVALID_TAG;
-	pm8001_tag_free(pm8001_ha, htag);
+	pm8001_ccb_free(pm8001_ha, ccb);
 	return 0;
 }
 
@@ -3580,6 +3558,7 @@ int pm8001_mpi_fw_flash_update_resp(struct pm8001_hba_info *pm8001_ha,
 		(struct fw_flash_Update_resp *)(piomb + 4);
 	u32 tag = le32_to_cpu(ppayload->tag);
 	struct pm8001_ccb_info *ccb = &pm8001_ha->ccb_info[tag];
+
 	status = le32_to_cpu(ppayload->status);
 	switch (status) {
 	case FLASH_UPDATE_COMPLETE_PENDING_REBOOT:
@@ -3617,9 +3596,7 @@ int pm8001_mpi_fw_flash_update_resp(struct pm8001_hba_info *pm8001_ha,
 		break;
 	}
 	kfree(ccb->fw_control_context);
-	ccb->task = NULL;
-	ccb->ccb_tag = PM8001_INVALID_TAG;
-	pm8001_tag_free(pm8001_ha, tag);
+	pm8001_ccb_free(pm8001_ha, ccb);
 	complete(pm8001_ha->nvmd_completion);
 	return 0;
 }
@@ -4412,7 +4389,7 @@ static int pm8001_chip_reg_dev_req(struct pm8001_hba_info *pm8001_ha,
 	u32 stp_sspsmp_sata = 0x4;
 	struct inbound_queue_table *circularQ;
 	u32 linkrate, phy_id;
-	int rc, tag = 0xdeadbeef;
+	int rc;
 	struct pm8001_ccb_info *ccb;
 	u8 retryFlag = 0x1;
 	u16 firstBurstSize = 0;
@@ -4423,13 +4400,11 @@ static int pm8001_chip_reg_dev_req(struct pm8001_hba_info *pm8001_ha,
 	circularQ = &pm8001_ha->inbnd_q_tbl[0];
 
 	memset(&payload, 0, sizeof(payload));
-	rc = pm8001_tag_alloc(pm8001_ha, &tag);
-	if (rc)
-		return rc;
-	ccb = &pm8001_ha->ccb_info[tag];
-	ccb->device = pm8001_dev;
-	ccb->ccb_tag = tag;
-	payload.tag = cpu_to_le32(tag);
+	ccb = pm8001_ccb_alloc(pm8001_ha, pm8001_dev, NULL);
+	if (!ccb)
+		return -SAS_QUEUE_FULL;
+
+	payload.tag = cpu_to_le32(ccb->ccb_tag);
 	if (flag == 1)
 		stp_sspsmp_sata = 0x02; /*direct attached sata */
 	else {
@@ -4459,7 +4434,7 @@ static int pm8001_chip_reg_dev_req(struct pm8001_hba_info *pm8001_ha,
 	rc = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &payload,
 			sizeof(payload), 0);
 	if (rc)
-		pm8001_tag_free(pm8001_ha, tag);
+		pm8001_ccb_free(pm8001_ha, ccb);
 
 	return rc;
 }
@@ -4624,7 +4599,6 @@ int pm8001_chip_get_nvmd_req(struct pm8001_hba_info *pm8001_ha,
 	u32 opc = OPC_INB_GET_NVMD_DATA;
 	u32 nvmd_type;
 	int rc;
-	u32 tag;
 	struct pm8001_ccb_info *ccb;
 	struct inbound_queue_table *circularQ;
 	struct get_nvm_data_req nvmd_req;
@@ -4639,15 +4613,15 @@ int pm8001_chip_get_nvmd_req(struct pm8001_hba_info *pm8001_ha,
 	fw_control_context->len = ioctl_payload->rd_length;
 	circularQ = &pm8001_ha->inbnd_q_tbl[0];
 	memset(&nvmd_req, 0, sizeof(nvmd_req));
-	rc = pm8001_tag_alloc(pm8001_ha, &tag);
-	if (rc) {
+
+	ccb = pm8001_ccb_alloc(pm8001_ha, NULL, NULL);
+	if (!ccb) {
 		kfree(fw_control_context);
-		return rc;
+		return -SAS_QUEUE_FULL;
 	}
-	ccb = &pm8001_ha->ccb_info[tag];
-	ccb->ccb_tag = tag;
 	ccb->fw_control_context = fw_control_context;
-	nvmd_req.tag = cpu_to_le32(tag);
+
+	nvmd_req.tag = cpu_to_le32(ccb->ccb_tag);
 
 	switch (nvmd_type) {
 	case TWI_DEVICE: {
@@ -4708,7 +4682,7 @@ int pm8001_chip_get_nvmd_req(struct pm8001_hba_info *pm8001_ha,
 			sizeof(nvmd_req), 0);
 	if (rc) {
 		kfree(fw_control_context);
-		pm8001_tag_free(pm8001_ha, tag);
+		pm8001_ccb_free(pm8001_ha, ccb);
 	}
 	return rc;
 }
@@ -4719,7 +4693,6 @@ int pm8001_chip_set_nvmd_req(struct pm8001_hba_info *pm8001_ha,
 	u32 opc = OPC_INB_SET_NVMD_DATA;
 	u32 nvmd_type;
 	int rc;
-	u32 tag;
 	struct pm8001_ccb_info *ccb;
 	struct inbound_queue_table *circularQ;
 	struct set_nvm_data_req nvmd_req;
@@ -4735,15 +4708,15 @@ int pm8001_chip_set_nvmd_req(struct pm8001_hba_info *pm8001_ha,
 		&ioctl_payload->func_specific,
 		ioctl_payload->wr_length);
 	memset(&nvmd_req, 0, sizeof(nvmd_req));
-	rc = pm8001_tag_alloc(pm8001_ha, &tag);
-	if (rc) {
+
+	ccb = pm8001_ccb_alloc(pm8001_ha, NULL, NULL);
+	if (!ccb) {
 		kfree(fw_control_context);
-		return -EBUSY;
+		return -SAS_QUEUE_FULL;
 	}
-	ccb = &pm8001_ha->ccb_info[tag];
 	ccb->fw_control_context = fw_control_context;
-	ccb->ccb_tag = tag;
-	nvmd_req.tag = cpu_to_le32(tag);
+
+	nvmd_req.tag = cpu_to_le32(ccb->ccb_tag);
 	switch (nvmd_type) {
 	case TWI_DEVICE: {
 		u32 twi_addr, twi_page_size;
@@ -4793,7 +4766,7 @@ int pm8001_chip_set_nvmd_req(struct pm8001_hba_info *pm8001_ha,
 			sizeof(nvmd_req), 0);
 	if (rc) {
 		kfree(fw_control_context);
-		pm8001_tag_free(pm8001_ha, tag);
+		pm8001_ccb_free(pm8001_ha, ccb);
 	}
 	return rc;
 }
@@ -4839,7 +4812,6 @@ pm8001_chip_fw_flash_update_req(struct pm8001_hba_info *pm8001_ha,
 	struct fw_control_info *fw_control;
 	struct fw_control_ex *fw_control_context;
 	int rc;
-	u32 tag;
 	struct pm8001_ccb_info *ccb;
 	void *buffer = pm8001_ha->memoryMap.region[FW_FLASH].virt_ptr;
 	dma_addr_t phys_addr = pm8001_ha->memoryMap.region[FW_FLASH].phys_addr;
@@ -4863,19 +4835,19 @@ pm8001_chip_fw_flash_update_req(struct pm8001_hba_info *pm8001_ha,
 	fw_control_context->virtAddr = buffer;
 	fw_control_context->phys_addr = phys_addr;
 	fw_control_context->len = fw_control->len;
-	rc = pm8001_tag_alloc(pm8001_ha, &tag);
-	if (rc) {
+
+	ccb = pm8001_ccb_alloc(pm8001_ha, NULL, NULL);
+	if (!ccb) {
 		kfree(fw_control_context);
-		return -EBUSY;
+		return -SAS_QUEUE_FULL;
 	}
-	ccb = &pm8001_ha->ccb_info[tag];
 	ccb->fw_control_context = fw_control_context;
-	ccb->ccb_tag = tag;
+
 	rc = pm8001_chip_fw_flash_update_build(pm8001_ha, &flash_update_info,
-		tag);
+					       ccb->ccb_tag);
 	if (rc) {
 		kfree(fw_control_context);
-		pm8001_tag_free(pm8001_ha, tag);
+		pm8001_ccb_free(pm8001_ha, ccb);
 	}
 
 	return rc;
@@ -4967,26 +4939,25 @@ pm8001_chip_set_dev_state_req(struct pm8001_hba_info *pm8001_ha,
 	struct inbound_queue_table *circularQ;
 	struct pm8001_ccb_info *ccb;
 	int rc;
-	u32 tag;
 	u32 opc = OPC_INB_SET_DEVICE_STATE;
+
 	memset(&payload, 0, sizeof(payload));
-	rc = pm8001_tag_alloc(pm8001_ha, &tag);
-	if (rc)
-		return -1;
-	ccb = &pm8001_ha->ccb_info[tag];
-	ccb->ccb_tag = tag;
-	ccb->device = pm8001_dev;
+
+	ccb = pm8001_ccb_alloc(pm8001_ha, pm8001_dev, NULL);
+	if (!ccb)
+		return -SAS_QUEUE_FULL;
+
 	circularQ = &pm8001_ha->inbnd_q_tbl[0];
-	payload.tag = cpu_to_le32(tag);
+	payload.tag = cpu_to_le32(ccb->ccb_tag);
 	payload.device_id = cpu_to_le32(pm8001_dev->device_id);
 	payload.nds = cpu_to_le32(state);
+
 	rc = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &payload,
 			sizeof(payload), 0);
 	if (rc)
-		pm8001_tag_free(pm8001_ha, tag);
+		pm8001_ccb_free(pm8001_ha, ccb);
 
 	return rc;
-
 }
 
 static int
@@ -4996,25 +4967,26 @@ pm8001_chip_sas_re_initialization(struct pm8001_hba_info *pm8001_ha)
 	struct inbound_queue_table *circularQ;
 	struct pm8001_ccb_info *ccb;
 	int rc;
-	u32 tag;
 	u32 opc = OPC_INB_SAS_RE_INITIALIZE;
+
 	memset(&payload, 0, sizeof(payload));
-	rc = pm8001_tag_alloc(pm8001_ha, &tag);
-	if (rc)
-		return -ENOMEM;
-	ccb = &pm8001_ha->ccb_info[tag];
-	ccb->ccb_tag = tag;
+
+	ccb = pm8001_ccb_alloc(pm8001_ha, NULL, NULL);
+	if (!ccb)
+		return -SAS_QUEUE_FULL;
+
 	circularQ = &pm8001_ha->inbnd_q_tbl[0];
-	payload.tag = cpu_to_le32(tag);
+	payload.tag = cpu_to_le32(ccb->ccb_tag);
 	payload.SSAHOLT = cpu_to_le32(0xd << 25);
 	payload.sata_hol_tmo = cpu_to_le32(80);
 	payload.open_reject_cmdretries_data_retries = cpu_to_le32(0xff00ff);
+
 	rc = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &payload,
 			sizeof(payload), 0);
 	if (rc)
-		pm8001_tag_free(pm8001_ha, tag);
-	return rc;
+		pm8001_ccb_free(pm8001_ha, ccb);
 
+	return rc;
 }
 
 const struct pm8001_dispatch pm8001_8001_dispatch = {
diff --git a/drivers/scsi/pm8001/pm8001_sas.c b/drivers/scsi/pm8001/pm8001_sas.c
index 1e60ad82635e..52507bc8f963 100644
--- a/drivers/scsi/pm8001/pm8001_sas.c
+++ b/drivers/scsi/pm8001/pm8001_sas.c
@@ -74,7 +74,7 @@ void pm8001_tag_free(struct pm8001_hba_info *pm8001_ha, u32 tag)
   * @pm8001_ha: our hba struct
   * @tag_out: the found empty tag .
   */
-inline int pm8001_tag_alloc(struct pm8001_hba_info *pm8001_ha, u32 *tag_out)
+int pm8001_tag_alloc(struct pm8001_hba_info *pm8001_ha, u32 *tag_out)
 {
 	unsigned int tag;
 	void *bitmap = pm8001_ha->tags;
@@ -382,7 +382,7 @@ static int pm8001_task_exec(struct sas_task *task,
 	struct pm8001_port *port = NULL;
 	struct sas_task *t = task;
 	struct pm8001_ccb_info *ccb;
-	u32 tag = 0xdeadbeef, rc = 0, n_elem = 0;
+	u32 rc = 0, n_elem = 0;
 	unsigned long flags = 0;
 	enum sas_protocol task_proto = t->task_proto;
 
@@ -426,10 +426,12 @@ static int pm8001_task_exec(struct sas_task *task,
 				continue;
 			}
 		}
-		rc = pm8001_tag_alloc(pm8001_ha, &tag);
-		if (rc)
+
+		ccb = pm8001_ccb_alloc(pm8001_ha, pm8001_dev, t);
+		if (!ccb) {
+			rc = -SAS_QUEUE_FULL;
 			goto err_out;
-		ccb = &pm8001_ha->ccb_info[tag];
+		}
 
 		if (!sas_protocol_ata(task_proto)) {
 			if (t->num_scatter) {
@@ -439,7 +441,7 @@ static int pm8001_task_exec(struct sas_task *task,
 					t->data_dir);
 				if (!n_elem) {
 					rc = -ENOMEM;
-					goto err_out_tag;
+					goto err_out_ccb;
 				}
 			}
 		} else {
@@ -448,9 +450,7 @@ static int pm8001_task_exec(struct sas_task *task,
 
 		t->lldd_task = ccb;
 		ccb->n_elem = n_elem;
-		ccb->ccb_tag = tag;
-		ccb->task = t;
-		ccb->device = pm8001_dev;
+
 		switch (task_proto) {
 		case SAS_PROTOCOL_SMP:
 			atomic_inc(&pm8001_dev->running_req);
@@ -479,15 +479,15 @@ static int pm8001_task_exec(struct sas_task *task,
 		if (rc) {
 			pm8001_dbg(pm8001_ha, IO, "rc is %x\n", rc);
 			atomic_dec(&pm8001_dev->running_req);
-			goto err_out_tag;
+			goto err_out_ccb;
 		}
 		/* TODO: select normal or high priority */
 	} while (0);
 	rc = 0;
 	goto out_done;
 
-err_out_tag:
-	pm8001_tag_free(pm8001_ha, tag);
+err_out_ccb:
+	pm8001_ccb_free(pm8001_ha, ccb);
 err_out:
 	dev_printk(KERN_ERR, pm8001_ha->dev, "pm8001 exec failed[%d]!\n", rc);
 	if (!sas_protocol_ata(task_proto))
@@ -558,10 +558,7 @@ void pm8001_ccb_task_free(struct pm8001_hba_info *pm8001_ha,
 	}
 
 	task->lldd_task = NULL;
-	ccb->task = NULL;
-	ccb->ccb_tag = PM8001_INVALID_TAG;
-	ccb->open_retry = 0;
-	pm8001_tag_free(pm8001_ha, ccb_idx);
+	pm8001_ccb_free(pm8001_ha, ccb);
 }
 
 /**
@@ -812,7 +809,6 @@ pm8001_exec_internal_task_abort(struct pm8001_hba_info *pm8001_ha,
 	u32 task_tag)
 {
 	int res, retry;
-	u32 ccb_tag;
 	struct pm8001_ccb_info *ccb;
 	struct sas_task *task = NULL;
 
@@ -828,23 +824,19 @@ pm8001_exec_internal_task_abort(struct pm8001_hba_info *pm8001_ha,
 		task->slow_task->timer.expires = jiffies + PM8001_TASK_TIMEOUT * HZ;
 		add_timer(&task->slow_task->timer);
 
-		res = pm8001_tag_alloc(pm8001_ha, &ccb_tag);
-		if (res)
+		ccb = pm8001_ccb_alloc(pm8001_ha, pm8001_dev, task);
+		if (!ccb) {
+			res = -SAS_QUEUE_FULL;
 			break;
-
-		ccb = &pm8001_ha->ccb_info[ccb_tag];
-		ccb->device = pm8001_dev;
-		ccb->ccb_tag = ccb_tag;
-		ccb->task = task;
-		ccb->n_elem = 0;
+		}
 
 		res = PM8001_CHIP_DISP->task_abort(pm8001_ha,
-			pm8001_dev, flag, task_tag, ccb_tag);
+			pm8001_dev, flag, task_tag, ccb->ccb_tag);
 		if (res) {
 			del_timer(&task->slow_task->timer);
 			pm8001_dbg(pm8001_ha, FAIL,
 				   "Executing internal task failed\n");
-			pm8001_tag_free(pm8001_ha, ccb_tag);
+			pm8001_ccb_free(pm8001_ha, ccb);
 			break;
 		}
 
diff --git a/drivers/scsi/pm8001/pm8001_sas.h b/drivers/scsi/pm8001/pm8001_sas.h
index 1791cdf30276..824ada7f6a3f 100644
--- a/drivers/scsi/pm8001/pm8001_sas.h
+++ b/drivers/scsi/pm8001/pm8001_sas.h
@@ -740,6 +740,53 @@ extern const struct attribute_group *pm8001_host_groups[];
 
 #define PM8001_INVALID_TAG	((u32)-1)
 
+/*
+ * Allocate a new tag and return the corresponding ccb after initializing it.
+ */
+static inline struct pm8001_ccb_info *
+pm8001_ccb_alloc(struct pm8001_hba_info *pm8001_ha,
+		 struct pm8001_device *dev, struct sas_task *task)
+{
+	struct pm8001_ccb_info *ccb;
+	u32 tag;
+
+	if (pm8001_tag_alloc(pm8001_ha, &tag)) {
+		pm8001_dbg(pm8001_ha, FAIL, "Failed to allocate a tag\n");
+		return NULL;
+	}
+
+	ccb = &pm8001_ha->ccb_info[tag];
+	ccb->task = task;
+	ccb->n_elem = 0;
+	ccb->ccb_tag = tag;
+	ccb->device = dev;
+	ccb->fw_control_context = NULL;
+	ccb->open_retry = 0;
+
+	return ccb;
+}
+
+/*
+ * Free the tag of an initialized ccb.
+ */
+static inline void pm8001_ccb_free(struct pm8001_hba_info *pm8001_ha,
+				   struct pm8001_ccb_info *ccb)
+{
+	u32 tag = ccb->ccb_tag;
+
+	/*
+	 * Cleanup the ccb to make sure that a manual scan of the adapter
+	 * ccb_info array can detect ccb's that are in use.
+	 * C.f. pm8001_open_reject_retry()
+	 */
+	ccb->task = NULL;
+	ccb->ccb_tag = PM8001_INVALID_TAG;
+	ccb->device = NULL;
+	ccb->fw_control_context = NULL;
+
+	pm8001_tag_free(pm8001_ha, tag);
+}
+
 static inline void
 pm8001_ccb_task_free_done(struct pm8001_hba_info *pm8001_ha,
 			struct sas_task *task, struct pm8001_ccb_info *ccb,
diff --git a/drivers/scsi/pm8001/pm80xx_hwi.c b/drivers/scsi/pm8001/pm80xx_hwi.c
index 4419fdb0db78..57ea933dab66 100644
--- a/drivers/scsi/pm8001/pm80xx_hwi.c
+++ b/drivers/scsi/pm8001/pm80xx_hwi.c
@@ -1767,8 +1767,6 @@ pm80xx_chip_interrupt_disable(struct pm8001_hba_info *pm8001_ha, u8 vec)
 static void pm80xx_send_abort_all(struct pm8001_hba_info *pm8001_ha,
 		struct pm8001_device *pm8001_ha_dev)
 {
-	int res;
-	u32 ccb_tag;
 	struct pm8001_ccb_info *ccb;
 	struct sas_task *task = NULL;
 	struct task_abort_req task_abort;
@@ -1790,31 +1788,25 @@ static void pm80xx_send_abort_all(struct pm8001_hba_info *pm8001_ha,
 
 	task->task_done = pm8001_task_done;
 
-	res = pm8001_tag_alloc(pm8001_ha, &ccb_tag);
-	if (res) {
+	ccb = pm8001_ccb_alloc(pm8001_ha, pm8001_ha_dev, task);
+	if (!ccb) {
 		sas_free_task(task);
 		return;
 	}
 
-	ccb = &pm8001_ha->ccb_info[ccb_tag];
-	ccb->device = pm8001_ha_dev;
-	ccb->ccb_tag = ccb_tag;
-	ccb->task = task;
-	ccb->n_elem = 0;
-
 	circularQ = &pm8001_ha->inbnd_q_tbl[0];
 
 	memset(&task_abort, 0, sizeof(task_abort));
 	task_abort.abort_all = cpu_to_le32(1);
 	task_abort.device_id = cpu_to_le32(pm8001_ha_dev->device_id);
-	task_abort.tag = cpu_to_le32(ccb_tag);
+	task_abort.tag = cpu_to_le32(ccb->ccb_tag);
 
 	ret = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &task_abort,
 			sizeof(task_abort), 0);
 	pm8001_dbg(pm8001_ha, FAIL, "Executing abort task end\n");
 	if (ret) {
 		sas_free_task(task);
-		pm8001_tag_free(pm8001_ha, ccb_tag);
+		pm8001_ccb_free(pm8001_ha, ccb);
 	}
 }
 
@@ -1823,7 +1815,6 @@ static void pm80xx_send_read_log(struct pm8001_hba_info *pm8001_ha,
 {
 	struct sata_start_req sata_cmd;
 	int res;
-	u32 ccb_tag;
 	struct pm8001_ccb_info *ccb;
 	struct sas_task *task = NULL;
 	struct host_to_dev_fis fis;
@@ -1839,20 +1830,13 @@ static void pm80xx_send_read_log(struct pm8001_hba_info *pm8001_ha,
 	}
 	task->task_done = pm8001_task_done;
 
-	res = pm8001_tag_alloc(pm8001_ha, &ccb_tag);
-	if (res) {
-		sas_free_task(task);
-		pm8001_dbg(pm8001_ha, FAIL, "cannot allocate tag !!!\n");
-		return;
-	}
-
-	/* allocate domain device by ourselves as libsas
-	 * is not going to provide any
-	*/
+	/*
+	 * Allocate domain device by ourselves as libsas is not going to
+	 * provide any.
+	 */
 	dev = kzalloc(sizeof(struct domain_device), GFP_ATOMIC);
 	if (!dev) {
 		sas_free_task(task);
-		pm8001_tag_free(pm8001_ha, ccb_tag);
 		pm8001_dbg(pm8001_ha, FAIL,
 			   "Domain device cannot be allocated\n");
 		return;
@@ -1861,11 +1845,13 @@ static void pm80xx_send_read_log(struct pm8001_hba_info *pm8001_ha,
 	task->dev = dev;
 	task->dev->lldd_dev = pm8001_ha_dev;
 
-	ccb = &pm8001_ha->ccb_info[ccb_tag];
-	ccb->device = pm8001_ha_dev;
-	ccb->ccb_tag = ccb_tag;
-	ccb->task = task;
-	ccb->n_elem = 0;
+	ccb = pm8001_ccb_alloc(pm8001_ha, pm8001_ha_dev, task);
+	if (!ccb) {
+		sas_free_task(task);
+		kfree(dev);
+		return;
+	}
+
 	pm8001_ha_dev->id |= NCQ_READ_LOG_FLAG;
 	pm8001_ha_dev->id |= NCQ_2ND_RLE_FLAG;
 
@@ -1880,7 +1866,7 @@ static void pm80xx_send_read_log(struct pm8001_hba_info *pm8001_ha,
 	fis.lbal = 0x10;
 	fis.sector_count = 0x1;
 
-	sata_cmd.tag = cpu_to_le32(ccb_tag);
+	sata_cmd.tag = cpu_to_le32(ccb->ccb_tag);
 	sata_cmd.device_id = cpu_to_le32(pm8001_ha_dev->device_id);
 	sata_cmd.ncqtag_atap_dir_m_dad = cpu_to_le32(((0x1 << 7) | (0x5 << 9)));
 	memcpy(&sata_cmd.sata_fis, &fis, sizeof(struct host_to_dev_fis));
@@ -1890,7 +1876,7 @@ static void pm80xx_send_read_log(struct pm8001_hba_info *pm8001_ha,
 	pm8001_dbg(pm8001_ha, FAIL, "Executing read log end\n");
 	if (res) {
 		sas_free_task(task);
-		pm8001_tag_free(pm8001_ha, ccb_tag);
+		pm8001_ccb_free(pm8001_ha, ccb);
 		kfree(dev);
 	}
 }
@@ -4834,7 +4820,7 @@ static int pm80xx_chip_reg_dev_req(struct pm8001_hba_info *pm8001_ha,
 	u32 stp_sspsmp_sata = 0x4;
 	struct inbound_queue_table *circularQ;
 	u32 linkrate, phy_id;
-	int rc, tag = 0xdeadbeef;
+	int rc;
 	struct pm8001_ccb_info *ccb;
 	u8 retryFlag = 0x1;
 	u16 firstBurstSize = 0;
@@ -4845,13 +4831,11 @@ static int pm80xx_chip_reg_dev_req(struct pm8001_hba_info *pm8001_ha,
 	circularQ = &pm8001_ha->inbnd_q_tbl[0];
 
 	memset(&payload, 0, sizeof(payload));
-	rc = pm8001_tag_alloc(pm8001_ha, &tag);
-	if (rc)
-		return rc;
-	ccb = &pm8001_ha->ccb_info[tag];
-	ccb->device = pm8001_dev;
-	ccb->ccb_tag = tag;
-	payload.tag = cpu_to_le32(tag);
+	ccb = pm8001_ccb_alloc(pm8001_ha, pm8001_dev, NULL);
+	if (!ccb)
+		return -SAS_QUEUE_FULL;
+
+	payload.tag = cpu_to_le32(ccb->ccb_tag);
 
 	if (flag == 1) {
 		stp_sspsmp_sata = 0x02; /*direct attached sata */
@@ -4888,7 +4872,7 @@ static int pm80xx_chip_reg_dev_req(struct pm8001_hba_info *pm8001_ha,
 	rc = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &payload,
 			sizeof(payload), 0);
 	if (rc)
-		pm8001_tag_free(pm8001_ha, tag);
+		pm8001_ccb_free(pm8001_ha, ccb);
 
 	return rc;
 }
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 65+ messages in thread

* [PATCH v4 27/31] scsi: pm8001: Simplify pm8001_mpi_build_cmd() interface
  2022-02-17 13:29 [PATCH v4 00/31] libsas and pm8001 fixes Damien Le Moal
                   ` (25 preceding siblings ...)
  2022-02-17 13:29 ` [PATCH v4 26/31] scsi: pm8001: Introduce ccb alloc/free helpers Damien Le Moal
@ 2022-02-17 13:29 ` Damien Le Moal
  2022-02-17 19:46   ` Jinpu Wang
  2022-02-17 13:29 ` [PATCH v4 28/31] scsi: pm8001: Simplify pm8001_task_exec() Damien Le Moal
                   ` (3 subsequent siblings)
  30 siblings, 1 reply; 65+ messages in thread
From: Damien Le Moal @ 2022-02-17 13:29 UTC (permalink / raw)
  To: linux-scsi, Martin K . Petersen, Jack Wang, John Garry
  Cc: Xiang Chen, Jason Yan, Luo Jiaxing

There is no need to pass a pointer to a struct inbound_queue_table to
pm8001_mpi_build_cmd(). Passing the start index in the inbound queue
table of the adapter is enough. This change allows avoiding the
declaration of a struct inbound_queue_table pointer (circularQ
variables) in many functions, simplifying the code.

While at it, blank lines are added i(e.g. after local variable
declarations) to make the code more readable.

Signed-off-by: Damien Le Moal <damien.lemoal@opensource.wdc.com>
---
 drivers/scsi/pm8001/pm8001_hwi.c | 154 +++++++++++--------------------
 drivers/scsi/pm8001/pm8001_sas.h |   3 +-
 drivers/scsi/pm8001/pm80xx_hwi.c |  98 +++++++-------------
 3 files changed, 89 insertions(+), 166 deletions(-)

diff --git a/drivers/scsi/pm8001/pm8001_hwi.c b/drivers/scsi/pm8001/pm8001_hwi.c
index 699fecc09267..03bcf7497bf9 100644
--- a/drivers/scsi/pm8001/pm8001_hwi.c
+++ b/drivers/scsi/pm8001/pm8001_hwi.c
@@ -1309,21 +1309,20 @@ int pm8001_mpi_msg_free_get(struct inbound_queue_table *circularQ,
  * pm8001_mpi_build_cmd- build the message queue for transfer, update the PI to
  * FW to tell the fw to get this message from IOMB.
  * @pm8001_ha: our hba card information
- * @circularQ: the inbound queue we want to transfer to HBA.
+ * @q_index: the index in the inbound queue we want to transfer to HBA.
  * @opCode: the operation code represents commands which LLDD and fw recognized.
  * @payload: the command payload of each operation command.
  * @nb: size in bytes of the command payload
  * @responseQueue: queue to interrupt on w/ command response (if any)
  */
 int pm8001_mpi_build_cmd(struct pm8001_hba_info *pm8001_ha,
-			 struct inbound_queue_table *circularQ,
-			 u32 opCode, void *payload, size_t nb,
+			 u32 q_index, u32 opCode, void *payload, size_t nb,
 			 u32 responseQueue)
 {
 	u32 Header = 0, hpriority = 0, bc = 1, category = 0x02;
 	void *pMessage;
 	unsigned long flags;
-	int q_index = circularQ - pm8001_ha->inbnd_q_tbl;
+	struct inbound_queue_table *circularQ = &pm8001_ha->inbnd_q_tbl[q_index];
 	int rv;
 	u32 htag = le32_to_cpu(*(__le32 *)payload);
 
@@ -1752,7 +1751,6 @@ static void pm8001_send_abort_all(struct pm8001_hba_info *pm8001_ha,
 	struct pm8001_ccb_info *ccb;
 	struct sas_task *task = NULL;
 	struct task_abort_req task_abort;
-	struct inbound_queue_table *circularQ;
 	u32 opc = OPC_INB_SATA_ABORT;
 	int ret;
 
@@ -1775,15 +1773,13 @@ static void pm8001_send_abort_all(struct pm8001_hba_info *pm8001_ha,
 		return;
 	}
 
-	circularQ = &pm8001_ha->inbnd_q_tbl[0];
-
 	memset(&task_abort, 0, sizeof(task_abort));
 	task_abort.abort_all = cpu_to_le32(1);
 	task_abort.device_id = cpu_to_le32(pm8001_ha_dev->device_id);
 	task_abort.tag = cpu_to_le32(ccb->ccb_tag);
 
-	ret = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &task_abort,
-			sizeof(task_abort), 0);
+	ret = pm8001_mpi_build_cmd(pm8001_ha, 0, opc, &task_abort,
+				   sizeof(task_abort), 0);
 	if (ret) {
 		sas_free_task(task);
 		pm8001_ccb_free(pm8001_ha, ccb);
@@ -1799,11 +1795,9 @@ static void pm8001_send_read_log(struct pm8001_hba_info *pm8001_ha,
 	struct sas_task *task = NULL;
 	struct host_to_dev_fis fis;
 	struct domain_device *dev;
-	struct inbound_queue_table *circularQ;
 	u32 opc = OPC_INB_SATA_HOST_OPSTART;
 
 	task = sas_alloc_slow_task(GFP_ATOMIC);
-
 	if (!task) {
 		pm8001_dbg(pm8001_ha, FAIL, "cannot allocate task !!!\n");
 		return;
@@ -1834,9 +1828,6 @@ static void pm8001_send_read_log(struct pm8001_hba_info *pm8001_ha,
 	pm8001_ha_dev->id |= NCQ_READ_LOG_FLAG;
 	pm8001_ha_dev->id |= NCQ_2ND_RLE_FLAG;
 
-	memset(&sata_cmd, 0, sizeof(sata_cmd));
-	circularQ = &pm8001_ha->inbnd_q_tbl[0];
-
 	/* construct read log FIS */
 	memset(&fis, 0, sizeof(struct host_to_dev_fis));
 	fis.fis_type = 0x27;
@@ -1845,13 +1836,14 @@ static void pm8001_send_read_log(struct pm8001_hba_info *pm8001_ha,
 	fis.lbal = 0x10;
 	fis.sector_count = 0x1;
 
+	memset(&sata_cmd, 0, sizeof(sata_cmd));
 	sata_cmd.tag = cpu_to_le32(ccb->ccb_tag);
 	sata_cmd.device_id = cpu_to_le32(pm8001_ha_dev->device_id);
 	sata_cmd.ncqtag_atap_dir_m = cpu_to_le32((0x1 << 7) | (0x5 << 9));
 	memcpy(&sata_cmd.sata_fis, &fis, sizeof(struct host_to_dev_fis));
 
-	res = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &sata_cmd,
-			sizeof(sata_cmd), 0);
+	res = pm8001_mpi_build_cmd(pm8001_ha, 0, opc, &sata_cmd,
+				   sizeof(sata_cmd), 0);
 	if (res) {
 		sas_free_task(task);
 		pm8001_ccb_free(pm8001_ha, ccb);
@@ -3261,17 +3253,14 @@ static void pm8001_hw_event_ack_req(struct pm8001_hba_info *pm8001_ha,
 	struct hw_event_ack_req	 payload;
 	u32 opc = OPC_INB_SAS_HW_EVENT_ACK;
 
-	struct inbound_queue_table *circularQ;
-
 	memset((u8 *)&payload, 0, sizeof(payload));
-	circularQ = &pm8001_ha->inbnd_q_tbl[Qnum];
 	payload.tag = cpu_to_le32(1);
 	payload.sea_phyid_portid = cpu_to_le32(((SEA & 0xFFFF) << 8) |
 		((phyId & 0x0F) << 4) | (port_id & 0x0F));
 	payload.param0 = cpu_to_le32(param0);
 	payload.param1 = cpu_to_le32(param1);
-	pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &payload,
-			sizeof(payload), 0);
+
+	pm8001_mpi_build_cmd(pm8001_ha, Qnum, opc, &payload, sizeof(payload), 0);
 }
 
 static int pm8001_chip_phy_ctl_req(struct pm8001_hba_info *pm8001_ha,
@@ -4103,7 +4092,6 @@ static int pm8001_chip_smp_req(struct pm8001_hba_info *pm8001_ha,
 	u32 req_len, resp_len;
 	struct smp_req smp_cmd;
 	u32 opc;
-	struct inbound_queue_table *circularQ;
 
 	memset(&smp_cmd, 0, sizeof(smp_cmd));
 	/*
@@ -4129,7 +4117,6 @@ static int pm8001_chip_smp_req(struct pm8001_hba_info *pm8001_ha,
 	}
 
 	opc = OPC_INB_SMP_REQUEST;
-	circularQ = &pm8001_ha->inbnd_q_tbl[0];
 	smp_cmd.tag = cpu_to_le32(ccb->ccb_tag);
 	smp_cmd.long_smp_req.long_req_addr =
 		cpu_to_le64((u64)sg_dma_address(&task->smp_task.smp_req));
@@ -4140,8 +4127,8 @@ static int pm8001_chip_smp_req(struct pm8001_hba_info *pm8001_ha,
 	smp_cmd.long_smp_req.long_resp_size =
 		cpu_to_le32((u32)sg_dma_len(&task->smp_task.smp_resp)-4);
 	build_smp_cmd(pm8001_dev->device_id, smp_cmd.tag, &smp_cmd);
-	rc = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc,
-			&smp_cmd, sizeof(smp_cmd), 0);
+	rc = pm8001_mpi_build_cmd(pm8001_ha, 0, opc,
+				  &smp_cmd, sizeof(smp_cmd), 0);
 	if (rc)
 		goto err_out_2;
 
@@ -4169,9 +4156,7 @@ static int pm8001_chip_ssp_io_req(struct pm8001_hba_info *pm8001_ha,
 	struct pm8001_device *pm8001_dev = dev->lldd_dev;
 	struct ssp_ini_io_start_req ssp_cmd;
 	u32 tag = ccb->ccb_tag;
-	int ret;
 	u64 phys_addr;
-	struct inbound_queue_table *circularQ;
 	u32 opc = OPC_INB_SSPINIIOSTART;
 	memset(&ssp_cmd, 0, sizeof(ssp_cmd));
 	memcpy(ssp_cmd.ssp_iu.lun, task->ssp_task.LUN, 8);
@@ -4187,7 +4172,6 @@ static int pm8001_chip_ssp_io_req(struct pm8001_hba_info *pm8001_ha,
 	ssp_cmd.ssp_iu.efb_prio_attr |= (task->ssp_task.task_attr & 7);
 	memcpy(ssp_cmd.ssp_iu.cdb, task->ssp_task.cmd->cmnd,
 	       task->ssp_task.cmd->cmd_len);
-	circularQ = &pm8001_ha->inbnd_q_tbl[0];
 
 	/* fill in PRD (scatter/gather) table, if any */
 	if (task->num_scatter > 1) {
@@ -4208,9 +4192,9 @@ static int pm8001_chip_ssp_io_req(struct pm8001_hba_info *pm8001_ha,
 		ssp_cmd.len = cpu_to_le32(task->total_xfer_len);
 		ssp_cmd.esgl = 0;
 	}
-	ret = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &ssp_cmd,
-			sizeof(ssp_cmd), 0);
-	return ret;
+
+	return pm8001_mpi_build_cmd(pm8001_ha, 0, opc, &ssp_cmd,
+				    sizeof(ssp_cmd), 0);
 }
 
 static int pm8001_chip_sata_req(struct pm8001_hba_info *pm8001_ha,
@@ -4220,17 +4204,15 @@ static int pm8001_chip_sata_req(struct pm8001_hba_info *pm8001_ha,
 	struct domain_device *dev = task->dev;
 	struct pm8001_device *pm8001_ha_dev = dev->lldd_dev;
 	u32 tag = ccb->ccb_tag;
-	int ret;
 	struct sata_start_req sata_cmd;
 	u32 hdr_tag, ncg_tag = 0;
 	u64 phys_addr;
 	u32 ATAP = 0x0;
 	u32 dir;
-	struct inbound_queue_table *circularQ;
 	unsigned long flags;
 	u32  opc = OPC_INB_SATA_HOST_OPSTART;
+
 	memset(&sata_cmd, 0, sizeof(sata_cmd));
-	circularQ = &pm8001_ha->inbnd_q_tbl[0];
 
 	if (task->data_dir == DMA_NONE && !task->ata_task.use_ncq) {
 		ATAP = 0x04;  /* no data*/
@@ -4316,9 +4298,8 @@ static int pm8001_chip_sata_req(struct pm8001_hba_info *pm8001_ha,
 		}
 	}
 
-	ret = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &sata_cmd,
-			sizeof(sata_cmd), 0);
-	return ret;
+	return pm8001_mpi_build_cmd(pm8001_ha, 0, opc, &sata_cmd,
+				    sizeof(sata_cmd), 0);
 }
 
 /**
@@ -4330,11 +4311,9 @@ static int
 pm8001_chip_phy_start_req(struct pm8001_hba_info *pm8001_ha, u8 phy_id)
 {
 	struct phy_start_req payload;
-	struct inbound_queue_table *circularQ;
-	int ret;
 	u32 tag = 0x01;
 	u32 opcode = OPC_INB_PHYSTART;
-	circularQ = &pm8001_ha->inbnd_q_tbl[0];
+
 	memset(&payload, 0, sizeof(payload));
 	payload.tag = cpu_to_le32(tag);
 	/*
@@ -4351,9 +4330,9 @@ pm8001_chip_phy_start_req(struct pm8001_hba_info *pm8001_ha, u8 phy_id)
 	memcpy(payload.sas_identify.sas_addr,
 		pm8001_ha->sas_addr, SAS_ADDR_SIZE);
 	payload.sas_identify.phy_id = phy_id;
-	ret = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opcode, &payload,
-			sizeof(payload), 0);
-	return ret;
+
+	return pm8001_mpi_build_cmd(pm8001_ha, 0, opcode, &payload,
+				    sizeof(payload), 0);
 }
 
 /**
@@ -4365,17 +4344,15 @@ static int pm8001_chip_phy_stop_req(struct pm8001_hba_info *pm8001_ha,
 				    u8 phy_id)
 {
 	struct phy_stop_req payload;
-	struct inbound_queue_table *circularQ;
-	int ret;
 	u32 tag = 0x01;
 	u32 opcode = OPC_INB_PHYSTOP;
-	circularQ = &pm8001_ha->inbnd_q_tbl[0];
+
 	memset(&payload, 0, sizeof(payload));
 	payload.tag = cpu_to_le32(tag);
 	payload.phy_id = cpu_to_le32(phy_id);
-	ret = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opcode, &payload,
-			sizeof(payload), 0);
-	return ret;
+
+	return pm8001_mpi_build_cmd(pm8001_ha, 0, opcode, &payload,
+				    sizeof(payload), 0);
 }
 
 /*
@@ -4387,7 +4364,6 @@ static int pm8001_chip_reg_dev_req(struct pm8001_hba_info *pm8001_ha,
 	struct reg_dev_req payload;
 	u32	opc;
 	u32 stp_sspsmp_sata = 0x4;
-	struct inbound_queue_table *circularQ;
 	u32 linkrate, phy_id;
 	int rc;
 	struct pm8001_ccb_info *ccb;
@@ -4397,7 +4373,6 @@ static int pm8001_chip_reg_dev_req(struct pm8001_hba_info *pm8001_ha,
 	struct domain_device *dev = pm8001_dev->sas_device;
 	struct domain_device *parent_dev = dev->parent;
 	struct pm8001_port *port = dev->port->lldd_port;
-	circularQ = &pm8001_ha->inbnd_q_tbl[0];
 
 	memset(&payload, 0, sizeof(payload));
 	ccb = pm8001_ccb_alloc(pm8001_ha, pm8001_dev, NULL);
@@ -4431,8 +4406,9 @@ static int pm8001_chip_reg_dev_req(struct pm8001_hba_info *pm8001_ha,
 		cpu_to_le32(ITNT | (firstBurstSize * 0x10000));
 	memcpy(payload.sas_addr, pm8001_dev->sas_device->sas_addr,
 		SAS_ADDR_SIZE);
-	rc = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &payload,
-			sizeof(payload), 0);
+
+	rc = pm8001_mpi_build_cmd(pm8001_ha, 0, opc, &payload,
+				  sizeof(payload), 0);
 	if (rc)
 		pm8001_ccb_free(pm8001_ha, ccb);
 
@@ -4447,18 +4423,15 @@ int pm8001_chip_dereg_dev_req(struct pm8001_hba_info *pm8001_ha,
 {
 	struct dereg_dev_req payload;
 	u32 opc = OPC_INB_DEREG_DEV_HANDLE;
-	int ret;
-	struct inbound_queue_table *circularQ;
 
-	circularQ = &pm8001_ha->inbnd_q_tbl[0];
 	memset(&payload, 0, sizeof(payload));
 	payload.tag = cpu_to_le32(1);
 	payload.device_id = cpu_to_le32(device_id);
 	pm8001_dbg(pm8001_ha, MSG, "unregister device device_id = %d\n",
 		   device_id);
-	ret = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &payload,
-			sizeof(payload), 0);
-	return ret;
+
+	return pm8001_mpi_build_cmd(pm8001_ha, 0, opc, &payload,
+				    sizeof(payload), 0);
 }
 
 /**
@@ -4471,17 +4444,15 @@ static int pm8001_chip_phy_ctl_req(struct pm8001_hba_info *pm8001_ha,
 	u32 phyId, u32 phy_op)
 {
 	struct local_phy_ctl_req payload;
-	struct inbound_queue_table *circularQ;
-	int ret;
 	u32 opc = OPC_INB_LOCAL_PHY_CONTROL;
+
 	memset(&payload, 0, sizeof(payload));
-	circularQ = &pm8001_ha->inbnd_q_tbl[0];
 	payload.tag = cpu_to_le32(1);
 	payload.phyop_phyid =
 		cpu_to_le32(((phy_op & 0xff) << 8) | (phyId & 0x0F));
-	ret = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &payload,
-			sizeof(payload), 0);
-	return ret;
+
+	return pm8001_mpi_build_cmd(pm8001_ha, 0, opc, &payload,
+				    sizeof(payload), 0);
 }
 
 static u32 pm8001_chip_is_our_interrupt(struct pm8001_hba_info *pm8001_ha)
@@ -4519,9 +4490,7 @@ static int send_task_abort(struct pm8001_hba_info *pm8001_ha, u32 opc,
 	u32 dev_id, u8 flag, u32 task_tag, u32 cmd_tag)
 {
 	struct task_abort_req task_abort;
-	struct inbound_queue_table *circularQ;
-	int ret;
-	circularQ = &pm8001_ha->inbnd_q_tbl[0];
+
 	memset(&task_abort, 0, sizeof(task_abort));
 	if (ABORT_SINGLE == (flag & ABORT_MASK)) {
 		task_abort.abort_all = 0;
@@ -4533,9 +4502,9 @@ static int send_task_abort(struct pm8001_hba_info *pm8001_ha, u32 opc,
 		task_abort.device_id = cpu_to_le32(dev_id);
 		task_abort.tag = cpu_to_le32(cmd_tag);
 	}
-	ret = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &task_abort,
-			sizeof(task_abort), 0);
-	return ret;
+
+	return pm8001_mpi_build_cmd(pm8001_ha, 0, opc, &task_abort,
+				    sizeof(task_abort), 0);
 }
 
 /*
@@ -4575,9 +4544,7 @@ int pm8001_chip_ssp_tm_req(struct pm8001_hba_info *pm8001_ha,
 	struct domain_device *dev = task->dev;
 	struct pm8001_device *pm8001_dev = dev->lldd_dev;
 	u32 opc = OPC_INB_SSPINITMSTART;
-	struct inbound_queue_table *circularQ;
 	struct ssp_ini_tm_start_req sspTMCmd;
-	int ret;
 
 	memset(&sspTMCmd, 0, sizeof(sspTMCmd));
 	sspTMCmd.device_id = cpu_to_le32(pm8001_dev->device_id);
@@ -4587,10 +4554,9 @@ int pm8001_chip_ssp_tm_req(struct pm8001_hba_info *pm8001_ha,
 	sspTMCmd.tag = cpu_to_le32(ccb->ccb_tag);
 	if (pm8001_ha->chip_id != chip_8001)
 		sspTMCmd.ds_ads_m = cpu_to_le32(0x08);
-	circularQ = &pm8001_ha->inbnd_q_tbl[0];
-	ret = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &sspTMCmd,
-			sizeof(sspTMCmd), 0);
-	return ret;
+
+	return pm8001_mpi_build_cmd(pm8001_ha, 0, opc, &sspTMCmd,
+				    sizeof(sspTMCmd), 0);
 }
 
 int pm8001_chip_get_nvmd_req(struct pm8001_hba_info *pm8001_ha,
@@ -4600,7 +4566,6 @@ int pm8001_chip_get_nvmd_req(struct pm8001_hba_info *pm8001_ha,
 	u32 nvmd_type;
 	int rc;
 	struct pm8001_ccb_info *ccb;
-	struct inbound_queue_table *circularQ;
 	struct get_nvm_data_req nvmd_req;
 	struct fw_control_ex *fw_control_context;
 	struct pm8001_ioctl_payload *ioctl_payload = payload;
@@ -4611,7 +4576,6 @@ int pm8001_chip_get_nvmd_req(struct pm8001_hba_info *pm8001_ha,
 		return -ENOMEM;
 	fw_control_context->usrAddr = (u8 *)ioctl_payload->func_specific;
 	fw_control_context->len = ioctl_payload->rd_length;
-	circularQ = &pm8001_ha->inbnd_q_tbl[0];
 	memset(&nvmd_req, 0, sizeof(nvmd_req));
 
 	ccb = pm8001_ccb_alloc(pm8001_ha, NULL, NULL);
@@ -4678,8 +4642,9 @@ int pm8001_chip_get_nvmd_req(struct pm8001_hba_info *pm8001_ha,
 	default:
 		break;
 	}
-	rc = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &nvmd_req,
-			sizeof(nvmd_req), 0);
+
+	rc = pm8001_mpi_build_cmd(pm8001_ha, 0, opc, &nvmd_req,
+				  sizeof(nvmd_req), 0);
 	if (rc) {
 		kfree(fw_control_context);
 		pm8001_ccb_free(pm8001_ha, ccb);
@@ -4694,7 +4659,6 @@ int pm8001_chip_set_nvmd_req(struct pm8001_hba_info *pm8001_ha,
 	u32 nvmd_type;
 	int rc;
 	struct pm8001_ccb_info *ccb;
-	struct inbound_queue_table *circularQ;
 	struct set_nvm_data_req nvmd_req;
 	struct fw_control_ex *fw_control_context;
 	struct pm8001_ioctl_payload *ioctl_payload = payload;
@@ -4703,7 +4667,7 @@ int pm8001_chip_set_nvmd_req(struct pm8001_hba_info *pm8001_ha,
 	fw_control_context = kzalloc(sizeof(struct fw_control_ex), GFP_KERNEL);
 	if (!fw_control_context)
 		return -ENOMEM;
-	circularQ = &pm8001_ha->inbnd_q_tbl[0];
+
 	memcpy(pm8001_ha->memoryMap.region[NVMD].virt_ptr,
 		&ioctl_payload->func_specific,
 		ioctl_payload->wr_length);
@@ -4762,7 +4726,8 @@ int pm8001_chip_set_nvmd_req(struct pm8001_hba_info *pm8001_ha,
 	default:
 		break;
 	}
-	rc = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &nvmd_req,
+
+	rc = pm8001_mpi_build_cmd(pm8001_ha, 0, opc, &nvmd_req,
 			sizeof(nvmd_req), 0);
 	if (rc) {
 		kfree(fw_control_context);
@@ -4783,12 +4748,9 @@ pm8001_chip_fw_flash_update_build(struct pm8001_hba_info *pm8001_ha,
 {
 	struct fw_flash_Update_req payload;
 	struct fw_flash_updata_info *info;
-	struct inbound_queue_table *circularQ;
-	int ret;
 	u32 opc = OPC_INB_FW_FLASH_UPDATE;
 
 	memset(&payload, 0, sizeof(struct fw_flash_Update_req));
-	circularQ = &pm8001_ha->inbnd_q_tbl[0];
 	info = fw_flash_updata_info;
 	payload.tag = cpu_to_le32(tag);
 	payload.cur_image_len = cpu_to_le32(info->cur_image_len);
@@ -4799,9 +4761,9 @@ pm8001_chip_fw_flash_update_build(struct pm8001_hba_info *pm8001_ha,
 		cpu_to_le32(lower_32_bits(le64_to_cpu(info->sgl.addr)));
 	payload.sgl_addr_hi =
 		cpu_to_le32(upper_32_bits(le64_to_cpu(info->sgl.addr)));
-	ret = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &payload,
-			sizeof(payload), 0);
-	return ret;
+
+	return pm8001_mpi_build_cmd(pm8001_ha, 0, opc, &payload,
+				    sizeof(payload), 0);
 }
 
 int
@@ -4936,7 +4898,6 @@ pm8001_chip_set_dev_state_req(struct pm8001_hba_info *pm8001_ha,
 	struct pm8001_device *pm8001_dev, u32 state)
 {
 	struct set_dev_state_req payload;
-	struct inbound_queue_table *circularQ;
 	struct pm8001_ccb_info *ccb;
 	int rc;
 	u32 opc = OPC_INB_SET_DEVICE_STATE;
@@ -4947,13 +4908,12 @@ pm8001_chip_set_dev_state_req(struct pm8001_hba_info *pm8001_ha,
 	if (!ccb)
 		return -SAS_QUEUE_FULL;
 
-	circularQ = &pm8001_ha->inbnd_q_tbl[0];
 	payload.tag = cpu_to_le32(ccb->ccb_tag);
 	payload.device_id = cpu_to_le32(pm8001_dev->device_id);
 	payload.nds = cpu_to_le32(state);
 
-	rc = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &payload,
-			sizeof(payload), 0);
+	rc = pm8001_mpi_build_cmd(pm8001_ha, 0, opc, &payload,
+				  sizeof(payload), 0);
 	if (rc)
 		pm8001_ccb_free(pm8001_ha, ccb);
 
@@ -4964,7 +4924,6 @@ static int
 pm8001_chip_sas_re_initialization(struct pm8001_hba_info *pm8001_ha)
 {
 	struct sas_re_initialization_req payload;
-	struct inbound_queue_table *circularQ;
 	struct pm8001_ccb_info *ccb;
 	int rc;
 	u32 opc = OPC_INB_SAS_RE_INITIALIZE;
@@ -4975,14 +4934,13 @@ pm8001_chip_sas_re_initialization(struct pm8001_hba_info *pm8001_ha)
 	if (!ccb)
 		return -SAS_QUEUE_FULL;
 
-	circularQ = &pm8001_ha->inbnd_q_tbl[0];
 	payload.tag = cpu_to_le32(ccb->ccb_tag);
 	payload.SSAHOLT = cpu_to_le32(0xd << 25);
 	payload.sata_hol_tmo = cpu_to_le32(80);
 	payload.open_reject_cmdretries_data_retries = cpu_to_le32(0xff00ff);
 
-	rc = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &payload,
-			sizeof(payload), 0);
+	rc = pm8001_mpi_build_cmd(pm8001_ha, 0, opc, &payload,
+				  sizeof(payload), 0);
 	if (rc)
 		pm8001_ccb_free(pm8001_ha, ccb);
 
diff --git a/drivers/scsi/pm8001/pm8001_sas.h b/drivers/scsi/pm8001/pm8001_sas.h
index 824ada7f6a3f..aec4572906cf 100644
--- a/drivers/scsi/pm8001/pm8001_sas.h
+++ b/drivers/scsi/pm8001/pm8001_sas.h
@@ -668,8 +668,7 @@ int pm8001_mem_alloc(struct pci_dev *pdev, void **virt_addr,
 
 void pm8001_chip_iounmap(struct pm8001_hba_info *pm8001_ha);
 int pm8001_mpi_build_cmd(struct pm8001_hba_info *pm8001_ha,
-			struct inbound_queue_table *circularQ,
-			u32 opCode, void *payload, size_t nb,
+			u32 q_index, u32 opCode, void *payload, size_t nb,
 			u32 responseQueue);
 int pm8001_mpi_msg_free_get(struct inbound_queue_table *circularQ,
 				u16 messageSize, void **messagePtr);
diff --git a/drivers/scsi/pm8001/pm80xx_hwi.c b/drivers/scsi/pm8001/pm80xx_hwi.c
index 57ea933dab66..ce19aa361d26 100644
--- a/drivers/scsi/pm8001/pm80xx_hwi.c
+++ b/drivers/scsi/pm8001/pm80xx_hwi.c
@@ -1182,7 +1182,6 @@ int
 pm80xx_set_thermal_config(struct pm8001_hba_info *pm8001_ha)
 {
 	struct set_ctrl_cfg_req payload;
-	struct inbound_queue_table *circularQ;
 	int rc;
 	u32 tag;
 	u32 opc = OPC_INB_SET_CONTROLLER_CONFIG;
@@ -1193,7 +1192,6 @@ pm80xx_set_thermal_config(struct pm8001_hba_info *pm8001_ha)
 	if (rc)
 		return rc;
 
-	circularQ = &pm8001_ha->inbnd_q_tbl[0];
 	payload.tag = cpu_to_le32(tag);
 
 	if (IS_SPCV_12G(pm8001_ha->pdev))
@@ -1211,7 +1209,7 @@ pm80xx_set_thermal_config(struct pm8001_hba_info *pm8001_ha)
 		   "Setting up thermal config. cfg_pg 0 0x%x cfg_pg 1 0x%x\n",
 		   payload.cfg_pg[0], payload.cfg_pg[1]);
 
-	rc = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &payload,
+	rc = pm8001_mpi_build_cmd(pm8001_ha, 0, opc, &payload,
 			sizeof(payload), 0);
 	if (rc)
 		pm8001_tag_free(pm8001_ha, tag);
@@ -1228,7 +1226,6 @@ static int
 pm80xx_set_sas_protocol_timer_config(struct pm8001_hba_info *pm8001_ha)
 {
 	struct set_ctrl_cfg_req payload;
-	struct inbound_queue_table *circularQ;
 	SASProtocolTimerConfig_t SASConfigPage;
 	int rc;
 	u32 tag;
@@ -1238,11 +1235,9 @@ pm80xx_set_sas_protocol_timer_config(struct pm8001_hba_info *pm8001_ha)
 	memset(&SASConfigPage, 0, sizeof(SASProtocolTimerConfig_t));
 
 	rc = pm8001_tag_alloc(pm8001_ha, &tag);
-
 	if (rc)
 		return rc;
 
-	circularQ = &pm8001_ha->inbnd_q_tbl[0];
 	payload.tag = cpu_to_le32(tag);
 
 	SASConfigPage.pageCode = cpu_to_le32(SAS_PROTOCOL_TIMER_CONFIG_PAGE);
@@ -1284,7 +1279,7 @@ pm80xx_set_sas_protocol_timer_config(struct pm8001_hba_info *pm8001_ha)
 	memcpy(&payload.cfg_pg, &SASConfigPage,
 			 sizeof(SASProtocolTimerConfig_t));
 
-	rc = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &payload,
+	rc = pm8001_mpi_build_cmd(pm8001_ha, 0, opc, &payload,
 			sizeof(payload), 0);
 	if (rc)
 		pm8001_tag_free(pm8001_ha, tag);
@@ -1390,7 +1385,6 @@ pm80xx_get_encrypt_info(struct pm8001_hba_info *pm8001_ha)
 static int pm80xx_encrypt_update(struct pm8001_hba_info *pm8001_ha)
 {
 	struct kek_mgmt_req payload;
-	struct inbound_queue_table *circularQ;
 	int rc;
 	u32 tag;
 	u32 opc = OPC_INB_KEK_MANAGEMENT;
@@ -1400,7 +1394,6 @@ static int pm80xx_encrypt_update(struct pm8001_hba_info *pm8001_ha)
 	if (rc)
 		return rc;
 
-	circularQ = &pm8001_ha->inbnd_q_tbl[0];
 	payload.tag = cpu_to_le32(tag);
 	/* Currently only one key is used. New KEK index is 1.
 	 * Current KEK index is 1. Store KEK to NVRAM is 1.
@@ -1413,7 +1406,7 @@ static int pm80xx_encrypt_update(struct pm8001_hba_info *pm8001_ha)
 		   "Saving Encryption info to flash. payload 0x%x\n",
 		   le32_to_cpu(payload.new_curidx_ksop));
 
-	rc = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &payload,
+	rc = pm8001_mpi_build_cmd(pm8001_ha, 0, opc, &payload,
 			sizeof(payload), 0);
 	if (rc)
 		pm8001_tag_free(pm8001_ha, tag);
@@ -1770,7 +1763,6 @@ static void pm80xx_send_abort_all(struct pm8001_hba_info *pm8001_ha,
 	struct pm8001_ccb_info *ccb;
 	struct sas_task *task = NULL;
 	struct task_abort_req task_abort;
-	struct inbound_queue_table *circularQ;
 	u32 opc = OPC_INB_SATA_ABORT;
 	int ret;
 
@@ -1794,15 +1786,13 @@ static void pm80xx_send_abort_all(struct pm8001_hba_info *pm8001_ha,
 		return;
 	}
 
-	circularQ = &pm8001_ha->inbnd_q_tbl[0];
-
 	memset(&task_abort, 0, sizeof(task_abort));
 	task_abort.abort_all = cpu_to_le32(1);
 	task_abort.device_id = cpu_to_le32(pm8001_ha_dev->device_id);
 	task_abort.tag = cpu_to_le32(ccb->ccb_tag);
 
-	ret = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &task_abort,
-			sizeof(task_abort), 0);
+	ret = pm8001_mpi_build_cmd(pm8001_ha, 0, opc, &task_abort,
+				   sizeof(task_abort), 0);
 	pm8001_dbg(pm8001_ha, FAIL, "Executing abort task end\n");
 	if (ret) {
 		sas_free_task(task);
@@ -1819,11 +1809,9 @@ static void pm80xx_send_read_log(struct pm8001_hba_info *pm8001_ha,
 	struct sas_task *task = NULL;
 	struct host_to_dev_fis fis;
 	struct domain_device *dev;
-	struct inbound_queue_table *circularQ;
 	u32 opc = OPC_INB_SATA_HOST_OPSTART;
 
 	task = sas_alloc_slow_task(GFP_ATOMIC);
-
 	if (!task) {
 		pm8001_dbg(pm8001_ha, FAIL, "cannot allocate task !!!\n");
 		return;
@@ -1856,7 +1844,6 @@ static void pm80xx_send_read_log(struct pm8001_hba_info *pm8001_ha,
 	pm8001_ha_dev->id |= NCQ_2ND_RLE_FLAG;
 
 	memset(&sata_cmd, 0, sizeof(sata_cmd));
-	circularQ = &pm8001_ha->inbnd_q_tbl[0];
 
 	/* construct read log FIS */
 	memset(&fis, 0, sizeof(struct host_to_dev_fis));
@@ -1871,8 +1858,8 @@ static void pm80xx_send_read_log(struct pm8001_hba_info *pm8001_ha,
 	sata_cmd.ncqtag_atap_dir_m_dad = cpu_to_le32(((0x1 << 7) | (0x5 << 9)));
 	memcpy(&sata_cmd.sata_fis, &fis, sizeof(struct host_to_dev_fis));
 
-	res = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &sata_cmd,
-			sizeof(sata_cmd), 0);
+	res = pm8001_mpi_build_cmd(pm8001_ha, 0, opc, &sata_cmd,
+				   sizeof(sata_cmd), 0);
 	pm8001_dbg(pm8001_ha, FAIL, "Executing read log end\n");
 	if (res) {
 		sas_free_task(task);
@@ -3209,17 +3196,15 @@ static void pm80xx_hw_event_ack_req(struct pm8001_hba_info *pm8001_ha,
 	struct hw_event_ack_req	 payload;
 	u32 opc = OPC_INB_SAS_HW_EVENT_ACK;
 
-	struct inbound_queue_table *circularQ;
-
 	memset((u8 *)&payload, 0, sizeof(payload));
-	circularQ = &pm8001_ha->inbnd_q_tbl[Qnum];
 	payload.tag = cpu_to_le32(1);
 	payload.phyid_sea_portid = cpu_to_le32(((SEA & 0xFFFF) << 8) |
 		((phyId & 0xFF) << 24) | (port_id & 0xFF));
 	payload.param0 = cpu_to_le32(param0);
 	payload.param1 = cpu_to_le32(param1);
-	pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &payload,
-			sizeof(payload), 0);
+
+	pm8001_mpi_build_cmd(pm8001_ha, Qnum, opc, &payload,
+			     sizeof(payload), 0);
 }
 
 static int pm80xx_chip_phy_ctl_req(struct pm8001_hba_info *pm8001_ha,
@@ -4198,7 +4183,6 @@ static int pm80xx_chip_smp_req(struct pm8001_hba_info *pm8001_ha,
 	u32 req_len, resp_len;
 	struct smp_req smp_cmd;
 	u32 opc;
-	struct inbound_queue_table *circularQ;
 	u32 i, length;
 	u8 *payload;
 	u8 *to;
@@ -4227,7 +4211,6 @@ static int pm80xx_chip_smp_req(struct pm8001_hba_info *pm8001_ha,
 	}
 
 	opc = OPC_INB_SMP_REQUEST;
-	circularQ = &pm8001_ha->inbnd_q_tbl[0];
 	smp_cmd.tag = cpu_to_le32(ccb->ccb_tag);
 
 	length = sg_req->length;
@@ -4295,8 +4278,8 @@ static int pm80xx_chip_smp_req(struct pm8001_hba_info *pm8001_ha,
 	kunmap_atomic(to);
 	build_smp_cmd(pm8001_dev->device_id, smp_cmd.tag,
 				&smp_cmd, pm8001_ha->smp_exp_mode, length);
-	rc = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &smp_cmd,
-			sizeof(smp_cmd), 0);
+	rc = pm8001_mpi_build_cmd(pm8001_ha, 0, opc, &smp_cmd,
+				  sizeof(smp_cmd), 0);
 	if (rc)
 		goto err_out_2;
 	return 0;
@@ -4356,10 +4339,8 @@ static int pm80xx_chip_ssp_io_req(struct pm8001_hba_info *pm8001_ha,
 	struct pm8001_device *pm8001_dev = dev->lldd_dev;
 	struct ssp_ini_io_start_req ssp_cmd;
 	u32 tag = ccb->ccb_tag;
-	int ret;
 	u64 phys_addr, end_addr;
 	u32 end_addr_high, end_addr_low;
-	struct inbound_queue_table *circularQ;
 	u32 q_index, cpu_id;
 	u32 opc = OPC_INB_SSPINIIOSTART;
 
@@ -4383,7 +4364,6 @@ static int pm80xx_chip_ssp_io_req(struct pm8001_hba_info *pm8001_ha,
 		       task->ssp_task.cmd->cmd_len);
 	cpu_id = smp_processor_id();
 	q_index = (u32) (cpu_id) % (pm8001_ha->max_q_num);
-	circularQ = &pm8001_ha->inbnd_q_tbl[q_index];
 
 	/* Check if encryption is set */
 	if (pm8001_ha->chip->encrypt &&
@@ -4500,9 +4480,9 @@ static int pm80xx_chip_ssp_io_req(struct pm8001_hba_info *pm8001_ha,
 			ssp_cmd.esgl = 0;
 		}
 	}
-	ret = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc,
-			&ssp_cmd, sizeof(ssp_cmd), q_index);
-	return ret;
+
+	return pm8001_mpi_build_cmd(pm8001_ha, q_index, opc, &ssp_cmd,
+				    sizeof(ssp_cmd), q_index);
 }
 
 static int pm80xx_chip_sata_req(struct pm8001_hba_info *pm8001_ha,
@@ -4513,7 +4493,6 @@ static int pm80xx_chip_sata_req(struct pm8001_hba_info *pm8001_ha,
 	struct pm8001_device *pm8001_ha_dev = dev->lldd_dev;
 	struct ata_queued_cmd *qc = task->uldd_task;
 	u32 tag = ccb->ccb_tag;
-	int ret;
 	u32 q_index, cpu_id;
 	struct sata_start_req sata_cmd;
 	u32 hdr_tag, ncg_tag = 0;
@@ -4521,13 +4500,11 @@ static int pm80xx_chip_sata_req(struct pm8001_hba_info *pm8001_ha,
 	u32 end_addr_high, end_addr_low;
 	u32 ATAP = 0x0;
 	u32 dir;
-	struct inbound_queue_table *circularQ;
 	unsigned long flags;
 	u32 opc = OPC_INB_SATA_HOST_OPSTART;
 	memset(&sata_cmd, 0, sizeof(sata_cmd));
 	cpu_id = smp_processor_id();
 	q_index = (u32) (cpu_id) % (pm8001_ha->max_q_num);
-	circularQ = &pm8001_ha->inbnd_q_tbl[q_index];
 
 	if (task->data_dir == DMA_NONE && !task->ata_task.use_ncq) {
 		ATAP = 0x04; /* no data*/
@@ -4742,9 +4719,8 @@ static int pm80xx_chip_sata_req(struct pm8001_hba_info *pm8001_ha,
 				ccb->ccb_tag, opc,
 				qc ? qc->tf.command : 0, // ata opcode
 				ccb->device ? atomic_read(&ccb->device->running_req) : 0);
-	ret = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc,
-			&sata_cmd, sizeof(sata_cmd), q_index);
-	return ret;
+	return pm8001_mpi_build_cmd(pm8001_ha, q_index, opc, &sata_cmd,
+				    sizeof(sata_cmd), q_index);
 }
 
 /**
@@ -4756,11 +4732,9 @@ static int
 pm80xx_chip_phy_start_req(struct pm8001_hba_info *pm8001_ha, u8 phy_id)
 {
 	struct phy_start_req payload;
-	struct inbound_queue_table *circularQ;
-	int ret;
 	u32 tag = 0x01;
 	u32 opcode = OPC_INB_PHYSTART;
-	circularQ = &pm8001_ha->inbnd_q_tbl[0];
+
 	memset(&payload, 0, sizeof(payload));
 	payload.tag = cpu_to_le32(tag);
 
@@ -4782,9 +4756,9 @@ pm80xx_chip_phy_start_req(struct pm8001_hba_info *pm8001_ha, u8 phy_id)
 	memcpy(payload.sas_identify.sas_addr,
 	  &pm8001_ha->sas_addr, SAS_ADDR_SIZE);
 	payload.sas_identify.phy_id = phy_id;
-	ret = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opcode, &payload,
-			sizeof(payload), 0);
-	return ret;
+
+	return pm8001_mpi_build_cmd(pm8001_ha, 0, opcode, &payload,
+				    sizeof(payload), 0);
 }
 
 /**
@@ -4796,17 +4770,15 @@ static int pm80xx_chip_phy_stop_req(struct pm8001_hba_info *pm8001_ha,
 	u8 phy_id)
 {
 	struct phy_stop_req payload;
-	struct inbound_queue_table *circularQ;
-	int ret;
 	u32 tag = 0x01;
 	u32 opcode = OPC_INB_PHYSTOP;
-	circularQ = &pm8001_ha->inbnd_q_tbl[0];
+
 	memset(&payload, 0, sizeof(payload));
 	payload.tag = cpu_to_le32(tag);
 	payload.phy_id = cpu_to_le32(phy_id);
-	ret = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opcode, &payload,
-			sizeof(payload), 0);
-	return ret;
+
+	return pm8001_mpi_build_cmd(pm8001_ha, 0, opcode, &payload,
+				    sizeof(payload), 0);
 }
 
 /*
@@ -4818,7 +4790,6 @@ static int pm80xx_chip_reg_dev_req(struct pm8001_hba_info *pm8001_ha,
 	struct reg_dev_req payload;
 	u32	opc;
 	u32 stp_sspsmp_sata = 0x4;
-	struct inbound_queue_table *circularQ;
 	u32 linkrate, phy_id;
 	int rc;
 	struct pm8001_ccb_info *ccb;
@@ -4828,7 +4799,6 @@ static int pm80xx_chip_reg_dev_req(struct pm8001_hba_info *pm8001_ha,
 	struct domain_device *dev = pm8001_dev->sas_device;
 	struct domain_device *parent_dev = dev->parent;
 	struct pm8001_port *port = dev->port->lldd_port;
-	circularQ = &pm8001_ha->inbnd_q_tbl[0];
 
 	memset(&payload, 0, sizeof(payload));
 	ccb = pm8001_ccb_alloc(pm8001_ha, pm8001_dev, NULL);
@@ -4869,7 +4839,7 @@ static int pm80xx_chip_reg_dev_req(struct pm8001_hba_info *pm8001_ha,
 	memcpy(payload.sas_addr, pm8001_dev->sas_device->sas_addr,
 		SAS_ADDR_SIZE);
 
-	rc = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &payload,
+	rc = pm8001_mpi_build_cmd(pm8001_ha, 0, opc, &payload,
 			sizeof(payload), 0);
 	if (rc)
 		pm8001_ccb_free(pm8001_ha, ccb);
@@ -4889,18 +4859,18 @@ static int pm80xx_chip_phy_ctl_req(struct pm8001_hba_info *pm8001_ha,
 	u32 tag;
 	int rc;
 	struct local_phy_ctl_req payload;
-	struct inbound_queue_table *circularQ;
 	u32 opc = OPC_INB_LOCAL_PHY_CONTROL;
+
 	memset(&payload, 0, sizeof(payload));
 	rc = pm8001_tag_alloc(pm8001_ha, &tag);
 	if (rc)
 		return rc;
-	circularQ = &pm8001_ha->inbnd_q_tbl[0];
+
 	payload.tag = cpu_to_le32(tag);
 	payload.phyop_phyid =
 		cpu_to_le32(((phy_op & 0xFF) << 8) | (phyId & 0xFF));
 
-	rc = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &payload,
+	rc = pm8001_mpi_build_cmd(pm8001_ha, 0, opc, &payload,
 				  sizeof(payload), 0);
 	if (rc)
 		pm8001_tag_free(pm8001_ha, tag);
@@ -4946,7 +4916,6 @@ static void mpi_set_phy_profile_req(struct pm8001_hba_info *pm8001_ha,
 	u32 tag, i, j = 0;
 	int rc;
 	struct set_phy_profile_req payload;
-	struct inbound_queue_table *circularQ;
 	u32 opc = OPC_INB_SET_PHY_PROFILE;
 
 	memset(&payload, 0, sizeof(payload));
@@ -4956,7 +4925,6 @@ static void mpi_set_phy_profile_req(struct pm8001_hba_info *pm8001_ha,
 		return;
 	}
 
-	circularQ = &pm8001_ha->inbnd_q_tbl[0];
 	payload.tag = cpu_to_le32(tag);
 	payload.ppc_phyid =
 		cpu_to_le32(((operation & 0xF) << 8) | (phyid  & 0xFF));
@@ -4967,8 +4935,8 @@ static void mpi_set_phy_profile_req(struct pm8001_hba_info *pm8001_ha,
 		payload.reserved[j] = cpu_to_le32(*((u32 *)buf + i));
 		j++;
 	}
-	rc = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &payload,
-			sizeof(payload), 0);
+	rc = pm8001_mpi_build_cmd(pm8001_ha, 0, opc, &payload,
+				  sizeof(payload), 0);
 	if (rc)
 		pm8001_tag_free(pm8001_ha, tag);
 }
@@ -4992,7 +4960,6 @@ void pm8001_set_phy_profile_single(struct pm8001_hba_info *pm8001_ha,
 	u32 tag, opc;
 	int rc, i;
 	struct set_phy_profile_req payload;
-	struct inbound_queue_table *circularQ;
 
 	memset(&payload, 0, sizeof(payload));
 
@@ -5002,7 +4969,6 @@ void pm8001_set_phy_profile_single(struct pm8001_hba_info *pm8001_ha,
 		return;
 	}
 
-	circularQ = &pm8001_ha->inbnd_q_tbl[0];
 	opc = OPC_INB_SET_PHY_PROFILE;
 
 	payload.tag = cpu_to_le32(tag);
@@ -5013,7 +4979,7 @@ void pm8001_set_phy_profile_single(struct pm8001_hba_info *pm8001_ha,
 	for (i = 0; i < length; i++)
 		payload.reserved[i] = cpu_to_le32(*(buf + i));
 
-	rc = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &payload,
+	rc = pm8001_mpi_build_cmd(pm8001_ha, 0, opc, &payload,
 			sizeof(payload), 0);
 	if (rc)
 		pm8001_tag_free(pm8001_ha, tag);
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 65+ messages in thread

* [PATCH v4 28/31] scsi: pm8001: Simplify pm8001_task_exec()
  2022-02-17 13:29 [PATCH v4 00/31] libsas and pm8001 fixes Damien Le Moal
                   ` (26 preceding siblings ...)
  2022-02-17 13:29 ` [PATCH v4 27/31] scsi: pm8001: Simplify pm8001_mpi_build_cmd() interface Damien Le Moal
@ 2022-02-17 13:29 ` Damien Le Moal
  2022-02-17 19:47   ` Jinpu Wang
  2022-02-17 13:29 ` [PATCH v4 29/31] scsi: pm8001: Simplify pm8001_ccb_task_free() Damien Le Moal
                   ` (2 subsequent siblings)
  30 siblings, 1 reply; 65+ messages in thread
From: Damien Le Moal @ 2022-02-17 13:29 UTC (permalink / raw)
  To: linux-scsi, Martin K . Petersen, Jack Wang, John Garry
  Cc: Xiang Chen, Jason Yan, Luo Jiaxing

The main part of the pm8001_task_exec() function uses a do {} while(0)
loop that is useless and only makes the code harder to read. Remove this
loop. The unnecessary local variable t is also removed.

Additionally, avoid repeatedly declaring "struct task_status_struct *ts"
to handle error cases by declaring this variable for the entire function
scope. This allows simplifying the error cases, and together with the
addition of blank lines make the code more readable.

Finally, handling of the running_req counter is fixed to avoid
decrementing it without a corresponding incrementation in the case of
an invalid task protocol.

Signed-off-by: Damien Le Moal <damien.lemoal@opensource.wdc.com>
Reviewed-by: John Garry <john.garry@huawei.com>
---
 drivers/scsi/pm8001/pm8001_sas.c | 174 ++++++++++++++-----------------
 1 file changed, 80 insertions(+), 94 deletions(-)

diff --git a/drivers/scsi/pm8001/pm8001_sas.c b/drivers/scsi/pm8001/pm8001_sas.c
index 52507bc8f963..37aba0335f18 100644
--- a/drivers/scsi/pm8001/pm8001_sas.c
+++ b/drivers/scsi/pm8001/pm8001_sas.c
@@ -373,129 +373,115 @@ static int sas_find_local_port_id(struct domain_device *dev)
   * @is_tmf: if it is task management task.
   * @tmf: the task management IU
   */
-static int pm8001_task_exec(struct sas_task *task,
-	gfp_t gfp_flags, int is_tmf, struct pm8001_tmf_task *tmf)
+static int pm8001_task_exec(struct sas_task *task, gfp_t gfp_flags, int is_tmf,
+			    struct pm8001_tmf_task *tmf)
 {
+	struct task_status_struct *ts = &task->task_status;
+	enum sas_protocol task_proto = task->task_proto;
 	struct domain_device *dev = task->dev;
+	struct pm8001_device *pm8001_dev = dev->lldd_dev;
 	struct pm8001_hba_info *pm8001_ha;
-	struct pm8001_device *pm8001_dev;
 	struct pm8001_port *port = NULL;
-	struct sas_task *t = task;
 	struct pm8001_ccb_info *ccb;
-	u32 rc = 0, n_elem = 0;
-	unsigned long flags = 0;
-	enum sas_protocol task_proto = t->task_proto;
+	unsigned long flags;
+	u32 n_elem = 0;
+	int rc = 0;
 
 	if (!dev->port) {
-		struct task_status_struct *tsm = &t->task_status;
-		tsm->resp = SAS_TASK_UNDELIVERED;
-		tsm->stat = SAS_PHY_DOWN;
+		ts->resp = SAS_TASK_UNDELIVERED;
+		ts->stat = SAS_PHY_DOWN;
 		if (dev->dev_type != SAS_SATA_DEV)
-			t->task_done(t);
+			task->task_done(task);
 		return 0;
 	}
-	pm8001_ha = pm8001_find_ha_by_dev(task->dev);
-	if (pm8001_ha->controller_fatal_error) {
-		struct task_status_struct *ts = &t->task_status;
 
+	pm8001_ha = pm8001_find_ha_by_dev(dev);
+	if (pm8001_ha->controller_fatal_error) {
 		ts->resp = SAS_TASK_UNDELIVERED;
-		t->task_done(t);
+		task->task_done(task);
 		return 0;
 	}
+
 	pm8001_dbg(pm8001_ha, IO, "pm8001_task_exec device\n");
+
 	spin_lock_irqsave(&pm8001_ha->lock, flags);
-	do {
-		dev = t->dev;
-		pm8001_dev = dev->lldd_dev;
-		port = &pm8001_ha->port[sas_find_local_port_id(dev)];
-		if (DEV_IS_GONE(pm8001_dev) || !port->port_attached) {
-			if (sas_protocol_ata(task_proto)) {
-				struct task_status_struct *ts = &t->task_status;
-				ts->resp = SAS_TASK_UNDELIVERED;
-				ts->stat = SAS_PHY_DOWN;
 
-				spin_unlock_irqrestore(&pm8001_ha->lock, flags);
-				t->task_done(t);
-				spin_lock_irqsave(&pm8001_ha->lock, flags);
-				continue;
-			} else {
-				struct task_status_struct *ts = &t->task_status;
-				ts->resp = SAS_TASK_UNDELIVERED;
-				ts->stat = SAS_PHY_DOWN;
-				t->task_done(t);
-				continue;
-			}
-		}
+	pm8001_dev = dev->lldd_dev;
+	port = &pm8001_ha->port[sas_find_local_port_id(dev)];
 
-		ccb = pm8001_ccb_alloc(pm8001_ha, pm8001_dev, t);
-		if (!ccb) {
-			rc = -SAS_QUEUE_FULL;
-			goto err_out;
+	if (DEV_IS_GONE(pm8001_dev) || !port->port_attached) {
+		ts->resp = SAS_TASK_UNDELIVERED;
+		ts->stat = SAS_PHY_DOWN;
+		if (sas_protocol_ata(task_proto)) {
+			spin_unlock_irqrestore(&pm8001_ha->lock, flags);
+			task->task_done(task);
+			spin_lock_irqsave(&pm8001_ha->lock, flags);
+		} else {
+			task->task_done(task);
 		}
+		rc = -ENODEV;
+		goto err_out;
+	}
 
-		if (!sas_protocol_ata(task_proto)) {
-			if (t->num_scatter) {
-				n_elem = dma_map_sg(pm8001_ha->dev,
-					t->scatter,
-					t->num_scatter,
-					t->data_dir);
-				if (!n_elem) {
-					rc = -ENOMEM;
-					goto err_out_ccb;
-				}
+	ccb = pm8001_ccb_alloc(pm8001_ha, pm8001_dev, task);
+	if (!ccb) {
+		rc = -SAS_QUEUE_FULL;
+		goto err_out;
+	}
+
+	if (!sas_protocol_ata(task_proto)) {
+		if (task->num_scatter) {
+			n_elem = dma_map_sg(pm8001_ha->dev, task->scatter,
+					    task->num_scatter, task->data_dir);
+			if (!n_elem) {
+				rc = -ENOMEM;
+				goto err_out_ccb;
 			}
-		} else {
-			n_elem = t->num_scatter;
 		}
+	} else {
+		n_elem = task->num_scatter;
+	}
 
-		t->lldd_task = ccb;
-		ccb->n_elem = n_elem;
+	task->lldd_task = ccb;
+	ccb->n_elem = n_elem;
 
-		switch (task_proto) {
-		case SAS_PROTOCOL_SMP:
-			atomic_inc(&pm8001_dev->running_req);
-			rc = pm8001_task_prep_smp(pm8001_ha, ccb);
-			break;
-		case SAS_PROTOCOL_SSP:
-			atomic_inc(&pm8001_dev->running_req);
-			if (is_tmf)
-				rc = pm8001_task_prep_ssp_tm(pm8001_ha,
-					ccb, tmf);
-			else
-				rc = pm8001_task_prep_ssp(pm8001_ha, ccb);
-			break;
-		case SAS_PROTOCOL_SATA:
-		case SAS_PROTOCOL_STP:
-			atomic_inc(&pm8001_dev->running_req);
-			rc = pm8001_task_prep_ata(pm8001_ha, ccb);
-			break;
-		default:
-			dev_printk(KERN_ERR, pm8001_ha->dev,
-				"unknown sas_task proto: 0x%x\n", task_proto);
-			rc = -EINVAL;
-			break;
-		}
+	atomic_inc(&pm8001_dev->running_req);
 
-		if (rc) {
-			pm8001_dbg(pm8001_ha, IO, "rc is %x\n", rc);
-			atomic_dec(&pm8001_dev->running_req);
-			goto err_out_ccb;
-		}
-		/* TODO: select normal or high priority */
-	} while (0);
-	rc = 0;
-	goto out_done;
+	switch (task_proto) {
+	case SAS_PROTOCOL_SMP:
+		rc = pm8001_task_prep_smp(pm8001_ha, ccb);
+		break;
+	case SAS_PROTOCOL_SSP:
+		if (is_tmf)
+			rc = pm8001_task_prep_ssp_tm(pm8001_ha, ccb, tmf);
+		else
+			rc = pm8001_task_prep_ssp(pm8001_ha, ccb);
+		break;
+	case SAS_PROTOCOL_SATA:
+	case SAS_PROTOCOL_STP:
+		rc = pm8001_task_prep_ata(pm8001_ha, ccb);
+		break;
+	default:
+		dev_printk(KERN_ERR, pm8001_ha->dev,
+			   "unknown sas_task proto: 0x%x\n", task_proto);
+		rc = -EINVAL;
+		break;
+	}
 
+	if (rc) {
+		atomic_dec(&pm8001_dev->running_req);
+		if (!sas_protocol_ata(task_proto) && n_elem)
+			dma_unmap_sg(pm8001_ha->dev, task->scatter,
+				     task->num_scatter, task->data_dir);
 err_out_ccb:
-	pm8001_ccb_free(pm8001_ha, ccb);
+		pm8001_ccb_free(pm8001_ha, ccb);
+
 err_out:
-	dev_printk(KERN_ERR, pm8001_ha->dev, "pm8001 exec failed[%d]!\n", rc);
-	if (!sas_protocol_ata(task_proto))
-		if (n_elem)
-			dma_unmap_sg(pm8001_ha->dev, t->scatter, t->num_scatter,
-				t->data_dir);
-out_done:
+		pm8001_dbg(pm8001_ha, IO, "pm8001_task_exec failed[%d]!\n", rc);
+	}
+
 	spin_unlock_irqrestore(&pm8001_ha->lock, flags);
+
 	return rc;
 }
 
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 65+ messages in thread

* [PATCH v4 29/31] scsi: pm8001: Simplify pm8001_ccb_task_free()
  2022-02-17 13:29 [PATCH v4 00/31] libsas and pm8001 fixes Damien Le Moal
                   ` (27 preceding siblings ...)
  2022-02-17 13:29 ` [PATCH v4 28/31] scsi: pm8001: Simplify pm8001_task_exec() Damien Le Moal
@ 2022-02-17 13:29 ` Damien Le Moal
  2022-02-17 19:48   ` Jinpu Wang
  2022-02-17 13:29 ` [PATCH v4 30/31] scsi: pm8001: improve pm80XX_send_abort_all() Damien Le Moal
  2022-02-17 13:29 ` [PATCH v4 31/31] scsi: pm8001: Fix pm8001_info() message format Damien Le Moal
  30 siblings, 1 reply; 65+ messages in thread
From: Damien Le Moal @ 2022-02-17 13:29 UTC (permalink / raw)
  To: linux-scsi, Martin K . Petersen, Jack Wang, John Garry
  Cc: Xiang Chen, Jason Yan, Luo Jiaxing

The task argument of the pm8001_ccb_task_free() function can be infered
from the ccb argument ccb_task field. So there is no need to have this
argument. Likewise, the ccb_index argument is always equal to the ccb
tag field and is not needed either. Remove both arguments and update all
call sites. The pm8001_ccb_task_free_done() helper is also modified to
match this change.

Signed-off-by: Damien Le Moal <damien.lemoal@opensource.wdc.com>
---
 drivers/scsi/pm8001/pm8001_hwi.c | 42 +++++++++++++++-----------------
 drivers/scsi/pm8001/pm8001_sas.c | 25 +++++++++----------
 drivers/scsi/pm8001/pm8001_sas.h | 12 ++++-----
 drivers/scsi/pm8001/pm80xx_hwi.c | 35 ++++++++++++--------------
 4 files changed, 52 insertions(+), 62 deletions(-)

diff --git a/drivers/scsi/pm8001/pm8001_hwi.c b/drivers/scsi/pm8001/pm8001_hwi.c
index 03bcf7497bf9..c2dbadb5d91e 100644
--- a/drivers/scsi/pm8001/pm8001_hwi.c
+++ b/drivers/scsi/pm8001/pm8001_hwi.c
@@ -1564,11 +1564,11 @@ void pm8001_work_fn(struct work_struct *work)
 			spin_unlock_irqrestore(&t->task_state_lock, flags1);
 			pm8001_dbg(pm8001_ha, FAIL, "task 0x%p done with event 0x%x resp 0x%x stat 0x%x but aborted by upper layer!\n",
 				   t, pw->handler, ts->resp, ts->stat);
-			pm8001_ccb_task_free(pm8001_ha, t, ccb, ccb->ccb_tag);
+			pm8001_ccb_task_free(pm8001_ha, ccb);
 			spin_unlock_irqrestore(&pm8001_ha->lock, flags);
 		} else {
 			spin_unlock_irqrestore(&t->task_state_lock, flags1);
-			pm8001_ccb_task_free(pm8001_ha, t, ccb, ccb->ccb_tag);
+			pm8001_ccb_task_free(pm8001_ha, ccb);
 			mb();/* in order to force CPU ordering */
 			spin_unlock_irqrestore(&pm8001_ha->lock, flags);
 			t->task_done(t);
@@ -1697,8 +1697,7 @@ void pm8001_work_fn(struct work_struct *work)
 					continue;
 				}
 				/*complete sas task and update to top layer */
-				pm8001_ccb_task_free(pm8001_ha, task, ccb,
-						     ccb->ccb_tag);
+				pm8001_ccb_task_free(pm8001_ha, ccb);
 				ts->resp = SAS_TASK_COMPLETE;
 				task->task_done(task);
 			} else if (ccb->ccb_tag != PM8001_INVALID_TAG) {
@@ -2084,10 +2083,10 @@ mpi_ssp_completion(struct pm8001_hba_info *pm8001_ha, void *piomb)
 		spin_unlock_irqrestore(&t->task_state_lock, flags);
 		pm8001_dbg(pm8001_ha, FAIL, "task 0x%p done with io_status 0x%x resp 0x%x stat 0x%x but aborted by upper layer!\n",
 			   t, status, ts->resp, ts->stat);
-		pm8001_ccb_task_free(pm8001_ha, t, ccb, tag);
+		pm8001_ccb_task_free(pm8001_ha, ccb);
 	} else {
 		spin_unlock_irqrestore(&t->task_state_lock, flags);
-		pm8001_ccb_task_free(pm8001_ha, t, ccb, tag);
+		pm8001_ccb_task_free(pm8001_ha, ccb);
 		mb();/* in order to force CPU ordering */
 		t->task_done(t);
 	}
@@ -2251,10 +2250,10 @@ static void mpi_ssp_event(struct pm8001_hba_info *pm8001_ha, void *piomb)
 		spin_unlock_irqrestore(&t->task_state_lock, flags);
 		pm8001_dbg(pm8001_ha, FAIL, "task 0x%p done with event 0x%x resp 0x%x stat 0x%x but aborted by upper layer!\n",
 			   t, event, ts->resp, ts->stat);
-		pm8001_ccb_task_free(pm8001_ha, t, ccb, tag);
+		pm8001_ccb_task_free(pm8001_ha, ccb);
 	} else {
 		spin_unlock_irqrestore(&t->task_state_lock, flags);
-		pm8001_ccb_task_free(pm8001_ha, t, ccb, tag);
+		pm8001_ccb_task_free(pm8001_ha, ccb);
 		mb();/* in order to force CPU ordering */
 		t->task_done(t);
 	}
@@ -2480,7 +2479,7 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb)
 				IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS);
 			ts->resp = SAS_TASK_UNDELIVERED;
 			ts->stat = SAS_QUEUE_FULL;
-			pm8001_ccb_task_free_done(pm8001_ha, t, ccb, tag);
+			pm8001_ccb_task_free_done(pm8001_ha, ccb);
 			return;
 		}
 		break;
@@ -2496,7 +2495,7 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb)
 				IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS);
 			ts->resp = SAS_TASK_UNDELIVERED;
 			ts->stat = SAS_QUEUE_FULL;
-			pm8001_ccb_task_free_done(pm8001_ha, t, ccb, tag);
+			pm8001_ccb_task_free_done(pm8001_ha, ccb);
 			return;
 		}
 		break;
@@ -2518,7 +2517,7 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb)
 				IO_OPEN_CNX_ERROR_STP_RESOURCES_BUSY);
 			ts->resp = SAS_TASK_UNDELIVERED;
 			ts->stat = SAS_QUEUE_FULL;
-			pm8001_ccb_task_free_done(pm8001_ha, t, ccb, tag);
+			pm8001_ccb_task_free_done(pm8001_ha, ccb);
 			return;
 		}
 		break;
@@ -2589,7 +2588,7 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb)
 				    IO_DS_NON_OPERATIONAL);
 			ts->resp = SAS_TASK_UNDELIVERED;
 			ts->stat = SAS_QUEUE_FULL;
-			pm8001_ccb_task_free_done(pm8001_ha, t, ccb, tag);
+			pm8001_ccb_task_free_done(pm8001_ha, ccb);
 			return;
 		}
 		break;
@@ -2609,7 +2608,7 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb)
 				    IO_DS_IN_ERROR);
 			ts->resp = SAS_TASK_UNDELIVERED;
 			ts->stat = SAS_QUEUE_FULL;
-			pm8001_ccb_task_free_done(pm8001_ha, t, ccb, tag);
+			pm8001_ccb_task_free_done(pm8001_ha, ccb);
 			return;
 		}
 		break;
@@ -2639,10 +2638,10 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb)
 		pm8001_dbg(pm8001_ha, FAIL,
 			   "task 0x%p done with io_status 0x%x resp 0x%x stat 0x%x but aborted by upper layer!\n",
 			   t, status, ts->resp, ts->stat);
-		pm8001_ccb_task_free(pm8001_ha, t, ccb, tag);
+		pm8001_ccb_task_free(pm8001_ha, ccb);
 	} else {
 		spin_unlock_irqrestore(&t->task_state_lock, flags);
-		pm8001_ccb_task_free_done(pm8001_ha, t, ccb, tag);
+		pm8001_ccb_task_free_done(pm8001_ha, ccb);
 	}
 }
 
@@ -2994,12 +2993,10 @@ mpi_smp_completion(struct pm8001_hba_info *pm8001_ha, void *piomb)
 		spin_unlock_irqrestore(&t->task_state_lock, flags);
 		pm8001_dbg(pm8001_ha, FAIL, "task 0x%p done with io_status 0x%x resp 0x%x stat 0x%x but aborted by upper layer!\n",
 			   t, status, ts->resp, ts->stat);
-		pm8001_ccb_task_free(pm8001_ha, t, ccb, tag);
+		pm8001_ccb_task_free(pm8001_ha, ccb);
 	} else {
 		spin_unlock_irqrestore(&t->task_state_lock, flags);
-		pm8001_ccb_task_free(pm8001_ha, t, ccb, tag);
-		mb();/* in order to force CPU ordering */
-		t->task_done(t);
+		pm8001_ccb_task_free_done(pm8001_ha, ccb);
 	}
 }
 
@@ -3649,7 +3646,7 @@ int pm8001_mpi_task_abort_resp(struct pm8001_hba_info *pm8001_ha, void *piomb)
 	t->task_state_flags &= ~SAS_TASK_STATE_PENDING;
 	t->task_state_flags |= SAS_TASK_STATE_DONE;
 	spin_unlock_irqrestore(&t->task_state_lock, flags);
-	pm8001_ccb_task_free(pm8001_ha, t, ccb, tag);
+	pm8001_ccb_task_free(pm8001_ha, ccb);
 	mb();
 
 	if (pm8001_dev->id & NCQ_ABORT_ALL_FLAG) {
@@ -4287,12 +4284,11 @@ static int pm8001_chip_sata_req(struct pm8001_hba_info *pm8001_ha,
 					   "task 0x%p resp 0x%x  stat 0x%x but aborted by upper layer\n",
 					   task, ts->resp,
 					   ts->stat);
-				pm8001_ccb_task_free(pm8001_ha, task, ccb, tag);
+				pm8001_ccb_task_free(pm8001_ha, ccb);
 			} else {
 				spin_unlock_irqrestore(&task->task_state_lock,
 							flags);
-				pm8001_ccb_task_free_done(pm8001_ha, task,
-								ccb, tag);
+				pm8001_ccb_task_free_done(pm8001_ha, ccb);
 				return 0;
 			}
 		}
diff --git a/drivers/scsi/pm8001/pm8001_sas.c b/drivers/scsi/pm8001/pm8001_sas.c
index 37aba0335f18..da8f39631fb5 100644
--- a/drivers/scsi/pm8001/pm8001_sas.c
+++ b/drivers/scsi/pm8001/pm8001_sas.c
@@ -499,22 +499,21 @@ int pm8001_queue_command(struct sas_task *task, gfp_t gfp_flags)
 /**
   * pm8001_ccb_task_free - free the sg for ssp and smp command, free the ccb.
   * @pm8001_ha: our hba card information
-  * @ccb: the ccb which attached to ssp task
-  * @task: the task to be free.
-  * @ccb_idx: ccb index.
+  * @ccb: the ccb which attached to ssp task to free
   */
 void pm8001_ccb_task_free(struct pm8001_hba_info *pm8001_ha,
-	struct sas_task *task, struct pm8001_ccb_info *ccb, u32 ccb_idx)
+			  struct pm8001_ccb_info *ccb)
 {
+	struct sas_task *task = ccb->task;
 	struct ata_queued_cmd *qc;
 	struct pm8001_device *pm8001_dev;
 
-	if (!ccb->task)
+	if (!task)
 		return;
-	if (!sas_protocol_ata(task->task_proto))
-		if (ccb->n_elem)
-			dma_unmap_sg(pm8001_ha->dev, task->scatter,
-				task->num_scatter, task->data_dir);
+
+	if (!sas_protocol_ata(task->task_proto) && ccb->n_elem)
+		dma_unmap_sg(pm8001_ha->dev, task->scatter,
+			     task->num_scatter, task->data_dir);
 
 	switch (task->task_proto) {
 	case SAS_PROTOCOL_SMP:
@@ -533,12 +532,12 @@ void pm8001_ccb_task_free(struct pm8001_hba_info *pm8001_ha,
 	}
 
 	if (sas_protocol_ata(task->task_proto)) {
-		// For SCSI/ATA commands uldd_task points to ata_queued_cmd
+		/* For SCSI/ATA commands uldd_task points to ata_queued_cmd */
 		qc = task->uldd_task;
 		pm8001_dev = ccb->device;
 		trace_pm80xx_request_complete(pm8001_ha->id,
 			pm8001_dev ? pm8001_dev->attached_phy : PM8001_MAX_PHYS,
-			ccb_idx, 0 /* ctlr_opcode not known */,
+			ccb->ccb_tag, 0 /* ctlr_opcode not known */,
 			qc ? qc->tf.command : 0, // ata opcode
 			pm8001_dev ? atomic_read(&pm8001_dev->running_req) : -1);
 	}
@@ -960,11 +959,11 @@ void pm8001_open_reject_retry(
 				& SAS_TASK_STATE_ABORTED))) {
 			spin_unlock_irqrestore(&task->task_state_lock,
 				flags1);
-			pm8001_ccb_task_free(pm8001_ha, task, ccb, ccb->ccb_tag);
+			pm8001_ccb_task_free(pm8001_ha, ccb);
 		} else {
 			spin_unlock_irqrestore(&task->task_state_lock,
 				flags1);
-			pm8001_ccb_task_free(pm8001_ha, task, ccb, ccb->ccb_tag);
+			pm8001_ccb_task_free(pm8001_ha, ccb);
 			mb();/* in order to force CPU ordering */
 			spin_unlock_irqrestore(&pm8001_ha->lock, flags);
 			task->task_done(task);
diff --git a/drivers/scsi/pm8001/pm8001_sas.h b/drivers/scsi/pm8001/pm8001_sas.h
index aec4572906cf..2aab357d9a23 100644
--- a/drivers/scsi/pm8001/pm8001_sas.h
+++ b/drivers/scsi/pm8001/pm8001_sas.h
@@ -641,7 +641,7 @@ int pm8001_tag_alloc(struct pm8001_hba_info *pm8001_ha, u32 *tag_out);
 void pm8001_tag_init(struct pm8001_hba_info *pm8001_ha);
 u32 pm8001_get_ncq_tag(struct sas_task *task, u32 *tag);
 void pm8001_ccb_task_free(struct pm8001_hba_info *pm8001_ha,
-	struct sas_task *task, struct pm8001_ccb_info *ccb, u32 ccb_idx);
+			  struct pm8001_ccb_info *ccb);
 int pm8001_phy_control(struct asd_sas_phy *sas_phy, enum phy_func func,
 	void *funcdata);
 void pm8001_scan_start(struct Scsi_Host *shost);
@@ -786,12 +786,12 @@ static inline void pm8001_ccb_free(struct pm8001_hba_info *pm8001_ha,
 	pm8001_tag_free(pm8001_ha, tag);
 }
 
-static inline void
-pm8001_ccb_task_free_done(struct pm8001_hba_info *pm8001_ha,
-			struct sas_task *task, struct pm8001_ccb_info *ccb,
-			u32 ccb_idx)
+static inline void pm8001_ccb_task_free_done(struct pm8001_hba_info *pm8001_ha,
+					     struct pm8001_ccb_info *ccb)
 {
-	pm8001_ccb_task_free(pm8001_ha, task, ccb, ccb_idx);
+	struct sas_task *task = ccb->task;
+
+	pm8001_ccb_task_free(pm8001_ha, ccb);
 	smp_mb(); /*in order to force CPU ordering*/
 	task->task_done(task);
 }
diff --git a/drivers/scsi/pm8001/pm80xx_hwi.c b/drivers/scsi/pm8001/pm80xx_hwi.c
index ce19aa361d26..b5e1aaa0fd58 100644
--- a/drivers/scsi/pm8001/pm80xx_hwi.c
+++ b/drivers/scsi/pm8001/pm80xx_hwi.c
@@ -2157,14 +2157,12 @@ mpi_ssp_completion(struct pm8001_hba_info *pm8001_ha, void *piomb)
 		pm8001_dbg(pm8001_ha, FAIL,
 			   "task 0x%p done with io_status 0x%x resp 0x%x stat 0x%x but aborted by upper layer!\n",
 			   t, status, ts->resp, ts->stat);
-		pm8001_ccb_task_free(pm8001_ha, t, ccb, tag);
+		pm8001_ccb_task_free(pm8001_ha, ccb);
 		if (t->slow_task)
 			complete(&t->slow_task->completion);
 	} else {
 		spin_unlock_irqrestore(&t->task_state_lock, flags);
-		pm8001_ccb_task_free(pm8001_ha, t, ccb, tag);
-		mb();/* in order to force CPU ordering */
-		t->task_done(t);
+		pm8001_ccb_task_free_done(pm8001_ha, ccb);
 	}
 }
 
@@ -2340,12 +2338,10 @@ static void mpi_ssp_event(struct pm8001_hba_info *pm8001_ha, void *piomb)
 		pm8001_dbg(pm8001_ha, FAIL,
 			   "task 0x%p done with event 0x%x resp 0x%x stat 0x%x but aborted by upper layer!\n",
 			   t, event, ts->resp, ts->stat);
-		pm8001_ccb_task_free(pm8001_ha, t, ccb, tag);
+		pm8001_ccb_task_free(pm8001_ha, ccb);
 	} else {
 		spin_unlock_irqrestore(&t->task_state_lock, flags);
-		pm8001_ccb_task_free(pm8001_ha, t, ccb, tag);
-		mb();/* in order to force CPU ordering */
-		t->task_done(t);
+		pm8001_ccb_task_free_done(pm8001_ha, ccb);
 	}
 }
 
@@ -2579,7 +2575,7 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha,
 			ts->stat = SAS_QUEUE_FULL;
 			spin_unlock_irqrestore(&circularQ->oq_lock,
 					circularQ->lock_flags);
-			pm8001_ccb_task_free_done(pm8001_ha, t, ccb, tag);
+			pm8001_ccb_task_free_done(pm8001_ha, ccb);
 			spin_lock_irqsave(&circularQ->oq_lock,
 					circularQ->lock_flags);
 			return;
@@ -2599,7 +2595,7 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha,
 			ts->stat = SAS_QUEUE_FULL;
 			spin_unlock_irqrestore(&circularQ->oq_lock,
 					circularQ->lock_flags);
-			pm8001_ccb_task_free_done(pm8001_ha, t, ccb, tag);
+			pm8001_ccb_task_free_done(pm8001_ha, ccb);
 			spin_lock_irqsave(&circularQ->oq_lock,
 					circularQ->lock_flags);
 			return;
@@ -2627,7 +2623,7 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha,
 			ts->stat = SAS_QUEUE_FULL;
 			spin_unlock_irqrestore(&circularQ->oq_lock,
 					circularQ->lock_flags);
-			pm8001_ccb_task_free_done(pm8001_ha, t, ccb, tag);
+			pm8001_ccb_task_free_done(pm8001_ha, ccb);
 			spin_lock_irqsave(&circularQ->oq_lock,
 					circularQ->lock_flags);
 			return;
@@ -2702,7 +2698,7 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha,
 			ts->stat = SAS_QUEUE_FULL;
 			spin_unlock_irqrestore(&circularQ->oq_lock,
 					circularQ->lock_flags);
-			pm8001_ccb_task_free_done(pm8001_ha, t, ccb, tag);
+			pm8001_ccb_task_free_done(pm8001_ha, ccb);
 			spin_lock_irqsave(&circularQ->oq_lock,
 					circularQ->lock_flags);
 			return;
@@ -2726,7 +2722,7 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha,
 			ts->stat = SAS_QUEUE_FULL;
 			spin_unlock_irqrestore(&circularQ->oq_lock,
 					circularQ->lock_flags);
-			pm8001_ccb_task_free_done(pm8001_ha, t, ccb, tag);
+			pm8001_ccb_task_free_done(pm8001_ha, ccb);
 			spin_lock_irqsave(&circularQ->oq_lock,
 					circularQ->lock_flags);
 			return;
@@ -2760,14 +2756,14 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha,
 		pm8001_dbg(pm8001_ha, FAIL,
 			   "task 0x%p done with io_status 0x%x resp 0x%x stat 0x%x but aborted by upper layer!\n",
 			   t, status, ts->resp, ts->stat);
-		pm8001_ccb_task_free(pm8001_ha, t, ccb, tag);
+		pm8001_ccb_task_free(pm8001_ha, ccb);
 		if (t->slow_task)
 			complete(&t->slow_task->completion);
 	} else {
 		spin_unlock_irqrestore(&t->task_state_lock, flags);
 		spin_unlock_irqrestore(&circularQ->oq_lock,
 				circularQ->lock_flags);
-		pm8001_ccb_task_free_done(pm8001_ha, t, ccb, tag);
+		pm8001_ccb_task_free_done(pm8001_ha, ccb);
 		spin_lock_irqsave(&circularQ->oq_lock,
 				circularQ->lock_flags);
 	}
@@ -3171,10 +3167,10 @@ mpi_smp_completion(struct pm8001_hba_info *pm8001_ha, void *piomb)
 		pm8001_dbg(pm8001_ha, FAIL,
 			   "task 0x%p done with io_status 0x%x resp 0x%xstat 0x%x but aborted by upper layer!\n",
 			   t, status, ts->resp, ts->stat);
-		pm8001_ccb_task_free(pm8001_ha, t, ccb, tag);
+		pm8001_ccb_task_free(pm8001_ha, ccb);
 	} else {
 		spin_unlock_irqrestore(&t->task_state_lock, flags);
-		pm8001_ccb_task_free(pm8001_ha, t, ccb, tag);
+		pm8001_ccb_task_free(pm8001_ha, ccb);
 		mb();/* in order to force CPU ordering */
 		t->task_done(t);
 	}
@@ -4702,13 +4698,12 @@ static int pm80xx_chip_sata_req(struct pm8001_hba_info *pm8001_ha,
 					   "task 0x%p resp 0x%x  stat 0x%x but aborted by upper layer\n",
 					   task, ts->resp,
 					   ts->stat);
-				pm8001_ccb_task_free(pm8001_ha, task, ccb, tag);
+				pm8001_ccb_task_free(pm8001_ha, ccb);
 				return 0;
 			} else {
 				spin_unlock_irqrestore(&task->task_state_lock,
 							flags);
-				pm8001_ccb_task_free_done(pm8001_ha, task,
-								ccb, tag);
+				pm8001_ccb_task_free_done(pm8001_ha, ccb);
 				atomic_dec(&pm8001_ha_dev->running_req);
 				return 0;
 			}
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 65+ messages in thread

* [PATCH v4 30/31] scsi: pm8001: improve pm80XX_send_abort_all()
  2022-02-17 13:29 [PATCH v4 00/31] libsas and pm8001 fixes Damien Le Moal
                   ` (28 preceding siblings ...)
  2022-02-17 13:29 ` [PATCH v4 29/31] scsi: pm8001: Simplify pm8001_ccb_task_free() Damien Le Moal
@ 2022-02-17 13:29 ` Damien Le Moal
  2022-02-17 19:49   ` Jinpu Wang
  2022-02-17 13:29 ` [PATCH v4 31/31] scsi: pm8001: Fix pm8001_info() message format Damien Le Moal
  30 siblings, 1 reply; 65+ messages in thread
From: Damien Le Moal @ 2022-02-17 13:29 UTC (permalink / raw)
  To: linux-scsi, Martin K . Petersen, Jack Wang, John Garry
  Cc: Xiang Chen, Jason Yan, Luo Jiaxing

Both pm8001_send_abort_all() and pm80xx_send_abort_all() are called only
for a non null device with the NCQ_READ_LOG_FLAG set, so remove the
device check on entry of these functions. Furthermore, setting the
NCQ_ABORT_ALL_FLAG device id flag and clearing the NCQ_READ_LOG_FLAG is
always done before calling these functions. Move these operations inside
the functions.

Signed-off-by: Damien Le Moal <damien.lemoal@opensource.wdc.com>
---
 drivers/scsi/pm8001/pm8001_hwi.c | 14 ++++----------
 drivers/scsi/pm8001/pm80xx_hwi.c | 16 ++++------------
 2 files changed, 8 insertions(+), 22 deletions(-)

diff --git a/drivers/scsi/pm8001/pm8001_hwi.c b/drivers/scsi/pm8001/pm8001_hwi.c
index c2dbadb5d91e..edf83b8a6bd0 100644
--- a/drivers/scsi/pm8001/pm8001_hwi.c
+++ b/drivers/scsi/pm8001/pm8001_hwi.c
@@ -1748,15 +1748,13 @@ static void pm8001_send_abort_all(struct pm8001_hba_info *pm8001_ha,
 		struct pm8001_device *pm8001_ha_dev)
 {
 	struct pm8001_ccb_info *ccb;
-	struct sas_task *task = NULL;
+	struct sas_task *task;
 	struct task_abort_req task_abort;
 	u32 opc = OPC_INB_SATA_ABORT;
 	int ret;
 
-	if (!pm8001_ha_dev) {
-		pm8001_dbg(pm8001_ha, FAIL, "dev is null\n");
-		return;
-	}
+	pm8001_ha_dev->id |= NCQ_ABORT_ALL_FLAG;
+	pm8001_ha_dev->id &= ~NCQ_READ_LOG_FLAG;
 
 	task = sas_alloc_slow_task(GFP_ATOMIC);
 	if (!task) {
@@ -2358,11 +2356,7 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb)
 			ts->stat = SAS_SAM_STAT_GOOD;
 			/* check if response is for SEND READ LOG */
 			if (pm8001_dev &&
-				(pm8001_dev->id & NCQ_READ_LOG_FLAG)) {
-				/* set new bit for abort_all */
-				pm8001_dev->id |= NCQ_ABORT_ALL_FLAG;
-				/* clear bit for read log */
-				pm8001_dev->id = pm8001_dev->id & 0x7FFFFFFF;
+			    (pm8001_dev->id & NCQ_READ_LOG_FLAG)) {
 				pm8001_send_abort_all(pm8001_ha, pm8001_dev);
 				/* Free the tag */
 				pm8001_tag_free(pm8001_ha, tag);
diff --git a/drivers/scsi/pm8001/pm80xx_hwi.c b/drivers/scsi/pm8001/pm80xx_hwi.c
index b5e1aaa0fd58..9bb31f66db85 100644
--- a/drivers/scsi/pm8001/pm80xx_hwi.c
+++ b/drivers/scsi/pm8001/pm80xx_hwi.c
@@ -1761,23 +1761,19 @@ static void pm80xx_send_abort_all(struct pm8001_hba_info *pm8001_ha,
 		struct pm8001_device *pm8001_ha_dev)
 {
 	struct pm8001_ccb_info *ccb;
-	struct sas_task *task = NULL;
+	struct sas_task *task;
 	struct task_abort_req task_abort;
 	u32 opc = OPC_INB_SATA_ABORT;
 	int ret;
 
-	if (!pm8001_ha_dev) {
-		pm8001_dbg(pm8001_ha, FAIL, "dev is null\n");
-		return;
-	}
+	pm8001_ha_dev->id |= NCQ_ABORT_ALL_FLAG;
+	pm8001_ha_dev->id &= ~NCQ_READ_LOG_FLAG;
 
 	task = sas_alloc_slow_task(GFP_ATOMIC);
-
 	if (!task) {
 		pm8001_dbg(pm8001_ha, FAIL, "cannot allocate task\n");
 		return;
 	}
-
 	task->task_done = pm8001_task_done;
 
 	ccb = pm8001_ccb_alloc(pm8001_ha, pm8001_ha_dev, task);
@@ -2446,11 +2442,7 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha,
 			ts->stat = SAS_SAM_STAT_GOOD;
 			/* check if response is for SEND READ LOG */
 			if (pm8001_dev &&
-				(pm8001_dev->id & NCQ_READ_LOG_FLAG)) {
-				/* set new bit for abort_all */
-				pm8001_dev->id |= NCQ_ABORT_ALL_FLAG;
-				/* clear bit for read log */
-				pm8001_dev->id = pm8001_dev->id & 0x7FFFFFFF;
+			    (pm8001_dev->id & NCQ_READ_LOG_FLAG)) {
 				pm80xx_send_abort_all(pm8001_ha, pm8001_dev);
 				/* Free the tag */
 				pm8001_tag_free(pm8001_ha, tag);
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 65+ messages in thread

* [PATCH v4 31/31] scsi: pm8001: Fix pm8001_info() message format
  2022-02-17 13:29 [PATCH v4 00/31] libsas and pm8001 fixes Damien Le Moal
                   ` (29 preceding siblings ...)
  2022-02-17 13:29 ` [PATCH v4 30/31] scsi: pm8001: improve pm80XX_send_abort_all() Damien Le Moal
@ 2022-02-17 13:29 ` Damien Le Moal
  2022-02-17 19:50   ` Jinpu Wang
  30 siblings, 1 reply; 65+ messages in thread
From: Damien Le Moal @ 2022-02-17 13:29 UTC (permalink / raw)
  To: linux-scsi, Martin K . Petersen, Jack Wang, John Garry
  Cc: Xiang Chen, Jason Yan, Luo Jiaxing

Make the driver messages more readable by adding a space after the
message prefix ":" and removing the extra space between function name
and line number.

Signed-off-by: Damien Le Moal <damien.lemoal@opensource.wdc.com>
---
 drivers/scsi/pm8001/pm8001_sas.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/scsi/pm8001/pm8001_sas.h b/drivers/scsi/pm8001/pm8001_sas.h
index 2aab357d9a23..d78e6690333f 100644
--- a/drivers/scsi/pm8001/pm8001_sas.h
+++ b/drivers/scsi/pm8001/pm8001_sas.h
@@ -71,7 +71,7 @@
 #define PM8001_IOERR_LOGGING	0x200 /* development io err message logging */
 
 #define pm8001_info(HBA, fmt, ...)					\
-	pr_info("%s:: %s  %d:" fmt,					\
+	pr_info("%s:: %s %d: " fmt,					\
 		(HBA)->name, __func__, __LINE__, ##__VA_ARGS__)
 
 #define pm8001_dbg(HBA, level, fmt, ...)				\
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 65+ messages in thread

* Re: [PATCH v4 22/31] scsi: pm8001: Fix tag leaks on error
  2022-02-17 13:29 ` [PATCH v4 22/31] scsi: pm8001: Fix tag leaks on error Damien Le Moal
@ 2022-02-17 17:41   ` John Garry
  2022-02-17 22:42     ` Damien Le Moal
  2022-02-18  2:08     ` Damien Le Moal
  0 siblings, 2 replies; 65+ messages in thread
From: John Garry @ 2022-02-17 17:41 UTC (permalink / raw)
  To: Damien Le Moal, linux-scsi, Martin K . Petersen, Jack Wang
  Cc: Xiang Chen, Jason Yan, Luo Jiaxing

On 17/02/2022 13:29, Damien Le Moal wrote:
> In pm8001_chip_set_dev_state_req(), pm8001_chip_fw_flash_update_req()
> and pm8001_chip_reg_dev_req() add missing calls to pm8001_tag_free() to
> free the allocated tag when pm8001_mpi_build_cmd() fails.
> 
> Similarly, in pm8001_exec_internal_task_abort(), if the chip
> ->task_abort method fails, the tag allocated for the abort request task
> must be freed. Add the missing call to pm8001_tag_free(). Also remove
> the useless ex_err label and use "break" instead of "goto" statements
> in the retry loop.
> 
> Signed-off-by: Damien Le Moal <damien.lemoal@opensource.wdc.com>

This looks ok, but I think pm80xx_chip_phy_ctl_req() might be missed.

Apart from that and a nit, below:

Reviewed-by: John Garry <john.garry@huawei.com>

> ---
>   drivers/scsi/pm8001/pm8001_hwi.c |  9 +++++++++
>   drivers/scsi/pm8001/pm8001_sas.c | 33 +++++++++++++++++---------------
>   2 files changed, 27 insertions(+), 15 deletions(-)
> 
> diff --git a/drivers/scsi/pm8001/pm8001_hwi.c b/drivers/scsi/pm8001/pm8001_hwi.c
> index cc96e58454c8..431fc9160637 100644
> --- a/drivers/scsi/pm8001/pm8001_hwi.c
> +++ b/drivers/scsi/pm8001/pm8001_hwi.c
> @@ -4458,6 +4458,9 @@ static int pm8001_chip_reg_dev_req(struct pm8001_hba_info *pm8001_ha,
>   		SAS_ADDR_SIZE);
>   	rc = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &payload,
>   			sizeof(payload), 0);
> +	if (rc)
> +		pm8001_tag_free(pm8001_ha, tag);
> +
>   	return rc;
>   }
>   
> @@ -4870,6 +4873,9 @@ pm8001_chip_fw_flash_update_req(struct pm8001_hba_info *pm8001_ha,
>   	ccb->ccb_tag = tag;
>   	rc = pm8001_chip_fw_flash_update_build(pm8001_ha, &flash_update_info,
>   		tag);
> +	if (rc)
> +		pm8001_tag_free(pm8001_ha, tag);
> +
>   	return rc;
>   }
>   
> @@ -4974,6 +4980,9 @@ pm8001_chip_set_dev_state_req(struct pm8001_hba_info *pm8001_ha,
>   	payload.nds = cpu_to_le32(state);
>   	rc = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &payload,
>   			sizeof(payload), 0);
> +	if (rc)
> +		pm8001_tag_free(pm8001_ha, tag);
> +
>   	return rc;
>   
>   }
> diff --git a/drivers/scsi/pm8001/pm8001_sas.c b/drivers/scsi/pm8001/pm8001_sas.c
> index d0f5feb4f2d3..0440777a9135 100644
> --- a/drivers/scsi/pm8001/pm8001_sas.c
> +++ b/drivers/scsi/pm8001/pm8001_sas.c
> @@ -834,7 +834,8 @@ pm8001_exec_internal_task_abort(struct pm8001_hba_info *pm8001_ha,
>   
>   		res = pm8001_tag_alloc(pm8001_ha, &ccb_tag);
>   		if (res)
> -			goto ex_err;
> +			break;
> +
>   		ccb = &pm8001_ha->ccb_info[ccb_tag];
>   		ccb->device = pm8001_dev;
>   		ccb->ccb_tag = ccb_tag;
> @@ -843,36 +844,38 @@ pm8001_exec_internal_task_abort(struct pm8001_hba_info *pm8001_ha,
>   
>   		res = PM8001_CHIP_DISP->task_abort(pm8001_ha,
>   			pm8001_dev, flag, task_tag, ccb_tag);
> -
>   		if (res) {
>   			del_timer(&task->slow_task->timer);
> -			pm8001_dbg(pm8001_ha, FAIL, "Executing internal task failed\n");
> -			goto ex_err;
> +			pm8001_dbg(pm8001_ha, FAIL,
> +				   "Executing internal task failed\n");
> +			pm8001_tag_free(pm8001_ha, ccb_tag);
> +			break;
>   		}
> +
>   		wait_for_completion(&task->slow_task->completion);
>   		res = TMF_RESP_FUNC_FAILED;
> +
>   		/* Even TMF timed out, return direct. */
>   		if (task->task_state_flags & SAS_TASK_STATE_ABORTED) {
>   			pm8001_dbg(pm8001_ha, FAIL, "TMF task timeout.\n");
> -			goto ex_err;
> +			break;
>   		}

nit: these are really separate changes, but this series is so long 
already :)

>   
>   		if (task->task_status.resp == SAS_TASK_COMPLETE &&
>   			task->task_status.stat == SAS_SAM_STAT_GOOD) {
>   			res = TMF_RESP_FUNC_COMPLETE;
>   			break;
> -
> -		} else {
> -			pm8001_dbg(pm8001_ha, EH,
> -				   " Task to dev %016llx response: 0x%x status 0x%x\n",
> -				   SAS_ADDR(dev->sas_addr),
> -				   task->task_status.resp,
> -				   task->task_status.stat);
> -			sas_free_task(task);
> -			task = NULL;
>   		}
> +
> +		pm8001_dbg(pm8001_ha, EH,
> +			   " Task to dev %016llx response: 0x%x status 0x%x\n",
> +			   SAS_ADDR(dev->sas_addr),
> +			   task->task_status.resp,
> +			   task->task_status.stat);
> +		sas_free_task(task);
> +		task = NULL;
>   	}
> -ex_err:
> +
>   	BUG_ON(retry == 3 && task != NULL);
>   	sas_free_task(task);
>   	return res;


^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH v4 21/31] scsi: pm8001: Fix task leak in pm8001_send_abort_all()
  2022-02-17 13:29 ` [PATCH v4 21/31] scsi: pm8001: Fix task leak in pm8001_send_abort_all() Damien Le Moal
@ 2022-02-17 17:42   ` John Garry
  0 siblings, 0 replies; 65+ messages in thread
From: John Garry @ 2022-02-17 17:42 UTC (permalink / raw)
  To: Damien Le Moal, linux-scsi, Martin K . Petersen, Jack Wang
  Cc: Xiang Chen, Jason Yan, Luo Jiaxing

On 17/02/2022 13:29, Damien Le Moal wrote:
> In pm8001_send_abort_all(), make sure to free the allocated sas task
> if pm8001_tag_alloc() or pm8001_mpi_build_cmd() fail.
> 
> Signed-off-by: Damien Le Moal<damien.lemoal@opensource.wdc.com>

Reviewed-by: John Garry <john.garry@huawei.com>

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH v4 01/31] scsi: libsas: Fix sas_ata_qc_issue() handling of NCQ NON DATA commands
  2022-02-17 13:29 ` [PATCH v4 01/31] scsi: libsas: Fix sas_ata_qc_issue() handling of NCQ NON DATA commands Damien Le Moal
@ 2022-02-17 18:56   ` Jinpu Wang
  0 siblings, 0 replies; 65+ messages in thread
From: Jinpu Wang @ 2022-02-17 18:56 UTC (permalink / raw)
  To: Damien Le Moal
  Cc: linux-scsi, Martin K . Petersen, Jack Wang, John Garry,
	Xiang Chen, Jason Yan, Luo Jiaxing

On Thu, Feb 17, 2022 at 2:30 PM Damien Le Moal
<damien.lemoal@opensource.wdc.com> wrote:
>
> To detect for the DMA_NONE (no data transfer) DMA direction,
> sas_ata_qc_issue() tests if the command protocol is ATA_PROT_NODATA.
> This test does not include the ATA_CMD_NCQ_NON_DATA command as this
> command protocol is defined as ATA_PROT_NCQ_NODATA (equal to
> ATA_PROT_FLAG_NCQ) and not as ATA_PROT_NODATA.
>
> To include both NCQ and non-NCQ commands when testing for the DMA_NONE
> DMA direction, use "!ata_is_data()".
>
> Fixes: 176ddd89171d ("scsi: libsas: Reset num_scatter if libata marks qc as NODATA")
> Cc: stable@vger.kernel.org
> Signed-off-by: Damien Le Moal <damien.lemoal@opensource.wdc.com>
> Reviewed-by: John Garry <john.garry@huawei.com>
Reviewed-by: Jack Wang <jinpu.wang@ionos.com>
thx
> ---
>  drivers/scsi/libsas/sas_ata.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/scsi/libsas/sas_ata.c b/drivers/scsi/libsas/sas_ata.c
> index e0030a093994..50f779088b6e 100644
> --- a/drivers/scsi/libsas/sas_ata.c
> +++ b/drivers/scsi/libsas/sas_ata.c
> @@ -197,7 +197,7 @@ static unsigned int sas_ata_qc_issue(struct ata_queued_cmd *qc)
>                 task->total_xfer_len = qc->nbytes;
>                 task->num_scatter = qc->n_elem;
>                 task->data_dir = qc->dma_dir;
> -       } else if (qc->tf.protocol == ATA_PROT_NODATA) {
> +       } else if (!ata_is_data(qc->tf.protocol)) {
>                 task->data_dir = DMA_NONE;
>         } else {
>                 for_each_sg(qc->sg, sg, qc->n_elem, si)
> --
> 2.34.1
>

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH v4 02/31] scsi: pm8001: Fix __iomem pointer use in pm8001_phy_control()
  2022-02-17 13:29 ` [PATCH v4 02/31] scsi: pm8001: Fix __iomem pointer use in pm8001_phy_control() Damien Le Moal
@ 2022-02-17 19:01   ` Jinpu Wang
  0 siblings, 0 replies; 65+ messages in thread
From: Jinpu Wang @ 2022-02-17 19:01 UTC (permalink / raw)
  To: Damien Le Moal
  Cc: linux-scsi, Martin K . Petersen, Jack Wang, John Garry,
	Xiang Chen, Jason Yan, Luo Jiaxing

On Thu, Feb 17, 2022 at 2:30 PM Damien Le Moal
<damien.lemoal@opensource.wdc.com> wrote:
>
> Avoid the sparse warning "warning: cast removes address space '__iomem'
> of expression" by declaring the qp pointer as "u32 __iomem *".
> Accordingly, change the accesses to the qp array to use readl().
>
> Signed-off-by: Damien Le Moal <damien.lemoal@opensource.wdc.com>
looks good to me.
Reviewed-by: Jack Wang <jinpu.wang@ionos.com>
thx!
> ---
>  drivers/scsi/pm8001/pm8001_sas.c | 15 +++++++--------
>  1 file changed, 7 insertions(+), 8 deletions(-)
>
> diff --git a/drivers/scsi/pm8001/pm8001_sas.c b/drivers/scsi/pm8001/pm8001_sas.c
> index 8c12fbb9c476..4ab0ea9483f2 100644
> --- a/drivers/scsi/pm8001/pm8001_sas.c
> +++ b/drivers/scsi/pm8001/pm8001_sas.c
> @@ -234,14 +234,13 @@ int pm8001_phy_control(struct asd_sas_phy *sas_phy, enum phy_func func,
>                 }
>                 {
>                         struct sas_phy *phy = sas_phy->phy;
> -                       uint32_t *qp = (uint32_t *)(((char *)
> -                               pm8001_ha->io_mem[2].memvirtaddr)
> -                               + 0x1034 + (0x4000 * (phy_id & 3)));
> -
> -                       phy->invalid_dword_count = qp[0];
> -                       phy->running_disparity_error_count = qp[1];
> -                       phy->loss_of_dword_sync_count = qp[3];
> -                       phy->phy_reset_problem_count = qp[4];
> +                       u32 __iomem *qp = pm8001_ha->io_mem[2].memvirtaddr
> +                               + 0x1034 + (0x4000 * (phy_id & 3));
> +
> +                       phy->invalid_dword_count = readl(qp);
> +                       phy->running_disparity_error_count = readl(&qp[1]);
> +                       phy->loss_of_dword_sync_count = readl(&qp[3]);
> +                       phy->phy_reset_problem_count = readl(&qp[4]);
>                 }
>                 if (pm8001_ha->chip_id == chip_8001)
>                         pm8001_bar4_shift(pm8001_ha, 0);
> --
> 2.34.1
>

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH v4 03/31] scsi: pm8001: Fix pm8001_update_flash() local variable type
  2022-02-17 13:29 ` [PATCH v4 03/31] scsi: pm8001: Fix pm8001_update_flash() local variable type Damien Le Moal
@ 2022-02-17 19:03   ` Jinpu Wang
  0 siblings, 0 replies; 65+ messages in thread
From: Jinpu Wang @ 2022-02-17 19:03 UTC (permalink / raw)
  To: Damien Le Moal
  Cc: linux-scsi, Martin K . Petersen, Jack Wang, John Garry,
	Xiang Chen, Jason Yan, Luo Jiaxing

On Thu, Feb 17, 2022 at 2:30 PM Damien Le Moal
<damien.lemoal@opensource.wdc.com> wrote:
>
> Change the type of partitionSizeTmp from u32 to __be32 to suppress the
> sparse warning:
>
> warning: cast to restricted __be32
>
> Signed-off-by: Damien Le Moal <damien.lemoal@opensource.wdc.com>
Reviewed-by: Jack Wang <jinpu.wang@ionos.com>
thx!

> ---
>  drivers/scsi/pm8001/pm8001_ctl.c | 5 +++--
>  1 file changed, 3 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/scsi/pm8001/pm8001_ctl.c b/drivers/scsi/pm8001/pm8001_ctl.c
> index 66307783c73c..73f036bed128 100644
> --- a/drivers/scsi/pm8001/pm8001_ctl.c
> +++ b/drivers/scsi/pm8001/pm8001_ctl.c
> @@ -721,7 +721,8 @@ static int pm8001_update_flash(struct pm8001_hba_info *pm8001_ha)
>         DECLARE_COMPLETION_ONSTACK(completion);
>         u8              *ioctlbuffer;
>         struct fw_control_info  *fwControl;
> -       u32             partitionSize, partitionSizeTmp;
> +       __be32          partitionSizeTmp;
> +       u32             partitionSize;
>         u32             loopNumber, loopcount;
>         struct pm8001_fw_image_header *image_hdr;
>         u32             sizeRead = 0;
> @@ -742,7 +743,7 @@ static int pm8001_update_flash(struct pm8001_hba_info *pm8001_ha)
>         image_hdr = (struct pm8001_fw_image_header *)pm8001_ha->fw_image->data;
>         while (sizeRead < pm8001_ha->fw_image->size) {
>                 partitionSizeTmp =
> -                       *(u32 *)((u8 *)&image_hdr->image_length + sizeRead);
> +                       *(__be32 *)((u8 *)&image_hdr->image_length + sizeRead);
>                 partitionSize = be32_to_cpu(partitionSizeTmp);
>                 loopcount = DIV_ROUND_UP(partitionSize + HEADER_LEN,
>                                         IOCTL_BUF_SIZE);
> --
> 2.34.1
>

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH v4 04/31] scsi: pm8001: Fix command initialization in pm80XX_send_read_log()
  2022-02-17 13:29 ` [PATCH v4 04/31] scsi: pm8001: Fix command initialization in pm80XX_send_read_log() Damien Le Moal
@ 2022-02-17 19:05   ` Jinpu Wang
  0 siblings, 0 replies; 65+ messages in thread
From: Jinpu Wang @ 2022-02-17 19:05 UTC (permalink / raw)
  To: Damien Le Moal
  Cc: linux-scsi, Martin K . Petersen, Jack Wang, John Garry,
	Xiang Chen, Jason Yan

On Thu, Feb 17, 2022 at 2:30 PM Damien Le Moal
<damien.lemoal@opensource.wdc.com> wrote:
>
> Since the sata_cmd struct is zeroed out before its fields are
> initialized, there is no need for using "|=" to initialize the
> ncqtag_atap_dir_m field. Using a standard assignment removes the sparse
> warning:
>
> warning: invalid assignment: |=
>
> Also, since the ncqtag_atap_dir_m field has type __le32, use
> cpu_to_le32() to generate the assigned value.
>
> Fixes: c6b9ef5779c3 ("[SCSI] pm80xx: NCQ error handling changes")
> Reviewed-by: John Garry <john.garry@huawei.com>
> Signed-off-by: Damien Le Moal <damien.lemoal@opensource.wdc.com>
Reviewed-by: Jack Wang <jinpu.wang@ionos.com>
thx!
> ---
>  drivers/scsi/pm8001/pm8001_hwi.c | 2 +-
>  drivers/scsi/pm8001/pm80xx_hwi.c | 2 +-
>  2 files changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/scsi/pm8001/pm8001_hwi.c b/drivers/scsi/pm8001/pm8001_hwi.c
> index 4683fee87b84..817bba65feb3 100644
> --- a/drivers/scsi/pm8001/pm8001_hwi.c
> +++ b/drivers/scsi/pm8001/pm8001_hwi.c
> @@ -1864,7 +1864,7 @@ static void pm8001_send_read_log(struct pm8001_hba_info *pm8001_ha,
>
>         sata_cmd.tag = cpu_to_le32(ccb_tag);
>         sata_cmd.device_id = cpu_to_le32(pm8001_ha_dev->device_id);
> -       sata_cmd.ncqtag_atap_dir_m |= ((0x1 << 7) | (0x5 << 9));
> +       sata_cmd.ncqtag_atap_dir_m = cpu_to_le32((0x1 << 7) | (0x5 << 9));
>         memcpy(&sata_cmd.sata_fis, &fis, sizeof(struct host_to_dev_fis));
>
>         res = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &sata_cmd,
> diff --git a/drivers/scsi/pm8001/pm80xx_hwi.c b/drivers/scsi/pm8001/pm80xx_hwi.c
> index b83500ef3d86..f1663a10693a 100644
> --- a/drivers/scsi/pm8001/pm80xx_hwi.c
> +++ b/drivers/scsi/pm8001/pm80xx_hwi.c
> @@ -1882,7 +1882,7 @@ static void pm80xx_send_read_log(struct pm8001_hba_info *pm8001_ha,
>
>         sata_cmd.tag = cpu_to_le32(ccb_tag);
>         sata_cmd.device_id = cpu_to_le32(pm8001_ha_dev->device_id);
> -       sata_cmd.ncqtag_atap_dir_m_dad |= ((0x1 << 7) | (0x5 << 9));
> +       sata_cmd.ncqtag_atap_dir_m_dad = cpu_to_le32(((0x1 << 7) | (0x5 << 9)));
>         memcpy(&sata_cmd.sata_fis, &fis, sizeof(struct host_to_dev_fis));
>
>         res = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &sata_cmd,
> --
> 2.34.1
>

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH v4 05/31] scsi: pm8001: Fix pm80xx_pci_mem_copy() interface
  2022-02-17 13:29 ` [PATCH v4 05/31] scsi: pm8001: Fix pm80xx_pci_mem_copy() interface Damien Le Moal
@ 2022-02-17 19:06   ` Jinpu Wang
  0 siblings, 0 replies; 65+ messages in thread
From: Jinpu Wang @ 2022-02-17 19:06 UTC (permalink / raw)
  To: Damien Le Moal
  Cc: linux-scsi, Martin K . Petersen, Jack Wang, John Garry,
	Xiang Chen, Jason Yan, Luo Jiaxing

On Thu, Feb 17, 2022 at 2:30 PM Damien Le Moal
<damien.lemoal@opensource.wdc.com> wrote:
>
> The declaration of the local variable destination1 in
> pm80xx_pci_mem_copy() as a pointer to a u32 results in the sparse
> warning:
>
> warning: incorrect type in assignment (different base types)
>     expected unsigned int [usertype]
>     got restricted __le32 [usertype]
>
> Furthermore, the destination" argument of pm80xx_pci_mem_copy() is
> wrongly declared with the const attribute.
>
> Fix both problems by changing the type of the "destination" argument
> to "__le32 *" and use this argument directly inside the
> pm80xx_pci_mem_copy() function, thus removing the need for the
> destination1 local variable.
>
> Signed-off-by: Damien Le Moal <damien.lemoal@opensource.wdc.com>
Reviewed-by: Jack Wang <jinpu.wang@ionos.com>
thx!
> ---
>  drivers/scsi/pm8001/pm80xx_hwi.c | 8 +++-----
>  1 file changed, 3 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/scsi/pm8001/pm80xx_hwi.c b/drivers/scsi/pm8001/pm80xx_hwi.c
> index f1663a10693a..0b3386a3c508 100644
> --- a/drivers/scsi/pm8001/pm80xx_hwi.c
> +++ b/drivers/scsi/pm8001/pm80xx_hwi.c
> @@ -67,18 +67,16 @@ int pm80xx_bar4_shift(struct pm8001_hba_info *pm8001_ha, u32 shift_value)
>  }
>
>  static void pm80xx_pci_mem_copy(struct pm8001_hba_info  *pm8001_ha, u32 soffset,
> -                               const void *destination,
> +                               __le32 *destination,
>                                 u32 dw_count, u32 bus_base_number)
>  {
>         u32 index, value, offset;
> -       u32 *destination1;
> -       destination1 = (u32 *)destination;
>
> -       for (index = 0; index < dw_count; index += 4, destination1++) {
> +       for (index = 0; index < dw_count; index += 4, destination++) {
>                 offset = (soffset + index);
>                 if (offset < (64 * 1024)) {
>                         value = pm8001_cr32(pm8001_ha, bus_base_number, offset);
> -                       *destination1 =  cpu_to_le32(value);
> +                       *destination = cpu_to_le32(value);
>                 }
>         }
>         return;
> --
> 2.34.1
>

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH v4 06/31] scsi: pm8001: Fix command initialization in pm8001_chip_ssp_tm_req()
  2022-02-17 13:29 ` [PATCH v4 06/31] scsi: pm8001: Fix command initialization in pm8001_chip_ssp_tm_req() Damien Le Moal
@ 2022-02-17 19:07   ` Jinpu Wang
  0 siblings, 0 replies; 65+ messages in thread
From: Jinpu Wang @ 2022-02-17 19:07 UTC (permalink / raw)
  To: Damien Le Moal
  Cc: linux-scsi, Martin K . Petersen, Jack Wang, John Garry,
	Xiang Chen, Jason Yan

On Thu, Feb 17, 2022 at 2:30 PM Damien Le Moal
<damien.lemoal@opensource.wdc.com> wrote:
>
> The ds_ads_m field of struct ssp_ini_tm_start_req has the type __le32.
> Assigning a value to it should thus use cpu_to_le32(). This fixes the
> sparse warning:
>
> warning: incorrect type in assignment (different base types)
>    expected restricted __le32 [addressable] [assigned] [usertype] ds_ads_m
>    got int
>
> Fixes: dbf9bfe61571 ("[SCSI] pm8001: add SAS/SATA HBA driver")
> Signed-off-by: Damien Le Moal <damien.lemoal@opensource.wdc.com>
Reviewed-by: Jack Wang <jinpu.wang@ionos.com>
thx!
> ---
>  drivers/scsi/pm8001/pm8001_hwi.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/scsi/pm8001/pm8001_hwi.c b/drivers/scsi/pm8001/pm8001_hwi.c
> index 817bba65feb3..e20a1d4db026 100644
> --- a/drivers/scsi/pm8001/pm8001_hwi.c
> +++ b/drivers/scsi/pm8001/pm8001_hwi.c
> @@ -4619,7 +4619,7 @@ int pm8001_chip_ssp_tm_req(struct pm8001_hba_info *pm8001_ha,
>         memcpy(sspTMCmd.lun, task->ssp_task.LUN, 8);
>         sspTMCmd.tag = cpu_to_le32(ccb->ccb_tag);
>         if (pm8001_ha->chip_id != chip_8001)
> -               sspTMCmd.ds_ads_m = 0x08;
> +               sspTMCmd.ds_ads_m = cpu_to_le32(0x08);
>         circularQ = &pm8001_ha->inbnd_q_tbl[0];
>         ret = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &sspTMCmd,
>                         sizeof(sspTMCmd), 0);
> --
> 2.34.1
>

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH v4 08/31] scsi: pm8001: Fix le32 values handling in pm80xx_set_sas_protocol_timer_config()
  2022-02-17 13:29 ` [PATCH v4 08/31] scsi: pm8001: Fix le32 values handling in pm80xx_set_sas_protocol_timer_config() Damien Le Moal
@ 2022-02-17 19:08   ` Jinpu Wang
  0 siblings, 0 replies; 65+ messages in thread
From: Jinpu Wang @ 2022-02-17 19:08 UTC (permalink / raw)
  To: Damien Le Moal
  Cc: linux-scsi, Martin K . Petersen, Jack Wang, John Garry,
	Xiang Chen, Jason Yan, Luo Jiaxing

On Thu, Feb 17, 2022 at 2:30 PM Damien Le Moal
<damien.lemoal@opensource.wdc.com> wrote:
>
> All fields of the SASProtocolTimerConfig structure have the __le32 type.
> As such, use cpu_to_le32() to initialize them. This change suppresses
> many sparse warnings:
>
> warning: incorrect type in assignment (different base types)
>    expected restricted __le32 [addressable] [usertype] pageCode
>    got int
>
> Note that the check to limit the value of the STP_IDLE_TMO field is
> removed as this field is initialized using the fixed (and small) value
> defined by the STP_IDLE_TIME macro.
>
> The pm8001_dbg() calls printing the values of the SASProtocolTimerConfig
> structure fileds are changed to use le32_to_cpu() to present the values
> in human readable form.
>
> Fixes: a6cb3d012b98 ("[SCSI] pm80xx: thermal, sas controller config and error handling update")
> Signed-off-by: Damien Le Moal <damien.lemoal@opensource.wdc.com>
Reviewed-by: Jack Wang <jinpu.wang@ionos.com>
thx!
> ---
>  drivers/scsi/pm8001/pm80xx_hwi.c | 52 +++++++++++++++-----------------
>  1 file changed, 25 insertions(+), 27 deletions(-)
>
> diff --git a/drivers/scsi/pm8001/pm80xx_hwi.c b/drivers/scsi/pm8001/pm80xx_hwi.c
> index b303bc347f3d..e6fb89138030 100644
> --- a/drivers/scsi/pm8001/pm80xx_hwi.c
> +++ b/drivers/scsi/pm8001/pm80xx_hwi.c
> @@ -1245,43 +1245,41 @@ pm80xx_set_sas_protocol_timer_config(struct pm8001_hba_info *pm8001_ha)
>         circularQ = &pm8001_ha->inbnd_q_tbl[0];
>         payload.tag = cpu_to_le32(tag);
>
> -       SASConfigPage.pageCode        =  SAS_PROTOCOL_TIMER_CONFIG_PAGE;
> -       SASConfigPage.MST_MSI         =  3 << 15;
> -       SASConfigPage.STP_SSP_MCT_TMO =  (STP_MCT_TMO << 16) | SSP_MCT_TMO;
> -       SASConfigPage.STP_FRM_TMO     = (SAS_MAX_OPEN_TIME << 24) |
> -                               (SMP_MAX_CONN_TIMER << 16) | STP_FRM_TIMER;
> -       SASConfigPage.STP_IDLE_TMO    =  STP_IDLE_TIME;
> -
> -       if (SASConfigPage.STP_IDLE_TMO > 0x3FFFFFF)
> -               SASConfigPage.STP_IDLE_TMO = 0x3FFFFFF;
> -
> -
> -       SASConfigPage.OPNRJT_RTRY_INTVL =         (SAS_MFD << 16) |
> -                                               SAS_OPNRJT_RTRY_INTVL;
> -       SASConfigPage.Data_Cmd_OPNRJT_RTRY_TMO =  (SAS_DOPNRJT_RTRY_TMO << 16)
> -                                               | SAS_COPNRJT_RTRY_TMO;
> -       SASConfigPage.Data_Cmd_OPNRJT_RTRY_THR =  (SAS_DOPNRJT_RTRY_THR << 16)
> -                                               | SAS_COPNRJT_RTRY_THR;
> -       SASConfigPage.MAX_AIP =  SAS_MAX_AIP;
> +       SASConfigPage.pageCode = cpu_to_le32(SAS_PROTOCOL_TIMER_CONFIG_PAGE);
> +       SASConfigPage.MST_MSI = cpu_to_le32(3 << 15);
> +       SASConfigPage.STP_SSP_MCT_TMO =
> +               cpu_to_le32((STP_MCT_TMO << 16) | SSP_MCT_TMO);
> +       SASConfigPage.STP_FRM_TMO =
> +               cpu_to_le32((SAS_MAX_OPEN_TIME << 24) |
> +                           (SMP_MAX_CONN_TIMER << 16) | STP_FRM_TIMER);
> +       SASConfigPage.STP_IDLE_TMO = cpu_to_le32(STP_IDLE_TIME);
> +
> +       SASConfigPage.OPNRJT_RTRY_INTVL =
> +               cpu_to_le32((SAS_MFD << 16) | SAS_OPNRJT_RTRY_INTVL);
> +       SASConfigPage.Data_Cmd_OPNRJT_RTRY_TMO =
> +               cpu_to_le32((SAS_DOPNRJT_RTRY_TMO << 16) | SAS_COPNRJT_RTRY_TMO);
> +       SASConfigPage.Data_Cmd_OPNRJT_RTRY_THR =
> +               cpu_to_le32((SAS_DOPNRJT_RTRY_THR << 16) | SAS_COPNRJT_RTRY_THR);
> +       SASConfigPage.MAX_AIP = cpu_to_le32(SAS_MAX_AIP);
>
>         pm8001_dbg(pm8001_ha, INIT, "SASConfigPage.pageCode 0x%08x\n",
> -                  SASConfigPage.pageCode);
> +                  le32_to_cpu(SASConfigPage.pageCode));
>         pm8001_dbg(pm8001_ha, INIT, "SASConfigPage.MST_MSI  0x%08x\n",
> -                  SASConfigPage.MST_MSI);
> +                  le32_to_cpu(SASConfigPage.MST_MSI));
>         pm8001_dbg(pm8001_ha, INIT, "SASConfigPage.STP_SSP_MCT_TMO  0x%08x\n",
> -                  SASConfigPage.STP_SSP_MCT_TMO);
> +                  le32_to_cpu(SASConfigPage.STP_SSP_MCT_TMO));
>         pm8001_dbg(pm8001_ha, INIT, "SASConfigPage.STP_FRM_TMO  0x%08x\n",
> -                  SASConfigPage.STP_FRM_TMO);
> +                  le32_to_cpu(SASConfigPage.STP_FRM_TMO));
>         pm8001_dbg(pm8001_ha, INIT, "SASConfigPage.STP_IDLE_TMO  0x%08x\n",
> -                  SASConfigPage.STP_IDLE_TMO);
> +                  le32_to_cpu(SASConfigPage.STP_IDLE_TMO));
>         pm8001_dbg(pm8001_ha, INIT, "SASConfigPage.OPNRJT_RTRY_INTVL  0x%08x\n",
> -                  SASConfigPage.OPNRJT_RTRY_INTVL);
> +                  le32_to_cpu(SASConfigPage.OPNRJT_RTRY_INTVL));
>         pm8001_dbg(pm8001_ha, INIT, "SASConfigPage.Data_Cmd_OPNRJT_RTRY_TMO  0x%08x\n",
> -                  SASConfigPage.Data_Cmd_OPNRJT_RTRY_TMO);
> +                  le32_to_cpu(SASConfigPage.Data_Cmd_OPNRJT_RTRY_TMO));
>         pm8001_dbg(pm8001_ha, INIT, "SASConfigPage.Data_Cmd_OPNRJT_RTRY_THR  0x%08x\n",
> -                  SASConfigPage.Data_Cmd_OPNRJT_RTRY_THR);
> +                  le32_to_cpu(SASConfigPage.Data_Cmd_OPNRJT_RTRY_THR));
>         pm8001_dbg(pm8001_ha, INIT, "SASConfigPage.MAX_AIP  0x%08x\n",
> -                  SASConfigPage.MAX_AIP);
> +                  le32_to_cpu(SASConfigPage.MAX_AIP));
>
>         memcpy(&payload.cfg_pg, &SASConfigPage,
>                          sizeof(SASProtocolTimerConfig_t));
> --
> 2.34.1
>

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH v4 09/31] scsi: pm8001: Fix payload initialization in pm80xx_encrypt_update()
  2022-02-17 13:29 ` [PATCH v4 09/31] scsi: pm8001: Fix payload initialization in pm80xx_encrypt_update() Damien Le Moal
@ 2022-02-17 19:08   ` Jinpu Wang
  0 siblings, 0 replies; 65+ messages in thread
From: Jinpu Wang @ 2022-02-17 19:08 UTC (permalink / raw)
  To: Damien Le Moal
  Cc: linux-scsi, Martin K . Petersen, Jack Wang, John Garry,
	Xiang Chen, Jason Yan

On Thu, Feb 17, 2022 at 2:30 PM Damien Le Moal
<damien.lemoal@opensource.wdc.com> wrote:
>
> All fields of the kek_mgmt_req structure have the type __le32. So make
> sure to use cpu_to_le32() to initialize them. This suppresses the sparse
> warning:
>
> warning: incorrect type in assignment (different base types)
>    expected restricted __le32 [addressable] [assigned] [usertype] new_curidx_ksop
>    got int
>
> Fixes: 5860992db55c ("[SCSI] pm80xx: Added SPCv/ve specific hardware functionalities and relevant changes in common files")
> Signed-off-by: Damien Le Moal <damien.lemoal@opensource.wdc.com>
Reviewed-by: Jack Wang <jinpu.wang@ionos.com>
thx!
> ---
>  drivers/scsi/pm8001/pm80xx_hwi.c | 7 ++++---
>  1 file changed, 4 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/scsi/pm8001/pm80xx_hwi.c b/drivers/scsi/pm8001/pm80xx_hwi.c
> index e6fb89138030..b06d5ded45ca 100644
> --- a/drivers/scsi/pm8001/pm80xx_hwi.c
> +++ b/drivers/scsi/pm8001/pm80xx_hwi.c
> @@ -1405,12 +1405,13 @@ static int pm80xx_encrypt_update(struct pm8001_hba_info *pm8001_ha)
>         /* Currently only one key is used. New KEK index is 1.
>          * Current KEK index is 1. Store KEK to NVRAM is 1.
>          */
> -       payload.new_curidx_ksop = ((1 << 24) | (1 << 16) | (1 << 8) |
> -                                       KEK_MGMT_SUBOP_KEYCARDUPDATE);
> +       payload.new_curidx_ksop =
> +               cpu_to_le32(((1 << 24) | (1 << 16) | (1 << 8) |
> +                            KEK_MGMT_SUBOP_KEYCARDUPDATE));
>
>         pm8001_dbg(pm8001_ha, DEV,
>                    "Saving Encryption info to flash. payload 0x%x\n",
> -                  payload.new_curidx_ksop);
> +                  le32_to_cpu(payload.new_curidx_ksop));
>
>         rc = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &payload,
>                         sizeof(payload), 0);
> --
> 2.34.1
>

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH v4 07/31] scsi: pm8001: Fix payload initialization in pm80xx_set_thermal_config()
  2022-02-17 13:29 ` [PATCH v4 07/31] scsi: pm8001: Fix payload initialization in pm80xx_set_thermal_config() Damien Le Moal
@ 2022-02-17 19:09   ` Jinpu Wang
  0 siblings, 0 replies; 65+ messages in thread
From: Jinpu Wang @ 2022-02-17 19:09 UTC (permalink / raw)
  To: Damien Le Moal
  Cc: linux-scsi, Martin K . Petersen, Jack Wang, John Garry,
	Xiang Chen, Jason Yan, Luo Jiaxing

On Thu, Feb 17, 2022 at 2:30 PM Damien Le Moal
<damien.lemoal@opensource.wdc.com> wrote:
>
> The fields of the set_ctrl_cfg_req structure have the __le32 type, so
> use cpu_to_le32() to assign them. This removes the sparse warnings:
>
> warning: incorrect type in assignment (different base types)
>     expected restricted __le32
>     got unsigned int
>
> Fixes: 842784e0d15b ("pm80xx: Update For Thermal Page Code")
> Fixes: f5860992db55 ("[SCSI] pm80xx: Added SPCv/ve specific hardware functionalities and relevant changes in common files")
> Signed-off-by: Damien Le Moal <damien.lemoal@opensource.wdc.com>
> Reviewed-by: John Garry <john.garry@huawei.com>
Reviewed-by: Jack Wang <jinpu.wang@ionos.com>
thx!
> ---
>  drivers/scsi/pm8001/pm80xx_hwi.c | 8 +++++---
>  1 file changed, 5 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/scsi/pm8001/pm80xx_hwi.c b/drivers/scsi/pm8001/pm80xx_hwi.c
> index 0b3386a3c508..b303bc347f3d 100644
> --- a/drivers/scsi/pm8001/pm80xx_hwi.c
> +++ b/drivers/scsi/pm8001/pm80xx_hwi.c
> @@ -1201,9 +1201,11 @@ pm80xx_set_thermal_config(struct pm8001_hba_info *pm8001_ha)
>         else
>                 page_code = THERMAL_PAGE_CODE_8H;
>
> -       payload.cfg_pg[0] = (THERMAL_LOG_ENABLE << 9) |
> -                               (THERMAL_ENABLE << 8) | page_code;
> -       payload.cfg_pg[1] = (LTEMPHIL << 24) | (RTEMPHIL << 8);
> +       payload.cfg_pg[0] =
> +               cpu_to_le32((THERMAL_LOG_ENABLE << 9) |
> +                           (THERMAL_ENABLE << 8) | page_code);
> +       payload.cfg_pg[1] =
> +               cpu_to_le32((LTEMPHIL << 24) | (RTEMPHIL << 8));
>
>         pm8001_dbg(pm8001_ha, DEV,
>                    "Setting up thermal config. cfg_pg 0 0x%x cfg_pg 1 0x%x\n",
> --
> 2.34.1
>

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH v4 10/31] scsi: pm8001: Fix le32 values handling in pm80xx_chip_ssp_io_req()
  2022-02-17 13:29 ` [PATCH v4 10/31] scsi: pm8001: Fix le32 values handling in pm80xx_chip_ssp_io_req() Damien Le Moal
@ 2022-02-17 19:11   ` Jinpu Wang
  0 siblings, 0 replies; 65+ messages in thread
From: Jinpu Wang @ 2022-02-17 19:11 UTC (permalink / raw)
  To: Damien Le Moal
  Cc: linux-scsi, Martin K . Petersen, Jack Wang, John Garry,
	Xiang Chen, Jason Yan, Luo Jiaxing

On Thu, Feb 17, 2022 at 2:30 PM Damien Le Moal
<damien.lemoal@opensource.wdc.com> wrote:
>
> Make sure that the __le32 fields of struct ssp_ini_io_start_req are
> manipulated after applying the correct endian conversion. That is, use
> cpu_to_le32() for assigning values and le32_to_cpu() for consulting a
> field value. In particular, make sure that the calculations for the 4G
> boundary check are done using CPU endianness and *not* little endian
> values. With these fixes, many sparse warnings are removed.
>
> While at it, add blank lines after variable declarations and in some
> other places to make this code more readable.
>
> Fixes: 0ecdf00ba6e5 ("[SCSI] pm80xx: 4G boundary fix.")
> Signed-off-by: Damien Le Moal <damien.lemoal@opensource.wdc.com>
Reviewed-by: Jack Wang <jinpu.wang@ionos.com>
thx!
> ---
>  drivers/scsi/pm8001/pm80xx_hwi.c | 41 +++++++++++++++++++-------------
>  1 file changed, 25 insertions(+), 16 deletions(-)
>
> diff --git a/drivers/scsi/pm8001/pm80xx_hwi.c b/drivers/scsi/pm8001/pm80xx_hwi.c
> index b06d5ded45ca..130747b5a70a 100644
> --- a/drivers/scsi/pm8001/pm80xx_hwi.c
> +++ b/drivers/scsi/pm8001/pm80xx_hwi.c
> @@ -4374,13 +4374,15 @@ static int pm80xx_chip_ssp_io_req(struct pm8001_hba_info *pm8001_ha,
>         struct ssp_ini_io_start_req ssp_cmd;
>         u32 tag = ccb->ccb_tag;
>         int ret;
> -       u64 phys_addr, start_addr, end_addr;
> +       u64 phys_addr, end_addr;
>         u32 end_addr_high, end_addr_low;
>         struct inbound_queue_table *circularQ;
>         u32 q_index, cpu_id;
>         u32 opc = OPC_INB_SSPINIIOSTART;
> +
>         memset(&ssp_cmd, 0, sizeof(ssp_cmd));
>         memcpy(ssp_cmd.ssp_iu.lun, task->ssp_task.LUN, 8);
> +
>         /* data address domain added for spcv; set to 0 by host,
>          * used internally by controller
>          * 0 for SAS 1.1 and SAS 2.0 compatible TLR
> @@ -4391,7 +4393,7 @@ static int pm80xx_chip_ssp_io_req(struct pm8001_hba_info *pm8001_ha,
>         ssp_cmd.device_id = cpu_to_le32(pm8001_dev->device_id);
>         ssp_cmd.tag = cpu_to_le32(tag);
>         if (task->ssp_task.enable_first_burst)
> -               ssp_cmd.ssp_iu.efb_prio_attr |= 0x80;
> +               ssp_cmd.ssp_iu.efb_prio_attr = 0x80;
>         ssp_cmd.ssp_iu.efb_prio_attr |= (task->ssp_task.task_prio << 3);
>         ssp_cmd.ssp_iu.efb_prio_attr |= (task->ssp_task.task_attr & 7);
>         memcpy(ssp_cmd.ssp_iu.cdb, task->ssp_task.cmd->cmnd,
> @@ -4423,21 +4425,24 @@ static int pm80xx_chip_ssp_io_req(struct pm8001_hba_info *pm8001_ha,
>                         ssp_cmd.enc_esgl = cpu_to_le32(1<<31);
>                 } else if (task->num_scatter == 1) {
>                         u64 dma_addr = sg_dma_address(task->scatter);
> +
>                         ssp_cmd.enc_addr_low =
>                                 cpu_to_le32(lower_32_bits(dma_addr));
>                         ssp_cmd.enc_addr_high =
>                                 cpu_to_le32(upper_32_bits(dma_addr));
>                         ssp_cmd.enc_len = cpu_to_le32(task->total_xfer_len);
>                         ssp_cmd.enc_esgl = 0;
> +
>                         /* Check 4G Boundary */
> -                       start_addr = cpu_to_le64(dma_addr);
> -                       end_addr = (start_addr + ssp_cmd.enc_len) - 1;
> -                       end_addr_low = cpu_to_le32(lower_32_bits(end_addr));
> -                       end_addr_high = cpu_to_le32(upper_32_bits(end_addr));
> -                       if (end_addr_high != ssp_cmd.enc_addr_high) {
> +                       end_addr = dma_addr + le32_to_cpu(ssp_cmd.enc_len) - 1;
> +                       end_addr_low = lower_32_bits(end_addr);
> +                       end_addr_high = upper_32_bits(end_addr);
> +
> +                       if (end_addr_high != le32_to_cpu(ssp_cmd.enc_addr_high)) {
>                                 pm8001_dbg(pm8001_ha, FAIL,
>                                            "The sg list address start_addr=0x%016llx data_len=0x%x end_addr_high=0x%08x end_addr_low=0x%08x has crossed 4G boundary\n",
> -                                          start_addr, ssp_cmd.enc_len,
> +                                          dma_addr,
> +                                          le32_to_cpu(ssp_cmd.enc_len),
>                                            end_addr_high, end_addr_low);
>                                 pm8001_chip_make_sg(task->scatter, 1,
>                                         ccb->buf_prd);
> @@ -4446,7 +4451,7 @@ static int pm80xx_chip_ssp_io_req(struct pm8001_hba_info *pm8001_ha,
>                                         cpu_to_le32(lower_32_bits(phys_addr));
>                                 ssp_cmd.enc_addr_high =
>                                         cpu_to_le32(upper_32_bits(phys_addr));
> -                               ssp_cmd.enc_esgl = cpu_to_le32(1<<31);
> +                               ssp_cmd.enc_esgl = cpu_to_le32(1U<<31);
>                         }
>                 } else if (task->num_scatter == 0) {
>                         ssp_cmd.enc_addr_low = 0;
> @@ -4454,8 +4459,10 @@ static int pm80xx_chip_ssp_io_req(struct pm8001_hba_info *pm8001_ha,
>                         ssp_cmd.enc_len = cpu_to_le32(task->total_xfer_len);
>                         ssp_cmd.enc_esgl = 0;
>                 }
> +
>                 /* XTS mode. All other fields are 0 */
> -               ssp_cmd.key_cmode = 0x6 << 4;
> +               ssp_cmd.key_cmode = cpu_to_le32(0x6 << 4);
> +
>                 /* set tweak values. Should be the start lba */
>                 ssp_cmd.twk_val0 = cpu_to_le32((task->ssp_task.cmd->cmnd[2] << 24) |
>                                                 (task->ssp_task.cmd->cmnd[3] << 16) |
> @@ -4477,20 +4484,22 @@ static int pm80xx_chip_ssp_io_req(struct pm8001_hba_info *pm8001_ha,
>                         ssp_cmd.esgl = cpu_to_le32(1<<31);
>                 } else if (task->num_scatter == 1) {
>                         u64 dma_addr = sg_dma_address(task->scatter);
> +
>                         ssp_cmd.addr_low = cpu_to_le32(lower_32_bits(dma_addr));
>                         ssp_cmd.addr_high =
>                                 cpu_to_le32(upper_32_bits(dma_addr));
>                         ssp_cmd.len = cpu_to_le32(task->total_xfer_len);
>                         ssp_cmd.esgl = 0;
> +
>                         /* Check 4G Boundary */
> -                       start_addr = cpu_to_le64(dma_addr);
> -                       end_addr = (start_addr + ssp_cmd.len) - 1;
> -                       end_addr_low = cpu_to_le32(lower_32_bits(end_addr));
> -                       end_addr_high = cpu_to_le32(upper_32_bits(end_addr));
> -                       if (end_addr_high != ssp_cmd.addr_high) {
> +                       end_addr = dma_addr + le32_to_cpu(ssp_cmd.len) - 1;
> +                       end_addr_low = lower_32_bits(end_addr);
> +                       end_addr_high = upper_32_bits(end_addr);
> +                       if (end_addr_high != le32_to_cpu(ssp_cmd.addr_high)) {
>                                 pm8001_dbg(pm8001_ha, FAIL,
>                                            "The sg list address start_addr=0x%016llx data_len=0x%x end_addr_high=0x%08x end_addr_low=0x%08x has crossed 4G boundary\n",
> -                                          start_addr, ssp_cmd.len,
> +                                          dma_addr,
> +                                          le32_to_cpu(ssp_cmd.len),
>                                            end_addr_high, end_addr_low);
>                                 pm8001_chip_make_sg(task->scatter, 1,
>                                         ccb->buf_prd);
> --
> 2.34.1
>

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH v4 11/31] scsi: pm8001: Fix le32 values handling in pm80xx_chip_sata_req()
  2022-02-17 13:29 ` [PATCH v4 11/31] scsi: pm8001: Fix le32 values handling in pm80xx_chip_sata_req() Damien Le Moal
@ 2022-02-17 19:13   ` Jinpu Wang
  0 siblings, 0 replies; 65+ messages in thread
From: Jinpu Wang @ 2022-02-17 19:13 UTC (permalink / raw)
  To: Damien Le Moal
  Cc: linux-scsi, Martin K . Petersen, Jack Wang, John Garry,
	Xiang Chen, Jason Yan

On Thu, Feb 17, 2022 at 2:30 PM Damien Le Moal
<damien.lemoal@opensource.wdc.com> wrote:
>
> Make sure that the __le32 fields of struct sata_cmd are manipulated
> after applying the correct endian conversion. That is, use cpu_to_le32()
> for assigning values and le32_to_cpu() for consulting a field value.
> In particular, make sure that the calculations for the 4G boundary check
> are done using CPU endianness and *not* little endian values. With these
> fixes, many sparse warnings are removed.
>
> While at it, fix some code identation and add blank lines after
> variable declarations and in some other places to make this code more
> readable.
>
> Fixes: 0ecdf00ba6e5 ("[SCSI] pm80xx: 4G boundary fix.")
> Signed-off-by: Damien Le Moal <damien.lemoal@opensource.wdc.com>
Reviewed-by: Jack Wang <jinpu.wang@ionos.com>
thx!
> ---
>  drivers/scsi/pm8001/pm80xx_hwi.c | 82 ++++++++++++++++++--------------
>  1 file changed, 45 insertions(+), 37 deletions(-)
>
> diff --git a/drivers/scsi/pm8001/pm80xx_hwi.c b/drivers/scsi/pm8001/pm80xx_hwi.c
> index 130747b5a70a..1f3b01c70f24 100644
> --- a/drivers/scsi/pm8001/pm80xx_hwi.c
> +++ b/drivers/scsi/pm8001/pm80xx_hwi.c
> @@ -4534,7 +4534,7 @@ static int pm80xx_chip_sata_req(struct pm8001_hba_info *pm8001_ha,
>         u32 q_index, cpu_id;
>         struct sata_start_req sata_cmd;
>         u32 hdr_tag, ncg_tag = 0;
> -       u64 phys_addr, start_addr, end_addr;
> +       u64 phys_addr, end_addr;
>         u32 end_addr_high, end_addr_low;
>         u32 ATAP = 0x0;
>         u32 dir;
> @@ -4595,32 +4595,38 @@ static int pm80xx_chip_sata_req(struct pm8001_hba_info *pm8001_ha,
>                         pm8001_chip_make_sg(task->scatter,
>                                                 ccb->n_elem, ccb->buf_prd);
>                         phys_addr = ccb->ccb_dma_handle;
> -                       sata_cmd.enc_addr_low = lower_32_bits(phys_addr);
> -                       sata_cmd.enc_addr_high = upper_32_bits(phys_addr);
> +                       sata_cmd.enc_addr_low =
> +                               cpu_to_le32(lower_32_bits(phys_addr));
> +                       sata_cmd.enc_addr_high =
> +                               cpu_to_le32(upper_32_bits(phys_addr));
>                         sata_cmd.enc_esgl = cpu_to_le32(1 << 31);
>                 } else if (task->num_scatter == 1) {
>                         u64 dma_addr = sg_dma_address(task->scatter);
> -                       sata_cmd.enc_addr_low = lower_32_bits(dma_addr);
> -                       sata_cmd.enc_addr_high = upper_32_bits(dma_addr);
> +
> +                       sata_cmd.enc_addr_low =
> +                               cpu_to_le32(lower_32_bits(dma_addr));
> +                       sata_cmd.enc_addr_high =
> +                               cpu_to_le32(upper_32_bits(dma_addr));
>                         sata_cmd.enc_len = cpu_to_le32(task->total_xfer_len);
>                         sata_cmd.enc_esgl = 0;
> +
>                         /* Check 4G Boundary */
> -                       start_addr = cpu_to_le64(dma_addr);
> -                       end_addr = (start_addr + sata_cmd.enc_len) - 1;
> -                       end_addr_low = cpu_to_le32(lower_32_bits(end_addr));
> -                       end_addr_high = cpu_to_le32(upper_32_bits(end_addr));
> -                       if (end_addr_high != sata_cmd.enc_addr_high) {
> +                       end_addr = dma_addr + le32_to_cpu(sata_cmd.enc_len) - 1;
> +                       end_addr_low = lower_32_bits(end_addr);
> +                       end_addr_high = upper_32_bits(end_addr);
> +                       if (end_addr_high != le32_to_cpu(sata_cmd.enc_addr_high)) {
>                                 pm8001_dbg(pm8001_ha, FAIL,
>                                            "The sg list address start_addr=0x%016llx data_len=0x%x end_addr_high=0x%08x end_addr_low=0x%08x has crossed 4G boundary\n",
> -                                          start_addr, sata_cmd.enc_len,
> +                                          dma_addr,
> +                                          le32_to_cpu(sata_cmd.enc_len),
>                                            end_addr_high, end_addr_low);
>                                 pm8001_chip_make_sg(task->scatter, 1,
>                                         ccb->buf_prd);
>                                 phys_addr = ccb->ccb_dma_handle;
>                                 sata_cmd.enc_addr_low =
> -                                       lower_32_bits(phys_addr);
> +                                       cpu_to_le32(lower_32_bits(phys_addr));
>                                 sata_cmd.enc_addr_high =
> -                                       upper_32_bits(phys_addr);
> +                                       cpu_to_le32(upper_32_bits(phys_addr));
>                                 sata_cmd.enc_esgl =
>                                         cpu_to_le32(1 << 31);
>                         }
> @@ -4631,7 +4637,8 @@ static int pm80xx_chip_sata_req(struct pm8001_hba_info *pm8001_ha,
>                         sata_cmd.enc_esgl = 0;
>                 }
>                 /* XTS mode. All other fields are 0 */
> -               sata_cmd.key_index_mode = 0x6 << 4;
> +               sata_cmd.key_index_mode = cpu_to_le32(0x6 << 4);
> +
>                 /* set tweak values. Should be the start lba */
>                 sata_cmd.twk_val0 =
>                         cpu_to_le32((sata_cmd.sata_fis.lbal_exp << 24) |
> @@ -4657,31 +4664,31 @@ static int pm80xx_chip_sata_req(struct pm8001_hba_info *pm8001_ha,
>                         phys_addr = ccb->ccb_dma_handle;
>                         sata_cmd.addr_low = lower_32_bits(phys_addr);
>                         sata_cmd.addr_high = upper_32_bits(phys_addr);
> -                       sata_cmd.esgl = cpu_to_le32(1 << 31);
> +                       sata_cmd.esgl = cpu_to_le32(1U << 31);
>                 } else if (task->num_scatter == 1) {
>                         u64 dma_addr = sg_dma_address(task->scatter);
> +
>                         sata_cmd.addr_low = lower_32_bits(dma_addr);
>                         sata_cmd.addr_high = upper_32_bits(dma_addr);
>                         sata_cmd.len = cpu_to_le32(task->total_xfer_len);
>                         sata_cmd.esgl = 0;
> +
>                         /* Check 4G Boundary */
> -                       start_addr = cpu_to_le64(dma_addr);
> -                       end_addr = (start_addr + sata_cmd.len) - 1;
> -                       end_addr_low = cpu_to_le32(lower_32_bits(end_addr));
> -                       end_addr_high = cpu_to_le32(upper_32_bits(end_addr));
> +                       end_addr = dma_addr + le32_to_cpu(sata_cmd.len) - 1;
> +                       end_addr_low = lower_32_bits(end_addr);
> +                       end_addr_high = upper_32_bits(end_addr);
>                         if (end_addr_high != sata_cmd.addr_high) {
>                                 pm8001_dbg(pm8001_ha, FAIL,
>                                            "The sg list address start_addr=0x%016llx data_len=0x%xend_addr_high=0x%08x end_addr_low=0x%08x has crossed 4G boundary\n",
> -                                          start_addr, sata_cmd.len,
> +                                          dma_addr,
> +                                          le32_to_cpu(sata_cmd.len),
>                                            end_addr_high, end_addr_low);
>                                 pm8001_chip_make_sg(task->scatter, 1,
>                                         ccb->buf_prd);
>                                 phys_addr = ccb->ccb_dma_handle;
> -                               sata_cmd.addr_low =
> -                                       lower_32_bits(phys_addr);
> -                               sata_cmd.addr_high =
> -                                       upper_32_bits(phys_addr);
> -                               sata_cmd.esgl = cpu_to_le32(1 << 31);
> +                               sata_cmd.addr_low = lower_32_bits(phys_addr);
> +                               sata_cmd.addr_high = upper_32_bits(phys_addr);
> +                               sata_cmd.esgl = cpu_to_le32(1U << 31);
>                         }
>                 } else if (task->num_scatter == 0) {
>                         sata_cmd.addr_low = 0;
> @@ -4689,27 +4696,28 @@ static int pm80xx_chip_sata_req(struct pm8001_hba_info *pm8001_ha,
>                         sata_cmd.len = cpu_to_le32(task->total_xfer_len);
>                         sata_cmd.esgl = 0;
>                 }
> +
>                 /* scsi cdb */
>                 sata_cmd.atapi_scsi_cdb[0] =
>                         cpu_to_le32(((task->ata_task.atapi_packet[0]) |
> -                       (task->ata_task.atapi_packet[1] << 8) |
> -                       (task->ata_task.atapi_packet[2] << 16) |
> -                       (task->ata_task.atapi_packet[3] << 24)));
> +                                    (task->ata_task.atapi_packet[1] << 8) |
> +                                    (task->ata_task.atapi_packet[2] << 16) |
> +                                    (task->ata_task.atapi_packet[3] << 24)));
>                 sata_cmd.atapi_scsi_cdb[1] =
>                         cpu_to_le32(((task->ata_task.atapi_packet[4]) |
> -                       (task->ata_task.atapi_packet[5] << 8) |
> -                       (task->ata_task.atapi_packet[6] << 16) |
> -                       (task->ata_task.atapi_packet[7] << 24)));
> +                                    (task->ata_task.atapi_packet[5] << 8) |
> +                                    (task->ata_task.atapi_packet[6] << 16) |
> +                                    (task->ata_task.atapi_packet[7] << 24)));
>                 sata_cmd.atapi_scsi_cdb[2] =
>                         cpu_to_le32(((task->ata_task.atapi_packet[8]) |
> -                       (task->ata_task.atapi_packet[9] << 8) |
> -                       (task->ata_task.atapi_packet[10] << 16) |
> -                       (task->ata_task.atapi_packet[11] << 24)));
> +                                    (task->ata_task.atapi_packet[9] << 8) |
> +                                    (task->ata_task.atapi_packet[10] << 16) |
> +                                    (task->ata_task.atapi_packet[11] << 24)));
>                 sata_cmd.atapi_scsi_cdb[3] =
>                         cpu_to_le32(((task->ata_task.atapi_packet[12]) |
> -                       (task->ata_task.atapi_packet[13] << 8) |
> -                       (task->ata_task.atapi_packet[14] << 16) |
> -                       (task->ata_task.atapi_packet[15] << 24)));
> +                                    (task->ata_task.atapi_packet[13] << 8) |
> +                                    (task->ata_task.atapi_packet[14] << 16) |
> +                                    (task->ata_task.atapi_packet[15] << 24)));
>         }
>
>         /* Check for read log for failed drive and return */
> --
> 2.34.1
>

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH v4 12/31] scsi: pm8001: Fix use of struct set_phy_profile_req fields
  2022-02-17 13:29 ` [PATCH v4 12/31] scsi: pm8001: Fix use of struct set_phy_profile_req fields Damien Le Moal
@ 2022-02-17 19:14   ` Jinpu Wang
  0 siblings, 0 replies; 65+ messages in thread
From: Jinpu Wang @ 2022-02-17 19:14 UTC (permalink / raw)
  To: Damien Le Moal
  Cc: linux-scsi, Martin K . Petersen, Jack Wang, John Garry,
	Xiang Chen, Jason Yan, Luo Jiaxing

On Thu, Feb 17, 2022 at 2:30 PM Damien Le Moal
<damien.lemoal@opensource.wdc.com> wrote:
>
> In mpi_set_phy_profile_req() and pm8001_set_phy_profile_single(), use
> cpu_to_le32() to initialize the ppc_phyid field of struct
> set_phy_profile_req. Furthermore, fix the definition of the reserved
> field of this structure to be an array of __le32, to match the use of
> cpu_to_le32() when assigning values. These changes remove several sparse
> type warnings.
>
> Signed-off-by: Damien Le Moal <damien.lemoal@opensource.wdc.com>
Reviewed-by: Jack Wang <jinpu.wang@ionos.com>
thx!
> ---
>  drivers/scsi/pm8001/pm80xx_hwi.c | 12 +++++++-----
>  drivers/scsi/pm8001/pm80xx_hwi.h |  2 +-
>  2 files changed, 8 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/scsi/pm8001/pm80xx_hwi.c b/drivers/scsi/pm8001/pm80xx_hwi.c
> index 1f3b01c70f24..60c305f987b5 100644
> --- a/drivers/scsi/pm8001/pm80xx_hwi.c
> +++ b/drivers/scsi/pm8001/pm80xx_hwi.c
> @@ -4970,12 +4970,13 @@ static void mpi_set_phy_profile_req(struct pm8001_hba_info *pm8001_ha,
>                 pm8001_dbg(pm8001_ha, FAIL, "Invalid tag\n");
>         circularQ = &pm8001_ha->inbnd_q_tbl[0];
>         payload.tag = cpu_to_le32(tag);
> -       payload.ppc_phyid = (((operation & 0xF) << 8) | (phyid  & 0xFF));
> +       payload.ppc_phyid =
> +               cpu_to_le32(((operation & 0xF) << 8) | (phyid  & 0xFF));
>         pm8001_dbg(pm8001_ha, INIT,
>                    " phy profile command for phy %x ,length is %d\n",
> -                  payload.ppc_phyid, length);
> +                  le32_to_cpu(payload.ppc_phyid), length);
>         for (i = length; i < (length + PHY_DWORD_LENGTH - 1); i++) {
> -               payload.reserved[j] =  cpu_to_le32(*((u32 *)buf + i));
> +               payload.reserved[j] = cpu_to_le32(*((u32 *)buf + i));
>                 j++;
>         }
>         rc = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &payload,
> @@ -5015,8 +5016,9 @@ void pm8001_set_phy_profile_single(struct pm8001_hba_info *pm8001_ha,
>         opc = OPC_INB_SET_PHY_PROFILE;
>
>         payload.tag = cpu_to_le32(tag);
> -       payload.ppc_phyid = (((SAS_PHY_ANALOG_SETTINGS_PAGE & 0xF) << 8)
> -                               | (phy & 0xFF));
> +       payload.ppc_phyid =
> +               cpu_to_le32(((SAS_PHY_ANALOG_SETTINGS_PAGE & 0xF) << 8)
> +                           | (phy & 0xFF));
>
>         for (i = 0; i < length; i++)
>                 payload.reserved[i] = cpu_to_le32(*(buf + i));
> diff --git a/drivers/scsi/pm8001/pm80xx_hwi.h b/drivers/scsi/pm8001/pm80xx_hwi.h
> index c41ed039c92a..d66b49323d49 100644
> --- a/drivers/scsi/pm8001/pm80xx_hwi.h
> +++ b/drivers/scsi/pm8001/pm80xx_hwi.h
> @@ -972,7 +972,7 @@ struct dek_mgmt_req {
>  struct set_phy_profile_req {
>         __le32  tag;
>         __le32  ppc_phyid;
> -       u32     reserved[29];
> +       __le32  reserved[29];
>  } __attribute__((packed, aligned(4)));
>
>  /**
> --
> 2.34.1
>

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH v4 13/31] scsi: pm8001: Remove local variable in pm8001_pci_resume()
  2022-02-17 13:29 ` [PATCH v4 13/31] scsi: pm8001: Remove local variable in pm8001_pci_resume() Damien Le Moal
@ 2022-02-17 19:15   ` Jinpu Wang
  0 siblings, 0 replies; 65+ messages in thread
From: Jinpu Wang @ 2022-02-17 19:15 UTC (permalink / raw)
  To: Damien Le Moal
  Cc: linux-scsi, Martin K . Petersen, Jack Wang, John Garry,
	Xiang Chen, Jason Yan, Luo Jiaxing

On Thu, Feb 17, 2022 at 2:30 PM Damien Le Moal
<damien.lemoal@opensource.wdc.com> wrote:
>
> In pm8001_pci_resume(), the use of the u32 type for the local variable
> device_state causes a sparse warning:
>
> warning: incorrect type in assignment (different base types)
>     expected unsigned int [usertype] device_state
>     got restricted pci_power_t [usertype] current_state
>
> Since this variable is used only once in the function, remove it and
> use pdev->current_state directly. While at it, also add a blank line
> after the last local variable declaration.
>
> Reviewed-by: John Garry <john.garry@huawei.com>
> Signed-off-by: Damien Le Moal <damien.lemoal@opensource.wdc.com>
Reviewed-by: Jack Wang <jinpu.wang@ionos.com>
thx!
> ---
>  drivers/scsi/pm8001/pm8001_init.c | 8 ++++----
>  1 file changed, 4 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/scsi/pm8001/pm8001_init.c b/drivers/scsi/pm8001/pm8001_init.c
> index d8a2121cb8d9..4b9a26f008a9 100644
> --- a/drivers/scsi/pm8001/pm8001_init.c
> +++ b/drivers/scsi/pm8001/pm8001_init.c
> @@ -1335,13 +1335,13 @@ static int __maybe_unused pm8001_pci_resume(struct device *dev)
>         struct pm8001_hba_info *pm8001_ha;
>         int rc;
>         u8 i = 0, j;
> -       u32 device_state;
>         DECLARE_COMPLETION_ONSTACK(completion);
> +
>         pm8001_ha = sha->lldd_ha;
> -       device_state = pdev->current_state;
>
> -       pm8001_info(pm8001_ha, "pdev=0x%p, slot=%s, resuming from previous operating state [D%d]\n",
> -                     pdev, pm8001_ha->name, device_state);
> +       pm8001_info(pm8001_ha,
> +                   "pdev=0x%p, slot=%s, resuming from previous operating state [D%d]\n",
> +                   pdev, pm8001_ha->name, pdev->current_state);
>
>         rc = pci_go_44(pdev);
>         if (rc)
> --
> 2.34.1
>

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH v4 14/31] scsi: pm8001: Fix NCQ NON DATA command task initialization
  2022-02-17 13:29 ` [PATCH v4 14/31] scsi: pm8001: Fix NCQ NON DATA command task initialization Damien Le Moal
@ 2022-02-17 19:25   ` Jinpu Wang
  0 siblings, 0 replies; 65+ messages in thread
From: Jinpu Wang @ 2022-02-17 19:25 UTC (permalink / raw)
  To: Damien Le Moal
  Cc: linux-scsi, Martin K . Petersen, Jack Wang, John Garry,
	Xiang Chen, Jason Yan, Luo Jiaxing

On Thu, Feb 17, 2022 at 2:30 PM Damien Le Moal
<damien.lemoal@opensource.wdc.com> wrote:
>
> In the pm8001_chip_sata_req() and pm80xx_chip_sata_req() functions, all
> tasks with a DMA direction of DMA_NONE (no data transfer) are
> initialized using the ATAP value 0x04. However, NCQ NON DATA commands,
> while being DMA_NONE commands are NCQ commands and need to be
> initialized using the value 0x07 for ATAP, similarly to other NCQ
> commands.
>
> Make sure that NCQ NON DATA command tasks are initialized similarly to
> other NCQ commands by also testing the task "use_ncq" field in addition
> to the DMA direction. While at it, reorganize the code into a chain of
> if - else if - else to avoid useless affectations and debug messages.
>
> Fixes: dbf9bfe61571 ("[SCSI] pm8001: add SAS/SATA HBA driver")
> Signed-off-by: Damien Le Moal <damien.lemoal@opensource.wdc.com>
Reviewed-by: Jack Wang <jinpu.wang@ionos.com>
thx!


> ---
>  drivers/scsi/pm8001/pm8001_hwi.c | 14 +++++++-------
>  drivers/scsi/pm8001/pm80xx_hwi.c | 13 ++++++-------
>  2 files changed, 13 insertions(+), 14 deletions(-)
>
> diff --git a/drivers/scsi/pm8001/pm8001_hwi.c b/drivers/scsi/pm8001/pm8001_hwi.c
> index e20a1d4db026..c0215a35a7b5 100644
> --- a/drivers/scsi/pm8001/pm8001_hwi.c
> +++ b/drivers/scsi/pm8001/pm8001_hwi.c
> @@ -4265,22 +4265,22 @@ static int pm8001_chip_sata_req(struct pm8001_hba_info *pm8001_ha,
>         u32  opc = OPC_INB_SATA_HOST_OPSTART;
>         memset(&sata_cmd, 0, sizeof(sata_cmd));
>         circularQ = &pm8001_ha->inbnd_q_tbl[0];
> -       if (task->data_dir == DMA_NONE) {
> +
> +       if (task->data_dir == DMA_NONE && !task->ata_task.use_ncq) {
>                 ATAP = 0x04;  /* no data*/
>                 pm8001_dbg(pm8001_ha, IO, "no data\n");
>         } else if (likely(!task->ata_task.device_control_reg_update)) {
> -               if (task->ata_task.dma_xfer) {
> +               if (task->ata_task.use_ncq &&
> +                   dev->sata_dev.class != ATA_DEV_ATAPI) {
> +                       ATAP = 0x07; /* FPDMA */
> +                       pm8001_dbg(pm8001_ha, IO, "FPDMA\n");
> +               } else if (task->ata_task.dma_xfer) {
>                         ATAP = 0x06; /* DMA */
>                         pm8001_dbg(pm8001_ha, IO, "DMA\n");
>                 } else {
>                         ATAP = 0x05; /* PIO*/
>                         pm8001_dbg(pm8001_ha, IO, "PIO\n");
>                 }
> -               if (task->ata_task.use_ncq &&
> -                       dev->sata_dev.class != ATA_DEV_ATAPI) {
> -                       ATAP = 0x07; /* FPDMA */
> -                       pm8001_dbg(pm8001_ha, IO, "FPDMA\n");
> -               }
>         }
>         if (task->ata_task.use_ncq && pm8001_get_ncq_tag(task, &hdr_tag)) {
>                 task->ata_task.fis.sector_count |= (u8) (hdr_tag << 3);
> diff --git a/drivers/scsi/pm8001/pm80xx_hwi.c b/drivers/scsi/pm8001/pm80xx_hwi.c
> index 60c305f987b5..3deb89b11d2f 100644
> --- a/drivers/scsi/pm8001/pm80xx_hwi.c
> +++ b/drivers/scsi/pm8001/pm80xx_hwi.c
> @@ -4546,22 +4546,21 @@ static int pm80xx_chip_sata_req(struct pm8001_hba_info *pm8001_ha,
>         q_index = (u32) (cpu_id) % (pm8001_ha->max_q_num);
>         circularQ = &pm8001_ha->inbnd_q_tbl[q_index];
>
> -       if (task->data_dir == DMA_NONE) {
> +       if (task->data_dir == DMA_NONE && !task->ata_task.use_ncq) {
>                 ATAP = 0x04; /* no data*/
>                 pm8001_dbg(pm8001_ha, IO, "no data\n");
>         } else if (likely(!task->ata_task.device_control_reg_update)) {
> -               if (task->ata_task.dma_xfer) {
> +               if (task->ata_task.use_ncq &&
> +                   dev->sata_dev.class != ATA_DEV_ATAPI) {
> +                       ATAP = 0x07; /* FPDMA */
> +                       pm8001_dbg(pm8001_ha, IO, "FPDMA\n");
> +               } else if (task->ata_task.dma_xfer) {
>                         ATAP = 0x06; /* DMA */
>                         pm8001_dbg(pm8001_ha, IO, "DMA\n");
>                 } else {
>                         ATAP = 0x05; /* PIO*/
>                         pm8001_dbg(pm8001_ha, IO, "PIO\n");
>                 }
> -               if (task->ata_task.use_ncq &&
> -                   dev->sata_dev.class != ATA_DEV_ATAPI) {
> -                       ATAP = 0x07; /* FPDMA */
> -                       pm8001_dbg(pm8001_ha, IO, "FPDMA\n");
> -               }
>         }
>         if (task->ata_task.use_ncq && pm8001_get_ncq_tag(task, &hdr_tag)) {
>                 task->ata_task.fis.sector_count |= (u8) (hdr_tag << 3);
> --
> 2.34.1
>

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH v4 15/31] scsi: pm8001: Fix NCQ NON DATA command completion handling
  2022-02-17 13:29 ` [PATCH v4 15/31] scsi: pm8001: Fix NCQ NON DATA command completion handling Damien Le Moal
@ 2022-02-17 19:28   ` Jinpu Wang
  0 siblings, 0 replies; 65+ messages in thread
From: Jinpu Wang @ 2022-02-17 19:28 UTC (permalink / raw)
  To: Damien Le Moal
  Cc: linux-scsi, Martin K . Petersen, Jack Wang, John Garry,
	Xiang Chen, Jason Yan, Luo Jiaxing

On Thu, Feb 17, 2022 at 2:30 PM Damien Le Moal
<damien.lemoal@opensource.wdc.com> wrote:
>
> NCQ NON DATA is an NCQ command with the DMA_NONE DMA direction and so a
> register-device-to-host-FIS response is expected for it.
>
> However, for an IO_SUCCESS case, mpi_sata_completion() expects a
> set-device-bits-FIS for any ata task with an use_ncq field true, which
> includes NCQ NON DATA commands.
>
> Fix this to correctly treat NCQ NON DATA commands as non-data by also
> testing for the DMA_NONE DMA direction.
>
> Fixes: dbf9bfe61571 ("[SCSI] pm8001: add SAS/SATA HBA driver")
> Signed-off-by: Damien Le Moal <damien.lemoal@opensource.wdc.com>
Reviewed-by: Jack Wang <jinpu.wang@ionos.com>
thx!
> ---
>  drivers/scsi/pm8001/pm8001_hwi.c | 3 ++-
>  drivers/scsi/pm8001/pm80xx_hwi.c | 3 ++-
>  2 files changed, 4 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/scsi/pm8001/pm8001_hwi.c b/drivers/scsi/pm8001/pm8001_hwi.c
> index c0215a35a7b5..8149cc0d1ecd 100644
> --- a/drivers/scsi/pm8001/pm8001_hwi.c
> +++ b/drivers/scsi/pm8001/pm8001_hwi.c
> @@ -2415,7 +2415,8 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb)
>                                 len = sizeof(struct pio_setup_fis);
>                                 pm8001_dbg(pm8001_ha, IO,
>                                            "PIO read len = %d\n", len);
> -                       } else if (t->ata_task.use_ncq) {
> +                       } else if (t->ata_task.use_ncq &&
> +                                  t->data_dir != DMA_NONE) {
>                                 len = sizeof(struct set_dev_bits_fis);
>                                 pm8001_dbg(pm8001_ha, IO, "FPDMA len = %d\n",
>                                            len);
> diff --git a/drivers/scsi/pm8001/pm80xx_hwi.c b/drivers/scsi/pm8001/pm80xx_hwi.c
> index 3deb89b11d2f..ac2178a13e4c 100644
> --- a/drivers/scsi/pm8001/pm80xx_hwi.c
> +++ b/drivers/scsi/pm8001/pm80xx_hwi.c
> @@ -2507,7 +2507,8 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha,
>                                 len = sizeof(struct pio_setup_fis);
>                                 pm8001_dbg(pm8001_ha, IO,
>                                            "PIO read len = %d\n", len);
> -                       } else if (t->ata_task.use_ncq) {
> +                       } else if (t->ata_task.use_ncq &&
> +                                  t->data_dir != DMA_NONE) {
>                                 len = sizeof(struct set_dev_bits_fis);
>                                 pm8001_dbg(pm8001_ha, IO, "FPDMA len = %d\n",
>                                            len);
> --
> 2.34.1
>

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH v4 16/31] scsi: pm8001: Fix abort all task initialization
  2022-02-17 13:29 ` [PATCH v4 16/31] scsi: pm8001: Fix abort all task initialization Damien Le Moal
@ 2022-02-17 19:30   ` Jinpu Wang
  0 siblings, 0 replies; 65+ messages in thread
From: Jinpu Wang @ 2022-02-17 19:30 UTC (permalink / raw)
  To: Damien Le Moal
  Cc: linux-scsi, Martin K . Petersen, Jack Wang, John Garry,
	Xiang Chen, Jason Yan, Luo Jiaxing

On Thu, Feb 17, 2022 at 2:30 PM Damien Le Moal
<damien.lemoal@opensource.wdc.com> wrote:
>
> In pm80xx_send_abort_all(), the n_elem field of the ccb used is not
> initialized to 0. This missing initialization sometimes lead to the
> task completion path seeing the ccb with a non-zero n_elem resulting in
> the execution of invalid dma_unmap_sg() calls in pm8001_ccb_task_free(),
> causing a crash such as:
>
> [  197.676341] RIP: 0010:iommu_dma_unmap_sg+0x6d/0x280
> [  197.700204] RSP: 0018:ffff889bbcf89c88 EFLAGS: 00010012
> [  197.705485] RAX: dffffc0000000000 RBX: 0000000000000000 RCX: ffffffff83d0bda0
> [  197.712687] RDX: 0000000000000002 RSI: 0000000000000000 RDI: ffff88810dffc0d0
> [  197.719887] RBP: 0000000000000000 R08: 0000000000000000 R09: ffff8881c790098b
> [  197.727089] R10: ffffed1038f20131 R11: 0000000000000001 R12: 0000000000000000
> [  197.734296] R13: ffff88810dffc0d0 R14: 0000000000000010 R15: 0000000000000000
> [  197.741493] FS:  0000000000000000(0000) GS:ffff889bbcf80000(0000) knlGS:0000000000000000
> [  197.749659] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
> [  197.755459] CR2: 00007f16c1b42734 CR3: 0000000004814000 CR4: 0000000000350ee0
> [  197.762656] Call Trace:
> [  197.765127]  <IRQ>
> [  197.767162]  pm8001_ccb_task_free+0x5f1/0x820 [pm80xx]
> [  197.772364]  ? do_raw_spin_unlock+0x54/0x220
> [  197.776680]  pm8001_mpi_task_abort_resp+0x2ce/0x4f0 [pm80xx]
> [  197.782406]  process_oq+0xe85/0x7890 [pm80xx]
> [  197.786817]  ? lock_acquire+0x194/0x490
> [  197.790697]  ? handle_irq_event+0x10e/0x1b0
> [  197.794920]  ? mpi_sata_completion+0x2d70/0x2d70 [pm80xx]
> [  197.800378]  ? __wake_up_bit+0x100/0x100
> [  197.804340]  ? lock_is_held_type+0x98/0x110
> [  197.808565]  pm80xx_chip_isr+0x94/0x130 [pm80xx]
> [  197.813243]  tasklet_action_common.constprop.0+0x24b/0x2f0
> [  197.818785]  __do_softirq+0x1b5/0x82d
> [  197.822485]  ? do_raw_spin_unlock+0x54/0x220
> [  197.826799]  __irq_exit_rcu+0x17e/0x1e0
> [  197.830678]  irq_exit_rcu+0xa/0x20
> [  197.834114]  common_interrupt+0x78/0x90
> [  197.840051]  </IRQ>
> [  197.844236]  <TASK>
> [  197.848397]  asm_common_interrupt+0x1e/0x40
>
> Avoid this issue by always initializing the ccb n_elem field to 0 in
> pm8001_send_abort_all(), pm8001_send_read_log() and
> pm80xx_send_abort_all().
>
> Fixes: c6b9ef5779c3 ("[SCSI] pm80xx: NCQ error handling changes")
> Signed-off-by: Damien Le Moal <damien.lemoal@opensource.wdc.com>
Reviewed-by: Jack Wang <jinpu.wang@ionos.com>
thx
> ---
>  drivers/scsi/pm8001/pm8001_hwi.c | 2 ++
>  drivers/scsi/pm8001/pm80xx_hwi.c | 1 +
>  2 files changed, 3 insertions(+)
>
> diff --git a/drivers/scsi/pm8001/pm8001_hwi.c b/drivers/scsi/pm8001/pm8001_hwi.c
> index 8149cc0d1ecd..35d62e5c9200 100644
> --- a/drivers/scsi/pm8001/pm8001_hwi.c
> +++ b/drivers/scsi/pm8001/pm8001_hwi.c
> @@ -1787,6 +1787,7 @@ static void pm8001_send_abort_all(struct pm8001_hba_info *pm8001_ha,
>         ccb->device = pm8001_ha_dev;
>         ccb->ccb_tag = ccb_tag;
>         ccb->task = task;
> +       ccb->n_elem = 0;
>
>         circularQ = &pm8001_ha->inbnd_q_tbl[0];
>
> @@ -1848,6 +1849,7 @@ static void pm8001_send_read_log(struct pm8001_hba_info *pm8001_ha,
>         ccb->device = pm8001_ha_dev;
>         ccb->ccb_tag = ccb_tag;
>         ccb->task = task;
> +       ccb->n_elem = 0;
>         pm8001_ha_dev->id |= NCQ_READ_LOG_FLAG;
>         pm8001_ha_dev->id |= NCQ_2ND_RLE_FLAG;
>
> diff --git a/drivers/scsi/pm8001/pm80xx_hwi.c b/drivers/scsi/pm8001/pm80xx_hwi.c
> index ac2178a13e4c..8fd38e54f07c 100644
> --- a/drivers/scsi/pm8001/pm80xx_hwi.c
> +++ b/drivers/scsi/pm8001/pm80xx_hwi.c
> @@ -1800,6 +1800,7 @@ static void pm80xx_send_abort_all(struct pm8001_hba_info *pm8001_ha,
>         ccb->device = pm8001_ha_dev;
>         ccb->ccb_tag = ccb_tag;
>         ccb->task = task;
> +       ccb->n_elem = 0;
>
>         circularQ = &pm8001_ha->inbnd_q_tbl[0];
>
> --
> 2.34.1
>

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH v4 17/31] scsi: pm8001: Fix pm8001_tag_alloc() failures handling
  2022-02-17 13:29 ` [PATCH v4 17/31] scsi: pm8001: Fix pm8001_tag_alloc() failures handling Damien Le Moal
@ 2022-02-17 19:31   ` Jinpu Wang
  0 siblings, 0 replies; 65+ messages in thread
From: Jinpu Wang @ 2022-02-17 19:31 UTC (permalink / raw)
  To: Damien Le Moal
  Cc: linux-scsi, Martin K . Petersen, Jack Wang, John Garry,
	Xiang Chen, Jason Yan, Luo Jiaxing

On Thu, Feb 17, 2022 at 2:30 PM Damien Le Moal
<damien.lemoal@opensource.wdc.com> wrote:
>
> In mpi_set_phy_profile_req() and in pm8001_set_phy_profile_single(), if
> pm8001_tag_alloc() fails to allocate a new tag, a warning message is
> issued but the uninitialized tag variable is still used to build a
> command. Avoid this by returning early in case of tag allocation
> failure.
>
> Also make sure to always return the error code returned by
> pm8001_tag_alloc() when this function fails instead of an arbitrary
> value.
>
> Signed-off-by: Damien Le Moal <damien.lemoal@opensource.wdc.com>
> Reviewed-by: John Garry <john.garry@huawei.com>
Reviewed-by: Jack Wang <jinpu.wang@ionos.com>
thx
> ---
>  drivers/scsi/pm8001/pm80xx_hwi.c | 15 ++++++++++-----
>  1 file changed, 10 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/scsi/pm8001/pm80xx_hwi.c b/drivers/scsi/pm8001/pm80xx_hwi.c
> index 8fd38e54f07c..76260d06b6be 100644
> --- a/drivers/scsi/pm8001/pm80xx_hwi.c
> +++ b/drivers/scsi/pm8001/pm80xx_hwi.c
> @@ -1191,7 +1191,7 @@ pm80xx_set_thermal_config(struct pm8001_hba_info *pm8001_ha)
>         memset(&payload, 0, sizeof(struct set_ctrl_cfg_req));
>         rc = pm8001_tag_alloc(pm8001_ha, &tag);
>         if (rc)
> -               return -1;
> +               return rc;
>
>         circularQ = &pm8001_ha->inbnd_q_tbl[0];
>         payload.tag = cpu_to_le32(tag);
> @@ -1240,7 +1240,7 @@ pm80xx_set_sas_protocol_timer_config(struct pm8001_hba_info *pm8001_ha)
>         rc = pm8001_tag_alloc(pm8001_ha, &tag);
>
>         if (rc)
> -               return -1;
> +               return rc;
>
>         circularQ = &pm8001_ha->inbnd_q_tbl[0];
>         payload.tag = cpu_to_le32(tag);
> @@ -1398,7 +1398,7 @@ static int pm80xx_encrypt_update(struct pm8001_hba_info *pm8001_ha)
>         memset(&payload, 0, sizeof(struct kek_mgmt_req));
>         rc = pm8001_tag_alloc(pm8001_ha, &tag);
>         if (rc)
> -               return -1;
> +               return rc;
>
>         circularQ = &pm8001_ha->inbnd_q_tbl[0];
>         payload.tag = cpu_to_le32(tag);
> @@ -4967,8 +4967,11 @@ static void mpi_set_phy_profile_req(struct pm8001_hba_info *pm8001_ha,
>
>         memset(&payload, 0, sizeof(payload));
>         rc = pm8001_tag_alloc(pm8001_ha, &tag);
> -       if (rc)
> +       if (rc) {
>                 pm8001_dbg(pm8001_ha, FAIL, "Invalid tag\n");
> +               return;
> +       }
> +
>         circularQ = &pm8001_ha->inbnd_q_tbl[0];
>         payload.tag = cpu_to_le32(tag);
>         payload.ppc_phyid =
> @@ -5010,8 +5013,10 @@ void pm8001_set_phy_profile_single(struct pm8001_hba_info *pm8001_ha,
>         memset(&payload, 0, sizeof(payload));
>
>         rc = pm8001_tag_alloc(pm8001_ha, &tag);
> -       if (rc)
> +       if (rc) {
>                 pm8001_dbg(pm8001_ha, INIT, "Invalid tag\n");
> +               return;
> +       }
>
>         circularQ = &pm8001_ha->inbnd_q_tbl[0];
>         opc = OPC_INB_SET_PHY_PROFILE;
> --
> 2.34.1
>

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH v4 18/31] scsi: pm8001: Fix pm80xx_chip_phy_ctl_req()
  2022-02-17 13:29 ` [PATCH v4 18/31] scsi: pm8001: Fix pm80xx_chip_phy_ctl_req() Damien Le Moal
@ 2022-02-17 19:33   ` Jinpu Wang
  0 siblings, 0 replies; 65+ messages in thread
From: Jinpu Wang @ 2022-02-17 19:33 UTC (permalink / raw)
  To: Damien Le Moal
  Cc: linux-scsi, Martin K . Petersen, Jack Wang, John Garry,
	Xiang Chen, Jason Yan, Luo Jiaxing

On Thu, Feb 17, 2022 at 2:30 PM Damien Le Moal
<damien.lemoal@opensource.wdc.com> wrote:
>
> If pm8001_mpi_build_cmd() fails, the allocated tag should be freed.
>
> Signed-off-by: Damien Le Moal <damien.lemoal@opensource.wdc.com>
Reviewed-by: Jack Wang <jinpu.wang@ionos.com>
> ---
>  drivers/scsi/pm8001/pm80xx_hwi.c | 9 +++++++--
>  1 file changed, 7 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/scsi/pm8001/pm80xx_hwi.c b/drivers/scsi/pm8001/pm80xx_hwi.c
> index 76260d06b6be..a5a99d23cfbe 100644
> --- a/drivers/scsi/pm8001/pm80xx_hwi.c
> +++ b/drivers/scsi/pm8001/pm80xx_hwi.c
> @@ -4920,8 +4920,13 @@ static int pm80xx_chip_phy_ctl_req(struct pm8001_hba_info *pm8001_ha,
>         payload.tag = cpu_to_le32(tag);
>         payload.phyop_phyid =
>                 cpu_to_le32(((phy_op & 0xFF) << 8) | (phyId & 0xFF));
> -       return pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &payload,
> -                       sizeof(payload), 0);
> +
> +       rc = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &payload,
> +                                 sizeof(payload), 0);
> +       if (rc)
> +               pm8001_tag_free(pm8001_ha, tag);
> +
> +       return rc;
>  }
>
>  static u32 pm80xx_chip_is_our_interrupt(struct pm8001_hba_info *pm8001_ha)
> --
> 2.34.1
>

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH v4 19/31] scsi: pm8001: Fix pm8001_mpi_task_abort_resp()
  2022-02-17 13:29 ` [PATCH v4 19/31] scsi: pm8001: Fix pm8001_mpi_task_abort_resp() Damien Le Moal
@ 2022-02-17 19:35   ` Jinpu Wang
  0 siblings, 0 replies; 65+ messages in thread
From: Jinpu Wang @ 2022-02-17 19:35 UTC (permalink / raw)
  To: Damien Le Moal
  Cc: linux-scsi, Martin K . Petersen, Jack Wang, John Garry,
	Xiang Chen, Jason Yan, Luo Jiaxing

On Thu, Feb 17, 2022 at 2:30 PM Damien Le Moal
<damien.lemoal@opensource.wdc.com> wrote:
>
> The call to pm8001_ccb_task_free() at the end of
> pm8001_mpi_task_abort_resp() already frees the ccb tag. So when the
> device NCQ_ABORT_ALL_FLAG is set, the tag should not be freed again.
> Also change the hardcoded 0xBFFFFFFF value to ~NCQ_ABORT_ALL_FLAG as it
> ought to be.
>
> Signed-off-by: Damien Le Moal <damien.lemoal@opensource.wdc.com>
Reviewed-by: Jack Wang <jinpu.wang@ionos.com>
> ---
>  drivers/scsi/pm8001/pm8001_hwi.c | 7 +++----
>  1 file changed, 3 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/scsi/pm8001/pm8001_hwi.c b/drivers/scsi/pm8001/pm8001_hwi.c
> index 35d62e5c9200..5cad5504301e 100644
> --- a/drivers/scsi/pm8001/pm8001_hwi.c
> +++ b/drivers/scsi/pm8001/pm8001_hwi.c
> @@ -3700,12 +3700,11 @@ int pm8001_mpi_task_abort_resp(struct pm8001_hba_info *pm8001_ha, void *piomb)
>         mb();
>
>         if (pm8001_dev->id & NCQ_ABORT_ALL_FLAG) {
> -               pm8001_tag_free(pm8001_ha, tag);
>                 sas_free_task(t);
> -               /* clear the flag */
> -               pm8001_dev->id &= 0xBFFFFFFF;
> -       } else
> +               pm8001_dev->id &= ~NCQ_ABORT_ALL_FLAG;
> +       } else {
>                 t->task_done(t);
> +       }
>
>         return 0;
>  }
> --
> 2.34.1
>

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH v4 20/31] scsi: pm8001: Fix tag values handling
  2022-02-17 13:29 ` [PATCH v4 20/31] scsi: pm8001: Fix tag values handling Damien Le Moal
@ 2022-02-17 19:39   ` Jinpu Wang
  0 siblings, 0 replies; 65+ messages in thread
From: Jinpu Wang @ 2022-02-17 19:39 UTC (permalink / raw)
  To: Damien Le Moal
  Cc: linux-scsi, Martin K . Petersen, Jack Wang, John Garry,
	Xiang Chen, Jason Yan, Luo Jiaxing

On Thu, Feb 17, 2022 at 2:30 PM Damien Le Moal
<damien.lemoal@opensource.wdc.com> wrote:
>
> The function pm8001_tag_alloc() determines free tags using the function
> find_first_zero_bit() which can return 0 when the first bit of the
> bitmap being inspected is 0. As such, tag 0 is a valid tag value that
> should not be dismissed as invalid. Fix the functions pm8001_work_fn(),
> mpi_sata_completion(), pm8001_mpi_task_abort_resp() and
> pm8001_open_reject_retry() to not dismiss 0 tags as invalid.
>
> The value 0xffffffff is used for invalid tags for unused ccb
> information structures. Add the macro definition PM8001_INVALID_TAG to
> define this value.
>
> Signed-off-by: Damien Le Moal <damien.lemoal@opensource.wdc.com>
Reviewed-by: Jack Wang <jinpu.wang@ionos.com>
> ---
>  drivers/scsi/pm8001/pm8001_hwi.c  | 52 +++++++++++--------------------
>  drivers/scsi/pm8001/pm8001_init.c |  3 +-
>  drivers/scsi/pm8001/pm8001_sas.c  | 13 ++++----
>  drivers/scsi/pm8001/pm8001_sas.h  |  2 ++
>  drivers/scsi/pm8001/pm80xx_hwi.c  |  5 ---
>  5 files changed, 28 insertions(+), 47 deletions(-)
>
> diff --git a/drivers/scsi/pm8001/pm8001_hwi.c b/drivers/scsi/pm8001/pm8001_hwi.c
> index 5cad5504301e..3dc628b0384d 100644
> --- a/drivers/scsi/pm8001/pm8001_hwi.c
> +++ b/drivers/scsi/pm8001/pm8001_hwi.c
> @@ -1522,7 +1522,6 @@ void pm8001_work_fn(struct work_struct *work)
>         case IO_XFER_ERROR_BREAK:
>         {       /* This one stashes the sas_task instead */
>                 struct sas_task *t = (struct sas_task *)pm8001_dev;
> -               u32 tag;
>                 struct pm8001_ccb_info *ccb;
>                 struct pm8001_hba_info *pm8001_ha = pw->pm8001_ha;
>                 unsigned long flags, flags1;
> @@ -1544,8 +1543,8 @@ void pm8001_work_fn(struct work_struct *work)
>                 /* Search for a possible ccb that matches the task */
>                 for (i = 0; ccb = NULL, i < PM8001_MAX_CCB; i++) {
>                         ccb = &pm8001_ha->ccb_info[i];
> -                       tag = ccb->ccb_tag;
> -                       if ((tag != 0xFFFFFFFF) && (ccb->task == t))
> +                       if ((ccb->ccb_tag != PM8001_INVALID_TAG) &&
> +                           (ccb->task == t))
>                                 break;
>                 }
>                 if (!ccb) {
> @@ -1566,11 +1565,11 @@ void pm8001_work_fn(struct work_struct *work)
>                         spin_unlock_irqrestore(&t->task_state_lock, flags1);
>                         pm8001_dbg(pm8001_ha, FAIL, "task 0x%p done with event 0x%x resp 0x%x stat 0x%x but aborted by upper layer!\n",
>                                    t, pw->handler, ts->resp, ts->stat);
> -                       pm8001_ccb_task_free(pm8001_ha, t, ccb, tag);
> +                       pm8001_ccb_task_free(pm8001_ha, t, ccb, ccb->ccb_tag);
>                         spin_unlock_irqrestore(&pm8001_ha->lock, flags);
>                 } else {
>                         spin_unlock_irqrestore(&t->task_state_lock, flags1);
> -                       pm8001_ccb_task_free(pm8001_ha, t, ccb, tag);
> +                       pm8001_ccb_task_free(pm8001_ha, t, ccb, ccb->ccb_tag);
>                         mb();/* in order to force CPU ordering */
>                         spin_unlock_irqrestore(&pm8001_ha->lock, flags);
>                         t->task_done(t);
> @@ -1579,7 +1578,6 @@ void pm8001_work_fn(struct work_struct *work)
>         case IO_XFER_OPEN_RETRY_TIMEOUT:
>         {       /* This one stashes the sas_task instead */
>                 struct sas_task *t = (struct sas_task *)pm8001_dev;
> -               u32 tag;
>                 struct pm8001_ccb_info *ccb;
>                 struct pm8001_hba_info *pm8001_ha = pw->pm8001_ha;
>                 unsigned long flags, flags1;
> @@ -1613,8 +1611,8 @@ void pm8001_work_fn(struct work_struct *work)
>                 /* Search for a possible ccb that matches the task */
>                 for (i = 0; ccb = NULL, i < PM8001_MAX_CCB; i++) {
>                         ccb = &pm8001_ha->ccb_info[i];
> -                       tag = ccb->ccb_tag;
> -                       if ((tag != 0xFFFFFFFF) && (ccb->task == t))
> +                       if ((ccb->ccb_tag != PM8001_INVALID_TAG) &&
> +                           (ccb->task == t))
>                                 break;
>                 }
>                 if (!ccb) {
> @@ -1685,19 +1683,13 @@ void pm8001_work_fn(struct work_struct *work)
>                 struct task_status_struct *ts;
>                 struct sas_task *task;
>                 int i;
> -               u32 tag, device_id;
> +               u32 device_id;
>
>                 for (i = 0; ccb = NULL, i < PM8001_MAX_CCB; i++) {
>                         ccb = &pm8001_ha->ccb_info[i];
>                         task = ccb->task;
>                         ts = &task->task_status;
> -                       tag = ccb->ccb_tag;
> -                       /* check if tag is NULL */
> -                       if (!tag) {
> -                               pm8001_dbg(pm8001_ha, FAIL,
> -                                       "tag Null\n");
> -                               continue;
> -                       }
> +
>                         if (task != NULL) {
>                                 dev = task->dev;
>                                 if (!dev) {
> @@ -1706,10 +1698,11 @@ void pm8001_work_fn(struct work_struct *work)
>                                         continue;
>                                 }
>                                 /*complete sas task and update to top layer */
> -                               pm8001_ccb_task_free(pm8001_ha, task, ccb, tag);
> +                               pm8001_ccb_task_free(pm8001_ha, task, ccb,
> +                                                    ccb->ccb_tag);
>                                 ts->resp = SAS_TASK_COMPLETE;
>                                 task->task_done(task);
> -                       } else if (tag != 0xFFFFFFFF) {
> +                       } else if (ccb->ccb_tag != PM8001_INVALID_TAG) {
>                                 /* complete the internal commands/non-sas task */
>                                 pm8001_dev = ccb->device;
>                                 if (pm8001_dev->dcompletion) {
> @@ -1717,7 +1710,7 @@ void pm8001_work_fn(struct work_struct *work)
>                                         pm8001_dev->dcompletion = NULL;
>                                 }
>                                 complete(pm8001_ha->nvmd_completion);
> -                               pm8001_tag_free(pm8001_ha, tag);
> +                               pm8001_tag_free(pm8001_ha, ccb->ccb_tag);
>                         }
>                 }
>                 /* Deregister all the device ids  */
> @@ -2313,11 +2306,6 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb)
>         param = le32_to_cpu(psataPayload->param);
>         tag = le32_to_cpu(psataPayload->tag);
>
> -       if (!tag) {
> -               pm8001_dbg(pm8001_ha, FAIL, "tag null\n");
> -               return;
> -       }
> -
>         ccb = &pm8001_ha->ccb_info[tag];
>         t = ccb->task;
>         pm8001_dev = ccb->device;
> @@ -3051,7 +3039,7 @@ void pm8001_mpi_set_dev_state_resp(struct pm8001_hba_info *pm8001_ha,
>                    device_id, pds, nds, status);
>         complete(pm8001_dev->setds_completion);
>         ccb->task = NULL;
> -       ccb->ccb_tag = 0xFFFFFFFF;
> +       ccb->ccb_tag = PM8001_INVALID_TAG;
>         pm8001_tag_free(pm8001_ha, tag);
>  }
>
> @@ -3069,7 +3057,7 @@ void pm8001_mpi_set_nvmd_resp(struct pm8001_hba_info *pm8001_ha, void *piomb)
>                                 dlen_status);
>         }
>         ccb->task = NULL;
> -       ccb->ccb_tag = 0xFFFFFFFF;
> +       ccb->ccb_tag = PM8001_INVALID_TAG;
>         pm8001_tag_free(pm8001_ha, tag);
>  }
>
> @@ -3096,7 +3084,7 @@ pm8001_mpi_get_nvmd_resp(struct pm8001_hba_info *pm8001_ha, void *piomb)
>                  * freed by requesting path anywhere.
>                  */
>                 ccb->task = NULL;
> -               ccb->ccb_tag = 0xFFFFFFFF;
> +               ccb->ccb_tag = PM8001_INVALID_TAG;
>                 pm8001_tag_free(pm8001_ha, tag);
>                 return;
>         }
> @@ -3142,7 +3130,7 @@ pm8001_mpi_get_nvmd_resp(struct pm8001_hba_info *pm8001_ha, void *piomb)
>         complete(pm8001_ha->nvmd_completion);
>         pm8001_dbg(pm8001_ha, MSG, "Get nvmd data complete!\n");
>         ccb->task = NULL;
> -       ccb->ccb_tag = 0xFFFFFFFF;
> +       ccb->ccb_tag = PM8001_INVALID_TAG;
>         pm8001_tag_free(pm8001_ha, tag);
>  }
>
> @@ -3555,7 +3543,7 @@ int pm8001_mpi_reg_resp(struct pm8001_hba_info *pm8001_ha, void *piomb)
>         }
>         complete(pm8001_dev->dcompletion);
>         ccb->task = NULL;
> -       ccb->ccb_tag = 0xFFFFFFFF;
> +       ccb->ccb_tag = PM8001_INVALID_TAG;
>         pm8001_tag_free(pm8001_ha, htag);
>         return 0;
>  }
> @@ -3627,7 +3615,7 @@ int pm8001_mpi_fw_flash_update_resp(struct pm8001_hba_info *pm8001_ha,
>         }
>         kfree(ccb->fw_control_context);
>         ccb->task = NULL;
> -       ccb->ccb_tag = 0xFFFFFFFF;
> +       ccb->ccb_tag = PM8001_INVALID_TAG;
>         pm8001_tag_free(pm8001_ha, tag);
>         complete(pm8001_ha->nvmd_completion);
>         return 0;
> @@ -3663,10 +3651,6 @@ int pm8001_mpi_task_abort_resp(struct pm8001_hba_info *pm8001_ha, void *piomb)
>
>         status = le32_to_cpu(pPayload->status);
>         tag = le32_to_cpu(pPayload->tag);
> -       if (!tag) {
> -               pm8001_dbg(pm8001_ha, FAIL, " TAG NULL. RETURNING !!!\n");
> -               return -1;
> -       }
>
>         scp = le32_to_cpu(pPayload->scp);
>         ccb = &pm8001_ha->ccb_info[tag];
> diff --git a/drivers/scsi/pm8001/pm8001_init.c b/drivers/scsi/pm8001/pm8001_init.c
> index 4b9a26f008a9..8f44be8364dc 100644
> --- a/drivers/scsi/pm8001/pm8001_init.c
> +++ b/drivers/scsi/pm8001/pm8001_init.c
> @@ -1216,10 +1216,11 @@ pm8001_init_ccb_tag(struct pm8001_hba_info *pm8001_ha, struct Scsi_Host *shost,
>                         goto err_out;
>                 }
>                 pm8001_ha->ccb_info[i].task = NULL;
> -               pm8001_ha->ccb_info[i].ccb_tag = 0xffffffff;
> +               pm8001_ha->ccb_info[i].ccb_tag = PM8001_INVALID_TAG;
>                 pm8001_ha->ccb_info[i].device = NULL;
>                 ++pm8001_ha->tags_num;
>         }
> +
>         return 0;
>
>  err_out_noccb:
> diff --git a/drivers/scsi/pm8001/pm8001_sas.c b/drivers/scsi/pm8001/pm8001_sas.c
> index 4ab0ea9483f2..d0f5feb4f2d3 100644
> --- a/drivers/scsi/pm8001/pm8001_sas.c
> +++ b/drivers/scsi/pm8001/pm8001_sas.c
> @@ -563,7 +563,7 @@ void pm8001_ccb_task_free(struct pm8001_hba_info *pm8001_ha,
>
>         task->lldd_task = NULL;
>         ccb->task = NULL;
> -       ccb->ccb_tag = 0xFFFFFFFF;
> +       ccb->ccb_tag = PM8001_INVALID_TAG;
>         ccb->open_retry = 0;
>         pm8001_tag_free(pm8001_ha, ccb_idx);
>  }
> @@ -948,9 +948,11 @@ void pm8001_open_reject_retry(
>                 struct task_status_struct *ts;
>                 struct pm8001_device *pm8001_dev;
>                 unsigned long flags1;
> -               u32 tag;
>                 struct pm8001_ccb_info *ccb = &pm8001_ha->ccb_info[i];
>
> +               if (ccb->ccb_tag == PM8001_INVALID_TAG)
> +                       continue;
> +
>                 pm8001_dev = ccb->device;
>                 if (!pm8001_dev || (pm8001_dev->dev_type == SAS_PHY_UNUSED))
>                         continue;
> @@ -962,9 +964,6 @@ void pm8001_open_reject_retry(
>                                 continue;
>                 } else if (pm8001_dev != device_to_close)
>                         continue;
> -               tag = ccb->ccb_tag;
> -               if (!tag || (tag == 0xFFFFFFFF))
> -                       continue;
>                 task = ccb->task;
>                 if (!task || !task->task_done)
>                         continue;
> @@ -984,11 +983,11 @@ void pm8001_open_reject_retry(
>                                 & SAS_TASK_STATE_ABORTED))) {
>                         spin_unlock_irqrestore(&task->task_state_lock,
>                                 flags1);
> -                       pm8001_ccb_task_free(pm8001_ha, task, ccb, tag);
> +                       pm8001_ccb_task_free(pm8001_ha, task, ccb, ccb->ccb_tag);
>                 } else {
>                         spin_unlock_irqrestore(&task->task_state_lock,
>                                 flags1);
> -                       pm8001_ccb_task_free(pm8001_ha, task, ccb, tag);
> +                       pm8001_ccb_task_free(pm8001_ha, task, ccb, ccb->ccb_tag);
>                         mb();/* in order to force CPU ordering */
>                         spin_unlock_irqrestore(&pm8001_ha->lock, flags);
>                         task->task_done(task);
> diff --git a/drivers/scsi/pm8001/pm8001_sas.h b/drivers/scsi/pm8001/pm8001_sas.h
> index a17da1cebce1..1791cdf30276 100644
> --- a/drivers/scsi/pm8001/pm8001_sas.h
> +++ b/drivers/scsi/pm8001/pm8001_sas.h
> @@ -738,6 +738,8 @@ void pm8001_free_dev(struct pm8001_device *pm8001_dev);
>  /* ctl shared API */
>  extern const struct attribute_group *pm8001_host_groups[];
>
> +#define PM8001_INVALID_TAG     ((u32)-1)
> +
>  static inline void
>  pm8001_ccb_task_free_done(struct pm8001_hba_info *pm8001_ha,
>                         struct sas_task *task, struct pm8001_ccb_info *ccb,
> diff --git a/drivers/scsi/pm8001/pm80xx_hwi.c b/drivers/scsi/pm8001/pm80xx_hwi.c
> index a5a99d23cfbe..4419fdb0db78 100644
> --- a/drivers/scsi/pm8001/pm80xx_hwi.c
> +++ b/drivers/scsi/pm8001/pm80xx_hwi.c
> @@ -2402,11 +2402,6 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha,
>         param = le32_to_cpu(psataPayload->param);
>         tag = le32_to_cpu(psataPayload->tag);
>
> -       if (!tag) {
> -               pm8001_dbg(pm8001_ha, FAIL, "tag null\n");
> -               return;
> -       }
> -
>         ccb = &pm8001_ha->ccb_info[tag];
>         t = ccb->task;
>         pm8001_dev = ccb->device;
> --
> 2.34.1
>

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH v4 23/31] scsi: pm8001: fix memory leak in pm8001_chip_fw_flash_update_req()
  2022-02-17 13:29 ` [PATCH v4 23/31] scsi: pm8001: fix memory leak in pm8001_chip_fw_flash_update_req() Damien Le Moal
@ 2022-02-17 19:42   ` Jinpu Wang
  0 siblings, 0 replies; 65+ messages in thread
From: Jinpu Wang @ 2022-02-17 19:42 UTC (permalink / raw)
  To: Damien Le Moal
  Cc: linux-scsi, Martin K . Petersen, Jack Wang, John Garry,
	Xiang Chen, Jason Yan, Luo Jiaxing

On Thu, Feb 17, 2022 at 2:30 PM Damien Le Moal
<damien.lemoal@opensource.wdc.com> wrote:
>
> In pm8001_chip_fw_flash_update_build(), if
> pm8001_chip_fw_flash_update_build() fails, the struct fw_control_ex
> allocated must be freed.
>
> Signed-off-by: Damien Le Moal <damien.lemoal@opensource.wdc.com>
Reviewed-by: Jack Wang <jinpu.wang@ionos.com>

> ---
>  drivers/scsi/pm8001/pm8001_hwi.c | 4 +++-
>  1 file changed, 3 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/scsi/pm8001/pm8001_hwi.c b/drivers/scsi/pm8001/pm8001_hwi.c
> index 431fc9160637..41077c84eec9 100644
> --- a/drivers/scsi/pm8001/pm8001_hwi.c
> +++ b/drivers/scsi/pm8001/pm8001_hwi.c
> @@ -4873,8 +4873,10 @@ pm8001_chip_fw_flash_update_req(struct pm8001_hba_info *pm8001_ha,
>         ccb->ccb_tag = tag;
>         rc = pm8001_chip_fw_flash_update_build(pm8001_ha, &flash_update_info,
>                 tag);
> -       if (rc)
> +       if (rc) {
> +               kfree(fw_control_context);
>                 pm8001_tag_free(pm8001_ha, tag);
> +       }
>
>         return rc;
>  }
> --
> 2.34.1
>

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH v4 24/31] scsi: libsas: Simplify sas_ata_qc_issue() detection of NCQ commands
  2022-02-17 13:29 ` [PATCH v4 24/31] scsi: libsas: Simplify sas_ata_qc_issue() detection of NCQ commands Damien Le Moal
@ 2022-02-17 19:43   ` Jinpu Wang
  0 siblings, 0 replies; 65+ messages in thread
From: Jinpu Wang @ 2022-02-17 19:43 UTC (permalink / raw)
  To: Damien Le Moal
  Cc: linux-scsi, Martin K . Petersen, Jack Wang, John Garry,
	Xiang Chen, Jason Yan, Luo Jiaxing

On Thu, Feb 17, 2022 at 2:30 PM Damien Le Moal
<damien.lemoal@opensource.wdc.com> wrote:
>
> To detect if a command is NCQ, there is no need to test all possible NCQ
> command codes. Instead, use ata_is_ncq() to test the command protocol.
>
> Signed-off-by: Damien Le Moal <damien.lemoal@opensource.wdc.com>
Reviewed-by: Jack Wang <jinpu.wang@ionos.com>
> ---
>  drivers/scsi/libsas/sas_ata.c | 9 ++-------
>  1 file changed, 2 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/scsi/libsas/sas_ata.c b/drivers/scsi/libsas/sas_ata.c
> index 50f779088b6e..fcfc8fd4b14f 100644
> --- a/drivers/scsi/libsas/sas_ata.c
> +++ b/drivers/scsi/libsas/sas_ata.c
> @@ -181,14 +181,9 @@ static unsigned int sas_ata_qc_issue(struct ata_queued_cmd *qc)
>         task->task_proto = SAS_PROTOCOL_STP;
>         task->task_done = sas_ata_task_done;
>
> -       if (qc->tf.command == ATA_CMD_FPDMA_WRITE ||
> -           qc->tf.command == ATA_CMD_FPDMA_READ ||
> -           qc->tf.command == ATA_CMD_FPDMA_RECV ||
> -           qc->tf.command == ATA_CMD_FPDMA_SEND ||
> -           qc->tf.command == ATA_CMD_NCQ_NON_DATA) {
> -               /* Need to zero out the tag libata assigned us */
> +       /* For NCQ commands, zero out the tag libata assigned us */
> +       if (ata_is_ncq(qc->tf.protocol))
>                 qc->tf.nsect = 0;
> -       }
>
>         ata_tf_to_fis(&qc->tf, qc->dev->link->pmp, 1, (u8 *)&task->ata_task.fis);
>         task->uldd_task = qc;
> --
> 2.34.1
>

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH v4 25/31] scsi: pm8001: Simplify pm8001_get_ncq_tag()
  2022-02-17 13:29 ` [PATCH v4 25/31] scsi: pm8001: Simplify pm8001_get_ncq_tag() Damien Le Moal
@ 2022-02-17 19:43   ` Jinpu Wang
  0 siblings, 0 replies; 65+ messages in thread
From: Jinpu Wang @ 2022-02-17 19:43 UTC (permalink / raw)
  To: Damien Le Moal
  Cc: linux-scsi, Martin K . Petersen, Jack Wang, John Garry,
	Xiang Chen, Jason Yan, Luo Jiaxing

On Thu, Feb 17, 2022 at 2:30 PM Damien Le Moal
<damien.lemoal@opensource.wdc.com> wrote:
>
> To detect if a command is NCQ, there is no need to test all possible NCQ
> command codes. Instead, use ata_is_ncq() to test the command protocol.
>
> Reviewed-by: John Garry <john.garry@huawei.com>
> Signed-off-by: Damien Le Moal <damien.lemoal@opensource.wdc.com>
Reviewed-by: Jack Wang <jinpu.wang@ionos.com>
> ---
>  drivers/scsi/pm8001/pm8001_sas.c | 14 +++++---------
>  1 file changed, 5 insertions(+), 9 deletions(-)
>
> diff --git a/drivers/scsi/pm8001/pm8001_sas.c b/drivers/scsi/pm8001/pm8001_sas.c
> index 0440777a9135..1e60ad82635e 100644
> --- a/drivers/scsi/pm8001/pm8001_sas.c
> +++ b/drivers/scsi/pm8001/pm8001_sas.c
> @@ -304,16 +304,12 @@ static int pm8001_task_prep_smp(struct pm8001_hba_info *pm8001_ha,
>  u32 pm8001_get_ncq_tag(struct sas_task *task, u32 *tag)
>  {
>         struct ata_queued_cmd *qc = task->uldd_task;
> -       if (qc) {
> -               if (qc->tf.command == ATA_CMD_FPDMA_WRITE ||
> -                   qc->tf.command == ATA_CMD_FPDMA_READ ||
> -                   qc->tf.command == ATA_CMD_FPDMA_RECV ||
> -                   qc->tf.command == ATA_CMD_FPDMA_SEND ||
> -                   qc->tf.command == ATA_CMD_NCQ_NON_DATA) {
> -                       *tag = qc->tag;
> -                       return 1;
> -               }
> +
> +       if (qc && ata_is_ncq(qc->tf.protocol)) {
> +               *tag = qc->tag;
> +               return 1;
>         }
> +
>         return 0;
>  }
>
> --
> 2.34.1
>

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH v4 26/31] scsi: pm8001: Introduce ccb alloc/free helpers
  2022-02-17 13:29 ` [PATCH v4 26/31] scsi: pm8001: Introduce ccb alloc/free helpers Damien Le Moal
@ 2022-02-17 19:45   ` Jinpu Wang
  0 siblings, 0 replies; 65+ messages in thread
From: Jinpu Wang @ 2022-02-17 19:45 UTC (permalink / raw)
  To: Damien Le Moal
  Cc: linux-scsi, Martin K . Petersen, Jack Wang, John Garry,
	Xiang Chen, Jason Yan, Luo Jiaxing

On Thu, Feb 17, 2022 at 2:30 PM Damien Le Moal
<damien.lemoal@opensource.wdc.com> wrote:
>
> Introduce the pm8001_ccb_alloc() and pm8001_ccb_free() helpers to
> replace the typical code patterns:
>
>         res = pm8001_tag_alloc(pm8001_ha, &ccb_tag);
>         if (res)
>                 ...
>         ccb = &pm8001_ha->ccb_info[ccb_tag];
>         ccb->device = pm8001_ha_dev;
>         ccb->ccb_tag = ccb_tag;
>         ccb->task = task;
>         ccb->n_elem = 0;
>
> and
>
>         ccb->task = NULL;
>         ccb->ccb_tag = PM8001_INVALID_TAG;
>         pm8001_tag_free(pm8001_ha, tag);
>
> With the simpler function calls:
>
>         ccb = pm8001_ccb_alloc(pm8001_ha, pm8001_ha_dev, task);
>         if (!ccb)
>                 ...
>
> and
>
>         pm8001_ccb_free(pm8001_ha, ccb);
>
> The pm8001_ccb_alloc() helper ensures that all fields of the ccb info
> structure for the newly allocated tag are all initialized, except the
> buf_prd field. The pm8001_ccb_free() helper clears the initialized
> fields and the ccb tag to ensure that iteration over the adapter
> ccb_info array detects ccbs that are in use.
>
> All call site of the pm8001_tag_alloc() function that use a ccb info
> associated with an allocated tag are converted to use the new helpers.
>
> Signed-off-by: Damien Le Moal <damien.lemoal@opensource.wdc.com>
> Reviewed-by: John Garry <john.garry@huawei.com>
> ---
>  drivers/scsi/pm8001/pm8001_hwi.c | 180 +++++++++++++------------------
>  drivers/scsi/pm8001/pm8001_sas.c |  46 ++++----
>  drivers/scsi/pm8001/pm8001_sas.h |  47 ++++++++
>  drivers/scsi/pm8001/pm80xx_hwi.c |  64 +++++------
>  4 files changed, 166 insertions(+), 171 deletions(-)
so we saved 5 lines :)
Reviewed-by: Jack Wang <jinpu.wang@ionos.com>
>
> diff --git a/drivers/scsi/pm8001/pm8001_hwi.c b/drivers/scsi/pm8001/pm8001_hwi.c
> index 41077c84eec9..699fecc09267 100644
> --- a/drivers/scsi/pm8001/pm8001_hwi.c
> +++ b/drivers/scsi/pm8001/pm8001_hwi.c
> @@ -1710,7 +1710,7 @@ void pm8001_work_fn(struct work_struct *work)
>                                         pm8001_dev->dcompletion = NULL;
>                                 }
>                                 complete(pm8001_ha->nvmd_completion);
> -                               pm8001_tag_free(pm8001_ha, ccb->ccb_tag);
> +                               pm8001_ccb_free(pm8001_ha, ccb);
>                         }
>                 }
>                 /* Deregister all the device ids  */
> @@ -1749,8 +1749,6 @@ int pm8001_handle_event(struct pm8001_hba_info *pm8001_ha, void *data,
>  static void pm8001_send_abort_all(struct pm8001_hba_info *pm8001_ha,
>                 struct pm8001_device *pm8001_ha_dev)
>  {
> -       int res;
> -       u32 ccb_tag;
>         struct pm8001_ccb_info *ccb;
>         struct sas_task *task = NULL;
>         struct task_abort_req task_abort;
> @@ -1771,32 +1769,25 @@ static void pm8001_send_abort_all(struct pm8001_hba_info *pm8001_ha,
>
>         task->task_done = pm8001_task_done;
>
> -       res = pm8001_tag_alloc(pm8001_ha, &ccb_tag);
> -       if (res) {
> +       ccb = pm8001_ccb_alloc(pm8001_ha, pm8001_ha_dev, task);
> +       if (!ccb) {
>                 sas_free_task(task);
>                 return;
>         }
>
> -       ccb = &pm8001_ha->ccb_info[ccb_tag];
> -       ccb->device = pm8001_ha_dev;
> -       ccb->ccb_tag = ccb_tag;
> -       ccb->task = task;
> -       ccb->n_elem = 0;
> -
>         circularQ = &pm8001_ha->inbnd_q_tbl[0];
>
>         memset(&task_abort, 0, sizeof(task_abort));
>         task_abort.abort_all = cpu_to_le32(1);
>         task_abort.device_id = cpu_to_le32(pm8001_ha_dev->device_id);
> -       task_abort.tag = cpu_to_le32(ccb_tag);
> +       task_abort.tag = cpu_to_le32(ccb->ccb_tag);
>
>         ret = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &task_abort,
>                         sizeof(task_abort), 0);
>         if (ret) {
>                 sas_free_task(task);
> -               pm8001_tag_free(pm8001_ha, ccb_tag);
> +               pm8001_ccb_free(pm8001_ha, ccb);
>         }
> -
>  }
>
>  static void pm8001_send_read_log(struct pm8001_hba_info *pm8001_ha,
> @@ -1804,7 +1795,6 @@ static void pm8001_send_read_log(struct pm8001_hba_info *pm8001_ha,
>  {
>         struct sata_start_req sata_cmd;
>         int res;
> -       u32 ccb_tag;
>         struct pm8001_ccb_info *ccb;
>         struct sas_task *task = NULL;
>         struct host_to_dev_fis fis;
> @@ -1820,20 +1810,13 @@ static void pm8001_send_read_log(struct pm8001_hba_info *pm8001_ha,
>         }
>         task->task_done = pm8001_task_done;
>
> -       res = pm8001_tag_alloc(pm8001_ha, &ccb_tag);
> -       if (res) {
> -               sas_free_task(task);
> -               pm8001_dbg(pm8001_ha, FAIL, "cannot allocate tag !!!\n");
> -               return;
> -       }
> -
> -       /* allocate domain device by ourselves as libsas
> -        * is not going to provide any
> -       */
> +       /*
> +        * Allocate domain device by ourselves as libsas is not going to
> +        * provide any.
> +        */
>         dev = kzalloc(sizeof(struct domain_device), GFP_ATOMIC);
>         if (!dev) {
>                 sas_free_task(task);
> -               pm8001_tag_free(pm8001_ha, ccb_tag);
>                 pm8001_dbg(pm8001_ha, FAIL,
>                            "Domain device cannot be allocated\n");
>                 return;
> @@ -1841,11 +1824,13 @@ static void pm8001_send_read_log(struct pm8001_hba_info *pm8001_ha,
>         task->dev = dev;
>         task->dev->lldd_dev = pm8001_ha_dev;
>
> -       ccb = &pm8001_ha->ccb_info[ccb_tag];
> -       ccb->device = pm8001_ha_dev;
> -       ccb->ccb_tag = ccb_tag;
> -       ccb->task = task;
> -       ccb->n_elem = 0;
> +       ccb = pm8001_ccb_alloc(pm8001_ha, pm8001_ha_dev, task);
> +       if (!ccb) {
> +               sas_free_task(task);
> +               kfree(dev);
> +               return;
> +       }
> +
>         pm8001_ha_dev->id |= NCQ_READ_LOG_FLAG;
>         pm8001_ha_dev->id |= NCQ_2ND_RLE_FLAG;
>
> @@ -1860,7 +1845,7 @@ static void pm8001_send_read_log(struct pm8001_hba_info *pm8001_ha,
>         fis.lbal = 0x10;
>         fis.sector_count = 0x1;
>
> -       sata_cmd.tag = cpu_to_le32(ccb_tag);
> +       sata_cmd.tag = cpu_to_le32(ccb->ccb_tag);
>         sata_cmd.device_id = cpu_to_le32(pm8001_ha_dev->device_id);
>         sata_cmd.ncqtag_atap_dir_m = cpu_to_le32((0x1 << 7) | (0x5 << 9));
>         memcpy(&sata_cmd.sata_fis, &fis, sizeof(struct host_to_dev_fis));
> @@ -1869,7 +1854,7 @@ static void pm8001_send_read_log(struct pm8001_hba_info *pm8001_ha,
>                         sizeof(sata_cmd), 0);
>         if (res) {
>                 sas_free_task(task);
> -               pm8001_tag_free(pm8001_ha, ccb_tag);
> +               pm8001_ccb_free(pm8001_ha, ccb);
>                 kfree(dev);
>         }
>  }
> @@ -3038,12 +3023,12 @@ void pm8001_mpi_set_dev_state_resp(struct pm8001_hba_info *pm8001_ha,
>         u32 device_id = le32_to_cpu(pPayload->device_id);
>         u8 pds = le32_to_cpu(pPayload->pds_nds) & PDS_BITS;
>         u8 nds = le32_to_cpu(pPayload->pds_nds) & NDS_BITS;
> -       pm8001_dbg(pm8001_ha, MSG, "Set device id = 0x%x state from 0x%x to 0x%x status = 0x%x!\n",
> +
> +       pm8001_dbg(pm8001_ha, MSG,
> +                  "Set device id = 0x%x state from 0x%x to 0x%x status = 0x%x!\n",
>                    device_id, pds, nds, status);
>         complete(pm8001_dev->setds_completion);
> -       ccb->task = NULL;
> -       ccb->ccb_tag = PM8001_INVALID_TAG;
> -       pm8001_tag_free(pm8001_ha, tag);
> +       pm8001_ccb_free(pm8001_ha, ccb);
>  }
>
>  void pm8001_mpi_set_nvmd_resp(struct pm8001_hba_info *pm8001_ha, void *piomb)
> @@ -3053,15 +3038,14 @@ void pm8001_mpi_set_nvmd_resp(struct pm8001_hba_info *pm8001_ha, void *piomb)
>         u32 tag = le32_to_cpu(pPayload->tag);
>         struct pm8001_ccb_info *ccb = &pm8001_ha->ccb_info[tag];
>         u32 dlen_status = le32_to_cpu(pPayload->dlen_status);
> +
>         complete(pm8001_ha->nvmd_completion);
>         pm8001_dbg(pm8001_ha, MSG, "Set nvm data complete!\n");
>         if ((dlen_status & NVMD_STAT) != 0) {
>                 pm8001_dbg(pm8001_ha, FAIL, "Set nvm data error %x\n",
>                                 dlen_status);
>         }
> -       ccb->task = NULL;
> -       ccb->ccb_tag = PM8001_INVALID_TAG;
> -       pm8001_tag_free(pm8001_ha, tag);
> +       pm8001_ccb_free(pm8001_ha, ccb);
>  }
>
>  void
> @@ -3086,9 +3070,7 @@ pm8001_mpi_get_nvmd_resp(struct pm8001_hba_info *pm8001_ha, void *piomb)
>                 /* We should free tag during failure also, the tag is not being
>                  * freed by requesting path anywhere.
>                  */
> -               ccb->task = NULL;
> -               ccb->ccb_tag = PM8001_INVALID_TAG;
> -               pm8001_tag_free(pm8001_ha, tag);
> +               pm8001_ccb_free(pm8001_ha, ccb);
>                 return;
>         }
>         if (ir_tds_bn_dps_das_nvm & IPMode) {
> @@ -3132,9 +3114,7 @@ pm8001_mpi_get_nvmd_resp(struct pm8001_hba_info *pm8001_ha, void *piomb)
>          */
>         complete(pm8001_ha->nvmd_completion);
>         pm8001_dbg(pm8001_ha, MSG, "Get nvmd data complete!\n");
> -       ccb->task = NULL;
> -       ccb->ccb_tag = PM8001_INVALID_TAG;
> -       pm8001_tag_free(pm8001_ha, tag);
> +       pm8001_ccb_free(pm8001_ha, ccb);
>  }
>
>  int pm8001_mpi_local_phy_ctl(struct pm8001_hba_info *pm8001_ha, void *piomb)
> @@ -3545,9 +3525,7 @@ int pm8001_mpi_reg_resp(struct pm8001_hba_info *pm8001_ha, void *piomb)
>                 break;
>         }
>         complete(pm8001_dev->dcompletion);
> -       ccb->task = NULL;
> -       ccb->ccb_tag = PM8001_INVALID_TAG;
> -       pm8001_tag_free(pm8001_ha, htag);
> +       pm8001_ccb_free(pm8001_ha, ccb);
>         return 0;
>  }
>
> @@ -3580,6 +3558,7 @@ int pm8001_mpi_fw_flash_update_resp(struct pm8001_hba_info *pm8001_ha,
>                 (struct fw_flash_Update_resp *)(piomb + 4);
>         u32 tag = le32_to_cpu(ppayload->tag);
>         struct pm8001_ccb_info *ccb = &pm8001_ha->ccb_info[tag];
> +
>         status = le32_to_cpu(ppayload->status);
>         switch (status) {
>         case FLASH_UPDATE_COMPLETE_PENDING_REBOOT:
> @@ -3617,9 +3596,7 @@ int pm8001_mpi_fw_flash_update_resp(struct pm8001_hba_info *pm8001_ha,
>                 break;
>         }
>         kfree(ccb->fw_control_context);
> -       ccb->task = NULL;
> -       ccb->ccb_tag = PM8001_INVALID_TAG;
> -       pm8001_tag_free(pm8001_ha, tag);
> +       pm8001_ccb_free(pm8001_ha, ccb);
>         complete(pm8001_ha->nvmd_completion);
>         return 0;
>  }
> @@ -4412,7 +4389,7 @@ static int pm8001_chip_reg_dev_req(struct pm8001_hba_info *pm8001_ha,
>         u32 stp_sspsmp_sata = 0x4;
>         struct inbound_queue_table *circularQ;
>         u32 linkrate, phy_id;
> -       int rc, tag = 0xdeadbeef;
> +       int rc;
>         struct pm8001_ccb_info *ccb;
>         u8 retryFlag = 0x1;
>         u16 firstBurstSize = 0;
> @@ -4423,13 +4400,11 @@ static int pm8001_chip_reg_dev_req(struct pm8001_hba_info *pm8001_ha,
>         circularQ = &pm8001_ha->inbnd_q_tbl[0];
>
>         memset(&payload, 0, sizeof(payload));
> -       rc = pm8001_tag_alloc(pm8001_ha, &tag);
> -       if (rc)
> -               return rc;
> -       ccb = &pm8001_ha->ccb_info[tag];
> -       ccb->device = pm8001_dev;
> -       ccb->ccb_tag = tag;
> -       payload.tag = cpu_to_le32(tag);
> +       ccb = pm8001_ccb_alloc(pm8001_ha, pm8001_dev, NULL);
> +       if (!ccb)
> +               return -SAS_QUEUE_FULL;
> +
> +       payload.tag = cpu_to_le32(ccb->ccb_tag);
>         if (flag == 1)
>                 stp_sspsmp_sata = 0x02; /*direct attached sata */
>         else {
> @@ -4459,7 +4434,7 @@ static int pm8001_chip_reg_dev_req(struct pm8001_hba_info *pm8001_ha,
>         rc = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &payload,
>                         sizeof(payload), 0);
>         if (rc)
> -               pm8001_tag_free(pm8001_ha, tag);
> +               pm8001_ccb_free(pm8001_ha, ccb);
>
>         return rc;
>  }
> @@ -4624,7 +4599,6 @@ int pm8001_chip_get_nvmd_req(struct pm8001_hba_info *pm8001_ha,
>         u32 opc = OPC_INB_GET_NVMD_DATA;
>         u32 nvmd_type;
>         int rc;
> -       u32 tag;
>         struct pm8001_ccb_info *ccb;
>         struct inbound_queue_table *circularQ;
>         struct get_nvm_data_req nvmd_req;
> @@ -4639,15 +4613,15 @@ int pm8001_chip_get_nvmd_req(struct pm8001_hba_info *pm8001_ha,
>         fw_control_context->len = ioctl_payload->rd_length;
>         circularQ = &pm8001_ha->inbnd_q_tbl[0];
>         memset(&nvmd_req, 0, sizeof(nvmd_req));
> -       rc = pm8001_tag_alloc(pm8001_ha, &tag);
> -       if (rc) {
> +
> +       ccb = pm8001_ccb_alloc(pm8001_ha, NULL, NULL);
> +       if (!ccb) {
>                 kfree(fw_control_context);
> -               return rc;
> +               return -SAS_QUEUE_FULL;
>         }
> -       ccb = &pm8001_ha->ccb_info[tag];
> -       ccb->ccb_tag = tag;
>         ccb->fw_control_context = fw_control_context;
> -       nvmd_req.tag = cpu_to_le32(tag);
> +
> +       nvmd_req.tag = cpu_to_le32(ccb->ccb_tag);
>
>         switch (nvmd_type) {
>         case TWI_DEVICE: {
> @@ -4708,7 +4682,7 @@ int pm8001_chip_get_nvmd_req(struct pm8001_hba_info *pm8001_ha,
>                         sizeof(nvmd_req), 0);
>         if (rc) {
>                 kfree(fw_control_context);
> -               pm8001_tag_free(pm8001_ha, tag);
> +               pm8001_ccb_free(pm8001_ha, ccb);
>         }
>         return rc;
>  }
> @@ -4719,7 +4693,6 @@ int pm8001_chip_set_nvmd_req(struct pm8001_hba_info *pm8001_ha,
>         u32 opc = OPC_INB_SET_NVMD_DATA;
>         u32 nvmd_type;
>         int rc;
> -       u32 tag;
>         struct pm8001_ccb_info *ccb;
>         struct inbound_queue_table *circularQ;
>         struct set_nvm_data_req nvmd_req;
> @@ -4735,15 +4708,15 @@ int pm8001_chip_set_nvmd_req(struct pm8001_hba_info *pm8001_ha,
>                 &ioctl_payload->func_specific,
>                 ioctl_payload->wr_length);
>         memset(&nvmd_req, 0, sizeof(nvmd_req));
> -       rc = pm8001_tag_alloc(pm8001_ha, &tag);
> -       if (rc) {
> +
> +       ccb = pm8001_ccb_alloc(pm8001_ha, NULL, NULL);
> +       if (!ccb) {
>                 kfree(fw_control_context);
> -               return -EBUSY;
> +               return -SAS_QUEUE_FULL;
>         }
> -       ccb = &pm8001_ha->ccb_info[tag];
>         ccb->fw_control_context = fw_control_context;
> -       ccb->ccb_tag = tag;
> -       nvmd_req.tag = cpu_to_le32(tag);
> +
> +       nvmd_req.tag = cpu_to_le32(ccb->ccb_tag);
>         switch (nvmd_type) {
>         case TWI_DEVICE: {
>                 u32 twi_addr, twi_page_size;
> @@ -4793,7 +4766,7 @@ int pm8001_chip_set_nvmd_req(struct pm8001_hba_info *pm8001_ha,
>                         sizeof(nvmd_req), 0);
>         if (rc) {
>                 kfree(fw_control_context);
> -               pm8001_tag_free(pm8001_ha, tag);
> +               pm8001_ccb_free(pm8001_ha, ccb);
>         }
>         return rc;
>  }
> @@ -4839,7 +4812,6 @@ pm8001_chip_fw_flash_update_req(struct pm8001_hba_info *pm8001_ha,
>         struct fw_control_info *fw_control;
>         struct fw_control_ex *fw_control_context;
>         int rc;
> -       u32 tag;
>         struct pm8001_ccb_info *ccb;
>         void *buffer = pm8001_ha->memoryMap.region[FW_FLASH].virt_ptr;
>         dma_addr_t phys_addr = pm8001_ha->memoryMap.region[FW_FLASH].phys_addr;
> @@ -4863,19 +4835,19 @@ pm8001_chip_fw_flash_update_req(struct pm8001_hba_info *pm8001_ha,
>         fw_control_context->virtAddr = buffer;
>         fw_control_context->phys_addr = phys_addr;
>         fw_control_context->len = fw_control->len;
> -       rc = pm8001_tag_alloc(pm8001_ha, &tag);
> -       if (rc) {
> +
> +       ccb = pm8001_ccb_alloc(pm8001_ha, NULL, NULL);
> +       if (!ccb) {
>                 kfree(fw_control_context);
> -               return -EBUSY;
> +               return -SAS_QUEUE_FULL;
>         }
> -       ccb = &pm8001_ha->ccb_info[tag];
>         ccb->fw_control_context = fw_control_context;
> -       ccb->ccb_tag = tag;
> +
>         rc = pm8001_chip_fw_flash_update_build(pm8001_ha, &flash_update_info,
> -               tag);
> +                                              ccb->ccb_tag);
>         if (rc) {
>                 kfree(fw_control_context);
> -               pm8001_tag_free(pm8001_ha, tag);
> +               pm8001_ccb_free(pm8001_ha, ccb);
>         }
>
>         return rc;
> @@ -4967,26 +4939,25 @@ pm8001_chip_set_dev_state_req(struct pm8001_hba_info *pm8001_ha,
>         struct inbound_queue_table *circularQ;
>         struct pm8001_ccb_info *ccb;
>         int rc;
> -       u32 tag;
>         u32 opc = OPC_INB_SET_DEVICE_STATE;
> +
>         memset(&payload, 0, sizeof(payload));
> -       rc = pm8001_tag_alloc(pm8001_ha, &tag);
> -       if (rc)
> -               return -1;
> -       ccb = &pm8001_ha->ccb_info[tag];
> -       ccb->ccb_tag = tag;
> -       ccb->device = pm8001_dev;
> +
> +       ccb = pm8001_ccb_alloc(pm8001_ha, pm8001_dev, NULL);
> +       if (!ccb)
> +               return -SAS_QUEUE_FULL;
> +
>         circularQ = &pm8001_ha->inbnd_q_tbl[0];
> -       payload.tag = cpu_to_le32(tag);
> +       payload.tag = cpu_to_le32(ccb->ccb_tag);
>         payload.device_id = cpu_to_le32(pm8001_dev->device_id);
>         payload.nds = cpu_to_le32(state);
> +
>         rc = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &payload,
>                         sizeof(payload), 0);
>         if (rc)
> -               pm8001_tag_free(pm8001_ha, tag);
> +               pm8001_ccb_free(pm8001_ha, ccb);
>
>         return rc;
> -
>  }
>
>  static int
> @@ -4996,25 +4967,26 @@ pm8001_chip_sas_re_initialization(struct pm8001_hba_info *pm8001_ha)
>         struct inbound_queue_table *circularQ;
>         struct pm8001_ccb_info *ccb;
>         int rc;
> -       u32 tag;
>         u32 opc = OPC_INB_SAS_RE_INITIALIZE;
> +
>         memset(&payload, 0, sizeof(payload));
> -       rc = pm8001_tag_alloc(pm8001_ha, &tag);
> -       if (rc)
> -               return -ENOMEM;
> -       ccb = &pm8001_ha->ccb_info[tag];
> -       ccb->ccb_tag = tag;
> +
> +       ccb = pm8001_ccb_alloc(pm8001_ha, NULL, NULL);
> +       if (!ccb)
> +               return -SAS_QUEUE_FULL;
> +
>         circularQ = &pm8001_ha->inbnd_q_tbl[0];
> -       payload.tag = cpu_to_le32(tag);
> +       payload.tag = cpu_to_le32(ccb->ccb_tag);
>         payload.SSAHOLT = cpu_to_le32(0xd << 25);
>         payload.sata_hol_tmo = cpu_to_le32(80);
>         payload.open_reject_cmdretries_data_retries = cpu_to_le32(0xff00ff);
> +
>         rc = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &payload,
>                         sizeof(payload), 0);
>         if (rc)
> -               pm8001_tag_free(pm8001_ha, tag);
> -       return rc;
> +               pm8001_ccb_free(pm8001_ha, ccb);
>
> +       return rc;
>  }
>
>  const struct pm8001_dispatch pm8001_8001_dispatch = {
> diff --git a/drivers/scsi/pm8001/pm8001_sas.c b/drivers/scsi/pm8001/pm8001_sas.c
> index 1e60ad82635e..52507bc8f963 100644
> --- a/drivers/scsi/pm8001/pm8001_sas.c
> +++ b/drivers/scsi/pm8001/pm8001_sas.c
> @@ -74,7 +74,7 @@ void pm8001_tag_free(struct pm8001_hba_info *pm8001_ha, u32 tag)
>    * @pm8001_ha: our hba struct
>    * @tag_out: the found empty tag .
>    */
> -inline int pm8001_tag_alloc(struct pm8001_hba_info *pm8001_ha, u32 *tag_out)
> +int pm8001_tag_alloc(struct pm8001_hba_info *pm8001_ha, u32 *tag_out)
>  {
>         unsigned int tag;
>         void *bitmap = pm8001_ha->tags;
> @@ -382,7 +382,7 @@ static int pm8001_task_exec(struct sas_task *task,
>         struct pm8001_port *port = NULL;
>         struct sas_task *t = task;
>         struct pm8001_ccb_info *ccb;
> -       u32 tag = 0xdeadbeef, rc = 0, n_elem = 0;
> +       u32 rc = 0, n_elem = 0;
>         unsigned long flags = 0;
>         enum sas_protocol task_proto = t->task_proto;
>
> @@ -426,10 +426,12 @@ static int pm8001_task_exec(struct sas_task *task,
>                                 continue;
>                         }
>                 }
> -               rc = pm8001_tag_alloc(pm8001_ha, &tag);
> -               if (rc)
> +
> +               ccb = pm8001_ccb_alloc(pm8001_ha, pm8001_dev, t);
> +               if (!ccb) {
> +                       rc = -SAS_QUEUE_FULL;
>                         goto err_out;
> -               ccb = &pm8001_ha->ccb_info[tag];
> +               }
>
>                 if (!sas_protocol_ata(task_proto)) {
>                         if (t->num_scatter) {
> @@ -439,7 +441,7 @@ static int pm8001_task_exec(struct sas_task *task,
>                                         t->data_dir);
>                                 if (!n_elem) {
>                                         rc = -ENOMEM;
> -                                       goto err_out_tag;
> +                                       goto err_out_ccb;
>                                 }
>                         }
>                 } else {
> @@ -448,9 +450,7 @@ static int pm8001_task_exec(struct sas_task *task,
>
>                 t->lldd_task = ccb;
>                 ccb->n_elem = n_elem;
> -               ccb->ccb_tag = tag;
> -               ccb->task = t;
> -               ccb->device = pm8001_dev;
> +
>                 switch (task_proto) {
>                 case SAS_PROTOCOL_SMP:
>                         atomic_inc(&pm8001_dev->running_req);
> @@ -479,15 +479,15 @@ static int pm8001_task_exec(struct sas_task *task,
>                 if (rc) {
>                         pm8001_dbg(pm8001_ha, IO, "rc is %x\n", rc);
>                         atomic_dec(&pm8001_dev->running_req);
> -                       goto err_out_tag;
> +                       goto err_out_ccb;
>                 }
>                 /* TODO: select normal or high priority */
>         } while (0);
>         rc = 0;
>         goto out_done;
>
> -err_out_tag:
> -       pm8001_tag_free(pm8001_ha, tag);
> +err_out_ccb:
> +       pm8001_ccb_free(pm8001_ha, ccb);
>  err_out:
>         dev_printk(KERN_ERR, pm8001_ha->dev, "pm8001 exec failed[%d]!\n", rc);
>         if (!sas_protocol_ata(task_proto))
> @@ -558,10 +558,7 @@ void pm8001_ccb_task_free(struct pm8001_hba_info *pm8001_ha,
>         }
>
>         task->lldd_task = NULL;
> -       ccb->task = NULL;
> -       ccb->ccb_tag = PM8001_INVALID_TAG;
> -       ccb->open_retry = 0;
> -       pm8001_tag_free(pm8001_ha, ccb_idx);
> +       pm8001_ccb_free(pm8001_ha, ccb);
>  }
>
>  /**
> @@ -812,7 +809,6 @@ pm8001_exec_internal_task_abort(struct pm8001_hba_info *pm8001_ha,
>         u32 task_tag)
>  {
>         int res, retry;
> -       u32 ccb_tag;
>         struct pm8001_ccb_info *ccb;
>         struct sas_task *task = NULL;
>
> @@ -828,23 +824,19 @@ pm8001_exec_internal_task_abort(struct pm8001_hba_info *pm8001_ha,
>                 task->slow_task->timer.expires = jiffies + PM8001_TASK_TIMEOUT * HZ;
>                 add_timer(&task->slow_task->timer);
>
> -               res = pm8001_tag_alloc(pm8001_ha, &ccb_tag);
> -               if (res)
> +               ccb = pm8001_ccb_alloc(pm8001_ha, pm8001_dev, task);
> +               if (!ccb) {
> +                       res = -SAS_QUEUE_FULL;
>                         break;
> -
> -               ccb = &pm8001_ha->ccb_info[ccb_tag];
> -               ccb->device = pm8001_dev;
> -               ccb->ccb_tag = ccb_tag;
> -               ccb->task = task;
> -               ccb->n_elem = 0;
> +               }
>
>                 res = PM8001_CHIP_DISP->task_abort(pm8001_ha,
> -                       pm8001_dev, flag, task_tag, ccb_tag);
> +                       pm8001_dev, flag, task_tag, ccb->ccb_tag);
>                 if (res) {
>                         del_timer(&task->slow_task->timer);
>                         pm8001_dbg(pm8001_ha, FAIL,
>                                    "Executing internal task failed\n");
> -                       pm8001_tag_free(pm8001_ha, ccb_tag);
> +                       pm8001_ccb_free(pm8001_ha, ccb);
>                         break;
>                 }
>
> diff --git a/drivers/scsi/pm8001/pm8001_sas.h b/drivers/scsi/pm8001/pm8001_sas.h
> index 1791cdf30276..824ada7f6a3f 100644
> --- a/drivers/scsi/pm8001/pm8001_sas.h
> +++ b/drivers/scsi/pm8001/pm8001_sas.h
> @@ -740,6 +740,53 @@ extern const struct attribute_group *pm8001_host_groups[];
>
>  #define PM8001_INVALID_TAG     ((u32)-1)
>
> +/*
> + * Allocate a new tag and return the corresponding ccb after initializing it.
> + */
> +static inline struct pm8001_ccb_info *
> +pm8001_ccb_alloc(struct pm8001_hba_info *pm8001_ha,
> +                struct pm8001_device *dev, struct sas_task *task)
> +{
> +       struct pm8001_ccb_info *ccb;
> +       u32 tag;
> +
> +       if (pm8001_tag_alloc(pm8001_ha, &tag)) {
> +               pm8001_dbg(pm8001_ha, FAIL, "Failed to allocate a tag\n");
> +               return NULL;
> +       }
> +
> +       ccb = &pm8001_ha->ccb_info[tag];
> +       ccb->task = task;
> +       ccb->n_elem = 0;
> +       ccb->ccb_tag = tag;
> +       ccb->device = dev;
> +       ccb->fw_control_context = NULL;
> +       ccb->open_retry = 0;
> +
> +       return ccb;
> +}
> +
> +/*
> + * Free the tag of an initialized ccb.
> + */
> +static inline void pm8001_ccb_free(struct pm8001_hba_info *pm8001_ha,
> +                                  struct pm8001_ccb_info *ccb)
> +{
> +       u32 tag = ccb->ccb_tag;
> +
> +       /*
> +        * Cleanup the ccb to make sure that a manual scan of the adapter
> +        * ccb_info array can detect ccb's that are in use.
> +        * C.f. pm8001_open_reject_retry()
> +        */
> +       ccb->task = NULL;
> +       ccb->ccb_tag = PM8001_INVALID_TAG;
> +       ccb->device = NULL;
> +       ccb->fw_control_context = NULL;
> +
> +       pm8001_tag_free(pm8001_ha, tag);
> +}
> +
>  static inline void
>  pm8001_ccb_task_free_done(struct pm8001_hba_info *pm8001_ha,
>                         struct sas_task *task, struct pm8001_ccb_info *ccb,
> diff --git a/drivers/scsi/pm8001/pm80xx_hwi.c b/drivers/scsi/pm8001/pm80xx_hwi.c
> index 4419fdb0db78..57ea933dab66 100644
> --- a/drivers/scsi/pm8001/pm80xx_hwi.c
> +++ b/drivers/scsi/pm8001/pm80xx_hwi.c
> @@ -1767,8 +1767,6 @@ pm80xx_chip_interrupt_disable(struct pm8001_hba_info *pm8001_ha, u8 vec)
>  static void pm80xx_send_abort_all(struct pm8001_hba_info *pm8001_ha,
>                 struct pm8001_device *pm8001_ha_dev)
>  {
> -       int res;
> -       u32 ccb_tag;
>         struct pm8001_ccb_info *ccb;
>         struct sas_task *task = NULL;
>         struct task_abort_req task_abort;
> @@ -1790,31 +1788,25 @@ static void pm80xx_send_abort_all(struct pm8001_hba_info *pm8001_ha,
>
>         task->task_done = pm8001_task_done;
>
> -       res = pm8001_tag_alloc(pm8001_ha, &ccb_tag);
> -       if (res) {
> +       ccb = pm8001_ccb_alloc(pm8001_ha, pm8001_ha_dev, task);
> +       if (!ccb) {
>                 sas_free_task(task);
>                 return;
>         }
>
> -       ccb = &pm8001_ha->ccb_info[ccb_tag];
> -       ccb->device = pm8001_ha_dev;
> -       ccb->ccb_tag = ccb_tag;
> -       ccb->task = task;
> -       ccb->n_elem = 0;
> -
>         circularQ = &pm8001_ha->inbnd_q_tbl[0];
>
>         memset(&task_abort, 0, sizeof(task_abort));
>         task_abort.abort_all = cpu_to_le32(1);
>         task_abort.device_id = cpu_to_le32(pm8001_ha_dev->device_id);
> -       task_abort.tag = cpu_to_le32(ccb_tag);
> +       task_abort.tag = cpu_to_le32(ccb->ccb_tag);
>
>         ret = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &task_abort,
>                         sizeof(task_abort), 0);
>         pm8001_dbg(pm8001_ha, FAIL, "Executing abort task end\n");
>         if (ret) {
>                 sas_free_task(task);
> -               pm8001_tag_free(pm8001_ha, ccb_tag);
> +               pm8001_ccb_free(pm8001_ha, ccb);
>         }
>  }
>
> @@ -1823,7 +1815,6 @@ static void pm80xx_send_read_log(struct pm8001_hba_info *pm8001_ha,
>  {
>         struct sata_start_req sata_cmd;
>         int res;
> -       u32 ccb_tag;
>         struct pm8001_ccb_info *ccb;
>         struct sas_task *task = NULL;
>         struct host_to_dev_fis fis;
> @@ -1839,20 +1830,13 @@ static void pm80xx_send_read_log(struct pm8001_hba_info *pm8001_ha,
>         }
>         task->task_done = pm8001_task_done;
>
> -       res = pm8001_tag_alloc(pm8001_ha, &ccb_tag);
> -       if (res) {
> -               sas_free_task(task);
> -               pm8001_dbg(pm8001_ha, FAIL, "cannot allocate tag !!!\n");
> -               return;
> -       }
> -
> -       /* allocate domain device by ourselves as libsas
> -        * is not going to provide any
> -       */
> +       /*
> +        * Allocate domain device by ourselves as libsas is not going to
> +        * provide any.
> +        */
>         dev = kzalloc(sizeof(struct domain_device), GFP_ATOMIC);
>         if (!dev) {
>                 sas_free_task(task);
> -               pm8001_tag_free(pm8001_ha, ccb_tag);
>                 pm8001_dbg(pm8001_ha, FAIL,
>                            "Domain device cannot be allocated\n");
>                 return;
> @@ -1861,11 +1845,13 @@ static void pm80xx_send_read_log(struct pm8001_hba_info *pm8001_ha,
>         task->dev = dev;
>         task->dev->lldd_dev = pm8001_ha_dev;
>
> -       ccb = &pm8001_ha->ccb_info[ccb_tag];
> -       ccb->device = pm8001_ha_dev;
> -       ccb->ccb_tag = ccb_tag;
> -       ccb->task = task;
> -       ccb->n_elem = 0;
> +       ccb = pm8001_ccb_alloc(pm8001_ha, pm8001_ha_dev, task);
> +       if (!ccb) {
> +               sas_free_task(task);
> +               kfree(dev);
> +               return;
> +       }
> +
>         pm8001_ha_dev->id |= NCQ_READ_LOG_FLAG;
>         pm8001_ha_dev->id |= NCQ_2ND_RLE_FLAG;
>
> @@ -1880,7 +1866,7 @@ static void pm80xx_send_read_log(struct pm8001_hba_info *pm8001_ha,
>         fis.lbal = 0x10;
>         fis.sector_count = 0x1;
>
> -       sata_cmd.tag = cpu_to_le32(ccb_tag);
> +       sata_cmd.tag = cpu_to_le32(ccb->ccb_tag);
>         sata_cmd.device_id = cpu_to_le32(pm8001_ha_dev->device_id);
>         sata_cmd.ncqtag_atap_dir_m_dad = cpu_to_le32(((0x1 << 7) | (0x5 << 9)));
>         memcpy(&sata_cmd.sata_fis, &fis, sizeof(struct host_to_dev_fis));
> @@ -1890,7 +1876,7 @@ static void pm80xx_send_read_log(struct pm8001_hba_info *pm8001_ha,
>         pm8001_dbg(pm8001_ha, FAIL, "Executing read log end\n");
>         if (res) {
>                 sas_free_task(task);
> -               pm8001_tag_free(pm8001_ha, ccb_tag);
> +               pm8001_ccb_free(pm8001_ha, ccb);
>                 kfree(dev);
>         }
>  }
> @@ -4834,7 +4820,7 @@ static int pm80xx_chip_reg_dev_req(struct pm8001_hba_info *pm8001_ha,
>         u32 stp_sspsmp_sata = 0x4;
>         struct inbound_queue_table *circularQ;
>         u32 linkrate, phy_id;
> -       int rc, tag = 0xdeadbeef;
> +       int rc;
>         struct pm8001_ccb_info *ccb;
>         u8 retryFlag = 0x1;
>         u16 firstBurstSize = 0;
> @@ -4845,13 +4831,11 @@ static int pm80xx_chip_reg_dev_req(struct pm8001_hba_info *pm8001_ha,
>         circularQ = &pm8001_ha->inbnd_q_tbl[0];
>
>         memset(&payload, 0, sizeof(payload));
> -       rc = pm8001_tag_alloc(pm8001_ha, &tag);
> -       if (rc)
> -               return rc;
> -       ccb = &pm8001_ha->ccb_info[tag];
> -       ccb->device = pm8001_dev;
> -       ccb->ccb_tag = tag;
> -       payload.tag = cpu_to_le32(tag);
> +       ccb = pm8001_ccb_alloc(pm8001_ha, pm8001_dev, NULL);
> +       if (!ccb)
> +               return -SAS_QUEUE_FULL;
> +
> +       payload.tag = cpu_to_le32(ccb->ccb_tag);
>
>         if (flag == 1) {
>                 stp_sspsmp_sata = 0x02; /*direct attached sata */
> @@ -4888,7 +4872,7 @@ static int pm80xx_chip_reg_dev_req(struct pm8001_hba_info *pm8001_ha,
>         rc = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &payload,
>                         sizeof(payload), 0);
>         if (rc)
> -               pm8001_tag_free(pm8001_ha, tag);
> +               pm8001_ccb_free(pm8001_ha, ccb);
>
>         return rc;
>  }
> --
> 2.34.1
>

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH v4 27/31] scsi: pm8001: Simplify pm8001_mpi_build_cmd() interface
  2022-02-17 13:29 ` [PATCH v4 27/31] scsi: pm8001: Simplify pm8001_mpi_build_cmd() interface Damien Le Moal
@ 2022-02-17 19:46   ` Jinpu Wang
  0 siblings, 0 replies; 65+ messages in thread
From: Jinpu Wang @ 2022-02-17 19:46 UTC (permalink / raw)
  To: Damien Le Moal
  Cc: linux-scsi, Martin K . Petersen, Jack Wang, John Garry,
	Xiang Chen, Jason Yan, Luo Jiaxing

On Thu, Feb 17, 2022 at 2:30 PM Damien Le Moal
<damien.lemoal@opensource.wdc.com> wrote:
>
> There is no need to pass a pointer to a struct inbound_queue_table to
> pm8001_mpi_build_cmd(). Passing the start index in the inbound queue
> table of the adapter is enough. This change allows avoiding the
> declaration of a struct inbound_queue_table pointer (circularQ
> variables) in many functions, simplifying the code.
>
> While at it, blank lines are added i(e.g. after local variable
> declarations) to make the code more readable.
>
> Signed-off-by: Damien Le Moal <damien.lemoal@opensource.wdc.com>
Reviewed-by: Jack Wang <jinpu.wang@ionos.com>
> ---
>  drivers/scsi/pm8001/pm8001_hwi.c | 154 +++++++++++--------------------
>  drivers/scsi/pm8001/pm8001_sas.h |   3 +-
>  drivers/scsi/pm8001/pm80xx_hwi.c |  98 +++++++-------------
>  3 files changed, 89 insertions(+), 166 deletions(-)
>
> diff --git a/drivers/scsi/pm8001/pm8001_hwi.c b/drivers/scsi/pm8001/pm8001_hwi.c
> index 699fecc09267..03bcf7497bf9 100644
> --- a/drivers/scsi/pm8001/pm8001_hwi.c
> +++ b/drivers/scsi/pm8001/pm8001_hwi.c
> @@ -1309,21 +1309,20 @@ int pm8001_mpi_msg_free_get(struct inbound_queue_table *circularQ,
>   * pm8001_mpi_build_cmd- build the message queue for transfer, update the PI to
>   * FW to tell the fw to get this message from IOMB.
>   * @pm8001_ha: our hba card information
> - * @circularQ: the inbound queue we want to transfer to HBA.
> + * @q_index: the index in the inbound queue we want to transfer to HBA.
>   * @opCode: the operation code represents commands which LLDD and fw recognized.
>   * @payload: the command payload of each operation command.
>   * @nb: size in bytes of the command payload
>   * @responseQueue: queue to interrupt on w/ command response (if any)
>   */
>  int pm8001_mpi_build_cmd(struct pm8001_hba_info *pm8001_ha,
> -                        struct inbound_queue_table *circularQ,
> -                        u32 opCode, void *payload, size_t nb,
> +                        u32 q_index, u32 opCode, void *payload, size_t nb,
>                          u32 responseQueue)
>  {
>         u32 Header = 0, hpriority = 0, bc = 1, category = 0x02;
>         void *pMessage;
>         unsigned long flags;
> -       int q_index = circularQ - pm8001_ha->inbnd_q_tbl;
> +       struct inbound_queue_table *circularQ = &pm8001_ha->inbnd_q_tbl[q_index];
>         int rv;
>         u32 htag = le32_to_cpu(*(__le32 *)payload);
>
> @@ -1752,7 +1751,6 @@ static void pm8001_send_abort_all(struct pm8001_hba_info *pm8001_ha,
>         struct pm8001_ccb_info *ccb;
>         struct sas_task *task = NULL;
>         struct task_abort_req task_abort;
> -       struct inbound_queue_table *circularQ;
>         u32 opc = OPC_INB_SATA_ABORT;
>         int ret;
>
> @@ -1775,15 +1773,13 @@ static void pm8001_send_abort_all(struct pm8001_hba_info *pm8001_ha,
>                 return;
>         }
>
> -       circularQ = &pm8001_ha->inbnd_q_tbl[0];
> -
>         memset(&task_abort, 0, sizeof(task_abort));
>         task_abort.abort_all = cpu_to_le32(1);
>         task_abort.device_id = cpu_to_le32(pm8001_ha_dev->device_id);
>         task_abort.tag = cpu_to_le32(ccb->ccb_tag);
>
> -       ret = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &task_abort,
> -                       sizeof(task_abort), 0);
> +       ret = pm8001_mpi_build_cmd(pm8001_ha, 0, opc, &task_abort,
> +                                  sizeof(task_abort), 0);
>         if (ret) {
>                 sas_free_task(task);
>                 pm8001_ccb_free(pm8001_ha, ccb);
> @@ -1799,11 +1795,9 @@ static void pm8001_send_read_log(struct pm8001_hba_info *pm8001_ha,
>         struct sas_task *task = NULL;
>         struct host_to_dev_fis fis;
>         struct domain_device *dev;
> -       struct inbound_queue_table *circularQ;
>         u32 opc = OPC_INB_SATA_HOST_OPSTART;
>
>         task = sas_alloc_slow_task(GFP_ATOMIC);
> -
>         if (!task) {
>                 pm8001_dbg(pm8001_ha, FAIL, "cannot allocate task !!!\n");
>                 return;
> @@ -1834,9 +1828,6 @@ static void pm8001_send_read_log(struct pm8001_hba_info *pm8001_ha,
>         pm8001_ha_dev->id |= NCQ_READ_LOG_FLAG;
>         pm8001_ha_dev->id |= NCQ_2ND_RLE_FLAG;
>
> -       memset(&sata_cmd, 0, sizeof(sata_cmd));
> -       circularQ = &pm8001_ha->inbnd_q_tbl[0];
> -
>         /* construct read log FIS */
>         memset(&fis, 0, sizeof(struct host_to_dev_fis));
>         fis.fis_type = 0x27;
> @@ -1845,13 +1836,14 @@ static void pm8001_send_read_log(struct pm8001_hba_info *pm8001_ha,
>         fis.lbal = 0x10;
>         fis.sector_count = 0x1;
>
> +       memset(&sata_cmd, 0, sizeof(sata_cmd));
>         sata_cmd.tag = cpu_to_le32(ccb->ccb_tag);
>         sata_cmd.device_id = cpu_to_le32(pm8001_ha_dev->device_id);
>         sata_cmd.ncqtag_atap_dir_m = cpu_to_le32((0x1 << 7) | (0x5 << 9));
>         memcpy(&sata_cmd.sata_fis, &fis, sizeof(struct host_to_dev_fis));
>
> -       res = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &sata_cmd,
> -                       sizeof(sata_cmd), 0);
> +       res = pm8001_mpi_build_cmd(pm8001_ha, 0, opc, &sata_cmd,
> +                                  sizeof(sata_cmd), 0);
>         if (res) {
>                 sas_free_task(task);
>                 pm8001_ccb_free(pm8001_ha, ccb);
> @@ -3261,17 +3253,14 @@ static void pm8001_hw_event_ack_req(struct pm8001_hba_info *pm8001_ha,
>         struct hw_event_ack_req  payload;
>         u32 opc = OPC_INB_SAS_HW_EVENT_ACK;
>
> -       struct inbound_queue_table *circularQ;
> -
>         memset((u8 *)&payload, 0, sizeof(payload));
> -       circularQ = &pm8001_ha->inbnd_q_tbl[Qnum];
>         payload.tag = cpu_to_le32(1);
>         payload.sea_phyid_portid = cpu_to_le32(((SEA & 0xFFFF) << 8) |
>                 ((phyId & 0x0F) << 4) | (port_id & 0x0F));
>         payload.param0 = cpu_to_le32(param0);
>         payload.param1 = cpu_to_le32(param1);
> -       pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &payload,
> -                       sizeof(payload), 0);
> +
> +       pm8001_mpi_build_cmd(pm8001_ha, Qnum, opc, &payload, sizeof(payload), 0);
>  }
>
>  static int pm8001_chip_phy_ctl_req(struct pm8001_hba_info *pm8001_ha,
> @@ -4103,7 +4092,6 @@ static int pm8001_chip_smp_req(struct pm8001_hba_info *pm8001_ha,
>         u32 req_len, resp_len;
>         struct smp_req smp_cmd;
>         u32 opc;
> -       struct inbound_queue_table *circularQ;
>
>         memset(&smp_cmd, 0, sizeof(smp_cmd));
>         /*
> @@ -4129,7 +4117,6 @@ static int pm8001_chip_smp_req(struct pm8001_hba_info *pm8001_ha,
>         }
>
>         opc = OPC_INB_SMP_REQUEST;
> -       circularQ = &pm8001_ha->inbnd_q_tbl[0];
>         smp_cmd.tag = cpu_to_le32(ccb->ccb_tag);
>         smp_cmd.long_smp_req.long_req_addr =
>                 cpu_to_le64((u64)sg_dma_address(&task->smp_task.smp_req));
> @@ -4140,8 +4127,8 @@ static int pm8001_chip_smp_req(struct pm8001_hba_info *pm8001_ha,
>         smp_cmd.long_smp_req.long_resp_size =
>                 cpu_to_le32((u32)sg_dma_len(&task->smp_task.smp_resp)-4);
>         build_smp_cmd(pm8001_dev->device_id, smp_cmd.tag, &smp_cmd);
> -       rc = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc,
> -                       &smp_cmd, sizeof(smp_cmd), 0);
> +       rc = pm8001_mpi_build_cmd(pm8001_ha, 0, opc,
> +                                 &smp_cmd, sizeof(smp_cmd), 0);
>         if (rc)
>                 goto err_out_2;
>
> @@ -4169,9 +4156,7 @@ static int pm8001_chip_ssp_io_req(struct pm8001_hba_info *pm8001_ha,
>         struct pm8001_device *pm8001_dev = dev->lldd_dev;
>         struct ssp_ini_io_start_req ssp_cmd;
>         u32 tag = ccb->ccb_tag;
> -       int ret;
>         u64 phys_addr;
> -       struct inbound_queue_table *circularQ;
>         u32 opc = OPC_INB_SSPINIIOSTART;
>         memset(&ssp_cmd, 0, sizeof(ssp_cmd));
>         memcpy(ssp_cmd.ssp_iu.lun, task->ssp_task.LUN, 8);
> @@ -4187,7 +4172,6 @@ static int pm8001_chip_ssp_io_req(struct pm8001_hba_info *pm8001_ha,
>         ssp_cmd.ssp_iu.efb_prio_attr |= (task->ssp_task.task_attr & 7);
>         memcpy(ssp_cmd.ssp_iu.cdb, task->ssp_task.cmd->cmnd,
>                task->ssp_task.cmd->cmd_len);
> -       circularQ = &pm8001_ha->inbnd_q_tbl[0];
>
>         /* fill in PRD (scatter/gather) table, if any */
>         if (task->num_scatter > 1) {
> @@ -4208,9 +4192,9 @@ static int pm8001_chip_ssp_io_req(struct pm8001_hba_info *pm8001_ha,
>                 ssp_cmd.len = cpu_to_le32(task->total_xfer_len);
>                 ssp_cmd.esgl = 0;
>         }
> -       ret = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &ssp_cmd,
> -                       sizeof(ssp_cmd), 0);
> -       return ret;
> +
> +       return pm8001_mpi_build_cmd(pm8001_ha, 0, opc, &ssp_cmd,
> +                                   sizeof(ssp_cmd), 0);
>  }
>
>  static int pm8001_chip_sata_req(struct pm8001_hba_info *pm8001_ha,
> @@ -4220,17 +4204,15 @@ static int pm8001_chip_sata_req(struct pm8001_hba_info *pm8001_ha,
>         struct domain_device *dev = task->dev;
>         struct pm8001_device *pm8001_ha_dev = dev->lldd_dev;
>         u32 tag = ccb->ccb_tag;
> -       int ret;
>         struct sata_start_req sata_cmd;
>         u32 hdr_tag, ncg_tag = 0;
>         u64 phys_addr;
>         u32 ATAP = 0x0;
>         u32 dir;
> -       struct inbound_queue_table *circularQ;
>         unsigned long flags;
>         u32  opc = OPC_INB_SATA_HOST_OPSTART;
> +
>         memset(&sata_cmd, 0, sizeof(sata_cmd));
> -       circularQ = &pm8001_ha->inbnd_q_tbl[0];
>
>         if (task->data_dir == DMA_NONE && !task->ata_task.use_ncq) {
>                 ATAP = 0x04;  /* no data*/
> @@ -4316,9 +4298,8 @@ static int pm8001_chip_sata_req(struct pm8001_hba_info *pm8001_ha,
>                 }
>         }
>
> -       ret = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &sata_cmd,
> -                       sizeof(sata_cmd), 0);
> -       return ret;
> +       return pm8001_mpi_build_cmd(pm8001_ha, 0, opc, &sata_cmd,
> +                                   sizeof(sata_cmd), 0);
>  }
>
>  /**
> @@ -4330,11 +4311,9 @@ static int
>  pm8001_chip_phy_start_req(struct pm8001_hba_info *pm8001_ha, u8 phy_id)
>  {
>         struct phy_start_req payload;
> -       struct inbound_queue_table *circularQ;
> -       int ret;
>         u32 tag = 0x01;
>         u32 opcode = OPC_INB_PHYSTART;
> -       circularQ = &pm8001_ha->inbnd_q_tbl[0];
> +
>         memset(&payload, 0, sizeof(payload));
>         payload.tag = cpu_to_le32(tag);
>         /*
> @@ -4351,9 +4330,9 @@ pm8001_chip_phy_start_req(struct pm8001_hba_info *pm8001_ha, u8 phy_id)
>         memcpy(payload.sas_identify.sas_addr,
>                 pm8001_ha->sas_addr, SAS_ADDR_SIZE);
>         payload.sas_identify.phy_id = phy_id;
> -       ret = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opcode, &payload,
> -                       sizeof(payload), 0);
> -       return ret;
> +
> +       return pm8001_mpi_build_cmd(pm8001_ha, 0, opcode, &payload,
> +                                   sizeof(payload), 0);
>  }
>
>  /**
> @@ -4365,17 +4344,15 @@ static int pm8001_chip_phy_stop_req(struct pm8001_hba_info *pm8001_ha,
>                                     u8 phy_id)
>  {
>         struct phy_stop_req payload;
> -       struct inbound_queue_table *circularQ;
> -       int ret;
>         u32 tag = 0x01;
>         u32 opcode = OPC_INB_PHYSTOP;
> -       circularQ = &pm8001_ha->inbnd_q_tbl[0];
> +
>         memset(&payload, 0, sizeof(payload));
>         payload.tag = cpu_to_le32(tag);
>         payload.phy_id = cpu_to_le32(phy_id);
> -       ret = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opcode, &payload,
> -                       sizeof(payload), 0);
> -       return ret;
> +
> +       return pm8001_mpi_build_cmd(pm8001_ha, 0, opcode, &payload,
> +                                   sizeof(payload), 0);
>  }
>
>  /*
> @@ -4387,7 +4364,6 @@ static int pm8001_chip_reg_dev_req(struct pm8001_hba_info *pm8001_ha,
>         struct reg_dev_req payload;
>         u32     opc;
>         u32 stp_sspsmp_sata = 0x4;
> -       struct inbound_queue_table *circularQ;
>         u32 linkrate, phy_id;
>         int rc;
>         struct pm8001_ccb_info *ccb;
> @@ -4397,7 +4373,6 @@ static int pm8001_chip_reg_dev_req(struct pm8001_hba_info *pm8001_ha,
>         struct domain_device *dev = pm8001_dev->sas_device;
>         struct domain_device *parent_dev = dev->parent;
>         struct pm8001_port *port = dev->port->lldd_port;
> -       circularQ = &pm8001_ha->inbnd_q_tbl[0];
>
>         memset(&payload, 0, sizeof(payload));
>         ccb = pm8001_ccb_alloc(pm8001_ha, pm8001_dev, NULL);
> @@ -4431,8 +4406,9 @@ static int pm8001_chip_reg_dev_req(struct pm8001_hba_info *pm8001_ha,
>                 cpu_to_le32(ITNT | (firstBurstSize * 0x10000));
>         memcpy(payload.sas_addr, pm8001_dev->sas_device->sas_addr,
>                 SAS_ADDR_SIZE);
> -       rc = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &payload,
> -                       sizeof(payload), 0);
> +
> +       rc = pm8001_mpi_build_cmd(pm8001_ha, 0, opc, &payload,
> +                                 sizeof(payload), 0);
>         if (rc)
>                 pm8001_ccb_free(pm8001_ha, ccb);
>
> @@ -4447,18 +4423,15 @@ int pm8001_chip_dereg_dev_req(struct pm8001_hba_info *pm8001_ha,
>  {
>         struct dereg_dev_req payload;
>         u32 opc = OPC_INB_DEREG_DEV_HANDLE;
> -       int ret;
> -       struct inbound_queue_table *circularQ;
>
> -       circularQ = &pm8001_ha->inbnd_q_tbl[0];
>         memset(&payload, 0, sizeof(payload));
>         payload.tag = cpu_to_le32(1);
>         payload.device_id = cpu_to_le32(device_id);
>         pm8001_dbg(pm8001_ha, MSG, "unregister device device_id = %d\n",
>                    device_id);
> -       ret = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &payload,
> -                       sizeof(payload), 0);
> -       return ret;
> +
> +       return pm8001_mpi_build_cmd(pm8001_ha, 0, opc, &payload,
> +                                   sizeof(payload), 0);
>  }
>
>  /**
> @@ -4471,17 +4444,15 @@ static int pm8001_chip_phy_ctl_req(struct pm8001_hba_info *pm8001_ha,
>         u32 phyId, u32 phy_op)
>  {
>         struct local_phy_ctl_req payload;
> -       struct inbound_queue_table *circularQ;
> -       int ret;
>         u32 opc = OPC_INB_LOCAL_PHY_CONTROL;
> +
>         memset(&payload, 0, sizeof(payload));
> -       circularQ = &pm8001_ha->inbnd_q_tbl[0];
>         payload.tag = cpu_to_le32(1);
>         payload.phyop_phyid =
>                 cpu_to_le32(((phy_op & 0xff) << 8) | (phyId & 0x0F));
> -       ret = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &payload,
> -                       sizeof(payload), 0);
> -       return ret;
> +
> +       return pm8001_mpi_build_cmd(pm8001_ha, 0, opc, &payload,
> +                                   sizeof(payload), 0);
>  }
>
>  static u32 pm8001_chip_is_our_interrupt(struct pm8001_hba_info *pm8001_ha)
> @@ -4519,9 +4490,7 @@ static int send_task_abort(struct pm8001_hba_info *pm8001_ha, u32 opc,
>         u32 dev_id, u8 flag, u32 task_tag, u32 cmd_tag)
>  {
>         struct task_abort_req task_abort;
> -       struct inbound_queue_table *circularQ;
> -       int ret;
> -       circularQ = &pm8001_ha->inbnd_q_tbl[0];
> +
>         memset(&task_abort, 0, sizeof(task_abort));
>         if (ABORT_SINGLE == (flag & ABORT_MASK)) {
>                 task_abort.abort_all = 0;
> @@ -4533,9 +4502,9 @@ static int send_task_abort(struct pm8001_hba_info *pm8001_ha, u32 opc,
>                 task_abort.device_id = cpu_to_le32(dev_id);
>                 task_abort.tag = cpu_to_le32(cmd_tag);
>         }
> -       ret = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &task_abort,
> -                       sizeof(task_abort), 0);
> -       return ret;
> +
> +       return pm8001_mpi_build_cmd(pm8001_ha, 0, opc, &task_abort,
> +                                   sizeof(task_abort), 0);
>  }
>
>  /*
> @@ -4575,9 +4544,7 @@ int pm8001_chip_ssp_tm_req(struct pm8001_hba_info *pm8001_ha,
>         struct domain_device *dev = task->dev;
>         struct pm8001_device *pm8001_dev = dev->lldd_dev;
>         u32 opc = OPC_INB_SSPINITMSTART;
> -       struct inbound_queue_table *circularQ;
>         struct ssp_ini_tm_start_req sspTMCmd;
> -       int ret;
>
>         memset(&sspTMCmd, 0, sizeof(sspTMCmd));
>         sspTMCmd.device_id = cpu_to_le32(pm8001_dev->device_id);
> @@ -4587,10 +4554,9 @@ int pm8001_chip_ssp_tm_req(struct pm8001_hba_info *pm8001_ha,
>         sspTMCmd.tag = cpu_to_le32(ccb->ccb_tag);
>         if (pm8001_ha->chip_id != chip_8001)
>                 sspTMCmd.ds_ads_m = cpu_to_le32(0x08);
> -       circularQ = &pm8001_ha->inbnd_q_tbl[0];
> -       ret = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &sspTMCmd,
> -                       sizeof(sspTMCmd), 0);
> -       return ret;
> +
> +       return pm8001_mpi_build_cmd(pm8001_ha, 0, opc, &sspTMCmd,
> +                                   sizeof(sspTMCmd), 0);
>  }
>
>  int pm8001_chip_get_nvmd_req(struct pm8001_hba_info *pm8001_ha,
> @@ -4600,7 +4566,6 @@ int pm8001_chip_get_nvmd_req(struct pm8001_hba_info *pm8001_ha,
>         u32 nvmd_type;
>         int rc;
>         struct pm8001_ccb_info *ccb;
> -       struct inbound_queue_table *circularQ;
>         struct get_nvm_data_req nvmd_req;
>         struct fw_control_ex *fw_control_context;
>         struct pm8001_ioctl_payload *ioctl_payload = payload;
> @@ -4611,7 +4576,6 @@ int pm8001_chip_get_nvmd_req(struct pm8001_hba_info *pm8001_ha,
>                 return -ENOMEM;
>         fw_control_context->usrAddr = (u8 *)ioctl_payload->func_specific;
>         fw_control_context->len = ioctl_payload->rd_length;
> -       circularQ = &pm8001_ha->inbnd_q_tbl[0];
>         memset(&nvmd_req, 0, sizeof(nvmd_req));
>
>         ccb = pm8001_ccb_alloc(pm8001_ha, NULL, NULL);
> @@ -4678,8 +4642,9 @@ int pm8001_chip_get_nvmd_req(struct pm8001_hba_info *pm8001_ha,
>         default:
>                 break;
>         }
> -       rc = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &nvmd_req,
> -                       sizeof(nvmd_req), 0);
> +
> +       rc = pm8001_mpi_build_cmd(pm8001_ha, 0, opc, &nvmd_req,
> +                                 sizeof(nvmd_req), 0);
>         if (rc) {
>                 kfree(fw_control_context);
>                 pm8001_ccb_free(pm8001_ha, ccb);
> @@ -4694,7 +4659,6 @@ int pm8001_chip_set_nvmd_req(struct pm8001_hba_info *pm8001_ha,
>         u32 nvmd_type;
>         int rc;
>         struct pm8001_ccb_info *ccb;
> -       struct inbound_queue_table *circularQ;
>         struct set_nvm_data_req nvmd_req;
>         struct fw_control_ex *fw_control_context;
>         struct pm8001_ioctl_payload *ioctl_payload = payload;
> @@ -4703,7 +4667,7 @@ int pm8001_chip_set_nvmd_req(struct pm8001_hba_info *pm8001_ha,
>         fw_control_context = kzalloc(sizeof(struct fw_control_ex), GFP_KERNEL);
>         if (!fw_control_context)
>                 return -ENOMEM;
> -       circularQ = &pm8001_ha->inbnd_q_tbl[0];
> +
>         memcpy(pm8001_ha->memoryMap.region[NVMD].virt_ptr,
>                 &ioctl_payload->func_specific,
>                 ioctl_payload->wr_length);
> @@ -4762,7 +4726,8 @@ int pm8001_chip_set_nvmd_req(struct pm8001_hba_info *pm8001_ha,
>         default:
>                 break;
>         }
> -       rc = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &nvmd_req,
> +
> +       rc = pm8001_mpi_build_cmd(pm8001_ha, 0, opc, &nvmd_req,
>                         sizeof(nvmd_req), 0);
>         if (rc) {
>                 kfree(fw_control_context);
> @@ -4783,12 +4748,9 @@ pm8001_chip_fw_flash_update_build(struct pm8001_hba_info *pm8001_ha,
>  {
>         struct fw_flash_Update_req payload;
>         struct fw_flash_updata_info *info;
> -       struct inbound_queue_table *circularQ;
> -       int ret;
>         u32 opc = OPC_INB_FW_FLASH_UPDATE;
>
>         memset(&payload, 0, sizeof(struct fw_flash_Update_req));
> -       circularQ = &pm8001_ha->inbnd_q_tbl[0];
>         info = fw_flash_updata_info;
>         payload.tag = cpu_to_le32(tag);
>         payload.cur_image_len = cpu_to_le32(info->cur_image_len);
> @@ -4799,9 +4761,9 @@ pm8001_chip_fw_flash_update_build(struct pm8001_hba_info *pm8001_ha,
>                 cpu_to_le32(lower_32_bits(le64_to_cpu(info->sgl.addr)));
>         payload.sgl_addr_hi =
>                 cpu_to_le32(upper_32_bits(le64_to_cpu(info->sgl.addr)));
> -       ret = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &payload,
> -                       sizeof(payload), 0);
> -       return ret;
> +
> +       return pm8001_mpi_build_cmd(pm8001_ha, 0, opc, &payload,
> +                                   sizeof(payload), 0);
>  }
>
>  int
> @@ -4936,7 +4898,6 @@ pm8001_chip_set_dev_state_req(struct pm8001_hba_info *pm8001_ha,
>         struct pm8001_device *pm8001_dev, u32 state)
>  {
>         struct set_dev_state_req payload;
> -       struct inbound_queue_table *circularQ;
>         struct pm8001_ccb_info *ccb;
>         int rc;
>         u32 opc = OPC_INB_SET_DEVICE_STATE;
> @@ -4947,13 +4908,12 @@ pm8001_chip_set_dev_state_req(struct pm8001_hba_info *pm8001_ha,
>         if (!ccb)
>                 return -SAS_QUEUE_FULL;
>
> -       circularQ = &pm8001_ha->inbnd_q_tbl[0];
>         payload.tag = cpu_to_le32(ccb->ccb_tag);
>         payload.device_id = cpu_to_le32(pm8001_dev->device_id);
>         payload.nds = cpu_to_le32(state);
>
> -       rc = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &payload,
> -                       sizeof(payload), 0);
> +       rc = pm8001_mpi_build_cmd(pm8001_ha, 0, opc, &payload,
> +                                 sizeof(payload), 0);
>         if (rc)
>                 pm8001_ccb_free(pm8001_ha, ccb);
>
> @@ -4964,7 +4924,6 @@ static int
>  pm8001_chip_sas_re_initialization(struct pm8001_hba_info *pm8001_ha)
>  {
>         struct sas_re_initialization_req payload;
> -       struct inbound_queue_table *circularQ;
>         struct pm8001_ccb_info *ccb;
>         int rc;
>         u32 opc = OPC_INB_SAS_RE_INITIALIZE;
> @@ -4975,14 +4934,13 @@ pm8001_chip_sas_re_initialization(struct pm8001_hba_info *pm8001_ha)
>         if (!ccb)
>                 return -SAS_QUEUE_FULL;
>
> -       circularQ = &pm8001_ha->inbnd_q_tbl[0];
>         payload.tag = cpu_to_le32(ccb->ccb_tag);
>         payload.SSAHOLT = cpu_to_le32(0xd << 25);
>         payload.sata_hol_tmo = cpu_to_le32(80);
>         payload.open_reject_cmdretries_data_retries = cpu_to_le32(0xff00ff);
>
> -       rc = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &payload,
> -                       sizeof(payload), 0);
> +       rc = pm8001_mpi_build_cmd(pm8001_ha, 0, opc, &payload,
> +                                 sizeof(payload), 0);
>         if (rc)
>                 pm8001_ccb_free(pm8001_ha, ccb);
>
> diff --git a/drivers/scsi/pm8001/pm8001_sas.h b/drivers/scsi/pm8001/pm8001_sas.h
> index 824ada7f6a3f..aec4572906cf 100644
> --- a/drivers/scsi/pm8001/pm8001_sas.h
> +++ b/drivers/scsi/pm8001/pm8001_sas.h
> @@ -668,8 +668,7 @@ int pm8001_mem_alloc(struct pci_dev *pdev, void **virt_addr,
>
>  void pm8001_chip_iounmap(struct pm8001_hba_info *pm8001_ha);
>  int pm8001_mpi_build_cmd(struct pm8001_hba_info *pm8001_ha,
> -                       struct inbound_queue_table *circularQ,
> -                       u32 opCode, void *payload, size_t nb,
> +                       u32 q_index, u32 opCode, void *payload, size_t nb,
>                         u32 responseQueue);
>  int pm8001_mpi_msg_free_get(struct inbound_queue_table *circularQ,
>                                 u16 messageSize, void **messagePtr);
> diff --git a/drivers/scsi/pm8001/pm80xx_hwi.c b/drivers/scsi/pm8001/pm80xx_hwi.c
> index 57ea933dab66..ce19aa361d26 100644
> --- a/drivers/scsi/pm8001/pm80xx_hwi.c
> +++ b/drivers/scsi/pm8001/pm80xx_hwi.c
> @@ -1182,7 +1182,6 @@ int
>  pm80xx_set_thermal_config(struct pm8001_hba_info *pm8001_ha)
>  {
>         struct set_ctrl_cfg_req payload;
> -       struct inbound_queue_table *circularQ;
>         int rc;
>         u32 tag;
>         u32 opc = OPC_INB_SET_CONTROLLER_CONFIG;
> @@ -1193,7 +1192,6 @@ pm80xx_set_thermal_config(struct pm8001_hba_info *pm8001_ha)
>         if (rc)
>                 return rc;
>
> -       circularQ = &pm8001_ha->inbnd_q_tbl[0];
>         payload.tag = cpu_to_le32(tag);
>
>         if (IS_SPCV_12G(pm8001_ha->pdev))
> @@ -1211,7 +1209,7 @@ pm80xx_set_thermal_config(struct pm8001_hba_info *pm8001_ha)
>                    "Setting up thermal config. cfg_pg 0 0x%x cfg_pg 1 0x%x\n",
>                    payload.cfg_pg[0], payload.cfg_pg[1]);
>
> -       rc = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &payload,
> +       rc = pm8001_mpi_build_cmd(pm8001_ha, 0, opc, &payload,
>                         sizeof(payload), 0);
>         if (rc)
>                 pm8001_tag_free(pm8001_ha, tag);
> @@ -1228,7 +1226,6 @@ static int
>  pm80xx_set_sas_protocol_timer_config(struct pm8001_hba_info *pm8001_ha)
>  {
>         struct set_ctrl_cfg_req payload;
> -       struct inbound_queue_table *circularQ;
>         SASProtocolTimerConfig_t SASConfigPage;
>         int rc;
>         u32 tag;
> @@ -1238,11 +1235,9 @@ pm80xx_set_sas_protocol_timer_config(struct pm8001_hba_info *pm8001_ha)
>         memset(&SASConfigPage, 0, sizeof(SASProtocolTimerConfig_t));
>
>         rc = pm8001_tag_alloc(pm8001_ha, &tag);
> -
>         if (rc)
>                 return rc;
>
> -       circularQ = &pm8001_ha->inbnd_q_tbl[0];
>         payload.tag = cpu_to_le32(tag);
>
>         SASConfigPage.pageCode = cpu_to_le32(SAS_PROTOCOL_TIMER_CONFIG_PAGE);
> @@ -1284,7 +1279,7 @@ pm80xx_set_sas_protocol_timer_config(struct pm8001_hba_info *pm8001_ha)
>         memcpy(&payload.cfg_pg, &SASConfigPage,
>                          sizeof(SASProtocolTimerConfig_t));
>
> -       rc = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &payload,
> +       rc = pm8001_mpi_build_cmd(pm8001_ha, 0, opc, &payload,
>                         sizeof(payload), 0);
>         if (rc)
>                 pm8001_tag_free(pm8001_ha, tag);
> @@ -1390,7 +1385,6 @@ pm80xx_get_encrypt_info(struct pm8001_hba_info *pm8001_ha)
>  static int pm80xx_encrypt_update(struct pm8001_hba_info *pm8001_ha)
>  {
>         struct kek_mgmt_req payload;
> -       struct inbound_queue_table *circularQ;
>         int rc;
>         u32 tag;
>         u32 opc = OPC_INB_KEK_MANAGEMENT;
> @@ -1400,7 +1394,6 @@ static int pm80xx_encrypt_update(struct pm8001_hba_info *pm8001_ha)
>         if (rc)
>                 return rc;
>
> -       circularQ = &pm8001_ha->inbnd_q_tbl[0];
>         payload.tag = cpu_to_le32(tag);
>         /* Currently only one key is used. New KEK index is 1.
>          * Current KEK index is 1. Store KEK to NVRAM is 1.
> @@ -1413,7 +1406,7 @@ static int pm80xx_encrypt_update(struct pm8001_hba_info *pm8001_ha)
>                    "Saving Encryption info to flash. payload 0x%x\n",
>                    le32_to_cpu(payload.new_curidx_ksop));
>
> -       rc = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &payload,
> +       rc = pm8001_mpi_build_cmd(pm8001_ha, 0, opc, &payload,
>                         sizeof(payload), 0);
>         if (rc)
>                 pm8001_tag_free(pm8001_ha, tag);
> @@ -1770,7 +1763,6 @@ static void pm80xx_send_abort_all(struct pm8001_hba_info *pm8001_ha,
>         struct pm8001_ccb_info *ccb;
>         struct sas_task *task = NULL;
>         struct task_abort_req task_abort;
> -       struct inbound_queue_table *circularQ;
>         u32 opc = OPC_INB_SATA_ABORT;
>         int ret;
>
> @@ -1794,15 +1786,13 @@ static void pm80xx_send_abort_all(struct pm8001_hba_info *pm8001_ha,
>                 return;
>         }
>
> -       circularQ = &pm8001_ha->inbnd_q_tbl[0];
> -
>         memset(&task_abort, 0, sizeof(task_abort));
>         task_abort.abort_all = cpu_to_le32(1);
>         task_abort.device_id = cpu_to_le32(pm8001_ha_dev->device_id);
>         task_abort.tag = cpu_to_le32(ccb->ccb_tag);
>
> -       ret = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &task_abort,
> -                       sizeof(task_abort), 0);
> +       ret = pm8001_mpi_build_cmd(pm8001_ha, 0, opc, &task_abort,
> +                                  sizeof(task_abort), 0);
>         pm8001_dbg(pm8001_ha, FAIL, "Executing abort task end\n");
>         if (ret) {
>                 sas_free_task(task);
> @@ -1819,11 +1809,9 @@ static void pm80xx_send_read_log(struct pm8001_hba_info *pm8001_ha,
>         struct sas_task *task = NULL;
>         struct host_to_dev_fis fis;
>         struct domain_device *dev;
> -       struct inbound_queue_table *circularQ;
>         u32 opc = OPC_INB_SATA_HOST_OPSTART;
>
>         task = sas_alloc_slow_task(GFP_ATOMIC);
> -
>         if (!task) {
>                 pm8001_dbg(pm8001_ha, FAIL, "cannot allocate task !!!\n");
>                 return;
> @@ -1856,7 +1844,6 @@ static void pm80xx_send_read_log(struct pm8001_hba_info *pm8001_ha,
>         pm8001_ha_dev->id |= NCQ_2ND_RLE_FLAG;
>
>         memset(&sata_cmd, 0, sizeof(sata_cmd));
> -       circularQ = &pm8001_ha->inbnd_q_tbl[0];
>
>         /* construct read log FIS */
>         memset(&fis, 0, sizeof(struct host_to_dev_fis));
> @@ -1871,8 +1858,8 @@ static void pm80xx_send_read_log(struct pm8001_hba_info *pm8001_ha,
>         sata_cmd.ncqtag_atap_dir_m_dad = cpu_to_le32(((0x1 << 7) | (0x5 << 9)));
>         memcpy(&sata_cmd.sata_fis, &fis, sizeof(struct host_to_dev_fis));
>
> -       res = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &sata_cmd,
> -                       sizeof(sata_cmd), 0);
> +       res = pm8001_mpi_build_cmd(pm8001_ha, 0, opc, &sata_cmd,
> +                                  sizeof(sata_cmd), 0);
>         pm8001_dbg(pm8001_ha, FAIL, "Executing read log end\n");
>         if (res) {
>                 sas_free_task(task);
> @@ -3209,17 +3196,15 @@ static void pm80xx_hw_event_ack_req(struct pm8001_hba_info *pm8001_ha,
>         struct hw_event_ack_req  payload;
>         u32 opc = OPC_INB_SAS_HW_EVENT_ACK;
>
> -       struct inbound_queue_table *circularQ;
> -
>         memset((u8 *)&payload, 0, sizeof(payload));
> -       circularQ = &pm8001_ha->inbnd_q_tbl[Qnum];
>         payload.tag = cpu_to_le32(1);
>         payload.phyid_sea_portid = cpu_to_le32(((SEA & 0xFFFF) << 8) |
>                 ((phyId & 0xFF) << 24) | (port_id & 0xFF));
>         payload.param0 = cpu_to_le32(param0);
>         payload.param1 = cpu_to_le32(param1);
> -       pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &payload,
> -                       sizeof(payload), 0);
> +
> +       pm8001_mpi_build_cmd(pm8001_ha, Qnum, opc, &payload,
> +                            sizeof(payload), 0);
>  }
>
>  static int pm80xx_chip_phy_ctl_req(struct pm8001_hba_info *pm8001_ha,
> @@ -4198,7 +4183,6 @@ static int pm80xx_chip_smp_req(struct pm8001_hba_info *pm8001_ha,
>         u32 req_len, resp_len;
>         struct smp_req smp_cmd;
>         u32 opc;
> -       struct inbound_queue_table *circularQ;
>         u32 i, length;
>         u8 *payload;
>         u8 *to;
> @@ -4227,7 +4211,6 @@ static int pm80xx_chip_smp_req(struct pm8001_hba_info *pm8001_ha,
>         }
>
>         opc = OPC_INB_SMP_REQUEST;
> -       circularQ = &pm8001_ha->inbnd_q_tbl[0];
>         smp_cmd.tag = cpu_to_le32(ccb->ccb_tag);
>
>         length = sg_req->length;
> @@ -4295,8 +4278,8 @@ static int pm80xx_chip_smp_req(struct pm8001_hba_info *pm8001_ha,
>         kunmap_atomic(to);
>         build_smp_cmd(pm8001_dev->device_id, smp_cmd.tag,
>                                 &smp_cmd, pm8001_ha->smp_exp_mode, length);
> -       rc = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &smp_cmd,
> -                       sizeof(smp_cmd), 0);
> +       rc = pm8001_mpi_build_cmd(pm8001_ha, 0, opc, &smp_cmd,
> +                                 sizeof(smp_cmd), 0);
>         if (rc)
>                 goto err_out_2;
>         return 0;
> @@ -4356,10 +4339,8 @@ static int pm80xx_chip_ssp_io_req(struct pm8001_hba_info *pm8001_ha,
>         struct pm8001_device *pm8001_dev = dev->lldd_dev;
>         struct ssp_ini_io_start_req ssp_cmd;
>         u32 tag = ccb->ccb_tag;
> -       int ret;
>         u64 phys_addr, end_addr;
>         u32 end_addr_high, end_addr_low;
> -       struct inbound_queue_table *circularQ;
>         u32 q_index, cpu_id;
>         u32 opc = OPC_INB_SSPINIIOSTART;
>
> @@ -4383,7 +4364,6 @@ static int pm80xx_chip_ssp_io_req(struct pm8001_hba_info *pm8001_ha,
>                        task->ssp_task.cmd->cmd_len);
>         cpu_id = smp_processor_id();
>         q_index = (u32) (cpu_id) % (pm8001_ha->max_q_num);
> -       circularQ = &pm8001_ha->inbnd_q_tbl[q_index];
>
>         /* Check if encryption is set */
>         if (pm8001_ha->chip->encrypt &&
> @@ -4500,9 +4480,9 @@ static int pm80xx_chip_ssp_io_req(struct pm8001_hba_info *pm8001_ha,
>                         ssp_cmd.esgl = 0;
>                 }
>         }
> -       ret = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc,
> -                       &ssp_cmd, sizeof(ssp_cmd), q_index);
> -       return ret;
> +
> +       return pm8001_mpi_build_cmd(pm8001_ha, q_index, opc, &ssp_cmd,
> +                                   sizeof(ssp_cmd), q_index);
>  }
>
>  static int pm80xx_chip_sata_req(struct pm8001_hba_info *pm8001_ha,
> @@ -4513,7 +4493,6 @@ static int pm80xx_chip_sata_req(struct pm8001_hba_info *pm8001_ha,
>         struct pm8001_device *pm8001_ha_dev = dev->lldd_dev;
>         struct ata_queued_cmd *qc = task->uldd_task;
>         u32 tag = ccb->ccb_tag;
> -       int ret;
>         u32 q_index, cpu_id;
>         struct sata_start_req sata_cmd;
>         u32 hdr_tag, ncg_tag = 0;
> @@ -4521,13 +4500,11 @@ static int pm80xx_chip_sata_req(struct pm8001_hba_info *pm8001_ha,
>         u32 end_addr_high, end_addr_low;
>         u32 ATAP = 0x0;
>         u32 dir;
> -       struct inbound_queue_table *circularQ;
>         unsigned long flags;
>         u32 opc = OPC_INB_SATA_HOST_OPSTART;
>         memset(&sata_cmd, 0, sizeof(sata_cmd));
>         cpu_id = smp_processor_id();
>         q_index = (u32) (cpu_id) % (pm8001_ha->max_q_num);
> -       circularQ = &pm8001_ha->inbnd_q_tbl[q_index];
>
>         if (task->data_dir == DMA_NONE && !task->ata_task.use_ncq) {
>                 ATAP = 0x04; /* no data*/
> @@ -4742,9 +4719,8 @@ static int pm80xx_chip_sata_req(struct pm8001_hba_info *pm8001_ha,
>                                 ccb->ccb_tag, opc,
>                                 qc ? qc->tf.command : 0, // ata opcode
>                                 ccb->device ? atomic_read(&ccb->device->running_req) : 0);
> -       ret = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc,
> -                       &sata_cmd, sizeof(sata_cmd), q_index);
> -       return ret;
> +       return pm8001_mpi_build_cmd(pm8001_ha, q_index, opc, &sata_cmd,
> +                                   sizeof(sata_cmd), q_index);
>  }
>
>  /**
> @@ -4756,11 +4732,9 @@ static int
>  pm80xx_chip_phy_start_req(struct pm8001_hba_info *pm8001_ha, u8 phy_id)
>  {
>         struct phy_start_req payload;
> -       struct inbound_queue_table *circularQ;
> -       int ret;
>         u32 tag = 0x01;
>         u32 opcode = OPC_INB_PHYSTART;
> -       circularQ = &pm8001_ha->inbnd_q_tbl[0];
> +
>         memset(&payload, 0, sizeof(payload));
>         payload.tag = cpu_to_le32(tag);
>
> @@ -4782,9 +4756,9 @@ pm80xx_chip_phy_start_req(struct pm8001_hba_info *pm8001_ha, u8 phy_id)
>         memcpy(payload.sas_identify.sas_addr,
>           &pm8001_ha->sas_addr, SAS_ADDR_SIZE);
>         payload.sas_identify.phy_id = phy_id;
> -       ret = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opcode, &payload,
> -                       sizeof(payload), 0);
> -       return ret;
> +
> +       return pm8001_mpi_build_cmd(pm8001_ha, 0, opcode, &payload,
> +                                   sizeof(payload), 0);
>  }
>
>  /**
> @@ -4796,17 +4770,15 @@ static int pm80xx_chip_phy_stop_req(struct pm8001_hba_info *pm8001_ha,
>         u8 phy_id)
>  {
>         struct phy_stop_req payload;
> -       struct inbound_queue_table *circularQ;
> -       int ret;
>         u32 tag = 0x01;
>         u32 opcode = OPC_INB_PHYSTOP;
> -       circularQ = &pm8001_ha->inbnd_q_tbl[0];
> +
>         memset(&payload, 0, sizeof(payload));
>         payload.tag = cpu_to_le32(tag);
>         payload.phy_id = cpu_to_le32(phy_id);
> -       ret = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opcode, &payload,
> -                       sizeof(payload), 0);
> -       return ret;
> +
> +       return pm8001_mpi_build_cmd(pm8001_ha, 0, opcode, &payload,
> +                                   sizeof(payload), 0);
>  }
>
>  /*
> @@ -4818,7 +4790,6 @@ static int pm80xx_chip_reg_dev_req(struct pm8001_hba_info *pm8001_ha,
>         struct reg_dev_req payload;
>         u32     opc;
>         u32 stp_sspsmp_sata = 0x4;
> -       struct inbound_queue_table *circularQ;
>         u32 linkrate, phy_id;
>         int rc;
>         struct pm8001_ccb_info *ccb;
> @@ -4828,7 +4799,6 @@ static int pm80xx_chip_reg_dev_req(struct pm8001_hba_info *pm8001_ha,
>         struct domain_device *dev = pm8001_dev->sas_device;
>         struct domain_device *parent_dev = dev->parent;
>         struct pm8001_port *port = dev->port->lldd_port;
> -       circularQ = &pm8001_ha->inbnd_q_tbl[0];
>
>         memset(&payload, 0, sizeof(payload));
>         ccb = pm8001_ccb_alloc(pm8001_ha, pm8001_dev, NULL);
> @@ -4869,7 +4839,7 @@ static int pm80xx_chip_reg_dev_req(struct pm8001_hba_info *pm8001_ha,
>         memcpy(payload.sas_addr, pm8001_dev->sas_device->sas_addr,
>                 SAS_ADDR_SIZE);
>
> -       rc = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &payload,
> +       rc = pm8001_mpi_build_cmd(pm8001_ha, 0, opc, &payload,
>                         sizeof(payload), 0);
>         if (rc)
>                 pm8001_ccb_free(pm8001_ha, ccb);
> @@ -4889,18 +4859,18 @@ static int pm80xx_chip_phy_ctl_req(struct pm8001_hba_info *pm8001_ha,
>         u32 tag;
>         int rc;
>         struct local_phy_ctl_req payload;
> -       struct inbound_queue_table *circularQ;
>         u32 opc = OPC_INB_LOCAL_PHY_CONTROL;
> +
>         memset(&payload, 0, sizeof(payload));
>         rc = pm8001_tag_alloc(pm8001_ha, &tag);
>         if (rc)
>                 return rc;
> -       circularQ = &pm8001_ha->inbnd_q_tbl[0];
> +
>         payload.tag = cpu_to_le32(tag);
>         payload.phyop_phyid =
>                 cpu_to_le32(((phy_op & 0xFF) << 8) | (phyId & 0xFF));
>
> -       rc = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &payload,
> +       rc = pm8001_mpi_build_cmd(pm8001_ha, 0, opc, &payload,
>                                   sizeof(payload), 0);
>         if (rc)
>                 pm8001_tag_free(pm8001_ha, tag);
> @@ -4946,7 +4916,6 @@ static void mpi_set_phy_profile_req(struct pm8001_hba_info *pm8001_ha,
>         u32 tag, i, j = 0;
>         int rc;
>         struct set_phy_profile_req payload;
> -       struct inbound_queue_table *circularQ;
>         u32 opc = OPC_INB_SET_PHY_PROFILE;
>
>         memset(&payload, 0, sizeof(payload));
> @@ -4956,7 +4925,6 @@ static void mpi_set_phy_profile_req(struct pm8001_hba_info *pm8001_ha,
>                 return;
>         }
>
> -       circularQ = &pm8001_ha->inbnd_q_tbl[0];
>         payload.tag = cpu_to_le32(tag);
>         payload.ppc_phyid =
>                 cpu_to_le32(((operation & 0xF) << 8) | (phyid  & 0xFF));
> @@ -4967,8 +4935,8 @@ static void mpi_set_phy_profile_req(struct pm8001_hba_info *pm8001_ha,
>                 payload.reserved[j] = cpu_to_le32(*((u32 *)buf + i));
>                 j++;
>         }
> -       rc = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &payload,
> -                       sizeof(payload), 0);
> +       rc = pm8001_mpi_build_cmd(pm8001_ha, 0, opc, &payload,
> +                                 sizeof(payload), 0);
>         if (rc)
>                 pm8001_tag_free(pm8001_ha, tag);
>  }
> @@ -4992,7 +4960,6 @@ void pm8001_set_phy_profile_single(struct pm8001_hba_info *pm8001_ha,
>         u32 tag, opc;
>         int rc, i;
>         struct set_phy_profile_req payload;
> -       struct inbound_queue_table *circularQ;
>
>         memset(&payload, 0, sizeof(payload));
>
> @@ -5002,7 +4969,6 @@ void pm8001_set_phy_profile_single(struct pm8001_hba_info *pm8001_ha,
>                 return;
>         }
>
> -       circularQ = &pm8001_ha->inbnd_q_tbl[0];
>         opc = OPC_INB_SET_PHY_PROFILE;
>
>         payload.tag = cpu_to_le32(tag);
> @@ -5013,7 +4979,7 @@ void pm8001_set_phy_profile_single(struct pm8001_hba_info *pm8001_ha,
>         for (i = 0; i < length; i++)
>                 payload.reserved[i] = cpu_to_le32(*(buf + i));
>
> -       rc = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &payload,
> +       rc = pm8001_mpi_build_cmd(pm8001_ha, 0, opc, &payload,
>                         sizeof(payload), 0);
>         if (rc)
>                 pm8001_tag_free(pm8001_ha, tag);
> --
> 2.34.1
>

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH v4 28/31] scsi: pm8001: Simplify pm8001_task_exec()
  2022-02-17 13:29 ` [PATCH v4 28/31] scsi: pm8001: Simplify pm8001_task_exec() Damien Le Moal
@ 2022-02-17 19:47   ` Jinpu Wang
  0 siblings, 0 replies; 65+ messages in thread
From: Jinpu Wang @ 2022-02-17 19:47 UTC (permalink / raw)
  To: Damien Le Moal
  Cc: linux-scsi, Martin K . Petersen, Jack Wang, John Garry,
	Xiang Chen, Jason Yan, Luo Jiaxing

On Thu, Feb 17, 2022 at 2:30 PM Damien Le Moal
<damien.lemoal@opensource.wdc.com> wrote:
>
> The main part of the pm8001_task_exec() function uses a do {} while(0)
> loop that is useless and only makes the code harder to read. Remove this
> loop. The unnecessary local variable t is also removed.
>
> Additionally, avoid repeatedly declaring "struct task_status_struct *ts"
> to handle error cases by declaring this variable for the entire function
> scope. This allows simplifying the error cases, and together with the
> addition of blank lines make the code more readable.
>
> Finally, handling of the running_req counter is fixed to avoid
> decrementing it without a corresponding incrementation in the case of
> an invalid task protocol.
>
> Signed-off-by: Damien Le Moal <damien.lemoal@opensource.wdc.com>
> Reviewed-by: John Garry <john.garry@huawei.com>
Reviewed-by: Jack Wang <jinpu.wang@ionos.com>
> ---
>  drivers/scsi/pm8001/pm8001_sas.c | 174 ++++++++++++++-----------------
>  1 file changed, 80 insertions(+), 94 deletions(-)
>
> diff --git a/drivers/scsi/pm8001/pm8001_sas.c b/drivers/scsi/pm8001/pm8001_sas.c
> index 52507bc8f963..37aba0335f18 100644
> --- a/drivers/scsi/pm8001/pm8001_sas.c
> +++ b/drivers/scsi/pm8001/pm8001_sas.c
> @@ -373,129 +373,115 @@ static int sas_find_local_port_id(struct domain_device *dev)
>    * @is_tmf: if it is task management task.
>    * @tmf: the task management IU
>    */
> -static int pm8001_task_exec(struct sas_task *task,
> -       gfp_t gfp_flags, int is_tmf, struct pm8001_tmf_task *tmf)
> +static int pm8001_task_exec(struct sas_task *task, gfp_t gfp_flags, int is_tmf,
> +                           struct pm8001_tmf_task *tmf)
>  {
> +       struct task_status_struct *ts = &task->task_status;
> +       enum sas_protocol task_proto = task->task_proto;
>         struct domain_device *dev = task->dev;
> +       struct pm8001_device *pm8001_dev = dev->lldd_dev;
>         struct pm8001_hba_info *pm8001_ha;
> -       struct pm8001_device *pm8001_dev;
>         struct pm8001_port *port = NULL;
> -       struct sas_task *t = task;
>         struct pm8001_ccb_info *ccb;
> -       u32 rc = 0, n_elem = 0;
> -       unsigned long flags = 0;
> -       enum sas_protocol task_proto = t->task_proto;
> +       unsigned long flags;
> +       u32 n_elem = 0;
> +       int rc = 0;
>
>         if (!dev->port) {
> -               struct task_status_struct *tsm = &t->task_status;
> -               tsm->resp = SAS_TASK_UNDELIVERED;
> -               tsm->stat = SAS_PHY_DOWN;
> +               ts->resp = SAS_TASK_UNDELIVERED;
> +               ts->stat = SAS_PHY_DOWN;
>                 if (dev->dev_type != SAS_SATA_DEV)
> -                       t->task_done(t);
> +                       task->task_done(task);
>                 return 0;
>         }
> -       pm8001_ha = pm8001_find_ha_by_dev(task->dev);
> -       if (pm8001_ha->controller_fatal_error) {
> -               struct task_status_struct *ts = &t->task_status;
>
> +       pm8001_ha = pm8001_find_ha_by_dev(dev);
> +       if (pm8001_ha->controller_fatal_error) {
>                 ts->resp = SAS_TASK_UNDELIVERED;
> -               t->task_done(t);
> +               task->task_done(task);
>                 return 0;
>         }
> +
>         pm8001_dbg(pm8001_ha, IO, "pm8001_task_exec device\n");
> +
>         spin_lock_irqsave(&pm8001_ha->lock, flags);
> -       do {
> -               dev = t->dev;
> -               pm8001_dev = dev->lldd_dev;
> -               port = &pm8001_ha->port[sas_find_local_port_id(dev)];
> -               if (DEV_IS_GONE(pm8001_dev) || !port->port_attached) {
> -                       if (sas_protocol_ata(task_proto)) {
> -                               struct task_status_struct *ts = &t->task_status;
> -                               ts->resp = SAS_TASK_UNDELIVERED;
> -                               ts->stat = SAS_PHY_DOWN;
>
> -                               spin_unlock_irqrestore(&pm8001_ha->lock, flags);
> -                               t->task_done(t);
> -                               spin_lock_irqsave(&pm8001_ha->lock, flags);
> -                               continue;
> -                       } else {
> -                               struct task_status_struct *ts = &t->task_status;
> -                               ts->resp = SAS_TASK_UNDELIVERED;
> -                               ts->stat = SAS_PHY_DOWN;
> -                               t->task_done(t);
> -                               continue;
> -                       }
> -               }
> +       pm8001_dev = dev->lldd_dev;
> +       port = &pm8001_ha->port[sas_find_local_port_id(dev)];
>
> -               ccb = pm8001_ccb_alloc(pm8001_ha, pm8001_dev, t);
> -               if (!ccb) {
> -                       rc = -SAS_QUEUE_FULL;
> -                       goto err_out;
> +       if (DEV_IS_GONE(pm8001_dev) || !port->port_attached) {
> +               ts->resp = SAS_TASK_UNDELIVERED;
> +               ts->stat = SAS_PHY_DOWN;
> +               if (sas_protocol_ata(task_proto)) {
> +                       spin_unlock_irqrestore(&pm8001_ha->lock, flags);
> +                       task->task_done(task);
> +                       spin_lock_irqsave(&pm8001_ha->lock, flags);
> +               } else {
> +                       task->task_done(task);
>                 }
> +               rc = -ENODEV;
> +               goto err_out;
> +       }
>
> -               if (!sas_protocol_ata(task_proto)) {
> -                       if (t->num_scatter) {
> -                               n_elem = dma_map_sg(pm8001_ha->dev,
> -                                       t->scatter,
> -                                       t->num_scatter,
> -                                       t->data_dir);
> -                               if (!n_elem) {
> -                                       rc = -ENOMEM;
> -                                       goto err_out_ccb;
> -                               }
> +       ccb = pm8001_ccb_alloc(pm8001_ha, pm8001_dev, task);
> +       if (!ccb) {
> +               rc = -SAS_QUEUE_FULL;
> +               goto err_out;
> +       }
> +
> +       if (!sas_protocol_ata(task_proto)) {
> +               if (task->num_scatter) {
> +                       n_elem = dma_map_sg(pm8001_ha->dev, task->scatter,
> +                                           task->num_scatter, task->data_dir);
> +                       if (!n_elem) {
> +                               rc = -ENOMEM;
> +                               goto err_out_ccb;
>                         }
> -               } else {
> -                       n_elem = t->num_scatter;
>                 }
> +       } else {
> +               n_elem = task->num_scatter;
> +       }
>
> -               t->lldd_task = ccb;
> -               ccb->n_elem = n_elem;
> +       task->lldd_task = ccb;
> +       ccb->n_elem = n_elem;
>
> -               switch (task_proto) {
> -               case SAS_PROTOCOL_SMP:
> -                       atomic_inc(&pm8001_dev->running_req);
> -                       rc = pm8001_task_prep_smp(pm8001_ha, ccb);
> -                       break;
> -               case SAS_PROTOCOL_SSP:
> -                       atomic_inc(&pm8001_dev->running_req);
> -                       if (is_tmf)
> -                               rc = pm8001_task_prep_ssp_tm(pm8001_ha,
> -                                       ccb, tmf);
> -                       else
> -                               rc = pm8001_task_prep_ssp(pm8001_ha, ccb);
> -                       break;
> -               case SAS_PROTOCOL_SATA:
> -               case SAS_PROTOCOL_STP:
> -                       atomic_inc(&pm8001_dev->running_req);
> -                       rc = pm8001_task_prep_ata(pm8001_ha, ccb);
> -                       break;
> -               default:
> -                       dev_printk(KERN_ERR, pm8001_ha->dev,
> -                               "unknown sas_task proto: 0x%x\n", task_proto);
> -                       rc = -EINVAL;
> -                       break;
> -               }
> +       atomic_inc(&pm8001_dev->running_req);
>
> -               if (rc) {
> -                       pm8001_dbg(pm8001_ha, IO, "rc is %x\n", rc);
> -                       atomic_dec(&pm8001_dev->running_req);
> -                       goto err_out_ccb;
> -               }
> -               /* TODO: select normal or high priority */
> -       } while (0);
> -       rc = 0;
> -       goto out_done;
> +       switch (task_proto) {
> +       case SAS_PROTOCOL_SMP:
> +               rc = pm8001_task_prep_smp(pm8001_ha, ccb);
> +               break;
> +       case SAS_PROTOCOL_SSP:
> +               if (is_tmf)
> +                       rc = pm8001_task_prep_ssp_tm(pm8001_ha, ccb, tmf);
> +               else
> +                       rc = pm8001_task_prep_ssp(pm8001_ha, ccb);
> +               break;
> +       case SAS_PROTOCOL_SATA:
> +       case SAS_PROTOCOL_STP:
> +               rc = pm8001_task_prep_ata(pm8001_ha, ccb);
> +               break;
> +       default:
> +               dev_printk(KERN_ERR, pm8001_ha->dev,
> +                          "unknown sas_task proto: 0x%x\n", task_proto);
> +               rc = -EINVAL;
> +               break;
> +       }
>
> +       if (rc) {
> +               atomic_dec(&pm8001_dev->running_req);
> +               if (!sas_protocol_ata(task_proto) && n_elem)
> +                       dma_unmap_sg(pm8001_ha->dev, task->scatter,
> +                                    task->num_scatter, task->data_dir);
>  err_out_ccb:
> -       pm8001_ccb_free(pm8001_ha, ccb);
> +               pm8001_ccb_free(pm8001_ha, ccb);
> +
>  err_out:
> -       dev_printk(KERN_ERR, pm8001_ha->dev, "pm8001 exec failed[%d]!\n", rc);
> -       if (!sas_protocol_ata(task_proto))
> -               if (n_elem)
> -                       dma_unmap_sg(pm8001_ha->dev, t->scatter, t->num_scatter,
> -                               t->data_dir);
> -out_done:
> +               pm8001_dbg(pm8001_ha, IO, "pm8001_task_exec failed[%d]!\n", rc);
> +       }
> +
>         spin_unlock_irqrestore(&pm8001_ha->lock, flags);
> +
>         return rc;
>  }
>
> --
> 2.34.1
>

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH v4 29/31] scsi: pm8001: Simplify pm8001_ccb_task_free()
  2022-02-17 13:29 ` [PATCH v4 29/31] scsi: pm8001: Simplify pm8001_ccb_task_free() Damien Le Moal
@ 2022-02-17 19:48   ` Jinpu Wang
  0 siblings, 0 replies; 65+ messages in thread
From: Jinpu Wang @ 2022-02-17 19:48 UTC (permalink / raw)
  To: Damien Le Moal
  Cc: linux-scsi, Martin K . Petersen, Jack Wang, John Garry,
	Xiang Chen, Jason Yan, Luo Jiaxing

On Thu, Feb 17, 2022 at 2:30 PM Damien Le Moal
<damien.lemoal@opensource.wdc.com> wrote:
>
> The task argument of the pm8001_ccb_task_free() function can be infered
> from the ccb argument ccb_task field. So there is no need to have this
> argument. Likewise, the ccb_index argument is always equal to the ccb
> tag field and is not needed either. Remove both arguments and update all
> call sites. The pm8001_ccb_task_free_done() helper is also modified to
> match this change.
>
> Signed-off-by: Damien Le Moal <damien.lemoal@opensource.wdc.com>
Reviewed-by: Jack Wang <jinpu.wang@ionos.com>
> ---
>  drivers/scsi/pm8001/pm8001_hwi.c | 42 +++++++++++++++-----------------
>  drivers/scsi/pm8001/pm8001_sas.c | 25 +++++++++----------
>  drivers/scsi/pm8001/pm8001_sas.h | 12 ++++-----
>  drivers/scsi/pm8001/pm80xx_hwi.c | 35 ++++++++++++--------------
>  4 files changed, 52 insertions(+), 62 deletions(-)
>
> diff --git a/drivers/scsi/pm8001/pm8001_hwi.c b/drivers/scsi/pm8001/pm8001_hwi.c
> index 03bcf7497bf9..c2dbadb5d91e 100644
> --- a/drivers/scsi/pm8001/pm8001_hwi.c
> +++ b/drivers/scsi/pm8001/pm8001_hwi.c
> @@ -1564,11 +1564,11 @@ void pm8001_work_fn(struct work_struct *work)
>                         spin_unlock_irqrestore(&t->task_state_lock, flags1);
>                         pm8001_dbg(pm8001_ha, FAIL, "task 0x%p done with event 0x%x resp 0x%x stat 0x%x but aborted by upper layer!\n",
>                                    t, pw->handler, ts->resp, ts->stat);
> -                       pm8001_ccb_task_free(pm8001_ha, t, ccb, ccb->ccb_tag);
> +                       pm8001_ccb_task_free(pm8001_ha, ccb);
>                         spin_unlock_irqrestore(&pm8001_ha->lock, flags);
>                 } else {
>                         spin_unlock_irqrestore(&t->task_state_lock, flags1);
> -                       pm8001_ccb_task_free(pm8001_ha, t, ccb, ccb->ccb_tag);
> +                       pm8001_ccb_task_free(pm8001_ha, ccb);
>                         mb();/* in order to force CPU ordering */
>                         spin_unlock_irqrestore(&pm8001_ha->lock, flags);
>                         t->task_done(t);
> @@ -1697,8 +1697,7 @@ void pm8001_work_fn(struct work_struct *work)
>                                         continue;
>                                 }
>                                 /*complete sas task and update to top layer */
> -                               pm8001_ccb_task_free(pm8001_ha, task, ccb,
> -                                                    ccb->ccb_tag);
> +                               pm8001_ccb_task_free(pm8001_ha, ccb);
>                                 ts->resp = SAS_TASK_COMPLETE;
>                                 task->task_done(task);
>                         } else if (ccb->ccb_tag != PM8001_INVALID_TAG) {
> @@ -2084,10 +2083,10 @@ mpi_ssp_completion(struct pm8001_hba_info *pm8001_ha, void *piomb)
>                 spin_unlock_irqrestore(&t->task_state_lock, flags);
>                 pm8001_dbg(pm8001_ha, FAIL, "task 0x%p done with io_status 0x%x resp 0x%x stat 0x%x but aborted by upper layer!\n",
>                            t, status, ts->resp, ts->stat);
> -               pm8001_ccb_task_free(pm8001_ha, t, ccb, tag);
> +               pm8001_ccb_task_free(pm8001_ha, ccb);
>         } else {
>                 spin_unlock_irqrestore(&t->task_state_lock, flags);
> -               pm8001_ccb_task_free(pm8001_ha, t, ccb, tag);
> +               pm8001_ccb_task_free(pm8001_ha, ccb);
>                 mb();/* in order to force CPU ordering */
>                 t->task_done(t);
>         }
> @@ -2251,10 +2250,10 @@ static void mpi_ssp_event(struct pm8001_hba_info *pm8001_ha, void *piomb)
>                 spin_unlock_irqrestore(&t->task_state_lock, flags);
>                 pm8001_dbg(pm8001_ha, FAIL, "task 0x%p done with event 0x%x resp 0x%x stat 0x%x but aborted by upper layer!\n",
>                            t, event, ts->resp, ts->stat);
> -               pm8001_ccb_task_free(pm8001_ha, t, ccb, tag);
> +               pm8001_ccb_task_free(pm8001_ha, ccb);
>         } else {
>                 spin_unlock_irqrestore(&t->task_state_lock, flags);
> -               pm8001_ccb_task_free(pm8001_ha, t, ccb, tag);
> +               pm8001_ccb_task_free(pm8001_ha, ccb);
>                 mb();/* in order to force CPU ordering */
>                 t->task_done(t);
>         }
> @@ -2480,7 +2479,7 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb)
>                                 IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS);
>                         ts->resp = SAS_TASK_UNDELIVERED;
>                         ts->stat = SAS_QUEUE_FULL;
> -                       pm8001_ccb_task_free_done(pm8001_ha, t, ccb, tag);
> +                       pm8001_ccb_task_free_done(pm8001_ha, ccb);
>                         return;
>                 }
>                 break;
> @@ -2496,7 +2495,7 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb)
>                                 IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS);
>                         ts->resp = SAS_TASK_UNDELIVERED;
>                         ts->stat = SAS_QUEUE_FULL;
> -                       pm8001_ccb_task_free_done(pm8001_ha, t, ccb, tag);
> +                       pm8001_ccb_task_free_done(pm8001_ha, ccb);
>                         return;
>                 }
>                 break;
> @@ -2518,7 +2517,7 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb)
>                                 IO_OPEN_CNX_ERROR_STP_RESOURCES_BUSY);
>                         ts->resp = SAS_TASK_UNDELIVERED;
>                         ts->stat = SAS_QUEUE_FULL;
> -                       pm8001_ccb_task_free_done(pm8001_ha, t, ccb, tag);
> +                       pm8001_ccb_task_free_done(pm8001_ha, ccb);
>                         return;
>                 }
>                 break;
> @@ -2589,7 +2588,7 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb)
>                                     IO_DS_NON_OPERATIONAL);
>                         ts->resp = SAS_TASK_UNDELIVERED;
>                         ts->stat = SAS_QUEUE_FULL;
> -                       pm8001_ccb_task_free_done(pm8001_ha, t, ccb, tag);
> +                       pm8001_ccb_task_free_done(pm8001_ha, ccb);
>                         return;
>                 }
>                 break;
> @@ -2609,7 +2608,7 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb)
>                                     IO_DS_IN_ERROR);
>                         ts->resp = SAS_TASK_UNDELIVERED;
>                         ts->stat = SAS_QUEUE_FULL;
> -                       pm8001_ccb_task_free_done(pm8001_ha, t, ccb, tag);
> +                       pm8001_ccb_task_free_done(pm8001_ha, ccb);
>                         return;
>                 }
>                 break;
> @@ -2639,10 +2638,10 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb)
>                 pm8001_dbg(pm8001_ha, FAIL,
>                            "task 0x%p done with io_status 0x%x resp 0x%x stat 0x%x but aborted by upper layer!\n",
>                            t, status, ts->resp, ts->stat);
> -               pm8001_ccb_task_free(pm8001_ha, t, ccb, tag);
> +               pm8001_ccb_task_free(pm8001_ha, ccb);
>         } else {
>                 spin_unlock_irqrestore(&t->task_state_lock, flags);
> -               pm8001_ccb_task_free_done(pm8001_ha, t, ccb, tag);
> +               pm8001_ccb_task_free_done(pm8001_ha, ccb);
>         }
>  }
>
> @@ -2994,12 +2993,10 @@ mpi_smp_completion(struct pm8001_hba_info *pm8001_ha, void *piomb)
>                 spin_unlock_irqrestore(&t->task_state_lock, flags);
>                 pm8001_dbg(pm8001_ha, FAIL, "task 0x%p done with io_status 0x%x resp 0x%x stat 0x%x but aborted by upper layer!\n",
>                            t, status, ts->resp, ts->stat);
> -               pm8001_ccb_task_free(pm8001_ha, t, ccb, tag);
> +               pm8001_ccb_task_free(pm8001_ha, ccb);
>         } else {
>                 spin_unlock_irqrestore(&t->task_state_lock, flags);
> -               pm8001_ccb_task_free(pm8001_ha, t, ccb, tag);
> -               mb();/* in order to force CPU ordering */
> -               t->task_done(t);
> +               pm8001_ccb_task_free_done(pm8001_ha, ccb);
>         }
>  }
>
> @@ -3649,7 +3646,7 @@ int pm8001_mpi_task_abort_resp(struct pm8001_hba_info *pm8001_ha, void *piomb)
>         t->task_state_flags &= ~SAS_TASK_STATE_PENDING;
>         t->task_state_flags |= SAS_TASK_STATE_DONE;
>         spin_unlock_irqrestore(&t->task_state_lock, flags);
> -       pm8001_ccb_task_free(pm8001_ha, t, ccb, tag);
> +       pm8001_ccb_task_free(pm8001_ha, ccb);
>         mb();
>
>         if (pm8001_dev->id & NCQ_ABORT_ALL_FLAG) {
> @@ -4287,12 +4284,11 @@ static int pm8001_chip_sata_req(struct pm8001_hba_info *pm8001_ha,
>                                            "task 0x%p resp 0x%x  stat 0x%x but aborted by upper layer\n",
>                                            task, ts->resp,
>                                            ts->stat);
> -                               pm8001_ccb_task_free(pm8001_ha, task, ccb, tag);
> +                               pm8001_ccb_task_free(pm8001_ha, ccb);
>                         } else {
>                                 spin_unlock_irqrestore(&task->task_state_lock,
>                                                         flags);
> -                               pm8001_ccb_task_free_done(pm8001_ha, task,
> -                                                               ccb, tag);
> +                               pm8001_ccb_task_free_done(pm8001_ha, ccb);
>                                 return 0;
>                         }
>                 }
> diff --git a/drivers/scsi/pm8001/pm8001_sas.c b/drivers/scsi/pm8001/pm8001_sas.c
> index 37aba0335f18..da8f39631fb5 100644
> --- a/drivers/scsi/pm8001/pm8001_sas.c
> +++ b/drivers/scsi/pm8001/pm8001_sas.c
> @@ -499,22 +499,21 @@ int pm8001_queue_command(struct sas_task *task, gfp_t gfp_flags)
>  /**
>    * pm8001_ccb_task_free - free the sg for ssp and smp command, free the ccb.
>    * @pm8001_ha: our hba card information
> -  * @ccb: the ccb which attached to ssp task
> -  * @task: the task to be free.
> -  * @ccb_idx: ccb index.
> +  * @ccb: the ccb which attached to ssp task to free
>    */
>  void pm8001_ccb_task_free(struct pm8001_hba_info *pm8001_ha,
> -       struct sas_task *task, struct pm8001_ccb_info *ccb, u32 ccb_idx)
> +                         struct pm8001_ccb_info *ccb)
>  {
> +       struct sas_task *task = ccb->task;
>         struct ata_queued_cmd *qc;
>         struct pm8001_device *pm8001_dev;
>
> -       if (!ccb->task)
> +       if (!task)
>                 return;
> -       if (!sas_protocol_ata(task->task_proto))
> -               if (ccb->n_elem)
> -                       dma_unmap_sg(pm8001_ha->dev, task->scatter,
> -                               task->num_scatter, task->data_dir);
> +
> +       if (!sas_protocol_ata(task->task_proto) && ccb->n_elem)
> +               dma_unmap_sg(pm8001_ha->dev, task->scatter,
> +                            task->num_scatter, task->data_dir);
>
>         switch (task->task_proto) {
>         case SAS_PROTOCOL_SMP:
> @@ -533,12 +532,12 @@ void pm8001_ccb_task_free(struct pm8001_hba_info *pm8001_ha,
>         }
>
>         if (sas_protocol_ata(task->task_proto)) {
> -               // For SCSI/ATA commands uldd_task points to ata_queued_cmd
> +               /* For SCSI/ATA commands uldd_task points to ata_queued_cmd */
>                 qc = task->uldd_task;
>                 pm8001_dev = ccb->device;
>                 trace_pm80xx_request_complete(pm8001_ha->id,
>                         pm8001_dev ? pm8001_dev->attached_phy : PM8001_MAX_PHYS,
> -                       ccb_idx, 0 /* ctlr_opcode not known */,
> +                       ccb->ccb_tag, 0 /* ctlr_opcode not known */,
>                         qc ? qc->tf.command : 0, // ata opcode
>                         pm8001_dev ? atomic_read(&pm8001_dev->running_req) : -1);
>         }
> @@ -960,11 +959,11 @@ void pm8001_open_reject_retry(
>                                 & SAS_TASK_STATE_ABORTED))) {
>                         spin_unlock_irqrestore(&task->task_state_lock,
>                                 flags1);
> -                       pm8001_ccb_task_free(pm8001_ha, task, ccb, ccb->ccb_tag);
> +                       pm8001_ccb_task_free(pm8001_ha, ccb);
>                 } else {
>                         spin_unlock_irqrestore(&task->task_state_lock,
>                                 flags1);
> -                       pm8001_ccb_task_free(pm8001_ha, task, ccb, ccb->ccb_tag);
> +                       pm8001_ccb_task_free(pm8001_ha, ccb);
>                         mb();/* in order to force CPU ordering */
>                         spin_unlock_irqrestore(&pm8001_ha->lock, flags);
>                         task->task_done(task);
> diff --git a/drivers/scsi/pm8001/pm8001_sas.h b/drivers/scsi/pm8001/pm8001_sas.h
> index aec4572906cf..2aab357d9a23 100644
> --- a/drivers/scsi/pm8001/pm8001_sas.h
> +++ b/drivers/scsi/pm8001/pm8001_sas.h
> @@ -641,7 +641,7 @@ int pm8001_tag_alloc(struct pm8001_hba_info *pm8001_ha, u32 *tag_out);
>  void pm8001_tag_init(struct pm8001_hba_info *pm8001_ha);
>  u32 pm8001_get_ncq_tag(struct sas_task *task, u32 *tag);
>  void pm8001_ccb_task_free(struct pm8001_hba_info *pm8001_ha,
> -       struct sas_task *task, struct pm8001_ccb_info *ccb, u32 ccb_idx);
> +                         struct pm8001_ccb_info *ccb);
>  int pm8001_phy_control(struct asd_sas_phy *sas_phy, enum phy_func func,
>         void *funcdata);
>  void pm8001_scan_start(struct Scsi_Host *shost);
> @@ -786,12 +786,12 @@ static inline void pm8001_ccb_free(struct pm8001_hba_info *pm8001_ha,
>         pm8001_tag_free(pm8001_ha, tag);
>  }
>
> -static inline void
> -pm8001_ccb_task_free_done(struct pm8001_hba_info *pm8001_ha,
> -                       struct sas_task *task, struct pm8001_ccb_info *ccb,
> -                       u32 ccb_idx)
> +static inline void pm8001_ccb_task_free_done(struct pm8001_hba_info *pm8001_ha,
> +                                            struct pm8001_ccb_info *ccb)
>  {
> -       pm8001_ccb_task_free(pm8001_ha, task, ccb, ccb_idx);
> +       struct sas_task *task = ccb->task;
> +
> +       pm8001_ccb_task_free(pm8001_ha, ccb);
>         smp_mb(); /*in order to force CPU ordering*/
>         task->task_done(task);
>  }
> diff --git a/drivers/scsi/pm8001/pm80xx_hwi.c b/drivers/scsi/pm8001/pm80xx_hwi.c
> index ce19aa361d26..b5e1aaa0fd58 100644
> --- a/drivers/scsi/pm8001/pm80xx_hwi.c
> +++ b/drivers/scsi/pm8001/pm80xx_hwi.c
> @@ -2157,14 +2157,12 @@ mpi_ssp_completion(struct pm8001_hba_info *pm8001_ha, void *piomb)
>                 pm8001_dbg(pm8001_ha, FAIL,
>                            "task 0x%p done with io_status 0x%x resp 0x%x stat 0x%x but aborted by upper layer!\n",
>                            t, status, ts->resp, ts->stat);
> -               pm8001_ccb_task_free(pm8001_ha, t, ccb, tag);
> +               pm8001_ccb_task_free(pm8001_ha, ccb);
>                 if (t->slow_task)
>                         complete(&t->slow_task->completion);
>         } else {
>                 spin_unlock_irqrestore(&t->task_state_lock, flags);
> -               pm8001_ccb_task_free(pm8001_ha, t, ccb, tag);
> -               mb();/* in order to force CPU ordering */
> -               t->task_done(t);
> +               pm8001_ccb_task_free_done(pm8001_ha, ccb);
>         }
>  }
>
> @@ -2340,12 +2338,10 @@ static void mpi_ssp_event(struct pm8001_hba_info *pm8001_ha, void *piomb)
>                 pm8001_dbg(pm8001_ha, FAIL,
>                            "task 0x%p done with event 0x%x resp 0x%x stat 0x%x but aborted by upper layer!\n",
>                            t, event, ts->resp, ts->stat);
> -               pm8001_ccb_task_free(pm8001_ha, t, ccb, tag);
> +               pm8001_ccb_task_free(pm8001_ha, ccb);
>         } else {
>                 spin_unlock_irqrestore(&t->task_state_lock, flags);
> -               pm8001_ccb_task_free(pm8001_ha, t, ccb, tag);
> -               mb();/* in order to force CPU ordering */
> -               t->task_done(t);
> +               pm8001_ccb_task_free_done(pm8001_ha, ccb);
>         }
>  }
>
> @@ -2579,7 +2575,7 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha,
>                         ts->stat = SAS_QUEUE_FULL;
>                         spin_unlock_irqrestore(&circularQ->oq_lock,
>                                         circularQ->lock_flags);
> -                       pm8001_ccb_task_free_done(pm8001_ha, t, ccb, tag);
> +                       pm8001_ccb_task_free_done(pm8001_ha, ccb);
>                         spin_lock_irqsave(&circularQ->oq_lock,
>                                         circularQ->lock_flags);
>                         return;
> @@ -2599,7 +2595,7 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha,
>                         ts->stat = SAS_QUEUE_FULL;
>                         spin_unlock_irqrestore(&circularQ->oq_lock,
>                                         circularQ->lock_flags);
> -                       pm8001_ccb_task_free_done(pm8001_ha, t, ccb, tag);
> +                       pm8001_ccb_task_free_done(pm8001_ha, ccb);
>                         spin_lock_irqsave(&circularQ->oq_lock,
>                                         circularQ->lock_flags);
>                         return;
> @@ -2627,7 +2623,7 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha,
>                         ts->stat = SAS_QUEUE_FULL;
>                         spin_unlock_irqrestore(&circularQ->oq_lock,
>                                         circularQ->lock_flags);
> -                       pm8001_ccb_task_free_done(pm8001_ha, t, ccb, tag);
> +                       pm8001_ccb_task_free_done(pm8001_ha, ccb);
>                         spin_lock_irqsave(&circularQ->oq_lock,
>                                         circularQ->lock_flags);
>                         return;
> @@ -2702,7 +2698,7 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha,
>                         ts->stat = SAS_QUEUE_FULL;
>                         spin_unlock_irqrestore(&circularQ->oq_lock,
>                                         circularQ->lock_flags);
> -                       pm8001_ccb_task_free_done(pm8001_ha, t, ccb, tag);
> +                       pm8001_ccb_task_free_done(pm8001_ha, ccb);
>                         spin_lock_irqsave(&circularQ->oq_lock,
>                                         circularQ->lock_flags);
>                         return;
> @@ -2726,7 +2722,7 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha,
>                         ts->stat = SAS_QUEUE_FULL;
>                         spin_unlock_irqrestore(&circularQ->oq_lock,
>                                         circularQ->lock_flags);
> -                       pm8001_ccb_task_free_done(pm8001_ha, t, ccb, tag);
> +                       pm8001_ccb_task_free_done(pm8001_ha, ccb);
>                         spin_lock_irqsave(&circularQ->oq_lock,
>                                         circularQ->lock_flags);
>                         return;
> @@ -2760,14 +2756,14 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha,
>                 pm8001_dbg(pm8001_ha, FAIL,
>                            "task 0x%p done with io_status 0x%x resp 0x%x stat 0x%x but aborted by upper layer!\n",
>                            t, status, ts->resp, ts->stat);
> -               pm8001_ccb_task_free(pm8001_ha, t, ccb, tag);
> +               pm8001_ccb_task_free(pm8001_ha, ccb);
>                 if (t->slow_task)
>                         complete(&t->slow_task->completion);
>         } else {
>                 spin_unlock_irqrestore(&t->task_state_lock, flags);
>                 spin_unlock_irqrestore(&circularQ->oq_lock,
>                                 circularQ->lock_flags);
> -               pm8001_ccb_task_free_done(pm8001_ha, t, ccb, tag);
> +               pm8001_ccb_task_free_done(pm8001_ha, ccb);
>                 spin_lock_irqsave(&circularQ->oq_lock,
>                                 circularQ->lock_flags);
>         }
> @@ -3171,10 +3167,10 @@ mpi_smp_completion(struct pm8001_hba_info *pm8001_ha, void *piomb)
>                 pm8001_dbg(pm8001_ha, FAIL,
>                            "task 0x%p done with io_status 0x%x resp 0x%xstat 0x%x but aborted by upper layer!\n",
>                            t, status, ts->resp, ts->stat);
> -               pm8001_ccb_task_free(pm8001_ha, t, ccb, tag);
> +               pm8001_ccb_task_free(pm8001_ha, ccb);
>         } else {
>                 spin_unlock_irqrestore(&t->task_state_lock, flags);
> -               pm8001_ccb_task_free(pm8001_ha, t, ccb, tag);
> +               pm8001_ccb_task_free(pm8001_ha, ccb);
>                 mb();/* in order to force CPU ordering */
>                 t->task_done(t);
>         }
> @@ -4702,13 +4698,12 @@ static int pm80xx_chip_sata_req(struct pm8001_hba_info *pm8001_ha,
>                                            "task 0x%p resp 0x%x  stat 0x%x but aborted by upper layer\n",
>                                            task, ts->resp,
>                                            ts->stat);
> -                               pm8001_ccb_task_free(pm8001_ha, task, ccb, tag);
> +                               pm8001_ccb_task_free(pm8001_ha, ccb);
>                                 return 0;
>                         } else {
>                                 spin_unlock_irqrestore(&task->task_state_lock,
>                                                         flags);
> -                               pm8001_ccb_task_free_done(pm8001_ha, task,
> -                                                               ccb, tag);
> +                               pm8001_ccb_task_free_done(pm8001_ha, ccb);
>                                 atomic_dec(&pm8001_ha_dev->running_req);
>                                 return 0;
>                         }
> --
> 2.34.1
>

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH v4 30/31] scsi: pm8001: improve pm80XX_send_abort_all()
  2022-02-17 13:29 ` [PATCH v4 30/31] scsi: pm8001: improve pm80XX_send_abort_all() Damien Le Moal
@ 2022-02-17 19:49   ` Jinpu Wang
  0 siblings, 0 replies; 65+ messages in thread
From: Jinpu Wang @ 2022-02-17 19:49 UTC (permalink / raw)
  To: Damien Le Moal
  Cc: linux-scsi, Martin K . Petersen, Jack Wang, John Garry,
	Xiang Chen, Jason Yan, Luo Jiaxing

On Thu, Feb 17, 2022 at 2:30 PM Damien Le Moal
<damien.lemoal@opensource.wdc.com> wrote:
>
> Both pm8001_send_abort_all() and pm80xx_send_abort_all() are called only
> for a non null device with the NCQ_READ_LOG_FLAG set, so remove the
> device check on entry of these functions. Furthermore, setting the
> NCQ_ABORT_ALL_FLAG device id flag and clearing the NCQ_READ_LOG_FLAG is
> always done before calling these functions. Move these operations inside
> the functions.
>
> Signed-off-by: Damien Le Moal <damien.lemoal@opensource.wdc.com>
Reviewed-by: Jack Wang <jinpu.wang@ionos.com>

> ---
>  drivers/scsi/pm8001/pm8001_hwi.c | 14 ++++----------
>  drivers/scsi/pm8001/pm80xx_hwi.c | 16 ++++------------
>  2 files changed, 8 insertions(+), 22 deletions(-)
>
> diff --git a/drivers/scsi/pm8001/pm8001_hwi.c b/drivers/scsi/pm8001/pm8001_hwi.c
> index c2dbadb5d91e..edf83b8a6bd0 100644
> --- a/drivers/scsi/pm8001/pm8001_hwi.c
> +++ b/drivers/scsi/pm8001/pm8001_hwi.c
> @@ -1748,15 +1748,13 @@ static void pm8001_send_abort_all(struct pm8001_hba_info *pm8001_ha,
>                 struct pm8001_device *pm8001_ha_dev)
>  {
>         struct pm8001_ccb_info *ccb;
> -       struct sas_task *task = NULL;
> +       struct sas_task *task;
>         struct task_abort_req task_abort;
>         u32 opc = OPC_INB_SATA_ABORT;
>         int ret;
>
> -       if (!pm8001_ha_dev) {
> -               pm8001_dbg(pm8001_ha, FAIL, "dev is null\n");
> -               return;
> -       }
> +       pm8001_ha_dev->id |= NCQ_ABORT_ALL_FLAG;
> +       pm8001_ha_dev->id &= ~NCQ_READ_LOG_FLAG;
>
>         task = sas_alloc_slow_task(GFP_ATOMIC);
>         if (!task) {
> @@ -2358,11 +2356,7 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb)
>                         ts->stat = SAS_SAM_STAT_GOOD;
>                         /* check if response is for SEND READ LOG */
>                         if (pm8001_dev &&
> -                               (pm8001_dev->id & NCQ_READ_LOG_FLAG)) {
> -                               /* set new bit for abort_all */
> -                               pm8001_dev->id |= NCQ_ABORT_ALL_FLAG;
> -                               /* clear bit for read log */
> -                               pm8001_dev->id = pm8001_dev->id & 0x7FFFFFFF;
> +                           (pm8001_dev->id & NCQ_READ_LOG_FLAG)) {
>                                 pm8001_send_abort_all(pm8001_ha, pm8001_dev);
>                                 /* Free the tag */
>                                 pm8001_tag_free(pm8001_ha, tag);
> diff --git a/drivers/scsi/pm8001/pm80xx_hwi.c b/drivers/scsi/pm8001/pm80xx_hwi.c
> index b5e1aaa0fd58..9bb31f66db85 100644
> --- a/drivers/scsi/pm8001/pm80xx_hwi.c
> +++ b/drivers/scsi/pm8001/pm80xx_hwi.c
> @@ -1761,23 +1761,19 @@ static void pm80xx_send_abort_all(struct pm8001_hba_info *pm8001_ha,
>                 struct pm8001_device *pm8001_ha_dev)
>  {
>         struct pm8001_ccb_info *ccb;
> -       struct sas_task *task = NULL;
> +       struct sas_task *task;
>         struct task_abort_req task_abort;
>         u32 opc = OPC_INB_SATA_ABORT;
>         int ret;
>
> -       if (!pm8001_ha_dev) {
> -               pm8001_dbg(pm8001_ha, FAIL, "dev is null\n");
> -               return;
> -       }
> +       pm8001_ha_dev->id |= NCQ_ABORT_ALL_FLAG;
> +       pm8001_ha_dev->id &= ~NCQ_READ_LOG_FLAG;
>
>         task = sas_alloc_slow_task(GFP_ATOMIC);
> -
>         if (!task) {
>                 pm8001_dbg(pm8001_ha, FAIL, "cannot allocate task\n");
>                 return;
>         }
> -
>         task->task_done = pm8001_task_done;
>
>         ccb = pm8001_ccb_alloc(pm8001_ha, pm8001_ha_dev, task);
> @@ -2446,11 +2442,7 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha,
>                         ts->stat = SAS_SAM_STAT_GOOD;
>                         /* check if response is for SEND READ LOG */
>                         if (pm8001_dev &&
> -                               (pm8001_dev->id & NCQ_READ_LOG_FLAG)) {
> -                               /* set new bit for abort_all */
> -                               pm8001_dev->id |= NCQ_ABORT_ALL_FLAG;
> -                               /* clear bit for read log */
> -                               pm8001_dev->id = pm8001_dev->id & 0x7FFFFFFF;
> +                           (pm8001_dev->id & NCQ_READ_LOG_FLAG)) {
>                                 pm80xx_send_abort_all(pm8001_ha, pm8001_dev);
>                                 /* Free the tag */
>                                 pm8001_tag_free(pm8001_ha, tag);
> --
> 2.34.1
>

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH v4 31/31] scsi: pm8001: Fix pm8001_info() message format
  2022-02-17 13:29 ` [PATCH v4 31/31] scsi: pm8001: Fix pm8001_info() message format Damien Le Moal
@ 2022-02-17 19:50   ` Jinpu Wang
  0 siblings, 0 replies; 65+ messages in thread
From: Jinpu Wang @ 2022-02-17 19:50 UTC (permalink / raw)
  To: Damien Le Moal
  Cc: linux-scsi, Martin K . Petersen, Jack Wang, John Garry,
	Xiang Chen, Jason Yan, Luo Jiaxing

On Thu, Feb 17, 2022 at 2:30 PM Damien Le Moal
<damien.lemoal@opensource.wdc.com> wrote:
>
> Make the driver messages more readable by adding a space after the
> message prefix ":" and removing the extra space between function name
> and line number.
>
> Signed-off-by: Damien Le Moal <damien.lemoal@opensource.wdc.com>
Reviewed-by: Jack Wang <jinpu.wang@ionos.com>
> ---
>  drivers/scsi/pm8001/pm8001_sas.h | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/scsi/pm8001/pm8001_sas.h b/drivers/scsi/pm8001/pm8001_sas.h
> index 2aab357d9a23..d78e6690333f 100644
> --- a/drivers/scsi/pm8001/pm8001_sas.h
> +++ b/drivers/scsi/pm8001/pm8001_sas.h
> @@ -71,7 +71,7 @@
>  #define PM8001_IOERR_LOGGING   0x200 /* development io err message logging */
>
>  #define pm8001_info(HBA, fmt, ...)                                     \
> -       pr_info("%s:: %s  %d:" fmt,                                     \
> +       pr_info("%s:: %s %d: " fmt,                                     \
>                 (HBA)->name, __func__, __LINE__, ##__VA_ARGS__)
>
>  #define pm8001_dbg(HBA, level, fmt, ...)                               \
> --
> 2.34.1
>

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH v4 22/31] scsi: pm8001: Fix tag leaks on error
  2022-02-17 17:41   ` John Garry
@ 2022-02-17 22:42     ` Damien Le Moal
  2022-02-18  2:08     ` Damien Le Moal
  1 sibling, 0 replies; 65+ messages in thread
From: Damien Le Moal @ 2022-02-17 22:42 UTC (permalink / raw)
  To: John Garry, linux-scsi, Martin K . Petersen, Jack Wang
  Cc: Xiang Chen, Jason Yan, Luo Jiaxing

On 2/18/22 02:41, John Garry wrote:
> On 17/02/2022 13:29, Damien Le Moal wrote:
>> In pm8001_chip_set_dev_state_req(), pm8001_chip_fw_flash_update_req()
>> and pm8001_chip_reg_dev_req() add missing calls to pm8001_tag_free() to
>> free the allocated tag when pm8001_mpi_build_cmd() fails.
>>
>> Similarly, in pm8001_exec_internal_task_abort(), if the chip
>> ->task_abort method fails, the tag allocated for the abort request task
>> must be freed. Add the missing call to pm8001_tag_free(). Also remove
>> the useless ex_err label and use "break" instead of "goto" statements
>> in the retry loop.
>>
>> Signed-off-by: Damien Le Moal <damien.lemoal@opensource.wdc.com>
> 
> This looks ok, but I think pm80xx_chip_phy_ctl_req() might be missed.

It is fixed separately in patch 18. I should have squashed it into this
one. forgot :)

> 
> Apart from that and a nit, below:
> 
> Reviewed-by: John Garry <john.garry@huawei.com>
> 
>> ---
>>   drivers/scsi/pm8001/pm8001_hwi.c |  9 +++++++++
>>   drivers/scsi/pm8001/pm8001_sas.c | 33 +++++++++++++++++---------------
>>   2 files changed, 27 insertions(+), 15 deletions(-)
>>
>> diff --git a/drivers/scsi/pm8001/pm8001_hwi.c b/drivers/scsi/pm8001/pm8001_hwi.c
>> index cc96e58454c8..431fc9160637 100644
>> --- a/drivers/scsi/pm8001/pm8001_hwi.c
>> +++ b/drivers/scsi/pm8001/pm8001_hwi.c
>> @@ -4458,6 +4458,9 @@ static int pm8001_chip_reg_dev_req(struct pm8001_hba_info *pm8001_ha,
>>   		SAS_ADDR_SIZE);
>>   	rc = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &payload,
>>   			sizeof(payload), 0);
>> +	if (rc)
>> +		pm8001_tag_free(pm8001_ha, tag);
>> +
>>   	return rc;
>>   }
>>   
>> @@ -4870,6 +4873,9 @@ pm8001_chip_fw_flash_update_req(struct pm8001_hba_info *pm8001_ha,
>>   	ccb->ccb_tag = tag;
>>   	rc = pm8001_chip_fw_flash_update_build(pm8001_ha, &flash_update_info,
>>   		tag);
>> +	if (rc)
>> +		pm8001_tag_free(pm8001_ha, tag);
>> +
>>   	return rc;
>>   }
>>   
>> @@ -4974,6 +4980,9 @@ pm8001_chip_set_dev_state_req(struct pm8001_hba_info *pm8001_ha,
>>   	payload.nds = cpu_to_le32(state);
>>   	rc = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &payload,
>>   			sizeof(payload), 0);
>> +	if (rc)
>> +		pm8001_tag_free(pm8001_ha, tag);
>> +
>>   	return rc;
>>   
>>   }
>> diff --git a/drivers/scsi/pm8001/pm8001_sas.c b/drivers/scsi/pm8001/pm8001_sas.c
>> index d0f5feb4f2d3..0440777a9135 100644
>> --- a/drivers/scsi/pm8001/pm8001_sas.c
>> +++ b/drivers/scsi/pm8001/pm8001_sas.c
>> @@ -834,7 +834,8 @@ pm8001_exec_internal_task_abort(struct pm8001_hba_info *pm8001_ha,
>>   
>>   		res = pm8001_tag_alloc(pm8001_ha, &ccb_tag);
>>   		if (res)
>> -			goto ex_err;
>> +			break;
>> +
>>   		ccb = &pm8001_ha->ccb_info[ccb_tag];
>>   		ccb->device = pm8001_dev;
>>   		ccb->ccb_tag = ccb_tag;
>> @@ -843,36 +844,38 @@ pm8001_exec_internal_task_abort(struct pm8001_hba_info *pm8001_ha,
>>   
>>   		res = PM8001_CHIP_DISP->task_abort(pm8001_ha,
>>   			pm8001_dev, flag, task_tag, ccb_tag);
>> -
>>   		if (res) {
>>   			del_timer(&task->slow_task->timer);
>> -			pm8001_dbg(pm8001_ha, FAIL, "Executing internal task failed\n");
>> -			goto ex_err;
>> +			pm8001_dbg(pm8001_ha, FAIL,
>> +				   "Executing internal task failed\n");
>> +			pm8001_tag_free(pm8001_ha, ccb_tag);
>> +			break;
>>   		}
>> +
>>   		wait_for_completion(&task->slow_task->completion);
>>   		res = TMF_RESP_FUNC_FAILED;
>> +
>>   		/* Even TMF timed out, return direct. */
>>   		if (task->task_state_flags & SAS_TASK_STATE_ABORTED) {
>>   			pm8001_dbg(pm8001_ha, FAIL, "TMF task timeout.\n");
>> -			goto ex_err;
>> +			break;
>>   		}
> 
> nit: these are really separate changes, but this series is so long 
> already :)
> 
>>   
>>   		if (task->task_status.resp == SAS_TASK_COMPLETE &&
>>   			task->task_status.stat == SAS_SAM_STAT_GOOD) {
>>   			res = TMF_RESP_FUNC_COMPLETE;
>>   			break;
>> -
>> -		} else {
>> -			pm8001_dbg(pm8001_ha, EH,
>> -				   " Task to dev %016llx response: 0x%x status 0x%x\n",
>> -				   SAS_ADDR(dev->sas_addr),
>> -				   task->task_status.resp,
>> -				   task->task_status.stat);
>> -			sas_free_task(task);
>> -			task = NULL;
>>   		}
>> +
>> +		pm8001_dbg(pm8001_ha, EH,
>> +			   " Task to dev %016llx response: 0x%x status 0x%x\n",
>> +			   SAS_ADDR(dev->sas_addr),
>> +			   task->task_status.resp,
>> +			   task->task_status.stat);
>> +		sas_free_task(task);
>> +		task = NULL;
>>   	}
>> -ex_err:
>> +
>>   	BUG_ON(retry == 3 && task != NULL);
>>   	sas_free_task(task);
>>   	return res;
> 


-- 
Damien Le Moal
Western Digital Research

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH v4 22/31] scsi: pm8001: Fix tag leaks on error
  2022-02-17 17:41   ` John Garry
  2022-02-17 22:42     ` Damien Le Moal
@ 2022-02-18  2:08     ` Damien Le Moal
  1 sibling, 0 replies; 65+ messages in thread
From: Damien Le Moal @ 2022-02-18  2:08 UTC (permalink / raw)
  To: John Garry, linux-scsi, Martin K . Petersen, Jack Wang
  Cc: Xiang Chen, Jason Yan, Luo Jiaxing

On 2/18/22 02:41, John Garry wrote:
> On 17/02/2022 13:29, Damien Le Moal wrote:
>> In pm8001_chip_set_dev_state_req(), pm8001_chip_fw_flash_update_req()
>> and pm8001_chip_reg_dev_req() add missing calls to pm8001_tag_free() to
>> free the allocated tag when pm8001_mpi_build_cmd() fails.
>>
>> Similarly, in pm8001_exec_internal_task_abort(), if the chip
>> ->task_abort method fails, the tag allocated for the abort request task
>> must be freed. Add the missing call to pm8001_tag_free(). Also remove
>> the useless ex_err label and use "break" instead of "goto" statements
>> in the retry loop.
>>
>> Signed-off-by: Damien Le Moal <damien.lemoal@opensource.wdc.com>
> 
> This looks ok, but I think pm80xx_chip_phy_ctl_req() might be missed.
> 
> Apart from that and a nit, below:

[...]

>> diff --git a/drivers/scsi/pm8001/pm8001_sas.c b/drivers/scsi/pm8001/pm8001_sas.c
>> index d0f5feb4f2d3..0440777a9135 100644
>> --- a/drivers/scsi/pm8001/pm8001_sas.c
>> +++ b/drivers/scsi/pm8001/pm8001_sas.c
>> @@ -834,7 +834,8 @@ pm8001_exec_internal_task_abort(struct pm8001_hba_info *pm8001_ha,
>>   
>>   		res = pm8001_tag_alloc(pm8001_ha, &ccb_tag);
>>   		if (res)
>> -			goto ex_err;
>> +			break;
>> +
>>   		ccb = &pm8001_ha->ccb_info[ccb_tag];
>>   		ccb->device = pm8001_dev;
>>   		ccb->ccb_tag = ccb_tag;
>> @@ -843,36 +844,38 @@ pm8001_exec_internal_task_abort(struct pm8001_hba_info *pm8001_ha,
>>   
>>   		res = PM8001_CHIP_DISP->task_abort(pm8001_ha,
>>   			pm8001_dev, flag, task_tag, ccb_tag);
>> -
>>   		if (res) {
>>   			del_timer(&task->slow_task->timer);
>> -			pm8001_dbg(pm8001_ha, FAIL, "Executing internal task failed\n");
>> -			goto ex_err;
>> +			pm8001_dbg(pm8001_ha, FAIL,
>> +				   "Executing internal task failed\n");
>> +			pm8001_tag_free(pm8001_ha, ccb_tag);
>> +			break;
>>   		}
>> +
>>   		wait_for_completion(&task->slow_task->completion);
>>   		res = TMF_RESP_FUNC_FAILED;
>> +
>>   		/* Even TMF timed out, return direct. */
>>   		if (task->task_state_flags & SAS_TASK_STATE_ABORTED) {
>>   			pm8001_dbg(pm8001_ha, FAIL, "TMF task timeout.\n");
>> -			goto ex_err;
>> +			break;
>>   		}
> 
> nit: these are really separate changes, but this series is so long 
> already :)

As it is better to have fixes and cleanups separated, I moved these
style changes to another patch and squashed the
pm80xx_chip_phy_ctl_req() tag leak patch into this one. So patch count
remains the same.

Sending v5. All but 2 patches are reviewed now.

Thanks !

-- 
Damien Le Moal
Western Digital Research

^ permalink raw reply	[flat|nested] 65+ messages in thread

end of thread, other threads:[~2022-02-18  2:08 UTC | newest]

Thread overview: 65+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-02-17 13:29 [PATCH v4 00/31] libsas and pm8001 fixes Damien Le Moal
2022-02-17 13:29 ` [PATCH v4 01/31] scsi: libsas: Fix sas_ata_qc_issue() handling of NCQ NON DATA commands Damien Le Moal
2022-02-17 18:56   ` Jinpu Wang
2022-02-17 13:29 ` [PATCH v4 02/31] scsi: pm8001: Fix __iomem pointer use in pm8001_phy_control() Damien Le Moal
2022-02-17 19:01   ` Jinpu Wang
2022-02-17 13:29 ` [PATCH v4 03/31] scsi: pm8001: Fix pm8001_update_flash() local variable type Damien Le Moal
2022-02-17 19:03   ` Jinpu Wang
2022-02-17 13:29 ` [PATCH v4 04/31] scsi: pm8001: Fix command initialization in pm80XX_send_read_log() Damien Le Moal
2022-02-17 19:05   ` Jinpu Wang
2022-02-17 13:29 ` [PATCH v4 05/31] scsi: pm8001: Fix pm80xx_pci_mem_copy() interface Damien Le Moal
2022-02-17 19:06   ` Jinpu Wang
2022-02-17 13:29 ` [PATCH v4 06/31] scsi: pm8001: Fix command initialization in pm8001_chip_ssp_tm_req() Damien Le Moal
2022-02-17 19:07   ` Jinpu Wang
2022-02-17 13:29 ` [PATCH v4 07/31] scsi: pm8001: Fix payload initialization in pm80xx_set_thermal_config() Damien Le Moal
2022-02-17 19:09   ` Jinpu Wang
2022-02-17 13:29 ` [PATCH v4 08/31] scsi: pm8001: Fix le32 values handling in pm80xx_set_sas_protocol_timer_config() Damien Le Moal
2022-02-17 19:08   ` Jinpu Wang
2022-02-17 13:29 ` [PATCH v4 09/31] scsi: pm8001: Fix payload initialization in pm80xx_encrypt_update() Damien Le Moal
2022-02-17 19:08   ` Jinpu Wang
2022-02-17 13:29 ` [PATCH v4 10/31] scsi: pm8001: Fix le32 values handling in pm80xx_chip_ssp_io_req() Damien Le Moal
2022-02-17 19:11   ` Jinpu Wang
2022-02-17 13:29 ` [PATCH v4 11/31] scsi: pm8001: Fix le32 values handling in pm80xx_chip_sata_req() Damien Le Moal
2022-02-17 19:13   ` Jinpu Wang
2022-02-17 13:29 ` [PATCH v4 12/31] scsi: pm8001: Fix use of struct set_phy_profile_req fields Damien Le Moal
2022-02-17 19:14   ` Jinpu Wang
2022-02-17 13:29 ` [PATCH v4 13/31] scsi: pm8001: Remove local variable in pm8001_pci_resume() Damien Le Moal
2022-02-17 19:15   ` Jinpu Wang
2022-02-17 13:29 ` [PATCH v4 14/31] scsi: pm8001: Fix NCQ NON DATA command task initialization Damien Le Moal
2022-02-17 19:25   ` Jinpu Wang
2022-02-17 13:29 ` [PATCH v4 15/31] scsi: pm8001: Fix NCQ NON DATA command completion handling Damien Le Moal
2022-02-17 19:28   ` Jinpu Wang
2022-02-17 13:29 ` [PATCH v4 16/31] scsi: pm8001: Fix abort all task initialization Damien Le Moal
2022-02-17 19:30   ` Jinpu Wang
2022-02-17 13:29 ` [PATCH v4 17/31] scsi: pm8001: Fix pm8001_tag_alloc() failures handling Damien Le Moal
2022-02-17 19:31   ` Jinpu Wang
2022-02-17 13:29 ` [PATCH v4 18/31] scsi: pm8001: Fix pm80xx_chip_phy_ctl_req() Damien Le Moal
2022-02-17 19:33   ` Jinpu Wang
2022-02-17 13:29 ` [PATCH v4 19/31] scsi: pm8001: Fix pm8001_mpi_task_abort_resp() Damien Le Moal
2022-02-17 19:35   ` Jinpu Wang
2022-02-17 13:29 ` [PATCH v4 20/31] scsi: pm8001: Fix tag values handling Damien Le Moal
2022-02-17 19:39   ` Jinpu Wang
2022-02-17 13:29 ` [PATCH v4 21/31] scsi: pm8001: Fix task leak in pm8001_send_abort_all() Damien Le Moal
2022-02-17 17:42   ` John Garry
2022-02-17 13:29 ` [PATCH v4 22/31] scsi: pm8001: Fix tag leaks on error Damien Le Moal
2022-02-17 17:41   ` John Garry
2022-02-17 22:42     ` Damien Le Moal
2022-02-18  2:08     ` Damien Le Moal
2022-02-17 13:29 ` [PATCH v4 23/31] scsi: pm8001: fix memory leak in pm8001_chip_fw_flash_update_req() Damien Le Moal
2022-02-17 19:42   ` Jinpu Wang
2022-02-17 13:29 ` [PATCH v4 24/31] scsi: libsas: Simplify sas_ata_qc_issue() detection of NCQ commands Damien Le Moal
2022-02-17 19:43   ` Jinpu Wang
2022-02-17 13:29 ` [PATCH v4 25/31] scsi: pm8001: Simplify pm8001_get_ncq_tag() Damien Le Moal
2022-02-17 19:43   ` Jinpu Wang
2022-02-17 13:29 ` [PATCH v4 26/31] scsi: pm8001: Introduce ccb alloc/free helpers Damien Le Moal
2022-02-17 19:45   ` Jinpu Wang
2022-02-17 13:29 ` [PATCH v4 27/31] scsi: pm8001: Simplify pm8001_mpi_build_cmd() interface Damien Le Moal
2022-02-17 19:46   ` Jinpu Wang
2022-02-17 13:29 ` [PATCH v4 28/31] scsi: pm8001: Simplify pm8001_task_exec() Damien Le Moal
2022-02-17 19:47   ` Jinpu Wang
2022-02-17 13:29 ` [PATCH v4 29/31] scsi: pm8001: Simplify pm8001_ccb_task_free() Damien Le Moal
2022-02-17 19:48   ` Jinpu Wang
2022-02-17 13:29 ` [PATCH v4 30/31] scsi: pm8001: improve pm80XX_send_abort_all() Damien Le Moal
2022-02-17 19:49   ` Jinpu Wang
2022-02-17 13:29 ` [PATCH v4 31/31] scsi: pm8001: Fix pm8001_info() message format Damien Le Moal
2022-02-17 19:50   ` Jinpu Wang

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.