Commit 5a141315 authored by Viswas G's avatar Viswas G Committed by Martin K. Petersen

scsi: pm80xx: Increase the number of outstanding I/O supported to 1024

The pm80xx driver currently sets the controller queue depth to
256. Hoewver, the controller supports outstanding I/Os up 1024.

Increase the number of outstanding I/Os from 256 to 1024.  CCBs and tags
are allocated according to outstanding I/Os. Also update the can_queue
value (max_out_io - PM8001_RESERVE_SLOT) used by the SCSI midlayer.

[mkp: fixed zeroday complaint]

Link: https://lore.kernel.org/r/20201005145011.23674-4-Viswas.G@microchip.com.comReported-by: default avatarkernel test robot <lkp@intel.com>
Acked-by: default avatarJack Wang <jinpu.wang@cloud.ionos.com>
Signed-off-by: default avatarViswas G <Viswas.G@microchip.com>
Signed-off-by: default avatarRuksar Devadi <Ruksar.devadi@microchip.com>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent 27bc43bd
......@@ -75,7 +75,7 @@ enum port_type {
};
/* driver compile-time configuration */
#define PM8001_MAX_CCB 256 /* max ccbs supported */
#define PM8001_MAX_CCB 1024 /* max ccbs supported */
#define PM8001_MPI_QUEUE 1024 /* maximum mpi queue entries */
#define PM8001_MAX_INB_NUM 64
#define PM8001_MAX_OUTB_NUM 64
......@@ -90,9 +90,11 @@ enum port_type {
#define PM8001_MAX_PORTS 16 /* max. possible ports */
#define PM8001_MAX_DEVICES 2048 /* max supported device */
#define PM8001_MAX_MSIX_VEC 64 /* max msi-x int for spcv/ve */
#define PM8001_RESERVE_SLOT 8
#define CONFIG_SCSI_PM8001_MAX_DMA_SG 528
#define PM8001_MAX_DMA_SG CONFIG_SCSI_PM8001_MAX_DMA_SG
enum memory_region_num {
AAP1 = 0x0, /* application acceleration processor */
IOP, /* IO processor */
......
......@@ -4375,8 +4375,7 @@ static int pm8001_chip_ssp_io_req(struct pm8001_hba_info *pm8001_ha,
/* fill in PRD (scatter/gather) table, if any */
if (task->num_scatter > 1) {
pm8001_chip_make_sg(task->scatter, ccb->n_elem, ccb->buf_prd);
phys_addr = ccb->ccb_dma_handle +
offsetof(struct pm8001_ccb_info, buf_prd[0]);
phys_addr = ccb->ccb_dma_handle;
ssp_cmd.addr_low = cpu_to_le32(lower_32_bits(phys_addr));
ssp_cmd.addr_high = cpu_to_le32(upper_32_bits(phys_addr));
ssp_cmd.esgl = cpu_to_le32(1<<31);
......@@ -4449,8 +4448,7 @@ static int pm8001_chip_sata_req(struct pm8001_hba_info *pm8001_ha,
/* fill in PRD (scatter/gather) table, if any */
if (task->num_scatter > 1) {
pm8001_chip_make_sg(task->scatter, ccb->n_elem, ccb->buf_prd);
phys_addr = ccb->ccb_dma_handle +
offsetof(struct pm8001_ccb_info, buf_prd[0]);
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);
......
......@@ -56,6 +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 *);
/*
* chip info structure to identify chip key functionality as
......@@ -302,9 +303,6 @@ static int pm8001_alloc(struct pm8001_hba_info *pm8001_ha,
INIT_LIST_HEAD(&pm8001_ha->port[i].list);
}
pm8001_ha->tags = kzalloc(PM8001_MAX_CCB, GFP_KERNEL);
if (!pm8001_ha->tags)
goto err_out;
/* MPI Memory region 1 for AAP Event Log for fw */
pm8001_ha->memoryMap.region[AAP1].num_elements = 1;
pm8001_ha->memoryMap.region[AAP1].element_size = PM8001_EVENT_LOG_SIZE;
......@@ -416,29 +414,11 @@ static int pm8001_alloc(struct pm8001_hba_info *pm8001_ha,
pm8001_ha->devices[i].device_id = PM8001_MAX_DEVICES;
pm8001_ha->devices[i].running_req = 0;
}
/* Memory region for ccb_info*/
pm8001_ha->ccb_info = kzalloc(PM8001_MAX_CCB
* sizeof(struct pm8001_ccb_info), GFP_KERNEL);
if (!pm8001_ha->ccb_info) {
rc = -ENOMEM;
goto err_out_noccb;
}
for (i = 0; i < PM8001_MAX_CCB; i++) {
pm8001_ha->ccb_info[i].ccb_dma_handle =
virt_to_phys(pm8001_ha->ccb_info) +
(i * sizeof(struct pm8001_ccb_info));
pm8001_ha->ccb_info[i].task = NULL;
pm8001_ha->ccb_info[i].ccb_tag = 0xffffffff;
pm8001_ha->ccb_info[i].device = NULL;
++pm8001_ha->tags_num;
}
pm8001_ha->flags = PM8001F_INIT_TIME;
/* Initialize tags */
pm8001_tag_init(pm8001_ha);
return 0;
err_out_noccb:
kfree(pm8001_ha->devices);
err_out_shost:
scsi_remove_host(pm8001_ha->shost);
err_out_nodev:
......@@ -1133,6 +1113,10 @@ static int pm8001_pci_probe(struct pci_dev *pdev,
goto err_out_ha_free;
}
rc = pm8001_init_ccb_tag(pm8001_ha, shost, pdev);
if (rc)
goto err_out_enable;
rc = scsi_add_host(shost, &pdev->dev);
if (rc)
goto err_out_ha_free;
......@@ -1178,6 +1162,60 @@ static int pm8001_pci_probe(struct pci_dev *pdev,
return rc;
}
/*
* pm8001_init_ccb_tag - allocate memory to CCB and tag.
* @pm8001_ha: our hba card information.
* @shost: scsi host which has been allocated outside.
*/
static int
pm8001_init_ccb_tag(struct pm8001_hba_info *pm8001_ha, struct Scsi_Host *shost,
struct pci_dev *pdev)
{
int i = 0;
u32 max_out_io, ccb_count;
u32 can_queue;
max_out_io = pm8001_ha->main_cfg_tbl.pm80xx_tbl.max_out_io;
ccb_count = min_t(int, PM8001_MAX_CCB, max_out_io);
/* Update to the scsi host*/
can_queue = ccb_count - PM8001_RESERVE_SLOT;
shost->can_queue = can_queue;
pm8001_ha->tags = kzalloc(ccb_count, GFP_KERNEL);
if (!pm8001_ha->tags)
goto err_out;
/* Memory region for ccb_info*/
pm8001_ha->ccb_info = (struct pm8001_ccb_info *)
kcalloc(ccb_count, sizeof(struct pm8001_ccb_info), GFP_KERNEL);
if (!pm8001_ha->ccb_info) {
PM8001_FAIL_DBG(pm8001_ha, pm8001_printk
("Unable to allocate memory for ccb\n"));
goto err_out_noccb;
}
for (i = 0; i < ccb_count; i++) {
pm8001_ha->ccb_info[i].buf_prd = pci_alloc_consistent(pdev,
sizeof(struct pm8001_prd) * PM8001_MAX_DMA_SG,
&pm8001_ha->ccb_info[i].ccb_dma_handle);
if (!pm8001_ha->ccb_info[i].buf_prd) {
PM8001_FAIL_DBG(pm8001_ha, pm8001_printk
("pm80xx: ccb prd memory allocation error\n"));
goto err_out;
}
pm8001_ha->ccb_info[i].task = NULL;
pm8001_ha->ccb_info[i].ccb_tag = 0xffffffff;
pm8001_ha->ccb_info[i].device = NULL;
++pm8001_ha->tags_num;
}
return 0;
err_out_noccb:
kfree(pm8001_ha->devices);
err_out:
return -ENOMEM;
}
static void pm8001_pci_remove(struct pci_dev *pdev)
{
struct sas_ha_struct *sha = pci_get_drvdata(pdev);
......
......@@ -315,7 +315,7 @@ struct pm8001_ccb_info {
u32 ccb_tag;
dma_addr_t ccb_dma_handle;
struct pm8001_device *device;
struct pm8001_prd buf_prd[PM8001_MAX_DMA_SG];
struct pm8001_prd *buf_prd;
struct fw_control_ex *fw_control_context;
u8 open_retry;
};
......
......@@ -4483,8 +4483,7 @@ static int pm80xx_chip_ssp_io_req(struct pm8001_hba_info *pm8001_ha,
if (task->num_scatter > 1) {
pm8001_chip_make_sg(task->scatter,
ccb->n_elem, ccb->buf_prd);
phys_addr = ccb->ccb_dma_handle +
offsetof(struct pm8001_ccb_info, buf_prd[0]);
phys_addr = ccb->ccb_dma_handle;
ssp_cmd.enc_addr_low =
cpu_to_le32(lower_32_bits(phys_addr));
ssp_cmd.enc_addr_high =
......@@ -4513,9 +4512,7 @@ static int pm80xx_chip_ssp_io_req(struct pm8001_hba_info *pm8001_ha,
end_addr_high, end_addr_low));
pm8001_chip_make_sg(task->scatter, 1,
ccb->buf_prd);
phys_addr = ccb->ccb_dma_handle +
offsetof(struct pm8001_ccb_info,
buf_prd[0]);
phys_addr = ccb->ccb_dma_handle;
ssp_cmd.enc_addr_low =
cpu_to_le32(lower_32_bits(phys_addr));
ssp_cmd.enc_addr_high =
......@@ -4543,8 +4540,7 @@ static int pm80xx_chip_ssp_io_req(struct pm8001_hba_info *pm8001_ha,
if (task->num_scatter > 1) {
pm8001_chip_make_sg(task->scatter, ccb->n_elem,
ccb->buf_prd);
phys_addr = ccb->ccb_dma_handle +
offsetof(struct pm8001_ccb_info, buf_prd[0]);
phys_addr = ccb->ccb_dma_handle;
ssp_cmd.addr_low =
cpu_to_le32(lower_32_bits(phys_addr));
ssp_cmd.addr_high =
......@@ -4572,9 +4568,7 @@ static int pm80xx_chip_ssp_io_req(struct pm8001_hba_info *pm8001_ha,
end_addr_high, end_addr_low));
pm8001_chip_make_sg(task->scatter, 1,
ccb->buf_prd);
phys_addr = ccb->ccb_dma_handle +
offsetof(struct pm8001_ccb_info,
buf_prd[0]);
phys_addr = ccb->ccb_dma_handle;
ssp_cmd.addr_low =
cpu_to_le32(lower_32_bits(phys_addr));
ssp_cmd.addr_high =
......@@ -4666,8 +4660,7 @@ static int pm80xx_chip_sata_req(struct pm8001_hba_info *pm8001_ha,
if (task->num_scatter > 1) {
pm8001_chip_make_sg(task->scatter,
ccb->n_elem, ccb->buf_prd);
phys_addr = ccb->ccb_dma_handle +
offsetof(struct pm8001_ccb_info, buf_prd[0]);
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_esgl = cpu_to_le32(1 << 31);
......@@ -4692,9 +4685,7 @@ static int pm80xx_chip_sata_req(struct pm8001_hba_info *pm8001_ha,
end_addr_high, end_addr_low));
pm8001_chip_make_sg(task->scatter, 1,
ccb->buf_prd);
phys_addr = ccb->ccb_dma_handle +
offsetof(struct pm8001_ccb_info,
buf_prd[0]);
phys_addr = ccb->ccb_dma_handle;
sata_cmd.enc_addr_low =
lower_32_bits(phys_addr);
sata_cmd.enc_addr_high =
......@@ -4732,8 +4723,7 @@ static int pm80xx_chip_sata_req(struct pm8001_hba_info *pm8001_ha,
if (task->num_scatter > 1) {
pm8001_chip_make_sg(task->scatter,
ccb->n_elem, ccb->buf_prd);
phys_addr = ccb->ccb_dma_handle +
offsetof(struct pm8001_ccb_info, buf_prd[0]);
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);
......@@ -4758,9 +4748,7 @@ static int pm80xx_chip_sata_req(struct pm8001_hba_info *pm8001_ha,
end_addr_high, end_addr_low));
pm8001_chip_make_sg(task->scatter, 1,
ccb->buf_prd);
phys_addr = ccb->ccb_dma_handle +
offsetof(struct pm8001_ccb_info,
buf_prd[0]);
phys_addr = ccb->ccb_dma_handle;
sata_cmd.addr_low =
lower_32_bits(phys_addr);
sata_cmd.addr_high =
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment