Commit 98132d84 authored by John Garry's avatar John Garry Committed by Martin K. Petersen
Browse files

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: default avatarDamien Le Moal <damien.lemoal@opensource.wdc.com>
Signed-off-by: default avatarJohn Garry <john.garry@huawei.com>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent 35a7e9db
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -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,
+9 −9
Original line number Diff line number Diff line
@@ -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 @@ static int pm8001_pci_probe(struct pci_dev *pdev,
/**
 * 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);
+1 −0
Original line number Diff line number Diff line
@@ -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);
+9 −2
Original line number Diff line number Diff line
@@ -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,