summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authoryuuzheng <yuuzheng@google.com>2020-03-16 13:19:03 +0530
committerMartin K. Petersen <martin.petersen@oracle.com>2020-03-17 13:57:16 -0400
commit9d9c7c20fb35444fe26bf284fb89006fd7767ab7 (patch)
treee89b093c1766ece9214eb5ea69a66dab5dac1ae7 /drivers
parentd384be6ede5caa22e8d34dc89949b987c4f44381 (diff)
downloadlinux-9d9c7c20fb35444fe26bf284fb89006fd7767ab7.tar.bz2
scsi: pm80xx: Free the tag when mpi_set_phy_profile_resp is received
In pm80xx driver, the command mpi_set_phy_profile_req is sent by host during boot to configure the phy profile such as analog setting page, rate control page. However, the tag is not freed when its response is received. As a result, 16 tags are missing for each HBA after boot. When NCQ is enabled with queue depth 16, it needs at least, 15 * 16 = 240 tags for each HBA to achieve the best performance. In current pm80xx driver with setting CCB_MAX = 256, the total number of tags in each HBA is 255 for data IO. Hence, without returning those tags to the pool after boot, some device will finally be forced to non-ncq mode by ATA layer due to excessive errors (i.e. LLDD cannot allocate tag for queued task). Link: https://lore.kernel.org/r/20200316074906.9119-4-deepak.ukey@microchip.com Acked-by: Jack Wang <jinpu.wang@cloud.ionos.com> Signed-off-by: yuuzheng <yuuzheng@google.com> Signed-off-by: Deepak Ukey <deepak.ukey@microchip.com> Signed-off-by: Viswas G <Viswas.G@microchip.com> Signed-off-by: Radha Ramachandran <radha@google.com> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/scsi/pm8001/pm80xx_hwi.c10
1 files changed, 7 insertions, 3 deletions
diff --git a/drivers/scsi/pm8001/pm80xx_hwi.c b/drivers/scsi/pm8001/pm80xx_hwi.c
index a3989e544bbe..9e12510d2d5d 100644
--- a/drivers/scsi/pm8001/pm80xx_hwi.c
+++ b/drivers/scsi/pm8001/pm80xx_hwi.c
@@ -3715,28 +3715,32 @@ static int mpi_flash_op_ext_resp(struct pm8001_hba_info *pm8001_ha, void *piomb)
static int mpi_set_phy_profile_resp(struct pm8001_hba_info *pm8001_ha,
void *piomb)
{
+ u32 tag;
u8 page_code;
+ int rc = 0;
struct set_phy_profile_resp *pPayload =
(struct set_phy_profile_resp *)(piomb + 4);
u32 ppc_phyid = le32_to_cpu(pPayload->ppc_phyid);
u32 status = le32_to_cpu(pPayload->status);
+ tag = le32_to_cpu(pPayload->tag);
page_code = (u8)((ppc_phyid & 0xFF00) >> 8);
if (status) {
/* status is FAILED */
PM8001_FAIL_DBG(pm8001_ha,
pm8001_printk("PhyProfile command failed with status "
"0x%08X \n", status));
- return -1;
+ rc = -1;
} else {
if (page_code != SAS_PHY_ANALOG_SETTINGS_PAGE) {
PM8001_FAIL_DBG(pm8001_ha,
pm8001_printk("Invalid page code 0x%X\n",
page_code));
- return -1;
+ rc = -1;
}
}
- return 0;
+ pm8001_tag_free(pm8001_ha, tag);
+ return rc;
}
/**