From 98132d842d4d1ca64c829eb968ff1df53b37aead Mon Sep 17 00:00:00 2001 From: John Garry Date: Sat, 11 Jun 2022 00:46:40 +0800 Subject: [PATCH] scsi: pm8001: Set up tags before using them The current code is buggy in that the tags are set up after they are needed in pm80xx_chip_init() -> pm80xx_set_sas_protocol_timer_config(). The tag depth is earlier read in pm80xx_chip_init() -> read_main_config_table(). Add a post init callback to do the pm80xx work which needs to be done after reading the tags. I don't see a better way to do this. Link: https://lore.kernel.org/r/1654879602-33497-3-git-send-email-john.garry@huawei.com Tested-by: Damien Le Moal Signed-off-by: John Garry Signed-off-by: Martin K. Petersen --- drivers/scsi/pm8001/pm8001_hwi.c | 5 +++++ drivers/scsi/pm8001/pm8001_init.c | 18 +++++++++--------- drivers/scsi/pm8001/pm8001_sas.h | 1 + drivers/scsi/pm8001/pm80xx_hwi.c | 11 +++++++++-- 4 files changed, 24 insertions(+), 11 deletions(-) diff --git a/drivers/scsi/pm8001/pm8001_hwi.c b/drivers/scsi/pm8001/pm8001_hwi.c index f7466a895d3b..a37595621d51 100644 --- a/drivers/scsi/pm8001/pm8001_hwi.c +++ b/drivers/scsi/pm8001/pm8001_hwi.c @@ -699,6 +699,10 @@ static int pm8001_chip_init(struct pm8001_hba_info *pm8001_ha) return 0; } +static void pm8001_chip_post_init(struct pm8001_hba_info *pm8001_ha) +{ +} + static int mpi_uninit_check(struct pm8001_hba_info *pm8001_ha) { u32 max_wait_count; @@ -4947,6 +4951,7 @@ pm8001_chip_sas_re_initialization(struct pm8001_hba_info *pm8001_ha) const struct pm8001_dispatch pm8001_8001_dispatch = { .name = "pmc8001", .chip_init = pm8001_chip_init, + .chip_post_init = pm8001_chip_post_init, .chip_soft_rst = pm8001_chip_soft_rst, .chip_rst = pm8001_hw_chip_rst, .chip_iounmap = pm8001_chip_iounmap, diff --git a/drivers/scsi/pm8001/pm8001_init.c b/drivers/scsi/pm8001/pm8001_init.c index 4288c6b8f041..171f0a2cf2d6 100644 --- a/drivers/scsi/pm8001/pm8001_init.c +++ b/drivers/scsi/pm8001/pm8001_init.c @@ -56,7 +56,7 @@ MODULE_PARM_DESC(link_rate, "Enable link rate.\n" " 8: Link rate 12.0G\n"); static struct scsi_transport_template *pm8001_stt; -static int pm8001_init_ccb_tag(struct pm8001_hba_info *, struct Scsi_Host *, struct pci_dev *); +static int pm8001_init_ccb_tag(struct pm8001_hba_info *); /* * chip info structure to identify chip key functionality as @@ -1119,10 +1119,12 @@ static int pm8001_pci_probe(struct pci_dev *pdev, goto err_out_ha_free; } - rc = pm8001_init_ccb_tag(pm8001_ha, shost, pdev); + rc = pm8001_init_ccb_tag(pm8001_ha); if (rc) goto err_out_enable; + PM8001_CHIP_DISP->chip_post_init(pm8001_ha); + rc = scsi_add_host(shost, &pdev->dev); if (rc) goto err_out_ha_free; @@ -1172,16 +1174,14 @@ err_out_enable: /** * pm8001_init_ccb_tag - allocate memory to CCB and tag. * @pm8001_ha: our hba card information. - * @shost: scsi host which has been allocated outside. - * @pdev: pci device. */ -static int -pm8001_init_ccb_tag(struct pm8001_hba_info *pm8001_ha, struct Scsi_Host *shost, - struct pci_dev *pdev) +static int pm8001_init_ccb_tag(struct pm8001_hba_info *pm8001_ha) { - int i = 0; + struct Scsi_Host *shost = pm8001_ha->shost; + struct device *dev = pm8001_ha->dev; u32 max_out_io, ccb_count; u32 can_queue; + int i; max_out_io = pm8001_ha->main_cfg_tbl.pm80xx_tbl.max_out_io; ccb_count = min_t(int, PM8001_MAX_CCB, max_out_io); @@ -1204,7 +1204,7 @@ pm8001_init_ccb_tag(struct pm8001_hba_info *pm8001_ha, struct Scsi_Host *shost, goto err_out_noccb; } for (i = 0; i < ccb_count; i++) { - pm8001_ha->ccb_info[i].buf_prd = dma_alloc_coherent(&pdev->dev, + pm8001_ha->ccb_info[i].buf_prd = dma_alloc_coherent(dev, sizeof(struct pm8001_prd) * PM8001_MAX_DMA_SG, &pm8001_ha->ccb_info[i].ccb_dma_handle, GFP_KERNEL); diff --git a/drivers/scsi/pm8001/pm8001_sas.h b/drivers/scsi/pm8001/pm8001_sas.h index 060ab680a7ed..c761a2fd25e5 100644 --- a/drivers/scsi/pm8001/pm8001_sas.h +++ b/drivers/scsi/pm8001/pm8001_sas.h @@ -172,6 +172,7 @@ struct forensic_data { struct pm8001_dispatch { char *name; int (*chip_init)(struct pm8001_hba_info *pm8001_ha); + void (*chip_post_init)(struct pm8001_hba_info *pm8001_ha); int (*chip_soft_rst)(struct pm8001_hba_info *pm8001_ha); void (*chip_rst)(struct pm8001_hba_info *pm8001_ha); int (*chip_ioremap)(struct pm8001_hba_info *pm8001_ha); diff --git a/drivers/scsi/pm8001/pm80xx_hwi.c b/drivers/scsi/pm8001/pm80xx_hwi.c index 01c5e8ff4cc5..d5cc726c034e 100644 --- a/drivers/scsi/pm8001/pm80xx_hwi.c +++ b/drivers/scsi/pm8001/pm80xx_hwi.c @@ -1469,11 +1469,18 @@ static int pm80xx_chip_init(struct pm8001_hba_info *pm8001_ha) } else return -EBUSY; + return 0; +} + +static void pm80xx_chip_post_init(struct pm8001_hba_info *pm8001_ha) +{ /* send SAS protocol timer configuration page to FW */ - ret = pm80xx_set_sas_protocol_timer_config(pm8001_ha); + pm80xx_set_sas_protocol_timer_config(pm8001_ha); /* Check for encryption */ if (pm8001_ha->chip->encrypt) { + int ret; + pm8001_dbg(pm8001_ha, INIT, "Checking for encryption\n"); ret = pm80xx_get_encrypt_info(pm8001_ha); if (ret == -1) { @@ -1485,7 +1492,6 @@ static int pm80xx_chip_init(struct pm8001_hba_info *pm8001_ha) } } } - return 0; } static int mpi_uninit_check(struct pm8001_hba_info *pm8001_ha) @@ -5007,6 +5013,7 @@ void pm8001_set_phy_profile_single(struct pm8001_hba_info *pm8001_ha, const struct pm8001_dispatch pm8001_80xx_dispatch = { .name = "pmc80xx", .chip_init = pm80xx_chip_init, + .chip_post_init = pm80xx_chip_post_init, .chip_soft_rst = pm80xx_chip_soft_rst, .chip_rst = pm80xx_hw_chip_rst, .chip_iounmap = pm8001_chip_iounmap,