From 4f6094f1663e2ed26a940f1842cdaa15c1dd649a Mon Sep 17 00:00:00 2001 From: Xiang Chen Date: Tue, 24 Aug 2021 18:00:56 +0800 Subject: [PATCH 001/279] scsi: hisi_sas: Use managed PCI functions Use managed PCI functions such as pcim_enable_device() and pcim_iomap_regions() to simplify exception handling code. Link: https://lore.kernel.org/r/1629799260-120116-2-git-send-email-john.garry@huawei.com Signed-off-by: Xiang Chen Signed-off-by: John Garry Signed-off-by: Martin K. Petersen --- drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c index 3ab669dc806f..e3be5743e77b 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c @@ -518,6 +518,8 @@ struct hisi_sas_err_record_v3 { #define CHNL_INT_STS_INT2_MSK BIT(3) #define CHNL_WIDTH 4 +#define BAR_NO_V3_HW 5 + enum { DSM_FUNC_ERR_HANDLE_MSI = 0, }; @@ -4676,15 +4678,15 @@ hisi_sas_v3_probe(struct pci_dev *pdev, const struct pci_device_id *id) struct sas_ha_struct *sha; int rc, phy_nr, port_nr, i; - rc = pci_enable_device(pdev); + rc = pcim_enable_device(pdev); if (rc) goto err_out; pci_set_master(pdev); - rc = pci_request_regions(pdev, DRV_NAME); + rc = pcim_iomap_regions(pdev, 1 << BAR_NO_V3_HW, DRV_NAME); if (rc) - goto err_out_disable_device; + goto err_out; rc = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64)); if (rc) @@ -4692,20 +4694,20 @@ hisi_sas_v3_probe(struct pci_dev *pdev, const struct pci_device_id *id) if (rc) { dev_err(dev, "No usable DMA addressing method\n"); rc = -ENODEV; - goto err_out_regions; + goto err_out; } shost = hisi_sas_shost_alloc_pci(pdev); if (!shost) { rc = -ENOMEM; - goto err_out_regions; + goto err_out; } sha = SHOST_TO_SAS_HA(shost); hisi_hba = shost_priv(shost); dev_set_drvdata(dev, sha); - hisi_hba->regs = pcim_iomap(pdev, 5, 0); + hisi_hba->regs = pcim_iomap_table(pdev)[BAR_NO_V3_HW]; if (!hisi_hba->regs) { dev_err(dev, "cannot map register\n"); rc = -ENOMEM; @@ -4799,10 +4801,6 @@ err_out_debugfs: err_out_ha: hisi_sas_free(hisi_hba); scsi_host_put(shost); -err_out_regions: - pci_release_regions(pdev); -err_out_disable_device: - pci_disable_device(pdev); err_out: return rc; } @@ -4840,8 +4838,6 @@ static void hisi_sas_v3_remove(struct pci_dev *pdev) sas_remove_host(sha->core.shost); hisi_sas_v3_destroy_irqs(pdev, hisi_hba); - pci_release_regions(pdev); - pci_disable_device(pdev); hisi_sas_free(hisi_hba); debugfs_exit_v3_hw(hisi_hba); scsi_host_put(shost); From 089226ef6a084470f4665a68ad7eb48fb48db093 Mon Sep 17 00:00:00 2001 From: John Garry Date: Tue, 24 Aug 2021 18:00:57 +0800 Subject: [PATCH 002/279] scsi: hisi_sas: Stop printing queue count in v3 hardware probe The number of hardware queues is available from sysfs. Remove the print in the v3 hardware probe function. Link: https://lore.kernel.org/r/1629799260-120116-3-git-send-email-john.garry@huawei.com Signed-off-by: John Garry Signed-off-by: Martin K. Petersen --- drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c index e3be5743e77b..f57d9f488a42 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c @@ -4762,7 +4762,7 @@ hisi_sas_v3_probe(struct pci_dev *pdev, const struct pci_device_id *id) rc = interrupt_preinit_v3_hw(hisi_hba); if (rc) goto err_out_debugfs; - dev_err(dev, "%d hw queues\n", shost->nr_hw_queues); + rc = scsi_add_host(shost, dev); if (rc) goto err_out_free_irq_vectors; From b5a9fa20e3bf59d89b5f48315a0c0c32963796ed Mon Sep 17 00:00:00 2001 From: Luo Jiaxing Date: Tue, 24 Aug 2021 18:00:58 +0800 Subject: [PATCH 003/279] scsi: hisi_sas: Rename HISI_SAS_{RESET -> RESETTING}_BIT HISI_SAS_RESET_BIT means that the controller is being reset, and so the name is a bit vague. Rename it to HISI_SAS_RESETTING_BIT. Link: https://lore.kernel.org/r/1629799260-120116-4-git-send-email-john.garry@huawei.com Signed-off-by: Luo Jiaxing Signed-off-by: John Garry Signed-off-by: Martin K. Petersen --- drivers/scsi/hisi_sas/hisi_sas.h | 2 +- drivers/scsi/hisi_sas/hisi_sas_main.c | 12 ++++++------ drivers/scsi/hisi_sas/hisi_sas_v1_hw.c | 2 +- drivers/scsi/hisi_sas/hisi_sas_v2_hw.c | 2 +- drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 10 +++++----- 5 files changed, 14 insertions(+), 14 deletions(-) diff --git a/drivers/scsi/hisi_sas/hisi_sas.h b/drivers/scsi/hisi_sas/hisi_sas.h index 436d174f2194..57be32ba0109 100644 --- a/drivers/scsi/hisi_sas/hisi_sas.h +++ b/drivers/scsi/hisi_sas/hisi_sas.h @@ -35,7 +35,7 @@ #define HISI_SAS_QUEUE_SLOTS 4096 #define HISI_SAS_MAX_ITCT_ENTRIES 1024 #define HISI_SAS_MAX_DEVICES HISI_SAS_MAX_ITCT_ENTRIES -#define HISI_SAS_RESET_BIT 0 +#define HISI_SAS_RESETTING_BIT 0 #define HISI_SAS_REJECT_CMD_BIT 1 #define HISI_SAS_PM_BIT 2 #define HISI_SAS_HW_FAULT_BIT 3 diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c index 9515c45affa5..fec4db46c76c 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_main.c +++ b/drivers/scsi/hisi_sas/hisi_sas_main.c @@ -724,7 +724,7 @@ static int hisi_sas_init_device(struct domain_device *device) */ local_phy = sas_get_local_phy(device); if (!scsi_is_sas_phy_local(local_phy) && - !test_bit(HISI_SAS_RESET_BIT, &hisi_hba->flags)) { + !test_bit(HISI_SAS_RESETTING_BIT, &hisi_hba->flags)) { unsigned long deadline = ata_deadline(jiffies, 20000); struct sata_device *sata_dev = &device->sata_dev; struct ata_host *ata_host = sata_dev->ata_host; @@ -1072,7 +1072,7 @@ static void hisi_sas_dev_gone(struct domain_device *device) sas_dev->device_id, sas_dev->dev_type); down(&hisi_hba->sem); - if (!test_bit(HISI_SAS_RESET_BIT, &hisi_hba->flags)) { + if (!test_bit(HISI_SAS_RESETTING_BIT, &hisi_hba->flags)) { hisi_sas_internal_task_abort(hisi_hba, device, HISI_SAS_INT_ABT_DEV, 0, true); @@ -1576,7 +1576,7 @@ void hisi_sas_controller_reset_done(struct hisi_hba *hisi_hba) hisi_sas_reset_init_all_devices(hisi_hba); up(&hisi_hba->sem); scsi_unblock_requests(shost); - clear_bit(HISI_SAS_RESET_BIT, &hisi_hba->flags); + clear_bit(HISI_SAS_RESETTING_BIT, &hisi_hba->flags); hisi_sas_rescan_topology(hisi_hba, hisi_hba->phy_state); } @@ -1587,7 +1587,7 @@ static int hisi_sas_controller_prereset(struct hisi_hba *hisi_hba) if (!hisi_hba->hw->soft_reset) return -1; - if (test_and_set_bit(HISI_SAS_RESET_BIT, &hisi_hba->flags)) + if (test_and_set_bit(HISI_SAS_RESETTING_BIT, &hisi_hba->flags)) return -1; if (hisi_sas_debugfs_enable && hisi_hba->debugfs_itct[0].itct) @@ -1611,7 +1611,7 @@ static int hisi_sas_controller_reset(struct hisi_hba *hisi_hba) clear_bit(HISI_SAS_REJECT_CMD_BIT, &hisi_hba->flags); up(&hisi_hba->sem); scsi_unblock_requests(shost); - clear_bit(HISI_SAS_RESET_BIT, &hisi_hba->flags); + clear_bit(HISI_SAS_RESETTING_BIT, &hisi_hba->flags); return rc; } @@ -2251,7 +2251,7 @@ void hisi_sas_phy_down(struct hisi_hba *hisi_hba, int phy_no, int rdy, } else { struct hisi_sas_port *port = phy->port; - if (test_bit(HISI_SAS_RESET_BIT, &hisi_hba->flags) || + if (test_bit(HISI_SAS_RESETTING_BIT, &hisi_hba->flags) || phy->in_reset) { dev_info(dev, "ignore flutter phy%d down\n", phy_no); return; diff --git a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c index afe639994f3d..862f4e8b7eb5 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c +++ b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c @@ -1422,7 +1422,7 @@ static irqreturn_t int_bcast_v1_hw(int irq, void *p) goto end; } - if (!test_bit(HISI_SAS_RESET_BIT, &hisi_hba->flags)) + if (!test_bit(HISI_SAS_RESETTING_BIT, &hisi_hba->flags)) sas_notify_port_event(sas_phy, PORTE_BROADCAST_RCVD, GFP_ATOMIC); diff --git a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c index b0b2361e63fe..a5fc79b3f732 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c +++ b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c @@ -2824,7 +2824,7 @@ static void phy_bcast_v2_hw(int phy_no, struct hisi_hba *hisi_hba) hisi_sas_phy_write32(hisi_hba, phy_no, SL_RX_BCAST_CHK_MSK, 1); bcast_status = hisi_sas_phy_read32(hisi_hba, phy_no, RX_PRIMS_STATUS); if ((bcast_status & RX_BCAST_CHG_MSK) && - !test_bit(HISI_SAS_RESET_BIT, &hisi_hba->flags)) + !test_bit(HISI_SAS_RESETTING_BIT, &hisi_hba->flags)) sas_notify_port_event(sas_phy, PORTE_BROADCAST_RCVD, GFP_ATOMIC); hisi_sas_phy_write32(hisi_hba, phy_no, CHL_INT0, diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c index f57d9f488a42..b137e5619da1 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c @@ -1617,7 +1617,7 @@ static irqreturn_t phy_bcast_v3_hw(int phy_no, struct hisi_hba *hisi_hba) hisi_sas_phy_write32(hisi_hba, phy_no, SL_RX_BCAST_CHK_MSK, 1); bcast_status = hisi_sas_phy_read32(hisi_hba, phy_no, RX_PRIMS_STATUS); if ((bcast_status & RX_BCAST_CHG_MSK) && - !test_bit(HISI_SAS_RESET_BIT, &hisi_hba->flags)) + !test_bit(HISI_SAS_RESETTING_BIT, &hisi_hba->flags)) sas_notify_port_event(sas_phy, PORTE_BROADCAST_RCVD, GFP_ATOMIC); hisi_sas_phy_write32(hisi_hba, phy_no, CHL_INT0, @@ -4851,7 +4851,7 @@ static void hisi_sas_reset_prepare_v3_hw(struct pci_dev *pdev) int rc; dev_info(dev, "FLR prepare\n"); - set_bit(HISI_SAS_RESET_BIT, &hisi_hba->flags); + set_bit(HISI_SAS_RESETTING_BIT, &hisi_hba->flags); hisi_sas_controller_reset_prepare(hisi_hba); rc = disable_host_v3_hw(hisi_hba); @@ -4897,7 +4897,7 @@ static int _suspend_v3_hw(struct device *device) return -ENODEV; } - if (test_and_set_bit(HISI_SAS_RESET_BIT, &hisi_hba->flags)) + if (test_and_set_bit(HISI_SAS_RESETTING_BIT, &hisi_hba->flags)) return -1; scsi_block_requests(shost); @@ -4908,7 +4908,7 @@ static int _suspend_v3_hw(struct device *device) if (rc) { dev_err(dev, "PM suspend: disable host failed rc=%d\n", rc); clear_bit(HISI_SAS_REJECT_CMD_BIT, &hisi_hba->flags); - clear_bit(HISI_SAS_RESET_BIT, &hisi_hba->flags); + clear_bit(HISI_SAS_RESETTING_BIT, &hisi_hba->flags); scsi_unblock_requests(shost); return rc; } @@ -4947,7 +4947,7 @@ static int _resume_v3_hw(struct device *device) } phys_init_v3_hw(hisi_hba); sas_resume_ha(sha); - clear_bit(HISI_SAS_RESET_BIT, &hisi_hba->flags); + clear_bit(HISI_SAS_RESETTING_BIT, &hisi_hba->flags); return 0; } From 080b4f976bf7a61ae082d5ae1d2cee83b097b63a Mon Sep 17 00:00:00 2001 From: Xiang Chen Date: Tue, 24 Aug 2021 18:00:59 +0800 Subject: [PATCH 004/279] scsi: hisi_sas: Replace del_timer() calls with del_timer_sync() Some usage of del_timer() in the driver is potentially unsafe. When running the sas_task->slow_task timer in hisi_sas_exec_internal_tmf_task(), execution may be blocked in function hisi_sas_task_exec(); so it is possible that the timer is running when the callback to disable the timer is running. This could be dangerous, as we immediately release resources which the timer callback uses after disabling the timer. The same situation may be found at other sites, such as _hisi_sas_internal_task_abort(). Change calls to del_timer() to del_timer_sync() as necessary, to ensure any timer has finished when disabling. Also remove calls to timer_pending() prior to del_timer() as it is not necessary. Link: https://lore.kernel.org/r/1629799260-120116-5-git-send-email-john.garry@huawei.com Signed-off-by: Xiang Chen Signed-off-by: John Garry Signed-off-by: Martin K. Petersen --- drivers/scsi/hisi_sas/hisi_sas_main.c | 12 +++++------- drivers/scsi/hisi_sas/hisi_sas_v2_hw.c | 6 +++--- drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 3 +-- 3 files changed, 9 insertions(+), 12 deletions(-) diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c index fec4db46c76c..bb1c8ef3a76f 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_main.c +++ b/drivers/scsi/hisi_sas/hisi_sas_main.c @@ -1171,7 +1171,7 @@ static int hisi_sas_control_phy(struct asd_sas_phy *sas_phy, enum phy_func func, static void hisi_sas_task_done(struct sas_task *task) { - del_timer(&task->slow_task->timer); + del_timer_sync(&task->slow_task->timer); complete(&task->slow_task->completion); } @@ -1229,7 +1229,7 @@ static int hisi_sas_exec_internal_tmf_task(struct domain_device *device, res = hisi_sas_task_exec(task, GFP_KERNEL, 1, tmf); if (res) { - del_timer(&task->slow_task->timer); + del_timer_sync(&task->slow_task->timer); dev_err(dev, "abort tmf: executing internal task failed: %d\n", res); goto ex_err; @@ -1554,8 +1554,7 @@ void hisi_sas_controller_reset_prepare(struct hisi_hba *hisi_hba) scsi_block_requests(shost); hisi_hba->hw->wait_cmds_complete_timeout(hisi_hba, 100, 5000); - if (timer_pending(&hisi_hba->timer)) - del_timer_sync(&hisi_hba->timer); + del_timer_sync(&hisi_hba->timer); set_bit(HISI_SAS_REJECT_CMD_BIT, &hisi_hba->flags); } @@ -2097,7 +2096,7 @@ _hisi_sas_internal_task_abort(struct hisi_hba *hisi_hba, res = hisi_sas_internal_abort_task_exec(hisi_hba, sas_dev->device_id, task, abort_flag, tag, dq); if (res) { - del_timer(&task->slow_task->timer); + del_timer_sync(&task->slow_task->timer); dev_err(dev, "internal task abort: executing internal task failed: %d\n", res); goto exit; @@ -2769,8 +2768,7 @@ int hisi_sas_remove(struct platform_device *pdev) struct hisi_hba *hisi_hba = sha->lldd_ha; struct Scsi_Host *shost = sha->core.shost; - if (timer_pending(&hisi_hba->timer)) - del_timer(&hisi_hba->timer); + del_timer_sync(&hisi_hba->timer); sas_unregister_ha(sha); sas_remove_host(sha->core.shost); diff --git a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c index a5fc79b3f732..236cf65c2f97 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c +++ b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c @@ -2368,18 +2368,18 @@ static void slot_complete_v2_hw(struct hisi_hba *hisi_hba, case STAT_IO_COMPLETE: /* internal abort command complete */ ts->stat = TMF_RESP_FUNC_SUCC; - del_timer(&slot->internal_abort_timer); + del_timer_sync(&slot->internal_abort_timer); goto out; case STAT_IO_NO_DEVICE: ts->stat = TMF_RESP_FUNC_COMPLETE; - del_timer(&slot->internal_abort_timer); + del_timer_sync(&slot->internal_abort_timer); goto out; case STAT_IO_NOT_VALID: /* abort single io, controller don't find * the io need to abort */ ts->stat = TMF_RESP_FUNC_FAILED; - del_timer(&slot->internal_abort_timer); + del_timer_sync(&slot->internal_abort_timer); goto out; default: break; diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c index b137e5619da1..cbc6c2d86745 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c @@ -4830,8 +4830,7 @@ static void hisi_sas_v3_remove(struct pci_dev *pdev) struct Scsi_Host *shost = sha->core.shost; pm_runtime_get_noresume(dev); - if (timer_pending(&hisi_hba->timer)) - del_timer(&hisi_hba->timer); + del_timer_sync(&hisi_hba->timer); sas_unregister_ha(sha); flush_workqueue(hisi_hba->wq); From 9aec5ffa6e39926cff1a6b576c815a9cee90e259 Mon Sep 17 00:00:00 2001 From: Luo Jiaxing Date: Tue, 24 Aug 2021 18:01:00 +0800 Subject: [PATCH 005/279] scsi: hisi_sas: Increase debugfs_dump_index after dump is completed The hisi_hba debugfs_dump_index member should increased after a dump insertion completed, and not before it has started, so fix the code to do so. Link: https://lore.kernel.org/r/1629799260-120116-6-git-send-email-john.garry@huawei.com Signed-off-by: Luo Jiaxing Signed-off-by: John Garry Signed-off-by: Martin K. Petersen --- drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c index cbc6c2d86745..f4517f3eb922 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c @@ -3688,7 +3688,6 @@ static void debugfs_snapshot_regs_v3_hw(struct hisi_hba *hisi_hba) do_div(timestamp, NSEC_PER_MSEC); hisi_hba->debugfs_timestamp[debugfs_dump_index] = timestamp; - hisi_hba->debugfs_dump_index++; debugfs_snapshot_prepare_v3_hw(hisi_hba); @@ -3704,6 +3703,7 @@ static void debugfs_snapshot_regs_v3_hw(struct hisi_hba *hisi_hba) debugfs_create_files_v3_hw(hisi_hba); debugfs_snapshot_restore_v3_hw(hisi_hba); + hisi_hba->debugfs_dump_index++; } static ssize_t debugfs_trigger_dump_v3_hw_write(struct file *file, From ce4fc333e599c19973455c9d8f6fbb1e7c140dc8 Mon Sep 17 00:00:00 2001 From: John Garry Date: Mon, 13 Sep 2021 18:51:36 +0800 Subject: [PATCH 006/279] scsi: libsas: Co-locate exports with symbols It is standard practice to co-locate export declarations with the symbol which is being exported. Or at least in the same file - see sas_phy_reset(). Modify libsas to follow this practice consistently. Link: https://lore.kernel.org/r/1631530296-32358-1-git-send-email-john.garry@huawei.com Reviewed-by: Jason Yan Signed-off-by: John Garry Signed-off-by: Martin K. Petersen --- drivers/scsi/libsas/sas_init.c | 5 +++-- drivers/scsi/libsas/sas_scsi_host.c | 23 +++++++++++------------ 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/drivers/scsi/libsas/sas_init.c b/drivers/scsi/libsas/sas_init.c index 80592f53017a..37cc92837fdf 100644 --- a/drivers/scsi/libsas/sas_init.c +++ b/drivers/scsi/libsas/sas_init.c @@ -147,6 +147,7 @@ Undo_phys: return error; } +EXPORT_SYMBOL_GPL(sas_register_ha); static void sas_disable_events(struct sas_ha_struct *sas_ha) { @@ -176,6 +177,7 @@ int sas_unregister_ha(struct sas_ha_struct *sas_ha) return 0; } +EXPORT_SYMBOL_GPL(sas_unregister_ha); static int sas_get_linkerrors(struct sas_phy *phy) { @@ -313,6 +315,7 @@ int sas_phy_reset(struct sas_phy *phy, int hard_reset) } return ret; } +EXPORT_SYMBOL_GPL(sas_phy_reset); int sas_set_phy_speed(struct sas_phy *phy, struct sas_phy_linkrates *rates) @@ -659,5 +662,3 @@ MODULE_LICENSE("GPL v2"); module_init(sas_class_init); module_exit(sas_class_exit); -EXPORT_SYMBOL_GPL(sas_register_ha); -EXPORT_SYMBOL_GPL(sas_unregister_ha); diff --git a/drivers/scsi/libsas/sas_scsi_host.c b/drivers/scsi/libsas/sas_scsi_host.c index 08ffb8788290..2bf37151623e 100644 --- a/drivers/scsi/libsas/sas_scsi_host.c +++ b/drivers/scsi/libsas/sas_scsi_host.c @@ -201,6 +201,7 @@ out_done: cmd->scsi_done(cmd); return 0; } +EXPORT_SYMBOL_GPL(sas_queuecommand); static void sas_eh_finish_cmd(struct scsi_cmnd *cmd) { @@ -511,6 +512,7 @@ int sas_eh_device_reset_handler(struct scsi_cmnd *cmd) return FAILED; } +EXPORT_SYMBOL_GPL(sas_eh_device_reset_handler); int sas_eh_target_reset_handler(struct scsi_cmnd *cmd) { @@ -532,6 +534,7 @@ int sas_eh_target_reset_handler(struct scsi_cmnd *cmd) return FAILED; } +EXPORT_SYMBOL_GPL(sas_eh_target_reset_handler); /* Try to reset a device */ static int try_to_reset_cmd_device(struct scsi_cmnd *cmd) @@ -790,6 +793,7 @@ int sas_ioctl(struct scsi_device *sdev, unsigned int cmd, void __user *arg) return -EINVAL; } +EXPORT_SYMBOL_GPL(sas_ioctl); struct domain_device *sas_find_dev_by_rphy(struct sas_rphy *rphy) { @@ -832,6 +836,7 @@ int sas_target_alloc(struct scsi_target *starget) starget->hostdata = found_dev; return 0; } +EXPORT_SYMBOL_GPL(sas_target_alloc); #define SAS_DEF_QD 256 @@ -860,6 +865,7 @@ int sas_slave_configure(struct scsi_device *scsi_dev) return 0; } +EXPORT_SYMBOL_GPL(sas_slave_configure); int sas_change_queue_depth(struct scsi_device *sdev, int depth) { @@ -872,6 +878,7 @@ int sas_change_queue_depth(struct scsi_device *sdev, int depth) depth = 1; return scsi_change_queue_depth(sdev, depth); } +EXPORT_SYMBOL_GPL(sas_change_queue_depth); int sas_bios_param(struct scsi_device *scsi_dev, struct block_device *bdev, @@ -884,6 +891,7 @@ int sas_bios_param(struct scsi_device *scsi_dev, return 0; } +EXPORT_SYMBOL_GPL(sas_bios_param); /* * Tell an upper layer that it needs to initiate an abort for a given task. @@ -910,6 +918,7 @@ void sas_task_abort(struct sas_task *task) else blk_abort_request(scsi_cmd_to_rq(sc)); } +EXPORT_SYMBOL_GPL(sas_task_abort); int sas_slave_alloc(struct scsi_device *sdev) { @@ -918,6 +927,7 @@ int sas_slave_alloc(struct scsi_device *sdev) return 0; } +EXPORT_SYMBOL_GPL(sas_slave_alloc); void sas_target_destroy(struct scsi_target *starget) { @@ -929,6 +939,7 @@ void sas_target_destroy(struct scsi_target *starget) starget->hostdata = NULL; sas_put_device(found_dev); } +EXPORT_SYMBOL_GPL(sas_target_destroy); #define SAS_STRING_ADDR_SIZE 16 @@ -956,15 +967,3 @@ out: } EXPORT_SYMBOL_GPL(sas_request_addr); -EXPORT_SYMBOL_GPL(sas_queuecommand); -EXPORT_SYMBOL_GPL(sas_target_alloc); -EXPORT_SYMBOL_GPL(sas_slave_configure); -EXPORT_SYMBOL_GPL(sas_change_queue_depth); -EXPORT_SYMBOL_GPL(sas_bios_param); -EXPORT_SYMBOL_GPL(sas_task_abort); -EXPORT_SYMBOL_GPL(sas_phy_reset); -EXPORT_SYMBOL_GPL(sas_eh_device_reset_handler); -EXPORT_SYMBOL_GPL(sas_eh_target_reset_handler); -EXPORT_SYMBOL_GPL(sas_slave_alloc); -EXPORT_SYMBOL_GPL(sas_target_destroy); -EXPORT_SYMBOL_GPL(sas_ioctl); From e018f03d6ccbd9c3ce6a9fae4f582113f2a2906b Mon Sep 17 00:00:00 2001 From: Ding Hui Date: Sat, 11 Sep 2021 21:51:59 +0800 Subject: [PATCH 007/279] scsi: libiscsi: Move ehwait initialization to iscsi_session_setup() Commit ec29d0ac29be ("scsi: iscsi: Fix conn use after free during resets") moved member ehwait from 'conn' to 'session', but left the initialization of ehwait in iscsi_conn_setup(). Although a session can only have 1 conn currently, it is better to initialize ehwait in iscsi_session_setup() in case we implement handling multiple conns in the future. Link: https://lore.kernel.org/r/20210911135159.20543-1-dinghui@sangfor.com.cn Reviewed-by: Mike Christie Signed-off-by: Ding Hui Signed-off-by: Martin K. Petersen --- drivers/scsi/libiscsi.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c index 4683c183e9d4..712a45368385 100644 --- a/drivers/scsi/libiscsi.c +++ b/drivers/scsi/libiscsi.c @@ -2947,6 +2947,7 @@ iscsi_session_setup(struct iscsi_transport *iscsit, struct Scsi_Host *shost, session->tmf_state = TMF_INITIAL; timer_setup(&session->tmf_timer, iscsi_tmf_timedout, 0); mutex_init(&session->eh_mutex); + init_waitqueue_head(&session->ehwait); spin_lock_init(&session->frwd_lock); spin_lock_init(&session->back_lock); @@ -3074,8 +3075,6 @@ iscsi_conn_setup(struct iscsi_cls_session *cls_session, int dd_size, goto login_task_data_alloc_fail; conn->login_task->data = conn->data = data; - init_waitqueue_head(&session->ehwait); - return cls_conn; login_task_data_alloc_fail: From 08d0a992131a4db7328b0c2f5a0259732e4d0d12 Mon Sep 17 00:00:00 2001 From: Ajish Koshy Date: Mon, 6 Sep 2021 22:34:01 +0530 Subject: [PATCH 008/279] scsi: pm80xx: Fix incorrect port value when registering a device During phyup event, the firmware provides the phy_id and port_id and driver is supposed to use these during device handle registration. Previously the driver was using the port id value from libsas during device handle registration. Since id can be different from the one assigned by firmware, this can lead to wrong device registration and drives not showing up. Use firmware assigned port id during device registration. Link: https://lore.kernel.org/r/20210906170404.5682-2-Ajish.Koshy@microchip.com Acked-by: Jack Wang Signed-off-by: Ajish Koshy Signed-off-by: Viswas G Signed-off-by: Martin K. Petersen --- drivers/scsi/pm8001/pm8001_hwi.c | 7 ++++++- drivers/scsi/pm8001/pm8001_init.c | 1 + drivers/scsi/pm8001/pm8001_sas.c | 15 +++++++++++++++ drivers/scsi/pm8001/pm8001_sas.h | 2 ++ drivers/scsi/pm8001/pm80xx_hwi.c | 7 ++++++- 5 files changed, 30 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/pm8001/pm8001_hwi.c b/drivers/scsi/pm8001/pm8001_hwi.c index 63690508313b..c9ecddd0d719 100644 --- a/drivers/scsi/pm8001/pm8001_hwi.c +++ b/drivers/scsi/pm8001/pm8001_hwi.c @@ -3358,6 +3358,8 @@ hw_event_sas_phy_up(struct pm8001_hba_info *pm8001_ha, void *piomb) struct pm8001_phy *phy = &pm8001_ha->phy[phy_id]; unsigned long flags; u8 deviceType = pPayload->sas_identify.dev_type; + phy->port = port; + port->port_id = port_id; port->port_state = portstate; phy->phy_state = PHY_STATE_LINK_UP_SPC; pm8001_dbg(pm8001_ha, MSG, @@ -3434,6 +3436,8 @@ hw_event_sata_phy_up(struct pm8001_hba_info *pm8001_ha, void *piomb) unsigned long flags; pm8001_dbg(pm8001_ha, DEVIO, "HW_EVENT_SATA_PHY_UP port id = %d, phy id = %d\n", port_id, phy_id); + phy->port = port; + port->port_id = port_id; port->port_state = portstate; phy->phy_state = PHY_STATE_LINK_UP_SPC; port->port_attached = 1; @@ -4460,6 +4464,7 @@ static int pm8001_chip_reg_dev_req(struct pm8001_hba_info *pm8001_ha, u16 ITNT = 2000; 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)); @@ -4488,7 +4493,7 @@ static int pm8001_chip_reg_dev_req(struct pm8001_hba_info *pm8001_ha, linkrate = (pm8001_dev->sas_device->linkrate < dev->port->linkrate) ? pm8001_dev->sas_device->linkrate : dev->port->linkrate; payload.phyid_portid = - cpu_to_le32(((pm8001_dev->sas_device->port->id) & 0x0F) | + cpu_to_le32(((port->port_id) & 0x0F) | ((phy_id & 0x0F) << 4)); payload.dtype_dlr_retry = cpu_to_le32((retryFlag & 0x01) | ((linkrate & 0x0F) * 0x1000000) | diff --git a/drivers/scsi/pm8001/pm8001_init.c b/drivers/scsi/pm8001/pm8001_init.c index 47db7e0beae6..613455a3e686 100644 --- a/drivers/scsi/pm8001/pm8001_init.c +++ b/drivers/scsi/pm8001/pm8001_init.c @@ -128,6 +128,7 @@ static struct sas_domain_function_template pm8001_transport_ops = { .lldd_I_T_nexus_reset = pm8001_I_T_nexus_reset, .lldd_lu_reset = pm8001_lu_reset, .lldd_query_task = pm8001_query_task, + .lldd_port_formed = pm8001_port_formed, }; /** diff --git a/drivers/scsi/pm8001/pm8001_sas.c b/drivers/scsi/pm8001/pm8001_sas.c index 32e60f0c3b14..83e73009db5c 100644 --- a/drivers/scsi/pm8001/pm8001_sas.c +++ b/drivers/scsi/pm8001/pm8001_sas.c @@ -1355,3 +1355,18 @@ int pm8001_clear_task_set(struct domain_device *dev, u8 *lun) tmf_task.tmf = TMF_CLEAR_TASK_SET; return pm8001_issue_ssp_tmf(dev, lun, &tmf_task); } + +void pm8001_port_formed(struct asd_sas_phy *sas_phy) +{ + struct sas_ha_struct *sas_ha = sas_phy->ha; + struct pm8001_hba_info *pm8001_ha = sas_ha->lldd_ha; + struct pm8001_phy *phy = sas_phy->lldd_phy; + struct asd_sas_port *sas_port = sas_phy->port; + struct pm8001_port *port = phy->port; + + if (!sas_port) { + pm8001_dbg(pm8001_ha, FAIL, "Received null port\n"); + return; + } + sas_port->lldd_port = port; +} diff --git a/drivers/scsi/pm8001/pm8001_sas.h b/drivers/scsi/pm8001/pm8001_sas.h index 62d08b535a4b..1a016a421280 100644 --- a/drivers/scsi/pm8001/pm8001_sas.h +++ b/drivers/scsi/pm8001/pm8001_sas.h @@ -230,6 +230,7 @@ struct pm8001_port { u8 port_attached; u16 wide_port_phymap; u8 port_state; + u8 port_id; struct list_head list; }; @@ -651,6 +652,7 @@ int pm8001_lu_reset(struct domain_device *dev, u8 *lun); int pm8001_I_T_nexus_reset(struct domain_device *dev); int pm8001_I_T_nexus_event_handler(struct domain_device *dev); int pm8001_query_task(struct sas_task *task); +void pm8001_port_formed(struct asd_sas_phy *sas_phy); void pm8001_open_reject_retry( struct pm8001_hba_info *pm8001_ha, struct sas_task *task_to_close, diff --git a/drivers/scsi/pm8001/pm80xx_hwi.c b/drivers/scsi/pm8001/pm80xx_hwi.c index 6ffe17b849ae..cec932f830b8 100644 --- a/drivers/scsi/pm8001/pm80xx_hwi.c +++ b/drivers/scsi/pm8001/pm80xx_hwi.c @@ -3299,6 +3299,8 @@ hw_event_sas_phy_up(struct pm8001_hba_info *pm8001_ha, void *piomb) struct pm8001_phy *phy = &pm8001_ha->phy[phy_id]; unsigned long flags; u8 deviceType = pPayload->sas_identify.dev_type; + phy->port = port; + port->port_id = port_id; port->port_state = portstate; port->wide_port_phymap |= (1U << phy_id); phy->phy_state = PHY_STATE_LINK_UP_SPCV; @@ -3380,6 +3382,8 @@ hw_event_sata_phy_up(struct pm8001_hba_info *pm8001_ha, void *piomb) "port id %d, phy id %d link_rate %d portstate 0x%x\n", port_id, phy_id, link_rate, portstate); + phy->port = port; + port->port_id = port_id; port->port_state = portstate; phy->phy_state = PHY_STATE_LINK_UP_SPCV; port->port_attached = 1; @@ -4808,6 +4812,7 @@ static int pm80xx_chip_reg_dev_req(struct pm8001_hba_info *pm8001_ha, u16 ITNT = 2000; 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)); @@ -4840,7 +4845,7 @@ static int pm80xx_chip_reg_dev_req(struct pm8001_hba_info *pm8001_ha, pm8001_dev->sas_device->linkrate : dev->port->linkrate; payload.phyid_portid = - cpu_to_le32(((pm8001_dev->sas_device->port->id) & 0xFF) | + cpu_to_le32(((port->port_id) & 0xFF) | ((phy_id & 0xFF) << 8)); payload.dtype_dlr_mcn_ir_retry = cpu_to_le32((retryFlag & 0x01) | From b27a40534ef76a22628a5c12f98ea489823a8ba5 Mon Sep 17 00:00:00 2001 From: Ajish Koshy Date: Mon, 6 Sep 2021 22:34:02 +0530 Subject: [PATCH 009/279] scsi: pm80xx: Fix lockup in outbound queue management Commit 1f02beff224e ("scsi: pm80xx: Remove global lock from outbound queue processing") introduced a lock per outbound queue. Prior to that change the driver was using a global lock for all outbound queues. While processing the I/O responses and events the driver takes the outbound queue spinlock and is supposed to release it in pm8001_ccb_task_free_done() before calling command done(). Since the older code was using a global lock, pm8001_ccb_task_free_done() was releasing the global spin lock. The change that split the lock per outbound queue did not consider this and pm8001_ccb_task_free_done() was still releasing the global lock. Link: https://lore.kernel.org/r/20210906170404.5682-3-Ajish.Koshy@microchip.com Fixes: 1f02beff224e ("scsi: pm80xx: Remove global lock from outbound queue processing") Acked-by: Jack Wang Signed-off-by: Ajish Koshy Signed-off-by: Viswas G Signed-off-by: Martin K. Petersen --- drivers/scsi/pm8001/pm8001_sas.h | 3 +- drivers/scsi/pm8001/pm80xx_hwi.c | 53 ++++++++++++++++++++++++++------ 2 files changed, 45 insertions(+), 11 deletions(-) diff --git a/drivers/scsi/pm8001/pm8001_sas.h b/drivers/scsi/pm8001/pm8001_sas.h index 1a016a421280..3274d88a9ccc 100644 --- a/drivers/scsi/pm8001/pm8001_sas.h +++ b/drivers/scsi/pm8001/pm8001_sas.h @@ -458,6 +458,7 @@ struct outbound_queue_table { __le32 producer_index; u32 consumer_idx; spinlock_t oq_lock; + unsigned long lock_flags; }; struct pm8001_hba_memspace { void __iomem *memvirtaddr; @@ -740,9 +741,7 @@ pm8001_ccb_task_free_done(struct pm8001_hba_info *pm8001_ha, { pm8001_ccb_task_free(pm8001_ha, task, ccb, ccb_idx); smp_mb(); /*in order to force CPU ordering*/ - spin_unlock(&pm8001_ha->lock); task->task_done(task); - spin_lock(&pm8001_ha->lock); } #endif diff --git a/drivers/scsi/pm8001/pm80xx_hwi.c b/drivers/scsi/pm8001/pm80xx_hwi.c index cec932f830b8..1ae2f5c6042c 100644 --- a/drivers/scsi/pm8001/pm80xx_hwi.c +++ b/drivers/scsi/pm8001/pm80xx_hwi.c @@ -2379,7 +2379,8 @@ static void mpi_ssp_event(struct pm8001_hba_info *pm8001_ha, void *piomb) /*See the comments for mpi_ssp_completion */ static void -mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb) +mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, + struct outbound_queue_table *circularQ, void *piomb) { struct sas_task *t; struct pm8001_ccb_info *ccb; @@ -2616,7 +2617,11 @@ 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; + spin_unlock_irqrestore(&circularQ->oq_lock, + circularQ->lock_flags); pm8001_ccb_task_free_done(pm8001_ha, t, ccb, tag); + spin_lock_irqsave(&circularQ->oq_lock, + circularQ->lock_flags); return; } break; @@ -2632,7 +2637,11 @@ 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; + spin_unlock_irqrestore(&circularQ->oq_lock, + circularQ->lock_flags); pm8001_ccb_task_free_done(pm8001_ha, t, ccb, tag); + spin_lock_irqsave(&circularQ->oq_lock, + circularQ->lock_flags); return; } break; @@ -2656,7 +2665,11 @@ 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; + spin_unlock_irqrestore(&circularQ->oq_lock, + circularQ->lock_flags); pm8001_ccb_task_free_done(pm8001_ha, t, ccb, tag); + spin_lock_irqsave(&circularQ->oq_lock, + circularQ->lock_flags); return; } break; @@ -2727,7 +2740,11 @@ 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; + spin_unlock_irqrestore(&circularQ->oq_lock, + circularQ->lock_flags); pm8001_ccb_task_free_done(pm8001_ha, t, ccb, tag); + spin_lock_irqsave(&circularQ->oq_lock, + circularQ->lock_flags); return; } break; @@ -2747,7 +2764,11 @@ 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; + spin_unlock_irqrestore(&circularQ->oq_lock, + circularQ->lock_flags); pm8001_ccb_task_free_done(pm8001_ha, t, ccb, tag); + spin_lock_irqsave(&circularQ->oq_lock, + circularQ->lock_flags); return; } break; @@ -2785,12 +2806,17 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb) pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); } 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); + spin_lock_irqsave(&circularQ->oq_lock, + circularQ->lock_flags); } } /*See the comments for mpi_ssp_completion */ -static void mpi_sata_event(struct pm8001_hba_info *pm8001_ha, void *piomb) +static void mpi_sata_event(struct pm8001_hba_info *pm8001_ha, + struct outbound_queue_table *circularQ, void *piomb) { struct sas_task *t; struct task_status_struct *ts; @@ -2890,7 +2916,11 @@ static void mpi_sata_event(struct pm8001_hba_info *pm8001_ha, void *piomb) IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS); ts->resp = SAS_TASK_COMPLETE; ts->stat = SAS_QUEUE_FULL; + spin_unlock_irqrestore(&circularQ->oq_lock, + circularQ->lock_flags); pm8001_ccb_task_free_done(pm8001_ha, t, ccb, tag); + spin_lock_irqsave(&circularQ->oq_lock, + circularQ->lock_flags); return; } break; @@ -3002,7 +3032,11 @@ static void mpi_sata_event(struct pm8001_hba_info *pm8001_ha, void *piomb) pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); } 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); + spin_lock_irqsave(&circularQ->oq_lock, + circularQ->lock_flags); } } @@ -3906,7 +3940,8 @@ static int ssp_coalesced_comp_resp(struct pm8001_hba_info *pm8001_ha, * @pm8001_ha: our hba card information * @piomb: IO message buffer */ -static void process_one_iomb(struct pm8001_hba_info *pm8001_ha, void *piomb) +static void process_one_iomb(struct pm8001_hba_info *pm8001_ha, + struct outbound_queue_table *circularQ, void *piomb) { __le32 pHeader = *(__le32 *)piomb; u32 opc = (u32)((le32_to_cpu(pHeader)) & 0xFFF); @@ -3948,11 +3983,11 @@ static void process_one_iomb(struct pm8001_hba_info *pm8001_ha, void *piomb) break; case OPC_OUB_SATA_COMP: pm8001_dbg(pm8001_ha, MSG, "OPC_OUB_SATA_COMP\n"); - mpi_sata_completion(pm8001_ha, piomb); + mpi_sata_completion(pm8001_ha, circularQ, piomb); break; case OPC_OUB_SATA_EVENT: pm8001_dbg(pm8001_ha, MSG, "OPC_OUB_SATA_EVENT\n"); - mpi_sata_event(pm8001_ha, piomb); + mpi_sata_event(pm8001_ha, circularQ, piomb); break; case OPC_OUB_SSP_EVENT: pm8001_dbg(pm8001_ha, MSG, "OPC_OUB_SSP_EVENT\n"); @@ -4121,7 +4156,6 @@ static int process_oq(struct pm8001_hba_info *pm8001_ha, u8 vec) void *pMsg1 = NULL; u8 bc; u32 ret = MPI_IO_STATUS_FAIL; - unsigned long flags; u32 regval; if (vec == (pm8001_ha->max_q_num - 1)) { @@ -4138,7 +4172,7 @@ static int process_oq(struct pm8001_hba_info *pm8001_ha, u8 vec) } } circularQ = &pm8001_ha->outbnd_q_tbl[vec]; - spin_lock_irqsave(&circularQ->oq_lock, flags); + spin_lock_irqsave(&circularQ->oq_lock, circularQ->lock_flags); do { /* spurious interrupt during setup if kexec-ing and * driver doing a doorbell access w/ the pre-kexec oq @@ -4149,7 +4183,8 @@ static int process_oq(struct pm8001_hba_info *pm8001_ha, u8 vec) ret = pm8001_mpi_msg_consume(pm8001_ha, circularQ, &pMsg1, &bc); if (MPI_IO_STATUS_SUCCESS == ret) { /* process the outbound message */ - process_one_iomb(pm8001_ha, (void *)(pMsg1 - 4)); + process_one_iomb(pm8001_ha, circularQ, + (void *)(pMsg1 - 4)); /* free the message from the outbound circular buffer */ pm8001_mpi_msg_free_set(pm8001_ha, pMsg1, circularQ, bc); @@ -4164,7 +4199,7 @@ static int process_oq(struct pm8001_hba_info *pm8001_ha, u8 vec) break; } } while (1); - spin_unlock_irqrestore(&circularQ->oq_lock, flags); + spin_unlock_irqrestore(&circularQ->oq_lock, circularQ->lock_flags); return ret; } From c29737d03c74fbaf69ea50d355b25e43d0bacc73 Mon Sep 17 00:00:00 2001 From: Viswas G Date: Mon, 6 Sep 2021 22:34:03 +0530 Subject: [PATCH 010/279] scsi: pm80xx: Correct inbound and outbound queue logging Correct inbound queue and outbound queue size in 'ib_log' and 'ob_log' sysfs entries. Link: https://lore.kernel.org/r/20210906170404.5682-4-Ajish.Koshy@microchip.com Acked-by: Jack Wang Signed-off-by: Viswas G Signed-off-by: Ajish Koshy Signed-off-by: Martin K. Petersen --- drivers/scsi/pm8001/pm8001_ctl.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/pm8001/pm8001_ctl.c b/drivers/scsi/pm8001/pm8001_ctl.c index ec05c42e8ee6..b25e447aa3bd 100644 --- a/drivers/scsi/pm8001/pm8001_ctl.c +++ b/drivers/scsi/pm8001/pm8001_ctl.c @@ -409,6 +409,7 @@ static ssize_t pm8001_ctl_ib_queue_log_show(struct device *cdev, char *str = buf; int start = 0; u32 ib_offset = pm8001_ha->ib_offset; + u32 queue_size = pm8001_ha->max_q_num * PM8001_MPI_QUEUE * 128; #define IB_MEMMAP(c) \ (*(u32 *)((u8 *)pm8001_ha-> \ memoryMap.region[ib_offset].virt_ptr + \ @@ -419,7 +420,7 @@ static ssize_t pm8001_ctl_ib_queue_log_show(struct device *cdev, start = start + 4; } pm8001_ha->evtlog_ib_offset += SYSFS_OFFSET; - if (((pm8001_ha->evtlog_ib_offset) % (PM80XX_IB_OB_QUEUE_SIZE)) == 0) + if (((pm8001_ha->evtlog_ib_offset) % queue_size) == 0) pm8001_ha->evtlog_ib_offset = 0; return str - buf; @@ -445,6 +446,7 @@ static ssize_t pm8001_ctl_ob_queue_log_show(struct device *cdev, char *str = buf; int start = 0; u32 ob_offset = pm8001_ha->ob_offset; + u32 queue_size = pm8001_ha->max_q_num * PM8001_MPI_QUEUE * 128; #define OB_MEMMAP(c) \ (*(u32 *)((u8 *)pm8001_ha-> \ memoryMap.region[ob_offset].virt_ptr + \ @@ -455,7 +457,7 @@ static ssize_t pm8001_ctl_ob_queue_log_show(struct device *cdev, start = start + 4; } pm8001_ha->evtlog_ob_offset += SYSFS_OFFSET; - if (((pm8001_ha->evtlog_ob_offset) % (PM80XX_IB_OB_QUEUE_SIZE)) == 0) + if (((pm8001_ha->evtlog_ob_offset) % queue_size) == 0) pm8001_ha->evtlog_ob_offset = 0; return str - buf; From 51e6ed83bb4ade7c360551fa4ae55c4eacea354b Mon Sep 17 00:00:00 2001 From: Ajish Koshy Date: Mon, 6 Sep 2021 22:34:04 +0530 Subject: [PATCH 011/279] scsi: pm80xx: Fix memory leak during rmmod Driver failed to release all memory allocated. This would lead to memory leak during driver removal. Properly free memory when the module is removed. Link: https://lore.kernel.org/r/20210906170404.5682-5-Ajish.Koshy@microchip.com Acked-by: Jack Wang Signed-off-by: Ajish Koshy Signed-off-by: Viswas G Signed-off-by: Martin K. Petersen --- drivers/scsi/pm8001/pm8001_init.c | 11 +++++++++++ drivers/scsi/pm8001/pm8001_sas.h | 1 + 2 files changed, 12 insertions(+) diff --git a/drivers/scsi/pm8001/pm8001_init.c b/drivers/scsi/pm8001/pm8001_init.c index 613455a3e686..7082fecf7ce8 100644 --- a/drivers/scsi/pm8001/pm8001_init.c +++ b/drivers/scsi/pm8001/pm8001_init.c @@ -1199,6 +1199,7 @@ pm8001_init_ccb_tag(struct pm8001_hba_info *pm8001_ha, struct Scsi_Host *shost, goto err_out; /* Memory region for ccb_info*/ + pm8001_ha->ccb_count = ccb_count; pm8001_ha->ccb_info = kcalloc(ccb_count, sizeof(struct pm8001_ccb_info), GFP_KERNEL); if (!pm8001_ha->ccb_info) { @@ -1260,6 +1261,16 @@ static void pm8001_pci_remove(struct pci_dev *pdev) tasklet_kill(&pm8001_ha->tasklet[j]); #endif scsi_host_put(pm8001_ha->shost); + + for (i = 0; i < pm8001_ha->ccb_count; i++) { + dma_free_coherent(&pm8001_ha->pdev->dev, + sizeof(struct pm8001_prd) * PM8001_MAX_DMA_SG, + pm8001_ha->ccb_info[i].buf_prd, + pm8001_ha->ccb_info[i].ccb_dma_handle); + } + kfree(pm8001_ha->ccb_info); + kfree(pm8001_ha->devices); + pm8001_free(pm8001_ha); kfree(sha->sas_phy); kfree(sha->sas_port); diff --git a/drivers/scsi/pm8001/pm8001_sas.h b/drivers/scsi/pm8001/pm8001_sas.h index 3274d88a9ccc..7e999768bfd2 100644 --- a/drivers/scsi/pm8001/pm8001_sas.h +++ b/drivers/scsi/pm8001/pm8001_sas.h @@ -518,6 +518,7 @@ struct pm8001_hba_info { u32 iomb_size; /* SPC and SPCV IOMB size */ struct pm8001_device *devices; struct pm8001_ccb_info *ccb_info; + u32 ccb_count; #ifdef PM8001_USE_MSIX int number_of_intr;/*will be used in remove()*/ char intr_drvname[PM8001_MAX_MSIX_VEC] From 9e1c3206960f8e0a5b6a42d3e6693f10c5ca10ac Mon Sep 17 00:00:00 2001 From: Bikash Hazarika Date: Wed, 8 Sep 2021 09:46:13 -0700 Subject: [PATCH 012/279] scsi: qla2xxx: Add support for mailbox passthru This interface will allow user space applications to send a mailbox command to the firmware. Link: https://lore.kernel.org/r/20210908164622.19240-2-njavali@marvell.com Reviewed-by: Himanshu Madhani Signed-off-by: Bikash Hazarika Signed-off-by: Nilesh Javali Signed-off-by: Martin K. Petersen --- drivers/scsi/qla2xxx/qla_bsg.c | 48 ++++++++++++++++++++++++++++++++++ drivers/scsi/qla2xxx/qla_bsg.h | 7 +++++ drivers/scsi/qla2xxx/qla_gbl.h | 4 +++ drivers/scsi/qla2xxx/qla_mbx.c | 33 +++++++++++++++++++++++ 4 files changed, 92 insertions(+) diff --git a/drivers/scsi/qla2xxx/qla_bsg.c b/drivers/scsi/qla2xxx/qla_bsg.c index 4b5d28d89d69..0c33fb0de21a 100644 --- a/drivers/scsi/qla2xxx/qla_bsg.c +++ b/drivers/scsi/qla2xxx/qla_bsg.c @@ -2877,6 +2877,9 @@ qla2x00_process_vendor_specific(struct scsi_qla_host *vha, struct bsg_job *bsg_j case QL_VND_MANAGE_HOST_PORT: return qla2x00_manage_host_port(bsg_job); + case QL_VND_MBX_PASSTHRU: + return qla2x00_mailbox_passthru(bsg_job); + default: return -ENOSYS; } @@ -3013,3 +3016,48 @@ done: sp->free(sp); return 0; } + +int qla2x00_mailbox_passthru(struct bsg_job *bsg_job) +{ + struct fc_bsg_reply *bsg_reply = bsg_job->reply; + scsi_qla_host_t *vha = shost_priv(fc_bsg_to_shost(bsg_job)); + int ret = -EINVAL; + int ptsize = sizeof(struct qla_mbx_passthru); + struct qla_mbx_passthru *req_data = NULL; + uint32_t req_data_len; + + req_data_len = bsg_job->request_payload.payload_len; + if (req_data_len != ptsize) { + ql_log(ql_log_warn, vha, 0xf0a3, "req_data_len invalid.\n"); + return -EIO; + } + req_data = kzalloc(ptsize, GFP_KERNEL); + if (!req_data) { + ql_log(ql_log_warn, vha, 0xf0a4, + "req_data memory allocation failure.\n"); + return -ENOMEM; + } + + /* Copy the request buffer in req_data */ + sg_copy_to_buffer(bsg_job->request_payload.sg_list, + bsg_job->request_payload.sg_cnt, req_data, ptsize); + ret = qla_mailbox_passthru(vha, req_data->mbx_in, req_data->mbx_out); + + /* Copy the req_data in request buffer */ + sg_copy_from_buffer(bsg_job->reply_payload.sg_list, + bsg_job->reply_payload.sg_cnt, req_data, ptsize); + + bsg_reply->reply_payload_rcv_len = ptsize; + if (ret == QLA_SUCCESS) + bsg_reply->reply_data.vendor_reply.vendor_rsp[0] = EXT_STATUS_OK; + else + bsg_reply->reply_data.vendor_reply.vendor_rsp[0] = EXT_STATUS_ERR; + + bsg_job->reply_len = sizeof(*bsg_job->reply); + bsg_reply->result = DID_OK << 16; + bsg_job_done(bsg_job, bsg_reply->result, bsg_reply->reply_payload_rcv_len); + + kfree(req_data); + + return ret; +} diff --git a/drivers/scsi/qla2xxx/qla_bsg.h b/drivers/scsi/qla2xxx/qla_bsg.h index dd793cf8bc1e..0f8a4c7e52a2 100644 --- a/drivers/scsi/qla2xxx/qla_bsg.h +++ b/drivers/scsi/qla2xxx/qla_bsg.h @@ -36,6 +36,7 @@ #define QL_VND_GET_HOST_STATS 0x24 #define QL_VND_GET_TGT_STATS 0x25 #define QL_VND_MANAGE_HOST_PORT 0x26 +#define QL_VND_MBX_PASSTHRU 0x2B /* BSG Vendor specific subcode returns */ #define EXT_STATUS_OK 0 @@ -187,6 +188,12 @@ struct qla_port_param { uint16_t speed; } __attribute__ ((packed)); +struct qla_mbx_passthru { + uint16_t reserved1[2]; + uint16_t mbx_in[32]; + uint16_t mbx_out[32]; + uint32_t reserved2[16]; +} __packed; /* FRU VPD */ diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h index 1c3f055d41b8..8aadcdeca6cb 100644 --- a/drivers/scsi/qla2xxx/qla_gbl.h +++ b/drivers/scsi/qla2xxx/qla_gbl.h @@ -662,9 +662,13 @@ extern int qla2xxx_get_vpd_field(scsi_qla_host_t *, char *, char *, size_t); extern void qla2xxx_flash_npiv_conf(scsi_qla_host_t *); extern int qla24xx_read_fcp_prio_cfg(scsi_qla_host_t *); +extern int qla2x00_mailbox_passthru(struct bsg_job *bsg_job); int __qla_copy_purex_to_buffer(struct scsi_qla_host *vha, void **pkt, struct rsp_que **rsp, u8 *buf, u32 buf_len); +int qla_mailbox_passthru(scsi_qla_host_t *vha, uint16_t *mbx_in, + uint16_t *mbx_out); + /* * Global Function Prototypes in qla_dbg.c source file. */ diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c index 7811c4952035..9eb41dd39043 100644 --- a/drivers/scsi/qla2xxx/qla_mbx.c +++ b/drivers/scsi/qla2xxx/qla_mbx.c @@ -7011,3 +7011,36 @@ void qla_no_op_mb(struct scsi_qla_host *vha) "Failed %s %x\n", __func__, rval); } } + +int qla_mailbox_passthru(scsi_qla_host_t *vha, + uint16_t *mbx_in, uint16_t *mbx_out) +{ + mbx_cmd_t mc; + mbx_cmd_t *mcp = &mc; + int rval = -EINVAL; + + memset(&mc, 0, sizeof(mc)); + /* Receiving all 32 register's contents */ + memcpy(&mcp->mb, (char *)mbx_in, (32 * sizeof(uint16_t))); + + mcp->out_mb = 0xFFFFFFFF; + mcp->in_mb = 0xFFFFFFFF; + + mcp->tov = MBX_TOV_SECONDS; + mcp->flags = 0; + mcp->bufp = NULL; + + rval = qla2x00_mailbox_command(vha, mcp); + + if (rval != QLA_SUCCESS) { + ql_dbg(ql_dbg_mbx, vha, 0xf0a2, + "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]); + } else { + ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0xf0a3, "Done %s.\n", + __func__); + /* passing all 32 register's contents */ + memcpy(mbx_out, &mcp->mb, 32 * sizeof(uint16_t)); + } + + return rval; +} From 52cca50d35f814e737791e2c2cf8c279219a9f29 Mon Sep 17 00:00:00 2001 From: Saurav Kashyap Date: Wed, 8 Sep 2021 09:46:14 -0700 Subject: [PATCH 013/279] scsi: qla2xxx: Display 16G only as supported speeds for 3830c card This card is unique and doesn't support lower speeds, hence update the fdmi field to display 16G only. Link: https://lore.kernel.org/r/20210908164622.19240-3-njavali@marvell.com Reviewed-by: Himanshu Madhani Signed-off-by: Saurav Kashyap Signed-off-by: Nilesh Javali Signed-off-by: Martin K. Petersen --- drivers/scsi/qla2xxx/qla_gs.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/qla2xxx/qla_gs.c b/drivers/scsi/qla2xxx/qla_gs.c index ebc8fdb0b43d..28b574e20ef3 100644 --- a/drivers/scsi/qla2xxx/qla_gs.c +++ b/drivers/scsi/qla2xxx/qla_gs.c @@ -1537,7 +1537,8 @@ qla25xx_fdmi_port_speed_capability(struct qla_hw_data *ha) } if (IS_QLA2031(ha)) { if ((ha->pdev->subsystem_vendor == 0x103C) && - (ha->pdev->subsystem_device == 0x8002)) { + ((ha->pdev->subsystem_device == 0x8002) || + (ha->pdev->subsystem_device == 0x8086))) { speeds = FDMI_PORT_SPEED_16GB; } else { speeds = FDMI_PORT_SPEED_16GB|FDMI_PORT_SPEED_8GB| From 8192817efbc34e9ca482edf340d41c5ca0d4dad0 Mon Sep 17 00:00:00 2001 From: Saurav Kashyap Date: Wed, 8 Sep 2021 09:46:15 -0700 Subject: [PATCH 014/279] scsi: qla2xxx: Check for firmware capability before creating QPair Add firmware capability check of multiQ specifically for ISP25XX before creating qpair. Link: https://lore.kernel.org/r/20210908164622.19240-4-njavali@marvell.com Reviewed-by: Himanshu Madhani Signed-off-by: Saurav Kashyap Signed-off-by: Nilesh Javali Signed-off-by: Martin K. Petersen --- drivers/scsi/qla2xxx/qla_os.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index d2e40aaba734..a1e861ecfc01 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c @@ -3364,6 +3364,10 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) host->can_queue, base_vha->req, base_vha->mgmt_svr_loop_id, host->sg_tablesize); + /* Check if FW supports MQ or not for ISP25xx */ + if (IS_QLA25XX(ha) && !(ha->fw_attributes & BIT_6)) + ha->mqenable = 0; + if (ha->mqenable) { bool startit = false; From e6e22e6cc2962d3f3d71914b47f7fbc454670e8a Mon Sep 17 00:00:00 2001 From: Arun Easi Date: Wed, 8 Sep 2021 09:46:16 -0700 Subject: [PATCH 015/279] scsi: qla2xxx: Fix crash in NVMe abort path System crash was seen when I/O was run against an NVMe target and aborts were occurring. Crash stack is: -- relevant crash stack -- BUG: kernel NULL pointer dereference, address: 0000000000000010 : #6 [ffffae1f8666bdd0] page_fault at ffffffffa740122e [exception RIP: qla_nvme_abort_work+339] RIP: ffffffffc0f592e3 RSP: ffffae1f8666be80 RFLAGS: 00010297 RAX: 0000000000000000 RBX: ffff9b581fc8af80 RCX: ffffffffc0f83bd0 RDX: 0000000000000001 RSI: ffff9b5839c6c7c8 RDI: 0000000008000000 RBP: ffff9b6832f85000 R8: ffffffffc0f68160 R9: ffffffffc0f70652 R10: ffffae1f862ffdc8 R11: 0000000000000300 R12: 000000000000010d R13: 0000000000000000 R14: ffff9b5839cea000 R15: 0ffff9b583fab170 ORIG_RAX: ffffffffffffffff CS: 0010 SS: 0018 #7 [ffffae1f8666be98] process_one_work at ffffffffa6aba184 #8 [ffffae1f8666bed8] worker_thread at ffffffffa6aba39d #9 [ffffae1f8666bf10] kthread at ffffffffa6ac06ed The crash was due to a stale SRB structure access after it was aborted. Fix the issue by removing stale access. Link: https://lore.kernel.org/r/20210908164622.19240-5-njavali@marvell.com Fixes: 2cabf10dbbe3 ("scsi: qla2xxx: Fix hang on NVMe command timeouts") Cc: stable@vger.kernel.org Reviewed-by: Himanshu Madhani Signed-off-by: Arun Easi Signed-off-by: Nilesh Javali Signed-off-by: Martin K. Petersen --- drivers/scsi/qla2xxx/qla_nvme.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/qla2xxx/qla_nvme.c b/drivers/scsi/qla2xxx/qla_nvme.c index 1c5da2dbd6f9..877b2b625020 100644 --- a/drivers/scsi/qla2xxx/qla_nvme.c +++ b/drivers/scsi/qla2xxx/qla_nvme.c @@ -228,6 +228,8 @@ static void qla_nvme_abort_work(struct work_struct *work) fc_port_t *fcport = sp->fcport; struct qla_hw_data *ha = fcport->vha->hw; int rval, abts_done_called = 1; + bool io_wait_for_abort_done; + uint32_t handle; ql_dbg(ql_dbg_io, fcport->vha, 0xffff, "%s called for sp=%p, hndl=%x on fcport=%p desc=%p deleted=%d\n", @@ -244,12 +246,20 @@ static void qla_nvme_abort_work(struct work_struct *work) goto out; } + /* + * sp may not be valid after abort_command if return code is either + * SUCCESS or ERR_FROM_FW codes, so cache the value here. + */ + io_wait_for_abort_done = ql2xabts_wait_nvme && + QLA_ABTS_WAIT_ENABLED(sp); + handle = sp->handle; + rval = ha->isp_ops->abort_command(sp); ql_dbg(ql_dbg_io, fcport->vha, 0x212b, "%s: %s command for sp=%p, handle=%x on fcport=%p rval=%x\n", __func__, (rval != QLA_SUCCESS) ? "Failed to abort" : "Aborted", - sp, sp->handle, fcport, rval); + sp, handle, fcport, rval); /* * If async tmf is enabled, the abort callback is called only on @@ -264,7 +274,7 @@ static void qla_nvme_abort_work(struct work_struct *work) * are waited until ABTS complete. This kref is decreased * at qla24xx_abort_sp_done function. */ - if (abts_done_called && ql2xabts_wait_nvme && QLA_ABTS_WAIT_ENABLED(sp)) + if (abts_done_called && io_wait_for_abort_done) return; out: /* kref_get was done before work was schedule. */ From 527d46e0b0147f2b32b78ba49c6a231835b24a41 Mon Sep 17 00:00:00 2001 From: Quinn Tran Date: Wed, 8 Sep 2021 09:46:17 -0700 Subject: [PATCH 016/279] scsi: qla2xxx: edif: Use link event to wake up app Authentication application may be running and in the past tried to probe driver (app_start) but was unsuccessful. This could be due to the bsg layer not being ready to service the request. On a successful link up, driver will use the netlink Link Up event to notify the app to retry the app_start call. In another case, app does not poll for new NPIV host. This link up event would notify app of the presence of a new SCSI host. Link: https://lore.kernel.org/r/20210908164622.19240-6-njavali@marvell.com Fixes: 4de067e5df12 ("scsi: qla2xxx: edif: Add N2N support for EDIF") Reviewed-by: Himanshu Madhani Signed-off-by: Quinn Tran Signed-off-by: Nilesh Javali Signed-off-by: Martin K. Petersen --- drivers/scsi/qla2xxx/qla_init.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index 1e4e3e83b5c7..c6b3d0e7489e 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c @@ -5335,15 +5335,14 @@ qla2x00_configure_loop(scsi_qla_host_t *vha) "LOOP READY.\n"); ha->flags.fw_init_done = 1; + /* + * use link up to wake up app to get ready for + * authentication. + */ if (ha->flags.edif_enabled && - !(vha->e_dbell.db_flags & EDB_ACTIVE) && - N2N_TOPO(vha->hw)) { - /* - * use port online to wake up app to get ready - * for authentication - */ - qla2x00_post_aen_work(vha, FCH_EVT_PORT_ONLINE, 0); - } + !(vha->e_dbell.db_flags & EDB_ACTIVE)) + qla2x00_post_aen_work(vha, FCH_EVT_LINKUP, + ha->link_data_rate); /* * Process any ATIO queue entries that came in From 3ef68d4f0c9e7cb589ae8b70f07d77f528105331 Mon Sep 17 00:00:00 2001 From: Arun Easi Date: Wed, 8 Sep 2021 09:46:18 -0700 Subject: [PATCH 017/279] scsi: qla2xxx: Fix kernel crash when accessing port_speed sysfs file Kernel crashes when accessing port_speed sysfs file. The issue happens on a CNA when the local array was accessed beyond bounds. Fix this by changing the lookup. BUG: unable to handle kernel paging request at 0000000000004000 PGD 0 P4D 0 Oops: 0000 [#1] SMP PTI CPU: 15 PID: 455213 Comm: sosreport Kdump: loaded Not tainted 4.18.0-305.7.1.el8_4.x86_64 #1 RIP: 0010:string_nocheck+0x12/0x70 Code: 00 00 4c 89 e2 be 20 00 00 00 48 89 ef e8 86 9a 00 00 4c 01 e3 eb 81 90 49 89 f2 48 89 ce 48 89 f8 48 c1 fe 30 66 85 f6 74 4f <44> 0f b6 0a 45 84 c9 74 46 83 ee 01 41 b8 01 00 00 00 48 8d 7c 37 RSP: 0018:ffffb5141c1afcf0 EFLAGS: 00010286 RAX: ffff8bf4009f8000 RBX: ffff8bf4009f9000 RCX: ffff0a00ffffff04 RDX: 0000000000004000 RSI: ffffffffffffffff RDI: ffff8bf4009f8000 RBP: 0000000000004000 R08: 0000000000000001 R09: ffffb5141c1afb84 R10: ffff8bf4009f9000 R11: ffffb5141c1afce6 R12: ffff0a00ffffff04 R13: ffffffffc08e21aa R14: 0000000000001000 R15: ffffffffc08e21aa FS: 00007fc4ebfff700(0000) GS:ffff8c717f7c0000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 0000000000004000 CR3: 000000edfdee6006 CR4: 00000000001706e0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 Call Trace: string+0x40/0x50 vsnprintf+0x33c/0x520 scnprintf+0x4d/0x90 qla2x00_port_speed_show+0xb5/0x100 [qla2xxx] dev_attr_show+0x1c/0x40 sysfs_kf_seq_show+0x9b/0x100 seq_read+0x153/0x410 vfs_read+0x91/0x140 ksys_read+0x4f/0xb0 do_syscall_64+0x5b/0x1a0 entry_SYSCALL_64_after_hwframe+0x65/0xca Link: https://lore.kernel.org/r/20210908164622.19240-7-njavali@marvell.com Fixes: 4910b524ac9e ("scsi: qla2xxx: Add support for setting port speed") Cc: stable@vger.kernel.org Reviewed-by: Himanshu Madhani Signed-off-by: Arun Easi Signed-off-by: Nilesh Javali Signed-off-by: Martin K. Petersen --- drivers/scsi/qla2xxx/qla_attr.c | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c index d09776b77af2..cb5f2ecb652d 100644 --- a/drivers/scsi/qla2xxx/qla_attr.c +++ b/drivers/scsi/qla2xxx/qla_attr.c @@ -1868,6 +1868,18 @@ qla2x00_port_speed_store(struct device *dev, struct device_attribute *attr, return strlen(buf); } +static const struct { + u16 rate; + char *str; +} port_speed_str[] = { + { PORT_SPEED_4GB, "4" }, + { PORT_SPEED_8GB, "8" }, + { PORT_SPEED_16GB, "16" }, + { PORT_SPEED_32GB, "32" }, + { PORT_SPEED_64GB, "64" }, + { PORT_SPEED_10GB, "10" }, +}; + static ssize_t qla2x00_port_speed_show(struct device *dev, struct device_attribute *attr, char *buf) @@ -1875,7 +1887,8 @@ qla2x00_port_speed_show(struct device *dev, struct device_attribute *attr, struct scsi_qla_host *vha = shost_priv(dev_to_shost(dev)); struct qla_hw_data *ha = vha->hw; ssize_t rval; - char *spd[7] = {"0", "0", "0", "4", "8", "16", "32"}; + u16 i; + char *speed = "Unknown"; rval = qla2x00_get_data_rate(vha); if (rval != QLA_SUCCESS) { @@ -1884,7 +1897,14 @@ qla2x00_port_speed_show(struct device *dev, struct device_attribute *attr, return -EINVAL; } - return scnprintf(buf, PAGE_SIZE, "%s\n", spd[ha->link_data_rate]); + for (i = 0; i < ARRAY_SIZE(port_speed_str); i++) { + if (port_speed_str[i].rate != ha->link_data_rate) + continue; + speed = port_speed_str[i].str; + break; + } + + return scnprintf(buf, PAGE_SIZE, "%s\n", speed); } static ssize_t From 38c61709e66294f33e474eaafd6ae3be381030da Mon Sep 17 00:00:00 2001 From: Shreyas Deodhar Date: Wed, 8 Sep 2021 09:46:19 -0700 Subject: [PATCH 018/279] scsi: qla2xxx: Call process_response_queue() in Tx path Process responses in Tx path if any available for better performance. Link: https://lore.kernel.org/r/20210908164622.19240-8-njavali@marvell.com Reviewed-by: Himanshu Madhani Signed-off-by: Shreyas Deodhar Signed-off-by: Nilesh Javali Signed-off-by: Martin K. Petersen --- drivers/scsi/qla2xxx/qla_nvme.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/scsi/qla2xxx/qla_nvme.c b/drivers/scsi/qla2xxx/qla_nvme.c index 877b2b625020..0ae1e081cb03 100644 --- a/drivers/scsi/qla2xxx/qla_nvme.c +++ b/drivers/scsi/qla2xxx/qla_nvme.c @@ -399,6 +399,7 @@ static inline int qla2x00_start_nvme_mq(srb_t *sp) uint16_t avail_dsds; struct dsd64 *cur_dsd; struct req_que *req = NULL; + struct rsp_que *rsp = NULL; struct scsi_qla_host *vha = sp->fcport->vha; struct qla_hw_data *ha = vha->hw; struct qla_qpair *qpair = sp->qpair; @@ -410,6 +411,7 @@ static inline int qla2x00_start_nvme_mq(srb_t *sp) /* Setup qpair pointers */ req = qpair->req; + rsp = qpair->rsp; tot_dsds = fd->sg_cnt; /* Acquire qpair specific lock */ @@ -571,6 +573,10 @@ static inline int qla2x00_start_nvme_mq(srb_t *sp) /* Set chip new ring index. */ wrt_reg_dword(req->req_q_in, req->ring_index); + if (vha->flags.process_response_queue && + rsp->ring_ptr->signature != RESPONSE_PROCESSED) + qla24xx_process_response_queue(vha, rsp); + queuing_error: spin_unlock_irqrestore(&qpair->qp_lock, flags); From 3a4e1f3b3a3c733de3b82b9b522e54803e1165ae Mon Sep 17 00:00:00 2001 From: Manish Rangankar Date: Wed, 8 Sep 2021 09:46:20 -0700 Subject: [PATCH 019/279] scsi: qla2xxx: Move heartbeat handling from DPC thread to workqueue MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit DPC thread gets restricted due to a no-op mailbox, which is a blocking call and has a high execution frequency. To free up the DPC thread we move no-op handling to the workqueue. Also, modified qla_do_heartbeat() to send no-op MBC if we don’t have any active interrupts, but there are still I/Os outstanding with firmware. Link: https://lore.kernel.org/r/20210908164622.19240-9-njavali@marvell.com Fixes: d94d8158e184 ("scsi: qla2xxx: Add heartbeat check") Reviewed-by: Himanshu Madhani Signed-off-by: Manish Rangankar Signed-off-by: Nilesh Javali Signed-off-by: Martin K. Petersen --- drivers/scsi/qla2xxx/qla_def.h | 4 +- drivers/scsi/qla2xxx/qla_init.c | 2 + drivers/scsi/qla2xxx/qla_os.c | 78 +++++++++++++++------------------ 3 files changed, 40 insertions(+), 44 deletions(-) diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h index be2eb75ee1a3..8924eeb9367d 100644 --- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h @@ -3750,6 +3750,7 @@ struct qla_qpair { struct qla_fw_resources fwres ____cacheline_aligned; u32 cmd_cnt; u32 cmd_completion_cnt; + u32 prev_completion_cnt; }; /* Place holder for FW buffer parameters */ @@ -4607,6 +4608,7 @@ struct qla_hw_data { struct qla_chip_state_84xx *cs84xx; struct isp_operations *isp_ops; struct workqueue_struct *wq; + struct work_struct heartbeat_work; struct qlfc_fw fw_buf; /* FCP_CMND priority support */ @@ -4708,7 +4710,6 @@ struct qla_hw_data { struct qla_hw_data_stat stat; pci_error_state_t pci_error_state; - u64 prev_cmd_cnt; struct dma_pool *purex_dma_pool; struct btree_head32 host_map; @@ -4854,7 +4855,6 @@ typedef struct scsi_qla_host { #define SET_ZIO_THRESHOLD_NEEDED 32 #define ISP_ABORT_TO_ROM 33 #define VPORT_DELETE 34 -#define HEARTBEAT_CHK 38 #define PROCESS_PUREX_IOCB 63 diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index c6b3d0e7489e..a9a4243cb15a 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c @@ -7025,12 +7025,14 @@ qla2x00_abort_isp_cleanup(scsi_qla_host_t *vha) ha->chip_reset++; ha->base_qpair->chip_reset = ha->chip_reset; ha->base_qpair->cmd_cnt = ha->base_qpair->cmd_completion_cnt = 0; + ha->base_qpair->prev_completion_cnt = 0; for (i = 0; i < ha->max_qpairs; i++) { if (ha->queue_pair_map[i]) { ha->queue_pair_map[i]->chip_reset = ha->base_qpair->chip_reset; ha->queue_pair_map[i]->cmd_cnt = ha->queue_pair_map[i]->cmd_completion_cnt = 0; + ha->base_qpair->prev_completion_cnt = 0; } } diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index a1e861ecfc01..0c446438dcd3 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c @@ -2794,6 +2794,16 @@ qla2xxx_scan_finished(struct Scsi_Host *shost, unsigned long time) return atomic_read(&vha->loop_state) == LOOP_READY; } +static void qla_heartbeat_work_fn(struct work_struct *work) +{ + struct qla_hw_data *ha = container_of(work, + struct qla_hw_data, heartbeat_work); + struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev); + + if (!ha->flags.mbox_busy && base_vha->flags.init_done) + qla_no_op_mb(base_vha); +} + static void qla2x00_iocb_work_fn(struct work_struct *work) { struct scsi_qla_host *vha = container_of(work, @@ -3232,6 +3242,7 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) host->transportt, sht->vendor_id); INIT_WORK(&base_vha->iocb_work, qla2x00_iocb_work_fn); + INIT_WORK(&ha->heartbeat_work, qla_heartbeat_work_fn); /* Set up the irqs */ ret = qla2x00_request_irqs(ha, rsp); @@ -7118,17 +7129,6 @@ intr_on_check: qla2x00_lip_reset(base_vha); } - if (test_bit(HEARTBEAT_CHK, &base_vha->dpc_flags)) { - /* - * if there is a mb in progress then that's - * enough of a check to see if fw is still ticking. - */ - if (!ha->flags.mbox_busy && base_vha->flags.init_done) - qla_no_op_mb(base_vha); - - clear_bit(HEARTBEAT_CHK, &base_vha->dpc_flags); - } - ha->dpc_active = 0; end_loop: set_current_state(TASK_INTERRUPTIBLE); @@ -7187,57 +7187,51 @@ qla2x00_rst_aen(scsi_qla_host_t *vha) static bool qla_do_heartbeat(struct scsi_qla_host *vha) { - u64 cmd_cnt, prev_cmd_cnt; - bool do_hb = false; struct qla_hw_data *ha = vha->hw; - int i; + u32 cmpl_cnt; + u16 i; + bool do_heartbeat = false; - /* if cmds are still pending down in fw, then do hb */ - if (ha->base_qpair->cmd_cnt != ha->base_qpair->cmd_completion_cnt) { - do_hb = true; + /* + * Allow do_heartbeat only if we don’t have any active interrupts, + * but there are still IOs outstanding with firmware. + */ + cmpl_cnt = ha->base_qpair->cmd_completion_cnt; + if (cmpl_cnt == ha->base_qpair->prev_completion_cnt && + cmpl_cnt != ha->base_qpair->cmd_cnt) { + do_heartbeat = true; goto skip; } + ha->base_qpair->prev_completion_cnt = cmpl_cnt; for (i = 0; i < ha->max_qpairs; i++) { - if (ha->queue_pair_map[i] && - ha->queue_pair_map[i]->cmd_cnt != - ha->queue_pair_map[i]->cmd_completion_cnt) { - do_hb = true; - break; + if (ha->queue_pair_map[i]) { + cmpl_cnt = ha->queue_pair_map[i]->cmd_completion_cnt; + if (cmpl_cnt == ha->queue_pair_map[i]->prev_completion_cnt && + cmpl_cnt != ha->queue_pair_map[i]->cmd_cnt) { + do_heartbeat = true; + break; + } + ha->queue_pair_map[i]->prev_completion_cnt = cmpl_cnt; } } skip: - prev_cmd_cnt = ha->prev_cmd_cnt; - cmd_cnt = ha->base_qpair->cmd_cnt; - for (i = 0; i < ha->max_qpairs; i++) { - if (ha->queue_pair_map[i]) - cmd_cnt += ha->queue_pair_map[i]->cmd_cnt; - } - ha->prev_cmd_cnt = cmd_cnt; - - if (!do_hb && ((cmd_cnt - prev_cmd_cnt) > 50)) - /* - * IOs are completing before periodic hb check. - * IOs seems to be running, do hb for sanity check. - */ - do_hb = true; - - return do_hb; + return do_heartbeat; } static void qla_heart_beat(struct scsi_qla_host *vha) { + struct qla_hw_data *ha = vha->hw; + if (vha->vp_idx) return; if (vha->hw->flags.eeh_busy || qla2x00_chip_is_down(vha)) return; - if (qla_do_heartbeat(vha)) { - set_bit(HEARTBEAT_CHK, &vha->dpc_flags); - qla2xxx_wake_dpc(vha); - } + if (qla_do_heartbeat(vha)) + queue_work(ha->wq, &ha->heartbeat_work); } /************************************************************************** From 3d33b303d4f3b74a71bede5639ebba3cfd2a2b4d Mon Sep 17 00:00:00 2001 From: Quinn Tran Date: Wed, 8 Sep 2021 09:46:21 -0700 Subject: [PATCH 020/279] scsi: qla2xxx: Fix use after free in eh_abort path In eh_abort path driver prematurely exits the call to upper layer. Check whether command is aborted / completed by firmware before exiting the call. 9 [ffff8b1ebf803c00] page_fault at ffffffffb0389778 [exception RIP: qla2x00_status_entry+0x48d] RIP: ffffffffc04fa62d RSP: ffff8b1ebf803cb0 RFLAGS: 00010082 RAX: 00000000ffffffff RBX: 00000000000e0000 RCX: 0000000000000000 RDX: 0000000000000000 RSI: 00000000000013d8 RDI: fffff3253db78440 RBP: ffff8b1ebf803dd0 R8: ffff8b1ebcd9b0c0 R9: 0000000000000000 R10: ffff8b1e38a30808 R11: 0000000000001000 R12: 00000000000003e9 R13: 0000000000000000 R14: ffff8b1ebcd9d740 R15: 0000000000000028 ORIG_RAX: ffffffffffffffff CS: 0010 SS: 0018 10 [ffff8b1ebf803cb0] enqueue_entity at ffffffffafce708f 11 [ffff8b1ebf803d00] enqueue_task_fair at ffffffffafce7b88 12 [ffff8b1ebf803dd8] qla24xx_process_response_queue at ffffffffc04fc9a6 [qla2xxx] 13 [ffff8b1ebf803e78] qla24xx_msix_rsp_q at ffffffffc04ff01b [qla2xxx] 14 [ffff8b1ebf803eb0] __handle_irq_event_percpu at ffffffffafd50714 Link: https://lore.kernel.org/r/20210908164622.19240-10-njavali@marvell.com Fixes: f45bca8c5052 ("scsi: qla2xxx: Fix double scsi_done for abort path") Cc: stable@vger.kernel.org Reviewed-by: Himanshu Madhani Co-developed-by: David Jeffery Signed-off-by: David Jeffery Co-developed-by: Laurence Oberman Signed-off-by: Laurence Oberman Signed-off-by: Quinn Tran Signed-off-by: Nilesh Javali Signed-off-by: Martin K. Petersen --- drivers/scsi/qla2xxx/qla_os.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index 0c446438dcd3..03ff2596715b 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c @@ -1258,6 +1258,7 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd) uint32_t ratov_j; struct qla_qpair *qpair; unsigned long flags; + int fast_fail_status = SUCCESS; if (qla2x00_isp_reg_stat(ha)) { ql_log(ql_log_info, vha, 0x8042, @@ -1266,9 +1267,10 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd) return FAILED; } + /* Save any FAST_IO_FAIL value to return later if abort succeeds */ ret = fc_block_scsi_eh(cmd); if (ret != 0) - return ret; + fast_fail_status = ret; sp = scsi_cmd_priv(cmd); qpair = sp->qpair; @@ -1276,7 +1278,7 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd) vha->cmd_timeout_cnt++; if ((sp->fcport && sp->fcport->deleted) || !qpair) - return SUCCESS; + return fast_fail_status != SUCCESS ? fast_fail_status : FAILED; spin_lock_irqsave(qpair->qp_lock_ptr, flags); sp->comp = ∁ @@ -1311,7 +1313,7 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd) __func__, ha->r_a_tov/10); ret = FAILED; } else { - ret = SUCCESS; + ret = fast_fail_status; } break; default: From b0fe235dad775d267d75aa19c0ce61fa527a287f Mon Sep 17 00:00:00 2001 From: Nilesh Javali Date: Wed, 8 Sep 2021 09:46:22 -0700 Subject: [PATCH 021/279] scsi: qla2xxx: Update version to 10.02.07.100-k Link: https://lore.kernel.org/r/20210908164622.19240-11-njavali@marvell.com Reviewed-by: Himanshu Madhani Signed-off-by: Nilesh Javali Signed-off-by: Martin K. Petersen --- drivers/scsi/qla2xxx/qla_version.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/scsi/qla2xxx/qla_version.h b/drivers/scsi/qla2xxx/qla_version.h index 055040cbef9b..4b117165bf8b 100644 --- a/drivers/scsi/qla2xxx/qla_version.h +++ b/drivers/scsi/qla2xxx/qla_version.h @@ -6,9 +6,9 @@ /* * Driver version */ -#define QLA2XXX_VERSION "10.02.06.200-k" +#define QLA2XXX_VERSION "10.02.07.100-k" #define QLA_DRIVER_MAJOR_VER 10 #define QLA_DRIVER_MINOR_VER 2 -#define QLA_DRIVER_PATCH_VER 6 -#define QLA_DRIVER_BETA_VER 200 +#define QLA_DRIVER_PATCH_VER 7 +#define QLA_DRIVER_BETA_VER 100 From 914418f3690177b600f5b0d91e1902ab7332536d Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Fri, 10 Sep 2021 12:46:10 +0100 Subject: [PATCH 022/279] scsi: qla2xxx: Remove redundant initialization of pointer req The pointer req is being initialized with a value that is never read, it is being updated later on. The assignment is redundant and can be removed. Link: https://lore.kernel.org/r/20210910114610.44752-1-colin.king@canonical.com Reviewed-by: Himanshu Madhani Signed-off-by: Colin Ian King Signed-off-by: Martin K. Petersen Addresses-Coverity: ("Unused value") --- drivers/scsi/qla2xxx/qla_mbx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c index 9eb41dd39043..73a353153d33 100644 --- a/drivers/scsi/qla2xxx/qla_mbx.c +++ b/drivers/scsi/qla2xxx/qla_mbx.c @@ -3236,7 +3236,7 @@ qla24xx_abort_command(srb_t *sp) fc_port_t *fcport = sp->fcport; struct scsi_qla_host *vha = fcport->vha; struct qla_hw_data *ha = vha->hw; - struct req_que *req = vha->req; + struct req_que *req; struct qla_qpair *qpair = sp->qpair; ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x108c, From 99154581b05c8fb22607afb7c3d66c1bace6aa5d Mon Sep 17 00:00:00 2001 From: James Smart Date: Fri, 10 Sep 2021 16:31:46 -0700 Subject: [PATCH 023/279] scsi: lpfc: Fix list_add() corruption in lpfc_drain_txq() When parsing the txq list in lpfc_drain_txq(), the driver attempts to pass the requests to the adapter. If such an attempt fails, a local "fail_msg" string is set and a log message output. The job is then added to a completions list for cancellation. Processing of any further jobs from the txq list continues, but since "fail_msg" remains set, jobs are added to the completions list regardless of whether a wqe was passed to the adapter. If successfully added to txcmplq, jobs are added to both lists resulting in list corruption. Fix by clearing the fail_msg string after adding a job to the completions list. This stops the subsequent jobs from being added to the completions list unless they had an appropriate failure. Link: https://lore.kernel.org/r/20210910233159.115896-2-jsmart2021@gmail.com Co-developed-by: Justin Tee Signed-off-by: Justin Tee Signed-off-by: James Smart Signed-off-by: Martin K. Petersen --- drivers/scsi/lpfc/lpfc_sli.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index ffd8a140638c..546c851938bc 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c @@ -21104,6 +21104,7 @@ lpfc_drain_txq(struct lpfc_hba *phba) fail_msg, piocbq->iotag, piocbq->sli4_xritag); list_add_tail(&piocbq->list, &completions); + fail_msg = NULL; } spin_unlock_irqrestore(&pring->ring_lock, iflags); } From 982fc3965d1350d3332e04046b0e101006184ba9 Mon Sep 17 00:00:00 2001 From: James Smart Date: Fri, 10 Sep 2021 16:31:47 -0700 Subject: [PATCH 024/279] scsi: lpfc: Don't release final kref on Fport node while ABTS outstanding In a rarely executed path, FLOGI failure, there is a refcounting error. If FLOGI completed with an error, typically a timeout, the initial completion handler would remove the job reference. However, the job completion isn't the actual end of the job/exchange as the timeout usually initiates an ABTS, and upon that ABTS completion, a final completion is sent. The driver removes the reference again in the final completion. Thus the imbalance. In the buggy cases, if there was a link bounce while the delayed response is outstanding, the fport node may be referenced again but there was no additional reference as it is already present. The delayed completion then occurs and removes the last reference freeing the node and causing issues in the link up processed that is using the node. Fix this scenario by removing the snippet that removed the reference in the initial FLOGI completion. The bad snippet was poorly trying to identify the FLOGI as OK to do so by realizing the node was not registered with either SCSI or NVMe transport. Link: https://lore.kernel.org/r/20210910233159.115896-3-jsmart2021@gmail.com Fixes: 618e2ee146d4 ("scsi: lpfc: Fix FLOGI failure due to accessing a freed node") Cc: # v5.13+ Co-developed-by: Justin Tee Signed-off-by: Justin Tee Signed-off-by: James Smart Signed-off-by: Martin K. Petersen --- drivers/scsi/lpfc/lpfc_els.c | 11 +++++------ drivers/scsi/lpfc/lpfc_hbadisc.c | 10 ++++++---- drivers/scsi/lpfc/lpfc_nvme.c | 5 +++-- 3 files changed, 14 insertions(+), 12 deletions(-) diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c index 1254a575fd47..df5fc223ddb2 100644 --- a/drivers/scsi/lpfc/lpfc_els.c +++ b/drivers/scsi/lpfc/lpfc_els.c @@ -1059,9 +1059,10 @@ stop_rr_fcf_flogi: lpfc_printf_vlog(vport, KERN_WARNING, LOG_TRACE_EVENT, "0150 FLOGI failure Status:x%x/x%x " - "xri x%x TMO:x%x\n", + "xri x%x TMO:x%x refcnt %d\n", irsp->ulpStatus, irsp->un.ulpWord[4], - cmdiocb->sli4_xritag, irsp->ulpTimeout); + cmdiocb->sli4_xritag, irsp->ulpTimeout, + kref_read(&ndlp->kref)); /* If this is not a loop open failure, bail out */ if (!(irsp->ulpStatus == IOSTAT_LOCAL_REJECT && @@ -1122,12 +1123,12 @@ stop_rr_fcf_flogi: /* FLOGI completes successfully */ lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS, "0101 FLOGI completes successfully, I/O tag:x%x, " - "xri x%x Data: x%x x%x x%x x%x x%x x%x x%x\n", + "xri x%x Data: x%x x%x x%x x%x x%x x%x x%x %d\n", cmdiocb->iotag, cmdiocb->sli4_xritag, irsp->un.ulpWord[4], sp->cmn.e_d_tov, sp->cmn.w2.r_a_tov, sp->cmn.edtovResolution, vport->port_state, vport->fc_flag, - sp->cmn.priority_tagging); + sp->cmn.priority_tagging, kref_read(&ndlp->kref)); if (sp->cmn.priority_tagging) vport->vmid_flag |= LPFC_VMID_ISSUE_QFPA; @@ -1205,8 +1206,6 @@ flogifail: phba->fcf.fcf_flag &= ~FCF_DISCOVERY; spin_unlock_irq(&phba->hbalock); - if (!(ndlp->fc4_xpt_flags & (SCSI_XPT_REGD | NVME_XPT_REGD))) - lpfc_nlp_put(ndlp); if (!lpfc_error_lost_link(irsp)) { /* FLOGI failed, so just use loop map to make discovery list */ lpfc_disc_list_loopmap(vport); diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c index 7195ca0275f9..6f2e07c30f98 100644 --- a/drivers/scsi/lpfc/lpfc_hbadisc.c +++ b/drivers/scsi/lpfc/lpfc_hbadisc.c @@ -4449,8 +4449,9 @@ lpfc_register_remote_port(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) fc_remote_port_rolechg(rport, rport_ids.roles); lpfc_printf_vlog(ndlp->vport, KERN_INFO, LOG_NODE, - "3183 %s rport x%px DID x%x, role x%x\n", - __func__, rport, rport->port_id, rport->roles); + "3183 %s rport x%px DID x%x, role x%x refcnt %d\n", + __func__, rport, rport->port_id, rport->roles, + kref_read(&ndlp->kref)); if ((rport->scsi_target_id != -1) && (rport->scsi_target_id < LPFC_MAX_TARGET)) { @@ -4475,8 +4476,9 @@ lpfc_unregister_remote_port(struct lpfc_nodelist *ndlp) lpfc_printf_vlog(vport, KERN_INFO, LOG_NODE, "3184 rport unregister x%06x, rport x%px " - "xptflg x%x\n", - ndlp->nlp_DID, rport, ndlp->fc4_xpt_flags); + "xptflg x%x refcnt %d\n", + ndlp->nlp_DID, rport, ndlp->fc4_xpt_flags, + kref_read(&ndlp->kref)); fc_remote_port_delete(rport); lpfc_nlp_put(ndlp); diff --git a/drivers/scsi/lpfc/lpfc_nvme.c b/drivers/scsi/lpfc/lpfc_nvme.c index 73a3568ff17e..bd88477f9b82 100644 --- a/drivers/scsi/lpfc/lpfc_nvme.c +++ b/drivers/scsi/lpfc/lpfc_nvme.c @@ -209,8 +209,9 @@ lpfc_nvme_remoteport_delete(struct nvme_fc_remote_port *remoteport) * calling state machine to remove the node. */ lpfc_printf_vlog(vport, KERN_INFO, LOG_NVME_DISC, - "6146 remoteport delete of remoteport x%px\n", - remoteport); + "6146 remoteport delete of remoteport x%px, ndlp x%px " + "DID x%x xflags x%x\n", + remoteport, ndlp, ndlp->nlp_DID, ndlp->fc4_xpt_flags); spin_lock_irq(&ndlp->lock); /* The register rebind might have occurred before the delete From 20d2279f90ce87f1d08d2e7ad885a3dcc0678331 Mon Sep 17 00:00:00 2001 From: James Smart Date: Fri, 10 Sep 2021 16:31:48 -0700 Subject: [PATCH 025/279] scsi: lpfc: Fix premature rpi release for unsolicited TPLS and LS_RJT A test scenario has a target issuing a TPLS after accepting the driver's PRLI. TPLS is not supported by the driver so it rejects the ELS. However, the reject was only happening on the primary N_Port. If the TPLS was to a NPIV vport, not only would it reject the ELS, but it would act on the TPLS, starting devloss, then unregister from the SCSI transport and release the node. When devloss expired, it would access the node again and cause a page faul. Fix by altering the NPIV code to recognize that a correctly registered node can reject unsolicited ELS I/O and to not unregister with the SCSI transport and tear the node down. Add a check of the fc4_xpt_flags so that only a zero value allows the unreg and teardown. Link: https://lore.kernel.org/r/20210910233159.115896-4-jsmart2021@gmail.com Co-developed-by: Justin Tee Signed-off-by: Justin Tee Signed-off-by: James Smart Signed-off-by: Martin K. Petersen --- drivers/scsi/lpfc/lpfc_els.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c index df5fc223ddb2..262101e172ad 100644 --- a/drivers/scsi/lpfc/lpfc_els.c +++ b/drivers/scsi/lpfc/lpfc_els.c @@ -5295,6 +5295,7 @@ out: */ if (phba->sli_rev == LPFC_SLI_REV4 && (vport && vport->port_type == LPFC_NPIV_PORT) && + !(ndlp->fc4_xpt_flags & SCSI_XPT_REGD) && ndlp->nlp_flag & NLP_RELEASE_RPI) { lpfc_sli4_free_rpi(phba, ndlp->nlp_rpi); spin_lock_irq(&ndlp->lock); @@ -5598,11 +5599,12 @@ lpfc_els_rsp_reject(struct lpfc_vport *vport, uint32_t rejectError, } /* The NPIV instance is rejecting this unsolicited ELS. Make sure the - * node's assigned RPI needs to be released as this node will get - * freed. + * node's assigned RPI gets released provided this node is not already + * registered with the transport. */ if (phba->sli_rev == LPFC_SLI_REV4 && - vport->port_type == LPFC_NPIV_PORT) { + vport->port_type == LPFC_NPIV_PORT && + !(ndlp->fc4_xpt_flags & SCSI_XPT_REGD)) { spin_lock_irq(&ndlp->lock); ndlp->nlp_flag |= NLP_RELEASE_RPI; spin_unlock_irq(&ndlp->lock); From 88f7702984e6e562223ecc07c38ac4e61713780a Mon Sep 17 00:00:00 2001 From: James Smart Date: Fri, 10 Sep 2021 16:31:49 -0700 Subject: [PATCH 026/279] scsi: lpfc: Fix hang on unload due to stuck fport node A test scenario encountered an unload hang while an FLOGI ELS was in flight when a link down condition occurred. The driver fails unload as it never releases the fport node. For most nodes, when the link drops, devloss tmo is started and the timeout will cause the final node release. For the Fport, as it has not yet registered with the SCSI transport, there is no devloss timer to be started, so there is no final release. Additionally, the link down sequence causes ABORTS to be issued for pending ELS's. The completions from the ABORTS perform the release of node references. However, as the adapter is being reset to be unloaded, those completions will never occur. Fix by the following: - In the ELS cleanup, recognize when unloading and place the ELS's on a different list that immediately cleans up/completes the ELS's. It's recognized that this condition primarily affects only the fport, with other ports having normal clean up logic that handles things. - Resolve the devloss issue by, when cleaning up nodes on after link down, recognizing when the fabric node does not have a completed state (its state is UNUSED) and removing a reference so the node can delete after the ELS reference is released. Link: https://lore.kernel.org/r/20210910233159.115896-5-jsmart2021@gmail.com Co-developed-by: Justin Tee Signed-off-by: Justin Tee Signed-off-by: James Smart Signed-off-by: Martin K. Petersen --- drivers/scsi/lpfc/lpfc_els.c | 14 ++++++++++++++ drivers/scsi/lpfc/lpfc_hbadisc.c | 14 +++++++++++++- 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c index 262101e172ad..6c9cb87ef174 100644 --- a/drivers/scsi/lpfc/lpfc_els.c +++ b/drivers/scsi/lpfc/lpfc_els.c @@ -11386,6 +11386,7 @@ lpfc_sli4_vport_delete_els_xri_aborted(struct lpfc_vport *vport) { struct lpfc_hba *phba = vport->phba; struct lpfc_sglq *sglq_entry = NULL, *sglq_next = NULL; + struct lpfc_nodelist *ndlp = NULL; unsigned long iflag = 0; spin_lock_irqsave(&phba->sli4_hba.sgl_list_lock, iflag); @@ -11393,7 +11394,20 @@ lpfc_sli4_vport_delete_els_xri_aborted(struct lpfc_vport *vport) &phba->sli4_hba.lpfc_abts_els_sgl_list, list) { if (sglq_entry->ndlp && sglq_entry->ndlp->vport == vport) { lpfc_nlp_put(sglq_entry->ndlp); + ndlp = sglq_entry->ndlp; sglq_entry->ndlp = NULL; + + /* If the xri on the abts_els_sgl list is for the Fport + * node and the vport is unloading, the xri aborted wcqe + * likely isn't coming back. Just release the sgl. + */ + if ((vport->load_flag & FC_UNLOADING) && + ndlp->nlp_DID == Fabric_DID) { + list_del(&sglq_entry->list); + sglq_entry->state = SGL_FREED; + list_add_tail(&sglq_entry->list, + &phba->sli4_hba.lpfc_els_sgl_list); + } } } spin_unlock_irqrestore(&phba->sli4_hba.sgl_list_lock, iflag); diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c index 6f2e07c30f98..4ff93aef3295 100644 --- a/drivers/scsi/lpfc/lpfc_hbadisc.c +++ b/drivers/scsi/lpfc/lpfc_hbadisc.c @@ -966,8 +966,20 @@ lpfc_cleanup_rpis(struct lpfc_vport *vport, int remove) struct lpfc_nodelist *ndlp, *next_ndlp; list_for_each_entry_safe(ndlp, next_ndlp, &vport->fc_nodes, nlp_listp) { - if (ndlp->nlp_state == NLP_STE_UNUSED_NODE) + if (ndlp->nlp_state == NLP_STE_UNUSED_NODE) { + /* It's possible the FLOGI to the fabric node never + * successfully completed and never registered with the + * transport. In this case there is no way to clean up + * the node. + */ + if (ndlp->nlp_DID == Fabric_DID) { + if (ndlp->nlp_prev_state == + NLP_STE_UNUSED_NODE && + !ndlp->fc4_xpt_flags) + lpfc_nlp_put(ndlp); + } continue; + } if ((phba->sli3_options & LPFC_SLI3_VPORT_TEARDOWN) || ((vport->port_type == LPFC_NPIV_PORT) && From 3a874488d2e936340e165070a41508208d816fc3 Mon Sep 17 00:00:00 2001 From: James Smart Date: Fri, 10 Sep 2021 16:31:50 -0700 Subject: [PATCH 027/279] scsi: lpfc: Fix rediscovery of tape device after LIP On link up and node discovery, a remote port is registered with the SCSI transport and the driver sets fc4_xpt_flags to track transport registration. A link down event causes the driver to deregister with the SCSI transport, starting the devloss timer, and calls a local unreg routine to clear the login state. Part of the login state is the fc4_xpt_flags. However, with tape devices that support sequence level error recovery, which wants to preserve the login, the local unreg routine is skipped, thus the flags aren't cleared. A subsequent link up, ADISC is performed and the lpfc_nlp_reg_node() routine is called. As the fc4_xpt_flags is not clear, it's believed the node is already registered with the transport. Unfortunately, the registration was already terminated. Eventually the devloss tmo timer expires and tears down the device. Fix by ensuring the tape device, known by the ADISC flag, is always unregistered if the link drops. Link: https://lore.kernel.org/r/20210910233159.115896-6-jsmart2021@gmail.com Co-developed-by: Justin Tee Signed-off-by: Justin Tee Signed-off-by: James Smart Signed-off-by: Martin K. Petersen --- drivers/scsi/lpfc/lpfc_hbadisc.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c index 4ff93aef3295..12abfc027a67 100644 --- a/drivers/scsi/lpfc/lpfc_hbadisc.c +++ b/drivers/scsi/lpfc/lpfc_hbadisc.c @@ -4693,8 +4693,11 @@ lpfc_nlp_state_cleanup(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, /* Reg/Unreg for FCP and NVME Transport interface */ if ((old_state == NLP_STE_MAPPED_NODE || old_state == NLP_STE_UNMAPPED_NODE)) { - /* For nodes marked for ADISC, Handle unreg in ADISC cmpl */ - if (!(ndlp->nlp_flag & NLP_NPR_ADISC)) + /* For nodes marked for ADISC, Handle unreg in ADISC cmpl + * if linkup. In linkdown do unreg_node + */ + if (!(ndlp->nlp_flag & NLP_NPR_ADISC) || + !lpfc_is_link_up(vport->phba)) lpfc_nlp_unreg_node(vport, ndlp); } From a864ee709bc06095463c61fc22a4dc899fba1758 Mon Sep 17 00:00:00 2001 From: James Smart Date: Fri, 10 Sep 2021 16:31:51 -0700 Subject: [PATCH 028/279] scsi: lpfc: Don't remove ndlp on PRLI errors in P2P mode In pt-2-pt mode, the initiator does not log into the target after a PRLI error. In pt-2-pt mode, the target responded to the PRLI by sending a LOGO. The LOGO causes all ELS and I/Os to be aborted. This caused the PRLI to fail. The PRLI completion path caused the discovery node to be dropped to avoid being stick in an UNUSED (not logged in) state. As the node was dropped there is no retry of the login and as it is pt-2-pt, there is no RSCN to retrigger discovery. Thus the other end is not seen by the OS. Fix by ensuring the discovery node is not dropped if connecting pt-2-pt. This will cause PLOGI to be retried. Link: https://lore.kernel.org/r/20210910233159.115896-7-jsmart2021@gmail.com Co-developed-by: Justin Tee Signed-off-by: Justin Tee Signed-off-by: James Smart Signed-off-by: Martin K. Petersen --- drivers/scsi/lpfc/lpfc_els.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c index 6c9cb87ef174..c6eae545aabf 100644 --- a/drivers/scsi/lpfc/lpfc_els.c +++ b/drivers/scsi/lpfc/lpfc_els.c @@ -2329,6 +2329,13 @@ lpfc_cmpl_els_prli(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, lpfc_disc_state_machine(vport, ndlp, cmdiocb, NLP_EVT_CMPL_PRLI); + /* + * For P2P topology, retain the node so that PLOGI can be + * attempted on it again. + */ + if (vport->fc_flag & FC_PT2PT) + goto out; + /* As long as this node is not registered with the SCSI * or NVMe transport and no other PRLIs are outstanding, * it is no longer an active node. Otherwise devloss From b507357f79171fb4fb4e732ca43a1f30bc5aab1d Mon Sep 17 00:00:00 2001 From: James Smart Date: Fri, 10 Sep 2021 16:31:52 -0700 Subject: [PATCH 029/279] scsi: lpfc: Fix NVMe I/O failover to non-optimized path Currently, we hold off unregistering with NVMe transport layer until GID_FT or ADISC completes upon receipt of RSCN. In the ADISC discovery routine, for nodes not found in the GID_FT response, the nodes are unregistered from the SCSI transport but not UNREG_RPI'd. Meaning outstanding WQEs continue to be outstanding and were not failed back to the OS. If an NVMe device, this mean there wasn't initial termination of the I/Os so they could be issued on a different NVMe path. Fix by unregistering the RPI so that I/O is cancelled. Link: https://lore.kernel.org/r/20210910233159.115896-8-jsmart2021@gmail.com Fixes: 0614568361b0 ("scsi: lpfc: Delay unregistering from transport until GIDFT or ADISC completes") Co-developed-by: Justin Tee Signed-off-by: Justin Tee Signed-off-by: James Smart Signed-off-by: Martin K. Petersen --- drivers/scsi/lpfc/lpfc_els.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c index c6eae545aabf..40d166aeb466 100644 --- a/drivers/scsi/lpfc/lpfc_els.c +++ b/drivers/scsi/lpfc/lpfc_els.c @@ -6224,6 +6224,7 @@ lpfc_els_disc_adisc(struct lpfc_vport *vport) * from backend */ lpfc_nlp_unreg_node(vport, ndlp); + lpfc_unreg_rpi(vport, ndlp); continue; } From cd8a36a90babf958082b87bc6b4df5dd70901eba Mon Sep 17 00:00:00 2001 From: James Smart Date: Fri, 10 Sep 2021 16:31:53 -0700 Subject: [PATCH 030/279] scsi: lpfc: Fix FCP I/O flush functionality for TMF routines A prior patch inadvertently caused lpfc_sli_sum_iocb() to exclude counting of outstanding aborted I/Os and ABORT IOCBs. Thus, lpfc_reset_flush_io_context() called from any TMF routine does not properly wait to flush all outstanding FCP IOCBs leading to a block layer crash on an invalid scsi_cmnd->request pointer. kernel BUG at ../block/blk-core.c:1489! RIP: 0010:blk_requeue_request+0xaf/0xc0 ... Call Trace: __scsi_queue_insert+0x90/0xe0 [scsi_mod] blk_done_softirq+0x7e/0x90 __do_softirq+0xd2/0x280 irq_exit+0xd5/0xe0 do_IRQ+0x4c/0xd0 common_interrupt+0x87/0x87 Fix by separating out the LPFC_IO_FCP, LPFC_IO_ON_TXCMPLQ, LPFC_DRIVER_ABORTED, and CMD_ABORT_XRI_CN || CMD_CLOSE_XRI_CN checks into a new lpfc_sli_validate_fcp_iocb_for_abort() routine when determining to build an ABORT iocb. Restore lpfc_reset_flush_io_context() functionality by including counting of outstanding aborted IOCBs and ABORT IOCBs in lpfc_sli_sum_iocb(). Link: https://lore.kernel.org/r/20210910233159.115896-9-jsmart2021@gmail.com Fixes: e1364711359f ("scsi: lpfc: Fix illegal memory access on Abort IOCBs") Cc: # v5.12+ Co-developed-by: Justin Tee Signed-off-by: Justin Tee Signed-off-by: James Smart Signed-off-by: Martin K. Petersen --- drivers/scsi/lpfc/lpfc_sli.c | 101 +++++++++++++++++++++++++++-------- 1 file changed, 78 insertions(+), 23 deletions(-) diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index 546c851938bc..e8f6ad484768 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c @@ -12485,15 +12485,54 @@ lpfc_sli_hba_iocb_abort(struct lpfc_hba *phba) } /** - * lpfc_sli_validate_fcp_iocb - find commands associated with a vport or LUN + * lpfc_sli_validate_fcp_iocb_for_abort - filter iocbs appropriate for FCP aborts + * @iocbq: Pointer to iocb object. + * @vport: Pointer to driver virtual port object. + * + * This function acts as an iocb filter for functions which abort FCP iocbs. + * + * Return values + * -ENODEV, if a null iocb or vport ptr is encountered + * -EINVAL, if the iocb is not an FCP I/O, not on the TX cmpl queue, premarked as + * driver already started the abort process, or is an abort iocb itself + * 0, passes criteria for aborting the FCP I/O iocb + **/ +static int +lpfc_sli_validate_fcp_iocb_for_abort(struct lpfc_iocbq *iocbq, + struct lpfc_vport *vport) +{ + IOCB_t *icmd = NULL; + + /* No null ptr vports */ + if (!iocbq || iocbq->vport != vport) + return -ENODEV; + + /* iocb must be for FCP IO, already exists on the TX cmpl queue, + * can't be premarked as driver aborted, nor be an ABORT iocb itself + */ + icmd = &iocbq->iocb; + if (!(iocbq->iocb_flag & LPFC_IO_FCP) || + !(iocbq->iocb_flag & LPFC_IO_ON_TXCMPLQ) || + (iocbq->iocb_flag & LPFC_DRIVER_ABORTED) || + (icmd->ulpCommand == CMD_ABORT_XRI_CN || + icmd->ulpCommand == CMD_CLOSE_XRI_CN)) + return -EINVAL; + + return 0; +} + +/** + * lpfc_sli_validate_fcp_iocb - validate commands associated with a SCSI target * @iocbq: Pointer to driver iocb object. * @vport: Pointer to driver virtual port object. * @tgt_id: SCSI ID of the target. * @lun_id: LUN ID of the scsi device. * @ctx_cmd: LPFC_CTX_LUN/LPFC_CTX_TGT/LPFC_CTX_HOST * - * This function acts as an iocb filter for functions which abort or count - * all FCP iocbs pending on a lun/SCSI target/SCSI host. It will return + * This function acts as an iocb filter for validating a lun/SCSI target/SCSI + * host. + * + * It will return * 0 if the filtering criteria is met for the given iocb and will return * 1 if the filtering criteria is not met. * If ctx_cmd == LPFC_CTX_LUN, the function returns 0 only if the @@ -12512,22 +12551,8 @@ lpfc_sli_validate_fcp_iocb(struct lpfc_iocbq *iocbq, struct lpfc_vport *vport, lpfc_ctx_cmd ctx_cmd) { struct lpfc_io_buf *lpfc_cmd; - IOCB_t *icmd = NULL; int rc = 1; - if (!iocbq || iocbq->vport != vport) - return rc; - - if (!(iocbq->iocb_flag & LPFC_IO_FCP) || - !(iocbq->iocb_flag & LPFC_IO_ON_TXCMPLQ) || - iocbq->iocb_flag & LPFC_DRIVER_ABORTED) - return rc; - - icmd = &iocbq->iocb; - if (icmd->ulpCommand == CMD_ABORT_XRI_CN || - icmd->ulpCommand == CMD_CLOSE_XRI_CN) - return rc; - lpfc_cmd = container_of(iocbq, struct lpfc_io_buf, cur_iocbq); if (lpfc_cmd->pCmd == NULL) @@ -12582,17 +12607,33 @@ lpfc_sli_sum_iocb(struct lpfc_vport *vport, uint16_t tgt_id, uint64_t lun_id, { struct lpfc_hba *phba = vport->phba; struct lpfc_iocbq *iocbq; + IOCB_t *icmd = NULL; int sum, i; + unsigned long iflags; - spin_lock_irq(&phba->hbalock); + spin_lock_irqsave(&phba->hbalock, iflags); for (i = 1, sum = 0; i <= phba->sli.last_iotag; i++) { iocbq = phba->sli.iocbq_lookup[i]; - if (lpfc_sli_validate_fcp_iocb (iocbq, vport, tgt_id, lun_id, - ctx_cmd) == 0) + if (!iocbq || iocbq->vport != vport) + continue; + if (!(iocbq->iocb_flag & LPFC_IO_FCP) || + !(iocbq->iocb_flag & LPFC_IO_ON_TXCMPLQ)) + continue; + + /* Include counting outstanding aborts */ + icmd = &iocbq->iocb; + if (icmd->ulpCommand == CMD_ABORT_XRI_CN || + icmd->ulpCommand == CMD_CLOSE_XRI_CN) { + sum++; + continue; + } + + if (lpfc_sli_validate_fcp_iocb(iocbq, vport, tgt_id, lun_id, + ctx_cmd) == 0) sum++; } - spin_unlock_irq(&phba->hbalock); + spin_unlock_irqrestore(&phba->hbalock, iflags); return sum; } @@ -12659,7 +12700,11 @@ lpfc_sli_abort_fcp_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, * * This function sends an abort command for every SCSI command * associated with the given virtual port pending on the ring - * filtered by lpfc_sli_validate_fcp_iocb function. + * filtered by lpfc_sli_validate_fcp_iocb_for_abort and then + * lpfc_sli_validate_fcp_iocb function. The ordering for validation before + * submitting abort iocbs must be lpfc_sli_validate_fcp_iocb_for_abort + * followed by lpfc_sli_validate_fcp_iocb. + * * When abort_cmd == LPFC_CTX_LUN, the function sends abort only to the * FCP iocbs associated with lun specified by tgt_id and lun_id * parameters @@ -12691,6 +12736,9 @@ lpfc_sli_abort_iocb(struct lpfc_vport *vport, u16 tgt_id, u64 lun_id, for (i = 1; i <= phba->sli.last_iotag; i++) { iocbq = phba->sli.iocbq_lookup[i]; + if (lpfc_sli_validate_fcp_iocb_for_abort(iocbq, vport)) + continue; + if (lpfc_sli_validate_fcp_iocb(iocbq, vport, tgt_id, lun_id, abort_cmd) != 0) continue; @@ -12723,7 +12771,11 @@ lpfc_sli_abort_iocb(struct lpfc_vport *vport, u16 tgt_id, u64 lun_id, * * This function sends an abort command for every SCSI command * associated with the given virtual port pending on the ring - * filtered by lpfc_sli_validate_fcp_iocb function. + * filtered by lpfc_sli_validate_fcp_iocb_for_abort and then + * lpfc_sli_validate_fcp_iocb function. The ordering for validation before + * submitting abort iocbs must be lpfc_sli_validate_fcp_iocb_for_abort + * followed by lpfc_sli_validate_fcp_iocb. + * * When taskmgmt_cmd == LPFC_CTX_LUN, the function sends abort only to the * FCP iocbs associated with lun specified by tgt_id and lun_id * parameters @@ -12761,6 +12813,9 @@ lpfc_sli_abort_taskmgmt(struct lpfc_vport *vport, struct lpfc_sli_ring *pring, for (i = 1; i <= phba->sli.last_iotag; i++) { iocbq = phba->sli.iocbq_lookup[i]; + if (lpfc_sli_validate_fcp_iocb_for_abort(iocbq, vport)) + continue; + if (lpfc_sli_validate_fcp_iocb(iocbq, vport, tgt_id, lun_id, cmd) != 0) continue; From 25ac2c970be32993f1dff607f8354f3c053d42bc Mon Sep 17 00:00:00 2001 From: James Smart Date: Fri, 10 Sep 2021 16:31:54 -0700 Subject: [PATCH 031/279] scsi: lpfc: Fix EEH support for NVMe I/O Injecting errors on the PCI slot while the driver is handling NVMe I/O will cause crashes and hangs. There are several rather difficult scenarios occurring. The main issue is that the adapter can report a PCI error before or simultaneously to the PCI subsystem reporting the error. Both paths have different entry points and currently there is no interlock between them. Thus multiple teardown paths are competing and all heck breaks loose. Complicating things is the NVMs path. To a large degree, I/O was able to be shutdown for a full FC port on the SCSI stack. But on NVMe, there isn't a similar call. At best, it works on a per-controller basis, but even at the controller level, it's a controller "reset" call. All of which means I/O is still flowing on different CPUs with reset paths expecting hw access (mailbox commands) to execute properly. The following modifications are made: - A new flag is set in PCI error entrypoints so the driver can track being called by that path. - An interlock is added in the SLI hw error path and the PCI error path such that only one of the paths proceeds with the teardown logic. - RPI cleanup is patched such that RPIs are marked unregistered w/o mbx cmds in cases of hw error. - If entering the SLI port re-init calls, a case where SLI error teardown was quick and beat the PCI calls now reporting error, check whether the SLI port is still live on the PCI bus. - In the PCI reset code to bring the adapter back, recheck the IRQ settings. Different checks for SLI3 vs SLI4. - In I/O completions, that may be called as part of the cleanup or underway just before the hw error, check the state of the adapter. If in error, shortcut handling that would expect further adapter completions as the hw error won't be sending them. - In routines waiting on I/O completions, which may have been in progress prior to the hw error, detect the device is being torn down and abort from their waits and just give up. This points to a larger issue in the driver on ref-counting for data structures, as it doesn't have ref-counting on q and port structures. We'll do this fix for now as it would be a major rework to be done differently. - Fix the NVMe cleanup to simulate NVMe I/O completions if I/O is being failed back due to hw error. - In I/O buf allocation, done at the start of new I/Os, check hw state and fail if hw error. Link: https://lore.kernel.org/r/20210910233159.115896-10-jsmart2021@gmail.com Co-developed-by: Justin Tee Signed-off-by: Justin Tee Signed-off-by: James Smart Signed-off-by: Martin K. Petersen --- drivers/scsi/lpfc/lpfc.h | 1 + drivers/scsi/lpfc/lpfc_hbadisc.c | 1 + drivers/scsi/lpfc/lpfc_init.c | 31 +++++++++++++++- drivers/scsi/lpfc/lpfc_nvme.c | 53 ++++++++++++++++++++++++++- drivers/scsi/lpfc/lpfc_scsi.c | 63 +++++++++++++++++++++----------- drivers/scsi/lpfc/lpfc_sli.c | 31 +++++++++++++++- drivers/scsi/lpfc/lpfc_sli4.h | 2 + 7 files changed, 154 insertions(+), 28 deletions(-) diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h index befeb7c34290..2f6b81bc2451 100644 --- a/drivers/scsi/lpfc/lpfc.h +++ b/drivers/scsi/lpfc/lpfc.h @@ -1028,6 +1028,7 @@ struct lpfc_hba { * Firmware supports Forced Link Speed * capability */ +#define HBA_PCI_ERR 0x80000 /* The PCI slot is offline */ #define HBA_FLOGI_ISSUED 0x100000 /* FLOGI was issued */ #define HBA_CGN_RSVD1 0x200000 /* Reserved CGN flag */ #define HBA_CGN_DAY_WRAP 0x400000 /* HBA Congestion info day wraps */ diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c index 12abfc027a67..0b1e1cc00e01 100644 --- a/drivers/scsi/lpfc/lpfc_hbadisc.c +++ b/drivers/scsi/lpfc/lpfc_hbadisc.c @@ -5250,6 +5250,7 @@ lpfc_unreg_rpi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) rc = lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT); if (rc == MBX_NOT_FINISHED) { + ndlp->nlp_flag &= ~NLP_UNREG_INP; mempool_free(mbox, phba->mbox_mem_pool); acc_plogi = 1; } diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index 0ec322f0e3cb..3fd730613de3 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c @@ -1606,6 +1606,11 @@ void lpfc_sli4_offline_eratt(struct lpfc_hba *phba) { spin_lock_irq(&phba->hbalock); + if (phba->link_state == LPFC_HBA_ERROR && + phba->hba_flag & HBA_PCI_ERR) { + spin_unlock_irq(&phba->hbalock); + return; + } phba->link_state = LPFC_HBA_ERROR; spin_unlock_irq(&phba->hbalock); @@ -1945,7 +1950,6 @@ lpfc_handle_eratt_s4(struct lpfc_hba *phba) if (pci_channel_offline(phba->pcidev)) { lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT, "3166 pci channel is offline\n"); - lpfc_sli4_offline_eratt(phba); return; } @@ -3643,6 +3647,7 @@ lpfc_offline_prep(struct lpfc_hba *phba, int mbx_action) struct lpfc_vport **vports; struct Scsi_Host *shost; int i; + int offline = 0; if (vport->fc_flag & FC_OFFLINE_MODE) return; @@ -3651,6 +3656,8 @@ lpfc_offline_prep(struct lpfc_hba *phba, int mbx_action) lpfc_linkdown(phba); + offline = pci_channel_offline(phba->pcidev); + /* Issue an unreg_login to all nodes on all vports */ vports = lpfc_create_vport_work_array(phba); if (vports != NULL) { @@ -3673,7 +3680,14 @@ lpfc_offline_prep(struct lpfc_hba *phba, int mbx_action) ndlp->nlp_flag &= ~NLP_NPR_ADISC; spin_unlock_irq(&ndlp->lock); - lpfc_unreg_rpi(vports[i], ndlp); + if (offline) { + spin_lock_irq(&ndlp->lock); + ndlp->nlp_flag &= ~(NLP_UNREG_INP | + NLP_RPI_REGISTERED); + spin_unlock_irq(&ndlp->lock); + } else { + lpfc_unreg_rpi(vports[i], ndlp); + } /* * Whenever an SLI4 port goes offline, free the * RPI. Get a new RPI when the adapter port @@ -14080,6 +14094,10 @@ lpfc_pci_resume_one_s3(struct device *dev_d) return error; } + /* Init cpu_map array */ + lpfc_cpu_map_array_init(phba); + /* Init hba_eq_hdl array */ + lpfc_hba_eq_hdl_array_init(phba); /* Configure and enable interrupt */ intr_mode = lpfc_sli_enable_intr(phba, phba->intr_mode); if (intr_mode == LPFC_INTR_ERROR) { @@ -15033,14 +15051,17 @@ lpfc_io_error_detected_s4(struct pci_dev *pdev, pci_channel_state_t state) lpfc_sli4_prep_dev_for_recover(phba); return PCI_ERS_RESULT_CAN_RECOVER; case pci_channel_io_frozen: + phba->hba_flag |= HBA_PCI_ERR; /* Fatal error, prepare for slot reset */ lpfc_sli4_prep_dev_for_reset(phba); return PCI_ERS_RESULT_NEED_RESET; case pci_channel_io_perm_failure: + phba->hba_flag |= HBA_PCI_ERR; /* Permanent failure, prepare for device down */ lpfc_sli4_prep_dev_for_perm_failure(phba); return PCI_ERS_RESULT_DISCONNECT; default: + phba->hba_flag |= HBA_PCI_ERR; /* Unknown state, prepare and request slot reset */ lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT, "2825 Unknown PCI error state: x%x\n", state); @@ -15084,6 +15105,7 @@ lpfc_io_slot_reset_s4(struct pci_dev *pdev) pci_restore_state(pdev); + phba->hba_flag &= ~HBA_PCI_ERR; /* * As the new kernel behavior of pci_restore_state() API call clears * device saved_state flag, need to save the restored state again. @@ -15106,6 +15128,7 @@ lpfc_io_slot_reset_s4(struct pci_dev *pdev) return PCI_ERS_RESULT_DISCONNECT; } else phba->intr_mode = intr_mode; + lpfc_cpu_affinity_check(phba, phba->cfg_irq_chann); /* Log the current active interrupt mode */ lpfc_log_intr_mode(phba, phba->intr_mode); @@ -15307,6 +15330,10 @@ lpfc_io_error_detected(struct pci_dev *pdev, pci_channel_state_t state) struct lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba; pci_ers_result_t rc = PCI_ERS_RESULT_DISCONNECT; + if (phba->link_state == LPFC_HBA_ERROR && + phba->hba_flag & HBA_IOQ_FLUSH) + return PCI_ERS_RESULT_NEED_RESET; + switch (phba->pci_dev_grp) { case LPFC_PCI_DEV_LP: rc = lpfc_io_error_detected_s3(pdev, state); diff --git a/drivers/scsi/lpfc/lpfc_nvme.c b/drivers/scsi/lpfc/lpfc_nvme.c index bd88477f9b82..33266e1b24ab 100644 --- a/drivers/scsi/lpfc/lpfc_nvme.c +++ b/drivers/scsi/lpfc/lpfc_nvme.c @@ -937,6 +937,7 @@ lpfc_nvme_io_cmd_wqe_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pwqeIn, #ifdef CONFIG_SCSI_LPFC_DEBUG_FS int cpu; #endif + int offline = 0; /* Sanity check on return of outstanding command */ if (!lpfc_ncmd) { @@ -1098,11 +1099,12 @@ out_err: nCmd->transferred_length = 0; nCmd->rcv_rsplen = 0; nCmd->status = NVME_SC_INTERNAL; + offline = pci_channel_offline(vport->phba->pcidev); } } /* pick up SLI4 exhange busy condition */ - if (bf_get(lpfc_wcqe_c_xb, wcqe)) + if (bf_get(lpfc_wcqe_c_xb, wcqe) && !offline) lpfc_ncmd->flags |= LPFC_SBUF_XBUSY; else lpfc_ncmd->flags &= ~LPFC_SBUF_XBUSY; @@ -2169,6 +2171,10 @@ lpfc_nvme_lport_unreg_wait(struct lpfc_vport *vport, abts_nvme = 0; for (i = 0; i < phba->cfg_hdw_queue; i++) { qp = &phba->sli4_hba.hdwq[i]; + if (!vport || !vport->localport || + !qp || !qp->io_wq) + return; + pring = qp->io_wq->pring; if (!pring) continue; @@ -2176,6 +2182,10 @@ lpfc_nvme_lport_unreg_wait(struct lpfc_vport *vport, abts_scsi += qp->abts_scsi_io_bufs; abts_nvme += qp->abts_nvme_io_bufs; } + if (!vport || !vport->localport || + vport->phba->hba_flag & HBA_PCI_ERR) + return; + lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT, "6176 Lport x%px Localport x%px wait " "timed out. Pending %d [%d:%d]. " @@ -2215,6 +2225,8 @@ lpfc_nvme_destroy_localport(struct lpfc_vport *vport) return; localport = vport->localport; + if (!localport) + return; lport = (struct lpfc_nvme_lport *)localport->private; lpfc_printf_vlog(vport, KERN_INFO, LOG_NVME, @@ -2531,7 +2543,8 @@ lpfc_nvme_unregister_port(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) * return values is ignored. The upcall is a courtesy to the * transport. */ - if (vport->load_flag & FC_UNLOADING) + if (vport->load_flag & FC_UNLOADING || + unlikely(vport->phba->hba_flag & HBA_PCI_ERR)) (void)nvme_fc_set_remoteport_devloss(remoteport, 0); ret = nvme_fc_unregister_remoteport(remoteport); @@ -2559,6 +2572,42 @@ lpfc_nvme_unregister_port(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) vport->localport, ndlp->rport, ndlp->nlp_DID); } +/** + * lpfc_sli4_nvme_pci_offline_aborted - Fast-path process of NVME xri abort + * @phba: pointer to lpfc hba data structure. + * @lpfc_ncmd: The nvme job structure for the request being aborted. + * + * This routine is invoked by the worker thread to process a SLI4 fast-path + * NVME aborted xri. Aborted NVME IO commands are completed to the transport + * here. + **/ +void +lpfc_sli4_nvme_pci_offline_aborted(struct lpfc_hba *phba, + struct lpfc_io_buf *lpfc_ncmd) +{ + struct nvmefc_fcp_req *nvme_cmd = NULL; + + lpfc_printf_log(phba, KERN_INFO, LOG_NVME_ABTS, + "6533 %s nvme_cmd %p tag x%x abort complete and " + "xri released\n", __func__, + lpfc_ncmd->nvmeCmd, + lpfc_ncmd->cur_iocbq.iotag); + + /* Aborted NVME commands are required to not complete + * before the abort exchange command fully completes. + * Once completed, it is available via the put list. + */ + if (lpfc_ncmd->nvmeCmd) { + nvme_cmd = lpfc_ncmd->nvmeCmd; + nvme_cmd->transferred_length = 0; + nvme_cmd->rcv_rsplen = 0; + nvme_cmd->status = NVME_SC_INTERNAL; + nvme_cmd->done(nvme_cmd); + lpfc_ncmd->nvmeCmd = NULL; + } + lpfc_release_nvme_buf(phba, lpfc_ncmd); +} + /** * lpfc_sli4_nvme_xri_aborted - Fast-path process of NVME xri abort * @phba: pointer to lpfc hba data structure. diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c index 0fde1e874c7a..b70f71b5c1f7 100644 --- a/drivers/scsi/lpfc/lpfc_scsi.c +++ b/drivers/scsi/lpfc/lpfc_scsi.c @@ -493,8 +493,8 @@ void lpfc_sli4_io_xri_aborted(struct lpfc_hba *phba, struct sli4_wcqe_xri_aborted *axri, int idx) { - uint16_t xri = bf_get(lpfc_wcqe_xa_xri, axri); - uint16_t rxid = bf_get(lpfc_wcqe_xa_remote_xid, axri); + u16 xri = 0; + u16 rxid = 0; struct lpfc_io_buf *psb, *next_psb; struct lpfc_sli4_hdw_queue *qp; unsigned long iflag = 0; @@ -504,15 +504,22 @@ lpfc_sli4_io_xri_aborted(struct lpfc_hba *phba, int rrq_empty = 0; struct lpfc_sli_ring *pring = phba->sli4_hba.els_wq->pring; struct scsi_cmnd *cmd; + int offline = 0; if (!(phba->cfg_enable_fc4_type & LPFC_ENABLE_FCP)) return; - + offline = pci_channel_offline(phba->pcidev); + if (!offline) { + xri = bf_get(lpfc_wcqe_xa_xri, axri); + rxid = bf_get(lpfc_wcqe_xa_remote_xid, axri); + } qp = &phba->sli4_hba.hdwq[idx]; spin_lock_irqsave(&phba->hbalock, iflag); spin_lock(&qp->abts_io_buf_list_lock); list_for_each_entry_safe(psb, next_psb, &qp->lpfc_abts_io_buf_list, list) { + if (offline) + xri = psb->cur_iocbq.sli4_xritag; if (psb->cur_iocbq.sli4_xritag == xri) { list_del_init(&psb->list); psb->flags &= ~LPFC_SBUF_XBUSY; @@ -521,8 +528,15 @@ lpfc_sli4_io_xri_aborted(struct lpfc_hba *phba, qp->abts_nvme_io_bufs--; spin_unlock(&qp->abts_io_buf_list_lock); spin_unlock_irqrestore(&phba->hbalock, iflag); - lpfc_sli4_nvme_xri_aborted(phba, axri, psb); - return; + if (!offline) { + lpfc_sli4_nvme_xri_aborted(phba, axri, + psb); + return; + } + lpfc_sli4_nvme_pci_offline_aborted(phba, psb); + spin_lock_irqsave(&phba->hbalock, iflag); + spin_lock(&qp->abts_io_buf_list_lock); + continue; } qp->abts_scsi_io_bufs--; spin_unlock(&qp->abts_io_buf_list_lock); @@ -534,13 +548,13 @@ lpfc_sli4_io_xri_aborted(struct lpfc_hba *phba, rrq_empty = list_empty(&phba->active_rrq_list); spin_unlock_irqrestore(&phba->hbalock, iflag); - if (ndlp) { + if (ndlp && !offline) { lpfc_set_rrq_active(phba, ndlp, psb->cur_iocbq.sli4_lxritag, rxid, 1); lpfc_sli4_abts_err_handler(phba, ndlp, axri); } - if (phba->cfg_fcp_wait_abts_rsp) { + if (phba->cfg_fcp_wait_abts_rsp || offline) { spin_lock_irqsave(&psb->buf_lock, iflag); cmd = psb->pCmd; psb->pCmd = NULL; @@ -567,25 +581,30 @@ lpfc_sli4_io_xri_aborted(struct lpfc_hba *phba, lpfc_release_scsi_buf_s4(phba, psb); if (rrq_empty) lpfc_worker_wake_up(phba); - return; + if (!offline) + return; + spin_lock_irqsave(&phba->hbalock, iflag); + spin_lock(&qp->abts_io_buf_list_lock); + continue; } } spin_unlock(&qp->abts_io_buf_list_lock); - for (i = 1; i <= phba->sli.last_iotag; i++) { - iocbq = phba->sli.iocbq_lookup[i]; - - if (!(iocbq->iocb_flag & LPFC_IO_FCP) || - (iocbq->iocb_flag & LPFC_IO_LIBDFC)) - continue; - if (iocbq->sli4_xritag != xri) - continue; - psb = container_of(iocbq, struct lpfc_io_buf, cur_iocbq); - psb->flags &= ~LPFC_SBUF_XBUSY; - spin_unlock_irqrestore(&phba->hbalock, iflag); - if (!list_empty(&pring->txq)) - lpfc_worker_wake_up(phba); - return; + if (!offline) { + for (i = 1; i <= phba->sli.last_iotag; i++) { + iocbq = phba->sli.iocbq_lookup[i]; + if (!(iocbq->iocb_flag & LPFC_IO_FCP) || + (iocbq->iocb_flag & LPFC_IO_LIBDFC)) + continue; + if (iocbq->sli4_xritag != xri) + continue; + psb = container_of(iocbq, struct lpfc_io_buf, cur_iocbq); + psb->flags &= ~LPFC_SBUF_XBUSY; + spin_unlock_irqrestore(&phba->hbalock, iflag); + if (!list_empty(&pring->txq)) + lpfc_worker_wake_up(phba); + return; + } } spin_unlock_irqrestore(&phba->hbalock, iflag); } diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index e8f6ad484768..651e6ee64e88 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c @@ -1404,7 +1404,8 @@ __lpfc_sli_release_iocbq_s4(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq) } if ((iocbq->iocb_flag & LPFC_EXCHANGE_BUSY) && - (sglq->state != SGL_XRI_ABORTED)) { + (!(unlikely(pci_channel_offline(phba->pcidev)))) && + sglq->state != SGL_XRI_ABORTED) { spin_lock_irqsave(&phba->sli4_hba.sgl_list_lock, iflag); @@ -4583,10 +4584,12 @@ lpfc_sli_flush_io_rings(struct lpfc_hba *phba) lpfc_sli_cancel_iocbs(phba, &txq, IOSTAT_LOCAL_REJECT, IOERR_SLI_DOWN); - /* Flush the txcmpq */ + /* Flush the txcmplq */ lpfc_sli_cancel_iocbs(phba, &txcmplq, IOSTAT_LOCAL_REJECT, IOERR_SLI_DOWN); + if (unlikely(pci_channel_offline(phba->pcidev))) + lpfc_sli4_io_xri_aborted(phba, NULL, 0); } } else { pring = &psli->sli3_ring[LPFC_FCP_RING]; @@ -22019,8 +22022,26 @@ lpfc_get_io_buf_from_multixri_pools(struct lpfc_hba *phba, qp = &phba->sli4_hba.hdwq[hwqid]; lpfc_ncmd = NULL; + if (!qp) { + lpfc_printf_log(phba, KERN_INFO, + LOG_SLI | LOG_NVME_ABTS | LOG_FCP, + "5556 NULL qp for hwqid x%x\n", hwqid); + return lpfc_ncmd; + } multixri_pool = qp->p_multixri_pool; + if (!multixri_pool) { + lpfc_printf_log(phba, KERN_INFO, + LOG_SLI | LOG_NVME_ABTS | LOG_FCP, + "5557 NULL multixri for hwqid x%x\n", hwqid); + return lpfc_ncmd; + } pvt_pool = &multixri_pool->pvt_pool; + if (!pvt_pool) { + lpfc_printf_log(phba, KERN_INFO, + LOG_SLI | LOG_NVME_ABTS | LOG_FCP, + "5558 NULL pvt_pool for hwqid x%x\n", hwqid); + return lpfc_ncmd; + } multixri_pool->io_req_count++; /* If pvt_pool is empty, move some XRIs from public to private pool */ @@ -22096,6 +22117,12 @@ struct lpfc_io_buf *lpfc_get_io_buf(struct lpfc_hba *phba, qp = &phba->sli4_hba.hdwq[hwqid]; lpfc_cmd = NULL; + if (!qp) { + lpfc_printf_log(phba, KERN_WARNING, + LOG_SLI | LOG_NVME_ABTS | LOG_FCP, + "5555 NULL qp for hwqid x%x\n", hwqid); + return lpfc_cmd; + } if (phba->cfg_xri_rebalancing) lpfc_cmd = lpfc_get_io_buf_from_multixri_pools( diff --git a/drivers/scsi/lpfc/lpfc_sli4.h b/drivers/scsi/lpfc/lpfc_sli4.h index 99c5d1e4da5e..5962cf508842 100644 --- a/drivers/scsi/lpfc/lpfc_sli4.h +++ b/drivers/scsi/lpfc/lpfc_sli4.h @@ -1116,6 +1116,8 @@ void lpfc_sli4_fcf_redisc_event_proc(struct lpfc_hba *); int lpfc_sli4_resume_rpi(struct lpfc_nodelist *, void (*)(struct lpfc_hba *, LPFC_MBOXQ_t *), void *); void lpfc_sli4_els_xri_abort_event_proc(struct lpfc_hba *phba); +void lpfc_sli4_nvme_pci_offline_aborted(struct lpfc_hba *phba, + struct lpfc_io_buf *lpfc_ncmd); void lpfc_sli4_nvme_xri_aborted(struct lpfc_hba *phba, struct sli4_wcqe_xri_aborted *axri, struct lpfc_io_buf *lpfc_ncmd); From d5ac69b332d8859d1f8bd5d4dee31f3267f6b0d2 Mon Sep 17 00:00:00 2001 From: James Smart Date: Fri, 10 Sep 2021 16:31:55 -0700 Subject: [PATCH 032/279] scsi: lpfc: Adjust bytes received vales during cmf timer interval The newly added congestion mgmt framework is seeing unexpected congestion FPINs and signals. In analysis, time values given to the adapter are not at hard time intervals. Thus the drift vs the transfer count seen is affecting how the framework manages things. Adjust counters to cover the drift. Link: https://lore.kernel.org/r/20210910233159.115896-11-jsmart2021@gmail.com Co-developed-by: Justin Tee Signed-off-by: Justin Tee Signed-off-by: James Smart Signed-off-by: Martin K. Petersen --- drivers/scsi/lpfc/lpfc_init.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index 3fd730613de3..d3a2281cb48b 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c @@ -5876,7 +5876,7 @@ lpfc_cmf_timer(struct hrtimer *timer) uint32_t io_cnt; uint32_t head, tail; uint32_t busy, max_read; - uint64_t total, rcv, lat, mbpi; + uint64_t total, rcv, lat, mbpi, extra; int timer_interval = LPFC_CMF_INTERVAL; uint32_t ms; struct lpfc_cgn_stat *cgs; @@ -5943,7 +5943,19 @@ lpfc_cmf_timer(struct hrtimer *timer) phba->hba_flag & HBA_SETUP) { mbpi = phba->cmf_last_sync_bw; phba->cmf_last_sync_bw = 0; - lpfc_issue_cmf_sync_wqe(phba, LPFC_CMF_INTERVAL, total); + extra = 0; + + /* Calculate any extra bytes needed to account for the + * timer accuracy. If we are less than LPFC_CMF_INTERVAL + * add an extra 3% slop factor, equal to LPFC_CMF_INTERVAL + * add an extra 2%. The goal is to equalize total with a + * time > LPFC_CMF_INTERVAL or <= LPFC_CMF_INTERVAL + 1 + */ + if (ms == LPFC_CMF_INTERVAL) + extra = div_u64(total, 50); + else if (ms < LPFC_CMF_INTERVAL) + extra = div_u64(total, 33); + lpfc_issue_cmf_sync_wqe(phba, LPFC_CMF_INTERVAL, total + extra); } else { /* For Monitor mode or link down we want mbpi * to be the full link speed From 3ea998cbf9e781b6d16250fab1e6121dce32790b Mon Sep 17 00:00:00 2001 From: James Smart Date: Fri, 10 Sep 2021 16:31:56 -0700 Subject: [PATCH 033/279] scsi: lpfc: Fix I/O block after enabling managed congestion mode If the congestion management framework dynamically enables, it may do so while I/O is in flight. The updates of cmf info due to inflight I/O completing may happen before values have been initialized. Fix by ensure cmf_max_bytes_per_interval is initialized when checking bandwidth utilization for SCSI layer blocking. Link: https://lore.kernel.org/r/20210910233159.115896-12-jsmart2021@gmail.com Co-developed-by: Justin Tee Signed-off-by: Justin Tee Signed-off-by: James Smart Signed-off-by: Martin K. Petersen --- drivers/scsi/lpfc/lpfc_scsi.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c index b70f71b5c1f7..a2cd22728b0f 100644 --- a/drivers/scsi/lpfc/lpfc_scsi.c +++ b/drivers/scsi/lpfc/lpfc_scsi.c @@ -3961,7 +3961,8 @@ lpfc_update_cmf_cmd(struct lpfc_hba *phba, uint32_t size) int cpu; /* At this point we are either LPFC_CFG_MANAGED or LPFC_CFG_MONITOR */ - if (phba->cmf_active_mode == LPFC_CFG_MANAGED) { + if (phba->cmf_active_mode == LPFC_CFG_MANAGED && + phba->cmf_max_bytes_per_interval) { total = 0; for_each_present_cpu(cpu) { cgs = per_cpu_ptr(phba->cmf_stat, cpu); From afd63fa511494d7215120be7d25c20502aed4d89 Mon Sep 17 00:00:00 2001 From: James Smart Date: Fri, 10 Sep 2021 16:31:57 -0700 Subject: [PATCH 034/279] scsi: lpfc: Zero CGN stats only during initial driver load and stat reset Currently congestion management framework results are cleared whenever the framework settings changed (such as it being turned off then back on). This unfortunately means prior stats, rolled up to higher time windows lose meaning. Change such that stats are not cleared. Thus they pause and resume with prior values still being considered. Link: https://lore.kernel.org/r/20210910233159.115896-13-jsmart2021@gmail.com Co-developed-by: Justin Tee Signed-off-by: Justin Tee Signed-off-by: James Smart Signed-off-by: Martin K. Petersen --- drivers/scsi/lpfc/lpfc_init.c | 2 -- drivers/scsi/lpfc/lpfc_sli.c | 6 ++++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index d3a2281cb48b..ff2a4e387523 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c @@ -13394,8 +13394,6 @@ lpfc_init_congestion_buf(struct lpfc_hba *phba) atomic_set(&phba->cgn_sync_alarm_cnt, 0); atomic_set(&phba->cgn_sync_warn_cnt, 0); - atomic64_set(&phba->cgn_acqe_stat.alarm, 0); - atomic64_set(&phba->cgn_acqe_stat.warn, 0); atomic_set(&phba->cgn_driver_evt_cnt, 0); atomic_set(&phba->cgn_latency_evt_cnt, 0); atomic64_set(&phba->cgn_latency_evt, 0); diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index 651e6ee64e88..34cf2bfcce07 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c @@ -7764,8 +7764,6 @@ lpfc_mbx_cmpl_cgn_set_ftrs(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) /* Zero out Congestion Signal ACQE counter */ phba->cgn_acqe_cnt = 0; - atomic64_set(&phba->cgn_acqe_stat.warn, 0); - atomic64_set(&phba->cgn_acqe_stat.alarm, 0); acqe = bf_get(lpfc_mbx_set_feature_CGN_acqe_freq, &pmb->u.mqe.un.set_feature); @@ -8017,6 +8015,10 @@ lpfc_cmf_setup(struct lpfc_hba *phba) /* initialize congestion buffer info */ lpfc_init_congestion_buf(phba); lpfc_init_congestion_stat(phba); + + /* Zero out Congestion Signal counters */ + atomic64_set(&phba->cgn_acqe_stat.alarm, 0); + atomic64_set(&phba->cgn_acqe_stat.warn, 0); } rc = lpfc_sli4_cgn_params_read(phba); From 315b3fd13521fb44d97572eb24b7c8670ec7fd97 Mon Sep 17 00:00:00 2001 From: James Smart Date: Fri, 10 Sep 2021 16:31:58 -0700 Subject: [PATCH 035/279] scsi: lpfc: Improve PBDE checks during SGL processing The PBDE feature, setting payload buffer address explicitly in the WQE so it doesn't have to be fetched from the SGL, only makes sense when there is a single buffer for the I/O. When there are multiple buffers it actually hurts performance as the SGL subsequently has to be fetched. Rework the SGL logic to only use PBDE when a single buffer. Link: https://lore.kernel.org/r/20210910233159.115896-14-jsmart2021@gmail.com Co-developed-by: Justin Tee Signed-off-by: Justin Tee Signed-off-by: James Smart Signed-off-by: Martin K. Petersen --- drivers/scsi/lpfc/lpfc_nvme.c | 12 +++++----- drivers/scsi/lpfc/lpfc_nvmet.c | 44 ++++++++++++++++------------------ drivers/scsi/lpfc/lpfc_scsi.c | 26 ++++++++++---------- 3 files changed, 40 insertions(+), 42 deletions(-) diff --git a/drivers/scsi/lpfc/lpfc_nvme.c b/drivers/scsi/lpfc/lpfc_nvme.c index 33266e1b24ab..69d3758dd8dc 100644 --- a/drivers/scsi/lpfc/lpfc_nvme.c +++ b/drivers/scsi/lpfc/lpfc_nvme.c @@ -1299,7 +1299,6 @@ lpfc_nvme_prep_io_dma(struct lpfc_vport *vport, struct sli4_sge *first_data_sgl; struct ulp_bde64 *bde; dma_addr_t physaddr = 0; - uint32_t num_bde = 0; uint32_t dma_len = 0; uint32_t dma_offset = 0; int nseg, i, j; @@ -1353,7 +1352,7 @@ lpfc_nvme_prep_io_dma(struct lpfc_vport *vport, } sgl->word2 = 0; - if ((num_bde + 1) == nseg) { + if (nseg == 1) { bf_set(lpfc_sli4_sge_last, sgl, 1); bf_set(lpfc_sli4_sge_type, sgl, LPFC_SGE_TYPE_DATA); @@ -1422,8 +1421,9 @@ lpfc_nvme_prep_io_dma(struct lpfc_vport *vport, j++; } - if (phba->cfg_enable_pbde) { - /* Use PBDE support for first SGL only, offset == 0 */ + + /* PBDE support for first data SGE only */ + if (nseg == 1 && phba->cfg_enable_pbde) { /* Words 13-15 */ bde = (struct ulp_bde64 *) &wqe->words[13]; @@ -1434,11 +1434,11 @@ lpfc_nvme_prep_io_dma(struct lpfc_vport *vport, bde->tus.f.bdeFlags = BUFF_TYPE_BDE_64; bde->tus.w = cpu_to_le32(bde->tus.w); - /* Word 11 */ + /* Word 11 - set PBDE bit */ bf_set(wqe_pbde, &wqe->generic.wqe_com, 1); } else { memset(&wqe->words[13], 0, (sizeof(uint32_t) * 3)); - bf_set(wqe_pbde, &wqe->generic.wqe_com, 0); + /* Word 11 - PBDE bit disabled by default template */ } } else { diff --git a/drivers/scsi/lpfc/lpfc_nvmet.c b/drivers/scsi/lpfc/lpfc_nvmet.c index 6e3dd0b9bcfa..731802527b81 100644 --- a/drivers/scsi/lpfc/lpfc_nvmet.c +++ b/drivers/scsi/lpfc/lpfc_nvmet.c @@ -2708,7 +2708,7 @@ lpfc_nvmet_prep_fcp_wqe(struct lpfc_hba *phba, struct ulp_bde64 *bde; dma_addr_t physaddr; int i, cnt, nsegs; - int do_pbde; + bool use_pbde = false; int xc = 1; if (!lpfc_is_link_up(phba)) { @@ -2816,9 +2816,6 @@ lpfc_nvmet_prep_fcp_wqe(struct lpfc_hba *phba, if (!xc) bf_set(wqe_xc, &wqe->fcp_tsend.wqe_com, 0); - /* Word 11 - set sup, irsp, irsplen later */ - do_pbde = 0; - /* Word 12 */ wqe->fcp_tsend.fcp_data_len = rsp->transfer_length; @@ -2896,12 +2893,13 @@ lpfc_nvmet_prep_fcp_wqe(struct lpfc_hba *phba, if (!xc) bf_set(wqe_xc, &wqe->fcp_treceive.wqe_com, 0); - /* Word 11 - set pbde later */ - if (phba->cfg_enable_pbde) { - do_pbde = 1; + /* Word 11 - check for pbde */ + if (nsegs == 1 && phba->cfg_enable_pbde) { + use_pbde = true; + /* Word 11 - PBDE bit already preset by template */ } else { + /* Overwrite default template setting */ bf_set(wqe_pbde, &wqe->fcp_treceive.wqe_com, 0); - do_pbde = 0; } /* Word 12 */ @@ -2972,7 +2970,6 @@ lpfc_nvmet_prep_fcp_wqe(struct lpfc_hba *phba, ((rsp->rsplen >> 2) - 1)); memcpy(&wqe->words[16], rsp->rspaddr, rsp->rsplen); } - do_pbde = 0; /* Word 12 */ wqe->fcp_trsp.rsvd_12_15[0] = 0; @@ -3007,23 +3004,24 @@ lpfc_nvmet_prep_fcp_wqe(struct lpfc_hba *phba, bf_set(lpfc_sli4_sge_last, sgl, 1); sgl->word2 = cpu_to_le32(sgl->word2); sgl->sge_len = cpu_to_le32(cnt); - if (i == 0) { - bde = (struct ulp_bde64 *)&wqe->words[13]; - if (do_pbde) { - /* Words 13-15 (PBDE) */ - bde->addrLow = sgl->addr_lo; - bde->addrHigh = sgl->addr_hi; - bde->tus.f.bdeSize = - le32_to_cpu(sgl->sge_len); - bde->tus.f.bdeFlags = BUFF_TYPE_BDE_64; - bde->tus.w = cpu_to_le32(bde->tus.w); - } else { - memset(bde, 0, sizeof(struct ulp_bde64)); - } - } sgl++; ctxp->offset += cnt; } + + bde = (struct ulp_bde64 *)&wqe->words[13]; + if (use_pbde) { + /* decrement sgl ptr backwards once to first data sge */ + sgl--; + + /* Words 13-15 (PBDE) */ + bde->addrLow = sgl->addr_lo; + bde->addrHigh = sgl->addr_hi; + bde->tus.f.bdeSize = le32_to_cpu(sgl->sge_len); + bde->tus.f.bdeFlags = BUFF_TYPE_BDE_64; + bde->tus.w = cpu_to_le32(bde->tus.w); + } else { + memset(bde, 0, sizeof(struct ulp_bde64)); + } ctxp->state = LPFC_NVME_STE_DATA; ctxp->entry_cnt++; return nvmewqe; diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c index a2cd22728b0f..078fbea3f436 100644 --- a/drivers/scsi/lpfc/lpfc_scsi.c +++ b/drivers/scsi/lpfc/lpfc_scsi.c @@ -3235,7 +3235,6 @@ lpfc_scsi_prep_dma_buf_s4(struct lpfc_hba *phba, struct lpfc_io_buf *lpfc_cmd) struct lpfc_vport *vport = phba->pport; union lpfc_wqe128 *wqe = &pwqeq->wqe; dma_addr_t physaddr; - uint32_t num_bde = 0; uint32_t dma_len; uint32_t dma_offset = 0; int nseg, i, j; @@ -3297,7 +3296,7 @@ lpfc_scsi_prep_dma_buf_s4(struct lpfc_hba *phba, struct lpfc_io_buf *lpfc_cmd) j = 2; for (i = 0; i < nseg; i++) { sgl->word2 = 0; - if ((num_bde + 1) == nseg) { + if (nseg == 1) { bf_set(lpfc_sli4_sge_last, sgl, 1); bf_set(lpfc_sli4_sge_type, sgl, LPFC_SGE_TYPE_DATA); @@ -3366,13 +3365,15 @@ lpfc_scsi_prep_dma_buf_s4(struct lpfc_hba *phba, struct lpfc_io_buf *lpfc_cmd) j++; } - /* - * Setup the first Payload BDE. For FCoE we just key off - * Performance Hints, for FC we use lpfc_enable_pbde. - * We populate words 13-15 of IOCB/WQE. + + /* PBDE support for first data SGE only. + * For FCoE, we key off Performance Hints. + * For FC, we key off lpfc_enable_pbde. */ - if ((phba->sli3_options & LPFC_SLI4_PERFH_ENABLED) || - phba->cfg_enable_pbde) { + if (nseg == 1 && + ((phba->sli3_options & LPFC_SLI4_PERFH_ENABLED) || + phba->cfg_enable_pbde)) { + /* Words 13-15 */ bde = (struct ulp_bde64 *) &wqe->words[13]; bde->addrLow = first_data_sgl->addr_lo; @@ -3382,12 +3383,15 @@ lpfc_scsi_prep_dma_buf_s4(struct lpfc_hba *phba, struct lpfc_io_buf *lpfc_cmd) bde->tus.f.bdeFlags = BUFF_TYPE_BDE_64; bde->tus.w = cpu_to_le32(bde->tus.w); + /* Word 11 - set PBDE bit */ + bf_set(wqe_pbde, &wqe->generic.wqe_com, 1); } else { memset(&wqe->words[13], 0, (sizeof(uint32_t) * 3)); + /* Word 11 - PBDE bit disabled by default template */ } } else { sgl += 1; - /* clear the last flag in the fcp_rsp map entry */ + /* set the last flag in the fcp_rsp map entry */ sgl->word2 = le32_to_cpu(sgl->word2); bf_set(lpfc_sli4_sge_last, sgl, 1); sgl->word2 = cpu_to_le32(sgl->word2); @@ -3400,10 +3404,6 @@ lpfc_scsi_prep_dma_buf_s4(struct lpfc_hba *phba, struct lpfc_io_buf *lpfc_cmd) } } - /* Word 11 */ - if (phba->cfg_enable_pbde) - bf_set(wqe_pbde, &wqe->generic.wqe_com, 1); - /* * Finish initializing those IOCB fields that are dependent on the * scsi_cmnd request_buffer. Note that for SLI-2 the bdeSize is From 0d6b26795bd2b9f1d7f0d43a21a386438586bc69 Mon Sep 17 00:00:00 2001 From: James Smart Date: Fri, 10 Sep 2021 16:31:59 -0700 Subject: [PATCH 036/279] scsi: lpfc: Update lpfc version to 14.0.0.2 Update lpfc version to 14.0.0.2. Link: https://lore.kernel.org/r/20210910233159.115896-15-jsmart2021@gmail.com Co-developed-by: Justin Tee Signed-off-by: Justin Tee Signed-off-by: James Smart Signed-off-by: Martin K. Petersen --- drivers/scsi/lpfc/lpfc_version.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/lpfc/lpfc_version.h b/drivers/scsi/lpfc/lpfc_version.h index a7aba7833425..dec71775f677 100644 --- a/drivers/scsi/lpfc/lpfc_version.h +++ b/drivers/scsi/lpfc/lpfc_version.h @@ -20,7 +20,7 @@ * included with this package. * *******************************************************************/ -#define LPFC_DRIVER_VERSION "14.0.0.1" +#define LPFC_DRIVER_VERSION "14.0.0.2" #define LPFC_DRIVER_NAME "lpfc" /* Used for SLI 2/3 */ From 0a5e20fc8ca7ed10b8865421a7c1e8d460840956 Mon Sep 17 00:00:00 2001 From: Len Baker Date: Sun, 5 Sep 2021 08:24:48 +0200 Subject: [PATCH 037/279] scsi: elx: libefc: Prefer kcalloc() over open coded arithmetic As noted in the "Deprecated Interfaces, Language Features, Attributes, and Conventions" documentation [1], size calculations (especially multiplication) should not be performed in memory allocator (or similar) function arguments due to the risk of them overflowing. This could lead to values wrapping around and a smaller allocation being made than the caller was expecting. Using those allocations could lead to linear overflows of heap memory and other misbehaviors. Use the purpose specific kcalloc() function instead of the argument count * size in the kzalloc() function. [1] https://www.kernel.org/doc/html/v5.14/process/deprecated.html#open-coded-arithmetic-in-allocator-arguments Link: https://lore.kernel.org/r/20210905062448.6587-1-len.baker@gmx.com Reviewed-by: James Smart Signed-off-by: Len Baker Signed-off-by: Martin K. Petersen --- drivers/scsi/elx/libefc/efc_fabric.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/elx/libefc/efc_fabric.c b/drivers/scsi/elx/libefc/efc_fabric.c index d397220d9e54..f9412437ad47 100644 --- a/drivers/scsi/elx/libefc/efc_fabric.c +++ b/drivers/scsi/elx/libefc/efc_fabric.c @@ -686,7 +686,7 @@ efc_process_gidpt_payload(struct efc_node *node, } /* Allocate a buffer for all nodes */ - active_nodes = kzalloc(port_count * sizeof(*active_nodes), GFP_ATOMIC); + active_nodes = kcalloc(port_count, sizeof(*active_nodes), GFP_ATOMIC); if (!active_nodes) { node_printf(node, "efc_malloc failed\n"); return -EIO; From e9d73bfa8e047fbb078213e607019c701cd9f888 Mon Sep 17 00:00:00 2001 From: Muneendra Kumar Date: Sun, 12 Sep 2021 18:58:53 -0700 Subject: [PATCH 038/279] scsi: documentation: Document Fibre Channel sysfs node for appid Update documentation for sysfs node within /sys/class/fc/fc_udev_device/. Link: https://lore.kernel.org/r/20210913015853.2086512-1-muneendra.kumar@broadcom.com Reviewed-by: Himanshu Madhani Signed-off-by: Muneendra Kumar Signed-off-by: Martin K. Petersen --- Documentation/ABI/testing/sysfs-class-fc | 27 ++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 Documentation/ABI/testing/sysfs-class-fc diff --git a/Documentation/ABI/testing/sysfs-class-fc b/Documentation/ABI/testing/sysfs-class-fc new file mode 100644 index 000000000000..3057a6d3b8cf --- /dev/null +++ b/Documentation/ABI/testing/sysfs-class-fc @@ -0,0 +1,27 @@ +What: /sys/class/fc/fc_udev_device/appid_store +Date: Aug 2021 +Contact: Muneendra Kumar +Description: + This interface allows an admin to set an FC application + identifier in the blkcg associated with a cgroup id. The + identifier is typically a UUID that is associated with + an application or logical entity such as a virtual + machine or container group. The application or logical + entity utilizes a block device via the cgroup id. + FC adapter drivers may query the identifier and tag FC + traffic based on the identifier. FC host and FC fabric + entities can utilize the application id and FC traffic + tag to identify traffic sources. + + The interface expects a string ":" where: + is inode of the cgroup in hexadecimal + is user provided string upto 128 characters + in length. + + If an appid_store is done for a cgroup id that already + has an appid set, the new value will override the + previous value. + + If an admin wants to remove an FC application identifier + from a cgroup, an appid_store should be done with the + following string: ":" From c4adf171e834dab8ca72676ca7264c5b50a542a8 Mon Sep 17 00:00:00 2001 From: ChanWoo Lee Date: Tue, 7 Sep 2021 13:41:11 +0900 Subject: [PATCH 039/279] scsi: ufs: ufs-qcom: Remove unneeded variable 'err' 'err' is never set in this functon. Remove the declaration and just return 0. Link: https://lore.kernel.org/r/20210907044111.29632-1-cw9316.lee@samsung.com Signed-off-by: ChanWoo Lee Signed-off-by: Martin K. Petersen --- drivers/scsi/ufs/ufs-qcom.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/scsi/ufs/ufs-qcom.c b/drivers/scsi/ufs/ufs-qcom.c index 9d9770f1db4f..92d4c61fc9d0 100644 --- a/drivers/scsi/ufs/ufs-qcom.c +++ b/drivers/scsi/ufs/ufs-qcom.c @@ -888,7 +888,6 @@ static int ufs_qcom_setup_clocks(struct ufs_hba *hba, bool on, enum ufs_notify_change_status status) { struct ufs_qcom_host *host = ufshcd_get_variant(hba); - int err = 0; /* * In case ufs_qcom_init() is not yet done, simply ignore. @@ -916,7 +915,7 @@ static int ufs_qcom_setup_clocks(struct ufs_hba *hba, bool on, break; } - return err; + return 0; } static int From 351b3a849ac7d92449dc75c43db8a857b38387ea Mon Sep 17 00:00:00 2001 From: Daejun Park Date: Thu, 2 Sep 2021 09:35:34 +0900 Subject: [PATCH 040/279] scsi: ufs: ufshpb: Use proper power management API In ufshpb, pm_runtime_{get,put}_sync() are used to avoid unwanted runtime suspend during query requests. Whereas commit b294ff3e3449 ("scsi: ufs: core: Enable power management for wlun") modified the driver core to use ufshcd_rpm_{get,put}_sync() APIs. Switch to these APIs in HPB module as well. Link: https://lore.kernel.org/r/20210902003534epcms2p1937a0f0eeb48a441cb69f5ef13ff8430@epcms2p1 Reviewed-by: Avri Altman Signed-off-by: Daejun Park Signed-off-by: Martin K. Petersen --- drivers/scsi/ufs/ufshpb.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/scsi/ufs/ufshpb.c b/drivers/scsi/ufs/ufshpb.c index 02fb51ae8b25..9ea639bf6a59 100644 --- a/drivers/scsi/ufs/ufshpb.c +++ b/drivers/scsi/ufs/ufshpb.c @@ -2650,11 +2650,11 @@ static int ufshpb_get_lu_info(struct ufs_hba *hba, int lun, ufshcd_map_desc_id_to_length(hba, QUERY_DESC_IDN_UNIT, &size); - pm_runtime_get_sync(hba->dev); + ufshcd_rpm_get_sync(hba); ret = ufshcd_query_descriptor_retry(hba, UPIU_QUERY_OPCODE_READ_DESC, QUERY_DESC_IDN_UNIT, lun, 0, desc_buf, &size); - pm_runtime_put_sync(hba->dev); + ufshcd_rpm_put_sync(hba); if (ret) { dev_err(hba->dev, @@ -2877,10 +2877,10 @@ void ufshpb_get_dev_info(struct ufs_hba *hba, u8 *desc_buf) if (version == HPB_SUPPORT_LEGACY_VERSION) hpb_dev_info->is_legacy = true; - pm_runtime_get_sync(hba->dev); + ufshcd_rpm_get_sync(hba); ret = ufshcd_query_attr_retry(hba, UPIU_QUERY_OPCODE_READ_ATTR, QUERY_ATTR_IDN_MAX_HPB_SINGLE_CMD, 0, 0, &max_hpb_single_cmd); - pm_runtime_put_sync(hba->dev); + ufshcd_rpm_put_sync(hba); if (ret) dev_err(hba->dev, "%s: idn: read max size of single hpb cmd query request failed", From aba3b0757b6cba37953bb1d7e71c460d37fd496a Mon Sep 17 00:00:00 2001 From: Peter Wang Date: Mon, 6 Sep 2021 16:53:07 +0800 Subject: [PATCH 041/279] scsi: ufs: ufs-mediatek: Change dbg select by check IP version Mediatek UFS dbg select setting is changed in new IP version. Check the IP version before setting dbg select. Link: https://lore.kernel.org/r/1630918387-8333-1-git-send-email-peter.wang@mediatek.com Signed-off-by: Peter Wang Signed-off-by: Martin K. Petersen --- drivers/scsi/ufs/ufs-mediatek.c | 21 +++++++++++++++++++-- drivers/scsi/ufs/ufs-mediatek.h | 6 ++++++ 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/ufs/ufs-mediatek.c b/drivers/scsi/ufs/ufs-mediatek.c index 80b3545dd17d..d2d7e76c5ec8 100644 --- a/drivers/scsi/ufs/ufs-mediatek.c +++ b/drivers/scsi/ufs/ufs-mediatek.c @@ -296,6 +296,21 @@ static void ufs_mtk_setup_ref_clk_wait_us(struct ufs_hba *hba, host->ref_clk_ungating_wait_us = ungating_us; } +static void ufs_mtk_dbg_sel(struct ufs_hba *hba) +{ + struct ufs_mtk_host *host = ufshcd_get_variant(hba); + + if (((host->ip_ver >> 16) & 0xFF) >= 0x36) { + ufshcd_writel(hba, 0x820820, REG_UFS_DEBUG_SEL); + ufshcd_writel(hba, 0x0, REG_UFS_DEBUG_SEL_B0); + ufshcd_writel(hba, 0x55555555, REG_UFS_DEBUG_SEL_B1); + ufshcd_writel(hba, 0xaaaaaaaa, REG_UFS_DEBUG_SEL_B2); + ufshcd_writel(hba, 0xffffffff, REG_UFS_DEBUG_SEL_B3); + } else { + ufshcd_writel(hba, 0x20, REG_UFS_DEBUG_SEL); + } +} + static int ufs_mtk_wait_link_state(struct ufs_hba *hba, u32 state, unsigned long max_wait_ms) { @@ -305,7 +320,7 @@ static int ufs_mtk_wait_link_state(struct ufs_hba *hba, u32 state, timeout = ktime_add_ms(ktime_get(), max_wait_ms); do { time_checked = ktime_get(); - ufshcd_writel(hba, 0x20, REG_UFS_DEBUG_SEL); + ufs_mtk_dbg_sel(hba); val = ufshcd_readl(hba, REG_UFS_PROBE); val = val >> 28; @@ -689,6 +704,8 @@ static int ufs_mtk_init(struct ufs_hba *hba) ufs_mtk_mphy_power_on(hba, true); ufs_mtk_setup_clocks(hba, true, POST_CHANGE); + host->ip_ver = ufshcd_readl(hba, REG_UFS_MTK_IP_VER); + goto out; out_variant_clear: @@ -1001,7 +1018,7 @@ static void ufs_mtk_dbg_register_dump(struct ufs_hba *hba) "MPHY Ctrl "); /* Direct debugging information to REG_MTK_PROBE */ - ufshcd_writel(hba, 0x20, REG_UFS_DEBUG_SEL); + ufs_mtk_dbg_sel(hba); ufshcd_dump_regs(hba, REG_UFS_PROBE, 0x4, "Debug Probe "); } diff --git a/drivers/scsi/ufs/ufs-mediatek.h b/drivers/scsi/ufs/ufs-mediatek.h index 3f0d3bb769e8..524c8e2c1e6f 100644 --- a/drivers/scsi/ufs/ufs-mediatek.h +++ b/drivers/scsi/ufs/ufs-mediatek.h @@ -15,9 +15,14 @@ #define REG_UFS_REFCLK_CTRL 0x144 #define REG_UFS_EXTREG 0x2100 #define REG_UFS_MPHYCTRL 0x2200 +#define REG_UFS_MTK_IP_VER 0x2240 #define REG_UFS_REJECT_MON 0x22AC #define REG_UFS_DEBUG_SEL 0x22C0 #define REG_UFS_PROBE 0x22C8 +#define REG_UFS_DEBUG_SEL_B0 0x22D0 +#define REG_UFS_DEBUG_SEL_B1 0x22D4 +#define REG_UFS_DEBUG_SEL_B2 0x22D8 +#define REG_UFS_DEBUG_SEL_B3 0x22DC /* * Ref-clk control @@ -113,6 +118,7 @@ struct ufs_mtk_host { bool ref_clk_enabled; u16 ref_clk_ungating_wait_us; u16 ref_clk_gating_wait_us; + u32 ip_ver; }; #endif /* !_UFS_MEDIATEK_H */ From 7e642ca0375b95072ab6240c8eb9f0b4f013fb24 Mon Sep 17 00:00:00 2001 From: Li Feng Date: Mon, 13 Sep 2021 16:30:45 +0800 Subject: [PATCH 042/279] scsi: target: Remove unused function arguments The se_cmd is unused in these functions, just remove it. Link: https://lore.kernel.org/r/20210913083045.3670648-1-fengli@smartx.com Reviewed-by: Himanshu Madhani Signed-off-by: Li Feng Signed-off-by: Martin K. Petersen --- drivers/target/target_core_xcopy.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/drivers/target/target_core_xcopy.c b/drivers/target/target_core_xcopy.c index d4fe7cb2bd00..6bb20aa9c5bc 100644 --- a/drivers/target/target_core_xcopy.c +++ b/drivers/target/target_core_xcopy.c @@ -295,8 +295,7 @@ out: return -EINVAL; } -static int target_xcopy_parse_segdesc_02(struct se_cmd *se_cmd, struct xcopy_op *xop, - unsigned char *p) +static int target_xcopy_parse_segdesc_02(struct xcopy_op *xop, unsigned char *p) { unsigned char *desc = p; int dc = (desc[1] & 0x02); @@ -332,9 +331,9 @@ static int target_xcopy_parse_segdesc_02(struct se_cmd *se_cmd, struct xcopy_op return 0; } -static int target_xcopy_parse_segment_descriptors(struct se_cmd *se_cmd, - struct xcopy_op *xop, unsigned char *p, - unsigned int sdll, sense_reason_t *sense_ret) +static int target_xcopy_parse_segment_descriptors(struct xcopy_op *xop, + unsigned char *p, unsigned int sdll, + sense_reason_t *sense_ret) { unsigned char *desc = p; unsigned int start = 0; @@ -362,7 +361,7 @@ static int target_xcopy_parse_segment_descriptors(struct se_cmd *se_cmd, */ switch (desc[0]) { case 0x02: - rc = target_xcopy_parse_segdesc_02(se_cmd, xop, desc); + rc = target_xcopy_parse_segdesc_02(xop, desc); if (rc < 0) goto out; @@ -840,8 +839,7 @@ static sense_reason_t target_parse_xcopy_cmd(struct xcopy_op *xop) */ seg_desc = &p[16] + tdll; - rc = target_xcopy_parse_segment_descriptors(se_cmd, xop, seg_desc, - sdll, &ret); + rc = target_xcopy_parse_segment_descriptors(xop, seg_desc, sdll, &ret); if (rc <= 0) goto out; From a7c0520669869c088dc207735c2e85888a10b0eb Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Fri, 17 Sep 2021 14:27:51 -0700 Subject: [PATCH 043/279] scsi: core: Remove include from scsi_cmnd.h There are no dependencies in on the header file. Hence remove the scsi_host.h include directive from scsi_cmnd.h. This include directive was introduced in February 2021 by commit af1830956dc3 ("scsi: core: Add mq_poll support to SCSI layer"). Link: https://lore.kernel.org/r/20210917212751.2676054-1-bvanassche@acm.org Cc: Kashyap Desai Reviewed-by: Himanshu Madhani Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- include/scsi/scsi_cmnd.h | 1 - 1 file changed, 1 deletion(-) diff --git a/include/scsi/scsi_cmnd.h b/include/scsi/scsi_cmnd.h index eaf04c9a1dfc..a2315aac93c7 100644 --- a/include/scsi/scsi_cmnd.h +++ b/include/scsi/scsi_cmnd.h @@ -10,7 +10,6 @@ #include #include #include -#include #include struct Scsi_Host; From 8d4efd0040e52bad2907a6a7b1cd686bee31fbcd Mon Sep 17 00:00:00 2001 From: Dmitry Bogdanov Date: Tue, 14 Sep 2021 13:55:37 +0300 Subject: [PATCH 044/279] scsi: efct: Add state in nport sm trace printout Similar to other state machine traces and to make debug easier, add the state name to nport sm trace printout. Link: https://lore.kernel.org/r/20210914105539.6942-2-d.bogdanov@yadro.com Reviewed-by: Ram Vegesna Signed-off-by: Dmitry Bogdanov Signed-off-by: Martin K. Petersen --- drivers/scsi/elx/libefc/efc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/elx/libefc/efc.h b/drivers/scsi/elx/libefc/efc.h index 927016283f41..468ff3cc9c00 100644 --- a/drivers/scsi/elx/libefc/efc.h +++ b/drivers/scsi/elx/libefc/efc.h @@ -47,6 +47,6 @@ enum efc_scsi_del_target_reason { #define nport_sm_trace(nport) \ efc_log_debug(nport->efc, \ - "[%s] %-20s\n", nport->display_name, efc_sm_event_name(evt)) \ + "[%s] %-20s %-20s\n", nport->display_name, __func__, efc_sm_event_name(evt)) \ #endif /* __EFC_H__ */ From ee3dce9f38426776b48406441d0dc39c74940818 Mon Sep 17 00:00:00 2001 From: Dmitry Bogdanov Date: Tue, 14 Sep 2021 13:55:38 +0300 Subject: [PATCH 045/279] scsi: efct: Fix nport free nport_free for an empty nport hangs the state machine waiting for mbox completion if nport is not yet attached thinking that it is attaching right now. Add a check for nport attaching state and complete nport free. Link: https://lore.kernel.org/r/20210914105539.6942-3-d.bogdanov@yadro.com Reviewed-by: Ram Vegesna Signed-off-by: Dmitry Bogdanov Signed-off-by: Martin K. Petersen --- drivers/scsi/elx/libefc/efc_cmds.c | 7 ++++++- drivers/scsi/elx/libefc/efclib.h | 1 + 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/elx/libefc/efc_cmds.c b/drivers/scsi/elx/libefc/efc_cmds.c index 37e6697d86b8..f8665d48904a 100644 --- a/drivers/scsi/elx/libefc/efc_cmds.c +++ b/drivers/scsi/elx/libefc/efc_cmds.c @@ -249,6 +249,7 @@ efc_nport_attach_reg_vpi_cb(struct efc *efc, int status, u8 *mqe, { struct efc_nport *nport = arg; + nport->attaching = false; if (efc_nport_get_mbox_status(nport, mqe, status)) { efc_nport_free_resources(nport, EFC_EVT_NPORT_ATTACH_FAIL, mqe); return -EIO; @@ -286,6 +287,8 @@ efc_cmd_nport_attach(struct efc *efc, struct efc_nport *nport, u32 fc_id) if (rc) { efc_log_err(efc, "REG_VPI command failure\n"); efc_nport_free_resources(nport, EFC_EVT_NPORT_ATTACH_FAIL, buf); + } else { + nport->attaching = true; } return rc; @@ -302,8 +305,10 @@ efc_cmd_nport_free(struct efc *efc, struct efc_nport *nport) /* Issue the UNREG_VPI command to free the assigned VPI context */ if (nport->attached) efc_nport_free_unreg_vpi(nport); - else + else if (nport->attaching) nport->free_req_pending = true; + else + efc_sm_post_event(&nport->sm, EFC_EVT_NPORT_FREE_OK, NULL); return 0; } diff --git a/drivers/scsi/elx/libefc/efclib.h b/drivers/scsi/elx/libefc/efclib.h index ee291cabf7e0..dde20891c2dd 100644 --- a/drivers/scsi/elx/libefc/efclib.h +++ b/drivers/scsi/elx/libefc/efclib.h @@ -142,6 +142,7 @@ struct efc_nport { bool is_vport; bool free_req_pending; bool attached; + bool attaching; bool p2p_winner; struct efc_domain *domain; u64 wwpn; From e76b7c5e25a1fa818bb3e727873a899cc89f5196 Mon Sep 17 00:00:00 2001 From: Dmitry Bogdanov Date: Tue, 14 Sep 2021 13:55:39 +0300 Subject: [PATCH 046/279] scsi: efct: Decrease area under spinlock Under the session level spinlock node->active_ios_lock in efct_scsi_io_alloc() we are taking another spinlock for the port. This leads to contention between sessions and even between I/Os in the same session. Reduce the locked region to active_ios list for which active_ios_lock is intended. Spinlock CPU usage decreases from 18% down to 13%. IOPS are increased from 220 kIOPS to 264 kIOPS for one LUN. Link: https://lore.kernel.org/r/20210914105539.6942-4-d.bogdanov@yadro.com Reviewed-by: Roman Bolshakov Reviewed-by: Ram Vegesna Signed-off-by: Dmitry Bogdanov Signed-off-by: Martin K. Petersen --- drivers/scsi/elx/efct/efct_scsi.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/scsi/elx/efct/efct_scsi.c b/drivers/scsi/elx/efct/efct_scsi.c index 40fb3a724c76..8535bb7eabd8 100644 --- a/drivers/scsi/elx/efct/efct_scsi.c +++ b/drivers/scsi/elx/efct/efct_scsi.c @@ -38,8 +38,6 @@ efct_scsi_io_alloc(struct efct_node *node) xport = efct->xport; - spin_lock_irqsave(&node->active_ios_lock, flags); - io = efct_io_pool_io_alloc(efct->xport->io_pool); if (!io) { efc_log_err(efct, "IO alloc Failed\n"); @@ -66,6 +64,7 @@ efct_scsi_io_alloc(struct efct_node *node) /* Add to node's active_ios list */ INIT_LIST_HEAD(&io->list_entry); + spin_lock_irqsave(&node->active_ios_lock, flags); list_add(&io->list_entry, &node->active_ios); spin_unlock_irqrestore(&node->active_ios_lock, flags); From e88e2d32200a1734cb4a2ca292c5c7b338257bb6 Mon Sep 17 00:00:00 2001 From: Avri Altman Date: Wed, 15 Sep 2021 09:04:06 +0300 Subject: [PATCH 047/279] scsi: ufs: core: Probe for temperature notification support Probe the dExtendedUFSFeaturesSupport register for the device's temperature notification support and, if supported, add a hardware monitor device. Link: https://lore.kernel.org/r/20210915060407.40-2-avri.altman@wdc.com Reviewed-by: Guenter Roeck Reviewed-by: Bean Huo Reviewed-by: Daejun Park Signed-off-by: Avri Altman Signed-off-by: Martin K. Petersen --- drivers/scsi/ufs/Kconfig | 9 ++ drivers/scsi/ufs/Makefile | 1 + drivers/scsi/ufs/ufs-hwmon.c | 198 +++++++++++++++++++++++++++++++++++ drivers/scsi/ufs/ufs.h | 7 ++ drivers/scsi/ufs/ufshcd.c | 26 +++++ drivers/scsi/ufs/ufshcd.h | 18 ++++ 6 files changed, 259 insertions(+) create mode 100644 drivers/scsi/ufs/ufs-hwmon.c diff --git a/drivers/scsi/ufs/Kconfig b/drivers/scsi/ufs/Kconfig index 432df76e6318..565e8aa6319d 100644 --- a/drivers/scsi/ufs/Kconfig +++ b/drivers/scsi/ufs/Kconfig @@ -199,3 +199,12 @@ config SCSI_UFS_FAULT_INJECTION help Enable fault injection support in the UFS driver. This makes it easier to test the UFS error handler and abort handler. + +config SCSI_UFS_HWMON + bool "UFS Temperature Notification" + depends on SCSI_UFSHCD && HWMON + help + This provides support for UFS hardware monitoring. If enabled, + a hardware monitoring device will be created for the UFS device. + + If unsure, say N. diff --git a/drivers/scsi/ufs/Makefile b/drivers/scsi/ufs/Makefile index c407da9b5171..966048875b50 100644 --- a/drivers/scsi/ufs/Makefile +++ b/drivers/scsi/ufs/Makefile @@ -10,6 +10,7 @@ ufshcd-core-$(CONFIG_SCSI_UFS_BSG) += ufs_bsg.o ufshcd-core-$(CONFIG_SCSI_UFS_CRYPTO) += ufshcd-crypto.o ufshcd-core-$(CONFIG_SCSI_UFS_HPB) += ufshpb.o ufshcd-core-$(CONFIG_SCSI_UFS_FAULT_INJECTION) += ufs-fault-injection.o +ufshcd-core-$(CONFIG_SCSI_UFS_HWMON) += ufs-hwmon.o obj-$(CONFIG_SCSI_UFS_DWC_TC_PCI) += tc-dwc-g210-pci.o ufshcd-dwc.o tc-dwc-g210.o obj-$(CONFIG_SCSI_UFS_DWC_TC_PLATFORM) += tc-dwc-g210-pltfrm.o ufshcd-dwc.o tc-dwc-g210.o diff --git a/drivers/scsi/ufs/ufs-hwmon.c b/drivers/scsi/ufs/ufs-hwmon.c new file mode 100644 index 000000000000..33b66736aaa4 --- /dev/null +++ b/drivers/scsi/ufs/ufs-hwmon.c @@ -0,0 +1,198 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * UFS hardware monitoring support + * Copyright (c) 2021, Western Digital Corporation + */ + +#include +#include + +#include "ufshcd.h" + +struct ufs_hwmon_data { + struct ufs_hba *hba; + u8 mask; +}; + +static int ufs_read_temp_enable(struct ufs_hba *hba, u8 mask, long *val) +{ + u32 ee_mask; + int err; + + err = ufshcd_query_attr(hba, UPIU_QUERY_OPCODE_READ_ATTR, QUERY_ATTR_IDN_EE_CONTROL, 0, 0, + &ee_mask); + if (err) + return err; + + *val = (mask & ee_mask & MASK_EE_TOO_HIGH_TEMP) || (mask & ee_mask & MASK_EE_TOO_LOW_TEMP); + + return 0; +} + +static int ufs_get_temp(struct ufs_hba *hba, enum attr_idn idn, long *val) +{ + u32 value; + int err; + + err = ufshcd_query_attr(hba, UPIU_QUERY_OPCODE_READ_ATTR, idn, 0, 0, &value); + if (err) + return err; + + if (value == 0) + return -ENODATA; + + *val = ((long)value - 80) * MILLIDEGREE_PER_DEGREE; + + return 0; +} + +static int ufs_hwmon_read(struct device *dev, enum hwmon_sensor_types type, u32 attr, int channel, + long *val) +{ + struct ufs_hwmon_data *data = dev_get_drvdata(dev); + struct ufs_hba *hba = data->hba; + int err; + + down(&hba->host_sem); + + if (!ufshcd_is_user_access_allowed(hba)) { + up(&hba->host_sem); + return -EBUSY; + } + + ufshcd_rpm_get_sync(hba); + + switch (attr) { + case hwmon_temp_enable: + err = ufs_read_temp_enable(hba, data->mask, val); + + break; + case hwmon_temp_crit: + err = ufs_get_temp(hba, QUERY_ATTR_IDN_HIGH_TEMP_BOUND, val); + + break; + case hwmon_temp_lcrit: + err = ufs_get_temp(hba, QUERY_ATTR_IDN_LOW_TEMP_BOUND, val); + + break; + case hwmon_temp_input: + err = ufs_get_temp(hba, QUERY_ATTR_IDN_CASE_ROUGH_TEMP, val); + + break; + default: + err = -EOPNOTSUPP; + + break; + } + + ufshcd_rpm_put_sync(hba); + + up(&hba->host_sem); + + return err; +} + +static int ufs_hwmon_write(struct device *dev, enum hwmon_sensor_types type, u32 attr, int channel, + long val) +{ + struct ufs_hwmon_data *data = dev_get_drvdata(dev); + struct ufs_hba *hba = data->hba; + int err; + + if (attr != hwmon_temp_enable) + return -EINVAL; + + if (val != 0 && val != 1) + return -EINVAL; + + down(&hba->host_sem); + + if (!ufshcd_is_user_access_allowed(hba)) { + up(&hba->host_sem); + return -EBUSY; + } + + ufshcd_rpm_get_sync(hba); + + if (val == 1) + err = ufshcd_update_ee_usr_mask(hba, MASK_EE_URGENT_TEMP, 0); + else + err = ufshcd_update_ee_usr_mask(hba, 0, MASK_EE_URGENT_TEMP); + + ufshcd_rpm_put_sync(hba); + + up(&hba->host_sem); + + return err; +} + +static umode_t ufs_hwmon_is_visible(const void *_data, enum hwmon_sensor_types type, u32 attr, + int channel) +{ + if (type != hwmon_temp) + return 0; + + switch (attr) { + case hwmon_temp_enable: + return 0644; + case hwmon_temp_crit: + case hwmon_temp_lcrit: + case hwmon_temp_input: + return 0444; + default: + break; + } + return 0; +} + +static const struct hwmon_channel_info *ufs_hwmon_info[] = { + HWMON_CHANNEL_INFO(temp, HWMON_T_ENABLE | HWMON_T_INPUT | HWMON_T_CRIT | HWMON_T_LCRIT), + NULL +}; + +static const struct hwmon_ops ufs_hwmon_ops = { + .is_visible = ufs_hwmon_is_visible, + .read = ufs_hwmon_read, + .write = ufs_hwmon_write, +}; + +static const struct hwmon_chip_info ufs_hwmon_hba_info = { + .ops = &ufs_hwmon_ops, + .info = ufs_hwmon_info, +}; + +void ufs_hwmon_probe(struct ufs_hba *hba, u8 mask) +{ + struct device *dev = hba->dev; + struct ufs_hwmon_data *data; + struct device *hwmon; + + data = kzalloc(sizeof(*data), GFP_KERNEL); + if (!data) + return; + + data->hba = hba; + data->mask = mask; + + hwmon = hwmon_device_register_with_info(dev, "ufs", data, &ufs_hwmon_hba_info, NULL); + if (IS_ERR(hwmon)) { + dev_warn(dev, "Failed to instantiate hwmon device\n"); + kfree(data); + return; + } + + hba->hwmon_device = hwmon; +} + +void ufs_hwmon_remove(struct ufs_hba *hba) +{ + struct ufs_hwmon_data *data; + + if (!hba->hwmon_device) + return; + + data = dev_get_drvdata(hba->hwmon_device); + hwmon_device_unregister(hba->hwmon_device); + hba->hwmon_device = NULL; + kfree(data); +} diff --git a/drivers/scsi/ufs/ufs.h b/drivers/scsi/ufs/ufs.h index 8c6b38b1b142..0bfdca3e648e 100644 --- a/drivers/scsi/ufs/ufs.h +++ b/drivers/scsi/ufs/ufs.h @@ -152,6 +152,9 @@ enum attr_idn { QUERY_ATTR_IDN_PSA_STATE = 0x15, QUERY_ATTR_IDN_PSA_DATA_SIZE = 0x16, QUERY_ATTR_IDN_REF_CLK_GATING_WAIT_TIME = 0x17, + QUERY_ATTR_IDN_CASE_ROUGH_TEMP = 0x18, + QUERY_ATTR_IDN_HIGH_TEMP_BOUND = 0x19, + QUERY_ATTR_IDN_LOW_TEMP_BOUND = 0x1A, QUERY_ATTR_IDN_WB_FLUSH_STATUS = 0x1C, QUERY_ATTR_IDN_AVAIL_WB_BUFF_SIZE = 0x1D, QUERY_ATTR_IDN_WB_BUFF_LIFE_TIME_EST = 0x1E, @@ -338,6 +341,9 @@ enum { /* Possible values for dExtendedUFSFeaturesSupport */ enum { + UFS_DEV_LOW_TEMP_NOTIF = BIT(4), + UFS_DEV_HIGH_TEMP_NOTIF = BIT(5), + UFS_DEV_EXT_TEMP_NOTIF = BIT(6), UFS_DEV_HPB_SUPPORT = BIT(7), UFS_DEV_WRITE_BOOSTER_SUP = BIT(8), }; @@ -370,6 +376,7 @@ enum { MASK_EE_WRITEBOOSTER_EVENT = BIT(5), MASK_EE_PERFORMANCE_THROTTLING = BIT(6), }; +#define MASK_EE_URGENT_TEMP (MASK_EE_TOO_HIGH_TEMP | MASK_EE_TOO_LOW_TEMP) /* Background operation status */ enum bkops_status { diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index 3841ab49f556..ce22340024ce 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -7469,6 +7469,29 @@ wb_disabled: hba->caps &= ~UFSHCD_CAP_WB_EN; } +static void ufshcd_temp_notif_probe(struct ufs_hba *hba, u8 *desc_buf) +{ + struct ufs_dev_info *dev_info = &hba->dev_info; + u32 ext_ufs_feature; + u8 mask = 0; + + if (!(hba->caps & UFSHCD_CAP_TEMP_NOTIF) || dev_info->wspecversion < 0x300) + return; + + ext_ufs_feature = get_unaligned_be32(desc_buf + DEVICE_DESC_PARAM_EXT_UFS_FEATURE_SUP); + + if (ext_ufs_feature & UFS_DEV_LOW_TEMP_NOTIF) + mask |= MASK_EE_TOO_LOW_TEMP; + + if (ext_ufs_feature & UFS_DEV_HIGH_TEMP_NOTIF) + mask |= MASK_EE_TOO_HIGH_TEMP; + + if (mask) { + ufshcd_enable_ee(hba, mask); + ufs_hwmon_probe(hba, mask); + } +} + void ufshcd_fixup_dev_quirks(struct ufs_hba *hba, struct ufs_dev_fix *fixups) { struct ufs_dev_fix *f; @@ -7564,6 +7587,8 @@ static int ufs_get_device_desc(struct ufs_hba *hba) ufshcd_wb_probe(hba, desc_buf); + ufshcd_temp_notif_probe(hba, desc_buf); + /* * ufshcd_read_string_desc returns size of the string * reset the error value @@ -9408,6 +9433,7 @@ void ufshcd_remove(struct ufs_hba *hba) { if (hba->sdev_ufs_device) ufshcd_rpm_get_sync(hba); + ufs_hwmon_remove(hba); ufs_bsg_remove(hba); ufshpb_remove(hba); ufs_sysfs_remove_nodes(hba->dev); diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h index 52ea6f350b18..021c858955af 100644 --- a/drivers/scsi/ufs/ufshcd.h +++ b/drivers/scsi/ufs/ufshcd.h @@ -653,6 +653,12 @@ enum ufshcd_caps { * in order to exit DeepSleep state. */ UFSHCD_CAP_DEEPSLEEP = 1 << 10, + + /* + * This capability allows the host controller driver to use temperature + * notification if it is supported by the UFS device. + */ + UFSHCD_CAP_TEMP_NOTIF = 1 << 11, }; struct ufs_hba_variant_params { @@ -789,6 +795,10 @@ struct ufs_hba { struct scsi_device *sdev_ufs_device; struct scsi_device *sdev_rpmb; +#ifdef CONFIG_SCSI_UFS_HWMON + struct device *hwmon_device; +#endif + enum ufs_dev_pwr_mode curr_dev_pwr_mode; enum uic_link_state uic_link_state; /* Desired UFS power management level during runtime PM */ @@ -1049,6 +1059,14 @@ static inline u8 ufshcd_wb_get_query_index(struct ufs_hba *hba) return 0; } +#ifdef CONFIG_SCSI_UFS_HWMON +void ufs_hwmon_probe(struct ufs_hba *hba, u8 mask); +void ufs_hwmon_remove(struct ufs_hba *hba); +#else +static inline void ufs_hwmon_probe(struct ufs_hba *hba, u8 mask) {} +static inline void ufs_hwmon_remove(struct ufs_hba *hba) {} +#endif + #ifdef CONFIG_PM extern int ufshcd_runtime_suspend(struct device *dev); extern int ufshcd_runtime_resume(struct device *dev); From 322c4b29ee1f19ce153f027bfb21d272b029f2d7 Mon Sep 17 00:00:00 2001 From: Avri Altman Date: Wed, 15 Sep 2021 09:04:07 +0300 Subject: [PATCH 048/279] scsi: ufs: core: Add temperature notification exception handling MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The device may notify the host of an extreme temperature by using the exception event mechanism. The exception can be raised when the device’s Tcase temperature is either too high or too low. It is essentially up to the platform to decide what further actions need to be taken. leave a placeholder for a designated vop for that. Link: https://lore.kernel.org/r/20210915060407.40-3-avri.altman@wdc.com Reviewed-by: Guenter Roeck Reviewed-by: Bean Huo Reviewed-by: Daejun Park Signed-off-by: Avri Altman Signed-off-by: Martin K. Petersen --- drivers/scsi/ufs/ufs-hwmon.c | 12 ++++++++++++ drivers/scsi/ufs/ufshcd.c | 21 +++++++++++++++++++++ drivers/scsi/ufs/ufshcd.h | 2 ++ 3 files changed, 35 insertions(+) diff --git a/drivers/scsi/ufs/ufs-hwmon.c b/drivers/scsi/ufs/ufs-hwmon.c index 33b66736aaa4..74855491dc8f 100644 --- a/drivers/scsi/ufs/ufs-hwmon.c +++ b/drivers/scsi/ufs/ufs-hwmon.c @@ -196,3 +196,15 @@ void ufs_hwmon_remove(struct ufs_hba *hba) hba->hwmon_device = NULL; kfree(data); } + +void ufs_hwmon_notify_event(struct ufs_hba *hba, u8 ee_mask) +{ + if (!hba->hwmon_device) + return; + + if (ee_mask & MASK_EE_TOO_HIGH_TEMP) + hwmon_notify_event(hba->hwmon_device, hwmon_temp, hwmon_temp_max_alarm, 0); + + if (ee_mask & MASK_EE_TOO_LOW_TEMP) + hwmon_notify_event(hba->hwmon_device, hwmon_temp, hwmon_temp_min_alarm, 0); +} diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index ce22340024ce..debef631c89a 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -5642,6 +5642,24 @@ out: __func__, err); } +static void ufshcd_temp_exception_event_handler(struct ufs_hba *hba, u16 status) +{ + u32 value; + + if (ufshcd_query_attr_retry(hba, UPIU_QUERY_OPCODE_READ_ATTR, + QUERY_ATTR_IDN_CASE_ROUGH_TEMP, 0, 0, &value)) + return; + + dev_info(hba->dev, "exception Tcase %d\n", value - 80); + + ufs_hwmon_notify_event(hba, status & MASK_EE_URGENT_TEMP); + + /* + * A placeholder for the platform vendors to add whatever additional + * steps required + */ +} + static int __ufshcd_wb_toggle(struct ufs_hba *hba, bool set, enum flag_idn idn) { u8 index; @@ -5821,6 +5839,9 @@ static void ufshcd_exception_event_handler(struct work_struct *work) if (status & hba->ee_drv_mask & MASK_EE_URGENT_BKOPS) ufshcd_bkops_exception_event_handler(hba); + if (status & hba->ee_drv_mask & MASK_EE_URGENT_TEMP) + ufshcd_temp_exception_event_handler(hba, status); + ufs_debugfs_exception_event(hba, status); out: ufshcd_scsi_unblock_requests(hba); diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h index 021c858955af..92d05329de68 100644 --- a/drivers/scsi/ufs/ufshcd.h +++ b/drivers/scsi/ufs/ufshcd.h @@ -1062,9 +1062,11 @@ static inline u8 ufshcd_wb_get_query_index(struct ufs_hba *hba) #ifdef CONFIG_SCSI_UFS_HWMON void ufs_hwmon_probe(struct ufs_hba *hba, u8 mask); void ufs_hwmon_remove(struct ufs_hba *hba); +void ufs_hwmon_notify_event(struct ufs_hba *hba, u8 ee_mask); #else static inline void ufs_hwmon_probe(struct ufs_hba *hba, u8 mask) {} static inline void ufs_hwmon_remove(struct ufs_hba *hba) {} +static inline void ufs_hwmon_notify_event(struct ufs_hba *hba, u8 ee_mask) {} #endif #ifdef CONFIG_PM From cbd9a3347c757383f3d2b50cf7cfd03eb479c481 Mon Sep 17 00:00:00 2001 From: Tong Zhang Date: Mon, 6 Sep 2021 21:07:02 -0700 Subject: [PATCH 049/279] scsi: dc395: Fix error case unwinding dc395x_init_one()->adapter_init() might fail. In this case, the acb is already cleaned up by adapter_init(), no need to do that in adapter_uninit(acb) again. [ 1.252251] dc395x: adapter init failed [ 1.254900] RIP: 0010:adapter_uninit+0x94/0x170 [dc395x] [ 1.260307] Call Trace: [ 1.260442] dc395x_init_one.cold+0x72a/0x9bb [dc395x] Link: https://lore.kernel.org/r/20210907040702.1846409-1-ztong0001@gmail.com Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Reviewed-by: Finn Thain Signed-off-by: Tong Zhang Signed-off-by: Martin K. Petersen --- drivers/scsi/dc395x.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/scsi/dc395x.c b/drivers/scsi/dc395x.c index 24c7cefb0b78..1c79e6c27163 100644 --- a/drivers/scsi/dc395x.c +++ b/drivers/scsi/dc395x.c @@ -4618,6 +4618,7 @@ static int dc395x_init_one(struct pci_dev *dev, const struct pci_device_id *id) /* initialise the adapter and everything we need */ if (adapter_init(acb, io_port_base, io_port_len, irq)) { dprintkl(KERN_INFO, "adapter init failed\n"); + acb = NULL; goto fail; } From efe1dc571a5b808baa26682eef16561be2e356fd Mon Sep 17 00:00:00 2001 From: James Smart Date: Tue, 21 Sep 2021 07:30:08 -0700 Subject: [PATCH 050/279] scsi: lpfc: Fix mailbox command failure during driver initialization Contention for the mailbox interface may occur during driver initialization (immediately after a function reset), between mailbox commands initiated via ioctl (bsg) and those driver requested by the driver. After setting SLI_ACTIVE flag for a port, there is a window in which the driver will allow an ioctl to be initiated while the adapter is initializing and issuing mailbox commands via polling. The polling logic then gets confused. Correct by having thread setting SLI_ACTIVE spot an active mailbox command and allow it complete before proceeding. Link: https://lore.kernel.org/r/20210921143008.64212-1-jsmart2021@gmail.com Co-developed-by: Nigel Kirkland Signed-off-by: Nigel Kirkland Signed-off-by: James Smart Signed-off-by: Martin K. Petersen --- drivers/scsi/lpfc/lpfc_sli.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index 34cf2bfcce07..3f911cb48cf2 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c @@ -8158,6 +8158,7 @@ lpfc_sli4_hba_setup(struct lpfc_hba *phba) struct lpfc_vport *vport = phba->pport; struct lpfc_dmabuf *mp; struct lpfc_rqb *rqbp; + u32 flg; /* Perform a PCI function reset to start from clean */ rc = lpfc_pci_function_reset(phba); @@ -8171,7 +8172,17 @@ lpfc_sli4_hba_setup(struct lpfc_hba *phba) else { spin_lock_irq(&phba->hbalock); phba->sli.sli_flag |= LPFC_SLI_ACTIVE; + flg = phba->sli.sli_flag; spin_unlock_irq(&phba->hbalock); + /* Allow a little time after setting SLI_ACTIVE for any polled + * MBX commands to complete via BSG. + */ + for (i = 0; i < 50 && (flg & LPFC_SLI_MBOX_ACTIVE); i++) { + msleep(20); + spin_lock_irq(&phba->hbalock); + flg = phba->sli.sli_flag; + spin_unlock_irq(&phba->hbalock); + } } lpfc_sli4_dip(phba); @@ -9755,7 +9766,7 @@ lpfc_sli_issue_mbox_s4(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq, "(%d):2541 Mailbox command x%x " "(x%x/x%x) failure: " "mqe_sta: x%x mcqe_sta: x%x/x%x " - "Data: x%x x%x\n,", + "Data: x%x x%x\n", mboxq->vport ? mboxq->vport->vpi : 0, mboxq->u.mb.mbxCommand, lpfc_sli_config_mbox_subsys_get(phba, @@ -9789,7 +9800,7 @@ lpfc_sli_issue_mbox_s4(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq, "(%d):2597 Sync Mailbox command " "x%x (x%x/x%x) failure: " "mqe_sta: x%x mcqe_sta: x%x/x%x " - "Data: x%x x%x\n,", + "Data: x%x x%x\n", mboxq->vport ? mboxq->vport->vpi : 0, mboxq->u.mb.mbxCommand, lpfc_sli_config_mbox_subsys_get(phba, From ce580e47e8481047faf296757d747e95464ff71c Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Fri, 24 Sep 2021 15:26:58 +0200 Subject: [PATCH 051/279] scsi: ufs: exynos: Unify naming Use "Samsung" and "Exynos", not the uppercase versions. Link: https://lore.kernel.org/r/20210924132658.109814-2-krzysztof.kozlowski@canonical.com Reviewed-by: Alim Akhtar Signed-off-by: Krzysztof Kozlowski Signed-off-by: Martin K. Petersen --- drivers/scsi/ufs/Kconfig | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/scsi/ufs/Kconfig b/drivers/scsi/ufs/Kconfig index 565e8aa6319d..af66cb3634a8 100644 --- a/drivers/scsi/ufs/Kconfig +++ b/drivers/scsi/ufs/Kconfig @@ -165,14 +165,14 @@ config SCSI_UFS_BSG If unsure, say N. config SCSI_UFS_EXYNOS - tristate "EXYNOS specific hooks to UFS controller platform driver" + tristate "Exynos specific hooks to UFS controller platform driver" depends on SCSI_UFSHCD_PLATFORM && (ARCH_EXYNOS || COMPILE_TEST) help - This selects the EXYNOS specific additions to UFSHCD platform driver. - UFS host on EXYNOS includes HCI and UNIPRO layer, and associates with - UFS-PHY driver. + This selects the Samsung Exynos SoC specific additions to UFSHCD + platform driver. UFS host on Samsung Exynos SoC includes HCI and + UNIPRO layer, and associates with UFS-PHY driver. - Select this if you have UFS host controller on EXYNOS chipset. + Select this if you have UFS host controller on Samsung Exynos SoC. If unsure, say N. config SCSI_UFS_CRYPTO From 568778f5572afd5b30984edd2a4a2c96df8b2b16 Mon Sep 17 00:00:00 2001 From: Len Baker Date: Sat, 25 Sep 2021 13:42:05 +0200 Subject: [PATCH 052/279] scsi: advansys: Prefer struct_size() over open-coded arithmetic As noted in the "Deprecated Interfaces, Language Features, Attributes, and Conventions" documentation [1], size calculations (especially multiplication) should not be performed in memory allocator (or similar) function arguments due to the risk of them overflowing. This could lead to values wrapping around and a smaller allocation being made than the caller was expecting. Using those allocations could lead to linear overflows of heap memory and other misbehaviors. Use the struct_size() helper to do the arithmetic instead of the argument "size + count * size" in the kzalloc() function. This code was detected with the help of Coccinelle and audited and fixed manually. [1] https://www.kernel.org/doc/html/latest/process/deprecated.html#open-coded-arithmetic-in-allocator-arguments Link: https://lore.kernel.org/r/20210925114205.11377-1-len.baker@gmx.com Reviewed-by: Gustavo A. R. Silva Signed-off-by: Len Baker Signed-off-by: Martin K. Petersen --- drivers/scsi/advansys.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/advansys.c b/drivers/scsi/advansys.c index ffb391967573..e341b3372482 100644 --- a/drivers/scsi/advansys.c +++ b/drivers/scsi/advansys.c @@ -7477,8 +7477,8 @@ static int asc_build_req(struct asc_board *boardp, struct scsi_cmnd *scp, return ASC_ERROR; } - asc_sg_head = kzalloc(sizeof(asc_scsi_q->sg_head) + - use_sg * sizeof(struct asc_sg_list), GFP_ATOMIC); + asc_sg_head = kzalloc(struct_size(asc_sg_head, sg_list, use_sg), + GFP_ATOMIC); if (!asc_sg_head) { scsi_dma_unmap(scp); set_host_byte(scp, DID_SOFT_ERROR); From 8d807a068090ef15480d9e812f60d3356aa66b0e Mon Sep 17 00:00:00 2001 From: Cai Huoqing Date: Sat, 25 Sep 2021 20:53:23 +0800 Subject: [PATCH 053/279] scsi: lpfc: Fix a function name in comments Use dma_map_sg() instead of pci_map_sg() in comments. Link: https://lore.kernel.org/r/20210925125324.1760-3-caihuoqing@baidu.com Signed-off-by: Cai Huoqing Signed-off-by: Martin K. Petersen --- drivers/scsi/lpfc/lpfc_scsi.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c index 078fbea3f436..f25a9bad995f 100644 --- a/drivers/scsi/lpfc/lpfc_scsi.c +++ b/drivers/scsi/lpfc/lpfc_scsi.c @@ -894,7 +894,7 @@ lpfc_scsi_prep_dma_buf_s3(struct lpfc_hba *phba, struct lpfc_io_buf *lpfc_cmd) bpl += 2; if (scsi_sg_count(scsi_cmnd)) { /* - * The driver stores the segment count returned from pci_map_sg + * The driver stores the segment count returned from dma_map_sg * because this a count of dma-mappings used to map the use_sg * pages. They are not guaranteed to be the same for those * architectures that implement an IOMMU. @@ -2590,7 +2590,7 @@ lpfc_bg_scsi_prep_dma_buf_s3(struct lpfc_hba *phba, bpl += 2; if (scsi_sg_count(scsi_cmnd)) { /* - * The driver stores the segment count returned from pci_map_sg + * The driver stores the segment count returned from dma_map_sg * because this a count of dma-mappings used to map the use_sg * pages. They are not guaranteed to be the same for those * architectures that implement an IOMMU. @@ -3250,7 +3250,7 @@ lpfc_scsi_prep_dma_buf_s4(struct lpfc_hba *phba, struct lpfc_io_buf *lpfc_cmd) */ if (scsi_sg_count(scsi_cmnd)) { /* - * The driver stores the segment count returned from pci_map_sg + * The driver stores the segment count returned from dma_map_sg * because this a count of dma-mappings used to map the use_sg * pages. They are not guaranteed to be the same for those * architectures that implement an IOMMU. @@ -3489,7 +3489,7 @@ lpfc_bg_scsi_prep_dma_buf_s4(struct lpfc_hba *phba, */ if (scsi_sg_count(scsi_cmnd)) { /* - * The driver stores the segment count returned from pci_map_sg + * The driver stores the segment count returned from dma_map_sg * because this a count of dma-mappings used to map the use_sg * pages. They are not guaranteed to be the same for those * architectures that implement an IOMMU. From 9f80eca441a9e1c4682862e44ad3e7a618a0486f Mon Sep 17 00:00:00 2001 From: Cai Huoqing Date: Sat, 25 Sep 2021 21:29:30 +0800 Subject: [PATCH 054/279] scsi: aic7xxx: Fix a function name in comments Use dma_alloc_coherent() instead of pci_alloc_consistent(). Link: https://lore.kernel.org/r/20210925132931.95-1-caihuoqing@baidu.com Signed-off-by: Cai Huoqing Signed-off-by: Martin K. Petersen --- drivers/scsi/aic7xxx/aic79xx_osm.h | 2 +- drivers/scsi/aic7xxx/aic7xxx_osm.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/aic7xxx/aic79xx_osm.h b/drivers/scsi/aic7xxx/aic79xx_osm.h index 35ec24f28d2c..679a4fd13874 100644 --- a/drivers/scsi/aic7xxx/aic79xx_osm.h +++ b/drivers/scsi/aic7xxx/aic79xx_osm.h @@ -196,7 +196,7 @@ int ahd_dmamap_unload(struct ahd_softc *, bus_dma_tag_t, bus_dmamap_t); /* * XXX * ahd_dmamap_sync is only used on buffers allocated with - * the pci_alloc_consistent() API. Although I'm not sure how + * the dma_alloc_coherent() API. Although I'm not sure how * this works on architectures with a write buffer, Linux does * not have an API to sync "coherent" memory. Perhaps we need * to do an mb()? diff --git a/drivers/scsi/aic7xxx/aic7xxx_osm.h b/drivers/scsi/aic7xxx/aic7xxx_osm.h index 53240f53b654..4782a304e93c 100644 --- a/drivers/scsi/aic7xxx/aic7xxx_osm.h +++ b/drivers/scsi/aic7xxx/aic7xxx_osm.h @@ -209,7 +209,7 @@ int ahc_dmamap_unload(struct ahc_softc *, bus_dma_tag_t, bus_dmamap_t); /* * XXX * ahc_dmamap_sync is only used on buffers allocated with - * the pci_alloc_consistent() API. Although I'm not sure how + * the dma_alloc_coherent() API. Although I'm not sure how * this works on architectures with a write buffer, Linux does * not have an API to sync "coherent" memory. Perhaps we need * to do an mb()? From 5860d9fb5622ecd79913ac981403c612f6c8a2d8 Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Sat, 25 Sep 2021 23:41:13 +0100 Subject: [PATCH 055/279] scsi: lpfc: Return NULL rather than a plain 0 integer Function lpfc_sli4_perform_vport_cvl() returns a pointer to struct lpfc_nodelist so returning a plain 0 integer isn't good practice. Fix this by returning a NULL instead. Link: https://lore.kernel.org/r/20210925224113.183040-1-colin.king@canonical.com Signed-off-by: Colin Ian King Signed-off-by: Martin K. Petersen --- drivers/scsi/lpfc/lpfc_init.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index ff2a4e387523..0be8c8ab3d94 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c @@ -6564,7 +6564,7 @@ lpfc_sli4_perform_vport_cvl(struct lpfc_vport *vport) /* Cannot find existing Fabric ndlp, so allocate a new one */ ndlp = lpfc_nlp_init(vport, Fabric_DID); if (!ndlp) - return 0; + return NULL; /* Set the node type */ ndlp->nlp_type |= NLP_FABRIC; /* Put ndlp onto node list */ From 60c98a87fcaad9e71b835d2096e6665543cfe2e1 Mon Sep 17 00:00:00 2001 From: Anders Roxell Date: Mon, 27 Sep 2021 10:46:15 +0200 Subject: [PATCH 056/279] scsi: ufs: core: SCSI_UFS_HWMON depends on HWMON=y When building an allmodconfig kernel, the following build error shows up: aarch64-linux-gnu-ld: drivers/scsi/ufs/ufs-hwmon.o: in function `ufs_hwmon_probe': /kernel/next/drivers/scsi/ufs/ufs-hwmon.c:177: undefined reference to `hwmon_device_register_with_info' /kernel/next/drivers/scsi/ufs/ufs-hwmon.c:177:(.text+0x510): relocation truncated to fit: R_AARCH64_CALL26 against undefined symbol `hwmon_device_register_with_info' aarch64-linux-gnu-ld: drivers/scsi/ufs/ufs-hwmon.o: in function `ufs_hwmon_remove': /kernel/next/drivers/scsi/ufs/ufs-hwmon.c:195: undefined reference to `hwmon_device_unregister' /kernel/next/drivers/scsi/ufs/ufs-hwmon.c:195:(.text+0x5c8): relocation truncated to fit: R_AARCH64_CALL26 against undefined symbol `hwmon_device_unregister' aarch64-linux-gnu-ld: drivers/scsi/ufs/ufs-hwmon.o: in function `ufs_hwmon_notify_event': /kernel/next/drivers/scsi/ufs/ufs-hwmon.c:206: undefined reference to `hwmon_notify_event' /kernel/next/drivers/scsi/ufs/ufs-hwmon.c:206:(.text+0x64c): relocation truncated to fit: R_AARCH64_CALL26 against undefined symbol `hwmon_notify_event' aarch64-linux-gnu-ld: /home/anders/src/kernel/next/drivers/scsi/ufs/ufs-hwmon.c:209: undefined reference to `hwmon_notify_event' /kernel/next/drivers/scsi/ufs/ufs-hwmon.c:209:(.text+0x66c): relocation truncated to fit: R_AARCH64_CALL26 against undefined symbol `hwmon_notify_event' Since SCSI_UFS_HWMON can't be built as a module, SCSI_UFS_HWMON has to depend on HWMON=y. Link: https://lore.kernel.org/r/20210927084615.1938432-1-anders.roxell@linaro.org Fixes: e88e2d32200a ("scsi: ufs: core: Probe for temperature notification support") Also-reported-by: Randy Dunlap Acked-by: Randy Dunlap # build-tested Acked-by: Avri Altman Signed-off-by: Anders Roxell Signed-off-by: Martin K. Petersen --- drivers/scsi/ufs/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/ufs/Kconfig b/drivers/scsi/ufs/Kconfig index af66cb3634a8..b2521b830be7 100644 --- a/drivers/scsi/ufs/Kconfig +++ b/drivers/scsi/ufs/Kconfig @@ -202,7 +202,7 @@ config SCSI_UFS_FAULT_INJECTION config SCSI_UFS_HWMON bool "UFS Temperature Notification" - depends on SCSI_UFSHCD && HWMON + depends on SCSI_UFSHCD=HWMON || HWMON=y help This provides support for UFS hardware monitoring. If enabled, a hardware monitoring device will be created for the UFS device. From a5b141a895b592b401d739949d347ca473921c92 Mon Sep 17 00:00:00 2001 From: James Smart Date: Mon, 27 Sep 2021 11:35:18 -0700 Subject: [PATCH 057/279] scsi: lpfc: Add support for optional PLDV handling At adapter attachment or SLI port initialization, read the SLIPORT_STATUS register to check for pldv_enable. If found, the driver will perform a PCIe configuration space write when attaching to an SLI port instance that is an LPe32000 series adapter. Link: https://lore.kernel.org/r/20210927183518.22130-1-jsmart2021@gmail.com Co-developed-by: Nigel Kirkland Signed-off-by: Nigel Kirkland Signed-off-by: James Smart Signed-off-by: Martin K. Petersen --- drivers/scsi/lpfc/lpfc_hw4.h | 4 ++++ drivers/scsi/lpfc/lpfc_init.c | 14 ++++++++++++++ 2 files changed, 18 insertions(+) diff --git a/drivers/scsi/lpfc/lpfc_hw4.h b/drivers/scsi/lpfc/lpfc_hw4.h index 79a4872c2edb..143b73f71333 100644 --- a/drivers/scsi/lpfc/lpfc_hw4.h +++ b/drivers/scsi/lpfc/lpfc_hw4.h @@ -673,6 +673,10 @@ struct lpfc_register { #define lpfc_sliport_status_rdy_SHIFT 23 #define lpfc_sliport_status_rdy_MASK 0x1 #define lpfc_sliport_status_rdy_WORD word0 +#define lpfc_sliport_status_pldv_SHIFT 0 +#define lpfc_sliport_status_pldv_MASK 0x1 +#define lpfc_sliport_status_pldv_WORD word0 +#define CFG_PLD 0x3C #define MAX_IF_TYPE_2_RESETS 6 #define LPFC_CTL_PORT_CTL_OFFSET 0x408 diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index 0be8c8ab3d94..b9d3c848ac88 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c @@ -68,6 +68,7 @@ static enum cpuhp_state lpfc_cpuhp_state; /* Used when mapping IRQ vectors in a driver centric manner */ static uint32_t lpfc_present_cpu; +static bool lpfc_pldv_detect; static void __lpfc_cpuhp_remove(struct lpfc_hba *phba); static void lpfc_cpuhp_remove(struct lpfc_hba *phba); @@ -9359,7 +9360,15 @@ lpfc_sli4_post_status_check(struct lpfc_hba *phba) phba->work_status[0], phba->work_status[1]); port_error = -ENODEV; + break; } + + if (lpfc_pldv_detect && + bf_get(lpfc_sli_intf_sli_family, + &phba->sli4_hba.sli_intf) == + LPFC_SLI_INTF_FAMILY_G6) + pci_write_config_byte(phba->pcidev, + LPFC_SLI_INTF, CFG_PLD); break; case LPFC_SLI_INTF_IF_TYPE_1: default: @@ -11567,6 +11576,9 @@ wait: goto out; } + if (bf_get(lpfc_sliport_status_pldv, ®_data)) + lpfc_pldv_detect = true; + if (!port_reset) { /* * Reset the port now @@ -15560,6 +15572,8 @@ lpfc_init(void) /* Initialize in case vector mapping is needed */ lpfc_present_cpu = num_present_cpus(); + lpfc_pldv_detect = false; + error = cpuhp_setup_state_multi(CPUHP_AP_ONLINE_DYN, "lpfc/sli4:online", lpfc_cpu_online, lpfc_cpu_offline); From 525943a586ef43ed365974deef2ebd9e921f2f83 Mon Sep 17 00:00:00 2001 From: Asutosh Das Date: Tue, 28 Sep 2021 02:06:12 -0700 Subject: [PATCH 058/279] scsi: ufs: core: Export hibern8 entry and exit functions Qualcomm controllers need to be in hibern8 before scaling up or down the clocks. Hence, export the hibern8 entry and exit functions. Link: https://lore.kernel.org/r/a29bfdd0c8f1d1a3e5fb69e43ea277c97a7f0cb6.1632818942.git.nguyenb@codeaurora.org Reviewed-by: Bart Van Assche Reviewed-by: Alim Akhtar Signed-off-by: Asutosh Das Signed-off-by: Bao D. Nguyen Signed-off-by: Martin K. Petersen --- drivers/scsi/ufs/ufshcd.c | 4 ++-- drivers/scsi/ufs/ufshcd.h | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index debef631c89a..9faf02cbb9ad 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -227,7 +227,6 @@ static void ufshcd_hba_exit(struct ufs_hba *hba); static int ufshcd_clear_ua_wluns(struct ufs_hba *hba); static int ufshcd_probe_hba(struct ufs_hba *hba, bool async); static int ufshcd_setup_clocks(struct ufs_hba *hba, bool on); -static int ufshcd_uic_hibern8_enter(struct ufs_hba *hba); static inline void ufshcd_add_delay_before_dme_cmd(struct ufs_hba *hba); static int ufshcd_host_reset_and_restore(struct ufs_hba *hba); static void ufshcd_resume_clkscaling(struct ufs_hba *hba); @@ -4116,7 +4115,7 @@ int ufshcd_link_recovery(struct ufs_hba *hba) } EXPORT_SYMBOL_GPL(ufshcd_link_recovery); -static int ufshcd_uic_hibern8_enter(struct ufs_hba *hba) +int ufshcd_uic_hibern8_enter(struct ufs_hba *hba) { int ret; struct uic_command uic_cmd = {0}; @@ -4138,6 +4137,7 @@ static int ufshcd_uic_hibern8_enter(struct ufs_hba *hba) return ret; } +EXPORT_SYMBOL_GPL(ufshcd_uic_hibern8_enter); int ufshcd_uic_hibern8_exit(struct ufs_hba *hba) { diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h index 92d05329de68..ed960d206260 100644 --- a/drivers/scsi/ufs/ufshcd.h +++ b/drivers/scsi/ufs/ufshcd.h @@ -1011,6 +1011,7 @@ int ufshcd_init(struct ufs_hba *, void __iomem *, unsigned int); int ufshcd_link_recovery(struct ufs_hba *hba); int ufshcd_make_hba_operational(struct ufs_hba *hba); void ufshcd_remove(struct ufs_hba *); +int ufshcd_uic_hibern8_enter(struct ufs_hba *hba); int ufshcd_uic_hibern8_exit(struct ufs_hba *hba); void ufshcd_delay_us(unsigned long us, unsigned long tolerance); int ufshcd_wait_for_register(struct ufs_hba *hba, u32 reg, u32 mask, From a0cea83332ae2ba4b740a89fc094aba3298825db Mon Sep 17 00:00:00 2001 From: Asutosh Das Date: Tue, 28 Sep 2021 02:06:13 -0700 Subject: [PATCH 059/279] scsi: ufs: ufs-qcom: Enter and exit hibern8 during clock scaling Qualcomm controller needs to be in hibern8 before scaling clocks. This change puts the controller in hibern8 state before scaling and brings it out after scaling of clocks. Link: https://lore.kernel.org/r/212b7aaf6d834c4a8c682fdac4a59b84013ed573.1632818942.git.nguyenb@codeaurora.org Reviewed-by: Alim Akhtar Signed-off-by: Asutosh Das Signed-off-by: Bao D. Nguyen Signed-off-by: Martin K. Petersen --- drivers/scsi/ufs/ufs-qcom.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/ufs/ufs-qcom.c b/drivers/scsi/ufs/ufs-qcom.c index 92d4c61fc9d0..92f5bb4965fa 100644 --- a/drivers/scsi/ufs/ufs-qcom.c +++ b/drivers/scsi/ufs/ufs-qcom.c @@ -1212,24 +1212,34 @@ static int ufs_qcom_clk_scale_notify(struct ufs_hba *hba, int err = 0; if (status == PRE_CHANGE) { + err = ufshcd_uic_hibern8_enter(hba); + if (err) + return err; if (scale_up) err = ufs_qcom_clk_scale_up_pre_change(hba); else err = ufs_qcom_clk_scale_down_pre_change(hba); + if (err) + ufshcd_uic_hibern8_exit(hba); + } else { if (scale_up) err = ufs_qcom_clk_scale_up_post_change(hba); else err = ufs_qcom_clk_scale_down_post_change(hba); - if (err || !dev_req_params) + + if (err || !dev_req_params) { + ufshcd_uic_hibern8_exit(hba); goto out; + } ufs_qcom_cfg_timers(hba, dev_req_params->gear_rx, dev_req_params->pwr_rx, dev_req_params->hs_rate, false); + ufshcd_uic_hibern8_exit(hba); } out: From ca4ff9e751eb9c6371813ca9cc00c45444048088 Mon Sep 17 00:00:00 2001 From: Christophe JAILLET Date: Sun, 22 Aug 2021 13:55:33 +0200 Subject: [PATCH 060/279] scsi: elx: efct: Switch from 'pci_' to 'dma_' API The wrappers in include/linux/pci-dma-compat.h should go away. The patch has been generated with the coccinelle script below. It has been hand modified to use 'dma_set_mask_and_coherent()' instead of 'pci_set_dma_mask()/pci_set_consistent_dma_mask()' when applicable. This is less verbose. It has been compile tested. @@ @@ - PCI_DMA_BIDIRECTIONAL + DMA_BIDIRECTIONAL @@ @@ - PCI_DMA_TODEVICE + DMA_TO_DEVICE @@ @@ - PCI_DMA_FROMDEVICE + DMA_FROM_DEVICE @@ @@ - PCI_DMA_NONE + DMA_NONE @@ expression e1, e2, e3; @@ - pci_alloc_consistent(e1, e2, e3) + dma_alloc_coherent(&e1->dev, e2, e3, GFP_) @@ expression e1, e2, e3; @@ - pci_zalloc_consistent(e1, e2, e3) + dma_alloc_coherent(&e1->dev, e2, e3, GFP_) @@ expression e1, e2, e3, e4; @@ - pci_free_consistent(e1, e2, e3, e4) + dma_free_coherent(&e1->dev, e2, e3, e4) @@ expression e1, e2, e3, e4; @@ - pci_map_single(e1, e2, e3, e4) + dma_map_single(&e1->dev, e2, e3, e4) @@ expression e1, e2, e3, e4; @@ - pci_unmap_single(e1, e2, e3, e4) + dma_unmap_single(&e1->dev, e2, e3, e4) @@ expression e1, e2, e3, e4, e5; @@ - pci_map_page(e1, e2, e3, e4, e5) + dma_map_page(&e1->dev, e2, e3, e4, e5) @@ expression e1, e2, e3, e4; @@ - pci_unmap_page(e1, e2, e3, e4) + dma_unmap_page(&e1->dev, e2, e3, e4) @@ expression e1, e2, e3, e4; @@ - pci_map_sg(e1, e2, e3, e4) + dma_map_sg(&e1->dev, e2, e3, e4) @@ expression e1, e2, e3, e4; @@ - pci_unmap_sg(e1, e2, e3, e4) + dma_unmap_sg(&e1->dev, e2, e3, e4) @@ expression e1, e2, e3, e4; @@ - pci_dma_sync_single_for_cpu(e1, e2, e3, e4) + dma_sync_single_for_cpu(&e1->dev, e2, e3, e4) @@ expression e1, e2, e3, e4; @@ - pci_dma_sync_single_for_device(e1, e2, e3, e4) + dma_sync_single_for_device(&e1->dev, e2, e3, e4) @@ expression e1, e2, e3, e4; @@ - pci_dma_sync_sg_for_cpu(e1, e2, e3, e4) + dma_sync_sg_for_cpu(&e1->dev, e2, e3, e4) @@ expression e1, e2, e3, e4; @@ - pci_dma_sync_sg_for_device(e1, e2, e3, e4) + dma_sync_sg_for_device(&e1->dev, e2, e3, e4) @@ expression e1, e2; @@ - pci_dma_mapping_error(e1, e2) + dma_mapping_error(&e1->dev, e2) @@ expression e1, e2; @@ - pci_set_dma_mask(e1, e2) + dma_set_mask(&e1->dev, e2) @@ expression e1, e2; @@ - pci_set_consistent_dma_mask(e1, e2) + dma_set_coherent_mask(&e1->dev, e2) Link: https://lore.kernel.org/r/3899b1ed4abac581c30845d82f33ec6df8b38976.1629633207.git.christophe.jaillet@wanadoo.fr Signed-off-by: Christophe JAILLET Signed-off-by: Martin K. Petersen --- drivers/scsi/elx/efct/efct_driver.c | 6 ++---- drivers/scsi/elx/efct/efct_lio.c | 4 ++-- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/drivers/scsi/elx/efct/efct_driver.c b/drivers/scsi/elx/efct/efct_driver.c index eab68fd9337a..b2b61bc45f12 100644 --- a/drivers/scsi/elx/efct/efct_driver.c +++ b/drivers/scsi/elx/efct/efct_driver.c @@ -541,11 +541,9 @@ efct_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) pci_set_drvdata(pdev, efct); - if (pci_set_dma_mask(pdev, DMA_BIT_MASK(64)) != 0 || - pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64)) != 0) { + if (dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64)) != 0) { dev_warn(&pdev->dev, "trying DMA_BIT_MASK(32)\n"); - if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32)) != 0 || - pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32)) != 0) { + if (dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32)) != 0) { dev_err(&pdev->dev, "setting DMA_BIT_MASK failed\n"); rc = -1; goto dma_mask_out; diff --git a/drivers/scsi/elx/efct/efct_lio.c b/drivers/scsi/elx/efct/efct_lio.c index bb3b460dc0bc..5f61d761258a 100644 --- a/drivers/scsi/elx/efct/efct_lio.c +++ b/drivers/scsi/elx/efct/efct_lio.c @@ -382,7 +382,7 @@ efct_lio_sg_map(struct efct_io *io) struct efct_scsi_tgt_io *ocp = &io->tgt_io; struct se_cmd *cmd = &ocp->cmd; - ocp->seg_map_cnt = pci_map_sg(io->efct->pci, cmd->t_data_sg, + ocp->seg_map_cnt = dma_map_sg(&io->efct->pci->dev, cmd->t_data_sg, cmd->t_data_nents, cmd->data_direction); if (ocp->seg_map_cnt == 0) return -EFAULT; @@ -398,7 +398,7 @@ efct_lio_sg_unmap(struct efct_io *io) if (WARN_ON(!ocp->seg_map_cnt || !cmd->t_data_sg)) return; - pci_unmap_sg(io->efct->pci, cmd->t_data_sg, + dma_unmap_sg(&io->efct->pci->dev, cmd->t_data_sg, ocp->seg_map_cnt, cmd->data_direction); ocp->seg_map_cnt = 0; } From 6bd49b1a8d43ec118c55f3aaa7577729b52bde15 Mon Sep 17 00:00:00 2001 From: John Garry Date: Mon, 13 Sep 2021 18:14:07 +0800 Subject: [PATCH 061/279] scsi: core: Delete scsi_{get,free}_host_dev() Since commit 0653c358d2dc ("scsi: Drop gdth driver"), functions scsi_{get,free}_host_dev() no longer have any in-tree users, so delete them. Link: https://lore.kernel.org/r/1631528047-30150-1-git-send-email-john.garry@huawei.com Reviewed-by: Bart Van Assche Reviewed-by: Christoph Hellwig Signed-off-by: John Garry Signed-off-by: Martin K. Petersen Nacked-by: Hannes Reinecke --- drivers/scsi/scsi_scan.c | 57 ---------------------------------------- include/scsi/scsi_host.h | 10 ------- 2 files changed, 67 deletions(-) diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c index fe22191522a3..0d0381df25f7 100644 --- a/drivers/scsi/scsi_scan.c +++ b/drivers/scsi/scsi_scan.c @@ -1902,60 +1902,3 @@ void scsi_forget_host(struct Scsi_Host *shost) spin_unlock_irqrestore(shost->host_lock, flags); } -/** - * scsi_get_host_dev - Create a scsi_device that points to the host adapter itself - * @shost: Host that needs a scsi_device - * - * Lock status: None assumed. - * - * Returns: The scsi_device or NULL - * - * Notes: - * Attach a single scsi_device to the Scsi_Host - this should - * be made to look like a "pseudo-device" that points to the - * HA itself. - * - * Note - this device is not accessible from any high-level - * drivers (including generics), which is probably not - * optimal. We can add hooks later to attach. - */ -struct scsi_device *scsi_get_host_dev(struct Scsi_Host *shost) -{ - struct scsi_device *sdev = NULL; - struct scsi_target *starget; - - mutex_lock(&shost->scan_mutex); - if (!scsi_host_scan_allowed(shost)) - goto out; - starget = scsi_alloc_target(&shost->shost_gendev, 0, shost->this_id); - if (!starget) - goto out; - - sdev = scsi_alloc_sdev(starget, 0, NULL); - if (sdev) - sdev->borken = 0; - else - scsi_target_reap(starget); - put_device(&starget->dev); - out: - mutex_unlock(&shost->scan_mutex); - return sdev; -} -EXPORT_SYMBOL(scsi_get_host_dev); - -/** - * scsi_free_host_dev - Free a scsi_device that points to the host adapter itself - * @sdev: Host device to be freed - * - * Lock status: None assumed. - * - * Returns: Nothing - */ -void scsi_free_host_dev(struct scsi_device *sdev) -{ - BUG_ON(sdev->id != sdev->host->this_id); - - __scsi_remove_device(sdev); -} -EXPORT_SYMBOL(scsi_free_host_dev); - diff --git a/include/scsi/scsi_host.h b/include/scsi/scsi_host.h index 75363707b73f..bc9c45ced145 100644 --- a/include/scsi/scsi_host.h +++ b/include/scsi/scsi_host.h @@ -797,16 +797,6 @@ void scsi_host_busy_iter(struct Scsi_Host *, struct class_container; -/* - * These two functions are used to allocate and free a pseudo device - * which will connect to the host adapter itself rather than any - * physical device. You must deallocate when you are done with the - * thing. This physical pseudo-device isn't real and won't be available - * from any high-level drivers. - */ -extern void scsi_free_host_dev(struct scsi_device *); -extern struct scsi_device *scsi_get_host_dev(struct Scsi_Host *); - /* * DIF defines the exchange of protection information between * initiator and SBC block device. From 17b49bcbf8351d3dbe57204468ac34f033ed60bc Mon Sep 17 00:00:00 2001 From: Damien Le Moal Date: Fri, 20 Aug 2021 16:02:53 +0900 Subject: [PATCH 062/279] scsi: core: Fix scsi_mode_sense() buffer length handling Several problems exist with scsi_mode_sense() buffer length handling: 1) The allocation length field of the MODE SENSE(10) command is 16-bits, occupying bytes 7 and 8 of the CDB. With this command, access to mode pages larger than 255 bytes is thus possible. However, the CDB allocation length field is set by assigning len to byte 8 only, thus truncating buffer length larger than 255. 2) If scsi_mode_sense() is called with len smaller than 8 with sdev->use_10_for_ms set, or smaller than 4 otherwise, the buffer length is increased to 8 and 4 respectively, and the buffer is zero filled with these increased values, thus corrupting the memory following the buffer. Fix these 2 problems by using put_unaligned_be16() to set the allocation length field of MODE SENSE(10) CDB and by returning an error when len is too small. Furthermore, if len is larger than 255B, always try MODE SENSE(10) first, even if the device driver did not set sdev->use_10_for_ms. In case of invalid opcode error for MODE SENSE(10), access to mode pages larger than 255 bytes are not retried using MODE SENSE(6). To avoid buffer length overflows for the MODE_SENSE(10) case, check that len is smaller than 65535 bytes. While at it, also fix the folowing: * Use get_unaligned_be16() to retrieve the mode data length and block descriptor length fields of the mode sense reply header instead of using an open coded calculation. * Fix the kdoc dbd argument explanation: the DBD bit stands for Disable Block Descriptor, which is the opposite of what the dbd argument description was. Link: https://lore.kernel.org/r/20210820070255.682775-2-damien.lemoal@wdc.com Signed-off-by: Damien Le Moal Signed-off-by: Martin K. Petersen --- drivers/scsi/scsi_lib.c | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index 572673873ddf..701d8e8480f2 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c @@ -2075,7 +2075,7 @@ EXPORT_SYMBOL_GPL(scsi_mode_select); /** * scsi_mode_sense - issue a mode sense, falling back from 10 to six bytes if necessary. * @sdev: SCSI device to be queried - * @dbd: set if mode sense will allow block descriptors to be returned + * @dbd: set to prevent mode sense from returning block descriptors * @modepage: mode page being requested * @buffer: request buffer (may not be smaller than eight bytes) * @len: length of request buffer. @@ -2110,18 +2110,18 @@ scsi_mode_sense(struct scsi_device *sdev, int dbd, int modepage, sshdr = &my_sshdr; retry: - use_10_for_ms = sdev->use_10_for_ms; + use_10_for_ms = sdev->use_10_for_ms || len > 255; if (use_10_for_ms) { - if (len < 8) - len = 8; + if (len < 8 || len > 65535) + return -EINVAL; cmd[0] = MODE_SENSE_10; - cmd[8] = len; + put_unaligned_be16(len, &cmd[7]); header_length = 8; } else { if (len < 4) - len = 4; + return -EINVAL; cmd[0] = MODE_SENSE; cmd[4] = len; @@ -2145,9 +2145,15 @@ scsi_mode_sense(struct scsi_device *sdev, int dbd, int modepage, if ((sshdr->sense_key == ILLEGAL_REQUEST) && (sshdr->asc == 0x20) && (sshdr->ascq == 0)) { /* - * Invalid command operation code + * Invalid command operation code: retry using + * MODE SENSE(6) if this was a MODE SENSE(10) + * request, except if the request mode page is + * too large for MODE SENSE single byte + * allocation length field. */ if (use_10_for_ms) { + if (len > 255) + return -EIO; sdev->use_10_for_ms = 0; goto retry; } @@ -2171,12 +2177,11 @@ scsi_mode_sense(struct scsi_device *sdev, int dbd, int modepage, data->longlba = 0; data->block_descriptor_length = 0; } else if (use_10_for_ms) { - data->length = buffer[0]*256 + buffer[1] + 2; + data->length = get_unaligned_be16(&buffer[0]) + 2; data->medium_type = buffer[2]; data->device_specific = buffer[3]; data->longlba = buffer[4] & 0x01; - data->block_descriptor_length = buffer[6]*256 - + buffer[7]; + data->block_descriptor_length = get_unaligned_be16(&buffer[6]); } else { data->length = buffer[0] + 1; data->medium_type = buffer[1]; From a7d6840bed0c2b16ac3071b74b5fcf08fc488241 Mon Sep 17 00:00:00 2001 From: Damien Le Moal Date: Fri, 20 Aug 2021 16:02:54 +0900 Subject: [PATCH 063/279] scsi: core: Fix scsi_mode_select() buffer length handling The MODE SELECT(6) command allows handling mode page buffers that are up to 255 bytes, including the 4 byte header needed in front of the page buffer. For requests larger than this limit, automatically use the MODE SELECT(10) command. In both cases, since scsi_mode_select() adds the mode select page header, checks on the buffer length value must include this header size to avoid overflows of the command CDB allocation length field. While at it, use put_unaligned_be16() for setting the header block descriptor length and CDB allocation length when using MODE SELECT(10). [mkp: fix MODE SENSE vs. MODE SELECT confusion] Link: https://lore.kernel.org/r/20210820070255.682775-3-damien.lemoal@wdc.com Signed-off-by: Damien Le Moal Signed-off-by: Martin K. Petersen --- drivers/scsi/scsi_lib.c | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index 701d8e8480f2..dcf105287a76 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c @@ -2026,8 +2026,15 @@ scsi_mode_select(struct scsi_device *sdev, int pf, int sp, int modepage, memset(cmd, 0, sizeof(cmd)); cmd[1] = (pf ? 0x10 : 0) | (sp ? 0x01 : 0); - if (sdev->use_10_for_ms) { - if (len > 65535) + /* + * Use MODE SELECT(10) if the device asked for it or if the mode page + * and the mode select header cannot fit within the maximumm 255 bytes + * of the MODE SELECT(6) command. + */ + if (sdev->use_10_for_ms || + len + 4 > 255 || + data->block_descriptor_length > 255) { + if (len > 65535 - 8) return -EINVAL; real_buffer = kmalloc(8 + len, GFP_KERNEL); if (!real_buffer) @@ -2040,15 +2047,13 @@ scsi_mode_select(struct scsi_device *sdev, int pf, int sp, int modepage, real_buffer[3] = data->device_specific; real_buffer[4] = data->longlba ? 0x01 : 0; real_buffer[5] = 0; - real_buffer[6] = data->block_descriptor_length >> 8; - real_buffer[7] = data->block_descriptor_length; + put_unaligned_be16(data->block_descriptor_length, + &real_buffer[6]); cmd[0] = MODE_SELECT_10; - cmd[7] = len >> 8; - cmd[8] = len; + put_unaligned_be16(len, &cmd[7]); } else { - if (len > 255 || data->block_descriptor_length > 255 || - data->longlba) + if (data->longlba) return -EINVAL; real_buffer = kmalloc(4 + len, GFP_KERNEL); From c749301ebee82eb5e97dec14b6ab31a4aabe37a6 Mon Sep 17 00:00:00 2001 From: Damien Le Moal Date: Fri, 20 Aug 2021 16:02:55 +0900 Subject: [PATCH 064/279] scsi: sd: Fix sd_do_mode_sense() buffer length handling For devices that explicitly asked for MODE SENSE(10) use, make sure that scsi_mode_sense() is called with a buffer of at least 8 bytes so that the sense header fits. Link: https://lore.kernel.org/r/20210820070255.682775-4-damien.lemoal@wdc.com Signed-off-by: Damien Le Moal Signed-off-by: Martin K. Petersen --- drivers/scsi/sd.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index cbd9999f93a6..71fa70b42c2b 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -2604,6 +2604,13 @@ sd_do_mode_sense(struct scsi_disk *sdkp, int dbd, int modepage, unsigned char *buffer, int len, struct scsi_mode_data *data, struct scsi_sense_hdr *sshdr) { + /* + * If we must use MODE SENSE(10), make sure that the buffer length + * is at least 8 bytes so that the mode sense header fits. + */ + if (sdkp->device->use_10_for_ms && len < 8) + len = 8; + return scsi_mode_sense(sdkp->device, dbd, modepage, buffer, len, SD_TIMEOUT, sdkp->max_retries, data, sshdr); From e9076e7f23aa087f8b7257f3be9e9586f341e3b1 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Wed, 29 Sep 2021 11:23:18 -0700 Subject: [PATCH 065/279] scsi: core: Fix spelling in a source code comment The typo in this source code comment makes the comment confusing. Clear up the confusion by fixing the typo. Link: https://lore.kernel.org/r/20210929182318.2060489-1-bvanassche@acm.org Fixes: bc85dc500f9d ("scsi: remove scsi_end_request") Cc: Christoph Hellwig Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/scsi_lib.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index dcf105287a76..5f5ad22512f5 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c @@ -949,7 +949,7 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes) /* * If there had been no error, but we have leftover bytes in the - * requeues just queue the command up again. + * request just queue the command up again. */ if (likely(result == 0)) scsi_io_completion_reprep(cmd, q); From 1da3b0141e74c18c2377d4c2655406a90a87742f Mon Sep 17 00:00:00 2001 From: Bean Huo Date: Wed, 29 Sep 2021 22:06:38 +0200 Subject: [PATCH 066/279] scsi: ufs: core: Fix NULL pointer dereference Calling ufshcd_rpm_{get/put}_sync() prior to ufshcd_scsi_add_wlus() being called will trigger a NULL pointer dereference. This is because hba->sdev_ufs_device is initialized in ufshcd_scsi_add_wlus(). Unable to handle kernel NULL pointer dereference at virtual address 0000000000000348 Mem abort info: ESR = 0x96000004 EC = 0x25: DABT (current EL), IL = 32 bits SET = 0, FnV = 0 EA = 0, S1PTW = 0 FSC = 0x04: level 0 translation fault Data abort info: ISV = 0, ISS = 0x00000004 CM = 0, WnR = 0 [0000000000000348] user address but active_mm is swapper Internal error: Oops: 96000004 [#1] PREEMPT SMP Modules linked in: CPU: 0 PID: 91 Comm: kworker/u16:1 Not tainted 5.15.0-rc1-beanhuo-linaro-1423 Hardware name: MicronRB (DT) Workqueue: events_unbound async_run_entry_fn pstate: 20000005 (nzCv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--) pc : pm_runtime_drop_link+0x128/0x338 lr : ufshpb_get_dev_info+0x8c/0x148 sp : ffff800012573c10 x29: ffff800012573c10 x28: 0000000000000000 x27: 0000000000000003 x26: ffff000001d21298 x25: 000000005abcea60 x24: ffff800011d89000 x23: 0000000000000001 x22: ffff000001d21880 x21: ffff000001ec9300 x20: 0000000000000004 x19: 0000000000000198 x18: ffffffffffffffff x17: 0000000000000000 x16: 0000000000000000 x15: 0000000000041400 x14: 5eee00201100200a x13: 000000000000bb03 x12: 0000000000000000 x11: 0000000000000100 x10: 0200000000000000 x9 : bb0000021a162c01 x8 : 0302010021021003 x7 : 0000000000000000 x6 : ffff800012573af0 x5 : 0000000000000001 x4 : 0000000000000001 x3 : 0000000000000200 x2 : 0000000000000348 x1 : 0000000000000348 x0 : ffff80001095308c Call trace: pm_runtime_drop_link+0x128/0x338 ufshpb_get_dev_info+0x8c/0x148 ufshcd_probe_hba+0xda0/0x11b8 ufshcd_async_scan+0x34/0x330 async_run_entry_fn+0x38/0x180 process_one_work+0x1f4/0x498 worker_thread+0x48/0x480 kthread+0x140/0x158 ret_from_fork+0x10/0x20 Code: 88027c01 35ffffa2 17fff6c4 f9800051 (885f7c40) ---[ end trace 2ba541335f595c95 ] ufshpb_get_dev_info() is only called during asynchronous scanning and at that time pm_runtime_get_sync() has been called: ... /* Hold auto suspend until async scan completes */ pm_runtime_get_sync(dev); atomic_set(&hba->scsi_block_reqs_cnt, 0); ... ufshcd_async_scan() ufshcd_probe_hba(hba, true); ufshcd_device_params_init(hba); ufshpb_get_dev_info(); ... pm_runtime_put_sync(hba->dev); Remove ufshcd_rpm_{get/put}_sync() from ufshpb_get_dev_info() to fix this problem. Link: https://lore.kernel.org/r/20210929200640.828611-2-huobean@gmail.com Fixes: 351b3a849ac7 ("scsi: ufs: ufshpb: Use proper power management API") Signed-off-by: Bean Huo Signed-off-by: Martin K. Petersen --- drivers/scsi/ufs/ufshpb.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/scsi/ufs/ufshpb.c b/drivers/scsi/ufs/ufshpb.c index 9ea639bf6a59..33a38c06a296 100644 --- a/drivers/scsi/ufs/ufshpb.c +++ b/drivers/scsi/ufs/ufshpb.c @@ -2877,11 +2877,8 @@ void ufshpb_get_dev_info(struct ufs_hba *hba, u8 *desc_buf) if (version == HPB_SUPPORT_LEGACY_VERSION) hpb_dev_info->is_legacy = true; - ufshcd_rpm_get_sync(hba); ret = ufshcd_query_attr_retry(hba, UPIU_QUERY_OPCODE_READ_ATTR, QUERY_ATTR_IDN_MAX_HPB_SINGLE_CMD, 0, 0, &max_hpb_single_cmd); - ufshcd_rpm_put_sync(hba); - if (ret) dev_err(hba->dev, "%s: idn: read max size of single hpb cmd query request failed", __func__); From 68444d73d6a5864ede12df6366bd6602e022ae5b Mon Sep 17 00:00:00 2001 From: Bean Huo Date: Wed, 29 Sep 2021 22:06:39 +0200 Subject: [PATCH 067/279] scsi: ufs: core: Fix ufshcd_probe_hba() prototype to match the definition Since commit 568dd9959611 ("scsi: ufs: Rename the second ufshcd_probe_hba() argument"), the second ufshcd_probe_hba() argument has been changed to init_dev_params. Link: https://lore.kernel.org/r/20210929200640.828611-3-huobean@gmail.com Fixes: 568dd9959611 ("scsi: ufs: Rename the second ufshcd_probe_hba() argument") Reviewed-by: Bart Van Assche Signed-off-by: Bean Huo Signed-off-by: Martin K. Petersen --- drivers/scsi/ufs/ufshcd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index 9faf02cbb9ad..e9120e6c5d62 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -225,7 +225,7 @@ static int ufshcd_eh_host_reset_handler(struct scsi_cmnd *cmd); static int ufshcd_clear_tm_cmd(struct ufs_hba *hba, int tag); static void ufshcd_hba_exit(struct ufs_hba *hba); static int ufshcd_clear_ua_wluns(struct ufs_hba *hba); -static int ufshcd_probe_hba(struct ufs_hba *hba, bool async); +static int ufshcd_probe_hba(struct ufs_hba *hba, bool init_dev_params); static int ufshcd_setup_clocks(struct ufs_hba *hba, bool on); static inline void ufshcd_add_delay_before_dme_cmd(struct ufs_hba *hba); static int ufshcd_host_reset_and_restore(struct ufs_hba *hba); From f44abcfc3f9f570970f71e790ec625cf26a27021 Mon Sep 17 00:00:00 2001 From: Bean Huo Date: Wed, 29 Sep 2021 22:06:40 +0200 Subject: [PATCH 068/279] scsi: ufs: core: Remove return statement in void function Return statement is not useful at the end of "void" function. Link: https://lore.kernel.org/r/20210929200640.828611-4-huobean@gmail.com Signed-off-by: Bean Huo Signed-off-by: Martin K. Petersen --- drivers/scsi/ufs/ufshcd.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index e9120e6c5d62..7126b7a88b56 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -5845,7 +5845,6 @@ static void ufshcd_exception_event_handler(struct work_struct *work) ufs_debugfs_exception_event(hba, status); out: ufshcd_scsi_unblock_requests(hba); - return; } /* Complete requests that have door-bell cleared */ From af21c3fd5b3ec540a97b367a70b26616ff7e0c55 Mon Sep 17 00:00:00 2001 From: Jaegeuk Kim Date: Fri, 1 Oct 2021 11:20:14 -0700 Subject: [PATCH 069/279] scsi: ufs: core: Retry START_STOP on UNIT_ATTENTION Commit 57d104c153d3 ("ufs: add UFS power management support") made the UFS driver submit a REQUEST SENSE command before submitting a power management command to a WLUN to clear the POWER ON unit attention. Instead of submitting a REQUEST SENSE command before submitting a power management command, retry the power management command until it succeeds. This is the preparation to get rid of all UNIT ATTENTION code which should be handled by users. Link: https://lore.kernel.org/r/20211001182015.1347587-2-jaegeuk@kernel.org Cc: Adrian Hunter Reviewed-by: Bart Van Assche Signed-off-by: Jaegeuk Kim Signed-off-by: Martin K. Petersen --- drivers/scsi/ufs/ufshcd.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index 7126b7a88b56..db5f375d89c5 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -8675,7 +8675,7 @@ static int ufshcd_set_dev_pwr_mode(struct ufs_hba *hba, struct scsi_sense_hdr sshdr; struct scsi_device *sdp; unsigned long flags; - int ret; + int ret, retries; spin_lock_irqsave(hba->host->host_lock, flags); sdp = hba->sdev_ufs_device; @@ -8710,8 +8710,14 @@ static int ufshcd_set_dev_pwr_mode(struct ufs_hba *hba, * callbacks hence set the RQF_PM flag so that it doesn't resume the * already suspended childs. */ - ret = scsi_execute(sdp, cmd, DMA_NONE, NULL, 0, NULL, &sshdr, - START_STOP_TIMEOUT, 0, 0, RQF_PM, NULL); + for (retries = 3; retries > 0; --retries) { + ret = scsi_execute(sdp, cmd, DMA_NONE, NULL, 0, NULL, &sshdr, + START_STOP_TIMEOUT, 0, 0, RQF_PM, NULL); + if (!scsi_status_is_check_condition(ret) || + !scsi_sense_valid(&sshdr) || + sshdr.sense_key != UNIT_ATTENTION) + break; + } if (ret) { sdev_printk(KERN_WARNING, sdp, "START_STOP failed for power mode: %d, result %x\n", From edc0596cc04bf0ac3a69c66e994d3ff8b650ff71 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Fri, 1 Oct 2021 11:20:15 -0700 Subject: [PATCH 070/279] scsi: ufs: core: Stop clearing UNIT ATTENTIONS Commit aa53f580e67b ("scsi: ufs: Minor adjustments to error handling") introduced a ufshcd_clear_ua_wluns() call in ufshcd_err_handling_unprepare(). As explained in detail by Adrian Hunter, this can trigger a deadlock. Avoid that deadlock by removing the code that clears the unit attention. This is safe because the only software that relies on clearing unit attentions is the Android Trusty software and because support for handling unit attentions has been added in the Trusty software. See also https://lore.kernel.org/linux-scsi/20210930124224.114031-2-adrian.hunter@intel.com/ Note that "scsi: ufs: Retry START_STOP on UNIT_ATTENTION" is a prerequisite for this commit. Link: https://lore.kernel.org/r/20211001182015.1347587-3-jaegeuk@kernel.org Fixes: aa53f580e67b ("scsi: ufs: Minor adjustments to error handling") Cc: Adrian Hunter Signed-off-by: Bart Van Assche Signed-off-by: Jaegeuk Kim Signed-off-by: Martin K. Petersen --- drivers/scsi/ufs/ufshcd.c | 184 +------------------------------------- drivers/scsi/ufs/ufshcd.h | 14 --- 2 files changed, 1 insertion(+), 197 deletions(-) diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index db5f375d89c5..47236ee93a0e 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -224,7 +224,6 @@ static int ufshcd_reset_and_restore(struct ufs_hba *hba); static int ufshcd_eh_host_reset_handler(struct scsi_cmnd *cmd); static int ufshcd_clear_tm_cmd(struct ufs_hba *hba, int tag); static void ufshcd_hba_exit(struct ufs_hba *hba); -static int ufshcd_clear_ua_wluns(struct ufs_hba *hba); static int ufshcd_probe_hba(struct ufs_hba *hba, bool init_dev_params); static int ufshcd_setup_clocks(struct ufs_hba *hba, bool on); static inline void ufshcd_add_delay_before_dme_cmd(struct ufs_hba *hba); @@ -4108,8 +4107,6 @@ int ufshcd_link_recovery(struct ufs_hba *hba) if (ret) dev_err(hba->dev, "%s: link recovery failed, err %d", __func__, ret); - else - ufshcd_clear_ua_wluns(hba); return ret; } @@ -5994,7 +5991,6 @@ static void ufshcd_err_handling_unprepare(struct ufs_hba *hba) ufshcd_release(hba); if (ufshcd_is_clkscaling_supported(hba)) ufshcd_clk_scaling_suspend(hba, false); - ufshcd_clear_ua_wluns(hba); ufshcd_rpm_put(hba); } @@ -7952,8 +7948,6 @@ static int ufshcd_add_lus(struct ufs_hba *hba) if (ret) goto out; - ufshcd_clear_ua_wluns(hba); - /* Initialize devfreq after UFS device is detected */ if (ufshcd_is_clkscaling_supported(hba)) { memcpy(&hba->clk_scaling.saved_pwr_info.info, @@ -7979,116 +7973,6 @@ out: return ret; } -static void ufshcd_request_sense_done(struct request *rq, blk_status_t error) -{ - if (error != BLK_STS_OK) - pr_err("%s: REQUEST SENSE failed (%d)\n", __func__, error); - kfree(rq->end_io_data); - blk_put_request(rq); -} - -static int -ufshcd_request_sense_async(struct ufs_hba *hba, struct scsi_device *sdev) -{ - /* - * Some UFS devices clear unit attention condition only if the sense - * size used (UFS_SENSE_SIZE in this case) is non-zero. - */ - static const u8 cmd[6] = {REQUEST_SENSE, 0, 0, 0, UFS_SENSE_SIZE, 0}; - struct scsi_request *rq; - struct request *req; - char *buffer; - int ret; - - buffer = kzalloc(UFS_SENSE_SIZE, GFP_KERNEL); - if (!buffer) - return -ENOMEM; - - req = blk_get_request(sdev->request_queue, REQ_OP_DRV_IN, - /*flags=*/BLK_MQ_REQ_PM); - if (IS_ERR(req)) { - ret = PTR_ERR(req); - goto out_free; - } - - ret = blk_rq_map_kern(sdev->request_queue, req, - buffer, UFS_SENSE_SIZE, GFP_NOIO); - if (ret) - goto out_put; - - rq = scsi_req(req); - rq->cmd_len = ARRAY_SIZE(cmd); - memcpy(rq->cmd, cmd, rq->cmd_len); - rq->retries = 3; - req->timeout = 1 * HZ; - req->rq_flags |= RQF_PM | RQF_QUIET; - req->end_io_data = buffer; - - blk_execute_rq_nowait(/*bd_disk=*/NULL, req, /*at_head=*/true, - ufshcd_request_sense_done); - return 0; - -out_put: - blk_put_request(req); -out_free: - kfree(buffer); - return ret; -} - -static int ufshcd_clear_ua_wlun(struct ufs_hba *hba, u8 wlun) -{ - struct scsi_device *sdp; - unsigned long flags; - int ret = 0; - - spin_lock_irqsave(hba->host->host_lock, flags); - if (wlun == UFS_UPIU_UFS_DEVICE_WLUN) - sdp = hba->sdev_ufs_device; - else if (wlun == UFS_UPIU_RPMB_WLUN) - sdp = hba->sdev_rpmb; - else - BUG(); - if (sdp) { - ret = scsi_device_get(sdp); - if (!ret && !scsi_device_online(sdp)) { - ret = -ENODEV; - scsi_device_put(sdp); - } - } else { - ret = -ENODEV; - } - spin_unlock_irqrestore(hba->host->host_lock, flags); - if (ret) - goto out_err; - - ret = ufshcd_request_sense_async(hba, sdp); - scsi_device_put(sdp); -out_err: - if (ret) - dev_err(hba->dev, "%s: UAC clear LU=%x ret = %d\n", - __func__, wlun, ret); - return ret; -} - -static int ufshcd_clear_ua_wluns(struct ufs_hba *hba) -{ - int ret = 0; - - if (!hba->wlun_dev_clr_ua) - goto out; - - ret = ufshcd_clear_ua_wlun(hba, UFS_UPIU_UFS_DEVICE_WLUN); - if (!ret) - ret = ufshcd_clear_ua_wlun(hba, UFS_UPIU_RPMB_WLUN); - if (!ret) - hba->wlun_dev_clr_ua = false; -out: - if (ret) - dev_err(hba->dev, "%s: Failed to clear UAC WLUNS ret = %d\n", - __func__, ret); - return ret; -} - /** * ufshcd_probe_hba - probe hba to detect device and initialize it * @hba: per-adapter instance @@ -8139,8 +8023,6 @@ static int ufshcd_probe_hba(struct ufs_hba *hba, bool init_dev_params) /* UFS device is also active now */ ufshcd_set_ufs_dev_active(hba); ufshcd_force_reset_auto_bkops(hba); - hba->wlun_dev_clr_ua = true; - hba->wlun_rpmb_clr_ua = true; /* Gear up to HS gear if supported */ if (hba->max_pwr_info.is_valid) { @@ -8700,8 +8582,6 @@ static int ufshcd_set_dev_pwr_mode(struct ufs_hba *hba, * handling context. */ hba->host->eh_noresume = 1; - if (hba->wlun_dev_clr_ua) - ufshcd_clear_ua_wlun(hba, UFS_UPIU_UFS_DEVICE_WLUN); cmd[4] = pwr_mode << 4; @@ -9767,10 +9647,6 @@ void ufshcd_resume_complete(struct device *dev) ufshcd_rpm_put(hba); hba->complete_put = false; } - if (hba->rpmb_complete_put) { - ufshcd_rpmb_rpm_put(hba); - hba->rpmb_complete_put = false; - } } EXPORT_SYMBOL_GPL(ufshcd_resume_complete); @@ -9793,10 +9669,6 @@ int ufshcd_suspend_prepare(struct device *dev) } hba->complete_put = true; } - if (hba->sdev_rpmb) { - ufshcd_rpmb_rpm_get_sync(hba); - hba->rpmb_complete_put = true; - } return 0; } EXPORT_SYMBOL_GPL(ufshcd_suspend_prepare); @@ -9865,49 +9737,6 @@ static struct scsi_driver ufs_dev_wlun_template = { }, }; -static int ufshcd_rpmb_probe(struct device *dev) -{ - return is_rpmb_wlun(to_scsi_device(dev)) ? 0 : -ENODEV; -} - -static inline int ufshcd_clear_rpmb_uac(struct ufs_hba *hba) -{ - int ret = 0; - - if (!hba->wlun_rpmb_clr_ua) - return 0; - ret = ufshcd_clear_ua_wlun(hba, UFS_UPIU_RPMB_WLUN); - if (!ret) - hba->wlun_rpmb_clr_ua = 0; - return ret; -} - -#ifdef CONFIG_PM -static int ufshcd_rpmb_resume(struct device *dev) -{ - struct ufs_hba *hba = wlun_dev_to_hba(dev); - - if (hba->sdev_rpmb) - ufshcd_clear_rpmb_uac(hba); - return 0; -} -#endif - -static const struct dev_pm_ops ufs_rpmb_pm_ops = { - SET_RUNTIME_PM_OPS(NULL, ufshcd_rpmb_resume, NULL) - SET_SYSTEM_SLEEP_PM_OPS(NULL, ufshcd_rpmb_resume) -}; - -/* ufs_rpmb_wlun_template - Describes UFS RPMB WLUN. Used only to send UAC. */ -static struct scsi_driver ufs_rpmb_wlun_template = { - .gendrv = { - .name = "ufs_rpmb_wlun", - .owner = THIS_MODULE, - .probe = ufshcd_rpmb_probe, - .pm = &ufs_rpmb_pm_ops, - }, -}; - static int __init ufshcd_core_init(void) { int ret; @@ -9916,24 +9745,13 @@ static int __init ufshcd_core_init(void) ret = scsi_register_driver(&ufs_dev_wlun_template.gendrv); if (ret) - goto debugfs_exit; - - ret = scsi_register_driver(&ufs_rpmb_wlun_template.gendrv); - if (ret) - goto unregister; - - return ret; -unregister: - scsi_unregister_driver(&ufs_dev_wlun_template.gendrv); -debugfs_exit: - ufs_debugfs_exit(); + ufs_debugfs_exit(); return ret; } static void __exit ufshcd_core_exit(void) { ufs_debugfs_exit(); - scsi_unregister_driver(&ufs_rpmb_wlun_template.gendrv); scsi_unregister_driver(&ufs_dev_wlun_template.gendrv); } diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h index ed960d206260..782bbe6d5a52 100644 --- a/drivers/scsi/ufs/ufshcd.h +++ b/drivers/scsi/ufs/ufshcd.h @@ -875,9 +875,6 @@ struct ufs_hba { struct ufs_vreg_info vreg_info; struct list_head clk_list_head; - bool wlun_dev_clr_ua; - bool wlun_rpmb_clr_ua; - /* Number of requests aborts */ int req_abort_count; @@ -924,7 +921,6 @@ struct ufs_hba { #endif u32 luns_avail; bool complete_put; - bool rpmb_complete_put; }; /* Returns true if clocks can be gated. Otherwise false */ @@ -1408,14 +1404,4 @@ static inline int ufshcd_rpm_put(struct ufs_hba *hba) return pm_runtime_put(&hba->sdev_ufs_device->sdev_gendev); } -static inline int ufshcd_rpmb_rpm_get_sync(struct ufs_hba *hba) -{ - return pm_runtime_get_sync(&hba->sdev_rpmb->sdev_gendev); -} - -static inline int ufshcd_rpmb_rpm_put(struct ufs_hba *hba) -{ - return pm_runtime_put(&hba->sdev_rpmb->sdev_gendev); -} - #endif /* End of Header */ From 54a4045342a8bffabde1827bfd6d86b63163111d Mon Sep 17 00:00:00 2001 From: Adrian Hunter Date: Sat, 2 Oct 2021 18:45:49 +0300 Subject: [PATCH 071/279] scsi: ufs: core: Do not exit ufshcd_reset_and_restore() unless operational or dead Callers of ufshcd_reset_and_restore() expect it to return in an operational state. However, the code only checks direct errors and so the ufshcd_state may not be UFSHCD_STATE_OPERATIONAL due to error interrupts. Fix by also checking ufshcd_state, still allowing non-fatal errors which are left for the error handler to deal with. Link: https://lore.kernel.org/r/20211002154550.128511-2-adrian.hunter@intel.com Reviewed-by: Avri altman Signed-off-by: Adrian Hunter Signed-off-by: Martin K. Petersen --- drivers/scsi/ufs/ufshcd.c | 36 +++++++++++++++++++++++------------- 1 file changed, 23 insertions(+), 13 deletions(-) diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index 47236ee93a0e..9f53a154cde5 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -7151,31 +7151,41 @@ static int ufshcd_host_reset_and_restore(struct ufs_hba *hba) */ static int ufshcd_reset_and_restore(struct ufs_hba *hba) { - u32 saved_err; - u32 saved_uic_err; + u32 saved_err = 0; + u32 saved_uic_err = 0; int err = 0; unsigned long flags; int retries = MAX_HOST_RESET_RETRIES; - /* - * This is a fresh start, cache and clear saved error first, - * in case new error generated during reset and restore. - */ spin_lock_irqsave(hba->host->host_lock, flags); - saved_err = hba->saved_err; - saved_uic_err = hba->saved_uic_err; - hba->saved_err = 0; - hba->saved_uic_err = 0; - spin_unlock_irqrestore(hba->host->host_lock, flags); - do { + /* + * This is a fresh start, cache and clear saved error first, + * in case new error generated during reset and restore. + */ + saved_err |= hba->saved_err; + saved_uic_err |= hba->saved_uic_err; + hba->saved_err = 0; + hba->saved_uic_err = 0; + hba->force_reset = false; + hba->ufshcd_state = UFSHCD_STATE_RESET; + spin_unlock_irqrestore(hba->host->host_lock, flags); + /* Reset the attached device */ ufshcd_device_reset(hba); err = ufshcd_host_reset_and_restore(hba); + + spin_lock_irqsave(hba->host->host_lock, flags); + if (err) + continue; + /* Do not exit unless operational or dead */ + if (hba->ufshcd_state != UFSHCD_STATE_OPERATIONAL && + hba->ufshcd_state != UFSHCD_STATE_ERROR && + hba->ufshcd_state != UFSHCD_STATE_EH_SCHEDULED_NON_FATAL) + err = -EAGAIN; } while (err && --retries); - spin_lock_irqsave(hba->host->host_lock, flags); /* * Inform scsi mid-layer that we did reset and allow to handle * Unit Attention properly. From 87bf6a6bbe8bd62b5924b00161d28a0d6df151ca Mon Sep 17 00:00:00 2001 From: Adrian Hunter Date: Sat, 2 Oct 2021 18:45:50 +0300 Subject: [PATCH 072/279] scsi: ufs: core: Do not exit ufshcd_err_handler() unless operational or dead Callers of ufshcd_err_handler() expect it to return in an operational state. However, the code does not check the state before exiting. Add a check for the state and perform retries until either success or the maximum number of retries is reached. Link: https://lore.kernel.org/r/20211002154550.128511-3-adrian.hunter@intel.com Reviewed-by: Avri Altman Signed-off-by: Adrian Hunter Signed-off-by: Martin K. Petersen --- drivers/scsi/ufs/ufshcd.c | 28 ++++++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index 9f53a154cde5..d91a405fd181 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -64,6 +64,9 @@ /* maximum number of reset retries before giving up */ #define MAX_HOST_RESET_RETRIES 5 +/* Maximum number of error handler retries before giving up */ +#define MAX_ERR_HANDLER_RETRIES 5 + /* Expose the flag value from utp_upiu_query.value */ #define MASK_QUERY_UPIU_FLAG_LOC 0xFF @@ -6065,12 +6068,14 @@ static bool ufshcd_is_pwr_mode_restore_needed(struct ufs_hba *hba) static void ufshcd_err_handler(struct Scsi_Host *host) { struct ufs_hba *hba = shost_priv(host); + int retries = MAX_ERR_HANDLER_RETRIES; unsigned long flags; - bool err_xfer = false; - bool err_tm = false; - int err = 0, pmc_err; + bool needs_restore; + bool needs_reset; + bool err_xfer; + bool err_tm; + int pmc_err; int tag; - bool needs_reset = false, needs_restore = false; down(&hba->host_sem); spin_lock_irqsave(hba->host->host_lock, flags); @@ -6088,6 +6093,12 @@ static void ufshcd_err_handler(struct Scsi_Host *host) /* Complete requests that have door-bell cleared by h/w */ ufshcd_complete_requests(hba); spin_lock_irqsave(hba->host->host_lock, flags); +again: + needs_restore = false; + needs_reset = false; + err_xfer = false; + err_tm = false; + if (hba->ufshcd_state != UFSHCD_STATE_ERROR) hba->ufshcd_state = UFSHCD_STATE_RESET; /* @@ -6208,6 +6219,8 @@ lock_skip_pending_xfer_clear: do_reset: /* Fatal errors need reset */ if (needs_reset) { + int err; + hba->force_reset = false; spin_unlock_irqrestore(hba->host->host_lock, flags); err = ufshcd_reset_and_restore(hba); @@ -6227,6 +6240,13 @@ skip_err_handling: dev_err_ratelimited(hba->dev, "%s: exit: saved_err 0x%x saved_uic_err 0x%x", __func__, hba->saved_err, hba->saved_uic_err); } + /* Exit in an operational state or dead */ + if (hba->ufshcd_state != UFSHCD_STATE_OPERATIONAL && + hba->ufshcd_state != UFSHCD_STATE_ERROR) { + if (--retries) + goto again; + hba->ufshcd_state = UFSHCD_STATE_ERROR; + } ufshcd_clear_eh_in_progress(hba); spin_unlock_irqrestore(hba->host->host_lock, flags); ufshcd_err_handling_unprepare(hba); From 05787e3456ffcc8598aab632fcd5d160894619b3 Mon Sep 17 00:00:00 2001 From: Konstantin Shelekhin Date: Wed, 29 Sep 2021 14:50:00 +0300 Subject: [PATCH 073/279] scsi: target: core: Make logs less verbose Change the log level of the following message to debug: Unsupported SCSI Opcode 0xXX, sending CHECK_CONDITION. This message is mostly helpful during debugging sessions in order to understand errors on the initiator side. But most of the time it's just useless and makes reading logs much harder. It gets particularly annoying if there are many initiators that come and go or if an initiator runs a program that does not care whether the command is supported and just keeps sending it. Link: https://lore.kernel.org/r/20210929114959.705852-1-k.shelekhin@yadro.com Reviewed-by: Roman Bolshakov Reviewed-by: Lee Duncan Signed-off-by: Konstantin Shelekhin Signed-off-by: Martin K. Petersen --- drivers/target/target_core_transport.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c index 14c6f2bb1b01..4a0055ab9151 100644 --- a/drivers/target/target_core_transport.c +++ b/drivers/target/target_core_transport.c @@ -1511,10 +1511,10 @@ target_cmd_parse_cdb(struct se_cmd *cmd) ret = dev->transport->parse_cdb(cmd); if (ret == TCM_UNSUPPORTED_SCSI_OPCODE) - pr_warn_ratelimited("%s/%s: Unsupported SCSI Opcode 0x%02x, sending CHECK_CONDITION.\n", - cmd->se_tfo->fabric_name, - cmd->se_sess->se_node_acl->initiatorname, - cmd->t_task_cdb[0]); + pr_debug_ratelimited("%s/%s: Unsupported SCSI Opcode 0x%02x, sending CHECK_CONDITION.\n", + cmd->se_tfo->fabric_name, + cmd->se_sess->se_node_acl->initiatorname, + cmd->t_task_cdb[0]); if (ret) return ret; From d4996c6eac4c81b8872043e9391563f67f13e406 Mon Sep 17 00:00:00 2001 From: Guo Zhi Date: Wed, 29 Sep 2021 20:25:37 +0800 Subject: [PATCH 074/279] scsi: advansys: Fix kernel pointer leak Pointers should be printed with %p or %px rather than cast to 'unsigned long' and printed with %lx. Change %lx to %p to print the hashed pointer. Link: https://lore.kernel.org/r/20210929122538.1158235-1-qtxuning1999@sjtu.edu.cn Signed-off-by: Guo Zhi Signed-off-by: Martin K. Petersen --- drivers/scsi/advansys.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/advansys.c b/drivers/scsi/advansys.c index e341b3372482..2df2a843a5ff 100644 --- a/drivers/scsi/advansys.c +++ b/drivers/scsi/advansys.c @@ -3308,8 +3308,8 @@ static void asc_prt_adv_board_info(struct seq_file *m, struct Scsi_Host *shost) shost->host_no); seq_printf(m, - " iop_base 0x%lx, cable_detect: %X, err_code %u\n", - (unsigned long)v->iop_base, + " iop_base 0x%p, cable_detect: %X, err_code %u\n", + v->iop_base, AdvReadWordRegister(iop_base,IOPW_SCSI_CFG1) & CABLE_DETECT, v->err_code); From e7dcc514a49e74051b869697d5ab0370f6301d57 Mon Sep 17 00:00:00 2001 From: Sumit Saxena Date: Wed, 29 Sep 2021 18:10:20 +0530 Subject: [PATCH 075/279] scsi: megaraid_sas: Fix concurrent access to ISR between IRQ polling and real interrupt IRQ polling thread calls ISR after enable_irq() to handle any missed I/O completion. The atomic flag "in_used" was added to have the synchronization between the IRQ polling thread and the interrupt context. There is a bug around it leading to a race condition. Below is the sequence: - IRQ polling thread accesses ISR, fetches the reply descriptor. - Real interrupt arrives and pre-empts polling thread (enable_irq() is already called). - Interrupt context picks the same reply descriptor as fetched by polling thread, processes it, and exits. - Polling thread resumes and processes the descriptor which is already processed by interrupt thread leads to kernel crash. Setting the "in_used" flag before fetching the reply descriptor ensures synchronized access to ISR. Link: https://www.spinics.net/lists/linux-scsi/msg159440.html Link: https://lore.kernel.org/r/20210929124022.24605-2-sumit.saxena@broadcom.com Fixes: 9bedd36e9146 ("scsi: megaraid_sas: Handle missing interrupts while re-enabling IRQs") Signed-off-by: Sumit Saxena Signed-off-by: Martin K. Petersen --- drivers/scsi/megaraid/megaraid_sas_fusion.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c index 26d0cf9353dd..eb5ceb75a15e 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fusion.c +++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c @@ -3530,6 +3530,9 @@ complete_cmd_fusion(struct megasas_instance *instance, u32 MSIxIndex, if (atomic_read(&instance->adprecovery) == MEGASAS_HW_CRITICAL_ERROR) return IRQ_HANDLED; + if (irq_context && !atomic_add_unless(&irq_context->in_used, 1, 1)) + return 0; + desc = fusion->reply_frames_desc[MSIxIndex] + fusion->last_reply_idx[MSIxIndex]; @@ -3540,11 +3543,11 @@ complete_cmd_fusion(struct megasas_instance *instance, u32 MSIxIndex, reply_descript_type = reply_desc->ReplyFlags & MPI2_RPY_DESCRIPT_FLAGS_TYPE_MASK; - if (reply_descript_type == MPI2_RPY_DESCRIPT_FLAGS_UNUSED) + if (reply_descript_type == MPI2_RPY_DESCRIPT_FLAGS_UNUSED) { + if (irq_context) + atomic_dec(&irq_context->in_used); return IRQ_NONE; - - if (irq_context && !atomic_add_unless(&irq_context->in_used, 1, 1)) - return 0; + } num_completed = 0; From 4c32edc350e4bebd93db1d63f506f4f343e23bd1 Mon Sep 17 00:00:00 2001 From: Sumit Saxena Date: Wed, 29 Sep 2021 18:10:21 +0530 Subject: [PATCH 076/279] scsi: megaraid_sas: Add helper functions for irq_context Adding helper functions for ISR access and release to improve readability. Link: https://lore.kernel.org/r/20210929124022.24605-3-sumit.saxena@broadcom.com Signed-off-by: Sumit Saxena Signed-off-by: Martin K. Petersen --- drivers/scsi/megaraid/megaraid_sas_fusion.c | 45 ++++++++++++++++++--- 1 file changed, 39 insertions(+), 6 deletions(-) diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c index eb5ceb75a15e..109782e3ec44 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fusion.c +++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c @@ -3497,6 +3497,41 @@ megasas_complete_r1_command(struct megasas_instance *instance, } } +/** + * access_irq_context: Access to reply processing + * @irq_context: IRQ context + * + * Synchronize access to reply processing. + * + * Return: true on success, false on failure. + */ +static inline +bool access_irq_context(struct megasas_irq_context *irq_context) +{ + if (!irq_context) + return true; + + if (atomic_add_unless(&irq_context->in_used, 1, 1)) + return true; + + return false; +} + +/** + * release_irq_context: Release reply processing + * @irq_context: IRQ context + * + * Release access of reply processing. + * + * Return: Nothing. + */ +static inline +void release_irq_context(struct megasas_irq_context *irq_context) +{ + if (irq_context) + atomic_dec(&irq_context->in_used); +} + /** * complete_cmd_fusion - Completes command * @instance: Adapter soft state @@ -3530,7 +3565,7 @@ complete_cmd_fusion(struct megasas_instance *instance, u32 MSIxIndex, if (atomic_read(&instance->adprecovery) == MEGASAS_HW_CRITICAL_ERROR) return IRQ_HANDLED; - if (irq_context && !atomic_add_unless(&irq_context->in_used, 1, 1)) + if (!access_irq_context(irq_context)) return 0; desc = fusion->reply_frames_desc[MSIxIndex] + @@ -3544,8 +3579,7 @@ complete_cmd_fusion(struct megasas_instance *instance, u32 MSIxIndex, MPI2_RPY_DESCRIPT_FLAGS_TYPE_MASK; if (reply_descript_type == MPI2_RPY_DESCRIPT_FLAGS_UNUSED) { - if (irq_context) - atomic_dec(&irq_context->in_used); + release_irq_context(irq_context); return IRQ_NONE; } @@ -3663,7 +3697,7 @@ complete_cmd_fusion(struct megasas_instance *instance, u32 MSIxIndex, irq_context->irq_line_enable = true; irq_poll_sched(&irq_context->irqpoll); } - atomic_dec(&irq_context->in_used); + release_irq_context(irq_context); return num_completed; } } @@ -3682,8 +3716,7 @@ complete_cmd_fusion(struct megasas_instance *instance, u32 MSIxIndex, megasas_check_and_restore_queue_depth(instance); } - if (irq_context) - atomic_dec(&irq_context->in_used); + release_irq_context(irq_context); return num_completed; } From cdf7f6a10d48589a819a98f0e3dd262079a38120 Mon Sep 17 00:00:00 2001 From: Sumit Saxena Date: Wed, 29 Sep 2021 18:10:22 +0530 Subject: [PATCH 077/279] scsi: megaraid_sas: Driver version update to 07.719.03.00-rc1 Link: https://lore.kernel.org/r/20210929124022.24605-4-sumit.saxena@broadcom.com Signed-off-by: Sumit Saxena Signed-off-by: Martin K. Petersen --- drivers/scsi/megaraid/megaraid_sas.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/megaraid/megaraid_sas.h b/drivers/scsi/megaraid/megaraid_sas.h index 7af2c23652b0..2c9d1b796475 100644 --- a/drivers/scsi/megaraid/megaraid_sas.h +++ b/drivers/scsi/megaraid/megaraid_sas.h @@ -21,8 +21,8 @@ /* * MegaRAID SAS Driver meta data */ -#define MEGASAS_VERSION "07.717.02.00-rc1" -#define MEGASAS_RELDATE "May 19, 2021" +#define MEGASAS_VERSION "07.719.03.00-rc1" +#define MEGASAS_RELDATE "Sep 29, 2021" #define MEGASAS_MSIX_NAME_LEN 32 From 80ed33c8ba932480be99f73dc3f29e1f7da1582c Mon Sep 17 00:00:00 2001 From: Dmitry Bogdanov Date: Fri, 10 Sep 2021 11:41:27 +0300 Subject: [PATCH 078/279] scsi: target: core: Add common tpg/enable attribute Many fabric modules provide their own implementation of enable attribute in tpg. Provide a way to remove code duplication in the fabric modules and automatically add "enable" attribute if a fabric module has an implementation of fabric_enable_tpg(). Link: https://lore.kernel.org/r/20210910084133.17956-2-d.bogdanov@yadro.com Reviewed-by: Roman Bolshakov Reviewed-by: Mike Christie Signed-off-by: Dmitry Bogdanov Signed-off-by: Martin K. Petersen --- drivers/target/target_core_configfs.c | 1 + drivers/target/target_core_fabric_configfs.c | 78 +++++++++++++++++++- include/target/target_core_base.h | 1 + include/target/target_core_fabric.h | 1 + 4 files changed, 79 insertions(+), 2 deletions(-) diff --git a/drivers/target/target_core_configfs.c b/drivers/target/target_core_configfs.c index 102ec644bc8a..3b9e50c1ccef 100644 --- a/drivers/target/target_core_configfs.c +++ b/drivers/target/target_core_configfs.c @@ -490,6 +490,7 @@ void target_unregister_template(const struct target_core_fabric_ops *fo) * fabric driver unload of TFO->module to proceed. */ rcu_barrier(); + kfree(t->tf_tpg_base_cit.ct_attrs); kfree(t); return; } diff --git a/drivers/target/target_core_fabric_configfs.c b/drivers/target/target_core_fabric_configfs.c index fc7edc04ee09..0b65de9f2df1 100644 --- a/drivers/target/target_core_fabric_configfs.c +++ b/drivers/target/target_core_fabric_configfs.c @@ -815,8 +815,76 @@ static struct configfs_item_operations target_fabric_tpg_base_item_ops = { .release = target_fabric_tpg_release, }; -TF_CIT_SETUP_DRV(tpg_base, &target_fabric_tpg_base_item_ops, NULL); +static ssize_t target_fabric_tpg_base_enable_show(struct config_item *item, + char *page) +{ + return sysfs_emit(page, "%d\n", to_tpg(item)->enabled); +} +static ssize_t target_fabric_tpg_base_enable_store(struct config_item *item, + const char *page, + size_t count) +{ + struct se_portal_group *se_tpg = to_tpg(item); + int ret; + bool op; + + ret = strtobool(page, &op); + if (ret) + return ret; + + if (se_tpg->enabled == op) + return count; + + ret = se_tpg->se_tpg_tfo->fabric_enable_tpg(se_tpg, op); + if (ret) + return ret; + + se_tpg->enabled = op; + + return count; +} + +CONFIGFS_ATTR(target_fabric_tpg_base_, enable); + +static int +target_fabric_setup_tpg_base_cit(struct target_fabric_configfs *tf) +{ + struct config_item_type *cit = &tf->tf_tpg_base_cit; + struct configfs_attribute **attrs = NULL; + size_t nr_attrs = 0; + int i = 0; + + if (tf->tf_ops->tfc_tpg_base_attrs) + while (tf->tf_ops->tfc_tpg_base_attrs[nr_attrs] != NULL) + nr_attrs++; + + if (tf->tf_ops->fabric_enable_tpg) + nr_attrs++; + + if (nr_attrs == 0) + goto done; + + /* + 1 for final NULL in the array */ + attrs = kcalloc(nr_attrs + 1, sizeof(*attrs), GFP_KERNEL); + if (!attrs) + return -ENOMEM; + + if (tf->tf_ops->tfc_tpg_base_attrs) + for (; tf->tf_ops->tfc_tpg_base_attrs[i] != NULL; i++) + attrs[i] = tf->tf_ops->tfc_tpg_base_attrs[i]; + + if (tf->tf_ops->fabric_enable_tpg) + attrs[i] = &target_fabric_tpg_base_attr_enable; + +done: + cit->ct_item_ops = &target_fabric_tpg_base_item_ops; + cit->ct_attrs = attrs; + cit->ct_owner = tf->tf_ops->module; + pr_debug("Setup generic tpg_base\n"); + + return 0; +} /* End of tfc_tpg_base_cit */ /* Start of tfc_tpg_cit */ @@ -1028,12 +1096,18 @@ TF_CIT_SETUP_DRV(discovery, NULL, NULL); int target_fabric_setup_cits(struct target_fabric_configfs *tf) { + int ret; + target_fabric_setup_discovery_cit(tf); target_fabric_setup_wwn_cit(tf); target_fabric_setup_wwn_fabric_stats_cit(tf); target_fabric_setup_wwn_param_cit(tf); target_fabric_setup_tpg_cit(tf); - target_fabric_setup_tpg_base_cit(tf); + + ret = target_fabric_setup_tpg_base_cit(tf); + if (ret) + return ret; + target_fabric_setup_tpg_port_cit(tf); target_fabric_setup_tpg_port_stat_cit(tf); target_fabric_setup_tpg_lun_cit(tf); diff --git a/include/target/target_core_base.h b/include/target/target_core_base.h index fb11c7693b25..2130f102798d 100644 --- a/include/target/target_core_base.h +++ b/include/target/target_core_base.h @@ -900,6 +900,7 @@ struct se_portal_group { * Negative values can be used by fabric drivers for internal use TPGs. */ int proto_id; + bool enabled; /* Used for PR SPEC_I_PT=1 and REGISTER_AND_MOVE */ atomic_t tpg_pr_ref_count; /* Spinlock for adding/removing ACLed Nodes */ diff --git a/include/target/target_core_fabric.h b/include/target/target_core_fabric.h index 3c5ade7a04a6..38f0662476d1 100644 --- a/include/target/target_core_fabric.h +++ b/include/target/target_core_fabric.h @@ -89,6 +89,7 @@ struct target_core_fabric_ops { void (*add_wwn_groups)(struct se_wwn *); struct se_portal_group *(*fabric_make_tpg)(struct se_wwn *, const char *); + int (*fabric_enable_tpg)(struct se_portal_group *se_tpg, bool enable); void (*fabric_drop_tpg)(struct se_portal_group *); int (*fabric_post_link)(struct se_portal_group *, struct se_lun *); From 382731ec01b376ab32b29b9463e6718bbc18467b Mon Sep 17 00:00:00 2001 From: Dmitry Bogdanov Date: Fri, 10 Sep 2021 11:41:28 +0300 Subject: [PATCH 079/279] scsi: target: iscsi: Replace tpg enable attr with ops.enable Remove tpg/enable attribute. Add fabric ops enable_tpg implementation instead. Link: https://lore.kernel.org/r/20210910084133.17956-3-d.bogdanov@yadro.com Reviewed-by: Roman Bolshakov Reviewed-by: Mike Christie Signed-off-by: Dmitry Bogdanov Signed-off-by: Martin K. Petersen --- drivers/target/iscsi/iscsi_target_configfs.c | 91 +++++++------------- 1 file changed, 32 insertions(+), 59 deletions(-) diff --git a/drivers/target/iscsi/iscsi_target_configfs.c b/drivers/target/iscsi/iscsi_target_configfs.c index f4a24fa5058e..2a9de24a8bbe 100644 --- a/drivers/target/iscsi/iscsi_target_configfs.c +++ b/drivers/target/iscsi/iscsi_target_configfs.c @@ -1005,74 +1005,15 @@ static struct configfs_attribute *lio_target_tpg_param_attrs[] = { /* Start items for lio_target_tpg_cit */ -static ssize_t lio_target_tpg_enable_show(struct config_item *item, char *page) -{ - struct se_portal_group *se_tpg = to_tpg(item); - struct iscsi_portal_group *tpg = container_of(se_tpg, - struct iscsi_portal_group, tpg_se_tpg); - ssize_t len; - - spin_lock(&tpg->tpg_state_lock); - len = sprintf(page, "%d\n", - (tpg->tpg_state == TPG_STATE_ACTIVE) ? 1 : 0); - spin_unlock(&tpg->tpg_state_lock); - - return len; -} - -static ssize_t lio_target_tpg_enable_store(struct config_item *item, - const char *page, size_t count) -{ - struct se_portal_group *se_tpg = to_tpg(item); - struct iscsi_portal_group *tpg = container_of(se_tpg, - struct iscsi_portal_group, tpg_se_tpg); - u32 op; - int ret; - - ret = kstrtou32(page, 0, &op); - if (ret) - return ret; - if ((op != 1) && (op != 0)) { - pr_err("Illegal value for tpg_enable: %u\n", op); - return -EINVAL; - } - - ret = iscsit_get_tpg(tpg); - if (ret < 0) - return -EINVAL; - - if (op) { - ret = iscsit_tpg_enable_portal_group(tpg); - if (ret < 0) - goto out; - } else { - /* - * iscsit_tpg_disable_portal_group() assumes force=1 - */ - ret = iscsit_tpg_disable_portal_group(tpg, 1); - if (ret < 0) - goto out; - } - - iscsit_put_tpg(tpg); - return count; -out: - iscsit_put_tpg(tpg); - return -EINVAL; -} - - static ssize_t lio_target_tpg_dynamic_sessions_show(struct config_item *item, char *page) { return target_show_dynamic_sessions(to_tpg(item), page); } -CONFIGFS_ATTR(lio_target_tpg_, enable); CONFIGFS_ATTR_RO(lio_target_tpg_, dynamic_sessions); static struct configfs_attribute *lio_target_tpg_attrs[] = { - &lio_target_tpg_attr_enable, &lio_target_tpg_attr_dynamic_sessions, NULL, }; @@ -1129,6 +1070,37 @@ free_out: return NULL; } +static int lio_target_tiqn_enabletpg(struct se_portal_group *se_tpg, + bool enable) +{ + struct iscsi_portal_group *tpg = container_of(se_tpg, + struct iscsi_portal_group, tpg_se_tpg); + int ret; + + ret = iscsit_get_tpg(tpg); + if (ret < 0) + return -EINVAL; + + if (enable) { + ret = iscsit_tpg_enable_portal_group(tpg); + if (ret < 0) + goto out; + } else { + /* + * iscsit_tpg_disable_portal_group() assumes force=1 + */ + ret = iscsit_tpg_disable_portal_group(tpg, 1); + if (ret < 0) + goto out; + } + + iscsit_put_tpg(tpg); + return 0; +out: + iscsit_put_tpg(tpg); + return -EINVAL; +} + static void lio_target_tiqn_deltpg(struct se_portal_group *se_tpg) { struct iscsi_portal_group *tpg; @@ -1556,6 +1528,7 @@ const struct target_core_fabric_ops iscsi_ops = { .fabric_drop_wwn = lio_target_call_coredeltiqn, .add_wwn_groups = lio_target_add_wwn_groups, .fabric_make_tpg = lio_target_tiqn_addtpg, + .fabric_enable_tpg = lio_target_tiqn_enabletpg, .fabric_drop_tpg = lio_target_tiqn_deltpg, .fabric_make_np = lio_target_call_addnptotpg, .fabric_drop_np = lio_target_call_delnpfromtpg, From cb8717a720a9e911095e0421be6693a80b3abd49 Mon Sep 17 00:00:00 2001 From: Dmitry Bogdanov Date: Fri, 10 Sep 2021 11:41:29 +0300 Subject: [PATCH 080/279] scsi: target: qla2xxx: Replace enable attr with ops.enable Remove tpg/enable attribute. Add fabric ops enable_tpg implementation instead. Link: https://lore.kernel.org/r/20210910084133.17956-4-d.bogdanov@yadro.com Reviewed-by: Roman Bolshakov Reviewed-by: Mike Christie Signed-off-by: Dmitry Bogdanov Signed-off-by: Martin K. Petersen --- drivers/scsi/qla2xxx/tcm_qla2xxx.c | 73 +++++------------------------- 1 file changed, 12 insertions(+), 61 deletions(-) diff --git a/drivers/scsi/qla2xxx/tcm_qla2xxx.c b/drivers/scsi/qla2xxx/tcm_qla2xxx.c index 03de1bcf1461..8fa0056b56dd 100644 --- a/drivers/scsi/qla2xxx/tcm_qla2xxx.c +++ b/drivers/scsi/qla2xxx/tcm_qla2xxx.c @@ -915,40 +915,17 @@ static struct configfs_attribute *tcm_qla2xxx_tpg_attrib_attrs[] = { /* End items for tcm_qla2xxx_tpg_attrib_cit */ -static ssize_t tcm_qla2xxx_tpg_enable_show(struct config_item *item, - char *page) +static int tcm_qla2xxx_enable_tpg(struct se_portal_group *se_tpg, + bool enable) { - struct se_portal_group *se_tpg = to_tpg(item); - struct tcm_qla2xxx_tpg *tpg = container_of(se_tpg, - struct tcm_qla2xxx_tpg, se_tpg); - - return snprintf(page, PAGE_SIZE, "%d\n", - atomic_read(&tpg->lport_tpg_enabled)); -} - -static ssize_t tcm_qla2xxx_tpg_enable_store(struct config_item *item, - const char *page, size_t count) -{ - struct se_portal_group *se_tpg = to_tpg(item); struct se_wwn *se_wwn = se_tpg->se_tpg_wwn; struct tcm_qla2xxx_lport *lport = container_of(se_wwn, struct tcm_qla2xxx_lport, lport_wwn); struct scsi_qla_host *vha = lport->qla_vha; struct tcm_qla2xxx_tpg *tpg = container_of(se_tpg, struct tcm_qla2xxx_tpg, se_tpg); - unsigned long op; - int rc; - rc = kstrtoul(page, 0, &op); - if (rc < 0) { - pr_err("kstrtoul() returned %d\n", rc); - return -EINVAL; - } - if ((op != 1) && (op != 0)) { - pr_err("Illegal value for tpg_enable: %lu\n", op); - return -EINVAL; - } - if (op) { + if (enable) { if (atomic_read(&tpg->lport_tpg_enabled)) return -EEXIST; @@ -956,14 +933,14 @@ static ssize_t tcm_qla2xxx_tpg_enable_store(struct config_item *item, qlt_enable_vha(vha); } else { if (!atomic_read(&tpg->lport_tpg_enabled)) - return count; + return 0; atomic_set(&tpg->lport_tpg_enabled, 0); qlt_stop_phase1(vha->vha_tgt.qla_tgt); qlt_stop_phase2(vha->vha_tgt.qla_tgt); } - return count; + return 0; } static ssize_t tcm_qla2xxx_tpg_dynamic_sessions_show(struct config_item *item, @@ -1004,12 +981,10 @@ static ssize_t tcm_qla2xxx_tpg_fabric_prot_type_show(struct config_item *item, return sprintf(page, "%d\n", tpg->tpg_attrib.fabric_prot_type); } -CONFIGFS_ATTR(tcm_qla2xxx_tpg_, enable); CONFIGFS_ATTR_RO(tcm_qla2xxx_tpg_, dynamic_sessions); CONFIGFS_ATTR(tcm_qla2xxx_tpg_, fabric_prot_type); static struct configfs_attribute *tcm_qla2xxx_tpg_attrs[] = { - &tcm_qla2xxx_tpg_attr_enable, &tcm_qla2xxx_tpg_attr_dynamic_sessions, &tcm_qla2xxx_tpg_attr_fabric_prot_type, NULL, @@ -1083,35 +1058,17 @@ static void tcm_qla2xxx_drop_tpg(struct se_portal_group *se_tpg) kfree(tpg); } -static ssize_t tcm_qla2xxx_npiv_tpg_enable_show(struct config_item *item, - char *page) +static int tcm_qla2xxx_npiv_enable_tpg(struct se_portal_group *se_tpg, + bool enable) { - return tcm_qla2xxx_tpg_enable_show(item, page); -} - -static ssize_t tcm_qla2xxx_npiv_tpg_enable_store(struct config_item *item, - const char *page, size_t count) -{ - struct se_portal_group *se_tpg = to_tpg(item); struct se_wwn *se_wwn = se_tpg->se_tpg_wwn; struct tcm_qla2xxx_lport *lport = container_of(se_wwn, struct tcm_qla2xxx_lport, lport_wwn); struct scsi_qla_host *vha = lport->qla_vha; struct tcm_qla2xxx_tpg *tpg = container_of(se_tpg, struct tcm_qla2xxx_tpg, se_tpg); - unsigned long op; - int rc; - rc = kstrtoul(page, 0, &op); - if (rc < 0) { - pr_err("kstrtoul() returned %d\n", rc); - return -EINVAL; - } - if ((op != 1) && (op != 0)) { - pr_err("Illegal value for tpg_enable: %lu\n", op); - return -EINVAL; - } - if (op) { + if (enable) { if (atomic_read(&tpg->lport_tpg_enabled)) return -EEXIST; @@ -1119,23 +1076,16 @@ static ssize_t tcm_qla2xxx_npiv_tpg_enable_store(struct config_item *item, qlt_enable_vha(vha); } else { if (!atomic_read(&tpg->lport_tpg_enabled)) - return count; + return 0; atomic_set(&tpg->lport_tpg_enabled, 0); qlt_stop_phase1(vha->vha_tgt.qla_tgt); qlt_stop_phase2(vha->vha_tgt.qla_tgt); } - return count; + return 0; } -CONFIGFS_ATTR(tcm_qla2xxx_npiv_tpg_, enable); - -static struct configfs_attribute *tcm_qla2xxx_npiv_tpg_attrs[] = { - &tcm_qla2xxx_npiv_tpg_attr_enable, - NULL, -}; - static struct se_portal_group *tcm_qla2xxx_npiv_make_tpg(struct se_wwn *wwn, const char *name) { @@ -1878,6 +1828,7 @@ static const struct target_core_fabric_ops tcm_qla2xxx_ops = { .fabric_make_wwn = tcm_qla2xxx_make_lport, .fabric_drop_wwn = tcm_qla2xxx_drop_lport, .fabric_make_tpg = tcm_qla2xxx_make_tpg, + .fabric_enable_tpg = tcm_qla2xxx_enable_tpg, .fabric_drop_tpg = tcm_qla2xxx_drop_tpg, .fabric_init_nodeacl = tcm_qla2xxx_init_nodeacl, @@ -1918,11 +1869,11 @@ static const struct target_core_fabric_ops tcm_qla2xxx_npiv_ops = { .fabric_make_wwn = tcm_qla2xxx_npiv_make_lport, .fabric_drop_wwn = tcm_qla2xxx_npiv_drop_lport, .fabric_make_tpg = tcm_qla2xxx_npiv_make_tpg, + .fabric_enable_tpg = tcm_qla2xxx_npiv_enable_tpg, .fabric_drop_tpg = tcm_qla2xxx_drop_tpg, .fabric_init_nodeacl = tcm_qla2xxx_init_nodeacl, .tfc_wwn_attrs = tcm_qla2xxx_wwn_attrs, - .tfc_tpg_base_attrs = tcm_qla2xxx_npiv_tpg_attrs, }; static int tcm_qla2xxx_register_configfs(void) From fb00af92e5db24f69bba8c05a2c1926bf4a5cdc6 Mon Sep 17 00:00:00 2001 From: Dmitry Bogdanov Date: Fri, 10 Sep 2021 11:41:30 +0300 Subject: [PATCH 081/279] scsi: target: sbp: Replace enable attr with ops.enable Remove tpg/enable attribute. Add fabric ops enable_tpg implementation instead. Link: https://lore.kernel.org/r/20210910084133.17956-5-d.bogdanov@yadro.com Reviewed-by: Roman Bolshakov Reviewed-by: Bart Van Assche Reviewed-by: Mike Christie Signed-off-by: Dmitry Bogdanov Signed-off-by: Martin K. Petersen --- drivers/target/sbp/sbp_target.c | 30 +++++------------------------- 1 file changed, 5 insertions(+), 25 deletions(-) diff --git a/drivers/target/sbp/sbp_target.c b/drivers/target/sbp/sbp_target.c index b9f9fb5d7e63..504670994fb4 100644 --- a/drivers/target/sbp/sbp_target.c +++ b/drivers/target/sbp/sbp_target.c @@ -2125,32 +2125,13 @@ static ssize_t sbp_tpg_directory_id_store(struct config_item *item, return count; } -static ssize_t sbp_tpg_enable_show(struct config_item *item, char *page) +static int sbp_enable_tpg(struct se_portal_group *se_tpg, bool enable) { - struct se_portal_group *se_tpg = to_tpg(item); struct sbp_tpg *tpg = container_of(se_tpg, struct sbp_tpg, se_tpg); struct sbp_tport *tport = tpg->tport; - return sprintf(page, "%d\n", tport->enable); -} - -static ssize_t sbp_tpg_enable_store(struct config_item *item, - const char *page, size_t count) -{ - struct se_portal_group *se_tpg = to_tpg(item); - struct sbp_tpg *tpg = container_of(se_tpg, struct sbp_tpg, se_tpg); - struct sbp_tport *tport = tpg->tport; - unsigned long val; int ret; - if (kstrtoul(page, 0, &val) < 0) - return -EINVAL; - if ((val != 0) && (val != 1)) - return -EINVAL; - - if (tport->enable == val) - return count; - - if (val) { + if (enable) { if (sbp_count_se_tpg_luns(&tpg->se_tpg) == 0) { pr_err("Cannot enable a target with no LUNs!\n"); return -EINVAL; @@ -2165,7 +2146,7 @@ static ssize_t sbp_tpg_enable_store(struct config_item *item, spin_unlock_bh(&se_tpg->session_lock); } - tport->enable = val; + tport->enable = enable; ret = sbp_update_unit_directory(tport); if (ret < 0) { @@ -2173,15 +2154,13 @@ static ssize_t sbp_tpg_enable_store(struct config_item *item, return ret; } - return count; + return 0; } CONFIGFS_ATTR(sbp_tpg_, directory_id); -CONFIGFS_ATTR(sbp_tpg_, enable); static struct configfs_attribute *sbp_tpg_base_attrs[] = { &sbp_tpg_attr_directory_id, - &sbp_tpg_attr_enable, NULL, }; @@ -2319,6 +2298,7 @@ static const struct target_core_fabric_ops sbp_ops = { .fabric_make_wwn = sbp_make_tport, .fabric_drop_wwn = sbp_drop_tport, .fabric_make_tpg = sbp_make_tpg, + .fabric_enable_tpg = sbp_enable_tpg, .fabric_drop_tpg = sbp_drop_tpg, .fabric_post_link = sbp_post_link_lun, .fabric_pre_unlink = sbp_pre_unlink_lun, From 9465b4871af07de6d4ad0ad4522f258e0c15b51a Mon Sep 17 00:00:00 2001 From: Dmitry Bogdanov Date: Fri, 10 Sep 2021 11:41:31 +0300 Subject: [PATCH 082/279] scsi: target: srpt: Replace enable attr with ops.enable Remove tpg/enable attribute. Add fabric ops enable_tpg implementation instead. Link: https://lore.kernel.org/r/20210910084133.17956-6-d.bogdanov@yadro.com Reviewed-by: Roman Bolshakov Reviewed-by: Bart Van Assche Reviewed-by: Mike Christie Signed-off-by: Dmitry Bogdanov Signed-off-by: Martin K. Petersen --- drivers/infiniband/ulp/srpt/ib_srpt.c | 38 +++------------------------ 1 file changed, 4 insertions(+), 34 deletions(-) diff --git a/drivers/infiniband/ulp/srpt/ib_srpt.c b/drivers/infiniband/ulp/srpt/ib_srpt.c index 3cadf1295417..f86ee1c4b970 100644 --- a/drivers/infiniband/ulp/srpt/ib_srpt.c +++ b/drivers/infiniband/ulp/srpt/ib_srpt.c @@ -3705,47 +3705,17 @@ static struct configfs_attribute *srpt_da_attrs[] = { NULL, }; -static ssize_t srpt_tpg_enable_show(struct config_item *item, char *page) +static int srpt_enable_tpg(struct se_portal_group *se_tpg, bool enable) { - struct se_portal_group *se_tpg = to_tpg(item); struct srpt_port *sport = srpt_tpg_to_sport(se_tpg); - return sysfs_emit(page, "%d\n", sport->enabled); -} - -static ssize_t srpt_tpg_enable_store(struct config_item *item, - const char *page, size_t count) -{ - struct se_portal_group *se_tpg = to_tpg(item); - struct srpt_port *sport = srpt_tpg_to_sport(se_tpg); - unsigned long tmp; - int ret; - - ret = kstrtoul(page, 0, &tmp); - if (ret < 0) { - pr_err("Unable to extract srpt_tpg_store_enable\n"); - return -EINVAL; - } - - if ((tmp != 0) && (tmp != 1)) { - pr_err("Illegal value for srpt_tpg_store_enable: %lu\n", tmp); - return -EINVAL; - } - mutex_lock(&sport->mutex); - srpt_set_enabled(sport, tmp); + srpt_set_enabled(sport, enable); mutex_unlock(&sport->mutex); - return count; + return 0; } -CONFIGFS_ATTR(srpt_tpg_, enable); - -static struct configfs_attribute *srpt_tpg_attrs[] = { - &srpt_tpg_attr_enable, - NULL, -}; - /** * srpt_make_tpg - configfs callback invoked for mkdir /sys/kernel/config/target/$driver/$port/$tpg * @wwn: Corresponds to $driver/$port. @@ -3856,12 +3826,12 @@ static const struct target_core_fabric_ops srpt_template = { .fabric_make_wwn = srpt_make_tport, .fabric_drop_wwn = srpt_drop_tport, .fabric_make_tpg = srpt_make_tpg, + .fabric_enable_tpg = srpt_enable_tpg, .fabric_drop_tpg = srpt_drop_tpg, .fabric_init_nodeacl = srpt_init_nodeacl, .tfc_discovery_attrs = srpt_da_attrs, .tfc_wwn_attrs = srpt_wwn_attrs, - .tfc_tpg_base_attrs = srpt_tpg_attrs, .tfc_tpg_attrib_attrs = srpt_tpg_attrib_attrs, }; From d7e2932bba1bd17b476e056c48ab1324f3a2c18d Mon Sep 17 00:00:00 2001 From: Dmitry Bogdanov Date: Fri, 10 Sep 2021 11:41:32 +0300 Subject: [PATCH 083/279] scsi: target: ibm_vscsi: Replace enable attr with ops.enable Remove tpg/enable attribute. Add fabric ops enable_tpg implementation instead. Link: https://lore.kernel.org/r/20210910084133.17956-7-d.bogdanov@yadro.com Reviewed-by: Roman Bolshakov Reviewed-by: Mike Christie Signed-off-by: Dmitry Bogdanov Signed-off-by: Martin K. Petersen --- drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c | 42 +++--------------------- 1 file changed, 4 insertions(+), 38 deletions(-) diff --git a/drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c b/drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c index 10b6c6daaacd..61f06f6885a5 100644 --- a/drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c +++ b/drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c @@ -3948,41 +3948,16 @@ static struct configfs_attribute *ibmvscsis_wwn_attrs[] = { NULL, }; -static ssize_t ibmvscsis_tpg_enable_show(struct config_item *item, - char *page) -{ - struct se_portal_group *se_tpg = to_tpg(item); - struct ibmvscsis_tport *tport = container_of(se_tpg, - struct ibmvscsis_tport, - se_tpg); - return snprintf(page, PAGE_SIZE, "%d\n", (tport->enabled) ? 1 : 0); -} - -static ssize_t ibmvscsis_tpg_enable_store(struct config_item *item, - const char *page, size_t count) +static int ibmvscsis_enable_tpg(struct se_portal_group *se_tpg, bool enable) { - struct se_portal_group *se_tpg = to_tpg(item); struct ibmvscsis_tport *tport = container_of(se_tpg, struct ibmvscsis_tport, se_tpg); struct scsi_info *vscsi = container_of(tport, struct scsi_info, tport); - unsigned long tmp; - int rc; long lrc; - rc = kstrtoul(page, 0, &tmp); - if (rc < 0) { - dev_err(&vscsi->dev, "Unable to extract srpt_tpg_store_enable\n"); - return -EINVAL; - } - - if ((tmp != 0) && (tmp != 1)) { - dev_err(&vscsi->dev, "Illegal value for srpt_tpg_store_enable\n"); - return -EINVAL; - } - - if (tmp) { + if (enable) { spin_lock_bh(&vscsi->intr_lock); tport->enabled = true; lrc = ibmvscsis_enable_change_state(vscsi); @@ -3998,17 +3973,8 @@ static ssize_t ibmvscsis_tpg_enable_store(struct config_item *item, spin_unlock_bh(&vscsi->intr_lock); } - dev_dbg(&vscsi->dev, "tpg_enable_store, tmp %ld, state %d\n", tmp, - vscsi->state); - - return count; + return 0; } -CONFIGFS_ATTR(ibmvscsis_tpg_, enable); - -static struct configfs_attribute *ibmvscsis_tpg_attrs[] = { - &ibmvscsis_tpg_attr_enable, - NULL, -}; static const struct target_core_fabric_ops ibmvscsis_ops = { .module = THIS_MODULE, @@ -4038,10 +4004,10 @@ static const struct target_core_fabric_ops ibmvscsis_ops = { .fabric_make_wwn = ibmvscsis_make_tport, .fabric_drop_wwn = ibmvscsis_drop_tport, .fabric_make_tpg = ibmvscsis_make_tpg, + .fabric_enable_tpg = ibmvscsis_enable_tpg, .fabric_drop_tpg = ibmvscsis_drop_tpg, .tfc_wwn_attrs = ibmvscsis_wwn_attrs, - .tfc_tpg_base_attrs = ibmvscsis_tpg_attrs, }; static void ibmvscsis_dev_release(struct device *dev) {}; From 5384ee089d1f79b027bb62b0cfa729890ca71f8b Mon Sep 17 00:00:00 2001 From: Dmitry Bogdanov Date: Fri, 10 Sep 2021 11:41:33 +0300 Subject: [PATCH 084/279] scsi: target: usb: Replace enable attr with ops.enable Remove tpg/enable attribute. Add fabric ops enable_tpg implementation instead. Link: https://lore.kernel.org/r/20210910084133.17956-8-d.bogdanov@yadro.com Reviewed-by: Roman Bolshakov Reviewed-by: Mike Christie Signed-off-by: Dmitry Bogdanov Signed-off-by: Martin K. Petersen --- drivers/usb/gadget/function/f_tcm.c | 31 ++++++----------------------- 1 file changed, 6 insertions(+), 25 deletions(-) diff --git a/drivers/usb/gadget/function/f_tcm.c b/drivers/usb/gadget/function/f_tcm.c index de161ee0b1f9..8e17ac831be0 100644 --- a/drivers/usb/gadget/function/f_tcm.c +++ b/drivers/usb/gadget/function/f_tcm.c @@ -1495,42 +1495,24 @@ static struct configfs_attribute *usbg_wwn_attrs[] = { NULL, }; -static ssize_t tcm_usbg_tpg_enable_show(struct config_item *item, char *page) -{ - struct se_portal_group *se_tpg = to_tpg(item); - struct usbg_tpg *tpg = container_of(se_tpg, struct usbg_tpg, se_tpg); - - return snprintf(page, PAGE_SIZE, "%u\n", tpg->gadget_connect); -} - static int usbg_attach(struct usbg_tpg *); static void usbg_detach(struct usbg_tpg *); -static ssize_t tcm_usbg_tpg_enable_store(struct config_item *item, - const char *page, size_t count) +static int usbg_enable_tpg(struct se_portal_group *se_tpg, bool enable) { - struct se_portal_group *se_tpg = to_tpg(item); struct usbg_tpg *tpg = container_of(se_tpg, struct usbg_tpg, se_tpg); - bool op; - ssize_t ret; + int ret = 0; - ret = strtobool(page, &op); - if (ret) - return ret; - - if ((op && tpg->gadget_connect) || (!op && !tpg->gadget_connect)) - return -EINVAL; - - if (op) + if (enable) ret = usbg_attach(tpg); else usbg_detach(tpg); if (ret) return ret; - tpg->gadget_connect = op; + tpg->gadget_connect = enable; - return count; + return 0; } static ssize_t tcm_usbg_tpg_nexus_show(struct config_item *item, char *page) @@ -1673,11 +1655,9 @@ static ssize_t tcm_usbg_tpg_nexus_store(struct config_item *item, return count; } -CONFIGFS_ATTR(tcm_usbg_tpg_, enable); CONFIGFS_ATTR(tcm_usbg_tpg_, nexus); static struct configfs_attribute *usbg_base_attrs[] = { - &tcm_usbg_tpg_attr_enable, &tcm_usbg_tpg_attr_nexus, NULL, }; @@ -1730,6 +1710,7 @@ static const struct target_core_fabric_ops usbg_ops = { .fabric_make_wwn = usbg_make_tport, .fabric_drop_wwn = usbg_drop_tport, .fabric_make_tpg = usbg_make_tpg, + .fabric_enable_tpg = usbg_enable_tpg, .fabric_drop_tpg = usbg_drop_tpg, .fabric_post_link = usbg_port_link, .fabric_pre_unlink = usbg_port_unlink, From c20bda341946c8ee77baec3bec7c5cd615ddf869 Mon Sep 17 00:00:00 2001 From: "Gustavo A. R. Silva" Date: Mon, 27 Sep 2021 17:43:44 -0500 Subject: [PATCH 085/279] scsi: target: tcmu: Use struct_size() helper in kmalloc() Make use of the struct_size() helper instead of an open-coded version, in order to avoid any potential type mistakes or integer overflows that, in the worst scenario, could lead to heap overflows. Link: https://github.com/KSPP/linux/issues/160 Link: https://lore.kernel.org/r/20210927224344.GA190701@embeddedor Reviewed-by: Bodo Stroesser Signed-off-by: Gustavo A. R. Silva Signed-off-by: Martin K. Petersen --- drivers/target/target_core_user.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/target/target_core_user.c b/drivers/target/target_core_user.c index 9f552f48084c..dc220fad06fa 100644 --- a/drivers/target/target_core_user.c +++ b/drivers/target/target_core_user.c @@ -1255,7 +1255,6 @@ tcmu_tmr_notify(struct se_device *se_dev, enum tcm_tmreq_table tmf, { int i = 0, cmd_cnt = 0; bool unqueued = false; - uint16_t *cmd_ids = NULL; struct tcmu_cmd *cmd; struct se_cmd *se_cmd; struct tcmu_tmr *tmr; @@ -1292,7 +1291,7 @@ tcmu_tmr_notify(struct se_device *se_dev, enum tcm_tmreq_table tmf, pr_debug("TMR event %d on dev %s, aborted cmds %d, afflicted cmd_ids %d\n", tcmu_tmr_type(tmf), udev->name, i, cmd_cnt); - tmr = kmalloc(sizeof(*tmr) + cmd_cnt * sizeof(*cmd_ids), GFP_NOIO); + tmr = kmalloc(struct_size(tmr, tmr_cmd_ids, cmd_cnt), GFP_NOIO); if (!tmr) goto unlock; From 4f632918e7a87d0da7c0bcb3f8242f62725dad44 Mon Sep 17 00:00:00 2001 From: Igor Pylypiv Date: Tue, 28 Sep 2021 19:58:07 -0700 Subject: [PATCH 086/279] scsi: pm80xx: Replace open coded check with dev_is_expander() This is a follow up cleanup to the commit 924a3541eab0 ("scsi: libsas: aic94xx: hisi_sas: mvsas: pm8001: Use dev_is_expander()") Link: https://lore.kernel.org/r/20210929025807.646589-1-ipylypiv@google.com Reviewed-by: Vishakha Channapattan Acked-by: Jack Wang Signed-off-by: Igor Pylypiv Signed-off-by: Martin K. Petersen --- drivers/scsi/pm8001/pm8001_hwi.c | 3 +-- drivers/scsi/pm8001/pm80xx_hwi.c | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/scsi/pm8001/pm8001_hwi.c b/drivers/scsi/pm8001/pm8001_hwi.c index c9ecddd0d719..275bc322a6f3 100644 --- a/drivers/scsi/pm8001/pm8001_hwi.c +++ b/drivers/scsi/pm8001/pm8001_hwi.c @@ -4481,8 +4481,7 @@ static int pm8001_chip_reg_dev_req(struct pm8001_hba_info *pm8001_ha, if (pm8001_dev->dev_type == SAS_SATA_DEV) stp_sspsmp_sata = 0x00; /* stp*/ else if (pm8001_dev->dev_type == SAS_END_DEVICE || - pm8001_dev->dev_type == SAS_EDGE_EXPANDER_DEVICE || - pm8001_dev->dev_type == SAS_FANOUT_EXPANDER_DEVICE) + dev_is_expander(pm8001_dev->dev_type)) stp_sspsmp_sata = 0x01; /*ssp or smp*/ } if (parent_dev && dev_is_expander(parent_dev->dev_type)) diff --git a/drivers/scsi/pm8001/pm80xx_hwi.c b/drivers/scsi/pm8001/pm80xx_hwi.c index 1ae2f5c6042c..b9f6d83ff380 100644 --- a/drivers/scsi/pm8001/pm80xx_hwi.c +++ b/drivers/scsi/pm8001/pm80xx_hwi.c @@ -4865,8 +4865,7 @@ static int pm80xx_chip_reg_dev_req(struct pm8001_hba_info *pm8001_ha, if (pm8001_dev->dev_type == SAS_SATA_DEV) stp_sspsmp_sata = 0x00; /* stp*/ else if (pm8001_dev->dev_type == SAS_END_DEVICE || - pm8001_dev->dev_type == SAS_EDGE_EXPANDER_DEVICE || - pm8001_dev->dev_type == SAS_FANOUT_EXPANDER_DEVICE) + dev_is_expander(pm8001_dev->dev_type)) stp_sspsmp_sata = 0x01; /*ssp or smp*/ } if (parent_dev && dev_is_expander(parent_dev->dev_type)) From 4084a7235d38311a77c86ba69ba849bd787db87b Mon Sep 17 00:00:00 2001 From: Igor Pylypiv Date: Tue, 28 Sep 2021 19:58:47 -0700 Subject: [PATCH 087/279] scsi: pm80xx: Fix misleading log statement in pm8001_mpi_get_nvmd_resp() pm8001_mpi_get_nvmd_resp() handles a GET_NVMD_DATA response, not a SET_NVMD_DATA response, as the log statement implies. Fixes: 1f889b58716a ("scsi: pm80xx: Fix pm8001_mpi_get_nvmd_resp() race condition") Link: https://lore.kernel.org/r/20210929025847.646999-1-ipylypiv@google.com Reviewed-by: Changyuan Lyu Acked-by: Jack Wang Signed-off-by: Igor Pylypiv Signed-off-by: Martin K. Petersen --- 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 275bc322a6f3..124cb69740c6 100644 --- a/drivers/scsi/pm8001/pm8001_hwi.c +++ b/drivers/scsi/pm8001/pm8001_hwi.c @@ -3169,7 +3169,7 @@ pm8001_mpi_get_nvmd_resp(struct pm8001_hba_info *pm8001_ha, void *piomb) * fw_control_context->usrAddr */ complete(pm8001_ha->nvmd_completion); - pm8001_dbg(pm8001_ha, MSG, "Set nvm data complete!\n"); + pm8001_dbg(pm8001_ha, MSG, "Get nvmd data complete!\n"); ccb->task = NULL; ccb->ccb_tag = 0xFFFFFFFF; pm8001_tag_free(pm8001_ha, tag); From 76a4f7cc5973608556c68ac1da60d29c4a6c1d30 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Thu, 16 Sep 2021 16:26:05 +0300 Subject: [PATCH 088/279] scsi: mpi3mr: Clean up mpi3mr_print_ioc_info() This function is more complicated than necessary. If we change from scnprintf() to snprintf() that lets us remove the if bytes_wrote < sizeof(protocol) checks. Also, we can use bytes_wrote ? "," : "" to print the comma and remove the separate if statement and the "is_string_nonempty" variable. [mkp: a few formatting cleanups and s/wrote/written/] Link: https://lore.kernel.org/r/20210916132605.GF25094@kili Signed-off-by: Dan Carpenter Signed-off-by: Martin K. Petersen --- drivers/scsi/mpi3mr/mpi3mr_fw.c | 32 +++++++++----------------------- 1 file changed, 9 insertions(+), 23 deletions(-) diff --git a/drivers/scsi/mpi3mr/mpi3mr_fw.c b/drivers/scsi/mpi3mr/mpi3mr_fw.c index 4a8316c6bd41..e34417a2429a 100644 --- a/drivers/scsi/mpi3mr/mpi3mr_fw.c +++ b/drivers/scsi/mpi3mr/mpi3mr_fw.c @@ -3018,11 +3018,10 @@ static const struct { static void mpi3mr_print_ioc_info(struct mpi3mr_ioc *mrioc) { - int i = 0, bytes_wrote = 0; + int i = 0, bytes_written = 0; char personality[16]; char protocol[50] = {0}; char capabilities[100] = {0}; - bool is_string_nonempty = false; struct mpi3mr_compimg_ver *fwver = &mrioc->facts.fw_ver; switch (mrioc->facts.personality) { @@ -3046,39 +3045,26 @@ mpi3mr_print_ioc_info(struct mpi3mr_ioc *mrioc) for (i = 0; i < ARRAY_SIZE(mpi3mr_protocols); i++) { if (mrioc->facts.protocol_flags & mpi3mr_protocols[i].protocol) { - if (is_string_nonempty && - (bytes_wrote < sizeof(protocol))) - bytes_wrote += snprintf(protocol + bytes_wrote, - (sizeof(protocol) - bytes_wrote), ","); - - if (bytes_wrote < sizeof(protocol)) - bytes_wrote += snprintf(protocol + bytes_wrote, - (sizeof(protocol) - bytes_wrote), "%s", + bytes_written += snprintf(protocol + bytes_written, + sizeof(protocol) - bytes_written, "%s%s", + bytes_written ? "," : "", mpi3mr_protocols[i].name); - is_string_nonempty = true; } } - bytes_wrote = 0; - is_string_nonempty = false; + bytes_written = 0; for (i = 0; i < ARRAY_SIZE(mpi3mr_capabilities); i++) { if (mrioc->facts.protocol_flags & mpi3mr_capabilities[i].capability) { - if (is_string_nonempty && - (bytes_wrote < sizeof(capabilities))) - bytes_wrote += snprintf(capabilities + bytes_wrote, - (sizeof(capabilities) - bytes_wrote), ","); - - if (bytes_wrote < sizeof(capabilities)) - bytes_wrote += snprintf(capabilities + bytes_wrote, - (sizeof(capabilities) - bytes_wrote), "%s", + bytes_written += snprintf(capabilities + bytes_written, + sizeof(capabilities) - bytes_written, "%s%s", + bytes_written ? "," : "", mpi3mr_capabilities[i].name); - is_string_nonempty = true; } } ioc_info(mrioc, "Protocol=(%s), Capabilities=(%s)\n", - protocol, capabilities); + protocol, capabilities); } /** From 819225b03dc73294a563d3ee9e24e04c71e7afe0 Mon Sep 17 00:00:00 2001 From: Don Brace Date: Tue, 28 Sep 2021 18:54:32 -0500 Subject: [PATCH 089/279] scsi: smartpqi: Update device removal management Update device removal path to handle issues for: - rmmod: Correct stack trace when removing devices. - rmmod: Synchronize SCSI cache. - Update handling for removing devices using sysfs. Link: https://lore.kernel.org/r/20210928235442.201875-2-don.brace@microchip.com Reviewed-by: Scott Benesh Reviewed-by: Scott Teel Reviewed-by: Mike McGowen Acked-by: John Donnelly Signed-off-by: Don Brace Signed-off-by: Martin K. Petersen --- drivers/scsi/smartpqi/smartpqi_init.c | 64 ++++++++++++--------------- 1 file changed, 28 insertions(+), 36 deletions(-) diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c index ecb2af3f43ca..97027574eb1f 100644 --- a/drivers/scsi/smartpqi/smartpqi_init.c +++ b/drivers/scsi/smartpqi/smartpqi_init.c @@ -1693,8 +1693,6 @@ static inline void pqi_remove_device(struct pqi_ctrl_info *ctrl_info, struct pqi { int rc; - pqi_device_remove_start(device); - rc = pqi_device_wait_for_pending_io(ctrl_info, device, PQI_REMOVE_DEVICE_PENDING_IO_TIMEOUT_MSECS); if (rc) @@ -1708,6 +1706,8 @@ static inline void pqi_remove_device(struct pqi_ctrl_info *ctrl_info, struct pqi scsi_remove_device(device->sdev); else pqi_remove_sas_device(device); + + pqi_device_remove_start(device); } /* Assumes the SCSI device list lock is held. */ @@ -1986,7 +1986,7 @@ static void pqi_update_device_list(struct pqi_ctrl_info *ctrl_info, list_for_each_entry_safe(device, next, &ctrl_info->scsi_device_list, scsi_device_list_entry) { if (device->device_gone) { - list_del_init(&device->scsi_device_list_entry); + list_del(&device->scsi_device_list_entry); list_add_tail(&device->delete_list_entry, &delete_list); } } @@ -2025,15 +2025,13 @@ static void pqi_update_device_list(struct pqi_ctrl_info *ctrl_info, if (device->volume_offline) { pqi_dev_info(ctrl_info, "offline", device); pqi_show_volume_status(ctrl_info, device); - } - list_del(&device->delete_list_entry); - if (pqi_is_device_added(device)) { - pqi_remove_device(ctrl_info, device); } else { - if (!device->volume_offline) - pqi_dev_info(ctrl_info, "removed", device); - pqi_free_device(device); + pqi_dev_info(ctrl_info, "removed", device); } + if (pqi_is_device_added(device)) + pqi_remove_device(ctrl_info, device); + list_del(&device->delete_list_entry); + pqi_free_device(device); } /* @@ -2328,6 +2326,25 @@ out: return rc; } +static void pqi_remove_all_scsi_devices(struct pqi_ctrl_info *ctrl_info) +{ + unsigned long flags; + struct pqi_scsi_dev *device; + struct pqi_scsi_dev *next; + + spin_lock_irqsave(&ctrl_info->scsi_device_list_lock, flags); + + list_for_each_entry_safe(device, next, &ctrl_info->scsi_device_list, + scsi_device_list_entry) { + if (pqi_is_device_added(device)) + pqi_remove_device(ctrl_info, device); + list_del(&device->scsi_device_list_entry); + pqi_free_device(device); + } + + spin_unlock_irqrestore(&ctrl_info->scsi_device_list_lock, flags); +} + static int pqi_scan_scsi_devices(struct pqi_ctrl_info *ctrl_info) { int rc; @@ -6120,31 +6137,6 @@ static int pqi_slave_configure(struct scsi_device *sdev) return 0; } -static void pqi_slave_destroy(struct scsi_device *sdev) -{ - unsigned long flags; - struct pqi_scsi_dev *device; - struct pqi_ctrl_info *ctrl_info; - - ctrl_info = shost_to_hba(sdev->host); - - spin_lock_irqsave(&ctrl_info->scsi_device_list_lock, flags); - - device = sdev->hostdata; - if (device) { - sdev->hostdata = NULL; - if (!list_empty(&device->scsi_device_list_entry)) - list_del(&device->scsi_device_list_entry); - } - - spin_unlock_irqrestore(&ctrl_info->scsi_device_list_lock, flags); - - if (device) { - pqi_dev_info(ctrl_info, "removed", device); - pqi_free_device(device); - } -} - static int pqi_getpciinfo_ioctl(struct pqi_ctrl_info *ctrl_info, void __user *arg) { struct pci_dev *pci_dev; @@ -6938,7 +6930,6 @@ static struct scsi_host_template pqi_driver_template = { .ioctl = pqi_ioctl, .slave_alloc = pqi_slave_alloc, .slave_configure = pqi_slave_configure, - .slave_destroy = pqi_slave_destroy, .map_queues = pqi_map_queues, .sdev_attrs = pqi_sdev_attrs, .shost_attrs = pqi_shost_attrs, @@ -8169,6 +8160,7 @@ static void pqi_remove_ctrl(struct pqi_ctrl_info *ctrl_info) { pqi_cancel_rescan_worker(ctrl_info); pqi_cancel_update_time_worker(ctrl_info); + pqi_remove_all_scsi_devices(ctrl_info); pqi_unregister_scsi(ctrl_info); if (ctrl_info->pqi_mode_enabled) pqi_revert_to_sis_mode(ctrl_info); From 9ee5d6e9ac52a3c8625697535f8e35864d9fd38c Mon Sep 17 00:00:00 2001 From: Mahesh Rajashekhara Date: Tue, 28 Sep 2021 18:54:33 -0500 Subject: [PATCH 090/279] scsi: smartpqi: Add controller handshake during kdump Correct kdump hangs when controller is locked up. There are occasions when a controller reboot (controller soft reset) is issued when a controller firmware crash dump is in progress. This leads to incomplete controller firmware crash dump: - When the controller crash dump is in progress, and a kdump is initiated, the driver issues inbound doorbell reset to bring back the controller in SIS mode. - If the controller is in locked up state, the inbound doorbell reset does not work causing controller initialization failures. This results in the driver hanging waiting for SIS mode. To avoid an incomplete controller crash dump, add in a controller crash dump handshake: - Controller will indicate start and end of the controller crash dump by setting some register bits. - Driver will look these bits when a kdump is initiated. If a controller crash dump is in progress, the driver will wait for the controller crash dump to complete before issuing the controller soft reset then complete driver initialization. Link: https://lore.kernel.org/r/20210928235442.201875-3-don.brace@microchip.com Reviewed-by: Scott Benesh Reviewed-by: Scott Teel Reviewed-by: Mike McGowen Acked-by: John Donnelly Signed-off-by: Mahesh Rajashekhara Signed-off-by: Don Brace Signed-off-by: Martin K. Petersen --- drivers/scsi/smartpqi/smartpqi_init.c | 41 +++++++++++++++++++-- drivers/scsi/smartpqi/smartpqi_sis.c | 51 +++++++++++++++++++++++++++ drivers/scsi/smartpqi/smartpqi_sis.h | 1 + 3 files changed, 91 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c index 97027574eb1f..5655d240f7a7 100644 --- a/drivers/scsi/smartpqi/smartpqi_init.c +++ b/drivers/scsi/smartpqi/smartpqi_init.c @@ -234,15 +234,46 @@ static inline bool pqi_is_hba_lunid(u8 *scsi3addr) return pqi_scsi3addr_equal(scsi3addr, RAID_CTLR_LUNID); } +#define PQI_DRIVER_SCRATCH_PQI_MODE 0x1 +#define PQI_DRIVER_SCRATCH_FW_TRIAGE_SUPPORTED 0x2 + static inline enum pqi_ctrl_mode pqi_get_ctrl_mode(struct pqi_ctrl_info *ctrl_info) { - return sis_read_driver_scratch(ctrl_info); + return sis_read_driver_scratch(ctrl_info) & PQI_DRIVER_SCRATCH_PQI_MODE ? PQI_MODE : SIS_MODE; } static inline void pqi_save_ctrl_mode(struct pqi_ctrl_info *ctrl_info, enum pqi_ctrl_mode mode) { - sis_write_driver_scratch(ctrl_info, mode); + u32 driver_scratch; + + driver_scratch = sis_read_driver_scratch(ctrl_info); + + if (mode == PQI_MODE) + driver_scratch |= PQI_DRIVER_SCRATCH_PQI_MODE; + else + driver_scratch &= ~PQI_DRIVER_SCRATCH_PQI_MODE; + + sis_write_driver_scratch(ctrl_info, driver_scratch); +} + +static inline bool pqi_is_fw_triage_supported(struct pqi_ctrl_info *ctrl_info) +{ + return (sis_read_driver_scratch(ctrl_info) & PQI_DRIVER_SCRATCH_FW_TRIAGE_SUPPORTED) != 0; +} + +static inline void pqi_save_fw_triage_setting(struct pqi_ctrl_info *ctrl_info, bool is_supported) +{ + u32 driver_scratch; + + driver_scratch = sis_read_driver_scratch(ctrl_info); + + if (is_supported) + driver_scratch |= PQI_DRIVER_SCRATCH_FW_TRIAGE_SUPPORTED; + else + driver_scratch &= ~PQI_DRIVER_SCRATCH_FW_TRIAGE_SUPPORTED; + + sis_write_driver_scratch(ctrl_info, driver_scratch); } static inline void pqi_ctrl_block_scan(struct pqi_ctrl_info *ctrl_info) @@ -7292,6 +7323,7 @@ static void pqi_ctrl_update_feature_flags(struct pqi_ctrl_info *ctrl_info, ctrl_info->unique_wwid_in_report_phys_lun_supported = firmware_feature->enabled; break; + pqi_save_fw_triage_setting(ctrl_info, firmware_feature->enabled); } pqi_firmware_feature_status(ctrl_info, firmware_feature); @@ -7618,6 +7650,11 @@ static int pqi_ctrl_init(struct pqi_ctrl_info *ctrl_info) u32 product_id; if (reset_devices) { + if (pqi_is_fw_triage_supported(ctrl_info)) { + rc = sis_wait_for_fw_triage_completion(ctrl_info); + if (rc) + return rc; + } sis_soft_reset(ctrl_info); msleep(PQI_POST_RESET_DELAY_SECS * PQI_HZ); } else { diff --git a/drivers/scsi/smartpqi/smartpqi_sis.c b/drivers/scsi/smartpqi/smartpqi_sis.c index d63c46a8e38b..8acd3a80f582 100644 --- a/drivers/scsi/smartpqi/smartpqi_sis.c +++ b/drivers/scsi/smartpqi/smartpqi_sis.c @@ -51,12 +51,20 @@ #define SIS_BASE_STRUCT_REVISION 9 #define SIS_BASE_STRUCT_ALIGNMENT 16 +#define SIS_CTRL_KERNEL_FW_TRIAGE 0x3 #define SIS_CTRL_KERNEL_UP 0x80 #define SIS_CTRL_KERNEL_PANIC 0x100 #define SIS_CTRL_READY_TIMEOUT_SECS 180 #define SIS_CTRL_READY_RESUME_TIMEOUT_SECS 90 #define SIS_CTRL_READY_POLL_INTERVAL_MSECS 10 +enum sis_fw_triage_status { + FW_TRIAGE_NOT_STARTED = 0, + FW_TRIAGE_STARTED, + FW_TRIAGE_COND_INVALID, + FW_TRIAGE_COMPLETED +}; + #pragma pack(1) /* for use with SIS_CMD_INIT_BASE_STRUCT_ADDRESS command */ @@ -419,12 +427,55 @@ u32 sis_read_driver_scratch(struct pqi_ctrl_info *ctrl_info) return readl(&ctrl_info->registers->sis_driver_scratch); } +static inline enum sis_fw_triage_status + sis_read_firmware_triage_status(struct pqi_ctrl_info *ctrl_info) +{ + return ((enum sis_fw_triage_status)(readl(&ctrl_info->registers->sis_firmware_status) & + SIS_CTRL_KERNEL_FW_TRIAGE)); +} + void sis_soft_reset(struct pqi_ctrl_info *ctrl_info) { writel(SIS_SOFT_RESET, &ctrl_info->registers->sis_host_to_ctrl_doorbell); } +#define SIS_FW_TRIAGE_STATUS_TIMEOUT_SECS 300 +#define SIS_FW_TRIAGE_STATUS_POLL_INTERVAL_SECS 1 + +int sis_wait_for_fw_triage_completion(struct pqi_ctrl_info *ctrl_info) +{ + int rc; + enum sis_fw_triage_status status; + unsigned long timeout; + + timeout = (SIS_FW_TRIAGE_STATUS_TIMEOUT_SECS * PQI_HZ) + jiffies; + while (1) { + status = sis_read_firmware_triage_status(ctrl_info); + if (status == FW_TRIAGE_COND_INVALID) { + dev_err(&ctrl_info->pci_dev->dev, + "firmware triage condition invalid\n"); + rc = -EINVAL; + break; + } else if (status == FW_TRIAGE_NOT_STARTED || + status == FW_TRIAGE_COMPLETED) { + rc = 0; + break; + } + + if (time_after(jiffies, timeout)) { + dev_err(&ctrl_info->pci_dev->dev, + "timed out waiting for firmware triage status\n"); + rc = -ETIMEDOUT; + break; + } + + ssleep(SIS_FW_TRIAGE_STATUS_POLL_INTERVAL_SECS); + } + + return rc; +} + static void __attribute__((unused)) verify_structures(void) { BUILD_BUG_ON(offsetof(struct sis_base_struct, diff --git a/drivers/scsi/smartpqi/smartpqi_sis.h b/drivers/scsi/smartpqi/smartpqi_sis.h index d29c1352a826..c1db93054c86 100644 --- a/drivers/scsi/smartpqi/smartpqi_sis.h +++ b/drivers/scsi/smartpqi/smartpqi_sis.h @@ -28,5 +28,6 @@ void sis_write_driver_scratch(struct pqi_ctrl_info *ctrl_info, u32 value); u32 sis_read_driver_scratch(struct pqi_ctrl_info *ctrl_info); void sis_soft_reset(struct pqi_ctrl_info *ctrl_info); u32 sis_get_product_id(struct pqi_ctrl_info *ctrl_info); +int sis_wait_for_fw_triage_completion(struct pqi_ctrl_info *ctrl_info); #endif /* _SMARTPQI_SIS_H */ From 5d1f03e6f49ae80d417dc72d1ee16a3379e2c026 Mon Sep 17 00:00:00 2001 From: Murthy Bhat Date: Tue, 28 Sep 2021 18:54:34 -0500 Subject: [PATCH 091/279] scsi: smartpqi: Capture controller reason codes In some rare cases, the driver can halt the controller. Add a reason code describing why the controller was halted. Store this reason code in a controller register to aid in debugging the issue. Link: https://lore.kernel.org/r/20210928235442.201875-4-don.brace@microchip.com Reviewed-by: Scott Benesh Reviewed-by: Scott Teel Reviewed-by: Mike McGowen Acked-by: John Donnelly Signed-off-by: Murthy Bhat Signed-off-by: Don Brace Signed-off-by: Martin K. Petersen --- drivers/scsi/smartpqi/smartpqi.h | 25 +++++++++++++++-- drivers/scsi/smartpqi/smartpqi_init.c | 40 ++++++++++++++++++--------- drivers/scsi/smartpqi/smartpqi_sis.c | 9 ++++-- drivers/scsi/smartpqi/smartpqi_sis.h | 3 +- 4 files changed, 57 insertions(+), 20 deletions(-) diff --git a/drivers/scsi/smartpqi/smartpqi.h b/drivers/scsi/smartpqi/smartpqi.h index 70eca203d72f..d66863f8d1cf 100644 --- a/drivers/scsi/smartpqi/smartpqi.h +++ b/drivers/scsi/smartpqi/smartpqi.h @@ -82,9 +82,11 @@ struct pqi_ctrl_registers { __le32 sis_product_identifier; /* B4h */ u8 reserved5[0xbc - (0xb4 + sizeof(__le32))]; __le32 sis_firmware_status; /* BCh */ - u8 reserved6[0x1000 - (0xbc + sizeof(__le32))]; + u8 reserved6[0xcc - (0xbc + sizeof(__le32))]; + __le32 sis_ctrl_shutdown_reason_code; /* CCh */ + u8 reserved7[0x1000 - (0xcc + sizeof(__le32))]; __le32 sis_mailbox[8]; /* 1000h */ - u8 reserved7[0x4000 - (0x1000 + (sizeof(__le32) * 8))]; + u8 reserved8[0x4000 - (0x1000 + (sizeof(__le32) * 8))]; /* * The PQI spec states that the PQI registers should be at * offset 0 from the PCIe BAR 0. However, we can't map @@ -102,6 +104,21 @@ struct pqi_ctrl_registers { #define PQI_DEVICE_REGISTERS_OFFSET 0x4000 +/* shutdown reasons for taking the controller offline */ +enum pqi_ctrl_shutdown_reason { + PQI_IQ_NOT_DRAINED_TIMEOUT = 1, + PQI_LUN_RESET_TIMEOUT = 2, + PQI_IO_PENDING_POST_LUN_RESET_TIMEOUT = 3, + PQI_NO_HEARTBEAT = 4, + PQI_FIRMWARE_KERNEL_NOT_UP = 5, + PQI_OFA_RESPONSE_TIMEOUT = 6, + PQI_INVALID_REQ_ID = 7, + PQI_UNMATCHED_REQ_ID = 8, + PQI_IO_PI_OUT_OF_RANGE = 9, + PQI_EVENT_PI_OUT_OF_RANGE = 10, + PQI_UNEXPECTED_IU_TYPE = 11 +}; + enum pqi_io_path { RAID_PATH = 0, AIO_PATH = 1 @@ -850,7 +867,8 @@ struct pqi_config_table_firmware_features { #define PQI_FIRMWARE_FEATURE_TMF_IU_TIMEOUT 14 #define PQI_FIRMWARE_FEATURE_RAID_BYPASS_ON_ENCRYPTED_NVME 15 #define PQI_FIRMWARE_FEATURE_UNIQUE_WWID_IN_REPORT_PHYS_LUN 16 -#define PQI_FIRMWARE_FEATURE_MAXIMUM 16 +#define PQI_FIRMWARE_FEATURE_FW_TRIAGE 17 +#define PQI_FIRMWARE_FEATURE_MAXIMUM 17 struct pqi_config_table_debug { struct pqi_config_table_section_header header; @@ -1297,6 +1315,7 @@ struct pqi_ctrl_info { u8 raid_iu_timeout_supported : 1; u8 tmf_iu_timeout_supported : 1; u8 unique_wwid_in_report_phys_lun_supported : 1; + u8 firmware_triage_supported : 1; u8 enable_r1_writes : 1; u8 enable_r5_writes : 1; u8 enable_r6_writes : 1; diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c index 5655d240f7a7..b6ac4d607664 100644 --- a/drivers/scsi/smartpqi/smartpqi_init.c +++ b/drivers/scsi/smartpqi/smartpqi_init.c @@ -54,7 +54,8 @@ MODULE_DESCRIPTION("Driver for Microchip Smart Family Controller version " MODULE_VERSION(DRIVER_VERSION); MODULE_LICENSE("GPL"); -static void pqi_take_ctrl_offline(struct pqi_ctrl_info *ctrl_info); +static void pqi_take_ctrl_offline(struct pqi_ctrl_info *ctrl_info, + enum pqi_ctrl_shutdown_reason ctrl_shutdown_reason); static void pqi_ctrl_offline_worker(struct work_struct *work); static int pqi_scan_scsi_devices(struct pqi_ctrl_info *ctrl_info); static void pqi_scan_start(struct Scsi_Host *shost); @@ -226,7 +227,7 @@ static inline void pqi_check_ctrl_health(struct pqi_ctrl_info *ctrl_info) { if (ctrl_info->controller_online) if (!sis_is_firmware_running(ctrl_info)) - pqi_take_ctrl_offline(ctrl_info); + pqi_take_ctrl_offline(ctrl_info, PQI_FIRMWARE_KERNEL_NOT_UP); } static inline bool pqi_is_hba_lunid(u8 *scsi3addr) @@ -3180,9 +3181,10 @@ static int pqi_interpret_task_management_response(struct pqi_ctrl_info *ctrl_inf return rc; } -static inline void pqi_invalid_response(struct pqi_ctrl_info *ctrl_info) +static inline void pqi_invalid_response(struct pqi_ctrl_info *ctrl_info, + enum pqi_ctrl_shutdown_reason ctrl_shutdown_reason) { - pqi_take_ctrl_offline(ctrl_info); + pqi_take_ctrl_offline(ctrl_info, ctrl_shutdown_reason); } static int pqi_process_io_intr(struct pqi_ctrl_info *ctrl_info, struct pqi_queue_group *queue_group) @@ -3200,7 +3202,7 @@ static int pqi_process_io_intr(struct pqi_ctrl_info *ctrl_info, struct pqi_queue while (1) { oq_pi = readl(queue_group->oq_pi); if (oq_pi >= ctrl_info->num_elements_per_oq) { - pqi_invalid_response(ctrl_info); + pqi_invalid_response(ctrl_info, PQI_IO_PI_OUT_OF_RANGE); dev_err(&ctrl_info->pci_dev->dev, "I/O interrupt: producer index (%u) out of range (0-%u): consumer index: %u\n", oq_pi, ctrl_info->num_elements_per_oq - 1, oq_ci); @@ -3215,7 +3217,7 @@ static int pqi_process_io_intr(struct pqi_ctrl_info *ctrl_info, struct pqi_queue request_id = get_unaligned_le16(&response->request_id); if (request_id >= ctrl_info->max_io_slots) { - pqi_invalid_response(ctrl_info); + pqi_invalid_response(ctrl_info, PQI_INVALID_REQ_ID); dev_err(&ctrl_info->pci_dev->dev, "request ID in response (%u) out of range (0-%u): producer index: %u consumer index: %u\n", request_id, ctrl_info->max_io_slots - 1, oq_pi, oq_ci); @@ -3224,7 +3226,7 @@ static int pqi_process_io_intr(struct pqi_ctrl_info *ctrl_info, struct pqi_queue io_request = &ctrl_info->io_request_pool[request_id]; if (atomic_read(&io_request->refcount) == 0) { - pqi_invalid_response(ctrl_info); + pqi_invalid_response(ctrl_info, PQI_UNMATCHED_REQ_ID); dev_err(&ctrl_info->pci_dev->dev, "request ID in response (%u) does not match an outstanding I/O request: producer index: %u consumer index: %u\n", request_id, oq_pi, oq_ci); @@ -3260,7 +3262,7 @@ static int pqi_process_io_intr(struct pqi_ctrl_info *ctrl_info, struct pqi_queue pqi_process_io_error(response->header.iu_type, io_request); break; default: - pqi_invalid_response(ctrl_info); + pqi_invalid_response(ctrl_info, PQI_UNEXPECTED_IU_TYPE); dev_err(&ctrl_info->pci_dev->dev, "unexpected IU type: 0x%x: producer index: %u consumer index: %u\n", response->header.iu_type, oq_pi, oq_ci); @@ -3442,7 +3444,7 @@ static void pqi_process_soft_reset(struct pqi_ctrl_info *ctrl_info) pqi_ofa_free_host_buffer(ctrl_info); pqi_ctrl_ofa_done(ctrl_info); pqi_ofa_ctrl_unquiesce(ctrl_info); - pqi_take_ctrl_offline(ctrl_info); + pqi_take_ctrl_offline(ctrl_info, PQI_OFA_RESPONSE_TIMEOUT); break; } } @@ -3567,7 +3569,7 @@ static void pqi_heartbeat_timer_handler(struct timer_list *t) dev_err(&ctrl_info->pci_dev->dev, "no heartbeat detected - last heartbeat count: %u\n", heartbeat_count); - pqi_take_ctrl_offline(ctrl_info); + pqi_take_ctrl_offline(ctrl_info, PQI_NO_HEARTBEAT); return; } } else { @@ -3631,7 +3633,7 @@ static int pqi_process_event_intr(struct pqi_ctrl_info *ctrl_info) while (1) { oq_pi = readl(event_queue->oq_pi); if (oq_pi >= PQI_NUM_EVENT_QUEUE_ELEMENTS) { - pqi_invalid_response(ctrl_info); + pqi_invalid_response(ctrl_info, PQI_EVENT_PI_OUT_OF_RANGE); dev_err(&ctrl_info->pci_dev->dev, "event interrupt: producer index (%u) out of range (0-%u): consumer index: %u\n", oq_pi, PQI_NUM_EVENT_QUEUE_ELEMENTS - 1, oq_ci); @@ -7323,7 +7325,10 @@ static void pqi_ctrl_update_feature_flags(struct pqi_ctrl_info *ctrl_info, ctrl_info->unique_wwid_in_report_phys_lun_supported = firmware_feature->enabled; break; + case PQI_FIRMWARE_FEATURE_FW_TRIAGE: + ctrl_info->firmware_triage_supported = firmware_feature->enabled; pqi_save_fw_triage_setting(ctrl_info, firmware_feature->enabled); + break; } pqi_firmware_feature_status(ctrl_info, firmware_feature); @@ -7419,6 +7424,11 @@ static struct pqi_firmware_feature pqi_firmware_features[] = { .feature_bit = PQI_FIRMWARE_FEATURE_UNIQUE_WWID_IN_REPORT_PHYS_LUN, .feature_status = pqi_ctrl_update_feature_flags, }, + { + .feature_name = "Firmware Triage", + .feature_bit = PQI_FIRMWARE_FEATURE_FW_TRIAGE, + .feature_status = pqi_ctrl_update_feature_flags, + }, }; static void pqi_process_firmware_features( @@ -7519,6 +7529,7 @@ static void pqi_ctrl_reset_config(struct pqi_ctrl_info *ctrl_info) ctrl_info->raid_iu_timeout_supported = false; ctrl_info->tmf_iu_timeout_supported = false; ctrl_info->unique_wwid_in_report_phys_lun_supported = false; + ctrl_info->firmware_triage_supported = false; } static int pqi_process_config_table(struct pqi_ctrl_info *ctrl_info) @@ -8459,7 +8470,8 @@ static void pqi_ctrl_offline_worker(struct work_struct *work) pqi_take_ctrl_offline_deferred(ctrl_info); } -static void pqi_take_ctrl_offline(struct pqi_ctrl_info *ctrl_info) +static void pqi_take_ctrl_offline(struct pqi_ctrl_info *ctrl_info, + enum pqi_ctrl_shutdown_reason ctrl_shutdown_reason) { if (!ctrl_info->controller_online) return; @@ -8468,7 +8480,7 @@ static void pqi_take_ctrl_offline(struct pqi_ctrl_info *ctrl_info) ctrl_info->pqi_mode_enabled = false; pqi_ctrl_block_requests(ctrl_info); if (!pqi_disable_ctrl_shutdown) - sis_shutdown_ctrl(ctrl_info); + sis_shutdown_ctrl(ctrl_info, ctrl_shutdown_reason); pci_disable_device(ctrl_info->pci_dev); dev_err(&ctrl_info->pci_dev->dev, "controller offline\n"); schedule_work(&ctrl_info->ctrl_offline_work); @@ -9303,6 +9315,8 @@ static void __attribute__((unused)) verify_structures(void) sis_product_identifier) != 0xb4); BUILD_BUG_ON(offsetof(struct pqi_ctrl_registers, sis_firmware_status) != 0xbc); + BUILD_BUG_ON(offsetof(struct pqi_ctrl_registers, + sis_ctrl_shutdown_reason_code) != 0xcc); BUILD_BUG_ON(offsetof(struct pqi_ctrl_registers, sis_mailbox) != 0x1000); BUILD_BUG_ON(offsetof(struct pqi_ctrl_registers, diff --git a/drivers/scsi/smartpqi/smartpqi_sis.c b/drivers/scsi/smartpqi/smartpqi_sis.c index 8acd3a80f582..d66eb8ea161c 100644 --- a/drivers/scsi/smartpqi/smartpqi_sis.c +++ b/drivers/scsi/smartpqi/smartpqi_sis.c @@ -397,14 +397,17 @@ void sis_enable_intx(struct pqi_ctrl_info *ctrl_info) sis_set_doorbell_bit(ctrl_info, SIS_ENABLE_INTX); } -void sis_shutdown_ctrl(struct pqi_ctrl_info *ctrl_info) +void sis_shutdown_ctrl(struct pqi_ctrl_info *ctrl_info, + enum pqi_ctrl_shutdown_reason ctrl_shutdown_reason) { if (readl(&ctrl_info->registers->sis_firmware_status) & SIS_CTRL_KERNEL_PANIC) return; - writel(SIS_TRIGGER_SHUTDOWN, - &ctrl_info->registers->sis_host_to_ctrl_doorbell); + if (ctrl_info->firmware_triage_supported) + writel(ctrl_shutdown_reason, &ctrl_info->registers->sis_ctrl_shutdown_reason_code); + + writel(SIS_TRIGGER_SHUTDOWN, &ctrl_info->registers->sis_host_to_ctrl_doorbell); } int sis_pqi_reset_quiesce(struct pqi_ctrl_info *ctrl_info) diff --git a/drivers/scsi/smartpqi/smartpqi_sis.h b/drivers/scsi/smartpqi/smartpqi_sis.h index c1db93054c86..bd92ff49f385 100644 --- a/drivers/scsi/smartpqi/smartpqi_sis.h +++ b/drivers/scsi/smartpqi/smartpqi_sis.h @@ -21,7 +21,8 @@ int sis_get_pqi_capabilities(struct pqi_ctrl_info *ctrl_info); int sis_init_base_struct_addr(struct pqi_ctrl_info *ctrl_info); void sis_enable_msix(struct pqi_ctrl_info *ctrl_info); void sis_enable_intx(struct pqi_ctrl_info *ctrl_info); -void sis_shutdown_ctrl(struct pqi_ctrl_info *ctrl_info); +void sis_shutdown_ctrl(struct pqi_ctrl_info *ctrl_info, + enum pqi_ctrl_shutdown_reason ctrl_shutdown_reason); int sis_pqi_reset_quiesce(struct pqi_ctrl_info *ctrl_info); int sis_reenable_sis_mode(struct pqi_ctrl_info *ctrl_info); void sis_write_driver_scratch(struct pqi_ctrl_info *ctrl_info, u32 value); From 6ce1ddf53252dfd9debaef87648488c85d84a482 Mon Sep 17 00:00:00 2001 From: Kevin Barnett Date: Tue, 28 Sep 2021 18:54:35 -0500 Subject: [PATCH 092/279] scsi: smartpqi: Update LUN reset handler Enhance check for commands queued to the controller. Add new function pqi_nonempty_inbound_queue_count() that will wait for all I/O queued for submission to controller across all queue groups to drain. Add helper functions to obtain queue command counts for each queue group. These queues should drain quickly as they are already staged to be submitted down to the controller's IB queue. Enhance check for outstanding command completion. Update the count of outstanding commands while waiting. This value was not re-obtained and was potentially causing infinite wait for all completions. Link: https://lore.kernel.org/r/20210928235442.201875-5-don.brace@microchip.com Reviewed-by: Scott Benesh Reviewed-by: Scott Teel Reviewed-by: Mike McGowen Acked-by: John Donnelly Signed-off-by: Kevin Barnett Signed-off-by: Don Brace Signed-off-by: Martin K. Petersen --- drivers/scsi/smartpqi/smartpqi_init.c | 107 ++++++++++++++++---------- 1 file changed, 67 insertions(+), 40 deletions(-) diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c index b6ac4d607664..01330fd67500 100644 --- a/drivers/scsi/smartpqi/smartpqi_init.c +++ b/drivers/scsi/smartpqi/smartpqi_init.c @@ -5799,64 +5799,91 @@ out: return rc; } -static int pqi_wait_until_queued_io_drained(struct pqi_ctrl_info *ctrl_info, - struct pqi_queue_group *queue_group) +static unsigned int pqi_queued_io_count(struct pqi_ctrl_info *ctrl_info) { + unsigned int i; unsigned int path; unsigned long flags; - bool list_is_empty; + unsigned int queued_io_count; + struct pqi_queue_group *queue_group; + struct pqi_io_request *io_request; - for (path = 0; path < 2; path++) { - while (1) { - spin_lock_irqsave( - &queue_group->submit_lock[path], flags); - list_is_empty = - list_empty(&queue_group->request_list[path]); - spin_unlock_irqrestore( - &queue_group->submit_lock[path], flags); - if (list_is_empty) - break; - pqi_check_ctrl_health(ctrl_info); - if (pqi_ctrl_offline(ctrl_info)) - return -ENXIO; - usleep_range(1000, 2000); + queued_io_count = 0; + + for (i = 0; i < ctrl_info->num_queue_groups; i++) { + queue_group = &ctrl_info->queue_groups[i]; + for (path = 0; path < 2; path++) { + spin_lock_irqsave(&queue_group->submit_lock[path], flags); + list_for_each_entry(io_request, &queue_group->request_list[path], request_list_entry) + queued_io_count++; + spin_unlock_irqrestore(&queue_group->submit_lock[path], flags); } } - return 0; + return queued_io_count; } -static int pqi_wait_until_inbound_queues_empty(struct pqi_ctrl_info *ctrl_info) +static unsigned int pqi_nonempty_inbound_queue_count(struct pqi_ctrl_info *ctrl_info) { - int rc; unsigned int i; unsigned int path; + unsigned int nonempty_inbound_queue_count; struct pqi_queue_group *queue_group; pqi_index_t iq_pi; pqi_index_t iq_ci; + nonempty_inbound_queue_count = 0; + for (i = 0; i < ctrl_info->num_queue_groups; i++) { queue_group = &ctrl_info->queue_groups[i]; - - rc = pqi_wait_until_queued_io_drained(ctrl_info, queue_group); - if (rc) - return rc; - for (path = 0; path < 2; path++) { iq_pi = queue_group->iq_pi_copy[path]; - - while (1) { - iq_ci = readl(queue_group->iq_ci[path]); - if (iq_ci == iq_pi) - break; - pqi_check_ctrl_health(ctrl_info); - if (pqi_ctrl_offline(ctrl_info)) - return -ENXIO; - usleep_range(1000, 2000); - } + iq_ci = readl(queue_group->iq_ci[path]); + if (iq_ci != iq_pi) + nonempty_inbound_queue_count++; } } + return nonempty_inbound_queue_count; +} + +#define PQI_INBOUND_QUEUES_NONEMPTY_WARNING_TIMEOUT_SECS 10 + +static int pqi_wait_until_inbound_queues_empty(struct pqi_ctrl_info *ctrl_info) +{ + unsigned long start_jiffies; + unsigned long warning_timeout; + unsigned int queued_io_count; + unsigned int nonempty_inbound_queue_count; + bool displayed_warning; + + displayed_warning = false; + start_jiffies = jiffies; + warning_timeout = (PQI_INBOUND_QUEUES_NONEMPTY_WARNING_TIMEOUT_SECS * PQI_HZ) + start_jiffies; + + while (1) { + queued_io_count = pqi_queued_io_count(ctrl_info); + nonempty_inbound_queue_count = pqi_nonempty_inbound_queue_count(ctrl_info); + if (queued_io_count == 0 && nonempty_inbound_queue_count == 0) + break; + pqi_check_ctrl_health(ctrl_info); + if (pqi_ctrl_offline(ctrl_info)) + return -ENXIO; + if (time_after(jiffies, warning_timeout)) { + dev_warn(&ctrl_info->pci_dev->dev, + "waiting %u seconds for queued I/O to drain (queued I/O count: %u; non-empty inbound queue count: %u)\n", + jiffies_to_msecs(jiffies - start_jiffies) / 1000, queued_io_count, nonempty_inbound_queue_count); + displayed_warning = true; + warning_timeout = (PQI_INBOUND_QUEUES_NONEMPTY_WARNING_TIMEOUT_SECS * PQI_HZ) + jiffies; + } + usleep_range(1000, 2000); + } + + if (displayed_warning) + dev_warn(&ctrl_info->pci_dev->dev, + "queued I/O drained after waiting for %u seconds\n", + jiffies_to_msecs(jiffies - start_jiffies) / 1000); + return 0; } @@ -5922,7 +5949,7 @@ static int pqi_device_wait_for_pending_io(struct pqi_ctrl_info *ctrl_info, if (pqi_ctrl_offline(ctrl_info)) return -ENXIO; msecs_waiting = jiffies_to_msecs(jiffies - start_jiffies); - if (msecs_waiting > timeout_msecs) { + if (msecs_waiting >= timeout_msecs) { dev_err(&ctrl_info->pci_dev->dev, "scsi %d:%d:%d:%d: timed out after %lu seconds waiting for %d outstanding command(s)\n", ctrl_info->scsi_host->host_no, device->bus, device->target, @@ -5957,6 +5984,7 @@ static int pqi_wait_for_lun_reset_completion(struct pqi_ctrl_info *ctrl_info, { int rc; unsigned int wait_secs; + int cmds_outstanding; wait_secs = 0; @@ -5974,11 +6002,10 @@ static int pqi_wait_for_lun_reset_completion(struct pqi_ctrl_info *ctrl_info, } wait_secs += PQI_LUN_RESET_POLL_COMPLETION_SECS; - + cmds_outstanding = atomic_read(&device->scsi_cmds_outstanding); dev_warn(&ctrl_info->pci_dev->dev, - "scsi %d:%d:%d:%d: waiting %u seconds for LUN reset to complete\n", - ctrl_info->scsi_host->host_no, device->bus, device->target, device->lun, - wait_secs); + "scsi %d:%d:%d:%d: waiting %u seconds for LUN reset to complete (%d command(s) outstanding)\n", + ctrl_info->scsi_host->host_no, device->bus, device->target, device->lun, wait_secs, cmds_outstanding); } return rc; From be76f90668d8406dccb4c05d6edde89f48ad04d8 Mon Sep 17 00:00:00 2001 From: Don Brace Date: Tue, 28 Sep 2021 18:54:36 -0500 Subject: [PATCH 093/279] scsi: smartpqi: Add TEST UNIT READY check for SANITIZE operation Send a TEST UNIT READY to HBA disks and do not present them to the OS if 0x02/0x04/0x1b (SANITIZE IN PROGRESS) is returned. During boot-up, some OSes appear to hang when there are one or more disks undergoing a sanitize operation. According to SCSI SBC4 specification section 4.11.2 "Commands allowed during SANITIZE", some SCSI commands are permitted, but read/write operations are not. When the OS attempts to read the disk partition table a CHECK CONDITION ASC 0x04 ASCQ 0x1b is returned which causes the OS to retry the read until SANITIZE has completed. This can take hours. According to document HPE Smart Storage Administrator User Guide, during the sanitize erase operation, the drive is unusable. I.e. the expected behavior for SANITIZE is the that disk remains offline even after SANITIZE has completed. The customer is expected to re-enable the disk using the management utility. Link: https://lore.kernel.org/r/20210928235442.201875-6-don.brace@microchip.com Reviewed-by: Scott Benesh Reviewed-by: Scott Teel Reviewed-by: Mike McGowen Acked-by: John Donnelly Signed-off-by: Don Brace Signed-off-by: Martin K. Petersen --- drivers/scsi/smartpqi/smartpqi_init.c | 87 +++++++++++++++++++++++++++ 1 file changed, 87 insertions(+) diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c index 01330fd67500..838274d8fadf 100644 --- a/drivers/scsi/smartpqi/smartpqi_init.c +++ b/drivers/scsi/smartpqi/smartpqi_init.c @@ -555,6 +555,10 @@ static int pqi_build_raid_path_request(struct pqi_ctrl_info *ctrl_info, cdb = request->cdb; switch (cmd) { + case TEST_UNIT_READY: + request->data_direction = SOP_READ_FLAG; + cdb[0] = TEST_UNIT_READY; + break; case INQUIRY: request->data_direction = SOP_READ_FLAG; cdb[0] = INQUIRY; @@ -1575,6 +1579,85 @@ out: return rc; } +/* + * Prevent adding drive to OS for some corner cases such as a drive + * undergoing a sanitize operation. Some OSes will continue to poll + * the drive until the sanitize completes, which can take hours, + * resulting in long bootup delays. Commands such as TUR, READ_CAP + * are allowed, but READ/WRITE cause check condition. So the OS + * cannot check/read the partition table. + * Note: devices that have completed sanitize must be re-enabled + * using the management utility. + */ +static bool pqi_keep_device_offline(struct pqi_ctrl_info *ctrl_info, + struct pqi_scsi_dev *device) +{ + u8 scsi_status; + int rc; + enum dma_data_direction dir; + char *buffer; + int buffer_length = 64; + size_t sense_data_length; + struct scsi_sense_hdr sshdr; + struct pqi_raid_path_request request; + struct pqi_raid_error_info error_info; + bool offline = false; /* Assume keep online */ + + /* Do not check controllers. */ + if (pqi_is_hba_lunid(device->scsi3addr)) + return false; + + /* Do not check LVs. */ + if (pqi_is_logical_device(device)) + return false; + + buffer = kmalloc(buffer_length, GFP_KERNEL); + if (!buffer) + return false; /* Assume not offline */ + + /* Check for SANITIZE in progress using TUR */ + rc = pqi_build_raid_path_request(ctrl_info, &request, + TEST_UNIT_READY, RAID_CTLR_LUNID, buffer, + buffer_length, 0, &dir); + if (rc) + goto out; /* Assume not offline */ + + memcpy(request.lun_number, device->scsi3addr, sizeof(request.lun_number)); + + rc = pqi_submit_raid_request_synchronous(ctrl_info, &request.header, 0, &error_info); + + if (rc) + goto out; /* Assume not offline */ + + scsi_status = error_info.status; + sense_data_length = get_unaligned_le16(&error_info.sense_data_length); + if (sense_data_length == 0) + sense_data_length = + get_unaligned_le16(&error_info.response_data_length); + if (sense_data_length) { + if (sense_data_length > sizeof(error_info.data)) + sense_data_length = sizeof(error_info.data); + + /* + * Check for sanitize in progress: asc:0x04, ascq: 0x1b + */ + if (scsi_status == SAM_STAT_CHECK_CONDITION && + scsi_normalize_sense(error_info.data, + sense_data_length, &sshdr) && + sshdr.sense_key == NOT_READY && + sshdr.asc == 0x04 && + sshdr.ascq == 0x1b) { + device->device_offline = true; + offline = true; + goto out; /* Keep device offline */ + } + } + +out: + kfree(buffer); + return offline; +} + static int pqi_get_device_info(struct pqi_ctrl_info *ctrl_info, struct pqi_scsi_dev *device, struct bmic_identify_physical_device *id_phys) @@ -2296,6 +2379,10 @@ static int pqi_update_scsi_devices(struct pqi_ctrl_info *ctrl_info) if (!pqi_is_supported_device(device)) continue; + /* Do not present disks that the OS cannot fully probe */ + if (pqi_keep_device_offline(ctrl_info, device)) + continue; + /* Gather information about the device. */ rc = pqi_get_device_info(ctrl_info, device, id_phys); if (rc == -ENOMEM) { From 4f3cefc3084d543d8fece39cf7388e3c0ef9e44d Mon Sep 17 00:00:00 2001 From: Mahesh Rajashekhara Date: Tue, 28 Sep 2021 18:54:37 -0500 Subject: [PATCH 094/279] scsi: smartpqi: Avoid failing I/Os for offline devices Prevent kernel crash by failing outstanding I/O request when the OS takes device offline. When posted I/Os to the controller's inbound queue are not picked by the controller, the driver will halt the controller and take the controller offline. When the driver takes the controller offline, the driver will fail all the outstanding requests which can sometimes lead to an OS crash. Link: https://lore.kernel.org/r/20210928235442.201875-7-don.brace@microchip.com Reviewed-by: Scott Benesh Reviewed-by: Scott Teel Acked-by: John Donnelly Signed-off-by: Mahesh Rajashekhara Signed-off-by: Don Brace Signed-off-by: Martin K. Petersen --- drivers/scsi/smartpqi/smartpqi_init.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c index 838274d8fadf..c9f2a3d54663 100644 --- a/drivers/scsi/smartpqi/smartpqi_init.c +++ b/drivers/scsi/smartpqi/smartpqi_init.c @@ -8544,6 +8544,7 @@ static void pqi_fail_all_outstanding_requests(struct pqi_ctrl_info *ctrl_info) unsigned int i; struct pqi_io_request *io_request; struct scsi_cmnd *scmd; + struct scsi_device *sdev; for (i = 0; i < ctrl_info->max_io_slots; i++) { io_request = &ctrl_info->io_request_pool[i]; @@ -8552,7 +8553,13 @@ static void pqi_fail_all_outstanding_requests(struct pqi_ctrl_info *ctrl_info) scmd = io_request->scmd; if (scmd) { - set_host_byte(scmd, DID_NO_CONNECT); + sdev = scmd->device; + if (!sdev || !scsi_device_online(sdev)) { + pqi_free_io_request(io_request); + continue; + } else { + set_host_byte(scmd, DID_NO_CONNECT); + } } else { io_request->status = -ENXIO; io_request->error_info = From 28ca6d876c5a375094847606046e0bf5d044d9b4 Mon Sep 17 00:00:00 2001 From: Mike McGowen Date: Tue, 28 Sep 2021 18:54:38 -0500 Subject: [PATCH 095/279] scsi: smartpqi: Add extended report physical LUNs Add support for the new extended formats in the data returned from the Report Physical LUNs command for controllers that enable this feature. The new formats allow the reporting of 16-byte WWIDs. Link: https://lore.kernel.org/r/20210928235442.201875-8-don.brace@microchip.com Reviewed-by: Scott Benesh Reviewed-by: Scott Teel Acked-by: John Donnelly Signed-off-by: Mike McGowen Signed-off-by: Don Brace Signed-off-by: Martin K. Petersen --- drivers/scsi/smartpqi/smartpqi.h | 37 +++- drivers/scsi/smartpqi/smartpqi_init.c | 163 +++++++++++++----- .../scsi/smartpqi/smartpqi_sas_transport.c | 6 +- 3 files changed, 147 insertions(+), 59 deletions(-) diff --git a/drivers/scsi/smartpqi/smartpqi.h b/drivers/scsi/smartpqi/smartpqi.h index d66863f8d1cf..c439583a4ca5 100644 --- a/drivers/scsi/smartpqi/smartpqi.h +++ b/drivers/scsi/smartpqi/smartpqi.h @@ -868,7 +868,8 @@ struct pqi_config_table_firmware_features { #define PQI_FIRMWARE_FEATURE_RAID_BYPASS_ON_ENCRYPTED_NVME 15 #define PQI_FIRMWARE_FEATURE_UNIQUE_WWID_IN_REPORT_PHYS_LUN 16 #define PQI_FIRMWARE_FEATURE_FW_TRIAGE 17 -#define PQI_FIRMWARE_FEATURE_MAXIMUM 17 +#define PQI_FIRMWARE_FEATURE_RPL_EXTENDED_FORMAT_4_5 18 +#define PQI_FIRMWARE_FEATURE_MAXIMUM 18 struct pqi_config_table_debug { struct pqi_config_table_section_header header; @@ -943,19 +944,21 @@ struct report_lun_header { #define CISS_REPORT_LOG_FLAG_QUEUE_DEPTH (1 << 5) #define CISS_REPORT_LOG_FLAG_DRIVE_TYPE_MIX (1 << 6) -#define CISS_REPORT_PHYS_FLAG_OTHER (1 << 1) +#define CISS_REPORT_PHYS_FLAG_EXTENDED_FORMAT_2 0x2 +#define CISS_REPORT_PHYS_FLAG_EXTENDED_FORMAT_4 0x4 +#define CISS_REPORT_PHYS_FLAG_EXTENDED_FORMAT_MASK 0xf -struct report_log_lun_extended_entry { +struct report_log_lun { u8 lunid[8]; u8 volume_id[16]; }; -struct report_log_lun_extended { +struct report_log_lun_list { struct report_lun_header header; - struct report_log_lun_extended_entry lun_entries[1]; + struct report_log_lun lun_entries[1]; }; -struct report_phys_lun_extended_entry { +struct report_phys_lun_8byte_wwid { u8 lunid[8]; __be64 wwid; u8 device_type; @@ -965,12 +968,27 @@ struct report_phys_lun_extended_entry { u32 aio_handle; }; +struct report_phys_lun_16byte_wwid { + u8 lunid[8]; + u8 wwid[16]; + u8 device_type; + u8 device_flags; + u8 lun_count; /* number of LUNs in a multi-LUN device */ + u8 redundant_paths; + u32 aio_handle; +}; + /* for device_flags field of struct report_phys_lun_extended_entry */ #define CISS_REPORT_PHYS_DEV_FLAG_AIO_ENABLED 0x8 -struct report_phys_lun_extended { +struct report_phys_lun_8byte_wwid_list { struct report_lun_header header; - struct report_phys_lun_extended_entry lun_entries[1]; + struct report_phys_lun_8byte_wwid lun_entries[1]; +}; + +struct report_phys_lun_16byte_wwid_list { + struct report_lun_header header; + struct report_phys_lun_16byte_wwid lun_entries[1]; }; struct raid_map_disk_data { @@ -1077,7 +1095,7 @@ struct pqi_scsi_dev { int target; int lun; u8 scsi3addr[8]; - __be64 wwid; + u8 wwid[16]; u8 volume_id[16]; u8 is_physical_device : 1; u8 is_external_raid_device : 1; @@ -1316,6 +1334,7 @@ struct pqi_ctrl_info { u8 tmf_iu_timeout_supported : 1; u8 unique_wwid_in_report_phys_lun_supported : 1; u8 firmware_triage_supported : 1; + u8 rpl_extended_format_4_5_supported : 1; u8 enable_r1_writes : 1; u8 enable_r5_writes : 1; u8 enable_r6_writes : 1; diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c index c9f2a3d54663..1e27e6ba0159 100644 --- a/drivers/scsi/smartpqi/smartpqi_init.c +++ b/drivers/scsi/smartpqi/smartpqi_init.c @@ -572,10 +572,14 @@ static int pqi_build_raid_path_request(struct pqi_ctrl_info *ctrl_info, case CISS_REPORT_PHYS: request->data_direction = SOP_READ_FLAG; cdb[0] = cmd; - if (cmd == CISS_REPORT_PHYS) - cdb[1] = CISS_REPORT_PHYS_FLAG_OTHER; - else + if (cmd == CISS_REPORT_PHYS) { + if (ctrl_info->rpl_extended_format_4_5_supported) + cdb[1] = CISS_REPORT_PHYS_FLAG_EXTENDED_FORMAT_4; + else + cdb[1] = CISS_REPORT_PHYS_FLAG_EXTENDED_FORMAT_2; + } else { cdb[1] = ctrl_info->ciss_report_log_flags; + } put_unaligned_be32(cdb_length, &cdb[6]); break; case CISS_GET_RAID_MAP: @@ -1132,7 +1136,64 @@ out: static inline int pqi_report_phys_luns(struct pqi_ctrl_info *ctrl_info, void **buffer) { - return pqi_report_phys_logical_luns(ctrl_info, CISS_REPORT_PHYS, buffer); + int rc; + unsigned int i; + u8 rpl_response_format; + u32 num_physicals; + size_t rpl_16byte_wwid_list_length; + void *rpl_list; + struct report_lun_header *rpl_header; + struct report_phys_lun_8byte_wwid_list *rpl_8byte_wwid_list; + struct report_phys_lun_16byte_wwid_list *rpl_16byte_wwid_list; + + rc = pqi_report_phys_logical_luns(ctrl_info, CISS_REPORT_PHYS, &rpl_list); + if (rc) + return rc; + + if (ctrl_info->rpl_extended_format_4_5_supported) { + rpl_header = rpl_list; + rpl_response_format = rpl_header->flags & CISS_REPORT_PHYS_FLAG_EXTENDED_FORMAT_MASK; + if (rpl_response_format == CISS_REPORT_PHYS_FLAG_EXTENDED_FORMAT_4) { + *buffer = rpl_list; + return 0; + } else if (rpl_response_format != CISS_REPORT_PHYS_FLAG_EXTENDED_FORMAT_2) { + dev_err(&ctrl_info->pci_dev->dev, + "RPL returned unsupported data format %u\n", + rpl_response_format); + return -EINVAL; + } else { + dev_warn(&ctrl_info->pci_dev->dev, + "RPL returned extended format 2 instead of 4\n"); + } + } + + rpl_8byte_wwid_list = rpl_list; + num_physicals = get_unaligned_be32(&rpl_8byte_wwid_list->header.list_length) / sizeof(rpl_8byte_wwid_list->lun_entries[0]); + rpl_16byte_wwid_list_length = sizeof(struct report_lun_header) + (num_physicals * sizeof(struct report_phys_lun_16byte_wwid)); + + rpl_16byte_wwid_list = kmalloc(rpl_16byte_wwid_list_length, GFP_KERNEL); + if (!rpl_16byte_wwid_list) + return -ENOMEM; + + put_unaligned_be32(num_physicals * sizeof(struct report_phys_lun_16byte_wwid), + &rpl_16byte_wwid_list->header.list_length); + rpl_16byte_wwid_list->header.flags = rpl_8byte_wwid_list->header.flags; + + for (i = 0; i < num_physicals; i++) { + memcpy(&rpl_16byte_wwid_list->lun_entries[i].lunid, &rpl_8byte_wwid_list->lun_entries[i].lunid, sizeof(rpl_8byte_wwid_list->lun_entries[i].lunid)); + memset(&rpl_16byte_wwid_list->lun_entries[i].wwid, 0, 8); + memcpy(&rpl_16byte_wwid_list->lun_entries[i].wwid[8], &rpl_8byte_wwid_list->lun_entries[i].wwid, sizeof(rpl_8byte_wwid_list->lun_entries[i].wwid)); + rpl_16byte_wwid_list->lun_entries[i].device_type = rpl_8byte_wwid_list->lun_entries[i].device_type; + rpl_16byte_wwid_list->lun_entries[i].device_flags = rpl_8byte_wwid_list->lun_entries[i].device_flags; + rpl_16byte_wwid_list->lun_entries[i].lun_count = rpl_8byte_wwid_list->lun_entries[i].lun_count; + rpl_16byte_wwid_list->lun_entries[i].redundant_paths = rpl_8byte_wwid_list->lun_entries[i].redundant_paths; + rpl_16byte_wwid_list->lun_entries[i].aio_handle = rpl_8byte_wwid_list->lun_entries[i].aio_handle; + } + + kfree(rpl_8byte_wwid_list); + *buffer = rpl_16byte_wwid_list; + + return 0; } static inline int pqi_report_logical_luns(struct pqi_ctrl_info *ctrl_info, void **buffer) @@ -1141,14 +1202,14 @@ static inline int pqi_report_logical_luns(struct pqi_ctrl_info *ctrl_info, void } static int pqi_get_device_lists(struct pqi_ctrl_info *ctrl_info, - struct report_phys_lun_extended **physdev_list, - struct report_log_lun_extended **logdev_list) + struct report_phys_lun_16byte_wwid_list **physdev_list, + struct report_log_lun_list **logdev_list) { int rc; size_t logdev_list_length; size_t logdev_data_length; - struct report_log_lun_extended *internal_logdev_list; - struct report_log_lun_extended *logdev_data; + struct report_log_lun_list *internal_logdev_list; + struct report_log_lun_list *logdev_data; struct report_lun_header report_lun_header; rc = pqi_report_phys_luns(ctrl_info, (void **)physdev_list); @@ -1173,7 +1234,7 @@ static int pqi_get_device_lists(struct pqi_ctrl_info *ctrl_info, } else { memset(&report_lun_header, 0, sizeof(report_lun_header)); logdev_data = - (struct report_log_lun_extended *)&report_lun_header; + (struct report_log_lun_list *)&report_lun_header; logdev_list_length = 0; } @@ -1181,7 +1242,7 @@ static int pqi_get_device_lists(struct pqi_ctrl_info *ctrl_info, logdev_list_length; internal_logdev_list = kmalloc(logdev_data_length + - sizeof(struct report_log_lun_extended), GFP_KERNEL); + sizeof(struct report_log_lun), GFP_KERNEL); if (!internal_logdev_list) { kfree(*logdev_list); *logdev_list = NULL; @@ -1190,9 +1251,9 @@ static int pqi_get_device_lists(struct pqi_ctrl_info *ctrl_info, memcpy(internal_logdev_list, logdev_data, logdev_data_length); memset((u8 *)internal_logdev_list + logdev_data_length, 0, - sizeof(struct report_log_lun_extended_entry)); + sizeof(struct report_log_lun)); put_unaligned_be32(logdev_list_length + - sizeof(struct report_log_lun_extended_entry), + sizeof(struct report_log_lun), &internal_logdev_list->header.list_length); kfree(*logdev_list); @@ -1845,7 +1906,7 @@ static inline bool pqi_device_equal(struct pqi_scsi_dev *dev1, struct pqi_scsi_d return false; if (dev1->is_physical_device) - return dev1->wwid == dev2->wwid; + return memcmp(dev1->wwid, dev2->wwid, sizeof(dev1->wwid)) == 0; return memcmp(dev1->volume_id, dev2->volume_id, sizeof(dev1->volume_id)) == 0; } @@ -1915,7 +1976,9 @@ static void pqi_dev_info(struct pqi_ctrl_info *ctrl_info, else count += scnprintf(buffer + count, PQI_DEV_INFO_BUFFER_LENGTH - count, - " %016llx", device->sas_address); + " %016llx%016llx", + get_unaligned_be64(&device->wwid[0]), + get_unaligned_be64(&device->wwid[8])); count += scnprintf(buffer + count, PQI_DEV_INFO_BUFFER_LENGTH - count, " %s %.8s %.16s ", @@ -2229,13 +2292,14 @@ static inline bool pqi_expose_device(struct pqi_scsi_dev *device) } static inline void pqi_set_physical_device_wwid(struct pqi_ctrl_info *ctrl_info, - struct pqi_scsi_dev *device, struct report_phys_lun_extended_entry *phys_lun_ext_entry) + struct pqi_scsi_dev *device, struct report_phys_lun_16byte_wwid *phys_lun) { if (ctrl_info->unique_wwid_in_report_phys_lun_supported || + ctrl_info->rpl_extended_format_4_5_supported || pqi_is_device_with_sas_address(device)) - device->wwid = phys_lun_ext_entry->wwid; + memcpy(device->wwid, phys_lun->wwid, sizeof(device->wwid)); else - device->wwid = cpu_to_be64(get_unaligned_be64(&device->page_83_identifier)); + memcpy(&device->wwid[8], device->page_83_identifier, 8); } static int pqi_update_scsi_devices(struct pqi_ctrl_info *ctrl_info) @@ -2243,10 +2307,10 @@ static int pqi_update_scsi_devices(struct pqi_ctrl_info *ctrl_info) int i; int rc; LIST_HEAD(new_device_list_head); - struct report_phys_lun_extended *physdev_list = NULL; - struct report_log_lun_extended *logdev_list = NULL; - struct report_phys_lun_extended_entry *phys_lun_ext_entry; - struct report_log_lun_extended_entry *log_lun_ext_entry; + struct report_phys_lun_16byte_wwid_list *physdev_list = NULL; + struct report_log_lun_list *logdev_list = NULL; + struct report_phys_lun_16byte_wwid *phys_lun; + struct report_log_lun *log_lun; struct bmic_identify_physical_device *id_phys = NULL; u32 num_physicals; u32 num_logicals; @@ -2297,10 +2361,9 @@ static int pqi_update_scsi_devices(struct pqi_ctrl_info *ctrl_info) if (pqi_hide_vsep) { for (i = num_physicals - 1; i >= 0; i--) { - phys_lun_ext_entry = - &physdev_list->lun_entries[i]; - if (CISS_GET_DRIVE_NUMBER(phys_lun_ext_entry->lunid) == PQI_VSEP_CISS_BTL) { - pqi_mask_device(phys_lun_ext_entry->lunid); + phys_lun = &physdev_list->lun_entries[i]; + if (CISS_GET_DRIVE_NUMBER(phys_lun->lunid) == PQI_VSEP_CISS_BTL) { + pqi_mask_device(phys_lun->lunid); break; } } @@ -2344,16 +2407,14 @@ static int pqi_update_scsi_devices(struct pqi_ctrl_info *ctrl_info) if ((!pqi_expose_ld_first && i < num_physicals) || (pqi_expose_ld_first && i >= num_logicals)) { is_physical_device = true; - phys_lun_ext_entry = - &physdev_list->lun_entries[physical_index++]; - log_lun_ext_entry = NULL; - scsi3addr = phys_lun_ext_entry->lunid; + phys_lun = &physdev_list->lun_entries[physical_index++]; + log_lun = NULL; + scsi3addr = phys_lun->lunid; } else { is_physical_device = false; - phys_lun_ext_entry = NULL; - log_lun_ext_entry = - &logdev_list->lun_entries[logical_index++]; - scsi3addr = log_lun_ext_entry->lunid; + phys_lun = NULL; + log_lun = &logdev_list->lun_entries[logical_index++]; + scsi3addr = log_lun->lunid; } if (is_physical_device && pqi_skip_device(scsi3addr)) @@ -2368,7 +2429,7 @@ static int pqi_update_scsi_devices(struct pqi_ctrl_info *ctrl_info) memcpy(device->scsi3addr, scsi3addr, sizeof(device->scsi3addr)); device->is_physical_device = is_physical_device; if (is_physical_device) { - device->device_type = phys_lun_ext_entry->device_type; + device->device_type = phys_lun->device_type; if (device->device_type == SA_DEVICE_TYPE_EXPANDER_SMP) device->is_expander_smp_device = true; } else { @@ -2393,8 +2454,9 @@ static int pqi_update_scsi_devices(struct pqi_ctrl_info *ctrl_info) if (rc) { if (device->is_physical_device) dev_warn(&ctrl_info->pci_dev->dev, - "obtaining device info failed, skipping physical device %016llx\n", - get_unaligned_be64(&phys_lun_ext_entry->wwid)); + "obtaining device info failed, skipping physical device %016llx%016llx\n", + get_unaligned_be64(&phys_lun->wwid[0]), + get_unaligned_be64(&phys_lun->wwid[8])); else dev_warn(&ctrl_info->pci_dev->dev, "obtaining device info failed, skipping logical device %08x%08x\n", @@ -2407,21 +2469,21 @@ static int pqi_update_scsi_devices(struct pqi_ctrl_info *ctrl_info) pqi_assign_bus_target_lun(device); if (device->is_physical_device) { - pqi_set_physical_device_wwid(ctrl_info, device, phys_lun_ext_entry); - if ((phys_lun_ext_entry->device_flags & + pqi_set_physical_device_wwid(ctrl_info, device, phys_lun); + if ((phys_lun->device_flags & CISS_REPORT_PHYS_DEV_FLAG_AIO_ENABLED) && - phys_lun_ext_entry->aio_handle) { + phys_lun->aio_handle) { device->aio_enabled = true; device->aio_handle = - phys_lun_ext_entry->aio_handle; + phys_lun->aio_handle; } } else { - memcpy(device->volume_id, log_lun_ext_entry->volume_id, + memcpy(device->volume_id, log_lun->volume_id, sizeof(device->volume_id)); } if (pqi_is_device_with_sas_address(device)) - device->sas_address = get_unaligned_be64(&device->wwid); + device->sas_address = get_unaligned_be64(&device->wwid[8]); new_device_list[num_valid_devices++] = device; } @@ -6804,12 +6866,10 @@ static ssize_t pqi_unique_id_show(struct device *dev, return -ENODEV; } - if (device->is_physical_device) { - memset(unique_id, 0, 8); - memcpy(unique_id + 8, &device->wwid, sizeof(device->wwid)); - } else { + if (device->is_physical_device) + memcpy(unique_id, device->wwid, sizeof(device->wwid)); + else memcpy(unique_id, device->volume_id, sizeof(device->volume_id)); - } spin_unlock_irqrestore(&ctrl_info->scsi_device_list_lock, flags); @@ -7443,6 +7503,9 @@ static void pqi_ctrl_update_feature_flags(struct pqi_ctrl_info *ctrl_info, ctrl_info->firmware_triage_supported = firmware_feature->enabled; pqi_save_fw_triage_setting(ctrl_info, firmware_feature->enabled); break; + case PQI_FIRMWARE_FEATURE_RPL_EXTENDED_FORMAT_4_5: + ctrl_info->rpl_extended_format_4_5_supported = firmware_feature->enabled; + break; } pqi_firmware_feature_status(ctrl_info, firmware_feature); @@ -7543,6 +7606,11 @@ static struct pqi_firmware_feature pqi_firmware_features[] = { .feature_bit = PQI_FIRMWARE_FEATURE_FW_TRIAGE, .feature_status = pqi_ctrl_update_feature_flags, }, + { + .feature_name = "RPL Extended Formats 4 and 5", + .feature_bit = PQI_FIRMWARE_FEATURE_RPL_EXTENDED_FORMAT_4_5, + .feature_status = pqi_ctrl_update_feature_flags, + }, }; static void pqi_process_firmware_features( @@ -7644,6 +7712,7 @@ static void pqi_ctrl_reset_config(struct pqi_ctrl_info *ctrl_info) ctrl_info->tmf_iu_timeout_supported = false; ctrl_info->unique_wwid_in_report_phys_lun_supported = false; ctrl_info->firmware_triage_supported = false; + ctrl_info->rpl_extended_format_4_5_supported = false; } static int pqi_process_config_table(struct pqi_ctrl_info *ctrl_info) diff --git a/drivers/scsi/smartpqi/smartpqi_sas_transport.c b/drivers/scsi/smartpqi/smartpqi_sas_transport.c index afd9bafebd1d..dea4ebaf1677 100644 --- a/drivers/scsi/smartpqi/smartpqi_sas_transport.c +++ b/drivers/scsi/smartpqi/smartpqi_sas_transport.c @@ -343,7 +343,7 @@ static int pqi_sas_get_enclosure_identifier(struct sas_rphy *rphy, } if (found_device->devtype == TYPE_ENCLOSURE) { - *identifier = get_unaligned_be64(&found_device->wwid); + *identifier = get_unaligned_be64(&found_device->wwid[8]); rc = 0; goto out; } @@ -364,7 +364,7 @@ static int pqi_sas_get_enclosure_identifier(struct sas_rphy *rphy, memcmp(device->phys_connector, found_device->phys_connector, 2) == 0) { *identifier = - get_unaligned_be64(&device->wwid); + get_unaligned_be64(&device->wwid[8]); rc = 0; goto out; } @@ -380,7 +380,7 @@ static int pqi_sas_get_enclosure_identifier(struct sas_rphy *rphy, if (device->devtype == TYPE_ENCLOSURE && CISS_GET_DRIVE_NUMBER(device->scsi3addr) == PQI_VSEP_CISS_BTL) { - *identifier = get_unaligned_be64(&device->wwid); + *identifier = get_unaligned_be64(&device->wwid[8]); rc = 0; goto out; } From 987d35605b7e82745bf69104611725d6505ed5a3 Mon Sep 17 00:00:00 2001 From: Mike McGowen Date: Tue, 28 Sep 2021 18:54:39 -0500 Subject: [PATCH 096/279] scsi: smartpqi: Fix boot failure during LUN rebuild Move the delay in the register polling loop to the beginning of the loop to ensure there is always a delay between writing the register and reading it. Link: https://lore.kernel.org/r/20210928235442.201875-9-don.brace@microchip.com Reviewed-by: Scott Benesh Reviewed-by: Scott Teel Acked-by: John Donnelly Signed-off-by: Mike McGowen Signed-off-by: Don Brace Signed-off-by: Martin K. Petersen --- drivers/scsi/smartpqi/smartpqi_init.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c index 1e27e6ba0159..c28eb7ea4a24 100644 --- a/drivers/scsi/smartpqi/smartpqi_init.c +++ b/drivers/scsi/smartpqi/smartpqi_init.c @@ -4278,12 +4278,12 @@ static int pqi_create_admin_queues(struct pqi_ctrl_info *ctrl_info) timeout = PQI_ADMIN_QUEUE_CREATE_TIMEOUT_JIFFIES + jiffies; while (1) { + msleep(PQI_ADMIN_QUEUE_CREATE_POLL_INTERVAL_MSECS); status = readb(&pqi_registers->function_and_status_code); if (status == PQI_STATUS_IDLE) break; if (time_after(jiffies, timeout)) return -ETIMEDOUT; - msleep(PQI_ADMIN_QUEUE_CREATE_POLL_INTERVAL_MSECS); } /* From d4dc6aea93cb40f454e3a4d0eb139633874d0f72 Mon Sep 17 00:00:00 2001 From: Kevin Barnett Date: Tue, 28 Sep 2021 18:54:40 -0500 Subject: [PATCH 097/279] scsi: smartpqi: Fix duplicate device nodes for tape changers Stop the OS from re-discovering multiple LUNs for tape drive and medium changer. Duplicate device nodes for Ultrium tape drive and medium changer are being created. The Ultrium tape drive is a multi-LUN SCSI target. It presents a LUN for the tape drive and a 2nd LUN for the medium changer. Our controller FW lists both LUNs in the RPL results. As a result, the smartpqi driver exposes both devices to the OS. Then the OS does its normal device discovery via the SCSI REPORT LUNS command, which causes it to re-discover both devices a 2nd time, which results in the duplicate device nodes. Link: https://lore.kernel.org/r/20210928235442.201875-10-don.brace@microchip.com Reviewed-by: Scott Benesh Reviewed-by: Scott Teel Reviewed-by: Mike McGowen Acked-by: John Donnelly Signed-off-by: Kevin Barnett Signed-off-by: Don Brace Signed-off-by: Martin K. Petersen --- drivers/scsi/smartpqi/smartpqi.h | 1 + drivers/scsi/smartpqi/smartpqi_init.c | 23 +++++++++++++++++++---- 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/drivers/scsi/smartpqi/smartpqi.h b/drivers/scsi/smartpqi/smartpqi.h index c439583a4ca5..aac88ac0a0b7 100644 --- a/drivers/scsi/smartpqi/smartpqi.h +++ b/drivers/scsi/smartpqi/smartpqi.h @@ -1106,6 +1106,7 @@ struct pqi_scsi_dev { u8 keep_device : 1; u8 volume_offline : 1; u8 rescan : 1; + u8 ignore_device : 1; bool aio_enabled; /* only valid for physical disks */ bool in_remove; bool device_offline; diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c index c28eb7ea4a24..8be116992cb0 100644 --- a/drivers/scsi/smartpqi/smartpqi_init.c +++ b/drivers/scsi/smartpqi/smartpqi_init.c @@ -6297,9 +6297,13 @@ static int pqi_slave_alloc(struct scsi_device *sdev) rphy = target_to_rphy(starget); device = pqi_find_device_by_sas_rphy(ctrl_info, rphy); if (device) { - device->target = sdev_id(sdev); - device->lun = sdev->lun; - device->target_lun_valid = true; + if (device->target_lun_valid) { + device->ignore_device = true; + } else { + device->target = sdev_id(sdev); + device->lun = sdev->lun; + device->target_lun_valid = true; + } } } else { device = pqi_find_scsi_dev(ctrl_info, sdev_channel(sdev), @@ -6336,14 +6340,25 @@ static int pqi_map_queues(struct Scsi_Host *shost) ctrl_info->pci_dev, 0); } +static inline bool pqi_is_tape_changer_device(struct pqi_scsi_dev *device) +{ + return device->devtype == TYPE_TAPE || device->devtype == TYPE_MEDIUM_CHANGER; +} + static int pqi_slave_configure(struct scsi_device *sdev) { + int rc = 0; struct pqi_scsi_dev *device; device = sdev->hostdata; device->devtype = sdev->type; - return 0; + if (pqi_is_tape_changer_device(device) && device->ignore_device) { + rc = -ENXIO; + device->ignore_device = false; + } + + return rc; } static int pqi_getpciinfo_ioctl(struct pqi_ctrl_info *ctrl_info, void __user *arg) From 80982656b78ec23cb4918a90ee723ac2db83df1c Mon Sep 17 00:00:00 2001 From: Mike McGowen Date: Tue, 28 Sep 2021 18:54:41 -0500 Subject: [PATCH 098/279] scsi: smartpqi: Add 3252-8i PCI id Add PCI ID information for the Adaptec SmartRAID 3252-8i controller: 9005 / 028F / 9005 / 14A2 Link: https://lore.kernel.org/r/20210928235442.201875-11-don.brace@microchip.com Reviewed-by: Scott Benesh Reviewed-by: Scott Teel Acked-by: John Donnelly Signed-off-by: Mike McGowen Signed-off-by: Don Brace Signed-off-by: Martin K. Petersen --- drivers/scsi/smartpqi/smartpqi_init.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c index 8be116992cb0..ffa217874352 100644 --- a/drivers/scsi/smartpqi/smartpqi_init.c +++ b/drivers/scsi/smartpqi/smartpqi_init.c @@ -9287,6 +9287,10 @@ static const struct pci_device_id pqi_pci_id_table[] = { PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, PCI_VENDOR_ID_ADAPTEC2, 0x14a1) }, + { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, + PCI_VENDOR_ID_ADAPTEC2, 0x14a2) + }, { PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, PCI_VENDOR_ID_ADAPTEC2, 0x14b0) From 605ae389ea0243344713648294cd86b442d255ee Mon Sep 17 00:00:00 2001 From: Don Brace Date: Tue, 28 Sep 2021 18:54:42 -0500 Subject: [PATCH 099/279] scsi: smartpqi: Update version to 2.1.12-055 Update driver version to reflect changes. Link: https://lore.kernel.org/r/20210928235442.201875-12-don.brace@microchip.com Reviewed-by: Scott Benesh Reviewed-by: Scott Teel Reviewed-by: Mike McGowen Acked-by: John Donnelly Signed-off-by: Don Brace Signed-off-by: Martin K. Petersen --- drivers/scsi/smartpqi/smartpqi_init.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c index ffa217874352..b966ce3b4385 100644 --- a/drivers/scsi/smartpqi/smartpqi_init.c +++ b/drivers/scsi/smartpqi/smartpqi_init.c @@ -33,11 +33,11 @@ #define BUILD_TIMESTAMP #endif -#define DRIVER_VERSION "2.1.10-020" +#define DRIVER_VERSION "2.1.12-055" #define DRIVER_MAJOR 2 #define DRIVER_MINOR 1 -#define DRIVER_RELEASE 10 -#define DRIVER_REVISION 20 +#define DRIVER_RELEASE 12 +#define DRIVER_REVISION 55 #define DRIVER_NAME "Microchip SmartPQI Driver (v" \ DRIVER_VERSION BUILD_TIMESTAMP ")" From f4875d509a0a78ad294a1a538d534b5ba94e685a Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Wed, 6 Oct 2021 10:32:43 +0300 Subject: [PATCH 100/279] scsi: csiostor: Uninitialized data in csio_ln_vnp_read_cbfn() This variable is just a temporary variable, used to do an endian conversion. The problem is that the last byte is not initialized. After the conversion is completely done, the last byte is discarded so it doesn't cause a problem. But static checkers and the KMSan runtime checker can detect the uninitialized read and will complain about it. Link: https://lore.kernel.org/r/20211006073242.GA8404@kili Fixes: 5036f0a0ecd3 ("[SCSI] csiostor: Fix sparse warnings.") Signed-off-by: Dan Carpenter Signed-off-by: Martin K. Petersen --- drivers/scsi/csiostor/csio_lnode.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/csiostor/csio_lnode.c b/drivers/scsi/csiostor/csio_lnode.c index dc98f51f466f..d5ac93897023 100644 --- a/drivers/scsi/csiostor/csio_lnode.c +++ b/drivers/scsi/csiostor/csio_lnode.c @@ -619,7 +619,7 @@ csio_ln_vnp_read_cbfn(struct csio_hw *hw, struct csio_mb *mbp) struct fc_els_csp *csp; struct fc_els_cssp *clsp; enum fw_retval retval; - __be32 nport_id; + __be32 nport_id = 0; retval = FW_CMD_RETVAL_G(ntohl(rsp->alloc_to_len16)); if (retval != FW_SUCCESS) { From 9561f58442e48c3c71da250aa63bd02ec6bffcb5 Mon Sep 17 00:00:00 2001 From: Peter Wang Date: Wed, 6 Oct 2021 13:47:05 +0800 Subject: [PATCH 101/279] scsi: ufs: mediatek: Support vops pre suspend to disable auto-hibern8 Mediatek UFS needs auto-hibern8 disabled before suspend. Introduce a solution to do pre-suspend before SSU (sleep). Link: https://lore.kernel.org/r/20211006054705.21885-1-peter.wang@mediatek.com Reviewed-by: Bart Van Assche Reviewed-by: Bean Huo Signed-off-by: Peter Wang Signed-off-by: Martin K. Petersen --- drivers/scsi/ufs/ufs-exynos.c | 6 ++- drivers/scsi/ufs/ufs-hisi.c | 6 ++- drivers/scsi/ufs/ufs-mediatek.c | 68 ++++++++++++++++++++++++++++++++- drivers/scsi/ufs/ufs-mediatek.h | 20 ++++++++++ drivers/scsi/ufs/ufs-qcom.c | 6 ++- drivers/scsi/ufs/ufshcd.c | 9 ++++- drivers/scsi/ufs/ufshcd.h | 8 ++-- 7 files changed, 114 insertions(+), 9 deletions(-) diff --git a/drivers/scsi/ufs/ufs-exynos.c b/drivers/scsi/ufs/ufs-exynos.c index a14dd8ce56d4..b2ec9e20b14d 100644 --- a/drivers/scsi/ufs/ufs-exynos.c +++ b/drivers/scsi/ufs/ufs-exynos.c @@ -1176,10 +1176,14 @@ static void exynos_ufs_hibern8_notify(struct ufs_hba *hba, } } -static int exynos_ufs_suspend(struct ufs_hba *hba, enum ufs_pm_op pm_op) +static int exynos_ufs_suspend(struct ufs_hba *hba, enum ufs_pm_op pm_op, + enum ufs_notify_change_status status) { struct exynos_ufs *ufs = ufshcd_get_variant(hba); + if (status == PRE_CHANGE) + return 0; + if (!ufshcd_is_link_active(hba)) phy_power_off(ufs->phy); diff --git a/drivers/scsi/ufs/ufs-hisi.c b/drivers/scsi/ufs/ufs-hisi.c index 6b706de8354b..8c7e8d321746 100644 --- a/drivers/scsi/ufs/ufs-hisi.c +++ b/drivers/scsi/ufs/ufs-hisi.c @@ -396,10 +396,14 @@ out: return ret; } -static int ufs_hisi_suspend(struct ufs_hba *hba, enum ufs_pm_op pm_op) +static int ufs_hisi_suspend(struct ufs_hba *hba, enum ufs_pm_op pm_op, + enum ufs_notify_change_status status) { struct ufs_hisi_host *host = ufshcd_get_variant(hba); + if (status == PRE_CHANGE) + return 0; + if (pm_op == UFS_RUNTIME_PM) return 0; diff --git a/drivers/scsi/ufs/ufs-mediatek.c b/drivers/scsi/ufs/ufs-mediatek.c index d2d7e76c5ec8..d1696db70ce8 100644 --- a/drivers/scsi/ufs/ufs-mediatek.c +++ b/drivers/scsi/ufs/ufs-mediatek.c @@ -311,6 +311,46 @@ static void ufs_mtk_dbg_sel(struct ufs_hba *hba) } } +static void ufs_mtk_wait_idle_state(struct ufs_hba *hba, + unsigned long retry_ms) +{ + u64 timeout, time_checked; + u32 val, sm; + bool wait_idle; + + timeout = sched_clock() + retry_ms * 1000000UL; + + + /* wait a specific time after check base */ + udelay(10); + wait_idle = false; + + do { + time_checked = sched_clock(); + ufs_mtk_dbg_sel(hba); + val = ufshcd_readl(hba, REG_UFS_PROBE); + + sm = val & 0x1f; + + /* + * if state is in H8 enter and H8 enter confirm + * wait until return to idle state. + */ + if ((sm >= VS_HIB_ENTER) && (sm <= VS_HIB_EXIT)) { + wait_idle = true; + udelay(50); + continue; + } else if (!wait_idle) + break; + + if (wait_idle && (sm == VS_HCE_BASE)) + break; + } while (time_checked < timeout); + + if (wait_idle && sm != VS_HCE_BASE) + dev_info(hba->dev, "wait idle tmo: 0x%x\n", val); +} + static int ufs_mtk_wait_link_state(struct ufs_hba *hba, u32 state, unsigned long max_wait_ms) { @@ -949,11 +989,37 @@ static void ufs_mtk_vreg_set_lpm(struct ufs_hba *hba, bool lpm) REGULATOR_MODE_NORMAL); } -static int ufs_mtk_suspend(struct ufs_hba *hba, enum ufs_pm_op pm_op) +static void ufs_mtk_auto_hibern8_disable(struct ufs_hba *hba) +{ + unsigned long flags; + int ret; + + /* disable auto-hibern8 */ + spin_lock_irqsave(hba->host->host_lock, flags); + ufshcd_writel(hba, 0, REG_AUTO_HIBERNATE_IDLE_TIMER); + spin_unlock_irqrestore(hba->host->host_lock, flags); + + /* wait host return to idle state when auto-hibern8 off */ + ufs_mtk_wait_idle_state(hba, 5); + + ret = ufs_mtk_wait_link_state(hba, VS_LINK_UP, 100); + if (ret) + dev_warn(hba->dev, "exit h8 state fail, ret=%d\n", ret); +} + +static int ufs_mtk_suspend(struct ufs_hba *hba, enum ufs_pm_op pm_op, + enum ufs_notify_change_status status) { int err; struct arm_smccc_res res; + if (status == PRE_CHANGE) { + if (!ufshcd_is_auto_hibern8_supported(hba)) + return 0; + ufs_mtk_auto_hibern8_disable(hba); + return 0; + } + if (ufshcd_is_link_hibern8(hba)) { err = ufs_mtk_link_set_lpm(hba); if (err) diff --git a/drivers/scsi/ufs/ufs-mediatek.h b/drivers/scsi/ufs/ufs-mediatek.h index 524c8e2c1e6f..c96b9b529ee2 100644 --- a/drivers/scsi/ufs/ufs-mediatek.h +++ b/drivers/scsi/ufs/ufs-mediatek.h @@ -54,6 +54,26 @@ enum { VS_LINK_CFG = 5, }; +/* + * Vendor specific host controller state + */ +enum { + VS_HCE_RESET = 0, + VS_HCE_BASE = 1, + VS_HCE_OOCPR_WAIT = 2, + VS_HCE_DME_RESET = 3, + VS_HCE_MIDDLE = 4, + VS_HCE_DME_ENABLE = 5, + VS_HCE_DEFAULTS = 6, + VS_HIB_IDLEEN = 7, + VS_HIB_ENTER = 8, + VS_HIB_ENTER_CONF = 9, + VS_HIB_MIDDLE = 10, + VS_HIB_WAITTIMER = 11, + VS_HIB_EXIT_CONF = 12, + VS_HIB_EXIT = 13, +}; + /* * SiP commands */ diff --git a/drivers/scsi/ufs/ufs-qcom.c b/drivers/scsi/ufs/ufs-qcom.c index 92f5bb4965fa..0d2e950d0865 100644 --- a/drivers/scsi/ufs/ufs-qcom.c +++ b/drivers/scsi/ufs/ufs-qcom.c @@ -589,11 +589,15 @@ static void ufs_qcom_device_reset_ctrl(struct ufs_hba *hba, bool asserted) gpiod_set_value_cansleep(host->device_reset, asserted); } -static int ufs_qcom_suspend(struct ufs_hba *hba, enum ufs_pm_op pm_op) +static int ufs_qcom_suspend(struct ufs_hba *hba, enum ufs_pm_op pm_op, + enum ufs_notify_change_status status) { struct ufs_qcom_host *host = ufshcd_get_variant(hba); struct phy *phy = host->generic_phy; + if (status == PRE_CHANGE) + return 0; + if (ufs_qcom_is_link_off(hba)) { /* * Disable the tx/rx lane symbol clocks before PHY is diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index 9283ab4ca2da..3de380a97a9b 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -8844,6 +8844,10 @@ static int __ufshcd_wl_suspend(struct ufs_hba *hba, enum ufs_pm_op pm_op) flush_work(&hba->eeh_work); + ret = ufshcd_vops_suspend(hba, pm_op, PRE_CHANGE); + if (ret) + goto enable_scaling; + if (req_dev_pwr_mode != hba->curr_dev_pwr_mode) { if (pm_op != UFS_RUNTIME_PM) /* ensure that bkops is disabled */ @@ -8871,7 +8875,7 @@ vops_suspend: * vendor specific host controller register space call them before the * host clocks are ON. */ - ret = ufshcd_vops_suspend(hba, pm_op); + ret = ufshcd_vops_suspend(hba, pm_op, POST_CHANGE); if (ret) goto set_link_active; goto out; @@ -8999,7 +9003,8 @@ static int __ufshcd_wl_resume(struct ufs_hba *hba, enum ufs_pm_op pm_op) set_old_link_state: ufshcd_link_state_transition(hba, old_link_state, 0); vendor_suspend: - ufshcd_vops_suspend(hba, pm_op); + ufshcd_vops_suspend(hba, pm_op, PRE_CHANGE); + ufshcd_vops_suspend(hba, pm_op, POST_CHANGE); out: if (ret) ufshcd_update_evt_hist(hba, UFS_EVT_WL_RES_ERR, (u32)ret); diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h index a50dfdac79f6..64ce723327b9 100644 --- a/drivers/scsi/ufs/ufshcd.h +++ b/drivers/scsi/ufs/ufshcd.h @@ -344,7 +344,8 @@ struct ufs_hba_variant_ops { enum ufs_notify_change_status); int (*apply_dev_quirks)(struct ufs_hba *hba); void (*fixup_dev_quirks)(struct ufs_hba *hba); - int (*suspend)(struct ufs_hba *, enum ufs_pm_op); + int (*suspend)(struct ufs_hba *, enum ufs_pm_op, + enum ufs_notify_change_status); int (*resume)(struct ufs_hba *, enum ufs_pm_op); void (*dbg_register_dump)(struct ufs_hba *hba); int (*phy_initialization)(struct ufs_hba *); @@ -1318,10 +1319,11 @@ static inline void ufshcd_vops_fixup_dev_quirks(struct ufs_hba *hba) hba->vops->fixup_dev_quirks(hba); } -static inline int ufshcd_vops_suspend(struct ufs_hba *hba, enum ufs_pm_op op) +static inline int ufshcd_vops_suspend(struct ufs_hba *hba, enum ufs_pm_op op, + enum ufs_notify_change_status status) { if (hba->vops && hba->vops->suspend) - return hba->vops->suspend(hba, op); + return hba->vops->suspend(hba, op, status); return 0; } From d489f18ad1fc33ab9b60dc40fe3851bb0d87de28 Mon Sep 17 00:00:00 2001 From: Adrian Hunter Date: Fri, 8 Oct 2021 11:40:48 +0300 Subject: [PATCH 102/279] scsi: ufs: core: Fix synchronization between scsi_unjam_host() and ufshcd_queuecommand() The SCSI error handler calls scsi_unjam_host() which can call the queue function ufshcd_queuecommand() indirectly. The error handler changes the state to UFSHCD_STATE_RESET while running, but error interrupts that happen while the error handler is running could change the state to UFSHCD_STATE_EH_SCHEDULED_NON_FATAL which would allow requests to go through ufshcd_queuecommand() even though the error handler is running. Block that hole by checking whether the error handler is in progress. Link: https://lore.kernel.org/r/20211008084048.257498-1-adrian.hunter@intel.com Reviewed-by: Asutosh Das Signed-off-by: Adrian Hunter Signed-off-by: Martin K. Petersen --- drivers/scsi/ufs/ufshcd.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index 3de380a97a9b..f871f74fd59e 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -2686,7 +2686,19 @@ static int ufshcd_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd) switch (hba->ufshcd_state) { case UFSHCD_STATE_OPERATIONAL: + break; case UFSHCD_STATE_EH_SCHEDULED_NON_FATAL: + /* + * SCSI error handler can call ->queuecommand() while UFS error + * handler is in progress. Error interrupts could change the + * state from UFSHCD_STATE_RESET to + * UFSHCD_STATE_EH_SCHEDULED_NON_FATAL. Prevent requests + * being issued in that case. + */ + if (ufshcd_eh_in_progress(hba)) { + err = SCSI_MLQUEUE_HOST_BUSY; + goto out; + } break; case UFSHCD_STATE_EH_SCHEDULED_FATAL: /* From 36c6b7613ef1ffd88637315f11c71896f3ce4856 Mon Sep 17 00:00:00 2001 From: Xiang Chen Date: Tue, 12 Oct 2021 20:26:25 +0800 Subject: [PATCH 103/279] scsi: hisi_sas: Initialise devices in .slave_alloc callback Perform driver-specific SCSI device initialization in the designated SCSI midlayer callback instead of relying on the libsas "device found" callback. The SCSI midlayer .slave_alloc interface is called prior to sending any I/O to the device. Link: https://lore.kernel.org/r/1634041588-74824-2-git-send-email-john.garry@huawei.com Signed-off-by: Xiang Chen Signed-off-by: John Garry Signed-off-by: Martin K. Petersen --- drivers/scsi/hisi_sas/hisi_sas.h | 1 + drivers/scsi/hisi_sas/hisi_sas_main.c | 17 ++++++++++++++--- drivers/scsi/hisi_sas/hisi_sas_v1_hw.c | 2 +- drivers/scsi/hisi_sas/hisi_sas_v2_hw.c | 2 +- drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 2 +- 5 files changed, 18 insertions(+), 6 deletions(-) diff --git a/drivers/scsi/hisi_sas/hisi_sas.h b/drivers/scsi/hisi_sas/hisi_sas.h index 57be32ba0109..2213a91923a5 100644 --- a/drivers/scsi/hisi_sas/hisi_sas.h +++ b/drivers/scsi/hisi_sas/hisi_sas.h @@ -649,6 +649,7 @@ extern int hisi_sas_probe(struct platform_device *pdev, extern int hisi_sas_remove(struct platform_device *pdev); extern int hisi_sas_slave_configure(struct scsi_device *sdev); +extern int hisi_sas_slave_alloc(struct scsi_device *sdev); extern int hisi_sas_scan_finished(struct Scsi_Host *shost, unsigned long time); extern void hisi_sas_scan_start(struct Scsi_Host *shost); extern int hisi_sas_host_reset(struct Scsi_Host *shost, int reset_type); diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c index bb1c8ef3a76f..0835ba7c0ac2 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_main.c +++ b/drivers/scsi/hisi_sas/hisi_sas_main.c @@ -756,6 +756,20 @@ static int hisi_sas_init_device(struct domain_device *device) return rc; } +int hisi_sas_slave_alloc(struct scsi_device *sdev) +{ + struct domain_device *ddev; + int rc; + + rc = sas_slave_alloc(sdev); + if (rc) + return rc; + ddev = sdev_to_domain_dev(sdev); + + return hisi_sas_init_device(ddev); +} +EXPORT_SYMBOL_GPL(hisi_sas_slave_alloc); + static int hisi_sas_dev_found(struct domain_device *device) { struct hisi_hba *hisi_hba = dev_to_hisi_hba(device); @@ -802,9 +816,6 @@ static int hisi_sas_dev_found(struct domain_device *device) dev_info(dev, "dev[%d:%x] found\n", sas_dev->device_id, sas_dev->dev_type); - rc = hisi_sas_init_device(device); - if (rc) - goto err_out; sas_dev->dev_status = HISI_SAS_DEV_NORMAL; return 0; diff --git a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c index 862f4e8b7eb5..51e7d12f5053 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c +++ b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c @@ -1771,7 +1771,7 @@ static struct scsi_host_template sht_v1_hw = { .max_sectors = SCSI_DEFAULT_MAX_SECTORS, .eh_device_reset_handler = sas_eh_device_reset_handler, .eh_target_reset_handler = sas_eh_target_reset_handler, - .slave_alloc = sas_slave_alloc, + .slave_alloc = hisi_sas_slave_alloc, .target_destroy = sas_target_destroy, .ioctl = sas_ioctl, #ifdef CONFIG_COMPAT diff --git a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c index 236cf65c2f97..741a62e6bf77 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c +++ b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c @@ -3584,7 +3584,7 @@ static struct scsi_host_template sht_v2_hw = { .max_sectors = SCSI_DEFAULT_MAX_SECTORS, .eh_device_reset_handler = sas_eh_device_reset_handler, .eh_target_reset_handler = sas_eh_target_reset_handler, - .slave_alloc = sas_slave_alloc, + .slave_alloc = hisi_sas_slave_alloc, .target_destroy = sas_target_destroy, .ioctl = sas_ioctl, #ifdef CONFIG_COMPAT diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c index f4517f3eb922..114a59654525 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c @@ -3157,7 +3157,7 @@ static struct scsi_host_template sht_v3_hw = { .max_sectors = SCSI_DEFAULT_MAX_SECTORS, .eh_device_reset_handler = sas_eh_device_reset_handler, .eh_target_reset_handler = sas_eh_target_reset_handler, - .slave_alloc = sas_slave_alloc, + .slave_alloc = hisi_sas_slave_alloc, .target_destroy = sas_target_destroy, .ioctl = sas_ioctl, #ifdef CONFIG_COMPAT From 046ab7d0f5943dd74c351e1f3a771dea785fe25d Mon Sep 17 00:00:00 2001 From: Xiang Chen Date: Tue, 12 Oct 2021 20:26:26 +0800 Subject: [PATCH 104/279] scsi: hisi_sas: Wait for phyup in hisi_sas_control_phy() When issuing a hardreset/linkreset/phy_set_linkrate from sysfs, the phy will be disabled and re-enabled for the directly attached scenario. It takes some time for the phy to come back up after re-enabling the phy. If the controller becomes suspended while waiting for the phy to come back, the phy up may be lost (along with the disk). To solve this problem, wait for the phy up to occur with a timeout. Indeed this is already done in hisi_sas_debug_I_T_nexus_reset() for local phys, so just relocate the functionality to hisi_sas_control_phy(). Since the HA workqueue is drained when suspending the controller, and the phy control function is called from the same workqueue, we can guarantee that the controller will not be suspended during this period. Link: https://lore.kernel.org/r/1634041588-74824-3-git-send-email-john.garry@huawei.com Signed-off-by: Xiang Chen Signed-off-by: John Garry Signed-off-by: Martin K. Petersen --- drivers/scsi/hisi_sas/hisi_sas_main.c | 43 +++++++++++++++++++------- drivers/scsi/hisi_sas/hisi_sas_v1_hw.c | 11 ++----- drivers/scsi/hisi_sas/hisi_sas_v2_hw.c | 17 ++-------- drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 9 ++---- 4 files changed, 39 insertions(+), 41 deletions(-) diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c index 0835ba7c0ac2..5b091388c095 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_main.c +++ b/drivers/scsi/hisi_sas/hisi_sas_main.c @@ -1146,9 +1146,17 @@ static int hisi_sas_phy_set_linkrate(struct hisi_hba *hisi_hba, int phy_no, static int hisi_sas_control_phy(struct asd_sas_phy *sas_phy, enum phy_func func, void *funcdata) { + struct hisi_sas_phy *phy = container_of(sas_phy, + struct hisi_sas_phy, sas_phy); struct sas_ha_struct *sas_ha = sas_phy->ha; struct hisi_hba *hisi_hba = sas_ha->lldd_ha; + struct device *dev = hisi_hba->dev; + DECLARE_COMPLETION_ONSTACK(completion); int phy_no = sas_phy->id; + u8 sts = phy->phy_attached; + int ret = 0; + + phy->reset_completion = &completion; switch (func) { case PHY_FUNC_HARD_RESET: @@ -1163,21 +1171,35 @@ static int hisi_sas_control_phy(struct asd_sas_phy *sas_phy, enum phy_func func, case PHY_FUNC_DISABLE: hisi_sas_phy_enable(hisi_hba, phy_no, 0); - break; + goto out; case PHY_FUNC_SET_LINK_RATE: - return hisi_sas_phy_set_linkrate(hisi_hba, phy_no, funcdata); + ret = hisi_sas_phy_set_linkrate(hisi_hba, phy_no, funcdata); + break; + case PHY_FUNC_GET_EVENTS: if (hisi_hba->hw->get_events) { hisi_hba->hw->get_events(hisi_hba, phy_no); - break; + goto out; } fallthrough; case PHY_FUNC_RELEASE_SPINUP_HOLD: default: - return -EOPNOTSUPP; + ret = -EOPNOTSUPP; + goto out; } - return 0; + + if (sts && !wait_for_completion_timeout(&completion, 2 * HZ)) { + dev_warn(dev, "phy%d wait phyup timed out for func %d\n", + phy_no, func); + if (phy->in_reset) + ret = -ETIMEDOUT; + } + +out: + phy->reset_completion = NULL; + + return ret; } static void hisi_sas_task_done(struct sas_task *task) @@ -1783,7 +1805,6 @@ static int hisi_sas_debug_I_T_nexus_reset(struct domain_device *device) struct hisi_sas_device *sas_dev = device->lldd_dev; struct hisi_hba *hisi_hba = dev_to_hisi_hba(device); struct sas_ha_struct *sas_ha = &hisi_hba->sha; - DECLARE_COMPLETION_ONSTACK(phyreset); int rc, reset_type; if (!local_phy->enabled) { @@ -1796,8 +1817,11 @@ static int hisi_sas_debug_I_T_nexus_reset(struct domain_device *device) sas_ha->sas_phy[local_phy->number]; struct hisi_sas_phy *phy = container_of(sas_phy, struct hisi_sas_phy, sas_phy); + unsigned long flags; + + spin_lock_irqsave(&phy->lock, flags); phy->in_reset = 1; - phy->reset_completion = &phyreset; + spin_unlock_irqrestore(&phy->lock, flags); } reset_type = (sas_dev->dev_status == HISI_SAS_DEV_INIT || @@ -1811,17 +1835,14 @@ static int hisi_sas_debug_I_T_nexus_reset(struct domain_device *device) sas_ha->sas_phy[local_phy->number]; struct hisi_sas_phy *phy = container_of(sas_phy, struct hisi_sas_phy, sas_phy); - int ret = wait_for_completion_timeout(&phyreset, - I_T_NEXUS_RESET_PHYUP_TIMEOUT); unsigned long flags; spin_lock_irqsave(&phy->lock, flags); - phy->reset_completion = NULL; phy->in_reset = 0; spin_unlock_irqrestore(&phy->lock, flags); /* report PHY down if timed out */ - if (!ret) + if (rc == -ETIMEDOUT) hisi_sas_phy_down(hisi_hba, sas_phy->id, 0, GFP_KERNEL); } else if (sas_dev->dev_status != HISI_SAS_DEV_INIT) { /* diff --git a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c index 51e7d12f5053..b4951ff9ca51 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c +++ b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c @@ -1327,7 +1327,6 @@ static irqreturn_t int_phyup_v1_hw(int irq_no, void *p) u32 *frame_rcvd = (u32 *)sas_phy->frame_rcvd; struct sas_identify_frame *id = (struct sas_identify_frame *)frame_rcvd; irqreturn_t res = IRQ_HANDLED; - unsigned long flags; irq_value = hisi_sas_phy_read32(hisi_hba, phy_no, CHL_INT2); if (!(irq_value & CHL_INT2_SL_PHY_ENA_MSK)) { @@ -1380,15 +1379,9 @@ static irqreturn_t int_phyup_v1_hw(int irq_no, void *p) phy->identify.target_port_protocols = SAS_PROTOCOL_SMP; hisi_sas_notify_phy_event(phy, HISI_PHYE_PHY_UP); - - spin_lock_irqsave(&phy->lock, flags); - if (phy->reset_completion) { - phy->in_reset = 0; - complete(phy->reset_completion); - } - spin_unlock_irqrestore(&phy->lock, flags); - end: + if (phy->reset_completion) + complete(phy->reset_completion); hisi_sas_phy_write32(hisi_hba, phy_no, CHL_INT2, CHL_INT2_SL_PHY_ENA_MSK); diff --git a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c index 741a62e6bf77..45eb0b98d00b 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c +++ b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c @@ -2641,7 +2641,6 @@ static int phy_up_v2_hw(int phy_no, struct hisi_hba *hisi_hba) struct device *dev = hisi_hba->dev; u32 *frame_rcvd = (u32 *)sas_phy->frame_rcvd; struct sas_identify_frame *id = (struct sas_identify_frame *)frame_rcvd; - unsigned long flags; hisi_sas_phy_write32(hisi_hba, phy_no, PHYCTRL_PHY_ENA_MSK, 1); @@ -2696,14 +2695,9 @@ static int phy_up_v2_hw(int phy_no, struct hisi_hba *hisi_hba) set_link_timer_quirk(hisi_hba); } hisi_sas_notify_phy_event(phy, HISI_PHYE_PHY_UP); - spin_lock_irqsave(&phy->lock, flags); - if (phy->reset_completion) { - phy->in_reset = 0; - complete(phy->reset_completion); - } - spin_unlock_irqrestore(&phy->lock, flags); - end: + if (phy->reset_completion) + complete(phy->reset_completion); hisi_sas_phy_write32(hisi_hba, phy_no, CHL_INT0, CHL_INT0_SL_PHY_ENABLE_MSK); hisi_sas_phy_write32(hisi_hba, phy_no, PHYCTRL_PHY_ENA_MSK, 0); @@ -3204,7 +3198,6 @@ static irqreturn_t sata_int_v2_hw(int irq_no, void *p) u32 ent_tmp, ent_msk, ent_int, port_id, link_rate, hard_phy_linkrate; irqreturn_t res = IRQ_HANDLED; u8 attached_sas_addr[SAS_ADDR_SIZE] = {0}; - unsigned long flags; int phy_no, offset; del_timer(&phy->timer); @@ -3280,12 +3273,8 @@ static irqreturn_t sata_int_v2_hw(int irq_no, void *p) phy->identify.target_port_protocols = SAS_PROTOCOL_SATA; hisi_sas_notify_phy_event(phy, HISI_PHYE_PHY_UP); - spin_lock_irqsave(&phy->lock, flags); - if (phy->reset_completion) { - phy->in_reset = 0; + if (phy->reset_completion) complete(phy->reset_completion); - } - spin_unlock_irqrestore(&phy->lock, flags); end: hisi_sas_write32(hisi_hba, ENT_INT_SRC1 + offset, ent_tmp); hisi_sas_write32(hisi_hba, ENT_INT_SRC_MSK1 + offset, ent_msk); diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c index 114a59654525..2082b066aca7 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c @@ -1482,7 +1482,6 @@ static irqreturn_t phy_up_v3_hw(int phy_no, struct hisi_hba *hisi_hba) struct hisi_sas_phy *phy = &hisi_hba->phy[phy_no]; struct asd_sas_phy *sas_phy = &phy->sas_phy; struct device *dev = hisi_hba->dev; - unsigned long flags; del_timer(&phy->timer); hisi_sas_phy_write32(hisi_hba, phy_no, PHYCTRL_PHY_ENA_MSK, 1); @@ -1564,13 +1563,9 @@ static irqreturn_t phy_up_v3_hw(int phy_no, struct hisi_hba *hisi_hba) phy->phy_attached = 1; hisi_sas_notify_phy_event(phy, HISI_PHYE_PHY_UP); res = IRQ_HANDLED; - spin_lock_irqsave(&phy->lock, flags); - if (phy->reset_completion) { - phy->in_reset = 0; - complete(phy->reset_completion); - } - spin_unlock_irqrestore(&phy->lock, flags); end: + if (phy->reset_completion) + complete(phy->reset_completion); hisi_sas_phy_write32(hisi_hba, phy_no, CHL_INT0, CHL_INT0_SL_PHY_ENABLE_MSK); hisi_sas_phy_write32(hisi_hba, phy_no, PHYCTRL_PHY_ENA_MSK, 0); From 00aeaf329a3a1ea3d3606fefa1d29f69f828bd21 Mon Sep 17 00:00:00 2001 From: Luo Jiaxing Date: Tue, 12 Oct 2021 20:26:27 +0800 Subject: [PATCH 105/279] scsi: libsas: Export sas_phy_enable() Export sas_phy_enable() so LLDDs can directly use it to control remote phys. We already do this for companion function sas_phy_reset(). Link: https://lore.kernel.org/r/1634041588-74824-4-git-send-email-john.garry@huawei.com Signed-off-by: Luo Jiaxing Signed-off-by: John Garry Signed-off-by: Martin K. Petersen --- drivers/scsi/libsas/sas_init.c | 3 ++- include/scsi/libsas.h | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/libsas/sas_init.c b/drivers/scsi/libsas/sas_init.c index 37cc92837fdf..b640e09af6a4 100644 --- a/drivers/scsi/libsas/sas_init.c +++ b/drivers/scsi/libsas/sas_init.c @@ -254,7 +254,7 @@ static int transport_sas_phy_reset(struct sas_phy *phy, int hard_reset) } } -static int sas_phy_enable(struct sas_phy *phy, int enable) +int sas_phy_enable(struct sas_phy *phy, int enable) { int ret; enum phy_func cmd; @@ -286,6 +286,7 @@ static int sas_phy_enable(struct sas_phy *phy, int enable) } return ret; } +EXPORT_SYMBOL_GPL(sas_phy_enable); int sas_phy_reset(struct sas_phy *phy, int hard_reset) { diff --git a/include/scsi/libsas.h b/include/scsi/libsas.h index 6fe125a71b60..79e4903bd414 100644 --- a/include/scsi/libsas.h +++ b/include/scsi/libsas.h @@ -664,6 +664,7 @@ extern void sas_suspend_ha(struct sas_ha_struct *sas_ha); int sas_set_phy_speed(struct sas_phy *phy, struct sas_phy_linkrates *rates); int sas_phy_reset(struct sas_phy *phy, int hard_reset); +int sas_phy_enable(struct sas_phy *phy, int enable); extern int sas_queuecommand(struct Scsi_Host *, struct scsi_cmnd *); extern int sas_target_alloc(struct scsi_target *); extern int sas_slave_configure(struct scsi_device *); From 21c7e972475e6a975fbe97f8974c96fe4713077c Mon Sep 17 00:00:00 2001 From: Luo Jiaxing Date: Tue, 12 Oct 2021 20:26:28 +0800 Subject: [PATCH 106/279] scsi: hisi_sas: Disable SATA disk phy for severe I_T nexus reset failure If the softreset fails in the I_T reset, libsas will then continue to issue a controller reset to try to recover. However a faulty disk may cause the softreset to fail, and resetting the controller will not help this scenario. Indeed, we will just continue the cycle of error handle handling to try to recover. So if the softreset fails upon certain conditions, just disable the phy associated with the disk. The user needs to handle this problem. Link: https://lore.kernel.org/r/1634041588-74824-5-git-send-email-john.garry@huawei.com Signed-off-by: Luo Jiaxing Signed-off-by: John Garry Signed-off-by: Martin K. Petersen --- drivers/scsi/hisi_sas/hisi_sas_main.c | 31 +++++++++++++++++++++------ 1 file changed, 25 insertions(+), 6 deletions(-) diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c index 5b091388c095..f206c433de32 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_main.c +++ b/drivers/scsi/hisi_sas/hisi_sas_main.c @@ -1870,13 +1870,32 @@ static int hisi_sas_I_T_nexus_reset(struct domain_device *device) } hisi_sas_dereg_device(hisi_hba, device); - if (dev_is_sata(device)) { - rc = hisi_sas_softreset_ata_disk(device); - if (rc == TMF_RESP_FUNC_FAILED) - return TMF_RESP_FUNC_FAILED; - } - rc = hisi_sas_debug_I_T_nexus_reset(device); + if (rc == TMF_RESP_FUNC_COMPLETE && dev_is_sata(device)) { + struct sas_phy *local_phy; + + rc = hisi_sas_softreset_ata_disk(device); + switch (rc) { + case -ECOMM: + rc = -ENODEV; + break; + case TMF_RESP_FUNC_FAILED: + case -EMSGSIZE: + case -EIO: + local_phy = sas_get_local_phy(device); + rc = sas_phy_enable(local_phy, 0); + if (!rc) { + local_phy->enabled = 0; + dev_err(dev, "Disabled local phy of ATA disk %016llx due to softreset fail (%d)\n", + SAS_ADDR(device->sas_addr), rc); + rc = -ENODEV; + } + sas_put_local_phy(local_phy); + break; + default: + break; + } + } if ((rc == TMF_RESP_FUNC_COMPLETE) || (rc == -ENODEV)) hisi_sas_release_task(hisi_hba, device); From a4bcbf71914b0cc44151a5238e4a8afa8e3319cd Mon Sep 17 00:00:00 2001 From: Sohaib Mohamed Date: Wed, 6 Oct 2021 17:48:03 +0200 Subject: [PATCH 107/279] scsi: Documentation: Fix typo in sysfs-driver-ufs Remove repeated word: "the The amount" Link: https://lore.kernel.org/r/20211006154804.135184-1-sohaib.amhmd@gmail.com Signed-off-by: Sohaib Mohamed Signed-off-by: Martin K. Petersen --- Documentation/ABI/testing/sysfs-driver-ufs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/ABI/testing/sysfs-driver-ufs b/Documentation/ABI/testing/sysfs-driver-ufs index ec3a7149ced5..62fe51cbbaa7 100644 --- a/Documentation/ABI/testing/sysfs-driver-ufs +++ b/Documentation/ABI/testing/sysfs-driver-ufs @@ -903,7 +903,7 @@ Description: This file shows the amount of data that the host plans to What: /sys/class/scsi_device/*/device/dyn_cap_needed Date: February 2018 Contact: Stanislav Nijnikov -Description: This file shows the The amount of physical memory needed +Description: This file shows the amount of physical memory needed to be removed from the physical memory resources pool of the particular logical unit. The full information about the attribute could be found at UFS specifications 2.1. From a19a93e4c6a98c9c0f2f5a6db76846f10d7d1f85 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Wed, 6 Oct 2021 14:54:51 -0700 Subject: [PATCH 108/279] scsi: core: pm: Rely on the device driver core for async power management Instead of implementing asynchronous resume support in the SCSI core, rely on the device driver core for resuming SCSI devices asynchronously. Instead of only supporting asynchronous resumes, also support asynchronous suspends. Link: https://lore.kernel.org/r/20211006215453.3318929-2-bvanassche@acm.org Cc: Alan Stern Cc: Dan Williams Cc: Hannes Reinecke Cc: Adrian Hunter Cc: Martin Kepplinger Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/hosts.c | 1 + drivers/scsi/scsi.c | 8 ------- drivers/scsi/scsi_pm.c | 44 ++------------------------------------- drivers/scsi/scsi_priv.h | 4 +--- drivers/scsi/scsi_scan.c | 17 +++++++++++++++ drivers/scsi/scsi_sysfs.c | 1 + drivers/scsi/sd.c | 1 - 7 files changed, 22 insertions(+), 54 deletions(-) diff --git a/drivers/scsi/hosts.c b/drivers/scsi/hosts.c index 3f6f14f0cafb..b8362700a9de 100644 --- a/drivers/scsi/hosts.c +++ b/drivers/scsi/hosts.c @@ -475,6 +475,7 @@ struct Scsi_Host *scsi_host_alloc(struct scsi_host_template *sht, int privsize) dev_set_name(&shost->shost_gendev, "host%d", shost->host_no); shost->shost_gendev.bus = &scsi_bus_type; shost->shost_gendev.type = &scsi_host_type; + scsi_enable_async_suspend(&shost->shost_gendev); device_initialize(&shost->shost_dev); shost->shost_dev.parent = &shost->shost_gendev; diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c index b241f9e3885c..ed9753f54b8a 100644 --- a/drivers/scsi/scsi.c +++ b/drivers/scsi/scsi.c @@ -86,14 +86,6 @@ unsigned int scsi_logging_level; EXPORT_SYMBOL(scsi_logging_level); #endif -/* - * Domain for asynchronous system resume operations. It is marked 'exclusive' - * to avoid being included in the async_synchronize_full() that is invoked by - * dpm_resume(). - */ -ASYNC_DOMAIN_EXCLUSIVE(scsi_sd_pm_domain); -EXPORT_SYMBOL(scsi_sd_pm_domain); - #ifdef CONFIG_SCSI_LOGGING void scsi_log_send(struct scsi_cmnd *cmd) { diff --git a/drivers/scsi/scsi_pm.c b/drivers/scsi/scsi_pm.c index 3717eea37ecb..50b6bad4df79 100644 --- a/drivers/scsi/scsi_pm.c +++ b/drivers/scsi/scsi_pm.c @@ -56,9 +56,6 @@ static int scsi_dev_type_suspend(struct device *dev, const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; int err; - /* flush pending in-flight resume operations, suspend is synchronous */ - async_synchronize_full_domain(&scsi_sd_pm_domain); - err = scsi_device_quiesce(to_scsi_device(dev)); if (err == 0) { err = cb(dev, pm); @@ -123,48 +120,11 @@ scsi_bus_suspend_common(struct device *dev, return err; } -static void async_sdev_resume(void *dev, async_cookie_t cookie) -{ - scsi_dev_type_resume(dev, do_scsi_resume); -} - -static void async_sdev_thaw(void *dev, async_cookie_t cookie) -{ - scsi_dev_type_resume(dev, do_scsi_thaw); -} - -static void async_sdev_restore(void *dev, async_cookie_t cookie) -{ - scsi_dev_type_resume(dev, do_scsi_restore); -} - static int scsi_bus_resume_common(struct device *dev, int (*cb)(struct device *, const struct dev_pm_ops *)) { - async_func_t fn; - - if (!scsi_is_sdev_device(dev)) - fn = NULL; - else if (cb == do_scsi_resume) - fn = async_sdev_resume; - else if (cb == do_scsi_thaw) - fn = async_sdev_thaw; - else if (cb == do_scsi_restore) - fn = async_sdev_restore; - else - fn = NULL; - - if (fn) { - async_schedule_domain(fn, dev, &scsi_sd_pm_domain); - - /* - * If a user has disabled async probing a likely reason - * is due to a storage enclosure that does not inject - * staggered spin-ups. For safety, make resume - * synchronous as well in that case. - */ - if (strncmp(scsi_scan_type, "async", 5) != 0) - async_synchronize_full_domain(&scsi_sd_pm_domain); + if (scsi_is_sdev_device(dev)) { + scsi_dev_type_resume(dev, cb); } else { pm_runtime_disable(dev); pm_runtime_set_active(dev); diff --git a/drivers/scsi/scsi_priv.h b/drivers/scsi/scsi_priv.h index 6d9152031a40..2d9de5a165ae 100644 --- a/drivers/scsi/scsi_priv.h +++ b/drivers/scsi/scsi_priv.h @@ -116,7 +116,7 @@ extern void scsi_exit_procfs(void); #endif /* CONFIG_PROC_FS */ /* scsi_scan.c */ -extern char scsi_scan_type[]; +void scsi_enable_async_suspend(struct device *dev); extern int scsi_complete_async_scans(void); extern int scsi_scan_host_selected(struct Scsi_Host *, unsigned int, unsigned int, u64, enum scsi_scan_mode); @@ -170,8 +170,6 @@ static inline int scsi_autopm_get_host(struct Scsi_Host *h) { return 0; } static inline void scsi_autopm_put_host(struct Scsi_Host *h) {} #endif /* CONFIG_PM */ -extern struct async_domain scsi_sd_pm_domain; - /* scsi_dh.c */ #ifdef CONFIG_SCSI_DH void scsi_dh_add_device(struct scsi_device *sdev); diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c index 0d0381df25f7..c86152f9c47a 100644 --- a/drivers/scsi/scsi_scan.c +++ b/drivers/scsi/scsi_scan.c @@ -122,6 +122,22 @@ struct async_scan_data { struct completion prev_finished; }; +/** + * scsi_enable_async_suspend - Enable async suspend and resume + */ +void scsi_enable_async_suspend(struct device *dev) +{ + /* + * If a user has disabled async probing a likely reason is due to a + * storage enclosure that does not inject staggered spin-ups. For + * safety, make resume synchronous as well in that case. + */ + if (strncmp(scsi_scan_type, "async", 5) != 0) + return; + /* Enable asynchronous suspend and resume. */ + device_enable_async_suspend(dev); +} + /** * scsi_complete_async_scans - Wait for asynchronous scans to complete * @@ -454,6 +470,7 @@ static struct scsi_target *scsi_alloc_target(struct device *parent, dev_set_name(dev, "target%d:%d:%d", shost->host_no, channel, id); dev->bus = &scsi_bus_type; dev->type = &scsi_target_type; + scsi_enable_async_suspend(dev); starget->id = id; starget->channel = channel; starget->can_queue = 0; diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c index 86793259e541..b598dfcbb67d 100644 --- a/drivers/scsi/scsi_sysfs.c +++ b/drivers/scsi/scsi_sysfs.c @@ -1616,6 +1616,7 @@ void scsi_sysfs_device_initialize(struct scsi_device *sdev) device_initialize(&sdev->sdev_gendev); sdev->sdev_gendev.bus = &scsi_bus_type; sdev->sdev_gendev.type = &scsi_dev_type; + scsi_enable_async_suspend(&sdev->sdev_gendev); dev_set_name(&sdev->sdev_gendev, "%d:%d:%d:%llu", sdev->host->host_no, sdev->channel, sdev->id, sdev->lun); diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index 5df665edf82a..842b78bd0254 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -3504,7 +3504,6 @@ static int sd_remove(struct device *dev) sdkp = dev_get_drvdata(dev); scsi_autopm_get_device(sdkp->device); - async_synchronize_full_domain(&scsi_sd_pm_domain); device_del(&sdkp->dev); del_gendisk(sdkp->disk); sd_shutdown(dev); From 1c9575326a4a09bdb82c104ed1ab4e932c7a1f49 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Wed, 6 Oct 2021 14:54:52 -0700 Subject: [PATCH 109/279] scsi: sd: Rename sd_resume() into sd_resume_system() This patch does not change any functionality but makes the next patch in this series easier to read. Link: https://lore.kernel.org/r/20211006215453.3318929-3-bvanassche@acm.org Cc: Alan Stern Cc: Dan Williams Cc: Hannes Reinecke Cc: Adrian Hunter Cc: Martin Kepplinger Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/sd.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index 842b78bd0254..fcf84e54c279 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -109,7 +109,7 @@ static int sd_remove(struct device *); static void sd_shutdown(struct device *); static int sd_suspend_system(struct device *); static int sd_suspend_runtime(struct device *); -static int sd_resume(struct device *); +static int sd_resume_system(struct device *); static int sd_resume_runtime(struct device *); static void sd_rescan(struct device *); static blk_status_t sd_init_command(struct scsi_cmnd *SCpnt); @@ -602,9 +602,9 @@ static struct class sd_disk_class = { static const struct dev_pm_ops sd_pm_ops = { .suspend = sd_suspend_system, - .resume = sd_resume, + .resume = sd_resume_system, .poweroff = sd_suspend_system, - .restore = sd_resume, + .restore = sd_resume_system, .runtime_suspend = sd_suspend_runtime, .runtime_resume = sd_resume_runtime, }; @@ -3686,6 +3686,11 @@ static int sd_resume(struct device *dev) return ret; } +static int sd_resume_system(struct device *dev) +{ + return sd_resume(dev); +} + static int sd_resume_runtime(struct device *dev) { struct scsi_disk *sdkp = dev_get_drvdata(dev); From 9131bff6a9f1d4c6ab2d4673974a9659d8d24dc7 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Wed, 6 Oct 2021 14:54:53 -0700 Subject: [PATCH 110/279] scsi: core: pm: Only runtime resume if necessary The following query shows which drivers define callbacks that are called by the power management support code in the SCSI core (scsi_pm.c): $ git grep -nHEwA16 "$(echo $(git grep -h 'scsi_register_driver(&' | sed 's/.*&//;s/\..*//') | sed 's/ /|/g')" | grep '\.pm[[:blank:]]*=[[:blank:]]' drivers/scsi/sd.c-620- .pm = &sd_pm_ops, drivers/scsi/sr.c-100- .pm = &sr_pm_ops, drivers/scsi/ufs/ufshcd.c-9765- .pm = &ufshcd_wl_pm_ops, Since unconditionally runtime resuming a device during system resume is not necessary, remove that code. Modify the SCSI disk (sd) driver such that it follows the same approach as the UFS driver, namely to skip system suspend and resume for devices that are runtime suspended. The CD-ROM code does not need to be updated since its PM callbacks do not affect the device power state. This patch has been tested as follows: [ shell 1 ] cd /sys/kernel/debug/tracing grep -E 'blk_(pre|post)_runtime|runtime_(suspend|resume)|autosuspend_delay|pm_runtime_(get|put)' available_filter_functions | while read a b; do echo "$a"; done | grep -v __pm_runtime_resume >set_ftrace_filter echo function > current_tracer echo 1 > tracing_on cat trace_pipe [ shell 2 ] cd /sys/block/sr0 # Increase the event poll interval to make it easier to derive from the # tracing output whether runtime power actions are the result of sg_inq. echo 30000 > events_poll_msecs cd device/power # Enable runtime power management. echo auto > control echo 1000 > autosuspend_delay_ms sleep 1 # Verify in shell 1 that sr0 has been runtime suspended sg_inq /dev/sr0 eject /dev/sr0 sg_inq /dev/sr0 # Disable runtime power management. echo on > control cd /sys/block/sda/device/power echo auto > control echo 1000 > autosuspend_delay_ms sleep 1 # Verify in shell 1 that sr0 has been runtime suspended sg_inq /dev/sda Link: https://lore.kernel.org/r/20211006215453.3318929-4-bvanassche@acm.org Cc: Alan Stern Cc: Dan Williams Cc: Hannes Reinecke Cc: Adrian Hunter Cc: Martin Kepplinger Tested-by: Martin Kepplinger Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/scsi_pm.c | 69 +++++++++--------------------------------- drivers/scsi/sd.c | 6 ++++ 2 files changed, 20 insertions(+), 55 deletions(-) diff --git a/drivers/scsi/scsi_pm.c b/drivers/scsi/scsi_pm.c index 50b6bad4df79..b5a858c29488 100644 --- a/drivers/scsi/scsi_pm.c +++ b/drivers/scsi/scsi_pm.c @@ -66,71 +66,30 @@ static int scsi_dev_type_suspend(struct device *dev, return err; } -static int scsi_dev_type_resume(struct device *dev, - int (*cb)(struct device *, const struct dev_pm_ops *)) -{ - const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; - int err = 0; - - err = cb(dev, pm); - scsi_device_resume(to_scsi_device(dev)); - dev_dbg(dev, "scsi resume: %d\n", err); - - if (err == 0) { - pm_runtime_disable(dev); - err = pm_runtime_set_active(dev); - pm_runtime_enable(dev); - - /* - * Forcibly set runtime PM status of request queue to "active" - * to make sure we can again get requests from the queue - * (see also blk_pm_peek_request()). - * - * The resume hook will correct runtime PM status of the disk. - */ - if (!err && scsi_is_sdev_device(dev)) { - struct scsi_device *sdev = to_scsi_device(dev); - - blk_set_runtime_active(sdev->request_queue); - } - } - - return err; -} - static int scsi_bus_suspend_common(struct device *dev, int (*cb)(struct device *, const struct dev_pm_ops *)) { - int err = 0; + if (!scsi_is_sdev_device(dev)) + return 0; - if (scsi_is_sdev_device(dev)) { - /* - * All the high-level SCSI drivers that implement runtime - * PM treat runtime suspend, system suspend, and system - * hibernate nearly identically. In all cases the requirements - * for runtime suspension are stricter. - */ - if (pm_runtime_suspended(dev)) - return 0; - - err = scsi_dev_type_suspend(dev, cb); - } - - return err; + return scsi_dev_type_suspend(dev, cb); } static int scsi_bus_resume_common(struct device *dev, int (*cb)(struct device *, const struct dev_pm_ops *)) { - if (scsi_is_sdev_device(dev)) { - scsi_dev_type_resume(dev, cb); - } else { - pm_runtime_disable(dev); - pm_runtime_set_active(dev); - pm_runtime_enable(dev); - } - return 0; + const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; + int err; + + if (!scsi_is_sdev_device(dev)) + return 0; + + err = cb(dev, pm); + scsi_device_resume(to_scsi_device(dev)); + dev_dbg(dev, "scsi resume: %d\n", err); + + return err; } static int scsi_bus_prepare(struct device *dev) diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index fcf84e54c279..4a78ab7185eb 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -3660,6 +3660,9 @@ static int sd_suspend_common(struct device *dev, bool ignore_stop_errors) static int sd_suspend_system(struct device *dev) { + if (pm_runtime_suspended(dev)) + return 0; + return sd_suspend_common(dev, true); } @@ -3688,6 +3691,9 @@ static int sd_resume(struct device *dev) static int sd_resume_system(struct device *dev) { + if (pm_runtime_suspended(dev)) + return 0; + return sd_resume(dev); } From bf23e619039d360d503b7282d030daf2277a5d47 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 7 Oct 2021 13:27:56 -0700 Subject: [PATCH 111/279] scsi: core: Use a structure member to track the SCSI command submitter Conditional statements are faster than indirect calls. Use a structure member to track the SCSI command submitter such that later patches can call scsi_done(scmd) instead of scmd->scsi_done(scmd). The asymmetric behavior that scsi_send_eh_cmnd() sets the submission context to the SCSI error handler and that it does not restore the submission context to the SCSI core is retained. Link: https://lore.kernel.org/r/20211007202923.2174984-2-bvanassche@acm.org Cc: Hannes Reinecke Cc: Ming Lei Cc: Christoph Hellwig Reviewed-by: Benjamin Block Reviewed-by: Bean Huo Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/scsi_error.c | 17 ++++++----------- drivers/scsi/scsi_lib.c | 10 ++++++++++ drivers/scsi/scsi_priv.h | 1 + include/scsi/scsi_cmnd.h | 7 +++++++ 4 files changed, 24 insertions(+), 11 deletions(-) diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c index b6c86cce57bf..3de03925550e 100644 --- a/drivers/scsi/scsi_error.c +++ b/drivers/scsi/scsi_error.c @@ -50,8 +50,6 @@ #include -static void scsi_eh_done(struct scsi_cmnd *scmd); - /* * These should *probably* be handled by the host itself. * Since it is allowed to sleep, it probably should. @@ -520,7 +518,8 @@ enum scsi_disposition scsi_check_sense(struct scsi_cmnd *scmd) /* handler does not care. Drop down to default handling */ } - if (scmd->cmnd[0] == TEST_UNIT_READY && scmd->scsi_done != scsi_eh_done) + if (scmd->cmnd[0] == TEST_UNIT_READY && + scmd->submitter != SUBMITTED_BY_SCSI_ERROR_HANDLER) /* * nasty: for mid-layer issued TURs, we need to return the * actual sense data without any recovery attempt. For eh @@ -782,7 +781,7 @@ static enum scsi_disposition scsi_eh_completed_normally(struct scsi_cmnd *scmd) * scsi_eh_done - Completion function for error handling. * @scmd: Cmd that is done. */ -static void scsi_eh_done(struct scsi_cmnd *scmd) +void scsi_eh_done(struct scsi_cmnd *scmd) { struct completion *eh_action; @@ -1082,7 +1081,7 @@ retry: shost->eh_action = &done; scsi_log_send(scmd); - scmd->scsi_done = scsi_eh_done; + scmd->submitter = SUBMITTED_BY_SCSI_ERROR_HANDLER; /* * Lock sdev->state_mutex to avoid that scsi_device_quiesce() can @@ -1109,6 +1108,7 @@ retry: if (rtn) { if (timeleft > stall_for) { scsi_eh_restore_cmnd(scmd, &ses); + timeleft -= stall_for; msleep(jiffies_to_msecs(stall_for)); goto retry; @@ -2338,11 +2338,6 @@ void scsi_report_device_reset(struct Scsi_Host *shost, int channel, int target) } EXPORT_SYMBOL(scsi_report_device_reset); -static void -scsi_reset_provider_done_command(struct scsi_cmnd *scmd) -{ -} - /** * scsi_ioctl_reset: explicitly reset a host/bus/target/device * @dev: scsi_device to operate on @@ -2379,7 +2374,7 @@ scsi_ioctl_reset(struct scsi_device *dev, int __user *arg) scsi_init_command(dev, scmd); scmd->cmnd = scsi_req(rq)->cmd; - scmd->scsi_done = scsi_reset_provider_done_command; + scmd->submitter = SUBMITTED_BY_SCSI_RESET_IOCTL; memset(&scmd->sdb, 0, sizeof(scmd->sdb)); scmd->cmd_len = 0; diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index 5f5ad22512f5..3fd24144b805 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c @@ -1577,6 +1577,15 @@ static blk_status_t scsi_prepare_cmd(struct request *req) static void scsi_mq_done(struct scsi_cmnd *cmd) { + switch (cmd->submitter) { + case SUBMITTED_BY_BLOCK_LAYER: + break; + case SUBMITTED_BY_SCSI_ERROR_HANDLER: + return scsi_eh_done(cmd); + case SUBMITTED_BY_SCSI_RESET_IOCTL: + return; + } + if (unlikely(blk_should_fake_timeout(scsi_cmd_to_rq(cmd)->q))) return; if (unlikely(test_and_set_bit(SCMD_STATE_COMPLETE, &cmd->state))) @@ -1683,6 +1692,7 @@ static blk_status_t scsi_queue_rq(struct blk_mq_hw_ctx *hctx, scsi_set_resid(cmd, 0); memset(cmd->sense_buffer, 0, SCSI_SENSE_BUFFERSIZE); + cmd->submitter = SUBMITTED_BY_BLOCK_LAYER; cmd->scsi_done = scsi_mq_done; blk_mq_start_request(req); diff --git a/drivers/scsi/scsi_priv.h b/drivers/scsi/scsi_priv.h index 2d9de5a165ae..f8ca22d495d9 100644 --- a/drivers/scsi/scsi_priv.h +++ b/drivers/scsi/scsi_priv.h @@ -84,6 +84,7 @@ void scsi_eh_ready_devs(struct Scsi_Host *shost, int scsi_eh_get_sense(struct list_head *work_q, struct list_head *done_q); int scsi_noretry_cmd(struct scsi_cmnd *scmd); +void scsi_eh_done(struct scsi_cmnd *scmd); /* scsi_lib.c */ extern int scsi_maybe_unblock_host(struct scsi_device *sdev); diff --git a/include/scsi/scsi_cmnd.h b/include/scsi/scsi_cmnd.h index a2315aac93c7..893c24aab8e4 100644 --- a/include/scsi/scsi_cmnd.h +++ b/include/scsi/scsi_cmnd.h @@ -64,6 +64,12 @@ struct scsi_pointer { #define SCMD_STATE_COMPLETE 0 #define SCMD_STATE_INFLIGHT 1 +enum scsi_cmnd_submitter { + SUBMITTED_BY_BLOCK_LAYER = 0, + SUBMITTED_BY_SCSI_ERROR_HANDLER = 1, + SUBMITTED_BY_SCSI_RESET_IOCTL = 2, +} __packed; + struct scsi_cmnd { struct scsi_request req; struct scsi_device *device; @@ -89,6 +95,7 @@ struct scsi_cmnd { unsigned char prot_op; unsigned char prot_type; unsigned char prot_flags; + enum scsi_cmnd_submitter submitter; unsigned short cmd_len; enum dma_data_direction sc_data_direction; From a710eacb9d13cb5d9eb5341ebc6fc8f7b96f8c6f Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 7 Oct 2021 13:27:57 -0700 Subject: [PATCH 112/279] scsi: core: Rename scsi_mq_done() into scsi_done() and export it Since the removal of the legacy block layer there is only one completion function left in the SCSI core, namely scsi_mq_done(). Rename it into scsi_done(). Export that function to allow SCSI LLDs to call it directly. Link: https://lore.kernel.org/r/20211007202923.2174984-3-bvanassche@acm.org Reviewed-by: Benjamin Block Reviewed-by: Bean Huo Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/scsi_lib.c | 5 +++-- include/scsi/scsi_cmnd.h | 2 ++ 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index 3fd24144b805..f690a2da21ea 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c @@ -1575,7 +1575,7 @@ static blk_status_t scsi_prepare_cmd(struct request *req) return scsi_cmd_to_driver(cmd)->init_command(cmd); } -static void scsi_mq_done(struct scsi_cmnd *cmd) +void scsi_done(struct scsi_cmnd *cmd) { switch (cmd->submitter) { case SUBMITTED_BY_BLOCK_LAYER: @@ -1593,6 +1593,7 @@ static void scsi_mq_done(struct scsi_cmnd *cmd) trace_scsi_dispatch_cmd_done(cmd); blk_mq_complete_request(scsi_cmd_to_rq(cmd)); } +EXPORT_SYMBOL(scsi_done); static void scsi_mq_put_budget(struct request_queue *q, int budget_token) { @@ -1693,7 +1694,7 @@ static blk_status_t scsi_queue_rq(struct blk_mq_hw_ctx *hctx, scsi_set_resid(cmd, 0); memset(cmd->sense_buffer, 0, SCSI_SENSE_BUFFERSIZE); cmd->submitter = SUBMITTED_BY_BLOCK_LAYER; - cmd->scsi_done = scsi_mq_done; + cmd->scsi_done = scsi_done; blk_mq_start_request(req); reason = scsi_dispatch_cmd(cmd); diff --git a/include/scsi/scsi_cmnd.h b/include/scsi/scsi_cmnd.h index 893c24aab8e4..4edaadc293a7 100644 --- a/include/scsi/scsi_cmnd.h +++ b/include/scsi/scsi_cmnd.h @@ -171,6 +171,8 @@ static inline struct scsi_driver *scsi_cmd_to_driver(struct scsi_cmnd *cmd) return *(struct scsi_driver **)rq->rq_disk->private_data; } +void scsi_done(struct scsi_cmnd *cmd); + extern void scsi_finish_command(struct scsi_cmnd *cmd); extern void *scsi_kmap_atomic_sg(struct scatterlist *sg, int sg_count, From 58bf201dfc032eadbb31eaf817b467bed17f753d Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 7 Oct 2021 13:27:58 -0700 Subject: [PATCH 113/279] scsi: ata: Call scsi_done() directly Conditional statements are faster than indirect calls. Hence call scsi_done() directly. Link: https://lore.kernel.org/r/20211007202923.2174984-4-bvanassche@acm.org Acked-by: Damien Le Moal Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/ata/libata-sata.c | 2 +- drivers/ata/libata-scsi.c | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/ata/libata-sata.c b/drivers/ata/libata-sata.c index 8f3ff830ab0c..60418d872c12 100644 --- a/drivers/ata/libata-sata.c +++ b/drivers/ata/libata-sata.c @@ -1258,7 +1258,7 @@ int ata_sas_queuecmd(struct scsi_cmnd *cmd, struct ata_port *ap) rc = __ata_scsi_queuecmd(cmd, ap->link.device); else { cmd->result = (DID_BAD_TARGET << 16); - cmd->scsi_done(cmd); + scsi_done(cmd); } return rc; } diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index 1fb4611f7eeb..4afe1abc4709 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -634,7 +634,7 @@ static struct ata_queued_cmd *ata_scsi_qc_new(struct ata_device *dev, qc = ata_qc_new_init(dev, scsi_cmd_to_rq(cmd)->tag); if (qc) { qc->scsicmd = cmd; - qc->scsidone = cmd->scsi_done; + qc->scsidone = scsi_done; qc->sg = scsi_sglist(cmd); qc->n_elem = scsi_sg_count(cmd); @@ -643,7 +643,7 @@ static struct ata_queued_cmd *ata_scsi_qc_new(struct ata_device *dev, qc->flags |= ATA_QCFLAG_QUIET; } else { cmd->result = (DID_OK << 16) | SAM_STAT_TASK_SET_FULL; - cmd->scsi_done(cmd); + scsi_done(cmd); } return qc; @@ -1738,14 +1738,14 @@ static int ata_scsi_translate(struct ata_device *dev, struct scsi_cmnd *cmd, early_finish: ata_qc_free(qc); - cmd->scsi_done(cmd); + scsi_done(cmd); DPRINTK("EXIT - early finish (good or error)\n"); return 0; err_did: ata_qc_free(qc); cmd->result = (DID_ERROR << 16); - cmd->scsi_done(cmd); + scsi_done(cmd); err_mem: DPRINTK("EXIT - internal\n"); return 0; @@ -4018,7 +4018,7 @@ int __ata_scsi_queuecmd(struct scsi_cmnd *scmd, struct ata_device *dev) DPRINTK("bad CDB len=%u, scsi_op=0x%02x, max=%u\n", scmd->cmd_len, scsi_op, dev->cdb_len); scmd->result = DID_ERROR << 16; - scmd->scsi_done(scmd); + scsi_done(scmd); return 0; } @@ -4060,7 +4060,7 @@ int ata_scsi_queuecmd(struct Scsi_Host *shost, struct scsi_cmnd *cmd) rc = __ata_scsi_queuecmd(cmd, dev); else { cmd->result = (DID_BAD_TARGET << 16); - cmd->scsi_done(cmd); + scsi_done(cmd); } spin_unlock_irqrestore(ap->lock, irq_flags); @@ -4188,7 +4188,7 @@ void ata_scsi_simulate(struct ata_device *dev, struct scsi_cmnd *cmd) break; } - cmd->scsi_done(cmd); + scsi_done(cmd); } int ata_scsi_add_hosts(struct ata_host *host, struct scsi_host_template *sht) From 409d337e6bd61498696f8ea22f4da48c0b7a245d Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 7 Oct 2021 13:27:59 -0700 Subject: [PATCH 114/279] scsi: firewire: sbp2: Call scsi_done() directly Conditional statements are faster than indirect calls. Hence call scsi_done() directly. Link: https://lore.kernel.org/r/20211007202923.2174984-5-bvanassche@acm.org Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/firewire/sbp2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/firewire/sbp2.c b/drivers/firewire/sbp2.c index 4d5054211550..aeed3f2273e8 100644 --- a/drivers/firewire/sbp2.c +++ b/drivers/firewire/sbp2.c @@ -1375,7 +1375,7 @@ static void complete_command_orb(struct sbp2_orb *base_orb, sbp2_unmap_scatterlist(device->card->device, orb); orb->cmd->result = result; - orb->cmd->scsi_done(orb->cmd); + scsi_done(orb->cmd); } static int sbp2_map_scatterlist(struct sbp2_command_orb *orb, From 5f9ae9eecb15ef00d89a5884add1117a8e634e7f Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 7 Oct 2021 13:28:00 -0700 Subject: [PATCH 115/279] scsi: ib_srp: Call scsi_done() directly Conditional statements are faster than indirect calls. Hence call scsi_done() directly. Link: https://lore.kernel.org/r/20211007202923.2174984-6-bvanassche@acm.org Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/infiniband/ulp/srp/ib_srp.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/infiniband/ulp/srp/ib_srp.c b/drivers/infiniband/ulp/srp/ib_srp.c index 71eda91e810c..f8765f96ec1e 100644 --- a/drivers/infiniband/ulp/srp/ib_srp.c +++ b/drivers/infiniband/ulp/srp/ib_srp.c @@ -1266,7 +1266,7 @@ static void srp_finish_req(struct srp_rdma_ch *ch, struct srp_request *req, if (scmnd) { srp_free_req(ch, req, scmnd, 0); scmnd->result = result; - scmnd->scsi_done(scmnd); + scsi_done(scmnd); } } @@ -1987,7 +1987,7 @@ static void srp_process_rsp(struct srp_rdma_ch *ch, struct srp_rsp *rsp) srp_free_req(ch, req, scmnd, be32_to_cpu(rsp->req_lim_delta)); - scmnd->scsi_done(scmnd); + scsi_done(scmnd); } } @@ -2239,7 +2239,7 @@ err_iu: err: if (scmnd->result) { - scmnd->scsi_done(scmnd); + scsi_done(scmnd); ret = 0; } else { ret = SCSI_MLQUEUE_HOST_BUSY; @@ -2811,7 +2811,7 @@ static int srp_abort(struct scsi_cmnd *scmnd) if (ret == SUCCESS) { srp_free_req(ch, req, scmnd, 0); scmnd->result = DID_ABORT << 16; - scmnd->scsi_done(scmnd); + scsi_done(scmnd); } return ret; From 1ae6d167793c3b293114335f474adfc0ef5438ed Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 7 Oct 2021 13:28:01 -0700 Subject: [PATCH 116/279] scsi: message: fusion: Call scsi_done() directly Conditional statements are faster than indirect calls. Hence call scsi_done() directly. Link: https://lore.kernel.org/r/20211007202923.2174984-7-bvanassche@acm.org Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/message/fusion/mptfc.c | 6 +++--- drivers/message/fusion/mptsas.c | 2 +- drivers/message/fusion/mptscsih.c | 10 +++++----- drivers/message/fusion/mptspi.c | 4 ++-- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/drivers/message/fusion/mptfc.c b/drivers/message/fusion/mptfc.c index 572333fadd68..7a6278ae71d2 100644 --- a/drivers/message/fusion/mptfc.c +++ b/drivers/message/fusion/mptfc.c @@ -649,14 +649,14 @@ mptfc_qcmd(struct Scsi_Host *shost, struct scsi_cmnd *SCpnt) if (!vdevice || !vdevice->vtarget) { SCpnt->result = DID_NO_CONNECT << 16; - SCpnt->scsi_done(SCpnt); + scsi_done(SCpnt); return 0; } err = fc_remote_port_chkready(rport); if (unlikely(err)) { SCpnt->result = err; - SCpnt->scsi_done(SCpnt); + scsi_done(SCpnt); return 0; } @@ -664,7 +664,7 @@ mptfc_qcmd(struct Scsi_Host *shost, struct scsi_cmnd *SCpnt) ri = *((struct mptfc_rport_info **)rport->dd_data); if (unlikely(!ri)) { SCpnt->result = DID_IMM_RETRY << 16; - SCpnt->scsi_done(SCpnt); + scsi_done(SCpnt); return 0; } diff --git a/drivers/message/fusion/mptsas.c b/drivers/message/fusion/mptsas.c index 85285ba8e817..38a7cb0a3ecc 100644 --- a/drivers/message/fusion/mptsas.c +++ b/drivers/message/fusion/mptsas.c @@ -1929,7 +1929,7 @@ mptsas_qcmd(struct Scsi_Host *shost, struct scsi_cmnd *SCpnt) if (!vdevice || !vdevice->vtarget || vdevice->vtarget->deleted) { SCpnt->result = DID_NO_CONNECT << 16; - SCpnt->scsi_done(SCpnt); + scsi_done(SCpnt); return 0; } diff --git a/drivers/message/fusion/mptscsih.c b/drivers/message/fusion/mptscsih.c index ce2e5b21978e..ab9611e775d3 100644 --- a/drivers/message/fusion/mptscsih.c +++ b/drivers/message/fusion/mptscsih.c @@ -1009,7 +1009,7 @@ out: /* Unmap the DMA buffers, if any. */ scsi_dma_unmap(sc); - sc->scsi_done(sc); /* Issue the command callback */ + scsi_done(sc); /* Issue the command callback */ /* Free Chain buffers */ mptscsih_freeChainBuffers(ioc, req_idx); @@ -1054,7 +1054,7 @@ mptscsih_flush_running_cmds(MPT_SCSI_HOST *hd) dtmprintk(ioc, sdev_printk(KERN_INFO, sc->device, MYIOC_s_FMT "completing cmds: fw_channel %d, fw_id %d, sc=%p, mf = %p, " "idx=%x\n", ioc->name, channel, id, sc, mf, ii)); - sc->scsi_done(sc); + scsi_done(sc); } } EXPORT_SYMBOL(mptscsih_flush_running_cmds); @@ -1118,7 +1118,7 @@ mptscsih_search_running_cmds(MPT_SCSI_HOST *hd, VirtDevice *vdevice) "fw_id %d, sc=%p, mf = %p, idx=%x\n", ioc->name, vdevice->vtarget->channel, vdevice->vtarget->id, sc, mf, ii)); - sc->scsi_done(sc); + scsi_done(sc); spin_lock_irqsave(&ioc->scsi_lookup_lock, flags); } } @@ -1693,7 +1693,7 @@ mptscsih_abort(struct scsi_cmnd * SCpnt) */ if ((hd = shost_priv(SCpnt->device->host)) == NULL) { SCpnt->result = DID_RESET << 16; - SCpnt->scsi_done(SCpnt); + scsi_done(SCpnt); printk(KERN_ERR MYNAM ": task abort: " "can't locate host! (sc=%p)\n", SCpnt); return FAILED; @@ -1710,7 +1710,7 @@ mptscsih_abort(struct scsi_cmnd * SCpnt) "task abort: device has been deleted (sc=%p)\n", ioc->name, SCpnt)); SCpnt->result = DID_NO_CONNECT << 16; - SCpnt->scsi_done(SCpnt); + scsi_done(SCpnt); retval = SUCCESS; goto out; } diff --git a/drivers/message/fusion/mptspi.c b/drivers/message/fusion/mptspi.c index af0ce5611e4a..44b7ce124ae1 100644 --- a/drivers/message/fusion/mptspi.c +++ b/drivers/message/fusion/mptspi.c @@ -782,14 +782,14 @@ mptspi_qcmd(struct Scsi_Host *shost, struct scsi_cmnd *SCpnt) if (!vdevice || !vdevice->vtarget) { SCpnt->result = DID_NO_CONNECT << 16; - SCpnt->scsi_done(SCpnt); + scsi_done(SCpnt); return 0; } if (SCpnt->device->channel == 1 && mptscsih_is_phys_disk(ioc, 0, SCpnt->device->id) == 0) { SCpnt->result = DID_NO_CONNECT << 16; - SCpnt->scsi_done(SCpnt); + scsi_done(SCpnt); return 0; } From 68f89c50cd0c4c13e5bb55dec67fac653ba8e38a Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 7 Oct 2021 13:28:02 -0700 Subject: [PATCH 117/279] scsi: zfcp_scsi: Call scsi_done() directly Conditional statements are faster than indirect calls. Hence call scsi_done() directly. Link: https://lore.kernel.org/r/20211007202923.2174984-8-bvanassche@acm.org Acked-by: Benjamin Block Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/s390/scsi/zfcp_fsf.c | 2 +- drivers/s390/scsi/zfcp_scsi.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c index c1f979296c1a..4f1e4385ce58 100644 --- a/drivers/s390/scsi/zfcp_fsf.c +++ b/drivers/s390/scsi/zfcp_fsf.c @@ -2501,7 +2501,7 @@ skip_fsfstatus: zfcp_dbf_scsi_result(scpnt, req); scpnt->host_scribble = NULL; - (scpnt->scsi_done) (scpnt); + scsi_done(scpnt); /* * We must hold this lock until scsi_done has been called. * Otherwise we may call scsi_done after abort regarding this diff --git a/drivers/s390/scsi/zfcp_scsi.c b/drivers/s390/scsi/zfcp_scsi.c index 9da9b2b2a580..e0a6d8c1f198 100644 --- a/drivers/s390/scsi/zfcp_scsi.c +++ b/drivers/s390/scsi/zfcp_scsi.c @@ -60,7 +60,7 @@ static void zfcp_scsi_command_fail(struct scsi_cmnd *scpnt, int result) { set_host_byte(scpnt, result); zfcp_dbf_scsi_fail_send(scpnt); - scpnt->scsi_done(scpnt); + scsi_done(scpnt); } static @@ -78,7 +78,7 @@ int zfcp_scsi_queuecommand(struct Scsi_Host *shost, struct scsi_cmnd *scpnt) if (unlikely(scsi_result)) { scpnt->result = scsi_result; zfcp_dbf_scsi_fail_send(scpnt); - scpnt->scsi_done(scpnt); + scsi_done(scpnt); return 0; } From 3e6d3832dc1b4d6426733b357412a96f90b0e368 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 7 Oct 2021 13:28:03 -0700 Subject: [PATCH 118/279] scsi: 3w-9xxx: Call scsi_done() directly Conditional statements are faster than indirect calls. Hence call scsi_done() directly. Link: https://lore.kernel.org/r/20211007202923.2174984-9-bvanassche@acm.org Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/3w-9xxx.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/drivers/scsi/3w-9xxx.c b/drivers/scsi/3w-9xxx.c index e41cc354cc8a..4ebc2c79f45f 100644 --- a/drivers/scsi/3w-9xxx.c +++ b/drivers/scsi/3w-9xxx.c @@ -1352,7 +1352,7 @@ static irqreturn_t twa_interrupt(int irq, void *dev_instance) /* Now complete the io */ if (twa_command_mapped(cmd)) scsi_dma_unmap(cmd); - cmd->scsi_done(cmd); + scsi_done(cmd); tw_dev->state[request_id] = TW_S_COMPLETED; twa_free_request_id(tw_dev, request_id); tw_dev->posted_request_count--; @@ -1596,7 +1596,7 @@ static int twa_reset_device_extension(TW_Device_Extension *tw_dev) cmd->result = (DID_RESET << 16); if (twa_command_mapped(cmd)) scsi_dma_unmap(cmd); - cmd->scsi_done(cmd); + scsi_done(cmd); } } } @@ -1763,9 +1763,6 @@ static int twa_scsi_queue_lck(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_ goto out; } - /* Save done function into scsi_cmnd struct */ - SCpnt->scsi_done = done; - /* Get a free request id */ twa_get_request_id(tw_dev, &request_id); From 2adf975e899a35936b89047d3a02c582ef11adeb Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 7 Oct 2021 13:28:04 -0700 Subject: [PATCH 119/279] scsi: 3w-sas: Call scsi_done() directly Conditional statements are faster than indirect calls. Hence call scsi_done() directly. Link: https://lore.kernel.org/r/20211007202923.2174984-10-bvanassche@acm.org Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/3w-sas.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/drivers/scsi/3w-sas.c b/drivers/scsi/3w-sas.c index 4fde39da54e4..e6f51904f5b1 100644 --- a/drivers/scsi/3w-sas.c +++ b/drivers/scsi/3w-sas.c @@ -1216,7 +1216,7 @@ static irqreturn_t twl_interrupt(int irq, void *dev_instance) /* Now complete the io */ scsi_dma_unmap(cmd); - cmd->scsi_done(cmd); + scsi_done(cmd); tw_dev->state[request_id] = TW_S_COMPLETED; twl_free_request_id(tw_dev, request_id); tw_dev->posted_request_count--; @@ -1369,7 +1369,7 @@ static int twl_reset_device_extension(TW_Device_Extension *tw_dev, int ioctl_res if (cmd) { cmd->result = (DID_RESET << 16); scsi_dma_unmap(cmd); - cmd->scsi_done(cmd); + scsi_done(cmd); } } } @@ -1461,9 +1461,6 @@ static int twl_scsi_queue_lck(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_ goto out; } - /* Save done function into scsi_cmnd struct */ - SCpnt->scsi_done = done; - /* Get a free request id */ twl_get_request_id(tw_dev, &request_id); From 9dd9b96c2623442d9999c67a2cc8f58d64a110d5 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 7 Oct 2021 13:28:05 -0700 Subject: [PATCH 120/279] scsi: 3w-xxxx: Call scsi_done() directly Conditional statements are faster than indirect calls. Hence call scsi_done() directly. Link: https://lore.kernel.org/r/20211007202923.2174984-11-bvanassche@acm.org Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/3w-xxxx.c | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/drivers/scsi/3w-xxxx.c b/drivers/scsi/3w-xxxx.c index 4ee485ab2714..bdd3ab8875e2 100644 --- a/drivers/scsi/3w-xxxx.c +++ b/drivers/scsi/3w-xxxx.c @@ -1160,7 +1160,7 @@ static int tw_setfeature(TW_Device_Extension *tw_dev, int parm, int param_size, tw_dev->state[request_id] = TW_S_COMPLETED; tw_state_request_finish(tw_dev, request_id); tw_dev->srb[request_id]->result = (DID_OK << 16); - tw_dev->srb[request_id]->scsi_done(tw_dev->srb[request_id]); + scsi_done(tw_dev->srb[request_id]); } command_packet->byte8.param.sgl[0].address = param_value; command_packet->byte8.param.sgl[0].length = sizeof(TW_Sector); @@ -1305,7 +1305,7 @@ static int tw_reset_device_extension(TW_Device_Extension *tw_dev) if (srb != NULL) { srb->result = (DID_RESET << 16); scsi_dma_unmap(srb); - srb->scsi_done(srb); + scsi_done(srb); } } } @@ -1505,7 +1505,7 @@ static int tw_scsiop_mode_sense(TW_Device_Extension *tw_dev, int request_id) tw_dev->state[request_id] = TW_S_COMPLETED; tw_state_request_finish(tw_dev, request_id); tw_dev->srb[request_id]->result = (DID_OK << 16); - tw_dev->srb[request_id]->scsi_done(tw_dev->srb[request_id]); + scsi_done(tw_dev->srb[request_id]); return 0; } @@ -1796,7 +1796,7 @@ static int tw_scsiop_request_sense(TW_Device_Extension *tw_dev, int request_id) /* If we got a request_sense, we probably want a reset, return error */ tw_dev->srb[request_id]->result = (DID_ERROR << 16); - tw_dev->srb[request_id]->scsi_done(tw_dev->srb[request_id]); + scsi_done(tw_dev->srb[request_id]); return 0; } /* End tw_scsiop_request_sense() */ @@ -1929,9 +1929,6 @@ static int tw_scsi_queue_lck(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_c if (test_bit(TW_IN_RESET, &tw_dev->flags)) return SCSI_MLQUEUE_HOST_BUSY; - /* Save done function into struct scsi_cmnd */ - SCpnt->scsi_done = done; - /* Queue the command and get a request id */ tw_state_request_start(tw_dev, &request_id); @@ -2165,7 +2162,7 @@ static irqreturn_t tw_interrupt(int irq, void *dev_instance) /* Now complete the io */ if ((error != TW_ISR_DONT_COMPLETE)) { scsi_dma_unmap(tw_dev->srb[request_id]); - tw_dev->srb[request_id]->scsi_done(tw_dev->srb[request_id]); + scsi_done(tw_dev->srb[request_id]); tw_dev->state[request_id] = TW_S_COMPLETED; tw_state_request_finish(tw_dev, request_id); tw_dev->posted_request_count--; From 656f26ade03ad98fe9cb3dab11d2111d1a60cb4f Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 7 Oct 2021 13:28:06 -0700 Subject: [PATCH 121/279] scsi: 53c700: Call scsi_done() directly Conditional statements are faster than indirect calls. Hence call scsi_done() directly. Link: https://lore.kernel.org/r/20211007202923.2174984-12-bvanassche@acm.org Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/53c700.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/scsi/53c700.c b/drivers/scsi/53c700.c index a12e3525977d..e7ed2fd6cdec 100644 --- a/drivers/scsi/53c700.c +++ b/drivers/scsi/53c700.c @@ -634,7 +634,7 @@ NCR_700_scsi_done(struct NCR_700_Host_Parameters *hostdata, SCp->host_scribble = NULL; SCp->result = result; - SCp->scsi_done(SCp); + scsi_done(SCp); } else { printk(KERN_ERR "53c700: SCSI DONE HAS NULL SCp\n"); } @@ -1571,7 +1571,7 @@ NCR_700_intr(int irq, void *dev_id) * deadlock on the * hostdata->state_lock */ SCp->result = DID_RESET << 16; - SCp->scsi_done(SCp); + scsi_done(SCp); } mdelay(25); NCR_700_chip_setup(host); @@ -1792,7 +1792,6 @@ NCR_700_queuecommand_lck(struct scsi_cmnd *SCp, void (*done)(struct scsi_cmnd *) slot->cmnd = SCp; - SCp->scsi_done = done; SCp->host_scribble = (unsigned char *)slot; SCp->SCp.ptr = NULL; SCp->SCp.buffer = NULL; From 0800a26aaa805dca5faad0a594db2570e43ce0dc Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 7 Oct 2021 13:28:07 -0700 Subject: [PATCH 122/279] scsi: BusLogic: Call scsi_done() directly Conditional statements are faster than indirect calls. Hence call scsi_done() directly. Link: https://lore.kernel.org/r/20211007202923.2174984-13-bvanassche@acm.org Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/BusLogic.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/drivers/scsi/BusLogic.c b/drivers/scsi/BusLogic.c index 40088dcb98cd..7287a9081684 100644 --- a/drivers/scsi/BusLogic.c +++ b/drivers/scsi/BusLogic.c @@ -2624,7 +2624,7 @@ static void blogic_process_ccbs(struct blogic_adapter *adapter) command->reset_chain; command->reset_chain = NULL; command->result = DID_RESET << 16; - command->scsi_done(command); + scsi_done(command); command = nxt_cmd; } #endif @@ -2641,7 +2641,7 @@ static void blogic_process_ccbs(struct blogic_adapter *adapter) blogic_dealloc_ccb(ccb, 1); adapter->active_cmds[tgt_id]--; command->result = DID_RESET << 16; - command->scsi_done(command); + scsi_done(command); } adapter->bdr_pend[tgt_id] = NULL; } else { @@ -2713,7 +2713,7 @@ static void blogic_process_ccbs(struct blogic_adapter *adapter) /* Call the SCSI Command Completion Routine. */ - command->scsi_done(command); + scsi_done(command); } } adapter->processing_ccbs = false; @@ -3038,7 +3038,6 @@ static int blogic_qcmd_lck(struct scsi_cmnd *command, return SCSI_MLQUEUE_HOST_BUSY; } ccb->sensedata = sense_buf; - command->scsi_done = comp_cb; if (blogic_multimaster_type(adapter)) { /* Place the CCB in an Outgoing Mailbox. The higher levels @@ -3060,7 +3059,7 @@ static int blogic_qcmd_lck(struct scsi_cmnd *command, blogic_warn("Still unable to write Outgoing Mailbox - Host Adapter Dead?\n", adapter); blogic_dealloc_ccb(ccb, 1); command->result = DID_ERROR << 16; - command->scsi_done(command); + scsi_done(command); } } } else { From 117cd238adfe5e9327142fd389883a3f101a06a2 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 7 Oct 2021 13:28:08 -0700 Subject: [PATCH 123/279] scsi: NCR5380: Call scsi_done() directly Conditional statements are faster than indirect calls. Hence call scsi_done() directly. Link: https://lore.kernel.org/r/20211007202923.2174984-14-bvanassche@acm.org Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/NCR5380.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/scsi/NCR5380.c b/drivers/scsi/NCR5380.c index a85589a2a8af..55af3e245a92 100644 --- a/drivers/scsi/NCR5380.c +++ b/drivers/scsi/NCR5380.c @@ -547,7 +547,7 @@ static void complete_cmd(struct Scsi_Host *instance, hostdata->sensing = NULL; } - cmd->scsi_done(cmd); + scsi_done(cmd); } /** @@ -573,7 +573,7 @@ static int NCR5380_queue_command(struct Scsi_Host *instance, case WRITE_10: shost_printk(KERN_DEBUG, instance, "WRITE attempted with NDEBUG_NO_WRITE set\n"); cmd->result = (DID_ERROR << 16); - cmd->scsi_done(cmd); + scsi_done(cmd); return 0; } #endif /* (NDEBUG & NDEBUG_NO_WRITE) */ @@ -960,7 +960,7 @@ static irqreturn_t __maybe_unused NCR5380_intr(int irq, void *dev_id) * hostdata->connected will be set to cmd. * SELECT interrupt will be disabled. * - * If failed (no target) : cmd->scsi_done() will be called, and the + * If failed (no target) : scsi_done() will be called, and the * cmd->result host byte set to DID_BAD_TARGET. */ @@ -2262,7 +2262,7 @@ static int NCR5380_abort(struct scsi_cmnd *cmd) dsprintk(NDEBUG_ABORT, instance, "abort: removed %p from issue queue\n", cmd); cmd->result = DID_ABORT << 16; - cmd->scsi_done(cmd); /* No tag or busy flag to worry about */ + scsi_done(cmd); /* No tag or busy flag to worry about */ goto out; } @@ -2357,7 +2357,7 @@ static void bus_reset_cleanup(struct Scsi_Host *instance) list_for_each_entry(ncmd, &hostdata->autosense, list) { struct scsi_cmnd *cmd = NCR5380_to_scmd(ncmd); - cmd->scsi_done(cmd); + scsi_done(cmd); } INIT_LIST_HEAD(&hostdata->autosense); @@ -2400,7 +2400,7 @@ static int NCR5380_host_reset(struct scsi_cmnd *cmd) struct scsi_cmnd *scmd = NCR5380_to_scmd(ncmd); scmd->result = DID_RESET << 16; - scmd->scsi_done(scmd); + scsi_done(scmd); } INIT_LIST_HEAD(&hostdata->unissued); From e42be9e75a029c77860643b45365ec8cfb550487 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 7 Oct 2021 13:28:09 -0700 Subject: [PATCH 124/279] scsi: a100u2w: Call scsi_done() directly Conditional statements are faster than indirect calls. Hence call scsi_done() directly. Link: https://lore.kernel.org/r/20211007202923.2174984-15-bvanassche@acm.org Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/a100u2w.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/scsi/a100u2w.c b/drivers/scsi/a100u2w.c index 028af6b1057c..68343bcb4616 100644 --- a/drivers/scsi/a100u2w.c +++ b/drivers/scsi/a100u2w.c @@ -917,7 +917,6 @@ static int inia100_queue_lck(struct scsi_cmnd * cmd, void (*done) (struct scsi_c struct orc_host *host; /* Point to Host adapter control block */ host = (struct orc_host *) cmd->device->host->hostdata; - cmd->scsi_done = done; /* Get free SCSI control block */ if ((scb = orc_alloc_scb(host)) == NULL) return SCSI_MLQUEUE_HOST_BUSY; @@ -1042,7 +1041,7 @@ static void inia100_scb_handler(struct orc_host *host, struct orc_scb *scb) } cmd->result = scb->tastat | (scb->hastat << 16); scsi_dma_unmap(cmd); - cmd->scsi_done(cmd); /* Notify system DONE */ + scsi_done(cmd); /* Notify system DONE */ orc_release_scb(host, scb); /* Release SCB for current channel */ } From 1dec65e32fb512dde098c1aa06ed35f0eed5d90f Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 7 Oct 2021 13:28:10 -0700 Subject: [PATCH 125/279] scsi: aacraid: Introduce aac_scsi_done() This patch does not change any functionality but makes the next patch in this series easier to read. Link: https://lore.kernel.org/r/20211007202923.2174984-16-bvanassche@acm.org Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/aacraid/aachba.c | 39 ++++++++++++++++++++--------------- 1 file changed, 22 insertions(+), 17 deletions(-) diff --git a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c index c2d6f0a9e0b1..40b86acac17b 100644 --- a/drivers/scsi/aacraid/aachba.c +++ b/drivers/scsi/aacraid/aachba.c @@ -517,6 +517,11 @@ int aac_get_containers(struct aac_dev *dev) return status; } +static void aac_scsi_done(struct scsi_cmnd *scmd) +{ + scmd->scsi_done(scmd); +} + static void get_container_name_callback(void *context, struct fib * fibptr) { struct aac_get_name_resp * get_name_reply; @@ -558,7 +563,7 @@ static void get_container_name_callback(void *context, struct fib * fibptr) scsicmd->result = DID_OK << 16 | SAM_STAT_GOOD; aac_fib_complete(fibptr); - scsicmd->scsi_done(scsicmd); + aac_scsi_done(scsicmd); } /* @@ -614,7 +619,7 @@ static int aac_probe_container_callback2(struct scsi_cmnd * scsicmd) return aac_scsi_cmd(scsicmd); scsicmd->result = DID_NO_CONNECT << 16; - scsicmd->scsi_done(scsicmd); + aac_scsi_done(scsicmd); return 0; } @@ -1094,7 +1099,7 @@ static void get_container_serial_callback(void *context, struct fib * fibptr) scsicmd->result = DID_OK << 16 | SAM_STAT_GOOD; aac_fib_complete(fibptr); - scsicmd->scsi_done(scsicmd); + aac_scsi_done(scsicmd); } /* @@ -1197,7 +1202,7 @@ static int aac_bounds_32(struct aac_dev * dev, struct scsi_cmnd * cmd, u64 lba) memcpy(cmd->sense_buffer, &dev->fsa_dev[cid].sense_data, min_t(size_t, sizeof(dev->fsa_dev[cid].sense_data), SCSI_SENSE_BUFFERSIZE)); - cmd->scsi_done(cmd); + aac_scsi_done(cmd); return 1; } return 0; @@ -2392,7 +2397,7 @@ static void io_callback(void *context, struct fib * fibptr) } aac_fib_complete(fibptr); - scsicmd->scsi_done(scsicmd); + aac_scsi_done(scsicmd); } static int aac_read(struct scsi_cmnd * scsicmd) @@ -2463,7 +2468,7 @@ static int aac_read(struct scsi_cmnd * scsicmd) memcpy(scsicmd->sense_buffer, &dev->fsa_dev[cid].sense_data, min_t(size_t, sizeof(dev->fsa_dev[cid].sense_data), SCSI_SENSE_BUFFERSIZE)); - scsicmd->scsi_done(scsicmd); + aac_scsi_done(scsicmd); return 0; } @@ -2489,7 +2494,7 @@ static int aac_read(struct scsi_cmnd * scsicmd) * For some reason, the Fib didn't queue, return QUEUE_FULL */ scsicmd->result = DID_OK << 16 | SAM_STAT_TASK_SET_FULL; - scsicmd->scsi_done(scsicmd); + aac_scsi_done(scsicmd); aac_fib_complete(cmd_fibcontext); aac_fib_free(cmd_fibcontext); return 0; @@ -2554,7 +2559,7 @@ static int aac_write(struct scsi_cmnd * scsicmd) memcpy(scsicmd->sense_buffer, &dev->fsa_dev[cid].sense_data, min_t(size_t, sizeof(dev->fsa_dev[cid].sense_data), SCSI_SENSE_BUFFERSIZE)); - scsicmd->scsi_done(scsicmd); + aac_scsi_done(scsicmd); return 0; } @@ -2580,7 +2585,7 @@ static int aac_write(struct scsi_cmnd * scsicmd) * For some reason, the Fib didn't queue, return QUEUE_FULL */ scsicmd->result = DID_OK << 16 | SAM_STAT_TASK_SET_FULL; - scsicmd->scsi_done(scsicmd); + aac_scsi_done(scsicmd); aac_fib_complete(cmd_fibcontext); aac_fib_free(cmd_fibcontext); @@ -2621,7 +2626,7 @@ static void synchronize_callback(void *context, struct fib *fibptr) aac_fib_complete(fibptr); aac_fib_free(fibptr); - cmd->scsi_done(cmd); + aac_scsi_done(cmd); } static int aac_synchronize(struct scsi_cmnd *scsicmd) @@ -2688,7 +2693,7 @@ static void aac_start_stop_callback(void *context, struct fib *fibptr) aac_fib_complete(fibptr); aac_fib_free(fibptr); - scsicmd->scsi_done(scsicmd); + aac_scsi_done(scsicmd); } static int aac_start_stop(struct scsi_cmnd *scsicmd) @@ -2702,7 +2707,7 @@ static int aac_start_stop(struct scsi_cmnd *scsicmd) if (!(aac->supplement_adapter_info.supported_options2 & AAC_OPTION_POWER_MANAGEMENT)) { scsicmd->result = DID_OK << 16 | SAM_STAT_GOOD; - scsicmd->scsi_done(scsicmd); + aac_scsi_done(scsicmd); return 0; } @@ -3237,7 +3242,7 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd) scsi_done_ret: - scsicmd->scsi_done(scsicmd); + aac_scsi_done(scsicmd); return 0; } @@ -3546,7 +3551,7 @@ static void aac_srb_callback(void *context, struct fib * fibptr) scsicmd->result |= le32_to_cpu(srbreply->scsi_status); aac_fib_complete(fibptr); - scsicmd->scsi_done(scsicmd); + aac_scsi_done(scsicmd); } static void hba_resp_task_complete(struct aac_dev *dev, @@ -3686,7 +3691,7 @@ out: if (fibptr->flags & FIB_CONTEXT_FLAG_NATIVE_HBA_TMF) scsicmd->SCp.sent_command = 1; else - scsicmd->scsi_done(scsicmd); + aac_scsi_done(scsicmd); } /** @@ -3706,7 +3711,7 @@ static int aac_send_srb_fib(struct scsi_cmnd* scsicmd) if (scmd_id(scsicmd) >= dev->maximum_num_physicals || scsicmd->device->lun > 7) { scsicmd->result = DID_NO_CONNECT << 16; - scsicmd->scsi_done(scsicmd); + aac_scsi_done(scsicmd); return 0; } @@ -3747,7 +3752,7 @@ static int aac_send_hba_fib(struct scsi_cmnd *scsicmd) if (scmd_id(scsicmd) >= dev->maximum_num_physicals || scsicmd->device->lun > AAC_MAX_LUN - 1) { scsicmd->result = DID_NO_CONNECT << 16; - scsicmd->scsi_done(scsicmd); + aac_scsi_done(scsicmd); return 0; } From 7afdb8637997497c8cfd0369f2b7bece477f47c0 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 7 Oct 2021 13:28:11 -0700 Subject: [PATCH 126/279] scsi: aacraid: Call scsi_done() directly The aacraid driver invokes scmd->scsi_done(scmd) for two types of SCSI commands: - SCSI commands initialized by the SCSI mid-layer. - SCSI commands initialized by aac_probe_container(). The processing sequence for SCSI commands allocated by aac_probe_container() is as follows: aac_probe_container() -> _aac_probe_container(scmd, aac_probe_container_callback1) -> scmd->SCp.ptr = aac_probe_container_callback1 -> aac_fib_send(..., _aac_probe_container1, scmd) -> fibptr->callback = _aac_probe_container1 -> fibptr->callback_data = scmd fibptr->callback(scmd) -> _aac_probe_container1(scmd, fibptr) [ ... ] -> _aac_probe_container2(scmd, fibptr) -> Call scmd->SCp.ptr == aac_probe_container_callback1 -> scmd->device = NULL; The processing sequence for SCSI commands allocated by the SCSI mid-layer if _aac_probe_container() is called is as follows: aac_queuecommand() -> aac_scsi_cmd() -> _aac_probe_container(scmd, aac_probe_container_callback2) -> scmd->SCp.ptr = aac_probe_container_callback2 -> aac_fib_send(..., _aac_probe_container1, scmd) fibptr->callback(scmd) -> _aac_probe_container1(scmd, fibptr) [ ... ] -> _aac_probe_container2(scmd, fibptr) -> Call scmd->SCp.ptr == aac_probe_container_callback2 Preserve the existing call sequences by calling scsi_done() for commands submitted by the mid-layer or aac_probe_container_scsi_done() for commands submitted by aac_probe_container(). Link: https://lore.kernel.org/r/20211007202923.2174984-17-bvanassche@acm.org Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/aacraid/aachba.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c index 40b86acac17b..59f6b7b2a70a 100644 --- a/drivers/scsi/aacraid/aachba.c +++ b/drivers/scsi/aacraid/aachba.c @@ -223,6 +223,7 @@ static long aac_build_sghba(struct scsi_cmnd *scsicmd, int sg_max, u64 sg_address); static int aac_convert_sgraw2(struct aac_raw_io2 *rio2, int pages, int nseg, int nseg_new); +static void aac_probe_container_scsi_done(struct scsi_cmnd *scsi_cmnd); static int aac_send_srb_fib(struct scsi_cmnd* scsicmd); static int aac_send_hba_fib(struct scsi_cmnd *scsicmd); #ifdef AAC_DETAILED_STATUS_INFO @@ -332,7 +333,7 @@ static inline int aac_valid_context(struct scsi_cmnd *scsicmd, struct fib *fibptr) { struct scsi_device *device; - if (unlikely(!scsicmd || !scsicmd->scsi_done)) { + if (unlikely(!scsicmd)) { dprintk((KERN_WARNING "aac_valid_context: scsi command corrupt\n")); aac_fib_complete(fibptr); return 0; @@ -519,7 +520,13 @@ int aac_get_containers(struct aac_dev *dev) static void aac_scsi_done(struct scsi_cmnd *scmd) { - scmd->scsi_done(scmd); + if (scmd->device->request_queue) { + /* SCSI command has been submitted by the SCSI mid-layer. */ + scsi_done(scmd); + } else { + /* SCSI command has been submitted by aac_probe_container(). */ + aac_probe_container_scsi_done(scmd); + } } static void get_container_name_callback(void *context, struct fib * fibptr) @@ -809,8 +816,8 @@ static void aac_probe_container_scsi_done(struct scsi_cmnd *scsi_cmnd) int aac_probe_container(struct aac_dev *dev, int cid) { - struct scsi_cmnd *scsicmd = kmalloc(sizeof(*scsicmd), GFP_KERNEL); - struct scsi_device *scsidev = kmalloc(sizeof(*scsidev), GFP_KERNEL); + struct scsi_cmnd *scsicmd = kzalloc(sizeof(*scsicmd), GFP_KERNEL); + struct scsi_device *scsidev = kzalloc(sizeof(*scsidev), GFP_KERNEL); int status; if (!scsicmd || !scsidev) { @@ -818,7 +825,6 @@ int aac_probe_container(struct aac_dev *dev, int cid) kfree(scsidev); return -ENOMEM; } - scsicmd->scsi_done = aac_probe_container_scsi_done; scsicmd->device = scsidev; scsidev->sdev_state = 0; From 396dd2c0b7b251dbe6013baf126ce954752a581b Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 7 Oct 2021 13:28:12 -0700 Subject: [PATCH 127/279] scsi: acornscsi: Call scsi_done() directly Conditional statements are faster than indirect calls. Hence call scsi_done() directly. Link: https://lore.kernel.org/r/20211007202923.2174984-18-bvanassche@acm.org Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/arm/acornscsi.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/drivers/scsi/arm/acornscsi.c b/drivers/scsi/arm/acornscsi.c index 0cc62c1b0825..dadaf5ee0ea9 100644 --- a/drivers/scsi/arm/acornscsi.c +++ b/drivers/scsi/arm/acornscsi.c @@ -841,13 +841,10 @@ static void acornscsi_done(AS_Host *host, struct scsi_cmnd **SCpntp, } } - if (!SCpnt->scsi_done) - panic("scsi%d.H: null scsi_done function in acornscsi_done", host->host->host_no); - clear_bit(SCpnt->device->id * 8 + (u8)(SCpnt->device->lun & 0x7), host->busyluns); - SCpnt->scsi_done(SCpnt); + scsi_done(SCpnt); } else printk("scsi%d: null command in acornscsi_done", host->host->host_no); @@ -2428,7 +2425,6 @@ static int acornscsi_queuecmd_lck(struct scsi_cmnd *SCpnt, } #endif - SCpnt->scsi_done = done; SCpnt->host_scribble = NULL; SCpnt->result = 0; SCpnt->SCp.phase = (int)acornscsi_datadirection(SCpnt->cmnd[0]); From f3bc9338e08de19f795b184a959c583195e1d6fd Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 7 Oct 2021 13:28:13 -0700 Subject: [PATCH 128/279] scsi: advansys: Call scsi_done() directly Conditional statements are faster than indirect calls. Hence call scsi_done() directly. Link: https://lore.kernel.org/r/20211007202923.2174984-19-bvanassche@acm.org Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/advansys.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/scsi/advansys.c b/drivers/scsi/advansys.c index 2df2a843a5ff..f2f14fbd5069 100644 --- a/drivers/scsi/advansys.c +++ b/drivers/scsi/advansys.c @@ -3592,7 +3592,7 @@ static void asc_scsi_done(struct scsi_cmnd *scp) { scsi_dma_unmap(scp); ASC_STATS(scp->device->host, done); - scp->scsi_done(scp); + scsi_done(scp); } static void AscSetBank(PortAddr iop_base, uchar bank) @@ -8460,7 +8460,6 @@ advansys_queuecommand_lck(struct scsi_cmnd *scp, void (*done)(struct scsi_cmnd * int asc_res, result = 0; ASC_STATS(shost, queuecommand); - scp->scsi_done = done; asc_res = asc_execute_scsi_cmnd(scp); From 3ab3b151ff1257623002d5e9b90c67f3e61228f2 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 7 Oct 2021 13:28:14 -0700 Subject: [PATCH 129/279] scsi: aha152x: Call scsi_done() directly Conditional statements are faster than indirect calls. Hence call scsi_done() and reset_done() directly. The changes in this patch are as follows: - Remove the 'done' argument from aha152x_internal_queue(). - Change ptr->scsi_done(ptr) into aha152x_scsi_done(ptr). - Inside aha152x_scsi_done(), check the 'resetting' flag of SCp.phase since aha152x_internal_queue() specifies the 'reset_done' function pointer if and only if the third argument has the value 'resetting'. Link: https://lore.kernel.org/r/20211007202923.2174984-20-bvanassche@acm.org Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/aha152x.c | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/drivers/scsi/aha152x.c b/drivers/scsi/aha152x.c index b13b5c85f3de..f07de9912790 100644 --- a/drivers/scsi/aha152x.c +++ b/drivers/scsi/aha152x.c @@ -905,13 +905,11 @@ static int setup_expected_interrupts(struct Scsi_Host *shpnt) * Queue a command and setup interrupts for a free bus. */ static int aha152x_internal_queue(struct scsi_cmnd *SCpnt, - struct completion *complete, - int phase, void (*done)(struct scsi_cmnd *)) + struct completion *complete, int phase) { struct Scsi_Host *shpnt = SCpnt->device->host; unsigned long flags; - SCpnt->scsi_done = done; SCpnt->SCp.phase = not_issued | phase; SCpnt->SCp.Status = 0x1; /* Ilegal status by SCSI standard */ SCpnt->SCp.Message = 0; @@ -980,7 +978,8 @@ static int aha152x_internal_queue(struct scsi_cmnd *SCpnt, static int aha152x_queue_lck(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *)) { - return aha152x_internal_queue(SCpnt, NULL, 0, done); + WARN_ON_ONCE(done != scsi_done); + return aha152x_internal_queue(SCpnt, NULL, 0); } static DEF_SCSI_QCMD(aha152x_queue) @@ -998,6 +997,14 @@ static void reset_done(struct scsi_cmnd *SCpnt) } } +static void aha152x_scsi_done(struct scsi_cmnd *SCpnt) +{ + if (SCpnt->SCp.phase & resetting) + reset_done(SCpnt); + else + scsi_done(SCpnt); +} + /* * Abort a command * @@ -1064,7 +1071,7 @@ static int aha152x_device_reset(struct scsi_cmnd * SCpnt) SCpnt->cmd_len = 0; - aha152x_internal_queue(SCpnt, &done, resetting, reset_done); + aha152x_internal_queue(SCpnt, &done, resetting); timeleft = wait_for_completion_timeout(&done, 100*HZ); if (!timeleft) { @@ -1439,12 +1446,12 @@ static void busfree_run(struct Scsi_Host *shpnt) scsi_eh_prep_cmnd(ptr, &sc->ses, NULL, 0, ~0); DO_UNLOCK(flags); - aha152x_internal_queue(ptr, NULL, check_condition, ptr->scsi_done); + aha152x_internal_queue(ptr, NULL, check_condition); DO_LOCK(flags); } } - if(DONE_SC && DONE_SC->scsi_done) { + if (DONE_SC) { struct scsi_cmnd *ptr = DONE_SC; DONE_SC=NULL; @@ -1453,13 +1460,13 @@ static void busfree_run(struct Scsi_Host *shpnt) if (!HOSTDATA(shpnt)->commands) SETPORT(PORTA, 0); /* turn led off */ - if(ptr->scsi_done != reset_done) { + if (!(ptr->SCp.phase & resetting)) { kfree(ptr->host_scribble); ptr->host_scribble=NULL; } DO_UNLOCK(flags); - ptr->scsi_done(ptr); + aha152x_scsi_done(ptr); DO_LOCK(flags); } @@ -2258,7 +2265,7 @@ static void rsti_run(struct Scsi_Host *shpnt) ptr->host_scribble=NULL; set_host_byte(ptr, DID_RESET); - ptr->scsi_done(ptr); + aha152x_scsi_done(ptr); } ptr = next; From 135223527c810b65c2ab9e64fa81bfd87feb051d Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 7 Oct 2021 13:28:15 -0700 Subject: [PATCH 130/279] scsi: aha1542: Call scsi_done() directly Conditional statements are faster than indirect calls. Hence call scsi_done() directly. Link: https://lore.kernel.org/r/20211007202923.2174984-21-bvanassche@acm.org Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/aha1542.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/drivers/scsi/aha1542.c b/drivers/scsi/aha1542.c index 584a59522038..8697f4720946 100644 --- a/drivers/scsi/aha1542.c +++ b/drivers/scsi/aha1542.c @@ -281,7 +281,6 @@ static irqreturn_t aha1542_interrupt(int irq, void *dev_id) { struct Scsi_Host *sh = dev_id; struct aha1542_hostdata *aha1542 = shost_priv(sh); - void (*my_done)(struct scsi_cmnd *) = NULL; int errstatus, mbi, mbo, mbistatus; int number_serviced; unsigned long flags; @@ -369,14 +368,13 @@ static irqreturn_t aha1542_interrupt(int irq, void *dev_id) tmp_cmd = aha1542->int_cmds[mbo]; - if (!tmp_cmd || !tmp_cmd->scsi_done) { + if (!tmp_cmd) { spin_unlock_irqrestore(sh->host_lock, flags); shost_printk(KERN_WARNING, sh, "Unexpected interrupt\n"); shost_printk(KERN_WARNING, sh, "tarstat=%x, hastat=%x idlun=%x ccb#=%d\n", ccb[mbo].tarstat, ccb[mbo].hastat, ccb[mbo].idlun, mbo); return IRQ_HANDLED; } - my_done = tmp_cmd->scsi_done; aha1542_free_cmd(tmp_cmd); /* * Fetch the sense data, and tuck it away, in the required slot. The @@ -410,7 +408,7 @@ static irqreturn_t aha1542_interrupt(int irq, void *dev_id) aha1542->int_cmds[mbo] = NULL; /* This effectively frees up the mailbox slot, as * far as queuecommand is concerned */ - my_done(tmp_cmd); + scsi_done(tmp_cmd); number_serviced++; }; } @@ -431,7 +429,7 @@ static int aha1542_queuecommand(struct Scsi_Host *sh, struct scsi_cmnd *cmd) if (*cmd->cmnd == REQUEST_SENSE) { /* Don't do the command - we have the sense data already */ cmd->result = 0; - cmd->scsi_done(cmd); + scsi_done(cmd); return 0; } #ifdef DEBUG @@ -488,7 +486,7 @@ static int aha1542_queuecommand(struct Scsi_Host *sh, struct scsi_cmnd *cmd) aha1542->aha1542_last_mbo_used = mbo; #ifdef DEBUG - shost_printk(KERN_DEBUG, sh, "Sending command (%d %p)...", mbo, cmd->scsi_done); + shost_printk(KERN_DEBUG, sh, "Sending command (%d)...", mbo); #endif /* This gets trashed for some reason */ From 07ebbc3a806701d1d639d94b79cf4df54e4f407e Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 7 Oct 2021 13:28:16 -0700 Subject: [PATCH 131/279] scsi: aic7xxx: Call scsi_done() directly Conditional statements are faster than indirect calls. Hence call scsi_done() directly. Link: https://lore.kernel.org/r/20211007202923.2174984-22-bvanassche@acm.org Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/aic7xxx/aic79xx_osm.c | 3 +-- drivers/scsi/aic7xxx/aic7xxx_osm.c | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/scsi/aic7xxx/aic79xx_osm.c b/drivers/scsi/aic7xxx/aic79xx_osm.c index 92ea24a075b8..af49c32cfaf7 100644 --- a/drivers/scsi/aic7xxx/aic79xx_osm.c +++ b/drivers/scsi/aic7xxx/aic79xx_osm.c @@ -581,7 +581,6 @@ ahd_linux_queue_lck(struct scsi_cmnd * cmd, void (*scsi_done) (struct scsi_cmnd ahd = *(struct ahd_softc **)cmd->device->host->hostdata; - cmd->scsi_done = scsi_done; cmd->result = CAM_REQ_INPROG << 16; rtn = ahd_linux_run_command(ahd, dev, cmd); @@ -2111,7 +2110,7 @@ ahd_linux_queue_cmd_complete(struct ahd_softc *ahd, struct scsi_cmnd *cmd) ahd_cmd_set_transaction_status(cmd, new_status); - cmd->scsi_done(cmd); + scsi_done(cmd); } static void diff --git a/drivers/scsi/aic7xxx/aic7xxx_osm.c b/drivers/scsi/aic7xxx/aic7xxx_osm.c index 8b3d472aa3cc..f2daca41f3f2 100644 --- a/drivers/scsi/aic7xxx/aic7xxx_osm.c +++ b/drivers/scsi/aic7xxx/aic7xxx_osm.c @@ -530,7 +530,6 @@ ahc_linux_queue_lck(struct scsi_cmnd * cmd, void (*scsi_done) (struct scsi_cmnd ahc_lock(ahc, &flags); if (ahc->platform_data->qfrozen == 0) { - cmd->scsi_done = scsi_done; cmd->result = CAM_REQ_INPROG << 16; rtn = ahc_linux_run_command(ahc, dev, cmd); } @@ -1986,7 +1985,7 @@ ahc_linux_queue_cmd_complete(struct ahc_softc *ahc, struct scsi_cmnd *cmd) ahc_cmd_set_transaction_status(cmd, new_status); } - cmd->scsi_done(cmd); + scsi_done(cmd); } static void From 3f0b59b6852d69a27c7c32cfd8c78b26a8207d0a Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 7 Oct 2021 13:28:17 -0700 Subject: [PATCH 132/279] scsi: arcmsr: Call scsi_done() directly Conditional statements are faster than indirect calls. Hence call scsi_done() directly. Link: https://lore.kernel.org/r/20211007202923.2174984-23-bvanassche@acm.org Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/arcmsr/arcmsr_hba.c | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/drivers/scsi/arcmsr/arcmsr_hba.c b/drivers/scsi/arcmsr/arcmsr_hba.c index ec1a834c922d..e2692ca87a6e 100644 --- a/drivers/scsi/arcmsr/arcmsr_hba.c +++ b/drivers/scsi/arcmsr/arcmsr_hba.c @@ -1318,7 +1318,7 @@ static void arcmsr_ccb_complete(struct CommandControlBlock *ccb) spin_lock_irqsave(&acb->ccblist_lock, flags); list_add_tail(&ccb->list, &acb->ccb_free_list); spin_unlock_irqrestore(&acb->ccblist_lock, flags); - pcmd->scsi_done(pcmd); + scsi_done(pcmd); } static void arcmsr_report_sense_info(struct CommandControlBlock *ccb) @@ -1598,7 +1598,7 @@ static void arcmsr_remove_scsi_devices(struct AdapterControlBlock *acb) if (ccb->startdone == ARCMSR_CCB_START) { ccb->pcmd->result = DID_NO_CONNECT << 16; arcmsr_pci_unmap_dma(ccb); - ccb->pcmd->scsi_done(ccb->pcmd); + scsi_done(ccb->pcmd); } } for (target = 0; target < ARCMSR_MAX_TARGETID; target++) { @@ -3192,7 +3192,7 @@ static void arcmsr_handle_virtual_command(struct AdapterControlBlock *acb, if (cmd->device->lun) { cmd->result = (DID_TIME_OUT << 16); - cmd->scsi_done(cmd); + scsi_done(cmd); return; } inqdata[0] = TYPE_PROCESSOR; @@ -3216,18 +3216,18 @@ static void arcmsr_handle_virtual_command(struct AdapterControlBlock *acb, sg = scsi_sglist(cmd); kunmap_atomic(buffer - sg->offset); - cmd->scsi_done(cmd); + scsi_done(cmd); } break; case WRITE_BUFFER: case READ_BUFFER: { if (arcmsr_iop_message_xfer(acb, cmd)) cmd->result = (DID_ERROR << 16); - cmd->scsi_done(cmd); + scsi_done(cmd); } break; default: - cmd->scsi_done(cmd); + scsi_done(cmd); } } @@ -3241,10 +3241,9 @@ static int arcmsr_queue_command_lck(struct scsi_cmnd *cmd, if (acb->acb_flags & ACB_F_ADAPTER_REMOVED) { cmd->result = (DID_NO_CONNECT << 16); - cmd->scsi_done(cmd); + scsi_done(cmd); return 0; } - cmd->scsi_done = done; cmd->host_scribble = NULL; cmd->result = 0; if (target == 16) { @@ -3257,7 +3256,7 @@ static int arcmsr_queue_command_lck(struct scsi_cmnd *cmd, return SCSI_MLQUEUE_HOST_BUSY; if (arcmsr_build_ccb( acb, ccb, cmd ) == FAILED) { cmd->result = (DID_ERROR << 16) | SAM_STAT_RESERVATION_CONFLICT; - cmd->scsi_done(cmd); + scsi_done(cmd); return 0; } arcmsr_post_ccb(acb, ccb); From 681fa5252fd4ba4d9fa77218c56c7ce9e411d72c Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 7 Oct 2021 13:28:18 -0700 Subject: [PATCH 133/279] scsi: atp870u: Call scsi_done() directly Conditional statements are faster than indirect calls. Hence call scsi_done() directly. Link: https://lore.kernel.org/r/20211007202923.2174984-24-bvanassche@acm.org Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/atp870u.c | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/drivers/scsi/atp870u.c b/drivers/scsi/atp870u.c index 9d179cd15bb8..6e1595b32bc0 100644 --- a/drivers/scsi/atp870u.c +++ b/drivers/scsi/atp870u.c @@ -512,7 +512,7 @@ static irqreturn_t atp870u_intr_handle(int irq, void *dev_id) scsi_dma_unmap(workreq); spin_lock_irqsave(dev->host->host_lock, flags); - (*workreq->scsi_done) (workreq); + scsi_done(workreq); #ifdef ED_DBGP printk("workreq->scsi_done\n"); #endif @@ -654,17 +654,6 @@ static int atp870u_queuecommand_lck(struct scsi_cmnd *req_p, return 0; } - if (done) { - req_p->scsi_done = done; - } else { -#ifdef ED_DBGP - printk( "atp870u_queuecommand: done can't be NULL\n"); -#endif - req_p->result = 0; - done(req_p); - return 0; - } - /* * Count new command */ From 4316b5b8b2c69d7d2f526ee5659b00ecb0abacbe Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 7 Oct 2021 13:28:19 -0700 Subject: [PATCH 134/279] scsi: bfa: Call scsi_done() directly Conditional statements are faster than indirect calls. Hence call scsi_done() directly. Link: https://lore.kernel.org/r/20211007202923.2174984-25-bvanassche@acm.org Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/bfa/bfad_im.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/drivers/scsi/bfa/bfad_im.c b/drivers/scsi/bfa/bfad_im.c index 6b5841b1c06e..e12ae60efd33 100644 --- a/drivers/scsi/bfa/bfad_im.c +++ b/drivers/scsi/bfa/bfad_im.c @@ -96,7 +96,7 @@ bfa_cb_ioim_done(void *drv, struct bfad_ioim_s *dio, } } - cmnd->scsi_done(cmnd); + scsi_done(cmnd); } void @@ -124,7 +124,7 @@ bfa_cb_ioim_good_comp(void *drv, struct bfad_ioim_s *dio) } } - cmnd->scsi_done(cmnd); + scsi_done(cmnd); } void @@ -226,7 +226,7 @@ bfad_im_abort_handler(struct scsi_cmnd *cmnd) timeout *= 2; } - cmnd->scsi_done(cmnd); + scsi_done(cmnd); bfa_trc(bfad, hal_io->iotag); BFA_LOG(KERN_INFO, bfad, bfa_log_level, "scsi%d: complete abort 0x%p iotag 0x%x\n", @@ -1233,8 +1233,6 @@ bfad_im_queuecommand_lck(struct scsi_cmnd *cmnd, void (*done) (struct scsi_cmnd if (sg_cnt < 0) return SCSI_MLQUEUE_HOST_BUSY; - cmnd->scsi_done = done; - spin_lock_irqsave(&bfad->bfad_lock, flags); if (!(bfad->bfad_flags & BFAD_HAL_START_DONE)) { printk(KERN_WARNING From a75af82a77d235f479f7675f60c74def0d35c7a2 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 7 Oct 2021 13:28:20 -0700 Subject: [PATCH 135/279] scsi: bnx2fc: Call scsi_done() directly Conditional statements are faster than indirect calls. Hence call scsi_done() directly. Link: https://lore.kernel.org/r/20211007202923.2174984-26-bvanassche@acm.org Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/bnx2fc/bnx2fc_io.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/scsi/bnx2fc/bnx2fc_io.c b/drivers/scsi/bnx2fc/bnx2fc_io.c index f2996a9b2f63..b9114113ee73 100644 --- a/drivers/scsi/bnx2fc/bnx2fc_io.c +++ b/drivers/scsi/bnx2fc/bnx2fc_io.c @@ -205,7 +205,7 @@ static void bnx2fc_scsi_done(struct bnx2fc_cmd *io_req, int err_code) sc_cmd->allowed); scsi_set_resid(sc_cmd, scsi_bufflen(sc_cmd)); sc_cmd->SCp.ptr = NULL; - sc_cmd->scsi_done(sc_cmd); + scsi_done(sc_cmd); } struct bnx2fc_cmd_mgr *bnx2fc_cmd_mgr_alloc(struct bnx2fc_hba *hba) @@ -1610,7 +1610,7 @@ void bnx2fc_process_tm_compl(struct bnx2fc_cmd *io_req, } sc_cmd->SCp.ptr = NULL; - sc_cmd->scsi_done(sc_cmd); + scsi_done(sc_cmd); kref_put(&io_req->refcount, bnx2fc_cmd_release); if (io_req->wait_for_abts_comp) { @@ -1853,7 +1853,7 @@ int bnx2fc_queuecommand(struct Scsi_Host *host, rval = fc_remote_port_chkready(rport); if (rval) { sc_cmd->result = rval; - sc_cmd->scsi_done(sc_cmd); + scsi_done(sc_cmd); return 0; } @@ -2019,7 +2019,7 @@ void bnx2fc_process_scsi_cmd_compl(struct bnx2fc_cmd *io_req, break; } sc_cmd->SCp.ptr = NULL; - sc_cmd->scsi_done(sc_cmd); + scsi_done(sc_cmd); kref_put(&io_req->refcount, bnx2fc_cmd_release); } From 0979e265e4b7e454dd240063d06d0444fb8d3259 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 7 Oct 2021 13:28:21 -0700 Subject: [PATCH 136/279] scsi: csiostor: Call scsi_done() directly Conditional statements are faster than indirect calls. Hence call scsi_done() directly. Link: https://lore.kernel.org/r/20211007202923.2174984-27-bvanassche@acm.org Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/csiostor/csio_scsi.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/scsi/csiostor/csio_scsi.c b/drivers/scsi/csiostor/csio_scsi.c index 3b2eb6ce1fcf..3978c3d7eed5 100644 --- a/drivers/scsi/csiostor/csio_scsi.c +++ b/drivers/scsi/csiostor/csio_scsi.c @@ -1720,7 +1720,7 @@ out: } cmnd->result = (((host_status) << 16) | scsi_status); - cmnd->scsi_done(cmnd); + scsi_done(cmnd); /* Wake up waiting threads */ csio_scsi_cmnd(req) = NULL; @@ -1748,7 +1748,7 @@ csio_scsi_cbfn(struct csio_hw *hw, struct csio_ioreq *req) } cmnd->result = (((host_status) << 16) | scsi_status); - cmnd->scsi_done(cmnd); + scsi_done(cmnd); csio_scsi_cmnd(req) = NULL; CSIO_INC_STATS(csio_hw_to_scsim(hw), n_tot_success); } else { @@ -1876,7 +1876,7 @@ err: return rv; err_done: - cmnd->scsi_done(cmnd); + scsi_done(cmnd); return 0; } @@ -1979,7 +1979,7 @@ inval_scmnd: spin_unlock_irq(&hw->lock); cmnd->result = (DID_ERROR << 16); - cmnd->scsi_done(cmnd); + scsi_done(cmnd); return FAILED; } From e82d6b179b142411c19a65bed881e148dc79bfa6 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 7 Oct 2021 13:28:22 -0700 Subject: [PATCH 137/279] scsi: cxlflash: Call scsi_done() directly Conditional statements are faster than indirect calls. Hence call scsi_done() directly. Link: https://lore.kernel.org/r/20211007202923.2174984-28-bvanassche@acm.org Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/cxlflash/main.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/scsi/cxlflash/main.c b/drivers/scsi/cxlflash/main.c index b2730e859df8..2943cdd83614 100644 --- a/drivers/scsi/cxlflash/main.c +++ b/drivers/scsi/cxlflash/main.c @@ -171,7 +171,7 @@ static void cmd_complete(struct afu_cmd *cmd) dev_dbg_ratelimited(dev, "%s:scp=%p result=%08x ioasc=%08x\n", __func__, scp, scp->result, cmd->sa.ioasc); - scp->scsi_done(scp); + scsi_done(scp); } else if (cmd->cmd_tmf) { spin_lock_irqsave(&cfg->tmf_slock, lock_flags); cfg->tmf_active = false; @@ -205,7 +205,7 @@ static void flush_pending_cmds(struct hwq *hwq) if (cmd->scp) { scp = cmd->scp; scp->result = (DID_IMM_RETRY << 16); - scp->scsi_done(scp); + scsi_done(scp); } else { cmd->cmd_aborted = true; @@ -601,7 +601,7 @@ static int cxlflash_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *scp) case STATE_FAILTERM: dev_dbg_ratelimited(dev, "%s: device has failed\n", __func__); scp->result = (DID_NO_CONNECT << 16); - scp->scsi_done(scp); + scsi_done(scp); rc = 0; goto out; default: From 6c365b880093d6f8c2061beb7db6f4b60d31c1ee Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 7 Oct 2021 13:28:23 -0700 Subject: [PATCH 138/279] scsi: dc395x: Call scsi_done() directly Conditional statements are faster than indirect calls. Hence call scsi_done() directly. Link: https://lore.kernel.org/r/20211007202923.2174984-29-bvanassche@acm.org Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/dc395x.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/drivers/scsi/dc395x.c b/drivers/scsi/dc395x.c index 1c79e6c27163..5adbc7f61c19 100644 --- a/drivers/scsi/dc395x.c +++ b/drivers/scsi/dc395x.c @@ -995,8 +995,6 @@ static int dc395x_queue_command_lck(struct scsi_cmnd *cmd, void (*done)(struct s goto complete; } - /* set callback and clear result in the command */ - cmd->scsi_done = done; set_host_byte(cmd, DID_OK); set_status_byte(cmd, SAM_STAT_GOOD); @@ -3336,7 +3334,7 @@ static void srb_done(struct AdapterCtlBlk *acb, struct DeviceCtlBlk *dcb, dprintkl(KERN_ERR, "srb_done: ERROR! Completed cmd with tmp_srb\n"); } - cmd->scsi_done(cmd); + scsi_done(cmd); waiting_process_next(acb); } @@ -3367,7 +3365,7 @@ static void doing_srb_done(struct AdapterCtlBlk *acb, u8 did_flag, if (force) { /* For new EH, we normally don't need to give commands back, * as they all complete or all time out */ - p->scsi_done(p); + scsi_done(p); } } if (!list_empty(&dcb->srb_going_list)) @@ -3394,7 +3392,7 @@ static void doing_srb_done(struct AdapterCtlBlk *acb, u8 did_flag, if (force) { /* For new EH, we normally don't need to give commands back, * as they all complete or all time out */ - cmd->scsi_done(cmd); + scsi_done(cmd); } } if (!list_empty(&dcb->srb_waiting_list)) From e6ed928effb6d516272fe47b2bf0b4ba9e6a0143 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 7 Oct 2021 13:28:24 -0700 Subject: [PATCH 139/279] scsi: dpt_i2o: Call scsi_done() directly Conditional statements are faster than indirect calls. Hence call scsi_done() directly. Link: https://lore.kernel.org/r/20211007202923.2174984-30-bvanassche@acm.org Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/dpt_i2o.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/drivers/scsi/dpt_i2o.c b/drivers/scsi/dpt_i2o.c index 7af96d14c9bc..1f00afcfe440 100644 --- a/drivers/scsi/dpt_i2o.c +++ b/drivers/scsi/dpt_i2o.c @@ -421,7 +421,6 @@ static int adpt_queue_lck(struct scsi_cmnd * cmd, void (*done) (struct scsi_cmnd adpt_hba* pHba = NULL; struct adpt_device* pDev = NULL; /* dpt per device information */ - cmd->scsi_done = done; /* * SCSI REQUEST_SENSE commands will be executed automatically by the * Host Adapter for any errors, so they should not be executed @@ -431,7 +430,7 @@ static int adpt_queue_lck(struct scsi_cmnd * cmd, void (*done) (struct scsi_cmnd if ((cmd->cmnd[0] == REQUEST_SENSE) && (cmd->sense_buffer[0] != 0)) { cmd->result = (DID_OK << 16); - cmd->scsi_done(cmd); + scsi_done(cmd); return 0; } @@ -456,7 +455,7 @@ static int adpt_queue_lck(struct scsi_cmnd * cmd, void (*done) (struct scsi_cmnd // TODO: if any luns are at this bus, scsi id then fake a TEST_UNIT_READY and INQUIRY response // with type 7F (for all luns less than the max for this bus,id) so the lun scan will continue. cmd->result = (DID_NO_CONNECT << 16); - cmd->scsi_done(cmd); + scsi_done(cmd); return 0; } cmd->device->hostdata = pDev; @@ -2227,7 +2226,7 @@ static s32 adpt_scsi_to_i2o(adpt_hba* pHba, struct scsi_cmnd* cmd, struct adpt_d printk(KERN_WARNING"%s: scsi opcode 0x%x not supported.\n", pHba->name, cmd->cmnd[0]); cmd->result = (DID_ERROR <<16); - cmd->scsi_done(cmd); + scsi_done(cmd); return 0; } } @@ -2451,9 +2450,7 @@ static void adpt_i2o_scsi_complete(void __iomem *reply, struct scsi_cmnd *cmd) cmd->result |= (dev_status); - if(cmd->scsi_done != NULL){ - cmd->scsi_done(cmd); - } + scsi_done(cmd); } From 52e65d1c25a6f22f08934878df737a6239f22d48 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 7 Oct 2021 13:28:25 -0700 Subject: [PATCH 140/279] scsi: esas2r: Call scsi_done() directly Conditional statements are faster than indirect calls. Hence call scsi_done() directly. Link: https://lore.kernel.org/r/20211007202923.2174984-31-bvanassche@acm.org Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/esas2r/esas2r_main.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/scsi/esas2r/esas2r_main.c b/drivers/scsi/esas2r/esas2r_main.c index 647f82898b6e..7a4eadad23d7 100644 --- a/drivers/scsi/esas2r/esas2r_main.c +++ b/drivers/scsi/esas2r/esas2r_main.c @@ -828,7 +828,7 @@ int esas2r_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd) if (unlikely(test_bit(AF_DEGRADED_MODE, &a->flags))) { cmd->result = DID_NO_CONNECT << 16; - cmd->scsi_done(cmd); + scsi_done(cmd); return 0; } @@ -988,7 +988,7 @@ int esas2r_eh_abort(struct scsi_cmnd *cmd) scsi_set_resid(cmd, 0); - cmd->scsi_done(cmd); + scsi_done(cmd); return SUCCESS; } @@ -1054,7 +1054,7 @@ check_active_queue: scsi_set_resid(cmd, 0); - cmd->scsi_done(cmd); + scsi_done(cmd); return SUCCESS; } @@ -1535,7 +1535,7 @@ void esas2r_complete_request_cb(struct esas2r_adapter *a, scsi_set_resid(rq->cmd, 0); } - rq->cmd->scsi_done(rq->cmd); + scsi_done(rq->cmd); esas2r_free_request(a, rq); } From f8ab27d9649440a4fa6e77bbea939a62fd44df27 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 7 Oct 2021 13:28:26 -0700 Subject: [PATCH 141/279] scsi: esp_scsi: Call scsi_done() directly Conditional statements are faster than indirect calls. Hence call scsi_done() directly. Link: https://lore.kernel.org/r/20211007202923.2174984-32-bvanassche@acm.org Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/esp_scsi.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/drivers/scsi/esp_scsi.c b/drivers/scsi/esp_scsi.c index 9a8c037a2f21..f7c2d64f1cef 100644 --- a/drivers/scsi/esp_scsi.c +++ b/drivers/scsi/esp_scsi.c @@ -936,7 +936,7 @@ static void esp_cmd_is_done(struct esp *esp, struct esp_cmd_entry *ent, } } - cmd->scsi_done(cmd); + scsi_done(cmd); list_del(&ent->list); esp_put_ent(esp, ent); @@ -965,8 +965,6 @@ static int esp_queuecommand_lck(struct scsi_cmnd *cmd, void (*done)(struct scsi_ ent->cmd = cmd; - cmd->scsi_done = done; - spriv = ESP_CMD_PRIV(cmd); spriv->num_sg = 0; @@ -2038,7 +2036,7 @@ static void esp_reset_cleanup_one(struct esp *esp, struct esp_cmd_entry *ent) if (ent->flags & ESP_CMD_FLAG_AUTOSENSE) esp_unmap_sense(esp, ent); - cmd->scsi_done(cmd); + scsi_done(cmd); list_del(&ent->list); esp_put_ent(esp, ent); } @@ -2061,7 +2059,7 @@ static void esp_reset_cleanup(struct esp *esp) list_del(&ent->list); cmd->result = DID_RESET << 16; - cmd->scsi_done(cmd); + scsi_done(cmd); esp_put_ent(esp, ent); } @@ -2535,7 +2533,7 @@ static int esp_eh_abort_handler(struct scsi_cmnd *cmd) list_del(&ent->list); cmd->result = DID_ABORT << 16; - cmd->scsi_done(cmd); + scsi_done(cmd); esp_put_ent(esp, ent); From caffd3ad966e2b47227e7f375287737a9f53cbf0 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 7 Oct 2021 13:28:27 -0700 Subject: [PATCH 142/279] scsi: fas216: Introduce struct fas216_cmd_priv Introduce a structure with driver-private data per SCSI command. This data structure will be used by the next patch to store a function pointer. Link: https://lore.kernel.org/r/20211007202923.2174984-33-bvanassche@acm.org Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/arm/arxescsi.c | 1 + drivers/scsi/arm/cumana_2.c | 1 + drivers/scsi/arm/eesox.c | 1 + drivers/scsi/arm/fas216.h | 10 ++++++++++ drivers/scsi/arm/powertec.c | 2 +- 5 files changed, 14 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/arm/arxescsi.c b/drivers/scsi/arm/arxescsi.c index 591414120754..7f667c198f6d 100644 --- a/drivers/scsi/arm/arxescsi.c +++ b/drivers/scsi/arm/arxescsi.c @@ -243,6 +243,7 @@ static struct scsi_host_template arxescsi_template = { .eh_bus_reset_handler = fas216_eh_bus_reset, .eh_device_reset_handler = fas216_eh_device_reset, .eh_abort_handler = fas216_eh_abort, + .cmd_size = sizeof(struct fas216_cmd_priv), .can_queue = 0, .this_id = 7, .sg_tablesize = SG_ALL, diff --git a/drivers/scsi/arm/cumana_2.c b/drivers/scsi/arm/cumana_2.c index 9dcd912267e6..3c00d7773876 100644 --- a/drivers/scsi/arm/cumana_2.c +++ b/drivers/scsi/arm/cumana_2.c @@ -363,6 +363,7 @@ static struct scsi_host_template cumanascsi2_template = { .eh_bus_reset_handler = fas216_eh_bus_reset, .eh_device_reset_handler = fas216_eh_device_reset, .eh_abort_handler = fas216_eh_abort, + .cmd_size = sizeof(struct fas216_cmd_priv), .can_queue = 1, .this_id = 7, .sg_tablesize = SG_MAX_SEGMENTS, diff --git a/drivers/scsi/arm/eesox.c b/drivers/scsi/arm/eesox.c index 5eb2415dda9d..1394590eecea 100644 --- a/drivers/scsi/arm/eesox.c +++ b/drivers/scsi/arm/eesox.c @@ -480,6 +480,7 @@ static struct scsi_host_template eesox_template = { .eh_bus_reset_handler = fas216_eh_bus_reset, .eh_device_reset_handler = fas216_eh_device_reset, .eh_abort_handler = fas216_eh_abort, + .cmd_size = sizeof(struct fas216_cmd_priv), .can_queue = 1, .this_id = 7, .sg_tablesize = SG_MAX_SEGMENTS, diff --git a/drivers/scsi/arm/fas216.h b/drivers/scsi/arm/fas216.h index 847413ce14cf..abf960487314 100644 --- a/drivers/scsi/arm/fas216.h +++ b/drivers/scsi/arm/fas216.h @@ -310,6 +310,16 @@ typedef struct { unsigned long magic_end; } FAS216_Info; +/* driver-private data per SCSI command. */ +struct fas216_cmd_priv { + void (*scsi_done)(struct scsi_cmnd *cmd); +}; + +static inline struct fas216_cmd_priv *fas216_cmd_priv(struct scsi_cmnd *cmd) +{ + return scsi_cmd_priv(cmd); +} + /* Function: int fas216_init (struct Scsi_Host *instance) * Purpose : initialise FAS/NCR/AMD SCSI structures. * Params : instance - a driver-specific filled-out structure diff --git a/drivers/scsi/arm/powertec.c b/drivers/scsi/arm/powertec.c index 9cc73da4e876..8fec435cee18 100644 --- a/drivers/scsi/arm/powertec.c +++ b/drivers/scsi/arm/powertec.c @@ -286,7 +286,7 @@ static struct scsi_host_template powertecscsi_template = { .eh_bus_reset_handler = fas216_eh_bus_reset, .eh_device_reset_handler = fas216_eh_device_reset, .eh_abort_handler = fas216_eh_abort, - + .cmd_size = sizeof(struct fas216_cmd_priv), .can_queue = 8, .this_id = 7, .sg_tablesize = SG_MAX_SEGMENTS, From 696fec18e17cb63d480e29aafc39d273bd9b776d Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 7 Oct 2021 13:28:28 -0700 Subject: [PATCH 143/279] scsi: fas216: Stop using scsi_cmnd.scsi_done Store the completion callback pointer in struct fas216_cmd_priv instead of in struct scsi_cmnd. This patch prepares for removal of the scsi_done member from struct scsi_cmnd. Link: https://lore.kernel.org/r/20211007202923.2174984-34-bvanassche@acm.org Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/arm/fas216.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/scsi/arm/fas216.c b/drivers/scsi/arm/fas216.c index cf71ef488e36..91c03bde310b 100644 --- a/drivers/scsi/arm/fas216.c +++ b/drivers/scsi/arm/fas216.c @@ -2015,7 +2015,7 @@ static void fas216_rq_sns_done(FAS216_Info *info, struct scsi_cmnd *SCpnt, * correctly by fas216_std_done. */ scsi_eh_restore_cmnd(SCpnt, &info->ses); - SCpnt->scsi_done(SCpnt); + fas216_cmd_priv(SCpnt)->scsi_done(SCpnt); } /** @@ -2086,8 +2086,8 @@ fas216_std_done(FAS216_Info *info, struct scsi_cmnd *SCpnt, unsigned int result) } done: - if (SCpnt->scsi_done) { - SCpnt->scsi_done(SCpnt); + if (fas216_cmd_priv(SCpnt)->scsi_done) { + fas216_cmd_priv(SCpnt)->scsi_done(SCpnt); return; } @@ -2203,7 +2203,7 @@ static int fas216_queue_command_lck(struct scsi_cmnd *SCpnt, fas216_log_command(info, LOG_CONNECT, SCpnt, "received command (%p)", SCpnt); - SCpnt->scsi_done = done; + fas216_cmd_priv(SCpnt)->scsi_done = done; SCpnt->host_scribble = (void *)fas216_std_done; SCpnt->result = 0; From a0c22474cbc64ba7099595151f97b33bdfdc5ff3 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 7 Oct 2021 13:28:29 -0700 Subject: [PATCH 144/279] scsi: fdomain: Call scsi_done() directly Conditional statements are faster than indirect calls. Hence call scsi_done() directly. Link: https://lore.kernel.org/r/20211007202923.2174984-35-bvanassche@acm.org Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/fdomain.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/fdomain.c b/drivers/scsi/fdomain.c index eda2be534aa7..9159b4057c5d 100644 --- a/drivers/scsi/fdomain.c +++ b/drivers/scsi/fdomain.c @@ -206,7 +206,7 @@ static void fdomain_finish_cmd(struct fdomain *fd) { outb(0, fd->base + REG_ICTL); fdomain_make_bus_idle(fd); - fd->cur_cmd->scsi_done(fd->cur_cmd); + scsi_done(fd->cur_cmd); fd->cur_cmd = NULL; } From a7510fbd879e98baf2848b4646adbbd2b9d0fbb3 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 7 Oct 2021 13:28:30 -0700 Subject: [PATCH 145/279] scsi: fnic: Call scsi_done() directly Conditional statements are faster than indirect calls. Hence call scsi_done() directly. Link: https://lore.kernel.org/r/20211007202923.2174984-36-bvanassche@acm.org Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/fnic/fnic_scsi.c | 115 +++++++++++++++------------------- 1 file changed, 52 insertions(+), 63 deletions(-) diff --git a/drivers/scsi/fnic/fnic_scsi.c b/drivers/scsi/fnic/fnic_scsi.c index f8afbfb468dc..09b8bf5adaf5 100644 --- a/drivers/scsi/fnic/fnic_scsi.c +++ b/drivers/scsi/fnic/fnic_scsi.c @@ -560,7 +560,6 @@ static int fnic_queuecommand_lck(struct scsi_cmnd *sc, void (*done)(struct scsi_ CMD_STATE(sc) = FNIC_IOREQ_CMD_PENDING; CMD_SP(sc) = (char *)io_req; CMD_FLAGS(sc) |= FNIC_IO_INITIALIZED; - sc->scsi_done = done; /* create copy wq desc and enqueue it */ wq = &fnic->wq_copy[0]; @@ -1051,8 +1050,7 @@ static void fnic_fcpio_icmnd_cmpl_handler(struct fnic *fnic, } /* Call SCSI completion function to complete the IO */ - if (sc->scsi_done) - sc->scsi_done(sc); + scsi_done(sc); } /* fnic_fcpio_itmf_cmpl_handler @@ -1193,28 +1191,25 @@ static void fnic_fcpio_itmf_cmpl_handler(struct fnic *fnic, fnic_release_ioreq_buf(fnic, io_req, sc); mempool_free(io_req, fnic->io_req_pool); - if (sc->scsi_done) { - FNIC_TRACE(fnic_fcpio_itmf_cmpl_handler, - sc->device->host->host_no, id, - sc, - jiffies_to_msecs(jiffies - start_time), - desc, - (((u64)hdr_status << 40) | - (u64)sc->cmnd[0] << 32 | - (u64)sc->cmnd[2] << 24 | - (u64)sc->cmnd[3] << 16 | - (u64)sc->cmnd[4] << 8 | sc->cmnd[5]), - (((u64)CMD_FLAGS(sc) << 32) | - CMD_STATE(sc))); - sc->scsi_done(sc); - atomic64_dec(&fnic_stats->io_stats.active_ios); - if (atomic64_read(&fnic->io_cmpl_skip)) - atomic64_dec(&fnic->io_cmpl_skip); - else - atomic64_inc(&fnic_stats->io_stats.io_completions); - } + FNIC_TRACE(fnic_fcpio_itmf_cmpl_handler, + sc->device->host->host_no, id, + sc, + jiffies_to_msecs(jiffies - start_time), + desc, + (((u64)hdr_status << 40) | + (u64)sc->cmnd[0] << 32 | + (u64)sc->cmnd[2] << 24 | + (u64)sc->cmnd[3] << 16 | + (u64)sc->cmnd[4] << 8 | sc->cmnd[5]), + (((u64)CMD_FLAGS(sc) << 32) | + CMD_STATE(sc))); + scsi_done(sc); + atomic64_dec(&fnic_stats->io_stats.active_ios); + if (atomic64_read(&fnic->io_cmpl_skip)) + atomic64_dec(&fnic->io_cmpl_skip); + else + atomic64_inc(&fnic_stats->io_stats.io_completions); } - } else if (id & FNIC_TAG_DEV_RST) { /* Completion of device reset */ CMD_LR_STATUS(sc) = hdr_status; @@ -1421,23 +1416,22 @@ cleanup_scsi_cmd: atomic64_inc(&fnic_stats->io_stats.io_completions); /* Complete the command to SCSI */ - if (sc->scsi_done) { - if (!(CMD_FLAGS(sc) & FNIC_IO_ISSUED)) - shost_printk(KERN_ERR, fnic->lport->host, - "Calling done for IO not issued to fw: tag:0x%x sc:0x%p\n", - tag, sc); + if (!(CMD_FLAGS(sc) & FNIC_IO_ISSUED)) + shost_printk(KERN_ERR, fnic->lport->host, + "Calling done for IO not issued to fw: tag:0x%x sc:0x%p\n", + tag, sc); - FNIC_TRACE(fnic_cleanup_io, - sc->device->host->host_no, tag, sc, - jiffies_to_msecs(jiffies - start_time), - 0, ((u64)sc->cmnd[0] << 32 | - (u64)sc->cmnd[2] << 24 | - (u64)sc->cmnd[3] << 16 | - (u64)sc->cmnd[4] << 8 | sc->cmnd[5]), - (((u64)CMD_FLAGS(sc) << 32) | CMD_STATE(sc))); + FNIC_TRACE(fnic_cleanup_io, + sc->device->host->host_no, tag, sc, + jiffies_to_msecs(jiffies - start_time), + 0, ((u64)sc->cmnd[0] << 32 | + (u64)sc->cmnd[2] << 24 | + (u64)sc->cmnd[3] << 16 | + (u64)sc->cmnd[4] << 8 | sc->cmnd[5]), + (((u64)CMD_FLAGS(sc) << 32) | CMD_STATE(sc))); + + scsi_done(sc); - sc->scsi_done(sc); - } return true; } @@ -1495,17 +1489,15 @@ wq_copy_cleanup_scsi_cmd: FNIC_SCSI_DBG(KERN_DEBUG, fnic->lport->host, "wq_copy_cleanup_handler:" " DID_NO_CONNECT\n"); - if (sc->scsi_done) { - FNIC_TRACE(fnic_wq_copy_cleanup_handler, - sc->device->host->host_no, id, sc, - jiffies_to_msecs(jiffies - start_time), - 0, ((u64)sc->cmnd[0] << 32 | - (u64)sc->cmnd[2] << 24 | (u64)sc->cmnd[3] << 16 | - (u64)sc->cmnd[4] << 8 | sc->cmnd[5]), - (((u64)CMD_FLAGS(sc) << 32) | CMD_STATE(sc))); + FNIC_TRACE(fnic_wq_copy_cleanup_handler, + sc->device->host->host_no, id, sc, + jiffies_to_msecs(jiffies - start_time), + 0, ((u64)sc->cmnd[0] << 32 | + (u64)sc->cmnd[2] << 24 | (u64)sc->cmnd[3] << 16 | + (u64)sc->cmnd[4] << 8 | sc->cmnd[5]), + (((u64)CMD_FLAGS(sc) << 32) | CMD_STATE(sc))); - sc->scsi_done(sc); - } + scsi_done(sc); } static inline int fnic_queue_abort_io_req(struct fnic *fnic, int tag, @@ -1931,16 +1923,14 @@ int fnic_abort_cmd(struct scsi_cmnd *sc) fnic_release_ioreq_buf(fnic, io_req, sc); mempool_free(io_req, fnic->io_req_pool); - if (sc->scsi_done) { /* Call SCSI completion function to complete the IO */ - sc->result = (DID_ABORT << 16); - sc->scsi_done(sc); - atomic64_dec(&fnic_stats->io_stats.active_ios); - if (atomic64_read(&fnic->io_cmpl_skip)) - atomic64_dec(&fnic->io_cmpl_skip); - else - atomic64_inc(&fnic_stats->io_stats.io_completions); - } + sc->result = DID_ABORT << 16; + scsi_done(sc); + atomic64_dec(&fnic_stats->io_stats.active_ios); + if (atomic64_read(&fnic->io_cmpl_skip)) + atomic64_dec(&fnic->io_cmpl_skip); + else + atomic64_inc(&fnic_stats->io_stats.io_completions); fnic_abort_cmd_end: FNIC_TRACE(fnic_abort_cmd, sc->device->host->host_no, tag, sc, @@ -2153,11 +2143,10 @@ static bool fnic_pending_aborts_iter(struct scsi_cmnd *sc, * Any IO is returned during reset, it needs to call scsi_done * to return the scsi_cmnd to upper layer. */ - if (sc->scsi_done) { - /* Set result to let upper SCSI layer retry */ - sc->result = DID_RESET << 16; - sc->scsi_done(sc); - } + /* Set result to let upper SCSI layer retry */ + sc->result = DID_RESET << 16; + scsi_done(sc); + return true; } From 82f01edcf9a81dd958015b36b409011187c013d0 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 7 Oct 2021 13:28:31 -0700 Subject: [PATCH 146/279] scsi: hpsa: Call scsi_done() directly Conditional statements are faster than indirect calls. Hence call scsi_done() directly. Link: https://lore.kernel.org/r/20211007202923.2174984-37-bvanassche@acm.org Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/hpsa.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c index 3faa87fa296a..a1153449344a 100644 --- a/drivers/scsi/hpsa.c +++ b/drivers/scsi/hpsa.c @@ -2482,8 +2482,8 @@ static void hpsa_cmd_free_and_done(struct ctlr_info *h, struct CommandList *c, struct scsi_cmnd *cmd) { hpsa_cmd_resolve_and_free(h, c); - if (cmd && cmd->scsi_done) - cmd->scsi_done(cmd); + if (cmd) + scsi_done(cmd); } static void hpsa_retry_cmd(struct ctlr_info *h, struct CommandList *c) @@ -5671,7 +5671,7 @@ static void hpsa_command_resubmit_worker(struct work_struct *work) * if it encountered a dma mapping failure. */ cmd->result = DID_IMM_RETRY << 16; - cmd->scsi_done(cmd); + scsi_done(cmd); } } @@ -5691,19 +5691,19 @@ static int hpsa_scsi_queue_command(struct Scsi_Host *sh, struct scsi_cmnd *cmd) dev = cmd->device->hostdata; if (!dev) { cmd->result = DID_NO_CONNECT << 16; - cmd->scsi_done(cmd); + scsi_done(cmd); return 0; } if (dev->removed) { cmd->result = DID_NO_CONNECT << 16; - cmd->scsi_done(cmd); + scsi_done(cmd); return 0; } if (unlikely(lockup_detected(h))) { cmd->result = DID_NO_CONNECT << 16; - cmd->scsi_done(cmd); + scsi_done(cmd); return 0; } From 574015a837317c7c477be3108a7e143ad24b6933 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 7 Oct 2021 13:28:32 -0700 Subject: [PATCH 147/279] scsi: hptiop: Call scsi_done() directly Conditional statements are faster than indirect calls. Hence call scsi_done() directly. Link: https://lore.kernel.org/r/20211007202923.2174984-38-bvanassche@acm.org Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/hptiop.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/drivers/scsi/hptiop.c b/drivers/scsi/hptiop.c index 61cda7b7624f..f18f6a677c1b 100644 --- a/drivers/scsi/hptiop.c +++ b/drivers/scsi/hptiop.c @@ -769,7 +769,7 @@ static void hptiop_finish_scsi_req(struct hptiop_hba *hba, u32 tag, skip_resid: dprintk("scsi_done(%p)\n", scp); - scp->scsi_done(scp); + scsi_done(scp); free_req(hba, &hba->reqs[tag]); } @@ -1002,9 +1002,6 @@ static int hptiop_queuecommand_lck(struct scsi_cmnd *scp, int sg_count = 0; struct hptiop_request *_req; - BUG_ON(!done); - scp->scsi_done = done; - _req = get_req(hba); if (_req == NULL) { dprintk("hptiop_queuecmd : no free req\n"); @@ -1059,7 +1056,7 @@ static int hptiop_queuecommand_lck(struct scsi_cmnd *scp, cmd_done: dprintk("scsi_done(scp=%p)\n", scp); - scp->scsi_done(scp); + scsi_done(scp); return 0; } From 85f6dd08c86ac4c13f165370e47eb1dcf3a4f983 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 7 Oct 2021 13:28:33 -0700 Subject: [PATCH 148/279] scsi: ibmvscsi: Call scsi_done() directly Conditional statements are faster than indirect calls. Hence call scsi_done() directly. Link: https://lore.kernel.org/r/20211007202923.2174984-39-bvanassche@acm.org Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/ibmvscsi/ibmvfc.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/scsi/ibmvscsi/ibmvfc.c b/drivers/scsi/ibmvscsi/ibmvfc.c index 1f1586ad48fe..63f42eebe0ba 100644 --- a/drivers/scsi/ibmvscsi/ibmvfc.c +++ b/drivers/scsi/ibmvscsi/ibmvfc.c @@ -1046,7 +1046,7 @@ static void ibmvfc_scsi_eh_done(struct ibmvfc_event *evt) if (cmnd) { scsi_dma_unmap(cmnd); - cmnd->scsi_done(cmnd); + scsi_done(cmnd); } ibmvfc_free_event(evt); @@ -1848,7 +1848,7 @@ static void ibmvfc_scsi_done(struct ibmvfc_event *evt) cmnd->result = (DID_ERROR << 16); scsi_dma_unmap(cmnd); - cmnd->scsi_done(cmnd); + scsi_done(cmnd); } ibmvfc_free_event(evt); @@ -1934,7 +1934,7 @@ static int ibmvfc_queuecommand(struct Scsi_Host *shost, struct scsi_cmnd *cmnd) if (unlikely((rc = fc_remote_port_chkready(rport))) || unlikely((rc = ibmvfc_host_chkready(vhost)))) { cmnd->result = rc; - cmnd->scsi_done(cmnd); + scsi_done(cmnd); return 0; } @@ -1974,7 +1974,7 @@ static int ibmvfc_queuecommand(struct Scsi_Host *shost, struct scsi_cmnd *cmnd) "Failed to map DMA buffer for command. rc=%d\n", rc); cmnd->result = DID_ERROR << 16; - cmnd->scsi_done(cmnd); + scsi_done(cmnd); return 0; } From 0233196eb238bc18fa89be9249b4b321af0c3fc1 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 7 Oct 2021 13:28:34 -0700 Subject: [PATCH 149/279] scsi: imm: Call scsi_done() directly Conditional statements are faster than indirect calls. Hence call scsi_done() directly. Link: https://lore.kernel.org/r/20211007202923.2174984-40-bvanassche@acm.org Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/imm.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/scsi/imm.c b/drivers/scsi/imm.c index 943c9102a7eb..be8edcff0177 100644 --- a/drivers/scsi/imm.c +++ b/drivers/scsi/imm.c @@ -769,7 +769,7 @@ static void imm_interrupt(struct work_struct *work) spin_lock_irqsave(host->host_lock, flags); dev->cur_cmd = NULL; - cmd->scsi_done(cmd); + scsi_done(cmd); spin_unlock_irqrestore(host->host_lock, flags); return; } @@ -922,7 +922,6 @@ static int imm_queuecommand_lck(struct scsi_cmnd *cmd, dev->failed = 0; dev->jstart = jiffies; dev->cur_cmd = cmd; - cmd->scsi_done = done; cmd->result = DID_ERROR << 16; /* default return code */ cmd->SCp.phase = 0; /* bus free */ From 25e1d89669ecb5fab5c3bede624e3a30251f0f09 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 7 Oct 2021 13:28:35 -0700 Subject: [PATCH 150/279] scsi: initio: Call scsi_done() directly Conditional statements are faster than indirect calls. Hence call scsi_done() directly. Link: https://lore.kernel.org/r/20211007202923.2174984-41-bvanassche@acm.org Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/initio.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/scsi/initio.c b/drivers/scsi/initio.c index 9b75e19a9bab..183f95758636 100644 --- a/drivers/scsi/initio.c +++ b/drivers/scsi/initio.c @@ -2615,8 +2615,6 @@ static int i91u_queuecommand_lck(struct scsi_cmnd *cmd, struct initio_host *host = (struct initio_host *) cmd->device->host->hostdata; struct scsi_ctrl_blk *cmnd; - cmd->scsi_done = done; - cmnd = initio_alloc_scb(host); if (!cmnd) return SCSI_MLQUEUE_HOST_BUSY; @@ -2788,7 +2786,7 @@ static void i91uSCBPost(u8 * host_mem, u8 * cblk_mem) cmnd->result = cblk->tastat | (cblk->hastat << 16); i91u_unmap_scb(host->pci_dev, cmnd); - cmnd->scsi_done(cmnd); /* Notify system DONE */ + scsi_done(cmnd); /* Notify system DONE */ initio_release_scb(host, cblk); /* Release SCB for current channel */ } From acd3c42d18f74f5da1aa690b3e9673c5ccbfab2b Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 7 Oct 2021 13:28:36 -0700 Subject: [PATCH 151/279] scsi: ipr: Call scsi_done() directly Conditional statements are faster than indirect calls. Hence call scsi_done() directly. Link: https://lore.kernel.org/r/20211007202923.2174984-42-bvanassche@acm.org Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/ipr.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c index 5d78f7e939a3..aa44216dcf9a 100644 --- a/drivers/scsi/ipr.c +++ b/drivers/scsi/ipr.c @@ -866,7 +866,7 @@ static void __ipr_scsi_eh_done(struct ipr_cmnd *ipr_cmd) scsi_cmd->result |= (DID_ERROR << 16); scsi_dma_unmap(ipr_cmd->scsi_cmd); - scsi_cmd->scsi_done(scsi_cmd); + scsi_done(scsi_cmd); if (ipr_cmd->eh_comp) complete(ipr_cmd->eh_comp); list_add_tail(&ipr_cmd->queue, &ipr_cmd->hrrq->hrrq_free_q); @@ -6065,7 +6065,7 @@ static void __ipr_erp_done(struct ipr_cmnd *ipr_cmd) res->in_erp = 0; } scsi_dma_unmap(ipr_cmd->scsi_cmd); - scsi_cmd->scsi_done(scsi_cmd); + scsi_done(scsi_cmd); if (ipr_cmd->eh_comp) complete(ipr_cmd->eh_comp); list_add_tail(&ipr_cmd->queue, &ipr_cmd->hrrq->hrrq_free_q); @@ -6502,7 +6502,7 @@ static void ipr_erp_start(struct ipr_ioa_cfg *ioa_cfg, } scsi_dma_unmap(ipr_cmd->scsi_cmd); - scsi_cmd->scsi_done(scsi_cmd); + scsi_done(scsi_cmd); if (ipr_cmd->eh_comp) complete(ipr_cmd->eh_comp); list_add_tail(&ipr_cmd->queue, &ipr_cmd->hrrq->hrrq_free_q); @@ -6531,7 +6531,7 @@ static void ipr_scsi_done(struct ipr_cmnd *ipr_cmd) scsi_dma_unmap(scsi_cmd); spin_lock_irqsave(ipr_cmd->hrrq->lock, lock_flags); - scsi_cmd->scsi_done(scsi_cmd); + scsi_done(scsi_cmd); if (ipr_cmd->eh_comp) complete(ipr_cmd->eh_comp); list_add_tail(&ipr_cmd->queue, &ipr_cmd->hrrq->hrrq_free_q); @@ -6685,7 +6685,7 @@ err_nodev: spin_lock_irqsave(hrrq->lock, hrrq_flags); memset(scsi_cmd->sense_buffer, 0, SCSI_SENSE_BUFFERSIZE); scsi_cmd->result = (DID_NO_CONNECT << 16); - scsi_cmd->scsi_done(scsi_cmd); + scsi_done(scsi_cmd); spin_unlock_irqrestore(hrrq->lock, hrrq_flags); return 0; } From 98cc0e69ba5da84f664e6e658c28d7940fbdc69a Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 7 Oct 2021 13:28:37 -0700 Subject: [PATCH 152/279] scsi: ips: Call scsi_done() directly Conditional statements are faster than indirect calls. Hence call scsi_done() directly. Link: https://lore.kernel.org/r/20211007202923.2174984-43-bvanassche@acm.org Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/ips.c | 28 +++++++++++++--------------- 1 file changed, 13 insertions(+), 15 deletions(-) diff --git a/drivers/scsi/ips.c b/drivers/scsi/ips.c index cdd94fb2aab7..0c93ec359e9b 100644 --- a/drivers/scsi/ips.c +++ b/drivers/scsi/ips.c @@ -936,7 +936,7 @@ static int __ips_eh_reset(struct scsi_cmnd *SC) while ((scb = ips_removeq_scb_head(&ha->scb_activelist))) { scb->scsi_cmd->result = DID_ERROR << 16; - scb->scsi_cmd->scsi_done(scb->scsi_cmd); + scsi_done(scb->scsi_cmd); ips_freescb(ha, scb); } @@ -946,7 +946,7 @@ static int __ips_eh_reset(struct scsi_cmnd *SC) while ((scsi_cmd = ips_removeq_wait_head(&ha->scb_waitlist))) { scsi_cmd->result = DID_ERROR; - scsi_cmd->scsi_done(scsi_cmd); + scsi_done(scsi_cmd); } ha->active = FALSE; @@ -965,7 +965,7 @@ static int __ips_eh_reset(struct scsi_cmnd *SC) while ((scb = ips_removeq_scb_head(&ha->scb_activelist))) { scb->scsi_cmd->result = DID_ERROR << 16; - scb->scsi_cmd->scsi_done(scb->scsi_cmd); + scsi_done(scb->scsi_cmd); ips_freescb(ha, scb); } @@ -975,7 +975,7 @@ static int __ips_eh_reset(struct scsi_cmnd *SC) while ((scsi_cmd = ips_removeq_wait_head(&ha->scb_waitlist))) { scsi_cmd->result = DID_ERROR << 16; - scsi_cmd->scsi_done(scsi_cmd); + scsi_done(scsi_cmd); } ha->active = FALSE; @@ -994,7 +994,7 @@ static int __ips_eh_reset(struct scsi_cmnd *SC) while ((scb = ips_removeq_scb_head(&ha->scb_activelist))) { scb->scsi_cmd->result = DID_RESET << 16; - scb->scsi_cmd->scsi_done(scb->scsi_cmd); + scsi_done(scb->scsi_cmd); ips_freescb(ha, scb); } @@ -1064,8 +1064,6 @@ static int ips_queue_lck(struct scsi_cmnd *SC, void (*done) (struct scsi_cmnd *) return (0); } - SC->scsi_done = done; - DEBUG_VAR(2, "(%s%d): ips_queue: cmd 0x%X (%d %d %d)", ips_name, ha->host_num, @@ -1099,7 +1097,7 @@ static int ips_queue_lck(struct scsi_cmnd *SC, void (*done) (struct scsi_cmnd *) ha->ioctl_reset = 1; /* This reset request is from an IOCTL */ __ips_eh_reset(SC); SC->result = DID_OK << 16; - SC->scsi_done(SC); + scsi_done(SC); return (0); } @@ -2579,7 +2577,7 @@ ips_next(ips_ha_t * ha, int intr) case IPS_FAILURE: if (scb->scsi_cmd) { scb->scsi_cmd->result = DID_ERROR << 16; - scb->scsi_cmd->scsi_done(scb->scsi_cmd); + scsi_done(scb->scsi_cmd); } ips_freescb(ha, scb); @@ -2587,7 +2585,7 @@ ips_next(ips_ha_t * ha, int intr) case IPS_SUCCESS_IMM: if (scb->scsi_cmd) { scb->scsi_cmd->result = DID_OK << 16; - scb->scsi_cmd->scsi_done(scb->scsi_cmd); + scsi_done(scb->scsi_cmd); } ips_freescb(ha, scb); @@ -2712,7 +2710,7 @@ ips_next(ips_ha_t * ha, int intr) case IPS_FAILURE: if (scb->scsi_cmd) { scb->scsi_cmd->result = DID_ERROR << 16; - scb->scsi_cmd->scsi_done(scb->scsi_cmd); + scsi_done(scb->scsi_cmd); } if (scb->bus) @@ -2723,7 +2721,7 @@ ips_next(ips_ha_t * ha, int intr) break; case IPS_SUCCESS_IMM: if (scb->scsi_cmd) - scb->scsi_cmd->scsi_done(scb->scsi_cmd); + scsi_done(scb->scsi_cmd); if (scb->bus) ha->dcdb_active[scb->bus - 1] &= @@ -3206,7 +3204,7 @@ ips_done(ips_ha_t * ha, ips_scb_t * scb) case IPS_FAILURE: if (scb->scsi_cmd) { scb->scsi_cmd->result = DID_ERROR << 16; - scb->scsi_cmd->scsi_done(scb->scsi_cmd); + scsi_done(scb->scsi_cmd); } ips_freescb(ha, scb); @@ -3214,7 +3212,7 @@ ips_done(ips_ha_t * ha, ips_scb_t * scb) case IPS_SUCCESS_IMM: if (scb->scsi_cmd) { scb->scsi_cmd->result = DID_ERROR << 16; - scb->scsi_cmd->scsi_done(scb->scsi_cmd); + scsi_done(scb->scsi_cmd); } ips_freescb(ha, scb); @@ -3231,7 +3229,7 @@ ips_done(ips_ha_t * ha, ips_scb_t * scb) ha->dcdb_active[scb->bus - 1] &= ~(1 << scb->target_id); } - scb->scsi_cmd->scsi_done(scb->scsi_cmd); + scsi_done(scb->scsi_cmd); ips_freescb(ha, scb); } From e0f63b2181cb66a7f8cd5b15ae6237fe0d283b0c Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 7 Oct 2021 13:28:38 -0700 Subject: [PATCH 153/279] scsi: libfc: Call scsi_done() directly Conditional statements are faster than indirect calls. Hence call scsi_done() directly. Link: https://lore.kernel.org/r/20211007202923.2174984-44-bvanassche@acm.org Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/libfc/fc_fcp.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/scsi/libfc/fc_fcp.c b/drivers/scsi/libfc/fc_fcp.c index 509eacd7893d..871b11edb586 100644 --- a/drivers/scsi/libfc/fc_fcp.c +++ b/drivers/scsi/libfc/fc_fcp.c @@ -1870,7 +1870,7 @@ int fc_queuecommand(struct Scsi_Host *shost, struct scsi_cmnd *sc_cmd) rval = fc_remote_port_chkready(rport); if (rval) { sc_cmd->result = rval; - sc_cmd->scsi_done(sc_cmd); + scsi_done(sc_cmd); return 0; } @@ -1880,7 +1880,7 @@ int fc_queuecommand(struct Scsi_Host *shost, struct scsi_cmnd *sc_cmd) * online */ sc_cmd->result = DID_IMM_RETRY << 16; - sc_cmd->scsi_done(sc_cmd); + scsi_done(sc_cmd); goto out; } @@ -2087,7 +2087,7 @@ static void fc_io_compl(struct fc_fcp_pkt *fsp) list_del(&fsp->list); sc_cmd->SCp.ptr = NULL; spin_unlock_irqrestore(&si->scsi_queue_lock, flags); - sc_cmd->scsi_done(sc_cmd); + scsi_done(sc_cmd); /* release ref from initial allocation in queue command */ fc_fcp_pkt_release(fsp); From b4b84edc5d3982749c342669b6fbef6ef239730e Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 7 Oct 2021 13:28:39 -0700 Subject: [PATCH 154/279] scsi: libiscsi: Call scsi_done() directly Conditional statements are faster than indirect calls. Hence call scsi_done() directly. Link: https://lore.kernel.org/r/20211007202923.2174984-45-bvanassche@acm.org Reviewed-by: Lee Duncan Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/libiscsi.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c index 54dd9f581290..284b939fb1ea 100644 --- a/drivers/scsi/libiscsi.c +++ b/drivers/scsi/libiscsi.c @@ -468,7 +468,7 @@ static void iscsi_free_task(struct iscsi_task *task) * it will decide how to return sc to scsi-ml. */ if (oldstate != ISCSI_TASK_REQUEUE_SCSIQ) - sc->scsi_done(sc); + scsi_done(sc); } } @@ -1807,7 +1807,7 @@ fault: ISCSI_DBG_SESSION(session, "iscsi: cmd 0x%x is not queued (%d)\n", sc->cmnd[0], reason); scsi_set_resid(sc, scsi_bufflen(sc)); - sc->scsi_done(sc); + scsi_done(sc); return 0; } EXPORT_SYMBOL_GPL(iscsi_queuecommand); From e803bc52b04b3cc1be61a7fc0091172531f8faaf Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 7 Oct 2021 13:28:40 -0700 Subject: [PATCH 155/279] scsi: libsas: Call scsi_done() directly Conditional statements are faster than indirect calls. Hence call scsi_done() directly. Link: https://lore.kernel.org/r/20211007202923.2174984-46-bvanassche@acm.org Reviewed-by: John Garry Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/libsas/sas_scsi_host.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/libsas/sas_scsi_host.c b/drivers/scsi/libsas/sas_scsi_host.c index 2bf37151623e..d337fdf1b9ca 100644 --- a/drivers/scsi/libsas/sas_scsi_host.c +++ b/drivers/scsi/libsas/sas_scsi_host.c @@ -125,7 +125,7 @@ static void sas_scsi_task_done(struct sas_task *task) } sas_end_task(sc, task); - sc->scsi_done(sc); + scsi_done(sc); } static struct sas_task *sas_create_task(struct scsi_cmnd *cmd, @@ -198,7 +198,7 @@ out_free_task: else cmd->result = DID_ERROR << 16; out_done: - cmd->scsi_done(cmd); + scsi_done(cmd); return 0; } EXPORT_SYMBOL_GPL(sas_queuecommand); From ca068c2c6ca07960106e861155563c0963b611fb Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 7 Oct 2021 13:28:41 -0700 Subject: [PATCH 156/279] scsi: lpfc: Call scsi_done() directly Conditional statements are faster than indirect calls. Hence call scsi_done() directly. Link: https://lore.kernel.org/r/20211007202923.2174984-47-bvanassche@acm.org Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/lpfc/lpfc_scsi.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c index 83ad03d22a49..35df919b6c03 100644 --- a/drivers/scsi/lpfc/lpfc_scsi.c +++ b/drivers/scsi/lpfc/lpfc_scsi.c @@ -564,7 +564,7 @@ lpfc_sli4_io_xri_aborted(struct lpfc_hba *phba, * scsi_done upcall. */ if (cmd) - cmd->scsi_done(cmd); + scsi_done(cmd); /* * We expect there is an abort thread waiting @@ -4501,7 +4501,7 @@ lpfc_fcp_io_cmd_wqe_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pwqeIn, goto out; /* The sdev is not guaranteed to be valid post scsi_done upcall. */ - cmd->scsi_done(cmd); + scsi_done(cmd); /* * If there is an abort thread waiting for command completion @@ -4770,7 +4770,7 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn, #endif /* The sdev is not guaranteed to be valid post scsi_done upcall. */ - cmd->scsi_done(cmd); + scsi_done(cmd); /* * If there is an abort thread waiting for command completion @@ -5842,7 +5842,7 @@ lpfc_queuecommand(struct Scsi_Host *shost, struct scsi_cmnd *cmnd) shost); out_fail_command: - cmnd->scsi_done(cmnd); + scsi_done(cmnd); return 0; } From c0e70ea3f7194c089a9030b9e48c5c419a2d25e4 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 7 Oct 2021 13:28:42 -0700 Subject: [PATCH 157/279] scsi: mac53c94: Call scsi_done() directly Conditional statements are faster than indirect calls. Hence call scsi_done() directly. Link: https://lore.kernel.org/r/20211007202923.2174984-48-bvanassche@acm.org Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/mac53c94.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/scsi/mac53c94.c b/drivers/scsi/mac53c94.c index ec9840d322e5..9731855805f5 100644 --- a/drivers/scsi/mac53c94.c +++ b/drivers/scsi/mac53c94.c @@ -83,7 +83,6 @@ static int mac53c94_queue_lck(struct scsi_cmnd *cmd, void (*done)(struct scsi_cm } #endif - cmd->scsi_done = done; cmd->host_scribble = NULL; state = (struct fsc_state *) cmd->device->host->hostdata; @@ -348,7 +347,7 @@ static void cmd_done(struct fsc_state *state, int result) cmd = state->current_req; if (cmd) { cmd->result = result; - (*cmd->scsi_done)(cmd); + scsi_done(cmd); state->current_req = NULL; } state->phase = idle; From f1170b83dff9f923728fbb78d9cd8ebcc120b8ed Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 7 Oct 2021 13:28:43 -0700 Subject: [PATCH 158/279] scsi: megaraid_mbox: Call scsi_done() directly Conditional statements are faster than indirect calls. Hence call scsi_done() directly. Link: https://lore.kernel.org/r/20211007202923.2174984-49-bvanassche@acm.org Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/megaraid/megaraid_mbox.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/drivers/scsi/megaraid/megaraid_mbox.c b/drivers/scsi/megaraid/megaraid_mbox.c index d20c2e4ee793..705c5027ba91 100644 --- a/drivers/scsi/megaraid/megaraid_mbox.c +++ b/drivers/scsi/megaraid/megaraid_mbox.c @@ -1440,7 +1440,6 @@ megaraid_queue_command_lck(struct scsi_cmnd *scp, void (*done)(struct scsi_cmnd int if_busy; adapter = SCP2ADAPTER(scp); - scp->scsi_done = done; scp->result = 0; /* @@ -2358,7 +2357,7 @@ megaraid_mbox_dpc(unsigned long devp) megaraid_dealloc_scb(adapter, scb); // send the scsi packet back to kernel - scp->scsi_done(scp); + scsi_done(scp); } return; @@ -2416,7 +2415,7 @@ megaraid_abort_handler(struct scsi_cmnd *scp) scb->sno, scb->dev_channel, scb->dev_target)); scp->result = (DID_ABORT << 16); - scp->scsi_done(scp); + scsi_done(scp); megaraid_dealloc_scb(adapter, scb); @@ -2446,7 +2445,7 @@ megaraid_abort_handler(struct scsi_cmnd *scp) scb->dev_channel, scb->dev_target)); scp->result = (DID_ABORT << 16); - scp->scsi_done(scp); + scsi_done(scp); megaraid_dealloc_scb(adapter, scb); @@ -2566,7 +2565,7 @@ megaraid_reset_handler(struct scsi_cmnd *scp) } scb->scp->result = (DID_RESET << 16); - scb->scp->scsi_done(scb->scp); + scsi_done(scb->scp); megaraid_dealloc_scb(adapter, scb); } From 012f14b269da11f43547b7d859ebdc1016213650 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 7 Oct 2021 13:28:43 -0700 Subject: [PATCH 159/279] scsi: megaraid_sas: Call scsi_done() directly Conditional statements are faster than indirect calls. Hence call scsi_done() directly. Link: https://lore.kernel.org/r/20211007202923.2174984-49-bvanassche@acm.org Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/megaraid/megaraid_sas_base.c | 16 ++++++++-------- drivers/scsi/megaraid/megaraid_sas_fusion.c | 6 +++--- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c index 39d8754e63ac..d1e7da28be9a 100644 --- a/drivers/scsi/megaraid/megaraid_sas_base.c +++ b/drivers/scsi/megaraid/megaraid_sas_base.c @@ -1794,7 +1794,7 @@ megasas_queue_command(struct Scsi_Host *shost, struct scsi_cmnd *scmd) if (instance->unload == 1) { scmd->result = DID_NO_CONNECT << 16; - scmd->scsi_done(scmd); + scsi_done(scmd); return 0; } @@ -1809,7 +1809,7 @@ megasas_queue_command(struct Scsi_Host *shost, struct scsi_cmnd *scmd) return SCSI_MLQUEUE_HOST_BUSY; } else { scmd->result = DID_NO_CONNECT << 16; - scmd->scsi_done(scmd); + scsi_done(scmd); return 0; } } @@ -1818,7 +1818,7 @@ megasas_queue_command(struct Scsi_Host *shost, struct scsi_cmnd *scmd) if (!mr_device_priv_data || (atomic_read(&instance->adprecovery) == MEGASAS_HW_CRITICAL_ERROR)) { scmd->result = DID_NO_CONNECT << 16; - scmd->scsi_done(scmd); + scsi_done(scmd); return 0; } @@ -1826,7 +1826,7 @@ megasas_queue_command(struct Scsi_Host *shost, struct scsi_cmnd *scmd) ld_tgt_id = MEGASAS_TARGET_ID(scmd->device); if (instance->ld_tgtid_status[ld_tgt_id] == LD_TARGET_ID_DELETED) { scmd->result = DID_NO_CONNECT << 16; - scmd->scsi_done(scmd); + scsi_done(scmd); return 0; } } @@ -1857,7 +1857,7 @@ megasas_queue_command(struct Scsi_Host *shost, struct scsi_cmnd *scmd) return instance->instancet->build_and_issue_cmd(instance, scmd); out_done: - scmd->scsi_done(scmd); + scsi_done(scmd); return 0; } @@ -2783,7 +2783,7 @@ static int megasas_wait_for_outstanding(struct megasas_instance *instance) reset_index, reset_cmd, reset_cmd->scmd->cmnd[0]); - reset_cmd->scmd->scsi_done(reset_cmd->scmd); + scsi_done(reset_cmd->scmd); megasas_return_cmd(instance, reset_cmd); } else if (reset_cmd->sync_cmd) { dev_notice(&instance->pdev->dev, "%p synch cmds" @@ -3640,7 +3640,7 @@ megasas_complete_cmd(struct megasas_instance *instance, struct megasas_cmd *cmd, atomic_dec(&instance->fw_outstanding); scsi_dma_unmap(cmd->scmd); - cmd->scmd->scsi_done(cmd->scmd); + scsi_done(cmd->scmd); megasas_return_cmd(instance, cmd); break; @@ -3686,7 +3686,7 @@ megasas_complete_cmd(struct megasas_instance *instance, struct megasas_cmd *cmd, atomic_dec(&instance->fw_outstanding); scsi_dma_unmap(cmd->scmd); - cmd->scmd->scsi_done(cmd->scmd); + scsi_done(cmd->scmd); megasas_return_cmd(instance, cmd); break; diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c index 109782e3ec44..fc90a0a687b5 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fusion.c +++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c @@ -3493,7 +3493,7 @@ megasas_complete_r1_command(struct megasas_instance *instance, megasas_return_cmd_fusion(instance, cmd); scsi_dma_unmap(scmd_local); megasas_sdev_busy_dec(instance, scmd_local); - scmd_local->scsi_done(scmd_local); + scsi_done(scmd_local); } } @@ -3634,7 +3634,7 @@ complete_cmd_fusion(struct megasas_instance *instance, u32 MSIxIndex, megasas_return_cmd_fusion(instance, cmd_fusion); scsi_dma_unmap(scmd_local); megasas_sdev_busy_dec(instance, scmd_local); - scmd_local->scsi_done(scmd_local); + scsi_done(scmd_local); } else /* Optimal VD - R1 FP command completion. */ megasas_complete_r1_command(instance, cmd_fusion); break; @@ -5013,7 +5013,7 @@ int megasas_reset_fusion(struct Scsi_Host *shost, int reason) atomic_dec(&instance->ldio_outstanding); megasas_return_cmd_fusion(instance, cmd_fusion); scsi_dma_unmap(scmd_local); - scmd_local->scsi_done(scmd_local); + scsi_done(scmd_local); } } From 9e0603656fdf2e5b919adcc06ce11bd748bdb543 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 7 Oct 2021 13:28:44 -0700 Subject: [PATCH 160/279] scsi: megaraid: Call scsi_done() directly Conditional statements are faster than indirect calls. Hence call scsi_done() directly. Link: https://lore.kernel.org/r/20211007202923.2174984-50-bvanassche@acm.org Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/megaraid.c | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/drivers/scsi/megaraid.c b/drivers/scsi/megaraid.c index 56910e94dbf2..c4ea833586e0 100644 --- a/drivers/scsi/megaraid.c +++ b/drivers/scsi/megaraid.c @@ -380,9 +380,6 @@ megaraid_queue_lck(struct scsi_cmnd *scmd, void (*done)(struct scsi_cmnd *)) adapter = (adapter_t *)scmd->device->host->hostdata; - scmd->scsi_done = done; - - /* * Allocate and build a SCB request * busy flag will be set if mega_build_cmd() command could not @@ -586,7 +583,7 @@ mega_build_cmd(adapter_t *adapter, struct scsi_cmnd *cmd, int *busy) /* have just LUN 0 for each target on virtual channels */ if (cmd->device->lun) { cmd->result = (DID_BAD_TARGET << 16); - cmd->scsi_done(cmd); + scsi_done(cmd); return NULL; } @@ -605,7 +602,7 @@ mega_build_cmd(adapter_t *adapter, struct scsi_cmnd *cmd, int *busy) if(ldrv_num > max_ldrv_num ) { cmd->result = (DID_BAD_TARGET << 16); - cmd->scsi_done(cmd); + scsi_done(cmd); return NULL; } @@ -617,7 +614,7 @@ mega_build_cmd(adapter_t *adapter, struct scsi_cmnd *cmd, int *busy) * devices */ cmd->result = (DID_BAD_TARGET << 16); - cmd->scsi_done(cmd); + scsi_done(cmd); return NULL; } } @@ -637,7 +634,7 @@ mega_build_cmd(adapter_t *adapter, struct scsi_cmnd *cmd, int *busy) */ if( !adapter->has_cluster ) { cmd->result = (DID_OK << 16); - cmd->scsi_done(cmd); + scsi_done(cmd); return NULL; } @@ -655,7 +652,7 @@ mega_build_cmd(adapter_t *adapter, struct scsi_cmnd *cmd, int *busy) return scb; #else cmd->result = (DID_OK << 16); - cmd->scsi_done(cmd); + scsi_done(cmd); return NULL; #endif @@ -670,7 +667,7 @@ mega_build_cmd(adapter_t *adapter, struct scsi_cmnd *cmd, int *busy) kunmap_atomic(buf - sg->offset); cmd->result = (DID_OK << 16); - cmd->scsi_done(cmd); + scsi_done(cmd); return NULL; } @@ -866,7 +863,7 @@ mega_build_cmd(adapter_t *adapter, struct scsi_cmnd *cmd, int *busy) if( ! adapter->has_cluster ) { cmd->result = (DID_BAD_TARGET << 16); - cmd->scsi_done(cmd); + scsi_done(cmd); return NULL; } @@ -889,7 +886,7 @@ mega_build_cmd(adapter_t *adapter, struct scsi_cmnd *cmd, int *busy) default: cmd->result = (DID_BAD_TARGET << 16); - cmd->scsi_done(cmd); + scsi_done(cmd); return NULL; } } @@ -1654,7 +1651,7 @@ mega_rundoneq (adapter_t *adapter) struct scsi_pointer* spos = (struct scsi_pointer *)pos; cmd = list_entry(spos, struct scsi_cmnd, SCp); - cmd->scsi_done(cmd); + scsi_done(cmd); } INIT_LIST_HEAD(&adapter->completed_list); From aaf2173b5cc3cf5a45b548e5fc62f155417778a1 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 7 Oct 2021 13:28:45 -0700 Subject: [PATCH 161/279] scsi: mesh: Call scsi_done() directly Conditional statements are faster than indirect calls. Hence call scsi_done() directly. Link: https://lore.kernel.org/r/20211007202923.2174984-51-bvanassche@acm.org Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/mesh.c | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) diff --git a/drivers/scsi/mesh.c b/drivers/scsi/mesh.c index 78b72bcf58fe..73a3e85802ad 100644 --- a/drivers/scsi/mesh.c +++ b/drivers/scsi/mesh.c @@ -342,15 +342,6 @@ static inline void mesh_flush_io(volatile struct mesh_regs __iomem *mr) } -/* - * Complete a SCSI command - */ -static void mesh_completed(struct mesh_state *ms, struct scsi_cmnd *cmd) -{ - (*cmd->scsi_done)(cmd); -} - - /* Called with meshinterrupt disabled, initialize the chipset * and eventually do the initial bus reset. The lock must not be * held since we can schedule. @@ -613,7 +604,7 @@ static void mesh_done(struct mesh_state *ms, int start_next) #endif } cmd->SCp.this_residual -= ms->data_ptr; - mesh_completed(ms, cmd); + scsi_done(cmd); } if (start_next) { out_8(&ms->mesh->sequence, SEQ_ENBRESEL); @@ -996,7 +987,7 @@ static void handle_reset(struct mesh_state *ms) if ((cmd = tp->current_req) != NULL) { set_host_byte(cmd, DID_RESET); tp->current_req = NULL; - mesh_completed(ms, cmd); + scsi_done(cmd); } ms->tgts[tgt].sdtr_state = do_sdtr; ms->tgts[tgt].sync_params = ASYNC_PARAMS; @@ -1005,7 +996,7 @@ static void handle_reset(struct mesh_state *ms) while ((cmd = ms->request_q) != NULL) { ms->request_q = (struct scsi_cmnd *) cmd->host_scribble; set_host_byte(cmd, DID_RESET); - mesh_completed(ms, cmd); + scsi_done(cmd); } ms->phase = idle; ms->msgphase = msg_none; @@ -1634,7 +1625,6 @@ static int mesh_queue_lck(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd * { struct mesh_state *ms; - cmd->scsi_done = done; cmd->host_scribble = NULL; ms = (struct mesh_state *) cmd->device->host->hostdata; From 1a30fd18f21b763357c76386b1c943cbe7602f04 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 7 Oct 2021 13:28:46 -0700 Subject: [PATCH 162/279] scsi: mpi3mr: Call scsi_done() directly Conditional statements are faster than indirect calls. Hence call scsi_done() directly. Link: https://lore.kernel.org/r/20211007202923.2174984-52-bvanassche@acm.org Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/mpi3mr/mpi3mr_os.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/drivers/scsi/mpi3mr/mpi3mr_os.c b/drivers/scsi/mpi3mr/mpi3mr_os.c index 2197988333fe..6373a877f439 100644 --- a/drivers/scsi/mpi3mr/mpi3mr_os.c +++ b/drivers/scsi/mpi3mr/mpi3mr_os.c @@ -409,7 +409,7 @@ static bool mpi3mr_flush_scmd(struct request *rq, scsi_dma_unmap(scmd); scmd->result = DID_RESET << 16; scsi_print_command(scmd); - scmd->scsi_done(scmd); + scsi_done(scmd); mrioc->flush_io_count++; } @@ -2312,7 +2312,7 @@ out_success: } mpi3mr_clear_scmd_priv(mrioc, scmd); scsi_dma_unmap(scmd); - scmd->scsi_done(scmd); + scsi_done(scmd); out: if (sense_buf) mpi3mr_repost_sense_buf(mrioc, @@ -3322,7 +3322,7 @@ static bool mpi3mr_check_return_unmap(struct mpi3mr_ioc *mrioc, __func__); scsi_print_command(scmd); scmd->result = DID_OK << 16; - scmd->scsi_done(scmd); + scsi_done(scmd); return true; } @@ -3334,7 +3334,7 @@ static bool mpi3mr_check_return_unmap(struct mpi3mr_ioc *mrioc, scmd->result = SAM_STAT_CHECK_CONDITION; scsi_build_sense_buffer(0, scmd->sense_buffer, ILLEGAL_REQUEST, 0x1A, 0); - scmd->scsi_done(scmd); + scsi_done(scmd); return true; } if (param_len != scsi_bufflen(scmd)) { @@ -3345,7 +3345,7 @@ static bool mpi3mr_check_return_unmap(struct mpi3mr_ioc *mrioc, scmd->result = SAM_STAT_CHECK_CONDITION; scsi_build_sense_buffer(0, scmd->sense_buffer, ILLEGAL_REQUEST, 0x1A, 0); - scmd->scsi_done(scmd); + scsi_done(scmd); return true; } buf = kzalloc(scsi_bufflen(scmd), GFP_ATOMIC); @@ -3354,7 +3354,7 @@ static bool mpi3mr_check_return_unmap(struct mpi3mr_ioc *mrioc, scmd->result = SAM_STAT_CHECK_CONDITION; scsi_build_sense_buffer(0, scmd->sense_buffer, ILLEGAL_REQUEST, 0x55, 0x03); - scmd->scsi_done(scmd); + scsi_done(scmd); return true; } scsi_sg_copy_to_buffer(scmd, buf, scsi_bufflen(scmd)); @@ -3368,7 +3368,7 @@ static bool mpi3mr_check_return_unmap(struct mpi3mr_ioc *mrioc, scmd->result = SAM_STAT_CHECK_CONDITION; scsi_build_sense_buffer(0, scmd->sense_buffer, ILLEGAL_REQUEST, 0x26, 0); - scmd->scsi_done(scmd); + scsi_done(scmd); kfree(buf); return true; } @@ -3438,14 +3438,14 @@ static int mpi3mr_qcmd(struct Scsi_Host *shost, sdev_priv_data = scmd->device->hostdata; if (!sdev_priv_data || !sdev_priv_data->tgt_priv_data) { scmd->result = DID_NO_CONNECT << 16; - scmd->scsi_done(scmd); + scsi_done(scmd); goto out; } if (mrioc->stop_drv_processing && !(mpi3mr_allow_scmd_to_fw(scmd))) { scmd->result = DID_NO_CONNECT << 16; - scmd->scsi_done(scmd); + scsi_done(scmd); goto out; } @@ -3459,19 +3459,19 @@ static int mpi3mr_qcmd(struct Scsi_Host *shost, dev_handle = stgt_priv_data->dev_handle; if (dev_handle == MPI3MR_INVALID_DEV_HANDLE) { scmd->result = DID_NO_CONNECT << 16; - scmd->scsi_done(scmd); + scsi_done(scmd); goto out; } if (stgt_priv_data->dev_removed) { scmd->result = DID_NO_CONNECT << 16; - scmd->scsi_done(scmd); + scsi_done(scmd); goto out; } if (atomic_read(&stgt_priv_data->block_io)) { if (mrioc->stop_drv_processing) { scmd->result = DID_NO_CONNECT << 16; - scmd->scsi_done(scmd); + scsi_done(scmd); goto out; } retval = SCSI_MLQUEUE_DEVICE_BUSY; @@ -3486,7 +3486,7 @@ static int mpi3mr_qcmd(struct Scsi_Host *shost, host_tag = mpi3mr_host_tag_for_scmd(mrioc, scmd); if (host_tag == MPI3MR_HOSTTAG_INVALID) { scmd->result = DID_ERROR << 16; - scmd->scsi_done(scmd); + scsi_done(scmd); goto out; } From b0c3007922f4bbe8d057396b57d771ba09698c43 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 7 Oct 2021 13:28:47 -0700 Subject: [PATCH 163/279] scsi: mpt3sas: Call scsi_done() directly Conditional statements are faster than indirect calls. Hence call scsi_done() directly. Link: https://lore.kernel.org/r/20211007202923.2174984-53-bvanassche@acm.org Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/mpt3sas/mpt3sas_scsih.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c b/drivers/scsi/mpt3sas/mpt3sas_scsih.c index d383d4a03436..39462535874b 100644 --- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c +++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c @@ -3314,7 +3314,7 @@ scsih_abort(struct scsi_cmnd *scmd) sdev_printk(KERN_INFO, scmd->device, "device been deleted! scmd(0x%p)\n", scmd); scmd->result = DID_NO_CONNECT << 16; - scmd->scsi_done(scmd); + scsi_done(scmd); r = SUCCESS; goto out; } @@ -3390,7 +3390,7 @@ scsih_dev_reset(struct scsi_cmnd *scmd) sdev_printk(KERN_INFO, scmd->device, "device been deleted! scmd(0x%p)\n", scmd); scmd->result = DID_NO_CONNECT << 16; - scmd->scsi_done(scmd); + scsi_done(scmd); r = SUCCESS; goto out; } @@ -3470,7 +3470,7 @@ scsih_target_reset(struct scsi_cmnd *scmd) starget_printk(KERN_INFO, starget, "target been deleted! scmd(0x%p)\n", scmd); scmd->result = DID_NO_CONNECT << 16; - scmd->scsi_done(scmd); + scsi_done(scmd); r = SUCCESS; goto out; } @@ -5030,7 +5030,7 @@ _scsih_flush_running_cmds(struct MPT3SAS_ADAPTER *ioc) scmd->result = DID_NO_CONNECT << 16; else scmd->result = DID_RESET << 16; - scmd->scsi_done(scmd); + scsi_done(scmd); } dtmprintk(ioc, ioc_info(ioc, "completing %d cmds\n", count)); } @@ -5139,13 +5139,13 @@ scsih_qcmd(struct Scsi_Host *shost, struct scsi_cmnd *scmd) sas_device_priv_data = scmd->device->hostdata; if (!sas_device_priv_data || !sas_device_priv_data->sas_target) { scmd->result = DID_NO_CONNECT << 16; - scmd->scsi_done(scmd); + scsi_done(scmd); return 0; } if (!(_scsih_allow_scmd_to_device(ioc, scmd))) { scmd->result = DID_NO_CONNECT << 16; - scmd->scsi_done(scmd); + scsi_done(scmd); return 0; } @@ -5155,7 +5155,7 @@ scsih_qcmd(struct Scsi_Host *shost, struct scsi_cmnd *scmd) handle = sas_target_priv_data->handle; if (handle == MPT3SAS_INVALID_DEVICE_HANDLE) { scmd->result = DID_NO_CONNECT << 16; - scmd->scsi_done(scmd); + scsi_done(scmd); return 0; } @@ -5166,7 +5166,7 @@ scsih_qcmd(struct Scsi_Host *shost, struct scsi_cmnd *scmd) } else if (sas_target_priv_data->deleted) { /* device has been deleted */ scmd->result = DID_NO_CONNECT << 16; - scmd->scsi_done(scmd); + scsi_done(scmd); return 0; } else if (sas_target_priv_data->tm_busy || sas_device_priv_data->block) { @@ -5909,7 +5909,7 @@ _scsih_io_done(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 msix_index, u32 reply) scsi_dma_unmap(scmd); mpt3sas_base_free_smid(ioc, smid); - scmd->scsi_done(scmd); + scsi_done(scmd); return 0; } From ca495999075b4b83e6b206a10aa726863dd1c83d Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 7 Oct 2021 13:28:48 -0700 Subject: [PATCH 164/279] scsi: mvumi: Call scsi_done() directly Conditional statements are faster than indirect calls. Hence call scsi_done() directly. Link: https://lore.kernel.org/r/20211007202923.2174984-54-bvanassche@acm.org Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/mvumi.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/mvumi.c b/drivers/scsi/mvumi.c index 4d251bf630a3..904de62c974c 100644 --- a/drivers/scsi/mvumi.c +++ b/drivers/scsi/mvumi.c @@ -1328,7 +1328,7 @@ static void mvumi_complete_cmd(struct mvumi_hba *mhba, struct mvumi_cmd *cmd, dma_unmap_sg(&mhba->pdev->dev, scsi_sglist(scmd), scsi_sg_count(scmd), scmd->sc_data_direction); - cmd->scmd->scsi_done(scmd); + scsi_done(scmd); mvumi_return_cmd(mhba, cmd); } @@ -2104,7 +2104,7 @@ static int mvumi_queue_command(struct Scsi_Host *shost, out_return_cmd: mvumi_return_cmd(mhba, cmd); - scmd->scsi_done(scmd); + scsi_done(scmd); spin_unlock_irqrestore(shost->host_lock, irq_flags); return 0; } From 0061e3f5e0c23383e5c7e62b4e6bf4bc5b05004e Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 7 Oct 2021 13:28:49 -0700 Subject: [PATCH 165/279] scsi: myrb: Call scsi_done() directly Conditional statements are faster than indirect calls. Hence call scsi_done() directly. Link: https://lore.kernel.org/r/20211007202923.2174984-55-bvanassche@acm.org Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/myrb.c | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/drivers/scsi/myrb.c b/drivers/scsi/myrb.c index a4a88323e020..e8a7bcce4674 100644 --- a/drivers/scsi/myrb.c +++ b/drivers/scsi/myrb.c @@ -1282,7 +1282,7 @@ static int myrb_pthru_queuecommand(struct Scsi_Host *shost, if (nsge > 1) { dma_pool_free(cb->dcdb_pool, dcdb, dcdb_addr); scmd->result = (DID_ERROR << 16); - scmd->scsi_done(scmd); + scsi_done(scmd); return 0; } @@ -1436,13 +1436,13 @@ static int myrb_ldev_queuecommand(struct Scsi_Host *shost, dev_dbg(&shost->shost_gendev, "ldev %u in state %x, skip\n", sdev->id, ldev_info ? ldev_info->state : 0xff); scmd->result = (DID_BAD_TARGET << 16); - scmd->scsi_done(scmd); + scsi_done(scmd); return 0; } switch (scmd->cmnd[0]) { case TEST_UNIT_READY: scmd->result = (DID_OK << 16); - scmd->scsi_done(scmd); + scsi_done(scmd); return 0; case INQUIRY: if (scmd->cmnd[1] & 1) { @@ -1452,11 +1452,11 @@ static int myrb_ldev_queuecommand(struct Scsi_Host *shost, myrb_inquiry(cb, scmd); scmd->result = (DID_OK << 16); } - scmd->scsi_done(scmd); + scsi_done(scmd); return 0; case SYNCHRONIZE_CACHE: scmd->result = (DID_OK << 16); - scmd->scsi_done(scmd); + scsi_done(scmd); return 0; case MODE_SENSE: if ((scmd->cmnd[2] & 0x3F) != 0x3F && @@ -1467,25 +1467,25 @@ static int myrb_ldev_queuecommand(struct Scsi_Host *shost, myrb_mode_sense(cb, scmd, ldev_info); scmd->result = (DID_OK << 16); } - scmd->scsi_done(scmd); + scsi_done(scmd); return 0; case READ_CAPACITY: if ((scmd->cmnd[1] & 1) || (scmd->cmnd[8] & 1)) { /* Illegal request, invalid field in CDB */ scsi_build_sense(scmd, 0, ILLEGAL_REQUEST, 0x24, 0); - scmd->scsi_done(scmd); + scsi_done(scmd); return 0; } lba = get_unaligned_be32(&scmd->cmnd[2]); if (lba) { /* Illegal request, invalid field in CDB */ scsi_build_sense(scmd, 0, ILLEGAL_REQUEST, 0x24, 0); - scmd->scsi_done(scmd); + scsi_done(scmd); return 0; } myrb_read_capacity(cb, scmd, ldev_info); - scmd->scsi_done(scmd); + scsi_done(scmd); return 0; case REQUEST_SENSE: myrb_request_sense(cb, scmd); @@ -1499,13 +1499,13 @@ static int myrb_ldev_queuecommand(struct Scsi_Host *shost, /* Assume good status */ scmd->result = (DID_OK << 16); } - scmd->scsi_done(scmd); + scsi_done(scmd); return 0; case READ_6: if (ldev_info->state == MYRB_DEVICE_WO) { /* Data protect, attempt to read invalid data */ scsi_build_sense(scmd, 0, DATA_PROTECT, 0x21, 0x06); - scmd->scsi_done(scmd); + scsi_done(scmd); return 0; } fallthrough; @@ -1519,7 +1519,7 @@ static int myrb_ldev_queuecommand(struct Scsi_Host *shost, if (ldev_info->state == MYRB_DEVICE_WO) { /* Data protect, attempt to read invalid data */ scsi_build_sense(scmd, 0, DATA_PROTECT, 0x21, 0x06); - scmd->scsi_done(scmd); + scsi_done(scmd); return 0; } fallthrough; @@ -1533,7 +1533,7 @@ static int myrb_ldev_queuecommand(struct Scsi_Host *shost, if (ldev_info->state == MYRB_DEVICE_WO) { /* Data protect, attempt to read invalid data */ scsi_build_sense(scmd, 0, DATA_PROTECT, 0x21, 0x06); - scmd->scsi_done(scmd); + scsi_done(scmd); return 0; } fallthrough; @@ -1546,7 +1546,7 @@ static int myrb_ldev_queuecommand(struct Scsi_Host *shost, default: /* Illegal request, invalid opcode */ scsi_build_sense(scmd, 0, ILLEGAL_REQUEST, 0x20, 0); - scmd->scsi_done(scmd); + scsi_done(scmd); return 0; } @@ -1610,7 +1610,7 @@ static int myrb_queuecommand(struct Scsi_Host *shost, if (sdev->channel > myrb_logical_channel(shost)) { scmd->result = (DID_BAD_TARGET << 16); - scmd->scsi_done(scmd); + scsi_done(scmd); return 0; } if (sdev->channel == myrb_logical_channel(shost)) @@ -2361,7 +2361,7 @@ static void myrb_handle_scsi(struct myrb_hba *cb, struct myrb_cmdblk *cmd_blk, scmd->result = (DID_ERROR << 16); break; } - scmd->scsi_done(scmd); + scsi_done(scmd); } static void myrb_handle_cmdblk(struct myrb_hba *cb, struct myrb_cmdblk *cmd_blk) From 1c21a4f495cfb0a0d7f6c6c6fb36df849ccd3816 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 7 Oct 2021 13:28:50 -0700 Subject: [PATCH 166/279] scsi: myrs: Call scsi_done() directly Conditional statements are faster than indirect calls. Hence call scsi_done() directly. Link: https://lore.kernel.org/r/20211007202923.2174984-56-bvanassche@acm.org Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/myrs.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/scsi/myrs.c b/drivers/scsi/myrs.c index 07f274afd7e5..2ffe3cadda66 100644 --- a/drivers/scsi/myrs.c +++ b/drivers/scsi/myrs.c @@ -1595,14 +1595,14 @@ static int myrs_queuecommand(struct Scsi_Host *shost, if (!scmd->device->hostdata) { scmd->result = (DID_NO_CONNECT << 16); - scmd->scsi_done(scmd); + scsi_done(scmd); return 0; } switch (scmd->cmnd[0]) { case REPORT_LUNS: scsi_build_sense(scmd, 0, ILLEGAL_REQUEST, 0x20, 0x0); - scmd->scsi_done(scmd); + scsi_done(scmd); return 0; case MODE_SENSE: if (scmd->device->channel >= cs->ctlr_info->physchan_present) { @@ -1616,7 +1616,7 @@ static int myrs_queuecommand(struct Scsi_Host *shost, myrs_mode_sense(cs, scmd, ldev_info); scmd->result = (DID_OK << 16); } - scmd->scsi_done(scmd); + scsi_done(scmd); return 0; } break; @@ -1756,7 +1756,7 @@ static int myrs_queuecommand(struct Scsi_Host *shost, if (WARN_ON(!hw_sgl)) { scsi_dma_unmap(scmd); scmd->result = (DID_ERROR << 16); - scmd->scsi_done(scmd); + scsi_done(scmd); return 0; } hw_sgl->sge_addr = (u64)sg_dma_address(sgl); @@ -2083,7 +2083,7 @@ static void myrs_handle_scsi(struct myrs_hba *cs, struct myrs_cmdblk *cmd_blk, scmd->result = (DID_BAD_TARGET << 16); else scmd->result = (DID_OK << 16) | status; - scmd->scsi_done(scmd); + scsi_done(scmd); } static void myrs_handle_cmdblk(struct myrs_hba *cs, struct myrs_cmdblk *cmd_blk) From f0f4f79a4f7d4d6109b9f927b6284c06b14b1b2f Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 7 Oct 2021 13:28:52 -0700 Subject: [PATCH 167/279] scsi: ncr53c8xx: Call scsi_done() directly Conditional statements are faster than indirect calls. Hence call scsi_done() directly. Link: https://lore.kernel.org/r/20211007202923.2174984-58-bvanassche@acm.org Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/ncr53c8xx.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/scsi/ncr53c8xx.c b/drivers/scsi/ncr53c8xx.c index 2b8c6fa5e775..6ad43a98409c 100644 --- a/drivers/scsi/ncr53c8xx.c +++ b/drivers/scsi/ncr53c8xx.c @@ -4003,7 +4003,7 @@ static inline void ncr_flush_done_cmds(struct scsi_cmnd *lcmd) while (lcmd) { cmd = lcmd; lcmd = (struct scsi_cmnd *) cmd->host_scribble; - cmd->scsi_done(cmd); + scsi_done(cmd); } } @@ -7862,7 +7862,6 @@ static int ncr53c8xx_queue_command_lck (struct scsi_cmnd *cmd, void (*done)(stru printk("ncr53c8xx_queue_command\n"); #endif - cmd->scsi_done = done; cmd->host_scribble = NULL; cmd->__data_mapped = 0; cmd->__data_mapping = 0; From 48760367a401c4b801f07c4c8326ebf0001fbba6 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 7 Oct 2021 13:28:53 -0700 Subject: [PATCH 168/279] scsi: nsp32: Call scsi_done() directly Conditional statements are faster than indirect calls. Hence call scsi_done() directly. Link: https://lore.kernel.org/r/20211007202923.2174984-59-bvanassche@acm.org Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/nsp32.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/scsi/nsp32.c b/drivers/scsi/nsp32.c index bc9d29e5fdba..1057b6fd7569 100644 --- a/drivers/scsi/nsp32.c +++ b/drivers/scsi/nsp32.c @@ -945,7 +945,6 @@ static int nsp32_queuecommand_lck(struct scsi_cmnd *SCpnt, show_command(SCpnt); - SCpnt->scsi_done = done; data->CurrentSC = SCpnt; SCpnt->SCp.Status = SAM_STAT_CHECK_CONDITION; scsi_set_resid(SCpnt, scsi_bufflen(SCpnt)); @@ -1546,7 +1545,7 @@ static void nsp32_scsi_done(struct scsi_cmnd *SCpnt) /* * call scsi_done */ - (*SCpnt->scsi_done)(SCpnt); + scsi_done(SCpnt); /* * reset parameters From ca0d62d29bb129b55627c7319ecbdc6145ec7c39 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 7 Oct 2021 13:28:54 -0700 Subject: [PATCH 169/279] scsi: pcmcia: Call scsi_done() directly Conditional statements are faster than indirect calls. Hence call scsi_done() directly. Link: https://lore.kernel.org/r/20211007202923.2174984-60-bvanassche@acm.org Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/pcmcia/nsp_cs.c | 4 +--- drivers/scsi/pcmcia/sym53c500_cs.c | 3 +-- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/drivers/scsi/pcmcia/nsp_cs.c b/drivers/scsi/pcmcia/nsp_cs.c index 7c0f931e55e8..0271d534133a 100644 --- a/drivers/scsi/pcmcia/nsp_cs.c +++ b/drivers/scsi/pcmcia/nsp_cs.c @@ -178,7 +178,7 @@ static void nsp_scsi_done(struct scsi_cmnd *SCpnt) data->CurrentSC = NULL; - SCpnt->scsi_done(SCpnt); + scsi_done(SCpnt); } static int nsp_queuecommand_lck(struct scsi_cmnd *SCpnt, @@ -197,8 +197,6 @@ static int nsp_queuecommand_lck(struct scsi_cmnd *SCpnt, scsi_bufflen(SCpnt), scsi_sg_count(SCpnt)); //nsp_dbg(NSP_DEBUG_QUEUECOMMAND, "before CurrentSC=0x%p", data->CurrentSC); - SCpnt->scsi_done = done; - if (data->CurrentSC != NULL) { nsp_msg(KERN_DEBUG, "CurrentSC!=NULL this can't be happen"); SCpnt->result = DID_BAD_TARGET << 16; diff --git a/drivers/scsi/pcmcia/sym53c500_cs.c b/drivers/scsi/pcmcia/sym53c500_cs.c index a366ff1a3959..d2adda815d7b 100644 --- a/drivers/scsi/pcmcia/sym53c500_cs.c +++ b/drivers/scsi/pcmcia/sym53c500_cs.c @@ -492,7 +492,7 @@ out: idle_out: curSC->SCp.phase = idle; - curSC->scsi_done(curSC); + scsi_done(curSC); goto out; } @@ -556,7 +556,6 @@ SYM53C500_queue_lck(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *)) VDEB(printk("\n")); data->current_SC = SCpnt; - data->current_SC->scsi_done = done; data->current_SC->SCp.phase = command_ph; data->current_SC->SCp.Status = 0; data->current_SC->SCp.Message = 0; From f13cc234bec93959d49b7db9e63f74272b282e5c Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 7 Oct 2021 13:28:55 -0700 Subject: [PATCH 170/279] scsi: pmcraid: Call scsi_done() directly Conditional statements are faster than indirect calls. Hence call scsi_done() directly. Link: https://lore.kernel.org/r/20211007202923.2174984-61-bvanassche@acm.org Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/pmcraid.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/drivers/scsi/pmcraid.c b/drivers/scsi/pmcraid.c index bffd9a9349e7..11f36fd4e62f 100644 --- a/drivers/scsi/pmcraid.c +++ b/drivers/scsi/pmcraid.c @@ -837,7 +837,7 @@ static void pmcraid_erp_done(struct pmcraid_cmd *cmd) scsi_dma_unmap(scsi_cmd); pmcraid_return_cmd(cmd); - scsi_cmd->scsi_done(scsi_cmd); + scsi_done(scsi_cmd); } /** @@ -2017,7 +2017,7 @@ static void pmcraid_fail_outstanding_cmds(struct pmcraid_instance *pinstance) le32_to_cpu(resp) >> 2, cmd->ioa_cb->ioarcb.cdb[0], scsi_cmd->result); - scsi_cmd->scsi_done(scsi_cmd); + scsi_done(scsi_cmd); } else if (cmd->cmd_done == pmcraid_internal_done || cmd->cmd_done == pmcraid_erp_done) { cmd->cmd_done(cmd); @@ -2814,7 +2814,7 @@ static int _pmcraid_io_done(struct pmcraid_cmd *cmd, int reslen, int ioasc) if (rc == 0) { scsi_dma_unmap(scsi_cmd); - scsi_cmd->scsi_done(scsi_cmd); + scsi_done(scsi_cmd); } return rc; @@ -3328,7 +3328,6 @@ static int pmcraid_queuecommand_lck( pinstance = (struct pmcraid_instance *)scsi_cmd->device->host->hostdata; fw_version = be16_to_cpu(pinstance->inq_data->fw_version); - scsi_cmd->scsi_done = done; res = scsi_cmd->device->hostdata; scsi_cmd->result = (DID_OK << 16); @@ -3338,7 +3337,7 @@ static int pmcraid_queuecommand_lck( if (pinstance->ioa_state == IOA_STATE_DEAD) { pmcraid_info("IOA is dead, but queuecommand is scheduled\n"); scsi_cmd->result = (DID_NO_CONNECT << 16); - scsi_cmd->scsi_done(scsi_cmd); + scsi_done(scsi_cmd); return 0; } @@ -3351,7 +3350,7 @@ static int pmcraid_queuecommand_lck( */ if (scsi_cmd->cmnd[0] == SYNCHRONIZE_CACHE) { pmcraid_info("SYNC_CACHE(0x35), completing in driver itself\n"); - scsi_cmd->scsi_done(scsi_cmd); + scsi_done(scsi_cmd); return 0; } From 7bc195c7513430aef09b3ef1f7438b58b3b7f12b Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 7 Oct 2021 13:28:56 -0700 Subject: [PATCH 171/279] scsi: ppa: Call scsi_done() directly Conditional statements are faster than indirect calls. Hence call scsi_done() directly. Link: https://lore.kernel.org/r/20211007202923.2174984-62-bvanassche@acm.org Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/ppa.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/scsi/ppa.c b/drivers/scsi/ppa.c index 977315fdc254..799ad8562e24 100644 --- a/drivers/scsi/ppa.c +++ b/drivers/scsi/ppa.c @@ -665,7 +665,7 @@ static void ppa_interrupt(struct work_struct *work) dev->cur_cmd = NULL; - cmd->scsi_done(cmd); + scsi_done(cmd); } static int ppa_engine(ppa_struct *dev, struct scsi_cmnd *cmd) @@ -798,7 +798,6 @@ static int ppa_queuecommand_lck(struct scsi_cmnd *cmd, dev->failed = 0; dev->jstart = jiffies; dev->cur_cmd = cmd; - cmd->scsi_done = done; cmd->result = DID_ERROR << 16; /* default return code */ cmd->SCp.phase = 0; /* bus free */ From 3ca2385af90534278afc95f79bd465211a5e3103 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 7 Oct 2021 13:28:57 -0700 Subject: [PATCH 172/279] scsi: ps3rom: Call scsi_done() directly Conditional statements are faster than indirect calls. Hence call scsi_done() directly. Link: https://lore.kernel.org/r/20211007202923.2174984-63-bvanassche@acm.org Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/ps3rom.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/scsi/ps3rom.c b/drivers/scsi/ps3rom.c index 0f4b99d92f12..08e970300b3f 100644 --- a/drivers/scsi/ps3rom.c +++ b/drivers/scsi/ps3rom.c @@ -209,7 +209,6 @@ static int ps3rom_queuecommand_lck(struct scsi_cmnd *cmd, int res; priv->curr_cmd = cmd; - cmd->scsi_done = done; opcode = cmd->cmnd[0]; /* @@ -237,7 +236,7 @@ static int ps3rom_queuecommand_lck(struct scsi_cmnd *cmd, scsi_build_sense(cmd, 0, ILLEGAL_REQUEST, 0, 0); cmd->result = res; priv->curr_cmd = NULL; - cmd->scsi_done(cmd); + scsi_done(cmd); } return 0; @@ -321,7 +320,7 @@ static irqreturn_t ps3rom_interrupt(int irq, void *data) done: priv->curr_cmd = NULL; - cmd->scsi_done(cmd); + scsi_done(cmd); return IRQ_HANDLED; } From ef697683d3eb6455c911212513256b1633fcec62 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 7 Oct 2021 13:28:58 -0700 Subject: [PATCH 173/279] scsi: qedf: Call scsi_done() directly Conditional statements are faster than indirect calls. Hence call scsi_done() directly. Link: https://lore.kernel.org/r/20211007202923.2174984-64-bvanassche@acm.org Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/qedf/qedf_io.c | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/drivers/scsi/qedf/qedf_io.c b/drivers/scsi/qedf/qedf_io.c index 3404782988d5..14aa544b0bc3 100644 --- a/drivers/scsi/qedf/qedf_io.c +++ b/drivers/scsi/qedf/qedf_io.c @@ -947,7 +947,7 @@ qedf_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *sc_cmd) "Number of SG elements %d exceeds what hardware limitation of %d.\n", num_sgs, QEDF_MAX_BDS_PER_CMD); sc_cmd->result = DID_ERROR; - sc_cmd->scsi_done(sc_cmd); + scsi_done(sc_cmd); return 0; } @@ -957,7 +957,7 @@ qedf_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *sc_cmd) "Returning DNC as unloading or stop io, flags 0x%lx.\n", qedf->flags); sc_cmd->result = DID_NO_CONNECT << 16; - sc_cmd->scsi_done(sc_cmd); + scsi_done(sc_cmd); return 0; } @@ -966,7 +966,7 @@ qedf_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *sc_cmd) "Completing sc_cmd=%p DID_NO_CONNECT as MSI-X is not enabled.\n", sc_cmd); sc_cmd->result = DID_NO_CONNECT << 16; - sc_cmd->scsi_done(sc_cmd); + scsi_done(sc_cmd); return 0; } @@ -976,7 +976,7 @@ qedf_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *sc_cmd) "fc_remote_port_chkready failed=0x%x for port_id=0x%06x.\n", rval, rport->port_id); sc_cmd->result = rval; - sc_cmd->scsi_done(sc_cmd); + scsi_done(sc_cmd); return 0; } @@ -1313,7 +1313,7 @@ out: io_req->sc_cmd = NULL; sc_cmd->SCp.ptr = NULL; - sc_cmd->scsi_done(sc_cmd); + scsi_done(sc_cmd); kref_put(&io_req->refcount, qedf_release_cmd); } @@ -1386,13 +1386,6 @@ void qedf_scsi_done(struct qedf_ctx *qedf, struct qedf_ioreq *io_req, goto bad_scsi_ptr; } - if (!sc_cmd->scsi_done) { - QEDF_ERR(&qedf->dbg_ctx, - "sc_cmd->scsi_done for sc_cmd %p is NULL.\n", - sc_cmd); - goto bad_scsi_ptr; - } - qedf_unmap_sg_list(qedf, io_req); sc_cmd->result = result << 16; @@ -1417,7 +1410,7 @@ void qedf_scsi_done(struct qedf_ctx *qedf, struct qedf_ioreq *io_req, io_req->sc_cmd = NULL; sc_cmd->SCp.ptr = NULL; - sc_cmd->scsi_done(sc_cmd); + scsi_done(sc_cmd); kref_put(&io_req->refcount, qedf_release_cmd); return; From 2d1609afd6d79d0d234a63f4dac4b0559f3ac5a4 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 7 Oct 2021 13:28:59 -0700 Subject: [PATCH 174/279] scsi: qla1280: Call scsi_done() directly Conditional statements are faster than indirect calls. Hence call scsi_done() directly. Link: https://lore.kernel.org/r/20211007202923.2174984-65-bvanassche@acm.org Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/qla1280.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/scsi/qla1280.c b/drivers/scsi/qla1280.c index d0b4e063bfe1..c508a6e20519 100644 --- a/drivers/scsi/qla1280.c +++ b/drivers/scsi/qla1280.c @@ -697,7 +697,6 @@ qla1280_queuecommand_lck(struct scsi_cmnd *cmd, void (*fn)(struct scsi_cmnd *)) struct srb *sp = (struct srb *)CMD_SP(cmd); int status; - cmd->scsi_done = fn; sp->cmd = cmd; sp->flags = 0; sp->wait = NULL; @@ -755,7 +754,7 @@ _qla1280_wait_for_single_command(struct scsi_qla_host *ha, struct srb *sp, sp->wait = NULL; if(CMD_HANDLE(cmd) == COMPLETED_HANDLE) { status = SUCCESS; - (*cmd->scsi_done)(cmd); + scsi_done(cmd); } return status; } @@ -1277,7 +1276,7 @@ qla1280_done(struct scsi_qla_host *ha) ha->actthreads--; if (sp->wait == NULL) - (*(cmd)->scsi_done)(cmd); + scsi_done(cmd); else complete(sp->wait); } From 79e30b884a0144418a594cf3498961780874fadc Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 7 Oct 2021 13:29:00 -0700 Subject: [PATCH 175/279] scsi: qla2xxx: Call scsi_done() directly Conditional statements are faster than indirect calls. Hence call scsi_done() directly. Link: https://lore.kernel.org/r/20211007202923.2174984-66-bvanassche@acm.org Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/qla2xxx/qla_os.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index 03ff2596715b..5d576a3ba14f 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c @@ -737,7 +737,7 @@ void qla2x00_sp_compl(srb_t *sp, int res) sp->free(sp); cmd->result = res; CMD_SP(cmd) = NULL; - cmd->scsi_done(cmd); + scsi_done(cmd); if (comp) complete(comp); } @@ -828,7 +828,7 @@ void qla2xxx_qpair_sp_compl(srb_t *sp, int res) sp->free(sp); cmd->result = res; CMD_SP(cmd) = NULL; - cmd->scsi_done(cmd); + scsi_done(cmd); if (comp) complete(comp); } @@ -950,7 +950,7 @@ qc24_target_busy: return SCSI_MLQUEUE_TARGET_BUSY; qc24_fail_command: - cmd->scsi_done(cmd); + scsi_done(cmd); return 0; } @@ -1038,7 +1038,7 @@ qc24_target_busy: return SCSI_MLQUEUE_TARGET_BUSY; qc24_fail_command: - cmd->scsi_done(cmd); + scsi_done(cmd); return 0; } From fdcfbd6517d9bff7afe31119a9ee7f386cf19b89 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 7 Oct 2021 13:29:01 -0700 Subject: [PATCH 176/279] scsi: qla4xxx: Call scsi_done() directly Conditional statements are faster than indirect calls. Hence call scsi_done() directly. Link: https://lore.kernel.org/r/20211007202923.2174984-67-bvanassche@acm.org Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/qla4xxx/ql4_os.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/qla4xxx/ql4_os.c b/drivers/scsi/qla4xxx/ql4_os.c index f1ea65c6e5f5..76d0b59a9982 100644 --- a/drivers/scsi/qla4xxx/ql4_os.c +++ b/drivers/scsi/qla4xxx/ql4_os.c @@ -4080,7 +4080,7 @@ void qla4xxx_srb_compl(struct kref *ref) mempool_free(srb, ha->srb_mempool); - cmd->scsi_done(cmd); + scsi_done(cmd); } /** @@ -4154,7 +4154,7 @@ qc_host_busy: return SCSI_MLQUEUE_HOST_BUSY; qc_fail_command: - cmd->scsi_done(cmd); + scsi_done(cmd); return 0; } From da65bc05cf9166478c38b63ec05b8c9fad2f7962 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 7 Oct 2021 13:29:02 -0700 Subject: [PATCH 177/279] scsi: qlogicfas408: Call scsi_done() directly Conditional statements are faster than indirect calls. Hence call scsi_done() directly. Link: https://lore.kernel.org/r/20211007202923.2174984-68-bvanassche@acm.org Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/qlogicfas408.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/scsi/qlogicfas408.c b/drivers/scsi/qlogicfas408.c index 3bbe0b5545d9..5471c046a4b7 100644 --- a/drivers/scsi/qlogicfas408.c +++ b/drivers/scsi/qlogicfas408.c @@ -442,7 +442,7 @@ static void ql_ihandl(void *dev_id) * If result is CHECK CONDITION done calls qcommand to request * sense */ - (icmd->scsi_done) (icmd); + scsi_done(icmd); } irqreturn_t qlogicfas408_ihandl(int irq, void *dev_id) @@ -473,7 +473,6 @@ static int qlogicfas408_queuecommand_lck(struct scsi_cmnd *cmd, return 0; } - cmd->scsi_done = done; /* wait for the last command's interrupt to finish */ while (priv->qlcmd != NULL) { barrier(); From c33a2dca9853584c97588bc4eb2ca10a770d0a28 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 7 Oct 2021 13:29:03 -0700 Subject: [PATCH 178/279] scsi: qlogicpti: Call scsi_done() directly Conditional statements are faster than indirect calls. Hence call scsi_done() directly. Link: https://lore.kernel.org/r/20211007202923.2174984-69-bvanassche@acm.org Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/qlogicpti.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/scsi/qlogicpti.c b/drivers/scsi/qlogicpti.c index 8e7e833a36cc..30b5e98b5de0 100644 --- a/drivers/scsi/qlogicpti.c +++ b/drivers/scsi/qlogicpti.c @@ -1021,8 +1021,6 @@ static int qlogicpti_queuecommand_lck(struct scsi_cmnd *Cmnd, void (*done)(struc u_int out_ptr; int in_ptr; - Cmnd->scsi_done = done; - in_ptr = qpti->req_in_ptr; cmd = (struct Command_Entry *) &qpti->req_cpu[in_ptr]; out_ptr = sbus_readw(qpti->qregs + MBOX4); @@ -1214,7 +1212,7 @@ static irqreturn_t qpti_intr(int irq, void *dev_id) struct scsi_cmnd *next; next = (struct scsi_cmnd *) dq->host_scribble; - dq->scsi_done(dq); + scsi_done(dq); dq = next; } while (dq != NULL); } From 6c2c7d6aa439e1ee0885d7c32d999df0124607d5 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 7 Oct 2021 13:29:04 -0700 Subject: [PATCH 179/279] scsi: scsi_debug: Call scsi_done() directly Conditional statements are faster than indirect calls. Hence call scsi_done() directly. Link: https://lore.kernel.org/r/20211007202923.2174984-70-bvanassche@acm.org Acked-by: Douglas Gilbert Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/scsi_debug.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c index 66f507469a31..407f1ce15118 100644 --- a/drivers/scsi/scsi_debug.c +++ b/drivers/scsi/scsi_debug.c @@ -4809,7 +4809,7 @@ static void sdebug_q_cmd_complete(struct sdebug_defer *sd_dp) pr_info("bypassing scsi_done() due to aborted cmd\n"); return; } - scp->scsi_done(scp); /* callback to mid level */ + scsi_done(scp); /* callback to mid level */ } /* When high resolution timer goes off this function is called. */ @@ -5524,7 +5524,7 @@ static int schedule_resp(struct scsi_cmnd *cmnd, struct sdebug_dev_info *devip, if (new_sd_dp) kfree(sd_dp); /* call scsi_done() from this thread */ - cmnd->scsi_done(cmnd); + scsi_done(cmnd); return 0; } /* otherwise reduce kt by elapsed time */ @@ -5604,7 +5604,7 @@ respond_in_thread: /* call back to mid-layer using invocation thread */ cmnd->result &= ~SDEG_RES_IMMED_MASK; if (cmnd->result == 0 && scsi_result != 0) cmnd->result = scsi_result; - cmnd->scsi_done(cmnd); + scsi_done(cmnd); return 0; } @@ -7363,7 +7363,7 @@ static int sdebug_blk_mq_poll(struct Scsi_Host *shost, unsigned int queue_num) } sd_dp->defer_t = SDEB_DEFER_NONE; spin_unlock_irqrestore(&sqp->qc_lock, iflags); - scp->scsi_done(scp); /* callback to mid level */ + scsi_done(scp); /* callback to mid level */ spin_lock_irqsave(&sqp->qc_lock, iflags); num_entries++; } From 0ca19080578456ed46b7e2abb283feb768ff7a19 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 7 Oct 2021 13:29:05 -0700 Subject: [PATCH 180/279] scsi: smartpqi: Call scsi_done() directly Conditional statements are faster than indirect calls. Hence call scsi_done() directly. Link: https://lore.kernel.org/r/20211007202923.2174984-71-bvanassche@acm.org Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/smartpqi/smartpqi_init.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c index b966ce3b4385..54c12b149fda 100644 --- a/drivers/scsi/smartpqi/smartpqi_init.c +++ b/drivers/scsi/smartpqi/smartpqi_init.c @@ -195,7 +195,7 @@ static char *pqi_raid_level_to_string(u8 raid_level) static inline void pqi_scsi_done(struct scsi_cmnd *scmd) { pqi_prep_for_scsi_done(scmd); - scmd->scsi_done(scmd); + scsi_done(scmd); } static inline void pqi_disable_write_same(struct scsi_device *sdev) From 70a5caf11f8c5c8ab45c01fb6414c1b5be5c2398 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 7 Oct 2021 13:29:06 -0700 Subject: [PATCH 181/279] scsi: snic: Call scsi_done() directly Conditional statements are faster than indirect calls. Hence call scsi_done() directly. Link: https://lore.kernel.org/r/20211007202923.2174984-72-bvanassche@acm.org Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/snic/snic_scsi.c | 33 ++++++++++++++------------------- 1 file changed, 14 insertions(+), 19 deletions(-) diff --git a/drivers/scsi/snic/snic_scsi.c b/drivers/scsi/snic/snic_scsi.c index 43a950185e24..5f17666f3e1d 100644 --- a/drivers/scsi/snic/snic_scsi.c +++ b/drivers/scsi/snic/snic_scsi.c @@ -342,7 +342,7 @@ snic_queuecommand(struct Scsi_Host *shost, struct scsi_cmnd *sc) SNIC_HOST_ERR(shost, "Tgt %p id %d Not Ready.\n", tgt, tgt->id); atomic64_inc(&snic->s_stats.misc.tgt_not_rdy); sc->result = ret; - sc->scsi_done(sc); + scsi_done(sc); return 0; } @@ -676,8 +676,7 @@ snic_icmnd_cmpl_handler(struct snic *snic, struct snic_fw_req *fwreq) SNIC_TRC_CMD(sc), SNIC_TRC_CMD_STATE_FLAGS(sc)); - if (sc->scsi_done) - sc->scsi_done(sc); + scsi_done(sc); snic_stats_update_io_cmpl(&snic->s_stats); } /* end of snic_icmnd_cmpl_handler */ @@ -855,14 +854,12 @@ snic_process_itmf_cmpl(struct snic *snic, snic_release_req_buf(snic, rqi, sc); - if (sc->scsi_done) { - SNIC_TRC(snic->shost->host_no, cmnd_id, (ulong) sc, - jiffies_to_msecs(jiffies - start_time), - (ulong) fwreq, SNIC_TRC_CMD(sc), - SNIC_TRC_CMD_STATE_FLAGS(sc)); + SNIC_TRC(snic->shost->host_no, cmnd_id, (ulong) sc, + jiffies_to_msecs(jiffies - start_time), + (ulong) fwreq, SNIC_TRC_CMD(sc), + SNIC_TRC_CMD_STATE_FLAGS(sc)); - sc->scsi_done(sc); - } + scsi_done(sc); break; @@ -1475,7 +1472,7 @@ snic_abort_finish(struct snic *snic, struct scsi_cmnd *sc) * Call scsi_done to complete the IO. */ sc->result = (DID_ERROR << 16); - sc->scsi_done(sc); + scsi_done(sc); break; default: @@ -1855,7 +1852,7 @@ snic_dr_clean_single_req(struct snic *snic, snic_release_req_buf(snic, rqi, sc); sc->result = (DID_ERROR << 16); - sc->scsi_done(sc); + scsi_done(sc); ret = 0; @@ -2500,14 +2497,12 @@ cleanup: /* Update IO stats */ snic_stats_update_io_cmpl(&snic->s_stats); - if (sc->scsi_done) { - SNIC_TRC(snic->shost->host_no, tag, (ulong) sc, - jiffies_to_msecs(jiffies - st_time), 0, - SNIC_TRC_CMD(sc), - SNIC_TRC_CMD_STATE_FLAGS(sc)); + SNIC_TRC(snic->shost->host_no, tag, (ulong) sc, + jiffies_to_msecs(jiffies - st_time), 0, + SNIC_TRC_CMD(sc), + SNIC_TRC_CMD_STATE_FLAGS(sc)); - sc->scsi_done(sc); - } + scsi_done(sc); } } /* end of snic_scsi_cleanup */ From 4acf838e80baaeaf9c5a139eaa2b54f2b95cf13f Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 7 Oct 2021 13:29:07 -0700 Subject: [PATCH 182/279] scsi: stex: Call scsi_done() directly Conditional statements are faster than indirect calls. Hence call scsi_done() directly. Link: https://lore.kernel.org/r/20211007202923.2174984-73-bvanassche@acm.org Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/stex.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/scsi/stex.c b/drivers/scsi/stex.c index f1ba7f5b52a8..2f96a2fdaa40 100644 --- a/drivers/scsi/stex.c +++ b/drivers/scsi/stex.c @@ -574,7 +574,7 @@ static void return_abnormal_state(struct st_hba *hba, int status) if (ccb->cmd) { scsi_dma_unmap(ccb->cmd); ccb->cmd->result = status << 16; - ccb->cmd->scsi_done(ccb->cmd); + scsi_done(ccb->cmd); ccb->cmd = NULL; } } @@ -688,8 +688,6 @@ stex_queuecommand_lck(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *)) break; } - cmd->scsi_done = done; - tag = scsi_cmd_to_rq(cmd)->tag; if (unlikely(tag >= host->can_queue)) @@ -764,7 +762,7 @@ static void stex_scsi_done(struct st_ccb *ccb) } cmd->result = result; - cmd->scsi_done(cmd); + scsi_done(cmd); } static void stex_copy_data(struct st_ccb *ccb, From 0c31fa0e66195bc2aacd90fbfc9fac75d0abada3 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 7 Oct 2021 13:29:08 -0700 Subject: [PATCH 183/279] scsi: storvsc_drv: Call scsi_done() directly Conditional statements are faster than indirect calls. Hence call scsi_done() directly. Link: https://lore.kernel.org/r/20211007202923.2174984-74-bvanassche@acm.org Reviewed-by: Haiyang Zhang Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/storvsc_drv.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c index ebbbc1299c62..70d0b1dd0f75 100644 --- a/drivers/scsi/storvsc_drv.c +++ b/drivers/scsi/storvsc_drv.c @@ -1154,7 +1154,7 @@ static void storvsc_command_completion(struct storvsc_cmd_request *cmd_request, scsi_set_resid(scmnd, cmd_request->payload->range.len - data_transfer_length); - scmnd->scsi_done(scmnd); + scsi_done(scmnd); if (payload_sz > sizeof(struct vmbus_channel_packet_multipage_buffer)) @@ -1753,7 +1753,7 @@ static int storvsc_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *scmnd) * future versions of the host. */ if (!storvsc_scsi_cmd_ok(scmnd)) { - scmnd->scsi_done(scmnd); + scsi_done(scmnd); return 0; } } From 37425f5d07ccc5088b01d5cceb6d3d2309461acd Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 7 Oct 2021 13:29:09 -0700 Subject: [PATCH 184/279] scsi: sym53c8xx_2: Call scsi_done() directly Conditional statements are faster than indirect calls. Hence call scsi_done() directly. Link: https://lore.kernel.org/r/20211007202923.2174984-75-bvanassche@acm.org Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/sym53c8xx_2/sym_glue.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/scsi/sym53c8xx_2/sym_glue.c b/drivers/scsi/sym53c8xx_2/sym_glue.c index 6d0b07b9cb31..76747e180b17 100644 --- a/drivers/scsi/sym53c8xx_2/sym_glue.c +++ b/drivers/scsi/sym53c8xx_2/sym_glue.c @@ -133,7 +133,7 @@ void sym_xpt_done(struct sym_hcb *np, struct scsi_cmnd *cmd) complete(ucmd->eh_done); scsi_dma_unmap(cmd); - cmd->scsi_done(cmd); + scsi_done(cmd); } /* @@ -493,7 +493,6 @@ static int sym53c8xx_queue_command_lck(struct scsi_cmnd *cmd, struct sym_ucmd *ucp = SYM_UCMD_PTR(cmd); int sts = 0; - cmd->scsi_done = done; memset(ucp, 0, sizeof(*ucp)); /* From 35c3730a965722e1b6b13539b9d4fab8116554b5 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 7 Oct 2021 13:46:01 -0700 Subject: [PATCH 185/279] scsi: ufs: Call scsi_done() directly Conditional statements are faster than indirect calls. Hence call scsi_done() directly. Link: https://lore.kernel.org/r/20211007204618.2196847-1-bvanassche@acm.org Reviewed-by: Bean Huo Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/ufs/ufshcd.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index f871f74fd59e..10f5805ae3f6 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -2714,7 +2714,7 @@ static int ufshcd_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd) if (hba->pm_op_in_progress) { hba->force_reset = true; set_host_byte(cmd, DID_BAD_TARGET); - cmd->scsi_done(cmd); + scsi_done(cmd); goto out; } fallthrough; @@ -2723,7 +2723,7 @@ static int ufshcd_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd) goto out; case UFSHCD_STATE_ERROR: set_host_byte(cmd, DID_ERROR); - cmd->scsi_done(cmd); + scsi_done(cmd); goto out; } @@ -5275,7 +5275,7 @@ static void __ufshcd_transfer_req_compl(struct ufs_hba *hba, /* Mark completed command as NULL in LRB */ lrbp->cmd = NULL; /* Do not touch lrbp after scsi done */ - cmd->scsi_done(cmd); + scsi_done(cmd); ufshcd_release(hba); update_scaling = true; } else if (lrbp->command_type == UTP_CMD_TYPE_DEV_MANAGE || From b4194fcb1b511722b7d2bdc1643e1bd237468f65 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 7 Oct 2021 13:46:02 -0700 Subject: [PATCH 186/279] scsi: virtio_scsi: Call scsi_done() directly Conditional statements are faster than indirect calls. Hence call scsi_done() directly. Additionally, update a comment that refers to the REQ_ATOM_COMPLETE flag since that flag has been removed a long time ago. Link: https://lore.kernel.org/r/20211007204618.2196847-2-bvanassche@acm.org Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/virtio_scsi.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/scsi/virtio_scsi.c b/drivers/scsi/virtio_scsi.c index 07d0250f17c3..44fbb0bea190 100644 --- a/drivers/scsi/virtio_scsi.c +++ b/drivers/scsi/virtio_scsi.c @@ -163,7 +163,7 @@ static void virtscsi_complete_cmd(struct virtio_scsi *vscsi, void *buf) VIRTIO_SCSI_SENSE_SIZE)); } - sc->scsi_done(sc); + scsi_done(sc); } static void virtscsi_vq_done(struct virtio_scsi *vscsi, @@ -619,9 +619,8 @@ static int virtscsi_tmf(struct virtio_scsi *vscsi, struct virtio_scsi_cmd *cmd) * we're using independent interrupts (e.g. MSI). Poll the * virtqueues once. * - * In the abort case, sc->scsi_done will do nothing, because - * the block layer must have detected a timeout and as a result - * REQ_ATOM_COMPLETE has been set. + * In the abort case, scsi_done() will do nothing, because the + * command timed out and hence SCMD_STATE_COMPLETE has been set. */ virtscsi_poll_requests(vscsi); From aeb2627dcfd98b57d0a5a8de9d268e586cad6e35 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 7 Oct 2021 13:46:03 -0700 Subject: [PATCH 187/279] scsi: vmw_pvscsi: Call scsi_done() directly Conditional statements are faster than indirect calls. Hence call scsi_done() directly. Link: https://lore.kernel.org/r/20211007204618.2196847-3-bvanassche@acm.org Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/vmw_pvscsi.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/scsi/vmw_pvscsi.c b/drivers/scsi/vmw_pvscsi.c index ce1ba1b93629..7bfa023d0feb 100644 --- a/drivers/scsi/vmw_pvscsi.c +++ b/drivers/scsi/vmw_pvscsi.c @@ -643,7 +643,7 @@ static void pvscsi_complete_request(struct pvscsi_adapter *adapter, "cmd=%p %x ctx=%p result=0x%x status=0x%x,%x\n", cmd, cmd->cmnd[0], ctx, cmd->result, btstat, sdstat); - cmd->scsi_done(cmd); + scsi_done(cmd); } /* @@ -786,7 +786,6 @@ static int pvscsi_queue_lck(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd return SCSI_MLQUEUE_HOST_BUSY; } - cmd->scsi_done = done; op = cmd->cmnd[0]; dev_dbg(&cmd->device->sdev_gendev, @@ -860,7 +859,7 @@ static int pvscsi_abort(struct scsi_cmnd *cmd) * Successfully aborted the command. */ cmd->result = (DID_ABORT << 16); - cmd->scsi_done(cmd); + scsi_done(cmd); out: spin_unlock_irqrestore(&adapter->hw_lock, flags); @@ -887,7 +886,7 @@ static void pvscsi_reset_all(struct pvscsi_adapter *adapter) pvscsi_patch_sense(cmd); pvscsi_release_context(adapter, ctx); cmd->result = (DID_RESET << 16); - cmd->scsi_done(cmd); + scsi_done(cmd); } } } From 9c4f6be7ddecce17684aa93085f2749695f870da Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 7 Oct 2021 13:46:04 -0700 Subject: [PATCH 188/279] scsi: wd33c93: Call scsi_done() directly Conditional statements are faster than indirect calls. Hence call scsi_done() directly. Link: https://lore.kernel.org/r/20211007204618.2196847-4-bvanassche@acm.org Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/wd33c93.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/drivers/scsi/wd33c93.c b/drivers/scsi/wd33c93.c index 4468bc45aaa4..fe28d21c7e93 100644 --- a/drivers/scsi/wd33c93.c +++ b/drivers/scsi/wd33c93.c @@ -376,11 +376,9 @@ wd33c93_queuecommand_lck(struct scsi_cmnd *cmd, /* Set up a few fields in the scsi_cmnd structure for our own use: * - host_scribble is the pointer to the next cmd in the input queue - * - scsi_done points to the routine we call when a cmd is finished * - result is what you'd expect */ cmd->host_scribble = NULL; - cmd->scsi_done = done; cmd->result = 0; /* We use the Scsi_Pointer structure that's included with each command @@ -856,7 +854,7 @@ wd33c93_intr(struct Scsi_Host *instance) cmd->result = DID_NO_CONNECT << 16; hostdata->busy[cmd->device->id] &= ~(1 << (cmd->device->lun & 0xff)); hostdata->state = S_UNCONNECTED; - cmd->scsi_done(cmd); + scsi_done(cmd); /* From esp.c: * There is a window of time within the scsi_done() path @@ -1183,7 +1181,7 @@ wd33c93_intr(struct Scsi_Host *instance) scsi_msg_to_host_byte(cmd, cmd->SCp.Message); set_status_byte(cmd, cmd->SCp.Status); } - cmd->scsi_done(cmd); + scsi_done(cmd); /* We are no longer connected to a target - check to see if * there are commands waiting to be executed. @@ -1270,7 +1268,7 @@ wd33c93_intr(struct Scsi_Host *instance) scsi_msg_to_host_byte(cmd, cmd->SCp.Message); set_status_byte(cmd, cmd->SCp.Status); } - cmd->scsi_done(cmd); + scsi_done(cmd); /* We are no longer connected to a target - check to see if * there are commands waiting to be executed. @@ -1306,7 +1304,7 @@ wd33c93_intr(struct Scsi_Host *instance) scsi_msg_to_host_byte(cmd, cmd->SCp.Message); set_status_byte(cmd, cmd->SCp.Status); } - cmd->scsi_done(cmd); + scsi_done(cmd); break; case S_PRE_TMP_DISC: case S_RUNNING_LEVEL2: @@ -1636,7 +1634,7 @@ wd33c93_abort(struct scsi_cmnd * cmd) ("scsi%d: Abort - removing command from input_Q. ", instance->host_no); enable_irq(cmd->device->host->irq); - cmd->scsi_done(cmd); + scsi_done(cmd); return SUCCESS; } prev = tmp; @@ -1711,7 +1709,7 @@ wd33c93_abort(struct scsi_cmnd * cmd) wd33c93_execute(instance); enable_irq(cmd->device->host->irq); - cmd->scsi_done(cmd); + scsi_done(cmd); return SUCCESS; } From f11e4da6bfc1d0a7823f89afda3f7e61f3f904c4 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 7 Oct 2021 13:46:05 -0700 Subject: [PATCH 189/279] scsi: wd719x: Call scsi_done() directly Conditional statements are faster than indirect calls. Hence call scsi_done() directly. Link: https://lore.kernel.org/r/20211007204618.2196847-5-bvanassche@acm.org Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/wd719x.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/wd719x.c b/drivers/scsi/wd719x.c index 6f10a43510fb..1a7947554581 100644 --- a/drivers/scsi/wd719x.c +++ b/drivers/scsi/wd719x.c @@ -200,7 +200,7 @@ static void wd719x_finish_cmd(struct wd719x_scb *scb, int result) SCSI_SENSE_BUFFERSIZE, DMA_FROM_DEVICE); cmd->result = result << 16; - cmd->scsi_done(cmd); + scsi_done(cmd); } /* Build a SCB and send it to the card */ @@ -295,7 +295,7 @@ out_unmap_scb: DMA_BIDIRECTIONAL); out_error: cmd->result = DID_ERROR << 16; - cmd->scsi_done(cmd); + scsi_done(cmd); return 0; } From fd17badb664e07467d3994dc00bee8b02cce26ea Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 7 Oct 2021 13:46:06 -0700 Subject: [PATCH 190/279] scsi: xen-scsifront: Call scsi_done() directly Conditional statements are faster than indirect calls. Hence call scsi_done() directly. Link: https://lore.kernel.org/r/20211007204618.2196847-6-bvanassche@acm.org Reviewed-by: Juergen Gross Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/xen-scsifront.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/xen-scsifront.c b/drivers/scsi/xen-scsifront.c index 0204e314b482..12c10a5e3d93 100644 --- a/drivers/scsi/xen-scsifront.c +++ b/drivers/scsi/xen-scsifront.c @@ -276,7 +276,7 @@ static void scsifront_cdb_cmd_done(struct vscsifrnt_info *info, if (sense_len) memcpy(sc->sense_buffer, ring_rsp->sense_buffer, sense_len); - sc->scsi_done(sc); + scsi_done(sc); } static void scsifront_sync_cmd_done(struct vscsifrnt_info *info, @@ -558,7 +558,7 @@ static int scsifront_queuecommand(struct Scsi_Host *shost, if (err == -ENOMEM) return SCSI_MLQUEUE_HOST_BUSY; sc->result = DID_ERROR << 16; - sc->scsi_done(sc); + scsi_done(sc); return 0; } From ae4ea859c0795ab4ee9e1df68fdefda1be7f3869 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 7 Oct 2021 13:46:07 -0700 Subject: [PATCH 191/279] scsi: staging: rts5208: Call scsi_done() directly Conditional statements are faster than indirect calls. Hence call scsi_done() directly. Link: https://lore.kernel.org/r/20211007204618.2196847-7-bvanassche@acm.org Acked-by: Greg Kroah-Hartman Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/staging/rts5208/rtsx.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/staging/rts5208/rtsx.c b/drivers/staging/rts5208/rtsx.c index 898add4d1fc8..f1136f6bcee2 100644 --- a/drivers/staging/rts5208/rtsx.c +++ b/drivers/staging/rts5208/rtsx.c @@ -140,7 +140,6 @@ static int queuecommand_lck(struct scsi_cmnd *srb, } /* enqueue the command and wake up the control thread */ - srb->scsi_done = done; chip->srb = srb; complete(&dev->cmnd_ready); @@ -423,7 +422,7 @@ static int rtsx_control_thread(void *__dev) /* indicate that the command is done */ else if (chip->srb->result != DID_ABORT << 16) { - chip->srb->scsi_done(chip->srb); + scsi_done(chip->srb); } else { skip_for_abort: dev_err(&dev->pci->dev, "scsi command aborted\n"); @@ -635,7 +634,7 @@ static void quiesce_and_remove_host(struct rtsx_dev *dev) if (chip->srb) { chip->srb->result = DID_NO_CONNECT << 16; scsi_lock(host); - chip->srb->scsi_done(dev->chip->srb); + scsi_done(dev->chip->srb); chip->srb = NULL; scsi_unlock(host); } From 4879f233b4f8c0b6e0b79ba4a0c9dd06cd84e826 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 7 Oct 2021 13:46:08 -0700 Subject: [PATCH 192/279] scsi: staging: unisys: visorhba: Call scsi_done() directly Conditional statements are faster than indirect calls. Hence call scsi_done() directly. Link: https://lore.kernel.org/r/20211007204618.2196847-8-bvanassche@acm.org Acked-by: Greg Kroah-Hartman Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/staging/unisys/visorhba/visorhba_main.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/drivers/staging/unisys/visorhba/visorhba_main.c b/drivers/staging/unisys/visorhba/visorhba_main.c index 41f8a72a2a95..6a8fa0587280 100644 --- a/drivers/staging/unisys/visorhba/visorhba_main.c +++ b/drivers/staging/unisys/visorhba/visorhba_main.c @@ -327,7 +327,7 @@ static int visorhba_abort_handler(struct scsi_cmnd *scsicmd) rtn = forward_taskmgmt_command(TASK_MGMT_ABORT_TASK, scsidev); if (rtn == SUCCESS) { scsicmd->result = DID_ABORT << 16; - scsicmd->scsi_done(scsicmd); + scsi_done(scsicmd); } return rtn; } @@ -354,7 +354,7 @@ static int visorhba_device_reset_handler(struct scsi_cmnd *scsicmd) rtn = forward_taskmgmt_command(TASK_MGMT_LUN_RESET, scsidev); if (rtn == SUCCESS) { scsicmd->result = DID_RESET << 16; - scsicmd->scsi_done(scsicmd); + scsi_done(scsicmd); } return rtn; } @@ -383,7 +383,7 @@ static int visorhba_bus_reset_handler(struct scsi_cmnd *scsicmd) rtn = forward_taskmgmt_command(TASK_MGMT_BUS_RESET, scsidev); if (rtn == SUCCESS) { scsicmd->result = DID_RESET << 16; - scsicmd->scsi_done(scsicmd); + scsi_done(scsicmd); } return rtn; } @@ -476,8 +476,7 @@ static int visorhba_queue_command_lck(struct scsi_cmnd *scsicmd, */ cmdrsp->scsi.handle = insert_location; - /* save done function that we have call when cmd is complete */ - scsicmd->scsi_done = visorhba_cmnd_done; + WARN_ON_ONCE(visorhba_cmnd_done != scsi_done); /* save destination */ cmdrsp->scsi.vdest.channel = scsidev->channel; cmdrsp->scsi.vdest.id = scsidev->id; @@ -686,8 +685,7 @@ static void visorhba_serverdown_complete(struct visorhba_devdata *devdata) case CMD_SCSI_TYPE: scsicmd = pendingdel->sent; scsicmd->result = DID_RESET << 16; - if (scsicmd->scsi_done) - scsicmd->scsi_done(scsicmd); + scsi_done(scsicmd); break; case CMD_SCSITASKMGMT_TYPE: cmdrsp = pendingdel->sent; @@ -853,7 +851,7 @@ static void complete_scsi_command(struct uiscmdrsp *cmdrsp, else do_scsi_nolinuxstat(cmdrsp, scsicmd); - scsicmd->scsi_done(scsicmd); + scsi_done(scsicmd); } /* From b9d82b7dea2c109d46c2b2a065a01a62286ed275 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 7 Oct 2021 13:46:09 -0700 Subject: [PATCH 193/279] scsi: target: tcm_loop: Call scsi_done() directly Conditional statements are faster than indirect calls. Hence call scsi_done() directly. Link: https://lore.kernel.org/r/20211007204618.2196847-9-bvanassche@acm.org Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/target/loopback/tcm_loop.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/target/loopback/tcm_loop.c b/drivers/target/loopback/tcm_loop.c index 52db28d868d5..4407b56aa6d1 100644 --- a/drivers/target/loopback/tcm_loop.c +++ b/drivers/target/loopback/tcm_loop.c @@ -71,7 +71,7 @@ static void tcm_loop_release_cmd(struct se_cmd *se_cmd) if (se_cmd->se_cmd_flags & SCF_SCSI_TMR_CDB) kmem_cache_free(tcm_loop_cmd_cache, tl_cmd); else - sc->scsi_done(sc); + scsi_done(sc); } static int tcm_loop_show_info(struct seq_file *m, struct Scsi_Host *host) @@ -165,7 +165,7 @@ static void tcm_loop_target_queue_cmd(struct tcm_loop_cmd *tl_cmd) return; out_done: - sc->scsi_done(sc); + scsi_done(sc); } /* From 46c97948e9b5bc8b67fd72741a2fe723ac1d14d7 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 7 Oct 2021 13:46:10 -0700 Subject: [PATCH 194/279] scsi: usb: Call scsi_done() directly Conditional statements are faster than indirect calls. Hence call scsi_done() directly. Link: https://lore.kernel.org/r/20211007204618.2196847-10-bvanassche@acm.org Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/usb/storage/scsiglue.c | 1 - drivers/usb/storage/uas.c | 10 ++++------ drivers/usb/storage/usb.c | 4 ++-- 3 files changed, 6 insertions(+), 9 deletions(-) diff --git a/drivers/usb/storage/scsiglue.c b/drivers/usb/storage/scsiglue.c index e5a971b83e3f..9dfea19e5a91 100644 --- a/drivers/usb/storage/scsiglue.c +++ b/drivers/usb/storage/scsiglue.c @@ -393,7 +393,6 @@ static int queuecommand_lck(struct scsi_cmnd *srb, } /* enqueue the command and wake up the control thread */ - srb->scsi_done = done; us->srb = srb; complete(&us->cmnd_ready); diff --git a/drivers/usb/storage/uas.c b/drivers/usb/storage/uas.c index bef89c6bd1d7..774d18907f47 100644 --- a/drivers/usb/storage/uas.c +++ b/drivers/usb/storage/uas.c @@ -256,7 +256,7 @@ static int uas_try_complete(struct scsi_cmnd *cmnd, const char *caller) return -EBUSY; devinfo->cmnd[cmdinfo->uas_tag - 1] = NULL; uas_free_unsubmitted_urbs(cmnd); - cmnd->scsi_done(cmnd); + scsi_done(cmnd); return 0; } @@ -653,7 +653,7 @@ static int uas_queuecommand_lck(struct scsi_cmnd *cmnd, memcpy(cmnd->sense_buffer, usb_stor_sense_invalidCDB, sizeof(usb_stor_sense_invalidCDB)); cmnd->result = SAM_STAT_CHECK_CONDITION; - cmnd->scsi_done(cmnd); + scsi_done(cmnd); return 0; } @@ -661,7 +661,7 @@ static int uas_queuecommand_lck(struct scsi_cmnd *cmnd, if (devinfo->resetting) { set_host_byte(cmnd, DID_ERROR); - cmnd->scsi_done(cmnd); + scsi_done(cmnd); goto zombie; } @@ -675,8 +675,6 @@ static int uas_queuecommand_lck(struct scsi_cmnd *cmnd, return SCSI_MLQUEUE_DEVICE_BUSY; } - cmnd->scsi_done = done; - memset(cmdinfo, 0, sizeof(*cmdinfo)); cmdinfo->uas_tag = idx + 1; /* uas-tag == usb-stream-id, so 1 based */ cmdinfo->state = SUBMIT_STATUS_URB | ALLOC_CMD_URB | SUBMIT_CMD_URB; @@ -706,7 +704,7 @@ static int uas_queuecommand_lck(struct scsi_cmnd *cmnd, */ if (err == -ENODEV) { set_host_byte(cmnd, DID_ERROR); - cmnd->scsi_done(cmnd); + scsi_done(cmnd); goto zombie; } if (err) { diff --git a/drivers/usb/storage/usb.c b/drivers/usb/storage/usb.c index 90aa9c12ffac..8b543f2c9857 100644 --- a/drivers/usb/storage/usb.c +++ b/drivers/usb/storage/usb.c @@ -388,7 +388,7 @@ static int usb_stor_control_thread(void * __us) if (srb->result == DID_ABORT << 16) { SkipForAbort: usb_stor_dbg(us, "scsi command aborted\n"); - srb = NULL; /* Don't call srb->scsi_done() */ + srb = NULL; /* Don't call scsi_done() */ } /* @@ -417,7 +417,7 @@ SkipForAbort: if (srb) { usb_stor_dbg(us, "scsi cmd done, result=0x%x\n", srb->result); - srb->scsi_done(srb); + scsi_done(srb); } } /* for (;;) */ From 11b68e36b16752ae3a48dc16229958ebc9bb324a Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 7 Oct 2021 13:46:11 -0700 Subject: [PATCH 195/279] scsi: core: Call scsi_done directly Conditional statements are faster than indirect calls. Hence call scsi_done() directly. Since this patch removes the last user of the scsi_done member, also remove that data structure member. Link: https://lore.kernel.org/r/20211007204618.2196847-11-bvanassche@acm.org Reviewed-by: Benjamin Block Reviewed-by: Bean Huo Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/hosts.c | 2 +- drivers/scsi/scsi_lib.c | 3 +-- include/scsi/scsi_cmnd.h | 4 ---- include/scsi/scsi_host.h | 2 +- 4 files changed, 3 insertions(+), 8 deletions(-) diff --git a/drivers/scsi/hosts.c b/drivers/scsi/hosts.c index b8362700a9de..d78cec702596 100644 --- a/drivers/scsi/hosts.c +++ b/drivers/scsi/hosts.c @@ -667,7 +667,7 @@ static bool complete_all_cmds_iter(struct request *rq, void *data, bool rsvd) scsi_dma_unmap(scmd); scmd->result = 0; set_host_byte(scmd, status); - scmd->scsi_done(scmd); + scsi_done(scmd); return true; } diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index f690a2da21ea..d0b7c6dc74f8 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c @@ -1520,7 +1520,7 @@ static int scsi_dispatch_cmd(struct scsi_cmnd *cmd) return rtn; done: - cmd->scsi_done(cmd); + scsi_done(cmd); return 0; } @@ -1694,7 +1694,6 @@ static blk_status_t scsi_queue_rq(struct blk_mq_hw_ctx *hctx, scsi_set_resid(cmd, 0); memset(cmd->sense_buffer, 0, SCSI_SENSE_BUFFERSIZE); cmd->submitter = SUBMITTED_BY_BLOCK_LAYER; - cmd->scsi_done = scsi_done; blk_mq_start_request(req); reason = scsi_dispatch_cmd(cmd); diff --git a/include/scsi/scsi_cmnd.h b/include/scsi/scsi_cmnd.h index 4edaadc293a7..7958a604f979 100644 --- a/include/scsi/scsi_cmnd.h +++ b/include/scsi/scsi_cmnd.h @@ -123,10 +123,6 @@ struct scsi_cmnd { * command (auto-sense). Length must be * SCSI_SENSE_BUFFERSIZE bytes. */ - /* Low-level done function - can be used by low-level driver to point - * to completion function. Not used by mid/upper level code. */ - void (*scsi_done) (struct scsi_cmnd *); - /* * The following fields can be written to by the host specific code. * Everything else should be left alone. diff --git a/include/scsi/scsi_host.h b/include/scsi/scsi_host.h index bc9c45ced145..04e9b821c0c7 100644 --- a/include/scsi/scsi_host.h +++ b/include/scsi/scsi_host.h @@ -516,7 +516,7 @@ struct scsi_host_template { unsigned long irq_flags; \ int rc; \ spin_lock_irqsave(shost->host_lock, irq_flags); \ - rc = func_name##_lck (cmd, cmd->scsi_done); \ + rc = func_name##_lck(cmd, scsi_done); \ spin_unlock_irqrestore(shost->host_lock, irq_flags); \ return rc; \ } From 814818fd4816968105b5978078cfd82f24a47d8d Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 7 Oct 2021 13:46:12 -0700 Subject: [PATCH 196/279] scsi: isci: Remove a declaration There is no function with the name isci_queuecommand(). Hence remove the declaration for isci_queuecommand(). Link: https://lore.kernel.org/r/20211007204618.2196847-12-bvanassche@acm.org Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/isci/task.h | 4 ---- 1 file changed, 4 deletions(-) diff --git a/drivers/scsi/isci/task.h b/drivers/scsi/isci/task.h index 8f4531f22ac2..cae168b8916f 100644 --- a/drivers/scsi/isci/task.h +++ b/drivers/scsi/isci/task.h @@ -182,8 +182,4 @@ void *isci_task_ssp_request_get_response_data_address( u32 isci_task_ssp_request_get_response_data_length( struct isci_request *request); -int isci_queuecommand( - struct scsi_cmnd *scsi_cmd, - void (*donefunc)(struct scsi_cmnd *)); - #endif /* !defined(_SCI_TASK_H_) */ From 0feb3429d735b3e79de80ced7a480278a31e66a1 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 7 Oct 2021 13:46:13 -0700 Subject: [PATCH 197/279] scsi: fas216: Introduce the function fas216_queue_command_internal() This patch does not change any functionality but prepares for removal of the second argument of the fas216_queue_command_lck() function. Link: https://lore.kernel.org/r/20211007204618.2196847-13-bvanassche@acm.org Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/arm/fas216.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/drivers/scsi/arm/fas216.c b/drivers/scsi/arm/fas216.c index 91c03bde310b..a8befd2eec52 100644 --- a/drivers/scsi/arm/fas216.c +++ b/drivers/scsi/arm/fas216.c @@ -2184,7 +2184,7 @@ no_command: } /** - * fas216_queue_command - queue a command for adapter to process. + * fas216_queue_command_internal - queue a command for the adapter to process * @SCpnt: Command to queue * @done: done function to call once command is complete * @@ -2192,8 +2192,8 @@ no_command: * Returns: 0 on success, else error. * Notes: io_request_lock is held, interrupts are disabled. */ -static int fas216_queue_command_lck(struct scsi_cmnd *SCpnt, - void (*done)(struct scsi_cmnd *)) +static int fas216_queue_command_internal(struct scsi_cmnd *SCpnt, + void (*done)(struct scsi_cmnd *)) { FAS216_Info *info = (FAS216_Info *)SCpnt->device->host->hostdata; int result; @@ -2233,6 +2233,12 @@ static int fas216_queue_command_lck(struct scsi_cmnd *SCpnt, return result; } +static int fas216_queue_command_lck(struct scsi_cmnd *SCpnt, + void (*done)(struct scsi_cmnd *)) +{ + return fas216_queue_command_internal(SCpnt, done); +} + DEF_SCSI_QCMD(fas216_queue_command) /** @@ -2272,7 +2278,7 @@ static int fas216_noqueue_command_lck(struct scsi_cmnd *SCpnt, BUG_ON(info->scsi.irq); info->internal_done = 0; - fas216_queue_command_lck(SCpnt, fas216_internal_done); + fas216_queue_command_internal(SCpnt, fas216_internal_done); /* * This wastes time, since we can't return until the command is From af049dfd0b105bab32170d1c68826a4cd8424efd Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 7 Oct 2021 13:46:14 -0700 Subject: [PATCH 198/279] scsi: core: Remove the 'done' argument from SCSI queuecommand_lck functions The DEF_SCSI_QCMD() macro passes the addresses of the SCSI host lock and also that of the scsi_done function to the queuecommand_lck() function implementations. Remove the 'scsi_done' argument since its address is now a constant and instead call 'scsi_done' directly from inside the queuecommand_lck() functions. Link: https://lore.kernel.org/r/20211007204618.2196847-14-bvanassche@acm.org Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/3w-9xxx.c | 3 ++- drivers/scsi/3w-sas.c | 3 ++- drivers/scsi/3w-xxxx.c | 3 ++- drivers/scsi/53c700.c | 3 +-- drivers/scsi/BusLogic.c | 4 ++-- drivers/scsi/a100u2w.c | 2 +- drivers/scsi/advansys.c | 3 +-- drivers/scsi/aha152x.c | 4 +--- drivers/scsi/aha1740.c | 4 ++-- drivers/scsi/aic7xxx/aic79xx_osm.c | 3 +-- drivers/scsi/aic7xxx/aic7xxx_osm.c | 3 +-- drivers/scsi/arcmsr/arcmsr_hba.c | 3 +-- drivers/scsi/arm/acornscsi.c | 14 +++----------- drivers/scsi/arm/fas216.c | 10 ++++------ drivers/scsi/atp870u.c | 4 ++-- drivers/scsi/bfa/bfad_im.c | 4 ++-- drivers/scsi/dc395x.c | 3 ++- drivers/scsi/dpt_i2o.c | 2 +- drivers/scsi/esp_scsi.c | 2 +- drivers/scsi/fnic/fnic_scsi.c | 3 ++- drivers/scsi/hptiop.c | 3 +-- drivers/scsi/ibmvscsi/ibmvscsi.c | 4 ++-- drivers/scsi/imm.c | 3 +-- drivers/scsi/initio.c | 3 +-- drivers/scsi/ips.c | 3 ++- drivers/scsi/mac53c94.c | 3 +-- drivers/scsi/megaraid.c | 3 +-- drivers/scsi/megaraid/megaraid_mbox.c | 4 ++-- drivers/scsi/mesh.c | 2 +- drivers/scsi/ncr53c8xx.c | 3 ++- drivers/scsi/nsp32.c | 4 ++-- drivers/scsi/pcmcia/nsp_cs.c | 3 +-- drivers/scsi/pcmcia/sym53c500_cs.c | 3 +-- drivers/scsi/pmcraid.c | 5 +---- drivers/scsi/ppa.c | 3 +-- drivers/scsi/ps3rom.c | 3 +-- drivers/scsi/qla1280.c | 3 +-- drivers/scsi/qlogicfas408.c | 4 ++-- drivers/scsi/qlogicpti.c | 3 ++- drivers/scsi/stex.c | 4 ++-- drivers/scsi/sym53c8xx_2/sym_glue.c | 3 +-- drivers/scsi/vmw_pvscsi.c | 2 +- drivers/scsi/wd33c93.c | 4 +--- drivers/staging/rts5208/rtsx.c | 4 ++-- drivers/staging/unisys/visorhba/visorhba_main.c | 5 ++--- drivers/usb/image/microtek.c | 5 ++--- drivers/usb/storage/scsiglue.c | 4 ++-- drivers/usb/storage/uas.c | 3 +-- include/scsi/scsi_host.h | 2 +- 49 files changed, 75 insertions(+), 103 deletions(-) diff --git a/drivers/scsi/3w-9xxx.c b/drivers/scsi/3w-9xxx.c index 4ebc2c79f45f..778d4892ed7d 100644 --- a/drivers/scsi/3w-9xxx.c +++ b/drivers/scsi/3w-9xxx.c @@ -1744,8 +1744,9 @@ out: } /* End twa_scsi_eh_reset() */ /* This is the main scsi queue function to handle scsi opcodes */ -static int twa_scsi_queue_lck(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *)) +static int twa_scsi_queue_lck(struct scsi_cmnd *SCpnt) { + void (*done)(struct scsi_cmnd *) = scsi_done; int request_id, retval; TW_Device_Extension *tw_dev = (TW_Device_Extension *)SCpnt->device->host->hostdata; diff --git a/drivers/scsi/3w-sas.c b/drivers/scsi/3w-sas.c index e6f51904f5b1..fc9a2f27aaf9 100644 --- a/drivers/scsi/3w-sas.c +++ b/drivers/scsi/3w-sas.c @@ -1450,8 +1450,9 @@ out: } /* End twl_scsi_eh_reset() */ /* This is the main scsi queue function to handle scsi opcodes */ -static int twl_scsi_queue_lck(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *)) +static int twl_scsi_queue_lck(struct scsi_cmnd *SCpnt) { + void (*done)(struct scsi_cmnd *) = scsi_done; int request_id, retval; TW_Device_Extension *tw_dev = (TW_Device_Extension *)SCpnt->device->host->hostdata; diff --git a/drivers/scsi/3w-xxxx.c b/drivers/scsi/3w-xxxx.c index bdd3ab8875e2..498a5ab7a321 100644 --- a/drivers/scsi/3w-xxxx.c +++ b/drivers/scsi/3w-xxxx.c @@ -1918,8 +1918,9 @@ static int tw_scsiop_test_unit_ready_complete(TW_Device_Extension *tw_dev, int r } /* End tw_scsiop_test_unit_ready_complete() */ /* This is the main scsi queue function to handle scsi opcodes */ -static int tw_scsi_queue_lck(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *)) +static int tw_scsi_queue_lck(struct scsi_cmnd *SCpnt) { + void (*done)(struct scsi_cmnd *) = scsi_done; unsigned char *command = SCpnt->cmnd; int request_id = 0; int retval = 1; diff --git a/drivers/scsi/53c700.c b/drivers/scsi/53c700.c index e7ed2fd6cdec..f1cbac77959e 100644 --- a/drivers/scsi/53c700.c +++ b/drivers/scsi/53c700.c @@ -1751,8 +1751,7 @@ NCR_700_intr(int irq, void *dev_id) return IRQ_RETVAL(handled); } -static int -NCR_700_queuecommand_lck(struct scsi_cmnd *SCp, void (*done)(struct scsi_cmnd *)) +static int NCR_700_queuecommand_lck(struct scsi_cmnd *SCp) { struct NCR_700_Host_Parameters *hostdata = (struct NCR_700_Host_Parameters *)SCp->device->host->hostdata[0]; diff --git a/drivers/scsi/BusLogic.c b/drivers/scsi/BusLogic.c index 7287a9081684..a897c8f914cf 100644 --- a/drivers/scsi/BusLogic.c +++ b/drivers/scsi/BusLogic.c @@ -2866,9 +2866,9 @@ static int blogic_hostreset(struct scsi_cmnd *SCpnt) Outgoing Mailbox for execution by the associated Host Adapter. */ -static int blogic_qcmd_lck(struct scsi_cmnd *command, - void (*comp_cb) (struct scsi_cmnd *)) +static int blogic_qcmd_lck(struct scsi_cmnd *command) { + void (*comp_cb)(struct scsi_cmnd *) = scsi_done; struct blogic_adapter *adapter = (struct blogic_adapter *) command->device->host->hostdata; struct blogic_tgt_flags *tgt_flags = diff --git a/drivers/scsi/a100u2w.c b/drivers/scsi/a100u2w.c index 68343bcb4616..564ade03b530 100644 --- a/drivers/scsi/a100u2w.c +++ b/drivers/scsi/a100u2w.c @@ -911,7 +911,7 @@ static int inia100_build_scb(struct orc_host * host, struct orc_scb * scb, struc * queue the command down to the controller */ -static int inia100_queue_lck(struct scsi_cmnd * cmd, void (*done) (struct scsi_cmnd *)) +static int inia100_queue_lck(struct scsi_cmnd *cmd) { struct orc_scb *scb; struct orc_host *host; /* Point to Host adapter control block */ diff --git a/drivers/scsi/advansys.c b/drivers/scsi/advansys.c index f2f14fbd5069..ace5eff828e9 100644 --- a/drivers/scsi/advansys.c +++ b/drivers/scsi/advansys.c @@ -8453,8 +8453,7 @@ static int asc_execute_scsi_cmnd(struct scsi_cmnd *scp) * This function always returns 0. Command return status is saved * in the 'scp' result field. */ -static int -advansys_queuecommand_lck(struct scsi_cmnd *scp, void (*done)(struct scsi_cmnd *)) +static int advansys_queuecommand_lck(struct scsi_cmnd *scp) { struct Scsi_Host *shost = scp->device->host; int asc_res, result = 0; diff --git a/drivers/scsi/aha152x.c b/drivers/scsi/aha152x.c index f07de9912790..d17880b57d17 100644 --- a/drivers/scsi/aha152x.c +++ b/drivers/scsi/aha152x.c @@ -975,10 +975,8 @@ static int aha152x_internal_queue(struct scsi_cmnd *SCpnt, * queue a command * */ -static int aha152x_queue_lck(struct scsi_cmnd *SCpnt, - void (*done)(struct scsi_cmnd *)) +static int aha152x_queue_lck(struct scsi_cmnd *SCpnt) { - WARN_ON_ONCE(done != scsi_done); return aha152x_internal_queue(SCpnt, NULL, 0); } diff --git a/drivers/scsi/aha1740.c b/drivers/scsi/aha1740.c index 39d8759fe558..18eb4cfcef9a 100644 --- a/drivers/scsi/aha1740.c +++ b/drivers/scsi/aha1740.c @@ -315,9 +315,9 @@ static irqreturn_t aha1740_intr_handle(int irq, void *dev_id) return IRQ_RETVAL(handled); } -static int aha1740_queuecommand_lck(struct scsi_cmnd * SCpnt, - void (*done)(struct scsi_cmnd *)) +static int aha1740_queuecommand_lck(struct scsi_cmnd *SCpnt) { + void (*done)(struct scsi_cmnd *) = scsi_done; unchar direction; unchar *cmd = (unchar *) SCpnt->cmnd; unchar target = scmd_id(SCpnt); diff --git a/drivers/scsi/aic7xxx/aic79xx_osm.c b/drivers/scsi/aic7xxx/aic79xx_osm.c index af49c32cfaf7..5d566d2b2997 100644 --- a/drivers/scsi/aic7xxx/aic79xx_osm.c +++ b/drivers/scsi/aic7xxx/aic79xx_osm.c @@ -572,8 +572,7 @@ ahd_linux_info(struct Scsi_Host *host) /* * Queue an SCB to the controller. */ -static int -ahd_linux_queue_lck(struct scsi_cmnd * cmd, void (*scsi_done) (struct scsi_cmnd *)) +static int ahd_linux_queue_lck(struct scsi_cmnd *cmd) { struct ahd_softc *ahd; struct ahd_linux_device *dev = scsi_transport_device_data(cmd->device); diff --git a/drivers/scsi/aic7xxx/aic7xxx_osm.c b/drivers/scsi/aic7xxx/aic7xxx_osm.c index f2daca41f3f2..d3b1082654d5 100644 --- a/drivers/scsi/aic7xxx/aic7xxx_osm.c +++ b/drivers/scsi/aic7xxx/aic7xxx_osm.c @@ -518,8 +518,7 @@ ahc_linux_info(struct Scsi_Host *host) /* * Queue an SCB to the controller. */ -static int -ahc_linux_queue_lck(struct scsi_cmnd * cmd, void (*scsi_done) (struct scsi_cmnd *)) +static int ahc_linux_queue_lck(struct scsi_cmnd *cmd) { struct ahc_softc *ahc; struct ahc_linux_device *dev = scsi_transport_device_data(cmd->device); diff --git a/drivers/scsi/arcmsr/arcmsr_hba.c b/drivers/scsi/arcmsr/arcmsr_hba.c index e2692ca87a6e..daa8cf61f6d6 100644 --- a/drivers/scsi/arcmsr/arcmsr_hba.c +++ b/drivers/scsi/arcmsr/arcmsr_hba.c @@ -3231,8 +3231,7 @@ static void arcmsr_handle_virtual_command(struct AdapterControlBlock *acb, } } -static int arcmsr_queue_command_lck(struct scsi_cmnd *cmd, - void (* done)(struct scsi_cmnd *)) +static int arcmsr_queue_command_lck(struct scsi_cmnd *cmd) { struct Scsi_Host *host = cmd->device->host; struct AdapterControlBlock *acb = (struct AdapterControlBlock *) host->hostdata; diff --git a/drivers/scsi/arm/acornscsi.c b/drivers/scsi/arm/acornscsi.c index dadaf5ee0ea9..81eb3bbdfc51 100644 --- a/drivers/scsi/arm/acornscsi.c +++ b/drivers/scsi/arm/acornscsi.c @@ -2397,24 +2397,16 @@ acornscsi_intr(int irq, void *dev_id) */ /* - * Function : acornscsi_queuecmd(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *)) + * Function : acornscsi_queuecmd(struct scsi_cmnd *cmd) * Purpose : queues a SCSI command * Params : cmd - SCSI command - * done - function called on completion, with pointer to command descriptor * Returns : 0, or < 0 on error. */ -static int acornscsi_queuecmd_lck(struct scsi_cmnd *SCpnt, - void (*done)(struct scsi_cmnd *)) +static int acornscsi_queuecmd_lck(struct scsi_cmnd *SCpnt) { + void (*done)(struct scsi_cmnd *) = scsi_done; AS_Host *host = (AS_Host *)SCpnt->device->host->hostdata; - if (!done) { - /* there should be some way of rejecting errors like this without panicing... */ - panic("scsi%d: queuecommand called with NULL done function [cmd=%p]", - host->host->host_no, SCpnt); - return -EINVAL; - } - #if (DEBUG & DEBUG_NO_WRITE) if (acornscsi_cmdtype(SCpnt->cmnd[0]) == CMD_WRITE && (NO_WRITE & (1 << SCpnt->device->id))) { printk(KERN_CRIT "scsi%d.%c: WRITE attempted with NO_WRITE flag set\n", diff --git a/drivers/scsi/arm/fas216.c b/drivers/scsi/arm/fas216.c index a8befd2eec52..7019b91f0ce6 100644 --- a/drivers/scsi/arm/fas216.c +++ b/drivers/scsi/arm/fas216.c @@ -2233,10 +2233,9 @@ static int fas216_queue_command_internal(struct scsi_cmnd *SCpnt, return result; } -static int fas216_queue_command_lck(struct scsi_cmnd *SCpnt, - void (*done)(struct scsi_cmnd *)) +static int fas216_queue_command_lck(struct scsi_cmnd *SCpnt) { - return fas216_queue_command_internal(SCpnt, done); + return fas216_queue_command_internal(SCpnt, scsi_done); } DEF_SCSI_QCMD(fas216_queue_command) @@ -2264,8 +2263,7 @@ static void fas216_internal_done(struct scsi_cmnd *SCpnt) * Returns: scsi result code. * Notes: io_request_lock is held, interrupts are disabled. */ -static int fas216_noqueue_command_lck(struct scsi_cmnd *SCpnt, - void (*done)(struct scsi_cmnd *)) +static int fas216_noqueue_command_lck(struct scsi_cmnd *SCpnt) { FAS216_Info *info = (FAS216_Info *)SCpnt->device->host->hostdata; @@ -2306,7 +2304,7 @@ static int fas216_noqueue_command_lck(struct scsi_cmnd *SCpnt, spin_lock_irq(info->host->host_lock); - done(SCpnt); + scsi_done(SCpnt); return 0; } diff --git a/drivers/scsi/atp870u.c b/drivers/scsi/atp870u.c index 6e1595b32bc0..dcd6fae65a88 100644 --- a/drivers/scsi/atp870u.c +++ b/drivers/scsi/atp870u.c @@ -618,9 +618,9 @@ static irqreturn_t atp870u_intr_handle(int irq, void *dev_id) * * Queue a command to the ATP queue. Called with the host lock held. */ -static int atp870u_queuecommand_lck(struct scsi_cmnd *req_p, - void (*done) (struct scsi_cmnd *)) +static int atp870u_queuecommand_lck(struct scsi_cmnd *req_p) { + void (*done)(struct scsi_cmnd *) = scsi_done; unsigned char c; unsigned int m; struct atp_unit *dev; diff --git a/drivers/scsi/bfa/bfad_im.c b/drivers/scsi/bfa/bfad_im.c index e12ae60efd33..79d8f2af1294 100644 --- a/drivers/scsi/bfa/bfad_im.c +++ b/drivers/scsi/bfa/bfad_im.c @@ -1199,9 +1199,9 @@ bfad_im_itnim_work_handler(struct work_struct *work) /* * Scsi_Host template entry, queue a SCSI command to the BFAD. */ -static int -bfad_im_queuecommand_lck(struct scsi_cmnd *cmnd, void (*done) (struct scsi_cmnd *)) +static int bfad_im_queuecommand_lck(struct scsi_cmnd *cmnd) { + void (*done)(struct scsi_cmnd *) = scsi_done; struct bfad_im_port_s *im_port = (struct bfad_im_port_s *) cmnd->device->host->hostdata[0]; struct bfad_s *bfad = im_port->bfad; diff --git a/drivers/scsi/dc395x.c b/drivers/scsi/dc395x.c index 5adbc7f61c19..9b8796c9e634 100644 --- a/drivers/scsi/dc395x.c +++ b/drivers/scsi/dc395x.c @@ -960,8 +960,9 @@ static void build_srb(struct scsi_cmnd *cmd, struct DeviceCtlBlk *dcb, * and is expected to be held on return. * **/ -static int dc395x_queue_command_lck(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *)) +static int dc395x_queue_command_lck(struct scsi_cmnd *cmd) { + void (*done)(struct scsi_cmnd *) = scsi_done; struct DeviceCtlBlk *dcb; struct ScsiReqBlk *srb; struct AdapterCtlBlk *acb = diff --git a/drivers/scsi/dpt_i2o.c b/drivers/scsi/dpt_i2o.c index 1f00afcfe440..93227c04ef59 100644 --- a/drivers/scsi/dpt_i2o.c +++ b/drivers/scsi/dpt_i2o.c @@ -416,7 +416,7 @@ static int adpt_slave_configure(struct scsi_device * device) return 0; } -static int adpt_queue_lck(struct scsi_cmnd * cmd, void (*done) (struct scsi_cmnd *)) +static int adpt_queue_lck(struct scsi_cmnd *cmd) { adpt_hba* pHba = NULL; struct adpt_device* pDev = NULL; /* dpt per device information */ diff --git a/drivers/scsi/esp_scsi.c b/drivers/scsi/esp_scsi.c index f7c2d64f1cef..57787537285a 100644 --- a/drivers/scsi/esp_scsi.c +++ b/drivers/scsi/esp_scsi.c @@ -952,7 +952,7 @@ static void esp_event_queue_full(struct esp *esp, struct esp_cmd_entry *ent) scsi_track_queue_full(dev, lp->num_tagged - 1); } -static int esp_queuecommand_lck(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *)) +static int esp_queuecommand_lck(struct scsi_cmnd *cmd) { struct scsi_device *dev = cmd->device; struct esp *esp = shost_priv(dev->host); diff --git a/drivers/scsi/fnic/fnic_scsi.c b/drivers/scsi/fnic/fnic_scsi.c index 09b8bf5adaf5..88c549f257db 100644 --- a/drivers/scsi/fnic/fnic_scsi.c +++ b/drivers/scsi/fnic/fnic_scsi.c @@ -420,8 +420,9 @@ static inline int fnic_queue_wq_copy_desc(struct fnic *fnic, * Routine to send a scsi cdb * Called with host_lock held and interrupts disabled. */ -static int fnic_queuecommand_lck(struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *)) +static int fnic_queuecommand_lck(struct scsi_cmnd *sc) { + void (*done)(struct scsi_cmnd *) = scsi_done; const int tag = scsi_cmd_to_rq(sc)->tag; struct fc_lport *lp = shost_priv(sc->device->host); struct fc_rport *rport; diff --git a/drivers/scsi/hptiop.c b/drivers/scsi/hptiop.c index f18f6a677c1b..f9a9def394cc 100644 --- a/drivers/scsi/hptiop.c +++ b/drivers/scsi/hptiop.c @@ -993,8 +993,7 @@ static int hptiop_reset_comm_mvfrey(struct hptiop_hba *hba) return 0; } -static int hptiop_queuecommand_lck(struct scsi_cmnd *scp, - void (*done)(struct scsi_cmnd *)) +static int hptiop_queuecommand_lck(struct scsi_cmnd *scp) { struct Scsi_Host *host = scp->device->host; struct hptiop_hba *hba = (struct hptiop_hba *)host->hostdata; diff --git a/drivers/scsi/ibmvscsi/ibmvscsi.c b/drivers/scsi/ibmvscsi/ibmvscsi.c index 50df7dd9cb91..5cc37859b874 100644 --- a/drivers/scsi/ibmvscsi/ibmvscsi.c +++ b/drivers/scsi/ibmvscsi/ibmvscsi.c @@ -1039,9 +1039,9 @@ static inline u16 lun_from_dev(struct scsi_device *dev) * @cmnd: struct scsi_cmnd to be executed * @done: Callback function to be called when cmd is completed */ -static int ibmvscsi_queuecommand_lck(struct scsi_cmnd *cmnd, - void (*done) (struct scsi_cmnd *)) +static int ibmvscsi_queuecommand_lck(struct scsi_cmnd *cmnd) { + void (*done)(struct scsi_cmnd *) = scsi_done; struct srp_cmd *srp_cmd; struct srp_event_struct *evt_struct; struct srp_indirect_buf *indirect; diff --git a/drivers/scsi/imm.c b/drivers/scsi/imm.c index be8edcff0177..8afdb4dba2be 100644 --- a/drivers/scsi/imm.c +++ b/drivers/scsi/imm.c @@ -910,8 +910,7 @@ static int imm_engine(imm_struct *dev, struct scsi_cmnd *cmd) return 0; } -static int imm_queuecommand_lck(struct scsi_cmnd *cmd, - void (*done)(struct scsi_cmnd *)) +static int imm_queuecommand_lck(struct scsi_cmnd *cmd) { imm_struct *dev = imm_dev(cmd->device->host); diff --git a/drivers/scsi/initio.c b/drivers/scsi/initio.c index 183f95758636..fd6da96bc51a 100644 --- a/drivers/scsi/initio.c +++ b/drivers/scsi/initio.c @@ -2609,8 +2609,7 @@ static void initio_build_scb(struct initio_host * host, struct scsi_ctrl_blk * c * will cause the mid layer to call us again later with the command) */ -static int i91u_queuecommand_lck(struct scsi_cmnd *cmd, - void (*done)(struct scsi_cmnd *)) +static int i91u_queuecommand_lck(struct scsi_cmnd *cmd) { struct initio_host *host = (struct initio_host *) cmd->device->host->hostdata; struct scsi_ctrl_blk *cmnd; diff --git a/drivers/scsi/ips.c b/drivers/scsi/ips.c index 0c93ec359e9b..498bf04499ce 100644 --- a/drivers/scsi/ips.c +++ b/drivers/scsi/ips.c @@ -1035,8 +1035,9 @@ static int ips_eh_reset(struct scsi_cmnd *SC) /* Linux obtains io_request_lock before calling this function */ /* */ /****************************************************************************/ -static int ips_queue_lck(struct scsi_cmnd *SC, void (*done) (struct scsi_cmnd *)) +static int ips_queue_lck(struct scsi_cmnd *SC) { + void (*done)(struct scsi_cmnd *) = scsi_done; ips_ha_t *ha; ips_passthru_t *pt; diff --git a/drivers/scsi/mac53c94.c b/drivers/scsi/mac53c94.c index 9731855805f5..3976a18f6333 100644 --- a/drivers/scsi/mac53c94.c +++ b/drivers/scsi/mac53c94.c @@ -66,8 +66,7 @@ static irqreturn_t do_mac53c94_interrupt(int, void *); static void cmd_done(struct fsc_state *, int result); static void set_dma_cmds(struct fsc_state *, struct scsi_cmnd *); - -static int mac53c94_queue_lck(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *)) +static int mac53c94_queue_lck(struct scsi_cmnd *cmd) { struct fsc_state *state; diff --git a/drivers/scsi/megaraid.c b/drivers/scsi/megaraid.c index c4ea833586e0..0d31d7a5e335 100644 --- a/drivers/scsi/megaraid.c +++ b/drivers/scsi/megaraid.c @@ -370,8 +370,7 @@ mega_runpendq(adapter_t *adapter) * * The command queuing entry point for the mid-layer. */ -static int -megaraid_queue_lck(struct scsi_cmnd *scmd, void (*done)(struct scsi_cmnd *)) +static int megaraid_queue_lck(struct scsi_cmnd *scmd) { adapter_t *adapter; scb_t *scb; diff --git a/drivers/scsi/megaraid/megaraid_mbox.c b/drivers/scsi/megaraid/megaraid_mbox.c index 705c5027ba91..0f47a9862ef9 100644 --- a/drivers/scsi/megaraid/megaraid_mbox.c +++ b/drivers/scsi/megaraid/megaraid_mbox.c @@ -1432,9 +1432,9 @@ mbox_post_cmd(adapter_t *adapter, scb_t *scb) * * Queue entry point for mailbox based controllers. */ -static int -megaraid_queue_command_lck(struct scsi_cmnd *scp, void (*done)(struct scsi_cmnd *)) +static int megaraid_queue_command_lck(struct scsi_cmnd *scp) { + void (*done)(struct scsi_cmnd *) = scsi_done; adapter_t *adapter; scb_t *scb; int if_busy; diff --git a/drivers/scsi/mesh.c b/drivers/scsi/mesh.c index 73a3e85802ad..ca133e0a140a 100644 --- a/drivers/scsi/mesh.c +++ b/drivers/scsi/mesh.c @@ -1621,7 +1621,7 @@ static void cmd_complete(struct mesh_state *ms) * Called by midlayer with host locked to queue a new * request */ -static int mesh_queue_lck(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *)) +static int mesh_queue_lck(struct scsi_cmnd *cmd) { struct mesh_state *ms; diff --git a/drivers/scsi/ncr53c8xx.c b/drivers/scsi/ncr53c8xx.c index 6ad43a98409c..168b854ccf14 100644 --- a/drivers/scsi/ncr53c8xx.c +++ b/drivers/scsi/ncr53c8xx.c @@ -7852,8 +7852,9 @@ static int ncr53c8xx_slave_configure(struct scsi_device *device) return 0; } -static int ncr53c8xx_queue_command_lck (struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *)) +static int ncr53c8xx_queue_command_lck(struct scsi_cmnd *cmd) { + void (*done)(struct scsi_cmnd *) = scsi_done; struct ncb *np = ((struct host_data *) cmd->device->host->hostdata)->ncb; unsigned long flags; int sts; diff --git a/drivers/scsi/nsp32.c b/drivers/scsi/nsp32.c index 1057b6fd7569..bd3ee3bf08ee 100644 --- a/drivers/scsi/nsp32.c +++ b/drivers/scsi/nsp32.c @@ -904,9 +904,9 @@ static int nsp32_setup_sg_table(struct scsi_cmnd *SCpnt) return TRUE; } -static int nsp32_queuecommand_lck(struct scsi_cmnd *SCpnt, - void (*done)(struct scsi_cmnd *)) +static int nsp32_queuecommand_lck(struct scsi_cmnd *SCpnt) { + void (*done)(struct scsi_cmnd *) = scsi_done; nsp32_hw_data *data = (nsp32_hw_data *)SCpnt->device->host->hostdata; nsp32_target *target; nsp32_lunt *cur_lunt; diff --git a/drivers/scsi/pcmcia/nsp_cs.c b/drivers/scsi/pcmcia/nsp_cs.c index 0271d534133a..8b9e889bc306 100644 --- a/drivers/scsi/pcmcia/nsp_cs.c +++ b/drivers/scsi/pcmcia/nsp_cs.c @@ -181,8 +181,7 @@ static void nsp_scsi_done(struct scsi_cmnd *SCpnt) scsi_done(SCpnt); } -static int nsp_queuecommand_lck(struct scsi_cmnd *SCpnt, - void (*done)(struct scsi_cmnd *)) +static int nsp_queuecommand_lck(struct scsi_cmnd *SCpnt) { #ifdef NSP_DEBUG /*unsigned int host_id = SCpnt->device->host->this_id;*/ diff --git a/drivers/scsi/pcmcia/sym53c500_cs.c b/drivers/scsi/pcmcia/sym53c500_cs.c index d2adda815d7b..d5c30ac662ba 100644 --- a/drivers/scsi/pcmcia/sym53c500_cs.c +++ b/drivers/scsi/pcmcia/sym53c500_cs.c @@ -537,8 +537,7 @@ SYM53C500_info(struct Scsi_Host *SChost) return (info_msg); } -static int -SYM53C500_queue_lck(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *)) +static int SYM53C500_queue_lck(struct scsi_cmnd *SCpnt) { int i; int port_base = SCpnt->device->host->io_port; diff --git a/drivers/scsi/pmcraid.c b/drivers/scsi/pmcraid.c index 11f36fd4e62f..18efb3e64c84 100644 --- a/drivers/scsi/pmcraid.c +++ b/drivers/scsi/pmcraid.c @@ -3313,10 +3313,7 @@ static int pmcraid_copy_sglist( * SCSI_MLQUEUE_DEVICE_BUSY if device is busy * SCSI_MLQUEUE_HOST_BUSY if host is busy */ -static int pmcraid_queuecommand_lck( - struct scsi_cmnd *scsi_cmd, - void (*done) (struct scsi_cmnd *) -) +static int pmcraid_queuecommand_lck(struct scsi_cmnd *scsi_cmd) { struct pmcraid_instance *pinstance; struct pmcraid_resource_entry *res; diff --git a/drivers/scsi/ppa.c b/drivers/scsi/ppa.c index 799ad8562e24..003043de23a5 100644 --- a/drivers/scsi/ppa.c +++ b/drivers/scsi/ppa.c @@ -786,8 +786,7 @@ static int ppa_engine(ppa_struct *dev, struct scsi_cmnd *cmd) return 0; } -static int ppa_queuecommand_lck(struct scsi_cmnd *cmd, - void (*done) (struct scsi_cmnd *)) +static int ppa_queuecommand_lck(struct scsi_cmnd *cmd) { ppa_struct *dev = ppa_dev(cmd->device->host); diff --git a/drivers/scsi/ps3rom.c b/drivers/scsi/ps3rom.c index 08e970300b3f..2b80cab70333 100644 --- a/drivers/scsi/ps3rom.c +++ b/drivers/scsi/ps3rom.c @@ -200,8 +200,7 @@ static int ps3rom_write_request(struct ps3_storage_device *dev, return 0; } -static int ps3rom_queuecommand_lck(struct scsi_cmnd *cmd, - void (*done)(struct scsi_cmnd *)) +static int ps3rom_queuecommand_lck(struct scsi_cmnd *cmd) { struct ps3rom_private *priv = shost_priv(cmd->device->host); struct ps3_storage_device *dev = priv->dev; diff --git a/drivers/scsi/qla1280.c b/drivers/scsi/qla1280.c index c508a6e20519..1dc56f4c89d8 100644 --- a/drivers/scsi/qla1280.c +++ b/drivers/scsi/qla1280.c @@ -689,8 +689,7 @@ qla1280_info(struct Scsi_Host *host) * handling). Unfortunately, it sometimes calls the scheduler in interrupt * context which is a big NO! NO!. **************************************************************************/ -static int -qla1280_queuecommand_lck(struct scsi_cmnd *cmd, void (*fn)(struct scsi_cmnd *)) +static int qla1280_queuecommand_lck(struct scsi_cmnd *cmd) { struct Scsi_Host *host = cmd->device->host; struct scsi_qla_host *ha = (struct scsi_qla_host *)host->hostdata; diff --git a/drivers/scsi/qlogicfas408.c b/drivers/scsi/qlogicfas408.c index 5471c046a4b7..30a88849a626 100644 --- a/drivers/scsi/qlogicfas408.c +++ b/drivers/scsi/qlogicfas408.c @@ -460,9 +460,9 @@ irqreturn_t qlogicfas408_ihandl(int irq, void *dev_id) * Queued command */ -static int qlogicfas408_queuecommand_lck(struct scsi_cmnd *cmd, - void (*done) (struct scsi_cmnd *)) +static int qlogicfas408_queuecommand_lck(struct scsi_cmnd *cmd) { + void (*done)(struct scsi_cmnd *) = scsi_done; struct qlogicfas408_priv *priv = get_priv_by_cmd(cmd); set_host_byte(cmd, DID_OK); diff --git a/drivers/scsi/qlogicpti.c b/drivers/scsi/qlogicpti.c index 30b5e98b5de0..57f2f4135a06 100644 --- a/drivers/scsi/qlogicpti.c +++ b/drivers/scsi/qlogicpti.c @@ -1013,8 +1013,9 @@ static int qlogicpti_slave_configure(struct scsi_device *sdev) * * "This code must fly." -davem */ -static int qlogicpti_queuecommand_lck(struct scsi_cmnd *Cmnd, void (*done)(struct scsi_cmnd *)) +static int qlogicpti_queuecommand_lck(struct scsi_cmnd *Cmnd) { + void (*done)(struct scsi_cmnd *) = scsi_done; struct Scsi_Host *host = Cmnd->device->host; struct qlogicpti *qpti = (struct qlogicpti *) host->hostdata; struct Command_Entry *cmd; diff --git a/drivers/scsi/stex.c b/drivers/scsi/stex.c index 2f96a2fdaa40..e6420f2127ce 100644 --- a/drivers/scsi/stex.c +++ b/drivers/scsi/stex.c @@ -590,9 +590,9 @@ stex_slave_config(struct scsi_device *sdev) return 0; } -static int -stex_queuecommand_lck(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *)) +static int stex_queuecommand_lck(struct scsi_cmnd *cmd) { + void (*done)(struct scsi_cmnd *) = scsi_done; struct st_hba *hba; struct Scsi_Host *host; unsigned int id, lun; diff --git a/drivers/scsi/sym53c8xx_2/sym_glue.c b/drivers/scsi/sym53c8xx_2/sym_glue.c index 76747e180b17..b04bfde65e3f 100644 --- a/drivers/scsi/sym53c8xx_2/sym_glue.c +++ b/drivers/scsi/sym53c8xx_2/sym_glue.c @@ -486,8 +486,7 @@ void sym_log_bus_error(struct Scsi_Host *shost) * queuecommand method. Entered with the host adapter lock held and * interrupts disabled. */ -static int sym53c8xx_queue_command_lck(struct scsi_cmnd *cmd, - void (*done)(struct scsi_cmnd *)) +static int sym53c8xx_queue_command_lck(struct scsi_cmnd *cmd) { struct sym_hcb *np = SYM_SOFTC_PTR(cmd); struct sym_ucmd *ucp = SYM_UCMD_PTR(cmd); diff --git a/drivers/scsi/vmw_pvscsi.c b/drivers/scsi/vmw_pvscsi.c index 7bfa023d0feb..c2ba65224633 100644 --- a/drivers/scsi/vmw_pvscsi.c +++ b/drivers/scsi/vmw_pvscsi.c @@ -768,7 +768,7 @@ static int pvscsi_queue_ring(struct pvscsi_adapter *adapter, return 0; } -static int pvscsi_queue_lck(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *)) +static int pvscsi_queue_lck(struct scsi_cmnd *cmd) { struct Scsi_Host *host = cmd->device->host; struct pvscsi_adapter *adapter = shost_priv(host); diff --git a/drivers/scsi/wd33c93.c b/drivers/scsi/wd33c93.c index fe28d21c7e93..7d2f00f3571a 100644 --- a/drivers/scsi/wd33c93.c +++ b/drivers/scsi/wd33c93.c @@ -362,9 +362,7 @@ calc_sync_msg(unsigned int period, unsigned int offset, unsigned int fast, msg[1] = offset; } -static int -wd33c93_queuecommand_lck(struct scsi_cmnd *cmd, - void (*done)(struct scsi_cmnd *)) +static int wd33c93_queuecommand_lck(struct scsi_cmnd *cmd) { struct WD33C93_hostdata *hostdata; struct scsi_cmnd *tmp; diff --git a/drivers/staging/rts5208/rtsx.c b/drivers/staging/rts5208/rtsx.c index f1136f6bcee2..8d6139fce13e 100644 --- a/drivers/staging/rts5208/rtsx.c +++ b/drivers/staging/rts5208/rtsx.c @@ -118,9 +118,9 @@ static int slave_configure(struct scsi_device *sdev) /* queue a command */ /* This is always called with scsi_lock(host) held */ -static int queuecommand_lck(struct scsi_cmnd *srb, - void (*done)(struct scsi_cmnd *)) +static int queuecommand_lck(struct scsi_cmnd *srb) { + void (*done)(struct scsi_cmnd *) = scsi_done; struct rtsx_dev *dev = host_to_rtsx(srb->device->host); struct rtsx_chip *chip = dev->chip; diff --git a/drivers/staging/unisys/visorhba/visorhba_main.c b/drivers/staging/unisys/visorhba/visorhba_main.c index 6a8fa0587280..b40c8cacb813 100644 --- a/drivers/staging/unisys/visorhba/visorhba_main.c +++ b/drivers/staging/unisys/visorhba/visorhba_main.c @@ -446,10 +446,9 @@ static u32 dma_data_dir_linux_to_spar(enum dma_data_direction d) * Return: 0 if successfully queued to the Service Partition, otherwise * error code */ -static int visorhba_queue_command_lck(struct scsi_cmnd *scsicmd, - void (*visorhba_cmnd_done) - (struct scsi_cmnd *)) +static int visorhba_queue_command_lck(struct scsi_cmnd *scsicmd) { + void (*visorhba_cmnd_done)(struct scsi_cmnd *) = scsi_done; struct uiscmdrsp *cmdrsp; struct scsi_device *scsidev = scsicmd->device; int insert_location; diff --git a/drivers/usb/image/microtek.c b/drivers/usb/image/microtek.c index 59b02a539963..b8dc6fa6a5a3 100644 --- a/drivers/usb/image/microtek.c +++ b/drivers/usb/image/microtek.c @@ -561,10 +561,9 @@ mts_build_transfer_context(struct scsi_cmnd *srb, struct mts_desc* desc) desc->context.data_pipe = pipe; } - -static int -mts_scsi_queuecommand_lck(struct scsi_cmnd *srb, mts_scsi_cmnd_callback callback) +static int mts_scsi_queuecommand_lck(struct scsi_cmnd *srb) { + mts_scsi_cmnd_callback callback = scsi_done; struct mts_desc* desc = (struct mts_desc*)(srb->device->host->hostdata[0]); int res; diff --git a/drivers/usb/storage/scsiglue.c b/drivers/usb/storage/scsiglue.c index 9dfea19e5a91..220aa1cf4b3d 100644 --- a/drivers/usb/storage/scsiglue.c +++ b/drivers/usb/storage/scsiglue.c @@ -363,9 +363,9 @@ static int target_alloc(struct scsi_target *starget) /* queue a command */ /* This is always called with scsi_lock(host) held */ -static int queuecommand_lck(struct scsi_cmnd *srb, - void (*done)(struct scsi_cmnd *)) +static int queuecommand_lck(struct scsi_cmnd *srb) { + void (*done)(struct scsi_cmnd *) = scsi_done; struct us_data *us = host_to_us(srb->device->host); /* check for state-transition errors */ diff --git a/drivers/usb/storage/uas.c b/drivers/usb/storage/uas.c index 774d18907f47..7f2944729ecd 100644 --- a/drivers/usb/storage/uas.c +++ b/drivers/usb/storage/uas.c @@ -633,8 +633,7 @@ static int uas_submit_urbs(struct scsi_cmnd *cmnd, return 0; } -static int uas_queuecommand_lck(struct scsi_cmnd *cmnd, - void (*done)(struct scsi_cmnd *)) +static int uas_queuecommand_lck(struct scsi_cmnd *cmnd) { struct scsi_device *sdev = cmnd->device; struct uas_dev_info *devinfo = sdev->hostdata; diff --git a/include/scsi/scsi_host.h b/include/scsi/scsi_host.h index 04e9b821c0c7..3bb46b188e1c 100644 --- a/include/scsi/scsi_host.h +++ b/include/scsi/scsi_host.h @@ -516,7 +516,7 @@ struct scsi_host_template { unsigned long irq_flags; \ int rc; \ spin_lock_irqsave(shost->host_lock, irq_flags); \ - rc = func_name##_lck(cmd, scsi_done); \ + rc = func_name##_lck(cmd); \ spin_unlock_irqrestore(shost->host_lock, irq_flags); \ return rc; \ } From 92c4b58b15c56298b1b225c1d2e533165b3e32af Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Tue, 12 Oct 2021 16:35:13 -0700 Subject: [PATCH 199/279] scsi: core: Register sysfs attributes earlier A quote from Documentation/driver-api/driver-model/device.rst: "Word of warning: While the kernel allows device_create_file() and device_remove_file() to be called on a device at any time, userspace has strict expectations on when attributes get created. When a new device is registered in the kernel, a uevent is generated to notify userspace (like udev) that a new device is available. If attributes are added after the device is registered, then userspace won't get notified and userspace will not know about the new attributes." Hence register SCSI host sysfs attributes before the SCSI host shost_dev uevent is emitted instead of after that event has been emitted. Link: https://lore.kernel.org/r/20211012233558.4066756-2-bvanassche@acm.org Cc: Greg Kroah-Hartman Reviewed-by: Benjamin Block Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/hosts.c | 23 ++++++++++- drivers/scsi/scsi_priv.h | 4 +- drivers/scsi/scsi_sysfs.c | 81 +++++++++++++++++++------------------- include/scsi/scsi_device.h | 7 ++++ include/scsi/scsi_host.h | 12 ++++++ 5 files changed, 84 insertions(+), 43 deletions(-) diff --git a/drivers/scsi/hosts.c b/drivers/scsi/hosts.c index d78cec702596..09157792d36b 100644 --- a/drivers/scsi/hosts.c +++ b/drivers/scsi/hosts.c @@ -376,7 +376,7 @@ static struct device_type scsi_host_type = { struct Scsi_Host *scsi_host_alloc(struct scsi_host_template *sht, int privsize) { struct Scsi_Host *shost; - int index; + int index, i, j = 0; shost = kzalloc(sizeof(struct Scsi_Host) + privsize, GFP_KERNEL); if (!shost) @@ -481,7 +481,26 @@ struct Scsi_Host *scsi_host_alloc(struct scsi_host_template *sht, int privsize) shost->shost_dev.parent = &shost->shost_gendev; shost->shost_dev.class = &shost_class; dev_set_name(&shost->shost_dev, "host%d", shost->host_no); - shost->shost_dev.groups = scsi_sysfs_shost_attr_groups; + shost->shost_dev.groups = shost->shost_dev_attr_groups; + shost->shost_dev_attr_groups[j++] = &scsi_shost_attr_group; + if (sht->shost_attrs) { + shost->lld_attr_group = (struct attribute_group){ + .attrs = scsi_convert_dev_attrs(&shost->shost_gendev, + sht->shost_attrs) + }; + if (shost->lld_attr_group.attrs) + shost->shost_dev_attr_groups[j++] = + &shost->lld_attr_group; + } + if (sht->shost_groups) { + for (i = 0; sht->shost_groups[i] && + j < ARRAY_SIZE(shost->shost_dev_attr_groups); + i++, j++) { + shost->shost_dev_attr_groups[j] = + sht->shost_groups[i]; + } + } + WARN_ON_ONCE(j >= ARRAY_SIZE(shost->shost_dev_attr_groups)); shost->ehandler = kthread_run(scsi_error_handler, shost, "scsi_eh_%d", shost->host_no); diff --git a/drivers/scsi/scsi_priv.h b/drivers/scsi/scsi_priv.h index f8ca22d495d9..483d0ad5fe60 100644 --- a/drivers/scsi/scsi_priv.h +++ b/drivers/scsi/scsi_priv.h @@ -138,13 +138,15 @@ extern int scsi_sysfs_add_sdev(struct scsi_device *); extern int scsi_sysfs_add_host(struct Scsi_Host *); extern int scsi_sysfs_register(void); extern void scsi_sysfs_unregister(void); +struct attribute **scsi_convert_dev_attrs(struct device *dev, + struct device_attribute **dev_attr); extern void scsi_sysfs_device_initialize(struct scsi_device *); extern int scsi_sysfs_target_initialize(struct scsi_device *); extern struct scsi_transport_template blank_transport_template; extern void __scsi_remove_device(struct scsi_device *); extern struct bus_type scsi_bus_type; -extern const struct attribute_group *scsi_sysfs_shost_attr_groups[]; +extern const struct attribute_group scsi_shost_attr_group; /* scsi_netlink.c */ #ifdef CONFIG_SCSI_NETLINK diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c index b598dfcbb67d..3d98db6a97e6 100644 --- a/drivers/scsi/scsi_sysfs.c +++ b/drivers/scsi/scsi_sysfs.c @@ -424,15 +424,10 @@ static struct attribute *scsi_sysfs_shost_attrs[] = { NULL }; -static struct attribute_group scsi_shost_attr_group = { +const struct attribute_group scsi_shost_attr_group = { .attrs = scsi_sysfs_shost_attrs, }; -const struct attribute_group *scsi_sysfs_shost_attr_groups[] = { - &scsi_shost_attr_group, - NULL -}; - static void scsi_device_cls_release(struct device *class_dev) { struct scsi_device *sdev; @@ -1333,7 +1328,7 @@ static int scsi_target_add(struct scsi_target *starget) **/ int scsi_sysfs_add_sdev(struct scsi_device *sdev) { - int error, i; + int error; struct scsi_target *starget = sdev->sdev_target; error = scsi_target_add(starget); @@ -1386,23 +1381,6 @@ int scsi_sysfs_add_sdev(struct scsi_device *sdev) } } - /* add additional host specific attributes */ - if (sdev->host->hostt->sdev_attrs) { - for (i = 0; sdev->host->hostt->sdev_attrs[i]; i++) { - error = device_create_file(&sdev->sdev_gendev, - sdev->host->hostt->sdev_attrs[i]); - if (error) - return error; - } - } - - if (sdev->host->hostt->sdev_groups) { - error = sysfs_create_groups(&sdev->sdev_gendev.kobj, - sdev->host->hostt->sdev_groups); - if (error) - return error; - } - scsi_autopm_put_device(sdev); return error; } @@ -1442,10 +1420,6 @@ void __scsi_remove_device(struct scsi_device *sdev) if (res != 0) return; - if (sdev->host->hostt->sdev_groups) - sysfs_remove_groups(&sdev->sdev_gendev.kobj, - sdev->host->hostt->sdev_groups); - if (IS_ENABLED(CONFIG_BLK_DEV_BSG) && sdev->bsg_dev) bsg_unregister_queue(sdev->bsg_dev); device_unregister(&sdev->sdev_dev); @@ -1584,23 +1558,31 @@ EXPORT_SYMBOL(scsi_register_interface); **/ int scsi_sysfs_add_host(struct Scsi_Host *shost) { - int error, i; - - /* add host specific attributes */ - if (shost->hostt->shost_attrs) { - for (i = 0; shost->hostt->shost_attrs[i]; i++) { - error = device_create_file(&shost->shost_dev, - shost->hostt->shost_attrs[i]); - if (error) - return error; - } - } - transport_register_device(&shost->shost_gendev); transport_configure_device(&shost->shost_gendev); return 0; } +/* + * Convert an array of struct device_attribute pointers into an array of + * struct attribute pointers. + */ +struct attribute **scsi_convert_dev_attrs(struct device *dev, + struct device_attribute **dev_attr) +{ + struct attribute **attrs; + int i; + + for (i = 0; dev_attr[i]; i++) + ; + attrs = devm_kzalloc(dev, (i + 1) * sizeof(*attrs), GFP_KERNEL); + if (!attrs) + return NULL; + for (i = 0; dev_attr[i]; i++) + attrs[i] = &dev_attr[i]->attr; + return attrs; +} + static struct device_type scsi_dev_type = { .name = "scsi_device", .release = scsi_device_dev_release, @@ -1609,8 +1591,10 @@ static struct device_type scsi_dev_type = { void scsi_sysfs_device_initialize(struct scsi_device *sdev) { + int i, j = 0; unsigned long flags; struct Scsi_Host *shost = sdev->host; + struct scsi_host_template *hostt = shost->hostt; struct scsi_target *starget = sdev->sdev_target; device_initialize(&sdev->sdev_gendev); @@ -1619,6 +1603,23 @@ void scsi_sysfs_device_initialize(struct scsi_device *sdev) scsi_enable_async_suspend(&sdev->sdev_gendev); dev_set_name(&sdev->sdev_gendev, "%d:%d:%d:%llu", sdev->host->host_no, sdev->channel, sdev->id, sdev->lun); + sdev->gendev_attr_groups[j++] = &scsi_sdev_attr_group; + if (hostt->sdev_attrs) { + sdev->lld_attr_group = (struct attribute_group){ + .attrs = scsi_convert_dev_attrs(&sdev->sdev_gendev, + hostt->sdev_attrs) + }; + if (sdev->lld_attr_group.attrs) + sdev->gendev_attr_groups[j++] = &sdev->lld_attr_group; + } + if (hostt->sdev_groups) { + for (i = 0; hostt->sdev_groups[i] && + j < ARRAY_SIZE(sdev->gendev_attr_groups); + i++, j++) { + sdev->gendev_attr_groups[j] = hostt->sdev_groups[i]; + } + } + WARN_ON_ONCE(j >= ARRAY_SIZE(sdev->gendev_attr_groups)); device_initialize(&sdev->sdev_dev); sdev->sdev_dev.parent = get_device(&sdev->sdev_gendev); diff --git a/include/scsi/scsi_device.h b/include/scsi/scsi_device.h index b97e142a7ca9..01732aabd7c3 100644 --- a/include/scsi/scsi_device.h +++ b/include/scsi/scsi_device.h @@ -225,6 +225,13 @@ struct scsi_device { struct device sdev_gendev, sdev_dev; + struct attribute_group lld_attr_group; + /* + * The array size 6 provides space for one attribute group for the + * SCSI core, four attribute groups defined by SCSI LLDs and one + * terminating NULL pointer. + */ + const struct attribute_group *gendev_attr_groups[6]; struct execute_work ew; /* used to get process context on put */ struct work_struct requeue_work; diff --git a/include/scsi/scsi_host.h b/include/scsi/scsi_host.h index 3bb46b188e1c..bc2fcb72ff59 100644 --- a/include/scsi/scsi_host.h +++ b/include/scsi/scsi_host.h @@ -483,6 +483,11 @@ struct scsi_host_template { */ struct device_attribute **sdev_attrs; + /* + * Pointer to the SCSI host sysfs attribute groups, NULL terminated. + */ + const struct attribute_group **shost_groups; + /* * Pointer to the SCSI device attribute groups for this host, * NULL terminated. @@ -695,6 +700,13 @@ struct Scsi_Host { /* ldm bits */ struct device shost_gendev, shost_dev; + struct attribute_group lld_attr_group; + /* + * The array size 3 provides space for one attribute group defined by + * the SCSI core, one attribute group defined by the SCSI LLD and one + * terminating NULL pointer. + */ + const struct attribute_group *shost_dev_attr_groups[3]; /* * Points to the transport data (if any) which is allocated From c3f69c7f629ff53c75f335754ea41426b8e095de Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Tue, 12 Oct 2021 16:35:14 -0700 Subject: [PATCH 200/279] scsi: ata: Switch to attribute groups struct device supports attribute groups directly but does not support struct device_attribute directly. Hence switch to attribute groups. Link: https://lore.kernel.org/r/20211012233558.4066756-3-bvanassche@acm.org Acked-by: Damien Le Moal Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/ata/ahci.h | 8 +++--- drivers/ata/ata_piix.c | 8 +++--- drivers/ata/libahci.c | 52 ++++++++++++++++++++++++++------------- drivers/ata/libata-sata.c | 19 ++++++++++---- drivers/ata/libata-scsi.c | 15 ++++++++--- drivers/ata/pata_macio.c | 2 +- drivers/ata/sata_mv.c | 2 +- drivers/ata/sata_nv.c | 4 +-- drivers/ata/sata_sil24.c | 2 +- include/linux/libata.h | 8 +++--- 10 files changed, 79 insertions(+), 41 deletions(-) diff --git a/drivers/ata/ahci.h b/drivers/ata/ahci.h index 2e89499bd9c3..eeac5482f1d1 100644 --- a/drivers/ata/ahci.h +++ b/drivers/ata/ahci.h @@ -376,8 +376,8 @@ struct ahci_host_priv { extern int ahci_ignore_sss; -extern struct device_attribute *ahci_shost_attrs[]; -extern struct device_attribute *ahci_sdev_attrs[]; +extern const struct attribute_group *ahci_shost_groups[]; +extern const struct attribute_group *ahci_sdev_groups[]; /* * This must be instantiated by the edge drivers. Read the comments @@ -388,8 +388,8 @@ extern struct device_attribute *ahci_sdev_attrs[]; .can_queue = AHCI_MAX_CMDS, \ .sg_tablesize = AHCI_MAX_SG, \ .dma_boundary = AHCI_DMA_BOUNDARY, \ - .shost_attrs = ahci_shost_attrs, \ - .sdev_attrs = ahci_sdev_attrs, \ + .shost_groups = ahci_shost_groups, \ + .sdev_groups = ahci_sdev_groups, \ .change_queue_depth = ata_scsi_change_queue_depth, \ .tag_alloc_policy = BLK_TAG_ALLOC_RR, \ .slave_configure = ata_scsi_slave_config diff --git a/drivers/ata/ata_piix.c b/drivers/ata/ata_piix.c index 3ca7720e7d8f..0b2fcf0d1d6c 100644 --- a/drivers/ata/ata_piix.c +++ b/drivers/ata/ata_piix.c @@ -1085,14 +1085,16 @@ static struct ata_port_operations ich_pata_ops = { .set_dmamode = ich_set_dmamode, }; -static struct device_attribute *piix_sidpr_shost_attrs[] = { - &dev_attr_link_power_management_policy, +static struct attribute *piix_sidpr_shost_attrs[] = { + &dev_attr_link_power_management_policy.attr, NULL }; +ATTRIBUTE_GROUPS(piix_sidpr_shost); + static struct scsi_host_template piix_sidpr_sht = { ATA_BMDMA_SHT(DRV_NAME), - .shost_attrs = piix_sidpr_shost_attrs, + .shost_groups = piix_sidpr_shost_groups, }; static struct ata_port_operations piix_sidpr_sata_ops = { diff --git a/drivers/ata/libahci.c b/drivers/ata/libahci.c index 5b3fa2cbe722..28430c093a7f 100644 --- a/drivers/ata/libahci.c +++ b/drivers/ata/libahci.c @@ -108,28 +108,46 @@ static DEVICE_ATTR(em_buffer, S_IWUSR | S_IRUGO, ahci_read_em_buffer, ahci_store_em_buffer); static DEVICE_ATTR(em_message_supported, S_IRUGO, ahci_show_em_supported, NULL); -struct device_attribute *ahci_shost_attrs[] = { - &dev_attr_link_power_management_policy, - &dev_attr_em_message_type, - &dev_attr_em_message, - &dev_attr_ahci_host_caps, - &dev_attr_ahci_host_cap2, - &dev_attr_ahci_host_version, - &dev_attr_ahci_port_cmd, - &dev_attr_em_buffer, - &dev_attr_em_message_supported, +static struct attribute *ahci_shost_attrs[] = { + &dev_attr_link_power_management_policy.attr, + &dev_attr_em_message_type.attr, + &dev_attr_em_message.attr, + &dev_attr_ahci_host_caps.attr, + &dev_attr_ahci_host_cap2.attr, + &dev_attr_ahci_host_version.attr, + &dev_attr_ahci_port_cmd.attr, + &dev_attr_em_buffer.attr, + &dev_attr_em_message_supported.attr, NULL }; -EXPORT_SYMBOL_GPL(ahci_shost_attrs); -struct device_attribute *ahci_sdev_attrs[] = { - &dev_attr_sw_activity, - &dev_attr_unload_heads, - &dev_attr_ncq_prio_supported, - &dev_attr_ncq_prio_enable, +static const struct attribute_group ahci_shost_attr_group = { + .attrs = ahci_shost_attrs +}; + +const struct attribute_group *ahci_shost_groups[] = { + &ahci_shost_attr_group, NULL }; -EXPORT_SYMBOL_GPL(ahci_sdev_attrs); +EXPORT_SYMBOL_GPL(ahci_shost_groups); + +struct attribute *ahci_sdev_attrs[] = { + &dev_attr_sw_activity.attr, + &dev_attr_unload_heads.attr, + &dev_attr_ncq_prio_supported.attr, + &dev_attr_ncq_prio_enable.attr, + NULL +}; + +static const struct attribute_group ahci_sdev_attr_group = { + .attrs = ahci_sdev_attrs +}; + +const struct attribute_group *ahci_sdev_groups[] = { + &ahci_sdev_attr_group, + NULL +}; +EXPORT_SYMBOL_GPL(ahci_sdev_groups); struct ata_port_operations ahci_ops = { .inherits = &sata_pmp_port_ops, diff --git a/drivers/ata/libata-sata.c b/drivers/ata/libata-sata.c index 60418d872c12..4e88597aa9df 100644 --- a/drivers/ata/libata-sata.c +++ b/drivers/ata/libata-sata.c @@ -922,13 +922,22 @@ DEVICE_ATTR(ncq_prio_enable, S_IRUGO | S_IWUSR, ata_ncq_prio_enable_show, ata_ncq_prio_enable_store); EXPORT_SYMBOL_GPL(dev_attr_ncq_prio_enable); -struct device_attribute *ata_ncq_sdev_attrs[] = { - &dev_attr_unload_heads, - &dev_attr_ncq_prio_enable, - &dev_attr_ncq_prio_supported, +struct attribute *ata_ncq_sdev_attrs[] = { + &dev_attr_unload_heads.attr, + &dev_attr_ncq_prio_enable.attr, + &dev_attr_ncq_prio_supported.attr, NULL }; -EXPORT_SYMBOL_GPL(ata_ncq_sdev_attrs); + +static const struct attribute_group ata_ncq_sdev_attr_group = { + .attrs = ata_ncq_sdev_attrs +}; + +const struct attribute_group *ata_ncq_sdev_groups[] = { + &ata_ncq_sdev_attr_group, + NULL +}; +EXPORT_SYMBOL_GPL(ata_ncq_sdev_groups); static ssize_t ata_scsi_em_message_store(struct device *dev, struct device_attribute *attr, diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index 4afe1abc4709..29eb7cca17a4 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -234,11 +234,20 @@ static void ata_scsi_set_invalid_parameter(struct ata_device *dev, field, 0xff, 0); } -struct device_attribute *ata_common_sdev_attrs[] = { - &dev_attr_unload_heads, +static struct attribute *ata_common_sdev_attrs[] = { + &dev_attr_unload_heads.attr, NULL }; -EXPORT_SYMBOL_GPL(ata_common_sdev_attrs); + +static const struct attribute_group ata_common_sdev_attr_group = { + .attrs = ata_common_sdev_attrs +}; + +const struct attribute_group *ata_common_sdev_groups[] = { + &ata_common_sdev_attr_group, + NULL +}; +EXPORT_SYMBOL_GPL(ata_common_sdev_groups); /** * ata_std_bios_param - generic bios head/sector/cylinder calculator used by sd. diff --git a/drivers/ata/pata_macio.c b/drivers/ata/pata_macio.c index be0ca8d5b345..16e8aa184a75 100644 --- a/drivers/ata/pata_macio.c +++ b/drivers/ata/pata_macio.c @@ -923,7 +923,7 @@ static struct scsi_host_template pata_macio_sht = { */ .max_segment_size = MAX_DBDMA_SEG, .slave_configure = pata_macio_slave_config, - .sdev_attrs = ata_common_sdev_attrs, + .sdev_groups = ata_common_sdev_groups, .can_queue = ATA_DEF_QUEUE, .tag_alloc_policy = BLK_TAG_ALLOC_RR, }; diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c index 9d86203e1e7a..24130e551b26 100644 --- a/drivers/ata/sata_mv.c +++ b/drivers/ata/sata_mv.c @@ -670,7 +670,7 @@ static struct scsi_host_template mv6_sht = { .can_queue = MV_MAX_Q_DEPTH - 1, .sg_tablesize = MV_MAX_SG_CT / 2, .dma_boundary = MV_DMA_BOUNDARY, - .sdev_attrs = ata_ncq_sdev_attrs, + .sdev_groups = ata_ncq_sdev_groups, .change_queue_depth = ata_scsi_change_queue_depth, .tag_alloc_policy = BLK_TAG_ALLOC_RR, .slave_configure = ata_scsi_slave_config diff --git a/drivers/ata/sata_nv.c b/drivers/ata/sata_nv.c index c385d18ce87b..16272c111208 100644 --- a/drivers/ata/sata_nv.c +++ b/drivers/ata/sata_nv.c @@ -380,7 +380,7 @@ static struct scsi_host_template nv_adma_sht = { .sg_tablesize = NV_ADMA_SGTBL_TOTAL_LEN, .dma_boundary = NV_ADMA_DMA_BOUNDARY, .slave_configure = nv_adma_slave_config, - .sdev_attrs = ata_ncq_sdev_attrs, + .sdev_groups = ata_ncq_sdev_groups, .change_queue_depth = ata_scsi_change_queue_depth, .tag_alloc_policy = BLK_TAG_ALLOC_RR, }; @@ -391,7 +391,7 @@ static struct scsi_host_template nv_swncq_sht = { .sg_tablesize = LIBATA_MAX_PRD, .dma_boundary = ATA_DMA_BOUNDARY, .slave_configure = nv_swncq_slave_config, - .sdev_attrs = ata_ncq_sdev_attrs, + .sdev_groups = ata_ncq_sdev_groups, .change_queue_depth = ata_scsi_change_queue_depth, .tag_alloc_policy = BLK_TAG_ALLOC_RR, }; diff --git a/drivers/ata/sata_sil24.c b/drivers/ata/sata_sil24.c index 06a1e27c4f84..f99ec6f7d7c0 100644 --- a/drivers/ata/sata_sil24.c +++ b/drivers/ata/sata_sil24.c @@ -379,7 +379,7 @@ static struct scsi_host_template sil24_sht = { .sg_tablesize = SIL24_MAX_SGE, .dma_boundary = ATA_DMA_BOUNDARY, .tag_alloc_policy = BLK_TAG_ALLOC_FIFO, - .sdev_attrs = ata_ncq_sdev_attrs, + .sdev_groups = ata_ncq_sdev_groups, .change_queue_depth = ata_scsi_change_queue_depth, .slave_configure = ata_scsi_slave_config }; diff --git a/include/linux/libata.h b/include/linux/libata.h index c0c64f03e107..bd1b782d1bbf 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -1388,7 +1388,7 @@ extern int ata_link_nr_enabled(struct ata_link *link); */ extern const struct ata_port_operations ata_base_port_ops; extern const struct ata_port_operations sata_port_ops; -extern struct device_attribute *ata_common_sdev_attrs[]; +extern const struct attribute_group *ata_common_sdev_groups[]; /* * All sht initializers (BASE, PIO, BMDMA, NCQ) must be instantiated @@ -1418,14 +1418,14 @@ extern struct device_attribute *ata_common_sdev_attrs[]; #define ATA_BASE_SHT(drv_name) \ ATA_SUBBASE_SHT(drv_name), \ - .sdev_attrs = ata_common_sdev_attrs + .sdev_groups = ata_common_sdev_groups #ifdef CONFIG_SATA_HOST -extern struct device_attribute *ata_ncq_sdev_attrs[]; +extern const struct attribute_group *ata_ncq_sdev_groups[]; #define ATA_NCQ_SHT(drv_name) \ ATA_SUBBASE_SHT(drv_name), \ - .sdev_attrs = ata_ncq_sdev_attrs, \ + .sdev_groups = ata_ncq_sdev_groups, \ .change_queue_depth = ata_scsi_change_queue_depth #endif From 5e88e67b6f3b84037c284285442df6e376fcd653 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Tue, 12 Oct 2021 16:35:15 -0700 Subject: [PATCH 201/279] scsi: firewire: sbp2: Switch to attribute groups struct device supports attribute groups directly but does not support struct device_attribute directly. Hence switch to attribute groups. Link: https://lore.kernel.org/r/20211012233558.4066756-4-bvanassche@acm.org Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/firewire/sbp2.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/firewire/sbp2.c b/drivers/firewire/sbp2.c index aeed3f2273e8..85cd379fd383 100644 --- a/drivers/firewire/sbp2.c +++ b/drivers/firewire/sbp2.c @@ -1578,11 +1578,13 @@ static ssize_t sbp2_sysfs_ieee1394_id_show(struct device *dev, static DEVICE_ATTR(ieee1394_id, S_IRUGO, sbp2_sysfs_ieee1394_id_show, NULL); -static struct device_attribute *sbp2_scsi_sysfs_attrs[] = { - &dev_attr_ieee1394_id, +static struct attribute *sbp2_scsi_sysfs_attrs[] = { + &dev_attr_ieee1394_id.attr, NULL }; +ATTRIBUTE_GROUPS(sbp2_scsi_sysfs); + static struct scsi_host_template scsi_driver_template = { .module = THIS_MODULE, .name = "SBP-2 IEEE-1394", @@ -1595,7 +1597,7 @@ static struct scsi_host_template scsi_driver_template = { .sg_tablesize = SG_ALL, .max_segment_size = SBP2_MAX_SEG_SIZE, .can_queue = 1, - .sdev_attrs = sbp2_scsi_sysfs_attrs, + .sdev_groups = sbp2_scsi_sysfs_groups, }; MODULE_AUTHOR("Kristian Hoegsberg "); From a3cf94c96ede60710e6f453620ccf529d7540c84 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Tue, 12 Oct 2021 16:35:16 -0700 Subject: [PATCH 202/279] scsi: RDMA/srp: Switch to attribute groups struct device supports attribute groups directly but does not support struct device_attribute directly. Hence switch to attribute groups. Link: https://lore.kernel.org/r/20211012233558.4066756-5-bvanassche@acm.org Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/infiniband/ulp/srp/ib_srp.c | 51 +++++++++++++++++------------ 1 file changed, 30 insertions(+), 21 deletions(-) diff --git a/drivers/infiniband/ulp/srp/ib_srp.c b/drivers/infiniband/ulp/srp/ib_srp.c index f8765f96ec1e..e174e853f8a4 100644 --- a/drivers/infiniband/ulp/srp/ib_srp.c +++ b/drivers/infiniband/ulp/srp/ib_srp.c @@ -1026,10 +1026,17 @@ out: */ static void srp_del_scsi_host_attr(struct Scsi_Host *shost) { - struct device_attribute **attr; + const struct attribute_group **g; + struct attribute **attr; - for (attr = shost->hostt->shost_attrs; attr && *attr; ++attr) - device_remove_file(&shost->shost_dev, *attr); + for (g = shost->hostt->shost_groups; *g; ++g) { + for (attr = (*g)->attrs; *attr; ++attr) { + struct device_attribute *dev_attr = + container_of(*attr, typeof(*dev_attr), attr); + + device_remove_file(&shost->shost_dev, dev_attr); + } + } } static void srp_remove_target(struct srp_target_port *target) @@ -3050,26 +3057,28 @@ static ssize_t allow_ext_sg_show(struct device *dev, static DEVICE_ATTR_RO(allow_ext_sg); -static struct device_attribute *srp_host_attrs[] = { - &dev_attr_id_ext, - &dev_attr_ioc_guid, - &dev_attr_service_id, - &dev_attr_pkey, - &dev_attr_sgid, - &dev_attr_dgid, - &dev_attr_orig_dgid, - &dev_attr_req_lim, - &dev_attr_zero_req_lim, - &dev_attr_local_ib_port, - &dev_attr_local_ib_device, - &dev_attr_ch_count, - &dev_attr_comp_vector, - &dev_attr_tl_retry_count, - &dev_attr_cmd_sg_entries, - &dev_attr_allow_ext_sg, +static struct attribute *srp_host_attrs[] = { + &dev_attr_id_ext.attr, + &dev_attr_ioc_guid.attr, + &dev_attr_service_id.attr, + &dev_attr_pkey.attr, + &dev_attr_sgid.attr, + &dev_attr_dgid.attr, + &dev_attr_orig_dgid.attr, + &dev_attr_req_lim.attr, + &dev_attr_zero_req_lim.attr, + &dev_attr_local_ib_port.attr, + &dev_attr_local_ib_device.attr, + &dev_attr_ch_count.attr, + &dev_attr_comp_vector.attr, + &dev_attr_tl_retry_count.attr, + &dev_attr_cmd_sg_entries.attr, + &dev_attr_allow_ext_sg.attr, NULL }; +ATTRIBUTE_GROUPS(srp_host); + static struct scsi_host_template srp_template = { .module = THIS_MODULE, .name = "InfiniBand SRP initiator", @@ -3090,7 +3099,7 @@ static struct scsi_host_template srp_template = { .can_queue = SRP_DEFAULT_CMD_SQ_SIZE, .this_id = -1, .cmd_per_lun = SRP_DEFAULT_CMD_SQ_SIZE, - .shost_attrs = srp_host_attrs, + .shost_groups = srp_host_groups, .track_queue_depth = 1, .cmd_size = sizeof(struct srp_request), }; From 2899836f9430664d5eab9f0b08f964b975dfc230 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Tue, 12 Oct 2021 16:35:17 -0700 Subject: [PATCH 203/279] scsi: message: fusion: Switch to attribute groups struct device supports attribute groups directly but does not support struct device_attribute directly. Hence switch to attribute groups. Link: https://lore.kernel.org/r/20211012233558.4066756-6-bvanassche@acm.org Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/message/fusion/mptfc.c | 2 +- drivers/message/fusion/mptsas.c | 2 +- drivers/message/fusion/mptscsih.c | 36 +++++++++++++++++++------------ drivers/message/fusion/mptscsih.h | 2 +- drivers/message/fusion/mptspi.c | 2 +- 5 files changed, 26 insertions(+), 18 deletions(-) diff --git a/drivers/message/fusion/mptfc.c b/drivers/message/fusion/mptfc.c index 7a6278ae71d2..fac747109209 100644 --- a/drivers/message/fusion/mptfc.c +++ b/drivers/message/fusion/mptfc.c @@ -129,7 +129,7 @@ static struct scsi_host_template mptfc_driver_template = { .sg_tablesize = MPT_SCSI_SG_DEPTH, .max_sectors = 8192, .cmd_per_lun = 7, - .shost_attrs = mptscsih_host_attrs, + .shost_groups = mptscsih_host_attr_groups, }; /**************************************************************************** diff --git a/drivers/message/fusion/mptsas.c b/drivers/message/fusion/mptsas.c index 38a7cb0a3ecc..091b45024d34 100644 --- a/drivers/message/fusion/mptsas.c +++ b/drivers/message/fusion/mptsas.c @@ -2020,7 +2020,7 @@ static struct scsi_host_template mptsas_driver_template = { .sg_tablesize = MPT_SCSI_SG_DEPTH, .max_sectors = 8192, .cmd_per_lun = 7, - .shost_attrs = mptscsih_host_attrs, + .shost_groups = mptscsih_host_attr_groups, .no_write_same = 1, }; diff --git a/drivers/message/fusion/mptscsih.c b/drivers/message/fusion/mptscsih.c index ab9611e775d3..276084ed04a6 100644 --- a/drivers/message/fusion/mptscsih.c +++ b/drivers/message/fusion/mptscsih.c @@ -3218,23 +3218,31 @@ mptscsih_debug_level_store(struct device *dev, struct device_attribute *attr, static DEVICE_ATTR(debug_level, S_IRUGO | S_IWUSR, mptscsih_debug_level_show, mptscsih_debug_level_store); -struct device_attribute *mptscsih_host_attrs[] = { - &dev_attr_version_fw, - &dev_attr_version_bios, - &dev_attr_version_mpi, - &dev_attr_version_product, - &dev_attr_version_nvdata_persistent, - &dev_attr_version_nvdata_default, - &dev_attr_board_name, - &dev_attr_board_assembly, - &dev_attr_board_tracer, - &dev_attr_io_delay, - &dev_attr_device_delay, - &dev_attr_debug_level, +static struct attribute *mptscsih_host_attrs[] = { + &dev_attr_version_fw.attr, + &dev_attr_version_bios.attr, + &dev_attr_version_mpi.attr, + &dev_attr_version_product.attr, + &dev_attr_version_nvdata_persistent.attr, + &dev_attr_version_nvdata_default.attr, + &dev_attr_board_name.attr, + &dev_attr_board_assembly.attr, + &dev_attr_board_tracer.attr, + &dev_attr_io_delay.attr, + &dev_attr_device_delay.attr, + &dev_attr_debug_level.attr, NULL, }; -EXPORT_SYMBOL(mptscsih_host_attrs); +static const struct attribute_group mptscsih_host_attr_group = { + .attrs = mptscsih_host_attrs +}; + +const struct attribute_group *mptscsih_host_attr_groups[] = { + &mptscsih_host_attr_group, + NULL +}; +EXPORT_SYMBOL(mptscsih_host_attr_groups); EXPORT_SYMBOL(mptscsih_remove); EXPORT_SYMBOL(mptscsih_shutdown); diff --git a/drivers/message/fusion/mptscsih.h b/drivers/message/fusion/mptscsih.h index 2baeefd9be7a..a22c5eaf703c 100644 --- a/drivers/message/fusion/mptscsih.h +++ b/drivers/message/fusion/mptscsih.h @@ -131,7 +131,7 @@ extern int mptscsih_ioc_reset(MPT_ADAPTER *ioc, int post_reset); extern int mptscsih_change_queue_depth(struct scsi_device *sdev, int qdepth); extern u8 mptscsih_raid_id_to_num(MPT_ADAPTER *ioc, u8 channel, u8 id); extern int mptscsih_is_phys_disk(MPT_ADAPTER *ioc, u8 channel, u8 id); -extern struct device_attribute *mptscsih_host_attrs[]; +extern const struct attribute_group *mptscsih_host_attr_groups[]; extern struct scsi_cmnd *mptscsih_get_scsi_lookup(MPT_ADAPTER *ioc, int i); extern void mptscsih_taskmgmt_response_code(MPT_ADAPTER *ioc, u8 response_code); extern void mptscsih_flush_running_cmds(MPT_SCSI_HOST *hd); diff --git a/drivers/message/fusion/mptspi.c b/drivers/message/fusion/mptspi.c index 44b7ce124ae1..acd4805dcf83 100644 --- a/drivers/message/fusion/mptspi.c +++ b/drivers/message/fusion/mptspi.c @@ -843,7 +843,7 @@ static struct scsi_host_template mptspi_driver_template = { .sg_tablesize = MPT_SCSI_SG_DEPTH, .max_sectors = 8192, .cmd_per_lun = 7, - .shost_attrs = mptscsih_host_attrs, + .shost_groups = mptscsih_host_attr_groups, }; static int mptspi_write_spi_device_pg1(struct scsi_target *starget, From d8d7cf3f7d073cea8c3e4c3a740d5d24744280d0 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Tue, 12 Oct 2021 16:35:18 -0700 Subject: [PATCH 204/279] scsi: zfcp: Switch to attribute groups struct device supports attribute groups directly but does not support struct device_attribute directly. Hence switch to attribute groups. Link: https://lore.kernel.org/r/20211012233558.4066756-7-bvanassche@acm.org Acked-by: Benjamin Block Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/s390/scsi/zfcp_ext.h | 4 +-- drivers/s390/scsi/zfcp_scsi.c | 4 +-- drivers/s390/scsi/zfcp_sysfs.c | 52 +++++++++++++++++++++++----------- 3 files changed, 39 insertions(+), 21 deletions(-) diff --git a/drivers/s390/scsi/zfcp_ext.h b/drivers/s390/scsi/zfcp_ext.h index 6bc96d70254d..c302cbb18a55 100644 --- a/drivers/s390/scsi/zfcp_ext.h +++ b/drivers/s390/scsi/zfcp_ext.h @@ -184,8 +184,8 @@ extern const struct attribute_group *zfcp_sysfs_adapter_attr_groups[]; extern const struct attribute_group *zfcp_unit_attr_groups[]; extern const struct attribute_group *zfcp_port_attr_groups[]; extern struct mutex zfcp_sysfs_port_units_mutex; -extern struct device_attribute *zfcp_sysfs_sdev_attrs[]; -extern struct device_attribute *zfcp_sysfs_shost_attrs[]; +extern const struct attribute_group *zfcp_sysfs_sdev_attr_groups[]; +extern const struct attribute_group *zfcp_sysfs_shost_attr_groups[]; bool zfcp_sysfs_port_is_removing(const struct zfcp_port *const port); /* zfcp_unit.c */ diff --git a/drivers/s390/scsi/zfcp_scsi.c b/drivers/s390/scsi/zfcp_scsi.c index e0a6d8c1f198..526ac240d9fe 100644 --- a/drivers/s390/scsi/zfcp_scsi.c +++ b/drivers/s390/scsi/zfcp_scsi.c @@ -444,8 +444,8 @@ static struct scsi_host_template zfcp_scsi_host_template = { /* report size limit per scatter-gather segment */ .max_segment_size = ZFCP_QDIO_SBALE_LEN, .dma_boundary = ZFCP_QDIO_SBALE_LEN - 1, - .shost_attrs = zfcp_sysfs_shost_attrs, - .sdev_attrs = zfcp_sysfs_sdev_attrs, + .shost_groups = zfcp_sysfs_shost_attr_groups, + .sdev_groups = zfcp_sysfs_sdev_attr_groups, .track_queue_depth = 1, .supported_mode = MODE_INITIATOR, }; diff --git a/drivers/s390/scsi/zfcp_sysfs.c b/drivers/s390/scsi/zfcp_sysfs.c index b8cd75a872ee..dbf3e50444e6 100644 --- a/drivers/s390/scsi/zfcp_sysfs.c +++ b/drivers/s390/scsi/zfcp_sysfs.c @@ -672,17 +672,26 @@ ZFCP_DEFINE_SCSI_ATTR(zfcp_in_recovery, "%d\n", ZFCP_DEFINE_SCSI_ATTR(zfcp_status, "0x%08x\n", atomic_read(&zfcp_sdev->status)); -struct device_attribute *zfcp_sysfs_sdev_attrs[] = { - &dev_attr_fcp_lun, - &dev_attr_wwpn, - &dev_attr_hba_id, - &dev_attr_read_latency, - &dev_attr_write_latency, - &dev_attr_cmd_latency, - &dev_attr_zfcp_access_denied, - &dev_attr_zfcp_failed, - &dev_attr_zfcp_in_recovery, - &dev_attr_zfcp_status, +struct attribute *zfcp_sdev_attrs[] = { + &dev_attr_fcp_lun.attr, + &dev_attr_wwpn.attr, + &dev_attr_hba_id.attr, + &dev_attr_read_latency.attr, + &dev_attr_write_latency.attr, + &dev_attr_cmd_latency.attr, + &dev_attr_zfcp_access_denied.attr, + &dev_attr_zfcp_failed.attr, + &dev_attr_zfcp_in_recovery.attr, + &dev_attr_zfcp_status.attr, + NULL +}; + +static const struct attribute_group zfcp_sysfs_sdev_attr_group = { + .attrs = zfcp_sdev_attrs +}; + +const struct attribute_group *zfcp_sysfs_sdev_attr_groups[] = { + &zfcp_sysfs_sdev_attr_group, NULL }; @@ -783,12 +792,21 @@ static ssize_t zfcp_sysfs_adapter_q_full_show(struct device *dev, } static DEVICE_ATTR(queue_full, S_IRUGO, zfcp_sysfs_adapter_q_full_show, NULL); -struct device_attribute *zfcp_sysfs_shost_attrs[] = { - &dev_attr_utilization, - &dev_attr_requests, - &dev_attr_megabytes, - &dev_attr_seconds_active, - &dev_attr_queue_full, +static struct attribute *zfcp_sysfs_shost_attrs[] = { + &dev_attr_utilization.attr, + &dev_attr_requests.attr, + &dev_attr_megabytes.attr, + &dev_attr_seconds_active.attr, + &dev_attr_queue_full.attr, + NULL +}; + +static const struct attribute_group zfcp_sysfs_shost_attr_group = { + .attrs = zfcp_sysfs_shost_attrs +}; + +const struct attribute_group *zfcp_sysfs_shost_attr_groups[] = { + &zfcp_sysfs_shost_attr_group, NULL }; From bd21c1e9891fa1acd8c1efbfbfdcd82a3fef0e4c Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Tue, 12 Oct 2021 16:35:19 -0700 Subject: [PATCH 205/279] scsi: 3w-9xxx: Switch to attribute groups struct device supports attribute groups directly but does not support struct device_attribute directly. Hence switch to attribute groups. Link: https://lore.kernel.org/r/20211012233558.4066756-8-bvanassche@acm.org Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/3w-9xxx.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/scsi/3w-9xxx.c b/drivers/scsi/3w-9xxx.c index 778d4892ed7d..cd823ff5deab 100644 --- a/drivers/scsi/3w-9xxx.c +++ b/drivers/scsi/3w-9xxx.c @@ -197,11 +197,13 @@ static struct device_attribute twa_host_stats_attr = { }; /* Host attributes initializer */ -static struct device_attribute *twa_host_attrs[] = { - &twa_host_stats_attr, +static struct attribute *twa_host_attrs[] = { + &twa_host_stats_attr.attr, NULL, }; +ATTRIBUTE_GROUPS(twa_host); + /* File operations struct for character device */ static const struct file_operations twa_fops = { .owner = THIS_MODULE, @@ -1988,7 +1990,7 @@ static struct scsi_host_template driver_template = { .sg_tablesize = TW_APACHE_MAX_SGL_LENGTH, .max_sectors = TW_MAX_SECTORS, .cmd_per_lun = TW_MAX_CMDS_PER_LUN, - .shost_attrs = twa_host_attrs, + .shost_groups = twa_host_groups, .emulated = 1, .no_write_same = 1, }; From 8de1cc904e17fded240533a78a4bf53ff94a64e3 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Tue, 12 Oct 2021 16:35:20 -0700 Subject: [PATCH 206/279] scsi: 3w-sas: Switch to attribute groups struct device supports attribute groups directly but does not support struct device_attribute directly. Hence switch to attribute groups. Link: https://lore.kernel.org/r/20211012233558.4066756-9-bvanassche@acm.org Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/3w-sas.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/scsi/3w-sas.c b/drivers/scsi/3w-sas.c index fc9a2f27aaf9..b9482da79512 100644 --- a/drivers/scsi/3w-sas.c +++ b/drivers/scsi/3w-sas.c @@ -198,11 +198,13 @@ static struct device_attribute twl_host_stats_attr = { }; /* Host attributes initializer */ -static struct device_attribute *twl_host_attrs[] = { - &twl_host_stats_attr, +static struct attribute *twl_host_attrs[] = { + &twl_host_stats_attr.attr, NULL, }; +ATTRIBUTE_GROUPS(twl_host); + /* This function will look up an AEN severity string */ static char *twl_aen_severity_lookup(unsigned char severity_code) { @@ -1542,7 +1544,7 @@ static struct scsi_host_template driver_template = { .sg_tablesize = TW_LIBERATOR_MAX_SGL_LENGTH, .max_sectors = TW_MAX_SECTORS, .cmd_per_lun = TW_MAX_CMDS_PER_LUN, - .shost_attrs = twl_host_attrs, + .shost_groups = twl_host_groups, .emulated = 1, .no_write_same = 1, }; From 65bc2a7fd83ee08017a4f2ca9515c15b046fd117 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Tue, 12 Oct 2021 16:35:21 -0700 Subject: [PATCH 207/279] scsi: 3w-xxxx: Switch to attribute groups struct device supports attribute groups directly but does not support struct device_attribute directly. Hence switch to attribute groups. Link: https://lore.kernel.org/r/20211012233558.4066756-10-bvanassche@acm.org Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/3w-xxxx.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/scsi/3w-xxxx.c b/drivers/scsi/3w-xxxx.c index 498a5ab7a321..2ab94179530a 100644 --- a/drivers/scsi/3w-xxxx.c +++ b/drivers/scsi/3w-xxxx.c @@ -532,11 +532,13 @@ static struct device_attribute tw_host_stats_attr = { }; /* Host attributes initializer */ -static struct device_attribute *tw_host_attrs[] = { - &tw_host_stats_attr, +static struct attribute *tw_host_attrs[] = { + &tw_host_stats_attr.attr, NULL, }; +ATTRIBUTE_GROUPS(tw_host); + /* This function will read the aen queue from the isr */ static int tw_aen_read_queue(TW_Device_Extension *tw_dev, int request_id) { @@ -2240,7 +2242,7 @@ static struct scsi_host_template driver_template = { .sg_tablesize = TW_MAX_SGL_LENGTH, .max_sectors = TW_MAX_SECTORS, .cmd_per_lun = TW_MAX_CMDS_PER_LUN, - .shost_attrs = tw_host_attrs, + .shost_groups = tw_host_groups, .emulated = 1, .no_write_same = 1, }; From 90cb6538b5da725f4204e7dd75d3b55c76b7fa70 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Tue, 12 Oct 2021 16:35:22 -0700 Subject: [PATCH 208/279] scsi: 53c700: Switch to attribute groups struct device supports attribute groups directly but does not support struct device_attribute directly. Hence switch to attribute groups. Link: https://lore.kernel.org/r/20211012233558.4066756-11-bvanassche@acm.org Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/53c700.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/drivers/scsi/53c700.c b/drivers/scsi/53c700.c index f1cbac77959e..3ad3ebaca8e9 100644 --- a/drivers/scsi/53c700.c +++ b/drivers/scsi/53c700.c @@ -163,7 +163,7 @@ STATIC int NCR_700_slave_configure(struct scsi_device *SDpnt); STATIC void NCR_700_slave_destroy(struct scsi_device *SDpnt); static int NCR_700_change_queue_depth(struct scsi_device *SDpnt, int depth); -STATIC struct device_attribute *NCR_700_dev_attrs[]; +STATIC const struct attribute_group *NCR_700_dev_groups[]; STATIC struct scsi_transport_template *NCR_700_transport_template = NULL; @@ -300,8 +300,8 @@ NCR_700_detect(struct scsi_host_template *tpnt, static int banner = 0; int j; - if(tpnt->sdev_attrs == NULL) - tpnt->sdev_attrs = NCR_700_dev_attrs; + if (tpnt->sdev_groups == NULL) + tpnt->sdev_groups = NCR_700_dev_groups; memory = dma_alloc_coherent(dev, TOTAL_MEM_SIZE, &pScript, GFP_KERNEL); if (!memory) { @@ -2085,11 +2085,13 @@ static struct device_attribute NCR_700_active_tags_attr = { .show = NCR_700_show_active_tags, }; -STATIC struct device_attribute *NCR_700_dev_attrs[] = { - &NCR_700_active_tags_attr, +STATIC struct attribute *NCR_700_dev_attrs[] = { + &NCR_700_active_tags_attr.attr, NULL, }; +ATTRIBUTE_GROUPS(NCR_700_dev); + EXPORT_SYMBOL(NCR_700_detect); EXPORT_SYMBOL(NCR_700_release); EXPORT_SYMBOL(NCR_700_intr); From bd16d71185c83ca825b1528ea18a6475e4eeff29 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Tue, 12 Oct 2021 16:35:23 -0700 Subject: [PATCH 209/279] scsi: aacraid: Switch to attribute groups struct device supports attribute groups directly but does not support struct device_attribute directly. Hence switch to attribute groups. Link: https://lore.kernel.org/r/20211012233558.4066756-12-bvanassche@acm.org Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/aacraid/linit.c | 38 ++++++++++++++++++++---------------- 1 file changed, 21 insertions(+), 17 deletions(-) diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c index 3168915adaa7..a911252075a6 100644 --- a/drivers/scsi/aacraid/linit.c +++ b/drivers/scsi/aacraid/linit.c @@ -605,12 +605,14 @@ static struct device_attribute aac_unique_id_attr = { -static struct device_attribute *aac_dev_attrs[] = { - &aac_raid_level_attr, - &aac_unique_id_attr, +static struct attribute *aac_dev_attrs[] = { + &aac_raid_level_attr.attr, + &aac_unique_id_attr.attr, NULL, }; +ATTRIBUTE_GROUPS(aac_dev); + static int aac_ioctl(struct scsi_device *sdev, unsigned int cmd, void __user *arg) { @@ -1442,21 +1444,23 @@ static struct device_attribute aac_reset = { .show = aac_show_reset_adapter, }; -static struct device_attribute *aac_attrs[] = { - &aac_model, - &aac_vendor, - &aac_flags, - &aac_kernel_version, - &aac_monitor_version, - &aac_bios_version, - &aac_lld_version, - &aac_serial_number, - &aac_max_channel, - &aac_max_id, - &aac_reset, +static struct attribute *aac_host_attrs[] = { + &aac_model.attr, + &aac_vendor.attr, + &aac_flags.attr, + &aac_kernel_version.attr, + &aac_monitor_version.attr, + &aac_bios_version.attr, + &aac_lld_version.attr, + &aac_serial_number.attr, + &aac_max_channel.attr, + &aac_max_id.attr, + &aac_reset.attr, NULL }; +ATTRIBUTE_GROUPS(aac_host); + ssize_t aac_get_serial_number(struct device *device, char *buf) { return aac_show_serial_number(device, &aac_serial_number, buf); @@ -1483,10 +1487,10 @@ static struct scsi_host_template aac_driver_template = { #endif .queuecommand = aac_queuecommand, .bios_param = aac_biosparm, - .shost_attrs = aac_attrs, + .shost_groups = aac_host_groups, .slave_configure = aac_slave_configure, .change_queue_depth = aac_change_queue_depth, - .sdev_attrs = aac_dev_attrs, + .sdev_groups = aac_dev_groups, .eh_abort_handler = aac_eh_abort, .eh_device_reset_handler = aac_eh_dev_reset, .eh_target_reset_handler = aac_eh_target_reset, From f2523502a40a1e0a7d8c2258f001fd81a4422008 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Tue, 12 Oct 2021 16:35:24 -0700 Subject: [PATCH 210/279] scsi: arcmsr: Switch to attribute groups struct device supports attribute groups directly but does not support struct device_attribute directly. Hence switch to attribute groups. Link: https://lore.kernel.org/r/20211012233558.4066756-13-bvanassche@acm.org Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/arcmsr/arcmsr.h | 2 +- drivers/scsi/arcmsr/arcmsr_attr.c | 33 +++++++++++++++++++------------ drivers/scsi/arcmsr/arcmsr_hba.c | 2 +- 3 files changed, 22 insertions(+), 15 deletions(-) diff --git a/drivers/scsi/arcmsr/arcmsr.h b/drivers/scsi/arcmsr/arcmsr.h index 6ce57f031df5..07df255c4b1b 100644 --- a/drivers/scsi/arcmsr/arcmsr.h +++ b/drivers/scsi/arcmsr/arcmsr.h @@ -1041,6 +1041,6 @@ extern uint32_t arcmsr_Read_iop_rqbuffer_data(struct AdapterControlBlock *, struct QBUFFER __iomem *); extern void arcmsr_clear_iop2drv_rqueue_buffer(struct AdapterControlBlock *); extern struct QBUFFER __iomem *arcmsr_get_iop_rqbuffer(struct AdapterControlBlock *); -extern struct device_attribute *arcmsr_host_attrs[]; +extern const struct attribute_group *arcmsr_host_groups[]; extern int arcmsr_alloc_sysfs_attr(struct AdapterControlBlock *); void arcmsr_free_sysfs_attr(struct AdapterControlBlock *acb); diff --git a/drivers/scsi/arcmsr/arcmsr_attr.c b/drivers/scsi/arcmsr/arcmsr_attr.c index 57be9609d504..baeb5e795690 100644 --- a/drivers/scsi/arcmsr/arcmsr_attr.c +++ b/drivers/scsi/arcmsr/arcmsr_attr.c @@ -58,8 +58,6 @@ #include #include "arcmsr.h" -struct device_attribute *arcmsr_host_attrs[]; - static ssize_t arcmsr_sysfs_iop_message_read(struct file *filp, struct kobject *kobj, struct bin_attribute *bin, @@ -389,16 +387,25 @@ static DEVICE_ATTR(host_fw_numbers_queue, S_IRUGO, arcmsr_attr_host_fw_numbers_q static DEVICE_ATTR(host_fw_sdram_size, S_IRUGO, arcmsr_attr_host_fw_sdram_size, NULL); static DEVICE_ATTR(host_fw_hd_channels, S_IRUGO, arcmsr_attr_host_fw_hd_channels, NULL); -struct device_attribute *arcmsr_host_attrs[] = { - &dev_attr_host_driver_version, - &dev_attr_host_driver_posted_cmd, - &dev_attr_host_driver_reset, - &dev_attr_host_driver_abort, - &dev_attr_host_fw_model, - &dev_attr_host_fw_version, - &dev_attr_host_fw_request_len, - &dev_attr_host_fw_numbers_queue, - &dev_attr_host_fw_sdram_size, - &dev_attr_host_fw_hd_channels, +static struct attribute *arcmsr_host_attrs[] = { + &dev_attr_host_driver_version.attr, + &dev_attr_host_driver_posted_cmd.attr, + &dev_attr_host_driver_reset.attr, + &dev_attr_host_driver_abort.attr, + &dev_attr_host_fw_model.attr, + &dev_attr_host_fw_version.attr, + &dev_attr_host_fw_request_len.attr, + &dev_attr_host_fw_numbers_queue.attr, + &dev_attr_host_fw_sdram_size.attr, + &dev_attr_host_fw_hd_channels.attr, NULL, }; + +static const struct attribute_group arcmsr_host_attr_group = { + .attrs = arcmsr_host_attrs, +}; + +const struct attribute_group *arcmsr_host_groups[] = { + &arcmsr_host_attr_group, + NULL +}; diff --git a/drivers/scsi/arcmsr/arcmsr_hba.c b/drivers/scsi/arcmsr/arcmsr_hba.c index daa8cf61f6d6..d3fb8a9c1c39 100644 --- a/drivers/scsi/arcmsr/arcmsr_hba.c +++ b/drivers/scsi/arcmsr/arcmsr_hba.c @@ -167,7 +167,7 @@ static struct scsi_host_template arcmsr_scsi_host_template = { .sg_tablesize = ARCMSR_DEFAULT_SG_ENTRIES, .max_sectors = ARCMSR_MAX_XFER_SECTORS_C, .cmd_per_lun = ARCMSR_DEFAULT_CMD_PERLUN, - .shost_attrs = arcmsr_host_attrs, + .shost_groups = arcmsr_host_groups, .no_write_same = 1, }; From ebcbac342cb5b77765dbe92085136d30fabc1595 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Tue, 12 Oct 2021 16:35:25 -0700 Subject: [PATCH 211/279] scsi: be2iscsi: Switch to attribute groups struct device supports attribute groups directly but does not support struct device_attribute directly. Hence switch to attribute groups. Link: https://lore.kernel.org/r/20211012233558.4066756-14-bvanassche@acm.org Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/be2iscsi/be_main.c | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/drivers/scsi/be2iscsi/be_main.c b/drivers/scsi/be2iscsi/be_main.c index e70f69f791db..ab55681145f8 100644 --- a/drivers/scsi/be2iscsi/be_main.c +++ b/drivers/scsi/be2iscsi/be_main.c @@ -163,17 +163,20 @@ DEVICE_ATTR(beiscsi_active_session_count, S_IRUGO, beiscsi_active_session_disp, NULL); DEVICE_ATTR(beiscsi_free_session_count, S_IRUGO, beiscsi_free_session_disp, NULL); -static struct device_attribute *beiscsi_attrs[] = { - &dev_attr_beiscsi_log_enable, - &dev_attr_beiscsi_drvr_ver, - &dev_attr_beiscsi_adapter_family, - &dev_attr_beiscsi_fw_ver, - &dev_attr_beiscsi_active_session_count, - &dev_attr_beiscsi_free_session_count, - &dev_attr_beiscsi_phys_port, + +static struct attribute *beiscsi_attrs[] = { + &dev_attr_beiscsi_log_enable.attr, + &dev_attr_beiscsi_drvr_ver.attr, + &dev_attr_beiscsi_adapter_family.attr, + &dev_attr_beiscsi_fw_ver.attr, + &dev_attr_beiscsi_active_session_count.attr, + &dev_attr_beiscsi_free_session_count.attr, + &dev_attr_beiscsi_phys_port.attr, NULL, }; +ATTRIBUTE_GROUPS(beiscsi); + static char const *cqe_desc[] = { "RESERVED_DESC", "SOL_CMD_COMPLETE", @@ -391,7 +394,7 @@ static struct scsi_host_template beiscsi_sht = { .eh_abort_handler = beiscsi_eh_abort, .eh_device_reset_handler = beiscsi_eh_device_reset, .eh_target_reset_handler = iscsi_eh_session_reset, - .shost_attrs = beiscsi_attrs, + .shost_groups = beiscsi_groups, .sg_tablesize = BEISCSI_SGLIST_ELEMENTS, .can_queue = BE2_IO_DEPTH, .this_id = -1, From e73af234a1a26a034dbf92539b54aedc5014dbb2 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Tue, 12 Oct 2021 16:35:26 -0700 Subject: [PATCH 212/279] scsi: bfa: Switch to attribute groups struct device supports attribute groups directly but does not support struct device_attribute directly. Hence switch to attribute groups. Link: https://lore.kernel.org/r/20211012233558.4066756-15-bvanassche@acm.org Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/bfa/bfad_attr.c | 68 ++++++++++++++++++++++-------------- drivers/scsi/bfa/bfad_im.c | 4 +-- drivers/scsi/bfa/bfad_im.h | 4 +-- 3 files changed, 46 insertions(+), 30 deletions(-) diff --git a/drivers/scsi/bfa/bfad_attr.c b/drivers/scsi/bfa/bfad_attr.c index 5ae1e3f78910..c8b947c16069 100644 --- a/drivers/scsi/bfa/bfad_attr.c +++ b/drivers/scsi/bfa/bfad_attr.c @@ -956,36 +956,52 @@ static DEVICE_ATTR(driver_name, S_IRUGO, bfad_im_drv_name_show, NULL); static DEVICE_ATTR(number_of_discovered_ports, S_IRUGO, bfad_im_num_of_discovered_ports_show, NULL); -struct device_attribute *bfad_im_host_attrs[] = { - &dev_attr_serial_number, - &dev_attr_model, - &dev_attr_model_description, - &dev_attr_node_name, - &dev_attr_symbolic_name, - &dev_attr_hardware_version, - &dev_attr_driver_version, - &dev_attr_option_rom_version, - &dev_attr_firmware_version, - &dev_attr_number_of_ports, - &dev_attr_driver_name, - &dev_attr_number_of_discovered_ports, +static struct attribute *bfad_im_host_attrs[] = { + &dev_attr_serial_number.attr, + &dev_attr_model.attr, + &dev_attr_model_description.attr, + &dev_attr_node_name.attr, + &dev_attr_symbolic_name.attr, + &dev_attr_hardware_version.attr, + &dev_attr_driver_version.attr, + &dev_attr_option_rom_version.attr, + &dev_attr_firmware_version.attr, + &dev_attr_number_of_ports.attr, + &dev_attr_driver_name.attr, + &dev_attr_number_of_discovered_ports.attr, NULL, }; -struct device_attribute *bfad_im_vport_attrs[] = { - &dev_attr_serial_number, - &dev_attr_model, - &dev_attr_model_description, - &dev_attr_node_name, - &dev_attr_symbolic_name, - &dev_attr_hardware_version, - &dev_attr_driver_version, - &dev_attr_option_rom_version, - &dev_attr_firmware_version, - &dev_attr_number_of_ports, - &dev_attr_driver_name, - &dev_attr_number_of_discovered_ports, +static const struct attribute_group bfad_im_host_attr_group = { + .attrs = bfad_im_host_attrs +}; + +const struct attribute_group *bfad_im_host_groups[] = { + &bfad_im_host_attr_group, + NULL +}; + +struct attribute *bfad_im_vport_attrs[] = { + &dev_attr_serial_number.attr, + &dev_attr_model.attr, + &dev_attr_model_description.attr, + &dev_attr_node_name.attr, + &dev_attr_symbolic_name.attr, + &dev_attr_hardware_version.attr, + &dev_attr_driver_version.attr, + &dev_attr_option_rom_version.attr, + &dev_attr_firmware_version.attr, + &dev_attr_number_of_ports.attr, + &dev_attr_driver_name.attr, + &dev_attr_number_of_discovered_ports.attr, NULL, }; +static const struct attribute_group bfad_im_vport_attr_group = { + .attrs = bfad_im_vport_attrs +}; +const struct attribute_group *bfad_im_vport_groups[] = { + &bfad_im_vport_attr_group, + NULL +}; diff --git a/drivers/scsi/bfa/bfad_im.c b/drivers/scsi/bfa/bfad_im.c index 79d8f2af1294..759d2bb1ecdd 100644 --- a/drivers/scsi/bfa/bfad_im.c +++ b/drivers/scsi/bfa/bfad_im.c @@ -809,7 +809,7 @@ struct scsi_host_template bfad_im_scsi_host_template = { .this_id = -1, .sg_tablesize = BFAD_IO_MAX_SGE, .cmd_per_lun = 3, - .shost_attrs = bfad_im_host_attrs, + .shost_groups = bfad_im_host_groups, .max_sectors = BFAD_MAX_SECTORS, .vendor_id = BFA_PCI_VENDOR_ID_BROCADE, }; @@ -831,7 +831,7 @@ struct scsi_host_template bfad_im_vport_template = { .this_id = -1, .sg_tablesize = BFAD_IO_MAX_SGE, .cmd_per_lun = 3, - .shost_attrs = bfad_im_vport_attrs, + .shost_groups = bfad_im_vport_groups, .max_sectors = BFAD_MAX_SECTORS, }; diff --git a/drivers/scsi/bfa/bfad_im.h b/drivers/scsi/bfa/bfad_im.h index f16d4b219e44..829345b514d1 100644 --- a/drivers/scsi/bfa/bfad_im.h +++ b/drivers/scsi/bfa/bfad_im.h @@ -174,8 +174,8 @@ extern struct fc_function_template bfad_im_vport_fc_function_template; extern struct scsi_transport_template *bfad_im_scsi_transport_template; extern struct scsi_transport_template *bfad_im_scsi_vport_transport_template; -extern struct device_attribute *bfad_im_host_attrs[]; -extern struct device_attribute *bfad_im_vport_attrs[]; +extern const struct attribute_group *bfad_im_host_groups[]; +extern const struct attribute_group *bfad_im_vport_groups[]; irqreturn_t bfad_intx(int irq, void *dev_id); From c3dd11d8ed4de2d79ec26b7d671ec1b7bfbeda0c Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Tue, 12 Oct 2021 16:35:27 -0700 Subject: [PATCH 213/279] scsi: bnx2fc: Switch to attribute groups struct device supports attribute groups directly but does not support struct device_attribute directly. Hence switch to attribute groups. Link: https://lore.kernel.org/r/20211012233558.4066756-16-bvanassche@acm.org Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/bnx2fc/bnx2fc_fcoe.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/scsi/bnx2fc/bnx2fc_fcoe.c b/drivers/scsi/bnx2fc/bnx2fc_fcoe.c index 8863a74e6c57..71fa62bd3083 100644 --- a/drivers/scsi/bnx2fc/bnx2fc_fcoe.c +++ b/drivers/scsi/bnx2fc/bnx2fc_fcoe.c @@ -2951,11 +2951,13 @@ bnx2fc_tm_timeout_store(struct device *dev, static DEVICE_ATTR(tm_timeout, S_IRUGO|S_IWUSR, bnx2fc_tm_timeout_show, bnx2fc_tm_timeout_store); -static struct device_attribute *bnx2fc_host_attrs[] = { - &dev_attr_tm_timeout, +static struct attribute *bnx2fc_host_attrs[] = { + &dev_attr_tm_timeout.attr, NULL, }; +ATTRIBUTE_GROUPS(bnx2fc_host); + /* * scsi_host_template structure used while registering with SCSI-ml */ @@ -2977,7 +2979,7 @@ static struct scsi_host_template bnx2fc_shost_template = { .max_sectors = 0x3fbf, .track_queue_depth = 1, .slave_configure = bnx2fc_slave_configure, - .shost_attrs = bnx2fc_host_attrs, + .shost_groups = bnx2fc_host_groups, }; static struct libfc_function_template bnx2fc_libfc_fcn_templ = { From eb78ac7a5474b56fa7b71991664843b9e678f8a3 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Tue, 12 Oct 2021 16:35:28 -0700 Subject: [PATCH 214/279] scsi: bnx2i: Switch to attribute groups struct device supports attribute groups directly but does not support struct device_attribute directly. Hence switch to attribute groups. Link: https://lore.kernel.org/r/20211012233558.4066756-17-bvanassche@acm.org Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/bnx2i/bnx2i.h | 2 +- drivers/scsi/bnx2i/bnx2i_iscsi.c | 2 +- drivers/scsi/bnx2i/bnx2i_sysfs.c | 15 ++++++++++++--- 3 files changed, 14 insertions(+), 5 deletions(-) diff --git a/drivers/scsi/bnx2i/bnx2i.h b/drivers/scsi/bnx2i/bnx2i.h index 663a63d4dae4..df7d04afce05 100644 --- a/drivers/scsi/bnx2i/bnx2i.h +++ b/drivers/scsi/bnx2i/bnx2i.h @@ -795,7 +795,7 @@ extern struct cnic_ulp_ops bnx2i_cnic_cb; extern unsigned int sq_size; extern unsigned int rq_size; -extern struct device_attribute *bnx2i_dev_attributes[]; +extern const struct attribute_group *bnx2i_dev_groups[]; diff --git a/drivers/scsi/bnx2i/bnx2i_iscsi.c b/drivers/scsi/bnx2i/bnx2i_iscsi.c index 1b5f3e143f07..e21b053b4f3e 100644 --- a/drivers/scsi/bnx2i/bnx2i_iscsi.c +++ b/drivers/scsi/bnx2i/bnx2i_iscsi.c @@ -2266,7 +2266,7 @@ static struct scsi_host_template bnx2i_host_template = { .cmd_per_lun = 128, .this_id = -1, .sg_tablesize = ISCSI_MAX_BDS_PER_CMD, - .shost_attrs = bnx2i_dev_attributes, + .shost_groups = bnx2i_dev_groups, .track_queue_depth = 1, }; diff --git a/drivers/scsi/bnx2i/bnx2i_sysfs.c b/drivers/scsi/bnx2i/bnx2i_sysfs.c index bea00073cb7c..d6b0bbb5176b 100644 --- a/drivers/scsi/bnx2i/bnx2i_sysfs.c +++ b/drivers/scsi/bnx2i/bnx2i_sysfs.c @@ -142,8 +142,17 @@ static DEVICE_ATTR(sq_size, S_IRUGO | S_IWUSR, static DEVICE_ATTR(num_ccell, S_IRUGO | S_IWUSR, bnx2i_show_ccell_info, bnx2i_set_ccell_info); -struct device_attribute *bnx2i_dev_attributes[] = { - &dev_attr_sq_size, - &dev_attr_num_ccell, +static struct attribute *bnx2i_dev_attributes[] = { + &dev_attr_sq_size.attr, + &dev_attr_num_ccell.attr, + NULL +}; + +static const struct attribute_group bnx2i_dev_attr_group = { + .attrs = bnx2i_dev_attributes +}; + +const struct attribute_group *bnx2i_dev_groups[] = { + &bnx2i_dev_attr_group, NULL }; From 623cf762c73e300849d4dad94d9fdb749b5e2072 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Tue, 12 Oct 2021 16:35:29 -0700 Subject: [PATCH 215/279] scsi: csiostor: Switch to attribute groups struct device supports attribute groups directly but does not support struct device_attribute directly. Hence switch to attribute groups. Link: https://lore.kernel.org/r/20211012233558.4066756-18-bvanassche@acm.org Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/csiostor/csio_scsi.c | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/drivers/scsi/csiostor/csio_scsi.c b/drivers/scsi/csiostor/csio_scsi.c index 3978c3d7eed5..55db02521221 100644 --- a/drivers/scsi/csiostor/csio_scsi.c +++ b/drivers/scsi/csiostor/csio_scsi.c @@ -1460,14 +1460,16 @@ static DEVICE_ATTR(disable_port, S_IWUSR, NULL, csio_disable_port); static DEVICE_ATTR(dbg_level, S_IRUGO | S_IWUSR, csio_show_dbg_level, csio_store_dbg_level); -static struct device_attribute *csio_fcoe_lport_attrs[] = { - &dev_attr_hw_state, - &dev_attr_device_reset, - &dev_attr_disable_port, - &dev_attr_dbg_level, +static struct attribute *csio_fcoe_lport_attrs[] = { + &dev_attr_hw_state.attr, + &dev_attr_device_reset.attr, + &dev_attr_disable_port.attr, + &dev_attr_dbg_level.attr, NULL, }; +ATTRIBUTE_GROUPS(csio_fcoe_lport); + static ssize_t csio_show_num_reg_rnodes(struct device *dev, struct device_attribute *attr, char *buf) @@ -1479,12 +1481,14 @@ csio_show_num_reg_rnodes(struct device *dev, static DEVICE_ATTR(num_reg_rnodes, S_IRUGO, csio_show_num_reg_rnodes, NULL); -static struct device_attribute *csio_fcoe_vport_attrs[] = { - &dev_attr_num_reg_rnodes, - &dev_attr_dbg_level, +static struct attribute *csio_fcoe_vport_attrs[] = { + &dev_attr_num_reg_rnodes.attr, + &dev_attr_dbg_level.attr, NULL, }; +ATTRIBUTE_GROUPS(csio_fcoe_vport); + static inline uint32_t csio_scsi_copy_to_sgl(struct csio_hw *hw, struct csio_ioreq *req) { @@ -2277,7 +2281,7 @@ struct scsi_host_template csio_fcoe_shost_template = { .this_id = -1, .sg_tablesize = CSIO_SCSI_MAX_SGE, .cmd_per_lun = CSIO_MAX_CMD_PER_LUN, - .shost_attrs = csio_fcoe_lport_attrs, + .shost_groups = csio_fcoe_lport_groups, .max_sectors = CSIO_MAX_SECTOR_SIZE, }; @@ -2296,7 +2300,7 @@ struct scsi_host_template csio_fcoe_shost_vport_template = { .this_id = -1, .sg_tablesize = CSIO_SCSI_MAX_SGE, .cmd_per_lun = CSIO_MAX_CMD_PER_LUN, - .shost_attrs = csio_fcoe_vport_attrs, + .shost_groups = csio_fcoe_vport_groups, .max_sectors = CSIO_MAX_SECTOR_SIZE, }; From 780c678912fbdae09e33127799eee30827a13516 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Tue, 12 Oct 2021 16:35:30 -0700 Subject: [PATCH 216/279] scsi: cxlflash: Switch to attribute groups struct device supports attribute groups directly but does not support struct device_attribute directly. Hence switch to attribute groups. Link: https://lore.kernel.org/r/20211012233558.4066756-19-bvanassche@acm.org Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/cxlflash/main.c | 40 ++++++++++++++++++++---------------- 1 file changed, 22 insertions(+), 18 deletions(-) diff --git a/drivers/scsi/cxlflash/main.c b/drivers/scsi/cxlflash/main.c index 2943cdd83614..e7be95ee7d64 100644 --- a/drivers/scsi/cxlflash/main.c +++ b/drivers/scsi/cxlflash/main.c @@ -3103,33 +3103,37 @@ static DEVICE_ATTR_RW(irqpoll_weight); static DEVICE_ATTR_RW(num_hwqs); static DEVICE_ATTR_RW(hwq_mode); -static struct device_attribute *cxlflash_host_attrs[] = { - &dev_attr_port0, - &dev_attr_port1, - &dev_attr_port2, - &dev_attr_port3, - &dev_attr_lun_mode, - &dev_attr_ioctl_version, - &dev_attr_port0_lun_table, - &dev_attr_port1_lun_table, - &dev_attr_port2_lun_table, - &dev_attr_port3_lun_table, - &dev_attr_irqpoll_weight, - &dev_attr_num_hwqs, - &dev_attr_hwq_mode, +static struct attribute *cxlflash_host_attrs[] = { + &dev_attr_port0.attr, + &dev_attr_port1.attr, + &dev_attr_port2.attr, + &dev_attr_port3.attr, + &dev_attr_lun_mode.attr, + &dev_attr_ioctl_version.attr, + &dev_attr_port0_lun_table.attr, + &dev_attr_port1_lun_table.attr, + &dev_attr_port2_lun_table.attr, + &dev_attr_port3_lun_table.attr, + &dev_attr_irqpoll_weight.attr, + &dev_attr_num_hwqs.attr, + &dev_attr_hwq_mode.attr, NULL }; +ATTRIBUTE_GROUPS(cxlflash_host); + /* * Device attributes */ static DEVICE_ATTR_RO(mode); -static struct device_attribute *cxlflash_dev_attrs[] = { - &dev_attr_mode, +static struct attribute *cxlflash_dev_attrs[] = { + &dev_attr_mode.attr, NULL }; +ATTRIBUTE_GROUPS(cxlflash_dev); + /* * Host template */ @@ -3150,8 +3154,8 @@ static struct scsi_host_template driver_template = { .this_id = -1, .sg_tablesize = 1, /* No scatter gather support */ .max_sectors = CXLFLASH_MAX_SECTORS, - .shost_attrs = cxlflash_host_attrs, - .sdev_attrs = cxlflash_dev_attrs, + .shost_groups = cxlflash_host_groups, + .sdev_groups = cxlflash_dev_groups, }; /* From d6ddcd8b38ab10d865e6a399a79934556ef4e0c4 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Tue, 12 Oct 2021 16:35:31 -0700 Subject: [PATCH 217/279] scsi: fnic: Switch to attribute groups struct device supports attribute groups directly but does not support struct device_attribute directly. Hence switch to attribute groups. Link: https://lore.kernel.org/r/20211012233558.4066756-20-bvanassche@acm.org Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/fnic/fnic.h | 2 +- drivers/scsi/fnic/fnic_attrs.c | 17 +++++++++++++---- drivers/scsi/fnic/fnic_main.c | 2 +- 3 files changed, 15 insertions(+), 6 deletions(-) diff --git a/drivers/scsi/fnic/fnic.h b/drivers/scsi/fnic/fnic.h index 69f373b53132..b95d0063dedb 100644 --- a/drivers/scsi/fnic/fnic.h +++ b/drivers/scsi/fnic/fnic.h @@ -322,7 +322,7 @@ static inline struct fnic *fnic_from_ctlr(struct fcoe_ctlr *fip) extern struct workqueue_struct *fnic_event_queue; extern struct workqueue_struct *fnic_fip_queue; -extern struct device_attribute *fnic_attrs[]; +extern const struct attribute_group *fnic_host_groups[]; void fnic_clear_intr_mode(struct fnic *fnic); int fnic_set_intr_mode(struct fnic *fnic); diff --git a/drivers/scsi/fnic/fnic_attrs.c b/drivers/scsi/fnic/fnic_attrs.c index aea0c3becfd4..bbe2ca4971b2 100644 --- a/drivers/scsi/fnic/fnic_attrs.c +++ b/drivers/scsi/fnic/fnic_attrs.c @@ -48,9 +48,18 @@ static DEVICE_ATTR(fnic_state, S_IRUGO, fnic_show_state, NULL); static DEVICE_ATTR(drv_version, S_IRUGO, fnic_show_drv_version, NULL); static DEVICE_ATTR(link_state, S_IRUGO, fnic_show_link_state, NULL); -struct device_attribute *fnic_attrs[] = { - &dev_attr_fnic_state, - &dev_attr_drv_version, - &dev_attr_link_state, +static struct attribute *fnic_host_attrs[] = { + &dev_attr_fnic_state.attr, + &dev_attr_drv_version.attr, + &dev_attr_link_state.attr, NULL, }; + +static const struct attribute_group fnic_host_attr_group = { + .attrs = fnic_host_attrs +}; + +const struct attribute_group *fnic_host_groups[] = { + &fnic_host_attr_group, + NULL +}; diff --git a/drivers/scsi/fnic/fnic_main.c b/drivers/scsi/fnic/fnic_main.c index 786f9d2704b6..44dbaa662d94 100644 --- a/drivers/scsi/fnic/fnic_main.c +++ b/drivers/scsi/fnic/fnic_main.c @@ -122,7 +122,7 @@ static struct scsi_host_template fnic_host_template = { .can_queue = FNIC_DFLT_IO_REQ, .sg_tablesize = FNIC_MAX_SG_DESC_CNT, .max_sectors = 0xffff, - .shost_attrs = fnic_attrs, + .shost_groups = fnic_host_groups, .track_queue_depth = 1, }; From 62ac8ccbb819e35eb107a7ef7ebdd678173aa49c Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Tue, 12 Oct 2021 16:35:32 -0700 Subject: [PATCH 218/279] scsi: hisi_sas: Switch to attribute groups struct device supports attribute groups directly but does not support struct device_attribute directly. Hence switch to attribute groups. Link: https://lore.kernel.org/r/20211012233558.4066756-21-bvanassche@acm.org Acked-by: John Garry Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/hisi_sas/hisi_sas_v1_hw.c | 8 +++++--- drivers/scsi/hisi_sas/hisi_sas_v2_hw.c | 8 +++++--- drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 14 ++++++++------ 3 files changed, 18 insertions(+), 12 deletions(-) diff --git a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c index b4951ff9ca51..3059d19e4368 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c +++ b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c @@ -1742,11 +1742,13 @@ static int hisi_sas_v1_init(struct hisi_hba *hisi_hba) return 0; } -static struct device_attribute *host_attrs_v1_hw[] = { - &dev_attr_phy_event_threshold, +static struct attribute *host_v1_hw_attrs[] = { + &dev_attr_phy_event_threshold.attr, NULL }; +ATTRIBUTE_GROUPS(host_v1_hw); + static struct scsi_host_template sht_v1_hw = { .name = DRV_NAME, .proc_name = DRV_NAME, @@ -1770,7 +1772,7 @@ static struct scsi_host_template sht_v1_hw = { #ifdef CONFIG_COMPAT .compat_ioctl = sas_ioctl, #endif - .shost_attrs = host_attrs_v1_hw, + .shost_groups = host_v1_hw_groups, .host_reset = hisi_sas_host_reset, }; diff --git a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c index 45eb0b98d00b..64ed3e472e65 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c +++ b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c @@ -3531,11 +3531,13 @@ static void wait_cmds_complete_timeout_v2_hw(struct hisi_hba *hisi_hba, } -static struct device_attribute *host_attrs_v2_hw[] = { - &dev_attr_phy_event_threshold, +static struct attribute *host_v2_hw_attrs[] = { + &dev_attr_phy_event_threshold.attr, NULL }; +ATTRIBUTE_GROUPS(host_v2_hw); + static int map_queues_v2_hw(struct Scsi_Host *shost) { struct hisi_hba *hisi_hba = shost_priv(shost); @@ -3579,7 +3581,7 @@ static struct scsi_host_template sht_v2_hw = { #ifdef CONFIG_COMPAT .compat_ioctl = sas_ioctl, #endif - .shost_attrs = host_attrs_v2_hw, + .shost_groups = host_v2_hw_groups, .host_reset = hisi_sas_host_reset, .map_queues = map_queues_v2_hw, .host_tagset = 1, diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c index 2082b066aca7..9ae47d1d9897 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c @@ -2766,14 +2766,16 @@ static int slave_configure_v3_hw(struct scsi_device *sdev) return 0; } -static struct device_attribute *host_attrs_v3_hw[] = { - &dev_attr_phy_event_threshold, - &dev_attr_intr_conv_v3_hw, - &dev_attr_intr_coal_ticks_v3_hw, - &dev_attr_intr_coal_count_v3_hw, +static struct attribute *host_v3_hw_attrs[] = { + &dev_attr_phy_event_threshold.attr, + &dev_attr_intr_conv_v3_hw.attr, + &dev_attr_intr_coal_ticks_v3_hw.attr, + &dev_attr_intr_coal_count_v3_hw.attr, NULL }; +ATTRIBUTE_GROUPS(host_v3_hw); + #define HISI_SAS_DEBUGFS_REG(x) {#x, x} struct hisi_sas_debugfs_reg_lu { @@ -3158,7 +3160,7 @@ static struct scsi_host_template sht_v3_hw = { #ifdef CONFIG_COMPAT .compat_ioctl = sas_ioctl, #endif - .shost_attrs = host_attrs_v3_hw, + .shost_groups = host_v3_hw_groups, .tag_alloc_policy = BLK_TAG_ALLOC_RR, .host_reset = hisi_sas_host_reset, .host_tagset = 1, From 4cd16323b5236e92636720f3591db3ce61c45955 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Tue, 12 Oct 2021 16:35:33 -0700 Subject: [PATCH 219/279] scsi: hpsa: Switch to attribute groups struct device supports attribute groups directly but does not support struct device_attribute directly. Hence switch to attribute groups. Link: https://lore.kernel.org/r/20211012233558.4066756-22-bvanassche@acm.org Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/hpsa.c | 44 ++++++++++++++++++++++++-------------------- 1 file changed, 24 insertions(+), 20 deletions(-) diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c index a1153449344a..cdf3328cc065 100644 --- a/drivers/scsi/hpsa.c +++ b/drivers/scsi/hpsa.c @@ -936,30 +936,34 @@ static DEVICE_ATTR(ctlr_num, S_IRUGO, static DEVICE_ATTR(legacy_board, S_IRUGO, host_show_legacy_board, NULL); -static struct device_attribute *hpsa_sdev_attrs[] = { - &dev_attr_raid_level, - &dev_attr_lunid, - &dev_attr_unique_id, - &dev_attr_hp_ssd_smart_path_enabled, - &dev_attr_path_info, - &dev_attr_sas_address, +static struct attribute *hpsa_sdev_attrs[] = { + &dev_attr_raid_level.attr, + &dev_attr_lunid.attr, + &dev_attr_unique_id.attr, + &dev_attr_hp_ssd_smart_path_enabled.attr, + &dev_attr_path_info.attr, + &dev_attr_sas_address.attr, NULL, }; -static struct device_attribute *hpsa_shost_attrs[] = { - &dev_attr_rescan, - &dev_attr_firmware_revision, - &dev_attr_commands_outstanding, - &dev_attr_transport_mode, - &dev_attr_resettable, - &dev_attr_hp_ssd_smart_path_status, - &dev_attr_raid_offload_debug, - &dev_attr_lockup_detected, - &dev_attr_ctlr_num, - &dev_attr_legacy_board, +ATTRIBUTE_GROUPS(hpsa_sdev); + +static struct attribute *hpsa_shost_attrs[] = { + &dev_attr_rescan.attr, + &dev_attr_firmware_revision.attr, + &dev_attr_commands_outstanding.attr, + &dev_attr_transport_mode.attr, + &dev_attr_resettable.attr, + &dev_attr_hp_ssd_smart_path_status.attr, + &dev_attr_raid_offload_debug.attr, + &dev_attr_lockup_detected.attr, + &dev_attr_ctlr_num.attr, + &dev_attr_legacy_board.attr, NULL, }; +ATTRIBUTE_GROUPS(hpsa_shost); + #define HPSA_NRESERVED_CMDS (HPSA_CMDS_RESERVED_FOR_DRIVER +\ HPSA_MAX_CONCURRENT_PASSTHRUS) @@ -980,8 +984,8 @@ static struct scsi_host_template hpsa_driver_template = { #ifdef CONFIG_COMPAT .compat_ioctl = hpsa_compat_ioctl, #endif - .sdev_attrs = hpsa_sdev_attrs, - .shost_attrs = hpsa_shost_attrs, + .sdev_groups = hpsa_sdev_groups, + .shost_groups = hpsa_shost_groups, .max_sectors = 2048, .no_write_same = 1, }; From e8fbc28e7fc71da2c820a5d3db49ca9bef7f4f3e Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Tue, 12 Oct 2021 16:35:34 -0700 Subject: [PATCH 220/279] scsi: hptiop: Switch to attribute groups struct device supports attribute groups directly but does not support struct device_attribute directly. Hence switch to attribute groups. Link: https://lore.kernel.org/r/20211012233558.4066756-23-bvanassche@acm.org Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/hptiop.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/drivers/scsi/hptiop.c b/drivers/scsi/hptiop.c index f9a9def394cc..d04245e379d7 100644 --- a/drivers/scsi/hptiop.c +++ b/drivers/scsi/hptiop.c @@ -1146,12 +1146,14 @@ static struct device_attribute hptiop_attr_fw_version = { .show = hptiop_show_fw_version, }; -static struct device_attribute *hptiop_attrs[] = { - &hptiop_attr_version, - &hptiop_attr_fw_version, +static struct attribute *hptiop_host_attrs[] = { + &hptiop_attr_version.attr, + &hptiop_attr_fw_version.attr, NULL }; +ATTRIBUTE_GROUPS(hptiop_host); + static int hptiop_slave_config(struct scsi_device *sdev) { if (sdev->type == TYPE_TAPE) @@ -1168,7 +1170,7 @@ static struct scsi_host_template driver_template = { .info = hptiop_info, .emulated = 0, .proc_name = driver_name, - .shost_attrs = hptiop_attrs, + .shost_groups = hptiop_host_groups, .slave_configure = hptiop_slave_config, .this_id = -1, .change_queue_depth = hptiop_adjust_disk_queue_depth, From c7da4e1cd0407cb6813d48aede1579428f79aa91 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Tue, 12 Oct 2021 16:35:35 -0700 Subject: [PATCH 221/279] scsi: ibmvscsi: Switch to attribute groups struct device supports attribute groups directly but does not support struct device_attribute directly. Hence switch to attribute groups. Link: https://lore.kernel.org/r/20211012233558.4066756-24-bvanassche@acm.org Acked-by: Tyrel Datwyler Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/ibmvscsi/ibmvscsi.c | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/drivers/scsi/ibmvscsi/ibmvscsi.c b/drivers/scsi/ibmvscsi/ibmvscsi.c index 5cc37859b874..10860593c42b 100644 --- a/drivers/scsi/ibmvscsi/ibmvscsi.c +++ b/drivers/scsi/ibmvscsi/ibmvscsi.c @@ -2064,18 +2064,20 @@ static int ibmvscsi_host_reset(struct Scsi_Host *shost, int reset_type) return 0; } -static struct device_attribute *ibmvscsi_attrs[] = { - &ibmvscsi_host_vhost_loc, - &ibmvscsi_host_vhost_name, - &ibmvscsi_host_srp_version, - &ibmvscsi_host_partition_name, - &ibmvscsi_host_partition_number, - &ibmvscsi_host_mad_version, - &ibmvscsi_host_os_type, - &ibmvscsi_host_config, +static struct attribute *ibmvscsi_host_attrs[] = { + &ibmvscsi_host_vhost_loc.attr, + &ibmvscsi_host_vhost_name.attr, + &ibmvscsi_host_srp_version.attr, + &ibmvscsi_host_partition_name.attr, + &ibmvscsi_host_partition_number.attr, + &ibmvscsi_host_mad_version.attr, + &ibmvscsi_host_os_type.attr, + &ibmvscsi_host_config.attr, NULL }; +ATTRIBUTE_GROUPS(ibmvscsi_host); + /* ------------------------------------------------------------ * SCSI driver registration */ @@ -2095,7 +2097,7 @@ static struct scsi_host_template driver_template = { .can_queue = IBMVSCSI_MAX_REQUESTS_DEFAULT, .this_id = -1, .sg_tablesize = SG_ALL, - .shost_attrs = ibmvscsi_attrs, + .shost_groups = ibmvscsi_host_groups, }; /** From 7adbf68f4950794519ccd462ba0c336a65ea3701 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Tue, 12 Oct 2021 16:35:36 -0700 Subject: [PATCH 222/279] scsi: ibmvfc: Switch to attribute groups struct device supports attribute groups directly but does not support struct device_attribute directly. Hence switch to attribute groups. Link: https://lore.kernel.org/r/20211012233558.4066756-25-bvanassche@acm.org Acked-by: Tyrel Datwyler Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/ibmvscsi/ibmvfc.c | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/drivers/scsi/ibmvscsi/ibmvfc.c b/drivers/scsi/ibmvscsi/ibmvfc.c index 63f42eebe0ba..a4b0a12f8a97 100644 --- a/drivers/scsi/ibmvscsi/ibmvfc.c +++ b/drivers/scsi/ibmvscsi/ibmvfc.c @@ -3588,18 +3588,20 @@ static struct bin_attribute ibmvfc_trace_attr = { }; #endif -static struct device_attribute *ibmvfc_attrs[] = { - &dev_attr_partition_name, - &dev_attr_device_name, - &dev_attr_port_loc_code, - &dev_attr_drc_name, - &dev_attr_npiv_version, - &dev_attr_capabilities, - &dev_attr_log_level, - &dev_attr_nr_scsi_channels, +static struct attribute *ibmvfc_host_attrs[] = { + &dev_attr_partition_name.attr, + &dev_attr_device_name.attr, + &dev_attr_port_loc_code.attr, + &dev_attr_drc_name.attr, + &dev_attr_npiv_version.attr, + &dev_attr_capabilities.attr, + &dev_attr_log_level.attr, + &dev_attr_nr_scsi_channels.attr, NULL }; +ATTRIBUTE_GROUPS(ibmvfc_host); + static struct scsi_host_template driver_template = { .module = THIS_MODULE, .name = "IBM POWER Virtual FC Adapter", @@ -3620,7 +3622,7 @@ static struct scsi_host_template driver_template = { .this_id = -1, .sg_tablesize = SG_ALL, .max_sectors = IBMVFC_MAX_SECTORS, - .shost_attrs = ibmvfc_attrs, + .shost_groups = ibmvfc_host_groups, .track_queue_depth = 1, .host_tagset = 1, }; From 47d1e6ae0e1e3feba63cffd59cbfea3757480e57 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Tue, 12 Oct 2021 16:35:37 -0700 Subject: [PATCH 223/279] scsi: ipr: Switch to attribute groups struct device supports attribute groups directly but does not support struct device_attribute directly. Hence switch to attribute groups. Link: https://lore.kernel.org/r/20211012233558.4066756-26-bvanassche@acm.org Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/ipr.c | 38 +++++++++++++++++++++----------------- 1 file changed, 21 insertions(+), 17 deletions(-) diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c index aa44216dcf9a..104bee9b3a9d 100644 --- a/drivers/scsi/ipr.c +++ b/drivers/scsi/ipr.c @@ -4236,18 +4236,20 @@ static struct bin_attribute ipr_ioa_async_err_log = { .write = ipr_next_async_err_log }; -static struct device_attribute *ipr_ioa_attrs[] = { - &ipr_fw_version_attr, - &ipr_log_level_attr, - &ipr_diagnostics_attr, - &ipr_ioa_state_attr, - &ipr_ioa_reset_attr, - &ipr_update_fw_attr, - &ipr_ioa_fw_type_attr, - &ipr_iopoll_weight_attr, +static struct attribute *ipr_ioa_attrs[] = { + &ipr_fw_version_attr.attr, + &ipr_log_level_attr.attr, + &ipr_diagnostics_attr.attr, + &ipr_ioa_state_attr.attr, + &ipr_ioa_reset_attr.attr, + &ipr_update_fw_attr.attr, + &ipr_ioa_fw_type_attr.attr, + &ipr_iopoll_weight_attr.attr, NULL, }; +ATTRIBUTE_GROUPS(ipr_ioa); + #ifdef CONFIG_SCSI_IPR_DUMP /** * ipr_read_dump - Dump the adapter @@ -4732,15 +4734,17 @@ static struct device_attribute ipr_raw_mode_attr = { .store = ipr_store_raw_mode }; -static struct device_attribute *ipr_dev_attrs[] = { - &ipr_adapter_handle_attr, - &ipr_resource_path_attr, - &ipr_device_id_attr, - &ipr_resource_type_attr, - &ipr_raw_mode_attr, +static struct attribute *ipr_dev_attrs[] = { + &ipr_adapter_handle_attr.attr, + &ipr_resource_path_attr.attr, + &ipr_device_id_attr.attr, + &ipr_resource_type_attr.attr, + &ipr_raw_mode_attr.attr, NULL, }; +ATTRIBUTE_GROUPS(ipr_dev); + /** * ipr_biosparam - Return the HSC mapping * @sdev: scsi device struct @@ -6762,8 +6766,8 @@ static struct scsi_host_template driver_template = { .sg_tablesize = IPR_MAX_SGLIST, .max_sectors = IPR_IOA_MAX_SECTORS, .cmd_per_lun = IPR_MAX_CMD_PER_LUN, - .shost_attrs = ipr_ioa_attrs, - .sdev_attrs = ipr_dev_attrs, + .shost_groups = ipr_ioa_groups, + .sdev_groups = ipr_dev_groups, .proc_name = IPR_NAME, }; From 7eae6af530a6d6c3cd8370cd79580515266eb5e0 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Tue, 12 Oct 2021 16:35:38 -0700 Subject: [PATCH 224/279] scsi: isci: Switch to attribute groups struct device supports attribute groups directly but does not support struct device_attribute directly. Hence switch to attribute groups. Link: https://lore.kernel.org/r/20211012233558.4066756-27-bvanassche@acm.org Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/isci/init.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/scsi/isci/init.c b/drivers/scsi/isci/init.c index ffd33e5decae..aade707c5553 100644 --- a/drivers/scsi/isci/init.c +++ b/drivers/scsi/isci/init.c @@ -142,11 +142,13 @@ static ssize_t isci_show_id(struct device *dev, struct device_attribute *attr, c static DEVICE_ATTR(isci_id, S_IRUGO, isci_show_id, NULL); -static struct device_attribute *isci_host_attrs[] = { - &dev_attr_isci_id, +static struct attribute *isci_host_attrs[] = { + &dev_attr_isci_id.attr, NULL }; +ATTRIBUTE_GROUPS(isci_host); + static struct scsi_host_template isci_sht = { .module = THIS_MODULE, @@ -173,7 +175,7 @@ static struct scsi_host_template isci_sht = { #ifdef CONFIG_COMPAT .compat_ioctl = sas_ioctl, #endif - .shost_attrs = isci_host_attrs, + .shost_groups = isci_host_groups, .track_queue_depth = 1, }; From 08adfa753743a19ceb753d8abffe51daadad7894 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Tue, 12 Oct 2021 16:35:39 -0700 Subject: [PATCH 225/279] scsi: lpfc: Switch to attribute groups struct device supports attribute groups directly but does not support struct device_attribute directly. Hence switch to attribute groups. Link: https://lore.kernel.org/r/20211012233558.4066756-28-bvanassche@acm.org Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/lpfc/lpfc_attr.c | 314 ++++++++++++++++++---------------- drivers/scsi/lpfc/lpfc_crtn.h | 4 +- drivers/scsi/lpfc/lpfc_init.c | 2 +- drivers/scsi/lpfc/lpfc_scsi.c | 4 +- 4 files changed, 171 insertions(+), 153 deletions(-) diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c index ebe417921dac..dd4c51b6ef4e 100644 --- a/drivers/scsi/lpfc/lpfc_attr.c +++ b/drivers/scsi/lpfc/lpfc_attr.c @@ -6394,160 +6394,178 @@ LPFC_ATTR_RW(vmid_priority_tagging, LPFC_VMID_PRIO_TAG_DISABLE, LPFC_VMID_PRIO_TAG_ALL_TARGETS, "Enable Priority Tagging VMID support"); -struct device_attribute *lpfc_hba_attrs[] = { - &dev_attr_nvme_info, - &dev_attr_scsi_stat, - &dev_attr_bg_info, - &dev_attr_bg_guard_err, - &dev_attr_bg_apptag_err, - &dev_attr_bg_reftag_err, - &dev_attr_info, - &dev_attr_serialnum, - &dev_attr_modeldesc, - &dev_attr_modelname, - &dev_attr_programtype, - &dev_attr_portnum, - &dev_attr_fwrev, - &dev_attr_hdw, - &dev_attr_option_rom_version, - &dev_attr_link_state, - &dev_attr_num_discovered_ports, - &dev_attr_menlo_mgmt_mode, - &dev_attr_lpfc_drvr_version, - &dev_attr_lpfc_enable_fip, - &dev_attr_lpfc_temp_sensor, - &dev_attr_lpfc_log_verbose, - &dev_attr_lpfc_lun_queue_depth, - &dev_attr_lpfc_tgt_queue_depth, - &dev_attr_lpfc_hba_queue_depth, - &dev_attr_lpfc_peer_port_login, - &dev_attr_lpfc_nodev_tmo, - &dev_attr_lpfc_devloss_tmo, - &dev_attr_lpfc_enable_fc4_type, - &dev_attr_lpfc_fcp_class, - &dev_attr_lpfc_use_adisc, - &dev_attr_lpfc_first_burst_size, - &dev_attr_lpfc_ack0, - &dev_attr_lpfc_xri_rebalancing, - &dev_attr_lpfc_topology, - &dev_attr_lpfc_scan_down, - &dev_attr_lpfc_link_speed, - &dev_attr_lpfc_fcp_io_sched, - &dev_attr_lpfc_ns_query, - &dev_attr_lpfc_fcp2_no_tgt_reset, - &dev_attr_lpfc_cr_delay, - &dev_attr_lpfc_cr_count, - &dev_attr_lpfc_multi_ring_support, - &dev_attr_lpfc_multi_ring_rctl, - &dev_attr_lpfc_multi_ring_type, - &dev_attr_lpfc_fdmi_on, - &dev_attr_lpfc_enable_SmartSAN, - &dev_attr_lpfc_max_luns, - &dev_attr_lpfc_enable_npiv, - &dev_attr_lpfc_fcf_failover_policy, - &dev_attr_lpfc_enable_rrq, - &dev_attr_lpfc_fcp_wait_abts_rsp, - &dev_attr_nport_evt_cnt, - &dev_attr_board_mode, - &dev_attr_max_vpi, - &dev_attr_used_vpi, - &dev_attr_max_rpi, - &dev_attr_used_rpi, - &dev_attr_max_xri, - &dev_attr_used_xri, - &dev_attr_npiv_info, - &dev_attr_issue_reset, - &dev_attr_lpfc_poll, - &dev_attr_lpfc_poll_tmo, - &dev_attr_lpfc_task_mgmt_tmo, - &dev_attr_lpfc_use_msi, - &dev_attr_lpfc_nvme_oas, - &dev_attr_lpfc_nvme_embed_cmd, - &dev_attr_lpfc_fcp_imax, - &dev_attr_lpfc_force_rscn, - &dev_attr_lpfc_cq_poll_threshold, - &dev_attr_lpfc_cq_max_proc_limit, - &dev_attr_lpfc_fcp_cpu_map, - &dev_attr_lpfc_fcp_mq_threshold, - &dev_attr_lpfc_hdw_queue, - &dev_attr_lpfc_irq_chann, - &dev_attr_lpfc_suppress_rsp, - &dev_attr_lpfc_nvmet_mrq, - &dev_attr_lpfc_nvmet_mrq_post, - &dev_attr_lpfc_nvme_enable_fb, - &dev_attr_lpfc_nvmet_fb_size, - &dev_attr_lpfc_enable_bg, - &dev_attr_lpfc_soft_wwnn, - &dev_attr_lpfc_soft_wwpn, - &dev_attr_lpfc_soft_wwn_enable, - &dev_attr_lpfc_enable_hba_reset, - &dev_attr_lpfc_enable_hba_heartbeat, - &dev_attr_lpfc_EnableXLane, - &dev_attr_lpfc_XLanePriority, - &dev_attr_lpfc_xlane_lun, - &dev_attr_lpfc_xlane_tgt, - &dev_attr_lpfc_xlane_vpt, - &dev_attr_lpfc_xlane_lun_state, - &dev_attr_lpfc_xlane_lun_status, - &dev_attr_lpfc_xlane_priority, - &dev_attr_lpfc_sg_seg_cnt, - &dev_attr_lpfc_max_scsicmpl_time, - &dev_attr_lpfc_stat_data_ctrl, - &dev_attr_lpfc_aer_support, - &dev_attr_lpfc_aer_state_cleanup, - &dev_attr_lpfc_sriov_nr_virtfn, - &dev_attr_lpfc_req_fw_upgrade, - &dev_attr_lpfc_suppress_link_up, - &dev_attr_iocb_hw, - &dev_attr_pls, - &dev_attr_pt, - &dev_attr_txq_hw, - &dev_attr_txcmplq_hw, - &dev_attr_lpfc_sriov_hw_max_virtfn, - &dev_attr_protocol, - &dev_attr_lpfc_xlane_supported, - &dev_attr_lpfc_enable_mds_diags, - &dev_attr_lpfc_ras_fwlog_buffsize, - &dev_attr_lpfc_ras_fwlog_level, - &dev_attr_lpfc_ras_fwlog_func, - &dev_attr_lpfc_enable_bbcr, - &dev_attr_lpfc_enable_dpp, - &dev_attr_lpfc_enable_mi, - &dev_attr_cmf_info, - &dev_attr_lpfc_max_vmid, - &dev_attr_lpfc_vmid_inactivity_timeout, - &dev_attr_lpfc_vmid_app_header, - &dev_attr_lpfc_vmid_priority_tagging, +static struct attribute *lpfc_hba_attrs[] = { + &dev_attr_nvme_info.attr, + &dev_attr_scsi_stat.attr, + &dev_attr_bg_info.attr, + &dev_attr_bg_guard_err.attr, + &dev_attr_bg_apptag_err.attr, + &dev_attr_bg_reftag_err.attr, + &dev_attr_info.attr, + &dev_attr_serialnum.attr, + &dev_attr_modeldesc.attr, + &dev_attr_modelname.attr, + &dev_attr_programtype.attr, + &dev_attr_portnum.attr, + &dev_attr_fwrev.attr, + &dev_attr_hdw.attr, + &dev_attr_option_rom_version.attr, + &dev_attr_link_state.attr, + &dev_attr_num_discovered_ports.attr, + &dev_attr_menlo_mgmt_mode.attr, + &dev_attr_lpfc_drvr_version.attr, + &dev_attr_lpfc_enable_fip.attr, + &dev_attr_lpfc_temp_sensor.attr, + &dev_attr_lpfc_log_verbose.attr, + &dev_attr_lpfc_lun_queue_depth.attr, + &dev_attr_lpfc_tgt_queue_depth.attr, + &dev_attr_lpfc_hba_queue_depth.attr, + &dev_attr_lpfc_peer_port_login.attr, + &dev_attr_lpfc_nodev_tmo.attr, + &dev_attr_lpfc_devloss_tmo.attr, + &dev_attr_lpfc_enable_fc4_type.attr, + &dev_attr_lpfc_fcp_class.attr, + &dev_attr_lpfc_use_adisc.attr, + &dev_attr_lpfc_first_burst_size.attr, + &dev_attr_lpfc_ack0.attr, + &dev_attr_lpfc_xri_rebalancing.attr, + &dev_attr_lpfc_topology.attr, + &dev_attr_lpfc_scan_down.attr, + &dev_attr_lpfc_link_speed.attr, + &dev_attr_lpfc_fcp_io_sched.attr, + &dev_attr_lpfc_ns_query.attr, + &dev_attr_lpfc_fcp2_no_tgt_reset.attr, + &dev_attr_lpfc_cr_delay.attr, + &dev_attr_lpfc_cr_count.attr, + &dev_attr_lpfc_multi_ring_support.attr, + &dev_attr_lpfc_multi_ring_rctl.attr, + &dev_attr_lpfc_multi_ring_type.attr, + &dev_attr_lpfc_fdmi_on.attr, + &dev_attr_lpfc_enable_SmartSAN.attr, + &dev_attr_lpfc_max_luns.attr, + &dev_attr_lpfc_enable_npiv.attr, + &dev_attr_lpfc_fcf_failover_policy.attr, + &dev_attr_lpfc_enable_rrq.attr, + &dev_attr_lpfc_fcp_wait_abts_rsp.attr, + &dev_attr_nport_evt_cnt.attr, + &dev_attr_board_mode.attr, + &dev_attr_max_vpi.attr, + &dev_attr_used_vpi.attr, + &dev_attr_max_rpi.attr, + &dev_attr_used_rpi.attr, + &dev_attr_max_xri.attr, + &dev_attr_used_xri.attr, + &dev_attr_npiv_info.attr, + &dev_attr_issue_reset.attr, + &dev_attr_lpfc_poll.attr, + &dev_attr_lpfc_poll_tmo.attr, + &dev_attr_lpfc_task_mgmt_tmo.attr, + &dev_attr_lpfc_use_msi.attr, + &dev_attr_lpfc_nvme_oas.attr, + &dev_attr_lpfc_nvme_embed_cmd.attr, + &dev_attr_lpfc_fcp_imax.attr, + &dev_attr_lpfc_force_rscn.attr, + &dev_attr_lpfc_cq_poll_threshold.attr, + &dev_attr_lpfc_cq_max_proc_limit.attr, + &dev_attr_lpfc_fcp_cpu_map.attr, + &dev_attr_lpfc_fcp_mq_threshold.attr, + &dev_attr_lpfc_hdw_queue.attr, + &dev_attr_lpfc_irq_chann.attr, + &dev_attr_lpfc_suppress_rsp.attr, + &dev_attr_lpfc_nvmet_mrq.attr, + &dev_attr_lpfc_nvmet_mrq_post.attr, + &dev_attr_lpfc_nvme_enable_fb.attr, + &dev_attr_lpfc_nvmet_fb_size.attr, + &dev_attr_lpfc_enable_bg.attr, + &dev_attr_lpfc_soft_wwnn.attr, + &dev_attr_lpfc_soft_wwpn.attr, + &dev_attr_lpfc_soft_wwn_enable.attr, + &dev_attr_lpfc_enable_hba_reset.attr, + &dev_attr_lpfc_enable_hba_heartbeat.attr, + &dev_attr_lpfc_EnableXLane.attr, + &dev_attr_lpfc_XLanePriority.attr, + &dev_attr_lpfc_xlane_lun.attr, + &dev_attr_lpfc_xlane_tgt.attr, + &dev_attr_lpfc_xlane_vpt.attr, + &dev_attr_lpfc_xlane_lun_state.attr, + &dev_attr_lpfc_xlane_lun_status.attr, + &dev_attr_lpfc_xlane_priority.attr, + &dev_attr_lpfc_sg_seg_cnt.attr, + &dev_attr_lpfc_max_scsicmpl_time.attr, + &dev_attr_lpfc_stat_data_ctrl.attr, + &dev_attr_lpfc_aer_support.attr, + &dev_attr_lpfc_aer_state_cleanup.attr, + &dev_attr_lpfc_sriov_nr_virtfn.attr, + &dev_attr_lpfc_req_fw_upgrade.attr, + &dev_attr_lpfc_suppress_link_up.attr, + &dev_attr_iocb_hw.attr, + &dev_attr_pls.attr, + &dev_attr_pt.attr, + &dev_attr_txq_hw.attr, + &dev_attr_txcmplq_hw.attr, + &dev_attr_lpfc_sriov_hw_max_virtfn.attr, + &dev_attr_protocol.attr, + &dev_attr_lpfc_xlane_supported.attr, + &dev_attr_lpfc_enable_mds_diags.attr, + &dev_attr_lpfc_ras_fwlog_buffsize.attr, + &dev_attr_lpfc_ras_fwlog_level.attr, + &dev_attr_lpfc_ras_fwlog_func.attr, + &dev_attr_lpfc_enable_bbcr.attr, + &dev_attr_lpfc_enable_dpp.attr, + &dev_attr_lpfc_enable_mi.attr, + &dev_attr_cmf_info.attr, + &dev_attr_lpfc_max_vmid.attr, + &dev_attr_lpfc_vmid_inactivity_timeout.attr, + &dev_attr_lpfc_vmid_app_header.attr, + &dev_attr_lpfc_vmid_priority_tagging.attr, NULL, }; -struct device_attribute *lpfc_vport_attrs[] = { - &dev_attr_info, - &dev_attr_link_state, - &dev_attr_num_discovered_ports, - &dev_attr_lpfc_drvr_version, - &dev_attr_lpfc_log_verbose, - &dev_attr_lpfc_lun_queue_depth, - &dev_attr_lpfc_tgt_queue_depth, - &dev_attr_lpfc_nodev_tmo, - &dev_attr_lpfc_devloss_tmo, - &dev_attr_lpfc_hba_queue_depth, - &dev_attr_lpfc_peer_port_login, - &dev_attr_lpfc_restrict_login, - &dev_attr_lpfc_fcp_class, - &dev_attr_lpfc_use_adisc, - &dev_attr_lpfc_first_burst_size, - &dev_attr_lpfc_max_luns, - &dev_attr_nport_evt_cnt, - &dev_attr_npiv_info, - &dev_attr_lpfc_enable_da_id, - &dev_attr_lpfc_max_scsicmpl_time, - &dev_attr_lpfc_stat_data_ctrl, - &dev_attr_lpfc_static_vport, - &dev_attr_cmf_info, +static const struct attribute_group lpfc_hba_attr_group = { + .attrs = lpfc_hba_attrs +}; + +const struct attribute_group *lpfc_hba_groups[] = { + &lpfc_hba_attr_group, + NULL +}; + +static struct attribute *lpfc_vport_attrs[] = { + &dev_attr_info.attr, + &dev_attr_link_state.attr, + &dev_attr_num_discovered_ports.attr, + &dev_attr_lpfc_drvr_version.attr, + &dev_attr_lpfc_log_verbose.attr, + &dev_attr_lpfc_lun_queue_depth.attr, + &dev_attr_lpfc_tgt_queue_depth.attr, + &dev_attr_lpfc_nodev_tmo.attr, + &dev_attr_lpfc_devloss_tmo.attr, + &dev_attr_lpfc_hba_queue_depth.attr, + &dev_attr_lpfc_peer_port_login.attr, + &dev_attr_lpfc_restrict_login.attr, + &dev_attr_lpfc_fcp_class.attr, + &dev_attr_lpfc_use_adisc.attr, + &dev_attr_lpfc_first_burst_size.attr, + &dev_attr_lpfc_max_luns.attr, + &dev_attr_nport_evt_cnt.attr, + &dev_attr_npiv_info.attr, + &dev_attr_lpfc_enable_da_id.attr, + &dev_attr_lpfc_max_scsicmpl_time.attr, + &dev_attr_lpfc_stat_data_ctrl.attr, + &dev_attr_lpfc_static_vport.attr, + &dev_attr_cmf_info.attr, NULL, }; +static const struct attribute_group lpfc_vport_attr_group = { + .attrs = lpfc_vport_attrs +}; + +const struct attribute_group *lpfc_vport_groups[] = { + &lpfc_vport_attr_group, + NULL +}; + /** * sysfs_ctlreg_write - Write method for writing to ctlreg * @filp: open sysfs file diff --git a/drivers/scsi/lpfc/lpfc_crtn.h b/drivers/scsi/lpfc/lpfc_crtn.h index c512f4199142..ad4a954ecc09 100644 --- a/drivers/scsi/lpfc/lpfc_crtn.h +++ b/drivers/scsi/lpfc/lpfc_crtn.h @@ -428,8 +428,8 @@ void lpfc_get_cfgparam(struct lpfc_hba *); void lpfc_get_vport_cfgparam(struct lpfc_vport *); int lpfc_alloc_sysfs_attr(struct lpfc_vport *); void lpfc_free_sysfs_attr(struct lpfc_vport *); -extern struct device_attribute *lpfc_hba_attrs[]; -extern struct device_attribute *lpfc_vport_attrs[]; +extern const struct attribute_group *lpfc_hba_groups[]; +extern const struct attribute_group *lpfc_vport_groups[]; extern struct scsi_host_template lpfc_template; extern struct scsi_host_template lpfc_template_nvme; extern struct fc_function_template lpfc_transport_functions; diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index b7de66f89b3b..34b5d042bfd0 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c @@ -4574,7 +4574,7 @@ lpfc_create_port(struct lpfc_hba *phba, int instance, struct device *dev) /* Template for all vports this physical port creates */ memcpy(&phba->vport_template, &lpfc_template, sizeof(*template)); - phba->vport_template.shost_attrs = lpfc_vport_attrs; + phba->vport_template.shost_groups = lpfc_vport_groups; phba->vport_template.eh_bus_reset_handler = NULL; phba->vport_template.eh_host_reset_handler = NULL; phba->vport_template.vendor_id = 0; diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c index 35df919b6c03..67844fcc0e94 100644 --- a/drivers/scsi/lpfc/lpfc_scsi.c +++ b/drivers/scsi/lpfc/lpfc_scsi.c @@ -7202,7 +7202,7 @@ struct scsi_host_template lpfc_template_nvme = { .this_id = -1, .sg_tablesize = 1, .cmd_per_lun = 1, - .shost_attrs = lpfc_hba_attrs, + .shost_groups = lpfc_hba_groups, .max_sectors = 0xFFFFFFFF, .vendor_id = LPFC_NL_VENDOR_ID, .track_queue_depth = 0, @@ -7228,7 +7228,7 @@ struct scsi_host_template lpfc_template = { .this_id = -1, .sg_tablesize = LPFC_DEFAULT_SG_SEG_CNT, .cmd_per_lun = LPFC_CMD_PER_LUN, - .shost_attrs = lpfc_hba_attrs, + .shost_groups = lpfc_hba_groups, .max_sectors = 0xFFFFFFFF, .vendor_id = LPFC_NL_VENDOR_ID, .change_queue_depth = scsi_change_queue_depth, From ab53de242e073eec654f3ee5a6316f2dbd74d29e Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Tue, 12 Oct 2021 16:35:40 -0700 Subject: [PATCH 226/279] scsi: megaraid_mbox: Switch to attribute groups struct device supports attribute groups directly but does not support struct device_attribute directly. Hence switch to attribute groups. Link: https://lore.kernel.org/r/20211012233558.4066756-29-bvanassche@acm.org Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/megaraid/megaraid_mbox.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/drivers/scsi/megaraid/megaraid_mbox.c b/drivers/scsi/megaraid/megaraid_mbox.c index 0f47a9862ef9..14f930d27ca1 100644 --- a/drivers/scsi/megaraid/megaraid_mbox.c +++ b/drivers/scsi/megaraid/megaraid_mbox.c @@ -305,20 +305,23 @@ static struct pci_driver megaraid_pci_driver = { static DEVICE_ATTR_ADMIN_RO(megaraid_mbox_app_hndl); // Host template initializer for megaraid mbox sysfs device attributes -static struct device_attribute *megaraid_shost_attrs[] = { - &dev_attr_megaraid_mbox_app_hndl, +static struct attribute *megaraid_shost_attrs[] = { + &dev_attr_megaraid_mbox_app_hndl.attr, NULL, }; +ATTRIBUTE_GROUPS(megaraid_shost); static DEVICE_ATTR_ADMIN_RO(megaraid_mbox_ld); // Host template initializer for megaraid mbox sysfs device attributes -static struct device_attribute *megaraid_sdev_attrs[] = { - &dev_attr_megaraid_mbox_ld, +static struct attribute *megaraid_sdev_attrs[] = { + &dev_attr_megaraid_mbox_ld.attr, NULL, }; +ATTRIBUTE_GROUPS(megaraid_sdev); + /* * Scsi host template for megaraid unified driver */ @@ -331,8 +334,8 @@ static struct scsi_host_template megaraid_template_g = { .eh_host_reset_handler = megaraid_reset_handler, .change_queue_depth = scsi_change_queue_depth, .no_write_same = 1, - .sdev_attrs = megaraid_sdev_attrs, - .shost_attrs = megaraid_shost_attrs, + .sdev_groups = megaraid_sdev_groups, + .shost_groups = megaraid_shost_groups, }; From 09723bb252caaf5384439319ff599acbd93ddc2f Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Tue, 12 Oct 2021 16:35:40 -0700 Subject: [PATCH 227/279] scsi: megaraid_sas: Switch to attribute groups struct device supports attribute groups directly but does not support struct device_attribute directly. Hence switch to attribute groups. Link: https://lore.kernel.org/r/20211012233558.4066756-29-bvanassche@acm.org Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/megaraid/megaraid_sas_base.c | 24 ++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c index d1e7da28be9a..aeb95f409826 100644 --- a/drivers/scsi/megaraid/megaraid_sas_base.c +++ b/drivers/scsi/megaraid/megaraid_sas_base.c @@ -3481,19 +3481,21 @@ static DEVICE_ATTR_RW(enable_sdev_max_qd); static DEVICE_ATTR_RO(dump_system_regs); static DEVICE_ATTR_RO(raid_map_id); -static struct device_attribute *megaraid_host_attrs[] = { - &dev_attr_fw_crash_buffer_size, - &dev_attr_fw_crash_buffer, - &dev_attr_fw_crash_state, - &dev_attr_page_size, - &dev_attr_ldio_outstanding, - &dev_attr_fw_cmds_outstanding, - &dev_attr_enable_sdev_max_qd, - &dev_attr_dump_system_regs, - &dev_attr_raid_map_id, +static struct attribute *megaraid_host_attrs[] = { + &dev_attr_fw_crash_buffer_size.attr, + &dev_attr_fw_crash_buffer.attr, + &dev_attr_fw_crash_state.attr, + &dev_attr_page_size.attr, + &dev_attr_ldio_outstanding.attr, + &dev_attr_fw_cmds_outstanding.attr, + &dev_attr_enable_sdev_max_qd.attr, + &dev_attr_dump_system_regs.attr, + &dev_attr_raid_map_id.attr, NULL, }; +ATTRIBUTE_GROUPS(megaraid_host); + /* * Scsi host template for megaraid_sas driver */ @@ -3510,7 +3512,7 @@ static struct scsi_host_template megasas_template = { .eh_abort_handler = megasas_task_abort, .eh_host_reset_handler = megasas_reset_bus_host, .eh_timed_out = megasas_reset_timer, - .shost_attrs = megaraid_host_attrs, + .shost_groups = megaraid_host_groups, .bios_param = megasas_bios_param, .map_queues = megasas_map_queues, .mq_poll = megasas_blk_mq_poll, From 1bb3ca27d2caa109c615fdd16c3b44492ee5bbee Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Tue, 12 Oct 2021 16:35:41 -0700 Subject: [PATCH 228/279] scsi: mpt3sas: Switch to attribute groups struct device supports attribute groups directly but does not support struct device_attribute directly. Hence switch to attribute groups. Link: https://lore.kernel.org/r/20211012233558.4066756-30-bvanassche@acm.org Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/mpt3sas/mpt3sas_base.h | 4 +- drivers/scsi/mpt3sas/mpt3sas_ctl.c | 84 +++++++++++++++++----------- drivers/scsi/mpt3sas/mpt3sas_scsih.c | 8 +-- 3 files changed, 57 insertions(+), 39 deletions(-) diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.h b/drivers/scsi/mpt3sas/mpt3sas_base.h index f87c0911f66a..db6a759de1e9 100644 --- a/drivers/scsi/mpt3sas/mpt3sas_base.h +++ b/drivers/scsi/mpt3sas/mpt3sas_base.h @@ -1939,8 +1939,8 @@ mpt3sas_config_update_driver_trigger_pg4(struct MPT3SAS_ADAPTER *ioc, struct SL_WH_MPI_TRIGGERS_T *mpi_tg, bool set); /* ctl shared API */ -extern struct device_attribute *mpt3sas_host_attrs[]; -extern struct device_attribute *mpt3sas_dev_attrs[]; +extern const struct attribute_group *mpt3sas_host_groups[]; +extern const struct attribute_group *mpt3sas_dev_groups[]; void mpt3sas_ctl_init(ushort hbas_to_enumerate); void mpt3sas_ctl_exit(ushort hbas_to_enumerate); u8 mpt3sas_ctl_done(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 msix_index, diff --git a/drivers/scsi/mpt3sas/mpt3sas_ctl.c b/drivers/scsi/mpt3sas/mpt3sas_ctl.c index 1b79f01f03a4..0aabc9761be1 100644 --- a/drivers/scsi/mpt3sas/mpt3sas_ctl.c +++ b/drivers/scsi/mpt3sas/mpt3sas_ctl.c @@ -3842,37 +3842,46 @@ enable_sdev_max_qd_store(struct device *cdev, } static DEVICE_ATTR_RW(enable_sdev_max_qd); -struct device_attribute *mpt3sas_host_attrs[] = { - &dev_attr_version_fw, - &dev_attr_version_bios, - &dev_attr_version_mpi, - &dev_attr_version_product, - &dev_attr_version_nvdata_persistent, - &dev_attr_version_nvdata_default, - &dev_attr_board_name, - &dev_attr_board_assembly, - &dev_attr_board_tracer, - &dev_attr_io_delay, - &dev_attr_device_delay, - &dev_attr_logging_level, - &dev_attr_fwfault_debug, - &dev_attr_fw_queue_depth, - &dev_attr_host_sas_address, - &dev_attr_ioc_reset_count, - &dev_attr_host_trace_buffer_size, - &dev_attr_host_trace_buffer, - &dev_attr_host_trace_buffer_enable, - &dev_attr_reply_queue_count, - &dev_attr_diag_trigger_master, - &dev_attr_diag_trigger_event, - &dev_attr_diag_trigger_scsi, - &dev_attr_diag_trigger_mpi, - &dev_attr_drv_support_bitmap, - &dev_attr_BRM_status, - &dev_attr_enable_sdev_max_qd, +static struct attribute *mpt3sas_host_attrs[] = { + &dev_attr_version_fw.attr, + &dev_attr_version_bios.attr, + &dev_attr_version_mpi.attr, + &dev_attr_version_product.attr, + &dev_attr_version_nvdata_persistent.attr, + &dev_attr_version_nvdata_default.attr, + &dev_attr_board_name.attr, + &dev_attr_board_assembly.attr, + &dev_attr_board_tracer.attr, + &dev_attr_io_delay.attr, + &dev_attr_device_delay.attr, + &dev_attr_logging_level.attr, + &dev_attr_fwfault_debug.attr, + &dev_attr_fw_queue_depth.attr, + &dev_attr_host_sas_address.attr, + &dev_attr_ioc_reset_count.attr, + &dev_attr_host_trace_buffer_size.attr, + &dev_attr_host_trace_buffer.attr, + &dev_attr_host_trace_buffer_enable.attr, + &dev_attr_reply_queue_count.attr, + &dev_attr_diag_trigger_master.attr, + &dev_attr_diag_trigger_event.attr, + &dev_attr_diag_trigger_scsi.attr, + &dev_attr_diag_trigger_mpi.attr, + &dev_attr_drv_support_bitmap.attr, + &dev_attr_BRM_status.attr, + &dev_attr_enable_sdev_max_qd.attr, NULL, }; +static const struct attribute_group mpt3sas_host_attr_group = { + .attrs = mpt3sas_host_attrs +}; + +const struct attribute_group *mpt3sas_host_groups[] = { + &mpt3sas_host_attr_group, + NULL +}; + /* device attributes */ /** @@ -3976,14 +3985,23 @@ sas_ncq_prio_enable_store(struct device *dev, } static DEVICE_ATTR_RW(sas_ncq_prio_enable); -struct device_attribute *mpt3sas_dev_attrs[] = { - &dev_attr_sas_address, - &dev_attr_sas_device_handle, - &dev_attr_sas_ncq_prio_supported, - &dev_attr_sas_ncq_prio_enable, +struct attribute *mpt3sas_dev_attrs[] = { + &dev_attr_sas_address.attr, + &dev_attr_sas_device_handle.attr, + &dev_attr_sas_ncq_prio_supported.attr, + &dev_attr_sas_ncq_prio_enable.attr, NULL, }; +static const struct attribute_group mpt3sas_dev_attr_group = { + .attrs = mpt3sas_dev_attrs +}; + +const struct attribute_group *mpt3sas_dev_groups[] = { + &mpt3sas_dev_attr_group, + NULL +}; + /* file operations table for mpt3ctl device */ static const struct file_operations ctl_fops = { .owner = THIS_MODULE, diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c b/drivers/scsi/mpt3sas/mpt3sas_scsih.c index 39462535874b..344c4322480e 100644 --- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c +++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c @@ -11875,8 +11875,8 @@ static struct scsi_host_template mpt2sas_driver_template = { .sg_tablesize = MPT2SAS_SG_DEPTH, .max_sectors = 32767, .cmd_per_lun = 7, - .shost_attrs = mpt3sas_host_attrs, - .sdev_attrs = mpt3sas_dev_attrs, + .shost_groups = mpt3sas_host_groups, + .sdev_groups = mpt3sas_dev_groups, .track_queue_depth = 1, .cmd_size = sizeof(struct scsiio_tracker), }; @@ -11914,8 +11914,8 @@ static struct scsi_host_template mpt3sas_driver_template = { .max_sectors = 32767, .max_segment_size = 0xffffffff, .cmd_per_lun = 7, - .shost_attrs = mpt3sas_host_attrs, - .sdev_attrs = mpt3sas_dev_attrs, + .shost_groups = mpt3sas_host_groups, + .sdev_groups = mpt3sas_dev_groups, .track_queue_depth = 1, .cmd_size = sizeof(struct scsiio_tracker), .map_queues = scsih_map_queues, From 88b8132cff99f29216098fb30714faa6ad969700 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Tue, 12 Oct 2021 16:35:42 -0700 Subject: [PATCH 229/279] scsi: mvsas: Switch to attribute groups struct device supports attribute groups directly but does not support struct device_attribute directly. Hence switch to attribute groups. Link: https://lore.kernel.org/r/20211012233558.4066756-31-bvanassche@acm.org Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/mvsas/mv_init.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/drivers/scsi/mvsas/mv_init.c b/drivers/scsi/mvsas/mv_init.c index f18dd9703595..dcae2d4464f9 100644 --- a/drivers/scsi/mvsas/mv_init.c +++ b/drivers/scsi/mvsas/mv_init.c @@ -25,7 +25,7 @@ static const struct mvs_chip_info mvs_chips[] = { [chip_1320] = { 2, 4, 0x800, 17, 64, 8, 9, &mvs_94xx_dispatch, }, }; -static struct device_attribute *mvst_host_attrs[]; +static const struct attribute_group *mvst_host_groups[]; #define SOC_SAS_NUM 2 @@ -52,7 +52,7 @@ static struct scsi_host_template mvs_sht = { #ifdef CONFIG_COMPAT .compat_ioctl = sas_ioctl, #endif - .shost_attrs = mvst_host_attrs, + .shost_groups = mvst_host_groups, .track_queue_depth = 1, }; @@ -773,12 +773,14 @@ static void __exit mvs_exit(void) sas_release_transport(mvs_stt); } -static struct device_attribute *mvst_host_attrs[] = { - &dev_attr_driver_version, - &dev_attr_interrupt_coalescing, +static struct attribute *mvst_host_attrs[] = { + &dev_attr_driver_version.attr, + &dev_attr_interrupt_coalescing.attr, NULL, }; +ATTRIBUTE_GROUPS(mvst_host); + module_init(mvs_init); module_exit(mvs_exit); From 582c0360db90a521d8447134ab89ac71bfc73803 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Tue, 12 Oct 2021 16:35:43 -0700 Subject: [PATCH 230/279] scsi: myrb: Switch to attribute groups struct device supports attribute groups directly but does not support struct device_attribute directly. Hence switch to attribute groups. Link: https://lore.kernel.org/r/20211012233558.4066756-32-bvanassche@acm.org Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/myrb.c | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/drivers/scsi/myrb.c b/drivers/scsi/myrb.c index e8a7bcce4674..2a4506a5083e 100644 --- a/drivers/scsi/myrb.c +++ b/drivers/scsi/myrb.c @@ -2182,22 +2182,26 @@ static ssize_t flush_cache_store(struct device *dev, } static DEVICE_ATTR_WO(flush_cache); -static struct device_attribute *myrb_sdev_attrs[] = { - &dev_attr_rebuild, - &dev_attr_consistency_check, - &dev_attr_raid_state, - &dev_attr_raid_level, +static struct attribute *myrb_sdev_attrs[] = { + &dev_attr_rebuild.attr, + &dev_attr_consistency_check.attr, + &dev_attr_raid_state.attr, + &dev_attr_raid_level.attr, NULL, }; -static struct device_attribute *myrb_shost_attrs[] = { - &dev_attr_ctlr_num, - &dev_attr_model, - &dev_attr_firmware, - &dev_attr_flush_cache, +ATTRIBUTE_GROUPS(myrb_sdev); + +static struct attribute *myrb_shost_attrs[] = { + &dev_attr_ctlr_num.attr, + &dev_attr_model.attr, + &dev_attr_firmware.attr, + &dev_attr_flush_cache.attr, NULL, }; +ATTRIBUTE_GROUPS(myrb_shost); + static struct scsi_host_template myrb_template = { .module = THIS_MODULE, .name = "DAC960", @@ -2209,8 +2213,8 @@ static struct scsi_host_template myrb_template = { .slave_destroy = myrb_slave_destroy, .bios_param = myrb_biosparam, .cmd_size = sizeof(struct myrb_cmdblk), - .shost_attrs = myrb_shost_attrs, - .sdev_attrs = myrb_sdev_attrs, + .shost_groups = myrb_shost_groups, + .sdev_groups = myrb_sdev_groups, .this_id = -1, }; From 087c3ace6337b52e924fcc8d17441baf675523e3 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Tue, 12 Oct 2021 16:35:44 -0700 Subject: [PATCH 231/279] scsi: myrs: Switch to attribute groups struct device supports attribute groups directly but does not support struct device_attribute directly. Hence switch to attribute groups. Link: https://lore.kernel.org/r/20211012233558.4066756-33-bvanassche@acm.org Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/myrs.c | 40 ++++++++++++++++++++++------------------ 1 file changed, 22 insertions(+), 18 deletions(-) diff --git a/drivers/scsi/myrs.c b/drivers/scsi/myrs.c index 2ffe3cadda66..6ea323e9a2e3 100644 --- a/drivers/scsi/myrs.c +++ b/drivers/scsi/myrs.c @@ -1286,14 +1286,16 @@ static ssize_t consistency_check_store(struct device *dev, } static DEVICE_ATTR_RW(consistency_check); -static struct device_attribute *myrs_sdev_attrs[] = { - &dev_attr_consistency_check, - &dev_attr_rebuild, - &dev_attr_raid_state, - &dev_attr_raid_level, +static struct attribute *myrs_sdev_attrs[] = { + &dev_attr_consistency_check.attr, + &dev_attr_rebuild.attr, + &dev_attr_raid_state.attr, + &dev_attr_raid_level.attr, NULL, }; +ATTRIBUTE_GROUPS(myrs_sdev); + static ssize_t serial_show(struct device *dev, struct device_attribute *attr, char *buf) { @@ -1510,20 +1512,22 @@ static ssize_t disable_enclosure_messages_store(struct device *dev, } static DEVICE_ATTR_RW(disable_enclosure_messages); -static struct device_attribute *myrs_shost_attrs[] = { - &dev_attr_serial, - &dev_attr_ctlr_num, - &dev_attr_processor, - &dev_attr_model, - &dev_attr_ctlr_type, - &dev_attr_cache_size, - &dev_attr_firmware, - &dev_attr_discovery, - &dev_attr_flush_cache, - &dev_attr_disable_enclosure_messages, +static struct attribute *myrs_shost_attrs[] = { + &dev_attr_serial.attr, + &dev_attr_ctlr_num.attr, + &dev_attr_processor.attr, + &dev_attr_model.attr, + &dev_attr_ctlr_type.attr, + &dev_attr_cache_size.attr, + &dev_attr_firmware.attr, + &dev_attr_discovery.attr, + &dev_attr_flush_cache.attr, + &dev_attr_disable_enclosure_messages.attr, NULL, }; +ATTRIBUTE_GROUPS(myrs_shost); + /* * SCSI midlayer interface */ @@ -1923,8 +1927,8 @@ static struct scsi_host_template myrs_template = { .slave_configure = myrs_slave_configure, .slave_destroy = myrs_slave_destroy, .cmd_size = sizeof(struct myrs_cmdblk), - .shost_attrs = myrs_shost_attrs, - .sdev_attrs = myrs_sdev_attrs, + .shost_groups = myrs_shost_groups, + .sdev_groups = myrs_sdev_groups, .this_id = -1, }; From aec4b25c8572ff0e89af7ae97164ff2af50c4427 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Tue, 12 Oct 2021 16:35:45 -0700 Subject: [PATCH 232/279] scsi: ncr53c8xx: Switch to attribute groups struct device supports attribute groups directly but does not support struct device_attribute directly. Hence switch to attribute groups. Link: https://lore.kernel.org/r/20211012233558.4066756-34-bvanassche@acm.org Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/ncr53c8xx.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/drivers/scsi/ncr53c8xx.c b/drivers/scsi/ncr53c8xx.c index 168b854ccf14..fc8abe05fa8f 100644 --- a/drivers/scsi/ncr53c8xx.c +++ b/drivers/scsi/ncr53c8xx.c @@ -8039,11 +8039,13 @@ static struct device_attribute ncr53c8xx_revision_attr = { .show = show_ncr53c8xx_revision, }; -static struct device_attribute *ncr53c8xx_host_attrs[] = { - &ncr53c8xx_revision_attr, +static struct attribute *ncr53c8xx_host_attrs[] = { + &ncr53c8xx_revision_attr.attr, NULL }; +ATTRIBUTE_GROUPS(ncr53c8xx_host); + /*========================================================== ** ** Boot command line. @@ -8085,8 +8087,8 @@ struct Scsi_Host * __init ncr_attach(struct scsi_host_template *tpnt, if (!tpnt->name) tpnt->name = SCSI_NCR_DRIVER_NAME; - if (!tpnt->shost_attrs) - tpnt->shost_attrs = ncr53c8xx_host_attrs; + if (!tpnt->shost_groups) + tpnt->shost_groups = ncr53c8xx_host_groups; tpnt->queuecommand = ncr53c8xx_queue_command; tpnt->slave_configure = ncr53c8xx_slave_configure; From e71eebf744e47436d6d6126bc4e413d02a77ae13 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Tue, 12 Oct 2021 16:35:46 -0700 Subject: [PATCH 233/279] scsi: sym53c500_cs: Switch to attribute groups struct device supports attribute groups directly but does not support struct device_attribute directly. Hence switch to attribute groups. Link: https://lore.kernel.org/r/20211012233558.4066756-35-bvanassche@acm.org Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/pcmcia/sym53c500_cs.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/scsi/pcmcia/sym53c500_cs.c b/drivers/scsi/pcmcia/sym53c500_cs.c index d5c30ac662ba..fc93d2a57e1e 100644 --- a/drivers/scsi/pcmcia/sym53c500_cs.c +++ b/drivers/scsi/pcmcia/sym53c500_cs.c @@ -650,11 +650,13 @@ static struct device_attribute SYM53C500_pio_attr = { .store = SYM53C500_store_pio, }; -static struct device_attribute *SYM53C500_shost_attrs[] = { - &SYM53C500_pio_attr, +static struct attribute *SYM53C500_shost_attrs[] = { + &SYM53C500_pio_attr.attr, NULL, }; +ATTRIBUTE_GROUPS(SYM53C500_shost); + /* * scsi_host_template initializer */ @@ -669,7 +671,7 @@ static struct scsi_host_template sym53c500_driver_template = { .can_queue = 1, .this_id = 7, .sg_tablesize = 32, - .shost_attrs = SYM53C500_shost_attrs + .shost_groups = SYM53C500_shost_groups }; static int SYM53C500_config_check(struct pcmcia_device *p_dev, void *priv_data) From c03b72b86c7777127dc3aadb83c807619fcf510d Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Tue, 12 Oct 2021 16:35:47 -0700 Subject: [PATCH 234/279] scsi: pm8001: Switch to attribute groups struct device supports attribute groups directly but does not support struct device_attribute directly. Hence switch to attribute groups. Link: https://lore.kernel.org/r/20211012233558.4066756-36-bvanassche@acm.org Acked-by: Jack Wang Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/pm8001/pm8001_ctl.c | 64 +++++++++++++++++-------------- drivers/scsi/pm8001/pm8001_init.c | 2 +- drivers/scsi/pm8001/pm8001_sas.h | 2 +- 3 files changed, 38 insertions(+), 30 deletions(-) diff --git a/drivers/scsi/pm8001/pm8001_ctl.c b/drivers/scsi/pm8001/pm8001_ctl.c index b25e447aa3bd..397eb9f6a1dd 100644 --- a/drivers/scsi/pm8001/pm8001_ctl.c +++ b/drivers/scsi/pm8001/pm8001_ctl.c @@ -1002,34 +1002,42 @@ static ssize_t ctl_iop1_count_show(struct device *cdev, } static DEVICE_ATTR_RO(ctl_iop1_count); -struct device_attribute *pm8001_host_attrs[] = { - &dev_attr_interface_rev, - &dev_attr_controller_fatal_error, - &dev_attr_fw_version, - &dev_attr_update_fw, - &dev_attr_aap_log, - &dev_attr_iop_log, - &dev_attr_fatal_log, - &dev_attr_non_fatal_log, - &dev_attr_non_fatal_count, - &dev_attr_gsm_log, - &dev_attr_max_out_io, - &dev_attr_max_devices, - &dev_attr_max_sg_list, - &dev_attr_sas_spec_support, - &dev_attr_logging_level, - &dev_attr_event_log_size, - &dev_attr_host_sas_address, - &dev_attr_bios_version, - &dev_attr_ib_log, - &dev_attr_ob_log, - &dev_attr_ila_version, - &dev_attr_inc_fw_ver, - &dev_attr_ctl_mpi_state, - &dev_attr_ctl_hmi_error, - &dev_attr_ctl_raae_count, - &dev_attr_ctl_iop0_count, - &dev_attr_ctl_iop1_count, +static struct attribute *pm8001_host_attrs[] = { + &dev_attr_interface_rev.attr, + &dev_attr_controller_fatal_error.attr, + &dev_attr_fw_version.attr, + &dev_attr_update_fw.attr, + &dev_attr_aap_log.attr, + &dev_attr_iop_log.attr, + &dev_attr_fatal_log.attr, + &dev_attr_non_fatal_log.attr, + &dev_attr_non_fatal_count.attr, + &dev_attr_gsm_log.attr, + &dev_attr_max_out_io.attr, + &dev_attr_max_devices.attr, + &dev_attr_max_sg_list.attr, + &dev_attr_sas_spec_support.attr, + &dev_attr_logging_level.attr, + &dev_attr_event_log_size.attr, + &dev_attr_host_sas_address.attr, + &dev_attr_bios_version.attr, + &dev_attr_ib_log.attr, + &dev_attr_ob_log.attr, + &dev_attr_ila_version.attr, + &dev_attr_inc_fw_ver.attr, + &dev_attr_ctl_mpi_state.attr, + &dev_attr_ctl_hmi_error.attr, + &dev_attr_ctl_raae_count.attr, + &dev_attr_ctl_iop0_count.attr, + &dev_attr_ctl_iop1_count.attr, NULL, }; +static const struct attribute_group pm8001_host_attr_group = { + .attrs = pm8001_host_attrs +}; + +const struct attribute_group *pm8001_host_groups[] = { + &pm8001_host_attr_group, + NULL +}; diff --git a/drivers/scsi/pm8001/pm8001_init.c b/drivers/scsi/pm8001/pm8001_init.c index 7082fecf7ce8..bed8cc125544 100644 --- a/drivers/scsi/pm8001/pm8001_init.c +++ b/drivers/scsi/pm8001/pm8001_init.c @@ -107,7 +107,7 @@ static struct scsi_host_template pm8001_sht = { #ifdef CONFIG_COMPAT .compat_ioctl = sas_ioctl, #endif - .shost_attrs = pm8001_host_attrs, + .shost_groups = pm8001_host_groups, .track_queue_depth = 1, }; diff --git a/drivers/scsi/pm8001/pm8001_sas.h b/drivers/scsi/pm8001/pm8001_sas.h index 7e999768bfd2..83eec16d021d 100644 --- a/drivers/scsi/pm8001/pm8001_sas.h +++ b/drivers/scsi/pm8001/pm8001_sas.h @@ -733,7 +733,7 @@ ssize_t pm8001_get_gsm_dump(struct device *cdev, u32, char *buf); int pm80xx_fatal_errors(struct pm8001_hba_info *pm8001_ha); void pm8001_free_dev(struct pm8001_device *pm8001_dev); /* ctl shared API */ -extern struct device_attribute *pm8001_host_attrs[]; +extern const struct attribute_group *pm8001_host_groups[]; static inline void pm8001_ccb_task_free_done(struct pm8001_hba_info *pm8001_ha, From 646bed7e6f45ef884913458fff6e7f4d69804a23 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Tue, 12 Oct 2021 16:35:48 -0700 Subject: [PATCH 235/279] scsi: pmcraid: Switch to attribute groups struct device supports attribute groups directly but does not support struct device_attribute directly. Hence switch to attribute groups. Link: https://lore.kernel.org/r/20211012233558.4066756-37-bvanassche@acm.org Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/pmcraid.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/drivers/scsi/pmcraid.c b/drivers/scsi/pmcraid.c index 18efb3e64c84..88046a793767 100644 --- a/drivers/scsi/pmcraid.c +++ b/drivers/scsi/pmcraid.c @@ -4093,13 +4093,14 @@ static struct device_attribute pmcraid_adapter_id_attr = { .show = pmcraid_show_adapter_id, }; -static struct device_attribute *pmcraid_host_attrs[] = { - &pmcraid_log_level_attr, - &pmcraid_driver_version_attr, - &pmcraid_adapter_id_attr, +static struct attribute *pmcraid_host_attrs[] = { + &pmcraid_log_level_attr.attr, + &pmcraid_driver_version_attr.attr, + &pmcraid_adapter_id_attr.attr, NULL, }; +ATTRIBUTE_GROUPS(pmcraid_host); /* host template structure for pmcraid driver */ static struct scsi_host_template pmcraid_host_template = { @@ -4122,7 +4123,7 @@ static struct scsi_host_template pmcraid_host_template = { .max_sectors = PMCRAID_IOA_MAX_SECTORS, .no_write_same = 1, .cmd_per_lun = PMCRAID_MAX_CMD_PER_LUN, - .shost_attrs = pmcraid_host_attrs, + .shost_groups = pmcraid_host_groups, .proc_name = PMCRAID_DRIVER_NAME, }; From 232cb469d24ef349c09bb1faad913109f394f253 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Tue, 12 Oct 2021 16:35:49 -0700 Subject: [PATCH 236/279] scsi: qedf: Switch to attribute groups struct device supports attribute groups directly but does not support struct device_attribute directly. Hence switch to attribute groups. Link: https://lore.kernel.org/r/20211012233558.4066756-38-bvanassche@acm.org Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/qedf/qedf.h | 2 +- drivers/scsi/qedf/qedf_attr.c | 15 ++++++++++++--- drivers/scsi/qedf/qedf_main.c | 2 +- 3 files changed, 14 insertions(+), 5 deletions(-) diff --git a/drivers/scsi/qedf/qedf.h b/drivers/scsi/qedf/qedf.h index ba94413fe2ea..4caddd6442f7 100644 --- a/drivers/scsi/qedf/qedf.h +++ b/drivers/scsi/qedf/qedf.h @@ -498,7 +498,7 @@ extern void qedf_process_abts_compl(struct qedf_ctx *qedf, struct fcoe_cqe *cqe, extern struct qedf_ioreq *qedf_alloc_cmd(struct qedf_rport *fcport, u8 cmd_type); -extern struct device_attribute *qedf_host_attrs[]; +extern const struct attribute_group *qedf_host_groups[]; extern void qedf_cmd_timer_set(struct qedf_ctx *qedf, struct qedf_ioreq *io_req, unsigned int timer_msec); extern int qedf_init_mp_req(struct qedf_ioreq *io_req); diff --git a/drivers/scsi/qedf/qedf_attr.c b/drivers/scsi/qedf/qedf_attr.c index 461c0c9180c4..fdc66d294813 100644 --- a/drivers/scsi/qedf/qedf_attr.c +++ b/drivers/scsi/qedf/qedf_attr.c @@ -60,12 +60,21 @@ static ssize_t fka_period_show(struct device *dev, static DEVICE_ATTR_RO(fcoe_mac); static DEVICE_ATTR_RO(fka_period); -struct device_attribute *qedf_host_attrs[] = { - &dev_attr_fcoe_mac, - &dev_attr_fka_period, +static struct attribute *qedf_host_attrs[] = { + &dev_attr_fcoe_mac.attr, + &dev_attr_fka_period.attr, NULL, }; +static const struct attribute_group qedf_host_attr_group = { + .attrs = qedf_host_attrs +}; + +const struct attribute_group *qedf_host_groups[] = { + &qedf_host_attr_group, + NULL +}; + extern const struct qed_fcoe_ops *qed_ops; void qedf_capture_grc_dump(struct qedf_ctx *qedf) diff --git a/drivers/scsi/qedf/qedf_main.c b/drivers/scsi/qedf/qedf_main.c index 42d0d941dba5..1eed6270e8f2 100644 --- a/drivers/scsi/qedf/qedf_main.c +++ b/drivers/scsi/qedf/qedf_main.c @@ -986,7 +986,7 @@ static struct scsi_host_template qedf_host_template = { .cmd_per_lun = 32, .max_sectors = 0xffff, .queuecommand = qedf_queuecommand, - .shost_attrs = qedf_host_attrs, + .shost_groups = qedf_host_groups, .eh_abort_handler = qedf_eh_abort, .eh_device_reset_handler = qedf_eh_device_reset, /* lun reset */ .eh_target_reset_handler = qedf_eh_target_reset, /* target reset */ From 1ebbd3b1d9a7294d16a34c24ef32e78d74d1c323 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Tue, 12 Oct 2021 16:35:50 -0700 Subject: [PATCH 237/279] scsi: qedi: Switch to attribute groups struct device supports attribute groups directly but does not support struct device_attribute directly. Hence switch to attribute groups. Link: https://lore.kernel.org/r/20211012233558.4066756-39-bvanassche@acm.org Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/qedi/qedi_gbl.h | 2 +- drivers/scsi/qedi/qedi_iscsi.c | 2 +- drivers/scsi/qedi/qedi_sysfs.c | 15 ++++++++++++--- 3 files changed, 14 insertions(+), 5 deletions(-) diff --git a/drivers/scsi/qedi/qedi_gbl.h b/drivers/scsi/qedi/qedi_gbl.h index 9f8e8ef405a1..72942772b198 100644 --- a/drivers/scsi/qedi/qedi_gbl.h +++ b/drivers/scsi/qedi/qedi_gbl.h @@ -22,7 +22,7 @@ extern struct iscsi_transport qedi_iscsi_transport; extern const struct qed_iscsi_ops *qedi_ops; extern const struct qedi_debugfs_ops qedi_debugfs_ops[]; extern const struct file_operations qedi_dbg_fops[]; -extern struct device_attribute *qedi_shost_attrs[]; +extern const struct attribute_group *qedi_shost_groups[]; int qedi_alloc_sq(struct qedi_ctx *qedi, struct qedi_endpoint *ep); void qedi_free_sq(struct qedi_ctx *qedi, struct qedi_endpoint *ep); diff --git a/drivers/scsi/qedi/qedi_iscsi.c b/drivers/scsi/qedi/qedi_iscsi.c index c5260429c637..88aa7d8b11c9 100644 --- a/drivers/scsi/qedi/qedi_iscsi.c +++ b/drivers/scsi/qedi/qedi_iscsi.c @@ -58,7 +58,7 @@ struct scsi_host_template qedi_host_template = { .max_sectors = 0xffff, .dma_boundary = QEDI_HW_DMA_BOUNDARY, .cmd_per_lun = 128, - .shost_attrs = qedi_shost_attrs, + .shost_groups = qedi_shost_groups, }; static void qedi_conn_free_login_resources(struct qedi_ctx *qedi, diff --git a/drivers/scsi/qedi/qedi_sysfs.c b/drivers/scsi/qedi/qedi_sysfs.c index be174d30eb7c..b00a7e08ef53 100644 --- a/drivers/scsi/qedi/qedi_sysfs.c +++ b/drivers/scsi/qedi/qedi_sysfs.c @@ -42,8 +42,17 @@ static ssize_t speed_show(struct device *dev, static DEVICE_ATTR_RO(port_state); static DEVICE_ATTR_RO(speed); -struct device_attribute *qedi_shost_attrs[] = { - &dev_attr_port_state, - &dev_attr_speed, +static struct attribute *qedi_shost_attrs[] = { + &dev_attr_port_state.attr, + &dev_attr_speed.attr, + NULL +}; + +static const struct attribute_group qedi_shost_attr_group = { + .attrs = qedi_shost_attrs +}; + +const struct attribute_group *qedi_shost_groups[] = { + &qedi_shost_attr_group, NULL }; From f8f8f857e7df0bdc96d7eaa713f91792e74a9d08 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Tue, 12 Oct 2021 16:35:51 -0700 Subject: [PATCH 238/279] scsi: qla2xxx: Remove a declaration Since there is no definition for the qla2x00_host_attrs_dm array, remove its declaration. Link: https://lore.kernel.org/r/20211012233558.4066756-40-bvanassche@acm.org Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/qla2xxx/qla_gbl.h | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h index 8aadcdeca6cb..5ff974e98783 100644 --- a/drivers/scsi/qla2xxx/qla_gbl.h +++ b/drivers/scsi/qla2xxx/qla_gbl.h @@ -743,7 +743,6 @@ uint qla25xx_fdmi_port_speed_currently(struct qla_hw_data *); */ struct device_attribute; extern struct device_attribute *qla2x00_host_attrs[]; -extern struct device_attribute *qla2x00_host_attrs_dm[]; struct fc_function_template; extern struct fc_function_template qla2xxx_transport_functions; extern struct fc_function_template qla2xxx_transport_vport_functions; From 66df386d0b7480b53e41b4a510db29fc94059249 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Tue, 12 Oct 2021 16:35:52 -0700 Subject: [PATCH 239/279] scsi: qla2xxx: Switch to attribute groups struct device supports attribute groups directly but does not support struct device_attribute directly. Hence switch to attribute groups. Additionally, remove qla_insert_tgt_attrs() and replace it with qla_host_attr_is_visible(). Link: https://lore.kernel.org/r/20211012233558.4066756-41-bvanassche@acm.org Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/qla2xxx/qla_attr.c | 127 +++++++++++++++++--------------- drivers/scsi/qla2xxx/qla_gbl.h | 3 +- drivers/scsi/qla2xxx/qla_os.c | 5 +- 3 files changed, 68 insertions(+), 67 deletions(-) diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c index cb5f2ecb652d..30f9545d2285 100644 --- a/drivers/scsi/qla2xxx/qla_attr.c +++ b/drivers/scsi/qla2xxx/qla_attr.c @@ -2481,73 +2481,78 @@ static DEVICE_ATTR(port_no, 0444, qla2x00_port_no_show, NULL); static DEVICE_ATTR(fw_attr, 0444, qla2x00_fw_attr_show, NULL); static DEVICE_ATTR_RO(edif_doorbell); - -struct device_attribute *qla2x00_host_attrs[] = { - &dev_attr_driver_version, - &dev_attr_fw_version, - &dev_attr_serial_num, - &dev_attr_isp_name, - &dev_attr_isp_id, - &dev_attr_model_name, - &dev_attr_model_desc, - &dev_attr_pci_info, - &dev_attr_link_state, - &dev_attr_zio, - &dev_attr_zio_timer, - &dev_attr_beacon, - &dev_attr_beacon_config, - &dev_attr_optrom_bios_version, - &dev_attr_optrom_efi_version, - &dev_attr_optrom_fcode_version, - &dev_attr_optrom_fw_version, - &dev_attr_84xx_fw_version, - &dev_attr_total_isp_aborts, - &dev_attr_serdes_version, - &dev_attr_mpi_version, - &dev_attr_phy_version, - &dev_attr_flash_block_size, - &dev_attr_vlan_id, - &dev_attr_vn_port_mac_address, - &dev_attr_fabric_param, - &dev_attr_fw_state, - &dev_attr_optrom_gold_fw_version, - &dev_attr_thermal_temp, - &dev_attr_diag_requests, - &dev_attr_diag_megabytes, - &dev_attr_fw_dump_size, - &dev_attr_allow_cna_fw_dump, - &dev_attr_pep_version, - &dev_attr_min_supported_speed, - &dev_attr_max_supported_speed, - &dev_attr_zio_threshold, - &dev_attr_dif_bundle_statistics, - &dev_attr_port_speed, - &dev_attr_port_no, - &dev_attr_fw_attr, - &dev_attr_dport_diagnostics, - &dev_attr_edif_doorbell, - &dev_attr_mpi_pause, - NULL, /* reserve for qlini_mode */ - NULL, /* reserve for ql2xiniexchg */ - NULL, /* reserve for ql2xexchoffld */ +static struct attribute *qla2x00_host_attrs[] = { + &dev_attr_driver_version.attr, + &dev_attr_fw_version.attr, + &dev_attr_serial_num.attr, + &dev_attr_isp_name.attr, + &dev_attr_isp_id.attr, + &dev_attr_model_name.attr, + &dev_attr_model_desc.attr, + &dev_attr_pci_info.attr, + &dev_attr_link_state.attr, + &dev_attr_zio.attr, + &dev_attr_zio_timer.attr, + &dev_attr_beacon.attr, + &dev_attr_beacon_config.attr, + &dev_attr_optrom_bios_version.attr, + &dev_attr_optrom_efi_version.attr, + &dev_attr_optrom_fcode_version.attr, + &dev_attr_optrom_fw_version.attr, + &dev_attr_84xx_fw_version.attr, + &dev_attr_total_isp_aborts.attr, + &dev_attr_serdes_version.attr, + &dev_attr_mpi_version.attr, + &dev_attr_phy_version.attr, + &dev_attr_flash_block_size.attr, + &dev_attr_vlan_id.attr, + &dev_attr_vn_port_mac_address.attr, + &dev_attr_fabric_param.attr, + &dev_attr_fw_state.attr, + &dev_attr_optrom_gold_fw_version.attr, + &dev_attr_thermal_temp.attr, + &dev_attr_diag_requests.attr, + &dev_attr_diag_megabytes.attr, + &dev_attr_fw_dump_size.attr, + &dev_attr_allow_cna_fw_dump.attr, + &dev_attr_pep_version.attr, + &dev_attr_min_supported_speed.attr, + &dev_attr_max_supported_speed.attr, + &dev_attr_zio_threshold.attr, + &dev_attr_dif_bundle_statistics.attr, + &dev_attr_port_speed.attr, + &dev_attr_port_no.attr, + &dev_attr_fw_attr.attr, + &dev_attr_dport_diagnostics.attr, + &dev_attr_edif_doorbell.attr, + &dev_attr_mpi_pause.attr, + &dev_attr_qlini_mode.attr, + &dev_attr_ql2xiniexchg.attr, + &dev_attr_ql2xexchoffld.attr, NULL, }; -void qla_insert_tgt_attrs(void) +static umode_t qla_host_attr_is_visible(struct kobject *kobj, + struct attribute *attr, int i) { - struct device_attribute **attr; - - /* advance to empty slot */ - for (attr = &qla2x00_host_attrs[0]; *attr; ++attr) - continue; - - *attr = &dev_attr_qlini_mode; - attr++; - *attr = &dev_attr_ql2xiniexchg; - attr++; - *attr = &dev_attr_ql2xexchoffld; + if (ql2x_ini_mode != QLA2XXX_INI_MODE_DUAL && + (attr == &dev_attr_qlini_mode.attr || + attr == &dev_attr_ql2xiniexchg.attr || + attr == &dev_attr_ql2xexchoffld.attr)) + return 0; + return attr->mode; } +static const struct attribute_group qla2x00_host_attr_group = { + .is_visible = qla_host_attr_is_visible, + .attrs = qla2x00_host_attrs +}; + +const struct attribute_group *qla2x00_host_groups[] = { + &qla2x00_host_attr_group, + NULL +}; + /* Host attributes. */ static void diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h index 5ff974e98783..3c4fa8bac88d 100644 --- a/drivers/scsi/qla2xxx/qla_gbl.h +++ b/drivers/scsi/qla2xxx/qla_gbl.h @@ -742,7 +742,7 @@ uint qla25xx_fdmi_port_speed_currently(struct qla_hw_data *); * Global Function Prototypes in qla_attr.c source file. */ struct device_attribute; -extern struct device_attribute *qla2x00_host_attrs[]; +extern const struct attribute_group *qla2x00_host_groups[]; struct fc_function_template; extern struct fc_function_template qla2xxx_transport_functions; extern struct fc_function_template qla2xxx_transport_vport_functions; @@ -756,7 +756,6 @@ extern int qla2x00_echo_test(scsi_qla_host_t *, extern int qla24xx_update_all_fcp_prio(scsi_qla_host_t *); extern int qla24xx_fcp_prio_cfg_valid(scsi_qla_host_t *, struct qla_fcp_prio_cfg *, uint8_t); -void qla_insert_tgt_attrs(void); /* * Global Function Prototypes in qla_dfs.c source file. */ diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index 5d576a3ba14f..04fd98f60c91 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c @@ -7943,7 +7943,7 @@ struct scsi_host_template qla2xxx_driver_template = { .sg_tablesize = SG_ALL, .max_sectors = 0xFFFF, - .shost_attrs = qla2x00_host_attrs, + .shost_groups = qla2x00_host_groups, .supported_mode = MODE_INITIATOR, .track_queue_depth = 1, @@ -8131,9 +8131,6 @@ qla2x00_module_init(void) if (ql2xextended_error_logging == 1) ql2xextended_error_logging = QL_DBG_DEFAULT1_MASK; - if (ql2x_ini_mode == QLA2XXX_INI_MODE_DUAL) - qla_insert_tgt_attrs(); - qla2xxx_transport_template = fc_attach_transport(&qla2xxx_transport_functions); if (!qla2xxx_transport_template) { From a8b476fc86d9a6580410ef4690bbb152cc027a34 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Tue, 12 Oct 2021 16:35:53 -0700 Subject: [PATCH 240/279] scsi: qla4xxx: Switch to attribute groups struct device supports attribute groups directly but does not support struct device_attribute directly. Hence switch to attribute groups. Link: https://lore.kernel.org/r/20211012233558.4066756-42-bvanassche@acm.org Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/qla4xxx/ql4_attr.c | 41 ++++++++++++++++++++------------- drivers/scsi/qla4xxx/ql4_glbl.h | 3 ++- drivers/scsi/qla4xxx/ql4_os.c | 2 +- 3 files changed, 28 insertions(+), 18 deletions(-) diff --git a/drivers/scsi/qla4xxx/ql4_attr.c b/drivers/scsi/qla4xxx/ql4_attr.c index ec4352818fbf..abfa6ef60480 100644 --- a/drivers/scsi/qla4xxx/ql4_attr.c +++ b/drivers/scsi/qla4xxx/ql4_attr.c @@ -330,21 +330,30 @@ static DEVICE_ATTR(fw_ext_timestamp, S_IRUGO, qla4xxx_fw_ext_timestamp_show, static DEVICE_ATTR(fw_load_src, S_IRUGO, qla4xxx_fw_load_src_show, NULL); static DEVICE_ATTR(fw_uptime, S_IRUGO, qla4xxx_fw_uptime_show, NULL); -struct device_attribute *qla4xxx_host_attrs[] = { - &dev_attr_fw_version, - &dev_attr_serial_num, - &dev_attr_iscsi_version, - &dev_attr_optrom_version, - &dev_attr_board_id, - &dev_attr_fw_state, - &dev_attr_phy_port_cnt, - &dev_attr_phy_port_num, - &dev_attr_iscsi_func_cnt, - &dev_attr_hba_model, - &dev_attr_fw_timestamp, - &dev_attr_fw_build_user, - &dev_attr_fw_ext_timestamp, - &dev_attr_fw_load_src, - &dev_attr_fw_uptime, +static struct attribute *qla4xxx_host_attrs[] = { + &dev_attr_fw_version.attr, + &dev_attr_serial_num.attr, + &dev_attr_iscsi_version.attr, + &dev_attr_optrom_version.attr, + &dev_attr_board_id.attr, + &dev_attr_fw_state.attr, + &dev_attr_phy_port_cnt.attr, + &dev_attr_phy_port_num.attr, + &dev_attr_iscsi_func_cnt.attr, + &dev_attr_hba_model.attr, + &dev_attr_fw_timestamp.attr, + &dev_attr_fw_build_user.attr, + &dev_attr_fw_ext_timestamp.attr, + &dev_attr_fw_load_src.attr, + &dev_attr_fw_uptime.attr, NULL, }; + +static const struct attribute_group qla4xxx_host_attr_group = { + .attrs = qla4xxx_host_attrs +}; + +const struct attribute_group *qla4xxx_host_groups[] = { + &qla4xxx_host_attr_group, + NULL +}; diff --git a/drivers/scsi/qla4xxx/ql4_glbl.h b/drivers/scsi/qla4xxx/ql4_glbl.h index ea60057b2e20..c0873381508d 100644 --- a/drivers/scsi/qla4xxx/ql4_glbl.h +++ b/drivers/scsi/qla4xxx/ql4_glbl.h @@ -286,5 +286,6 @@ extern int ql4xenablemsix; extern int ql4xmdcapmask; extern int ql4xenablemd; -extern struct device_attribute *qla4xxx_host_attrs[]; +extern const struct attribute_group *qla4xxx_host_groups[]; + #endif /* _QLA4x_GBL_H */ diff --git a/drivers/scsi/qla4xxx/ql4_os.c b/drivers/scsi/qla4xxx/ql4_os.c index 76d0b59a9982..8987acc24dac 100644 --- a/drivers/scsi/qla4xxx/ql4_os.c +++ b/drivers/scsi/qla4xxx/ql4_os.c @@ -241,7 +241,7 @@ static struct scsi_host_template qla4xxx_driver_template = { .sg_tablesize = SG_ALL, .max_sectors = 0xFFFF, - .shost_attrs = qla4xxx_host_attrs, + .shost_groups = qla4xxx_host_groups, .host_reset = qla4xxx_host_reset, .vendor_id = SCSI_NL_VID_TYPE_PCI | PCI_VENDOR_ID_QLOGIC, }; From 64fc9015fbeb041ed0b2ebf645764c06e0ad7753 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Tue, 12 Oct 2021 16:35:54 -0700 Subject: [PATCH 241/279] scsi: smartpqi: Switch to attribute groups struct device supports attribute groups directly but does not support struct device_attribute directly. Hence switch to attribute groups. Link: https://lore.kernel.org/r/20211012233558.4066756-43-bvanassche@acm.org Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/smartpqi/smartpqi_init.c | 46 +++++++++++++++------------ 1 file changed, 25 insertions(+), 21 deletions(-) diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c index 54c12b149fda..f0897d587454 100644 --- a/drivers/scsi/smartpqi/smartpqi_init.c +++ b/drivers/scsi/smartpqi/smartpqi_init.c @@ -6847,20 +6847,22 @@ static DEVICE_ATTR(enable_r5_writes, 0644, static DEVICE_ATTR(enable_r6_writes, 0644, pqi_host_enable_r6_writes_show, pqi_host_enable_r6_writes_store); -static struct device_attribute *pqi_shost_attrs[] = { - &dev_attr_driver_version, - &dev_attr_firmware_version, - &dev_attr_model, - &dev_attr_serial_number, - &dev_attr_vendor, - &dev_attr_rescan, - &dev_attr_lockup_action, - &dev_attr_enable_stream_detection, - &dev_attr_enable_r5_writes, - &dev_attr_enable_r6_writes, +static struct attribute *pqi_shost_attrs[] = { + &dev_attr_driver_version.attr, + &dev_attr_firmware_version.attr, + &dev_attr_model.attr, + &dev_attr_serial_number.attr, + &dev_attr_vendor.attr, + &dev_attr_rescan.attr, + &dev_attr_lockup_action.attr, + &dev_attr_enable_stream_detection.attr, + &dev_attr_enable_r5_writes.attr, + &dev_attr_enable_r6_writes.attr, NULL }; +ATTRIBUTE_GROUPS(pqi_shost); + static ssize_t pqi_unique_id_show(struct device *dev, struct device_attribute *attr, char *buffer) { @@ -7129,17 +7131,19 @@ static DEVICE_ATTR(ssd_smart_path_enabled, 0444, pqi_ssd_smart_path_enabled_show static DEVICE_ATTR(raid_level, 0444, pqi_raid_level_show, NULL); static DEVICE_ATTR(raid_bypass_cnt, 0444, pqi_raid_bypass_cnt_show, NULL); -static struct device_attribute *pqi_sdev_attrs[] = { - &dev_attr_lunid, - &dev_attr_unique_id, - &dev_attr_path_info, - &dev_attr_sas_address, - &dev_attr_ssd_smart_path_enabled, - &dev_attr_raid_level, - &dev_attr_raid_bypass_cnt, +static struct attribute *pqi_sdev_attrs[] = { + &dev_attr_lunid.attr, + &dev_attr_unique_id.attr, + &dev_attr_path_info.attr, + &dev_attr_sas_address.attr, + &dev_attr_ssd_smart_path_enabled.attr, + &dev_attr_raid_level.attr, + &dev_attr_raid_bypass_cnt.attr, NULL }; +ATTRIBUTE_GROUPS(pqi_sdev); + static struct scsi_host_template pqi_driver_template = { .module = THIS_MODULE, .name = DRIVER_NAME_SHORT, @@ -7153,8 +7157,8 @@ static struct scsi_host_template pqi_driver_template = { .slave_alloc = pqi_slave_alloc, .slave_configure = pqi_slave_configure, .map_queues = pqi_map_queues, - .sdev_attrs = pqi_sdev_attrs, - .shost_attrs = pqi_shost_attrs, + .sdev_groups = pqi_sdev_groups, + .shost_groups = pqi_shost_groups, }; static int pqi_register_scsi(struct pqi_ctrl_info *ctrl_info) From 7500be62910d9273bff783a5d6aa06f6444b7146 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Tue, 12 Oct 2021 16:35:55 -0700 Subject: [PATCH 242/279] scsi: snic: Switch to attribute groups struct device supports attribute groups directly but does not support struct device_attribute directly. Hence switch to attribute groups. Link: https://lore.kernel.org/r/20211012233558.4066756-44-bvanassche@acm.org Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/snic/snic.h | 2 +- drivers/scsi/snic/snic_attrs.c | 19 ++++++++++++++----- drivers/scsi/snic/snic_main.c | 2 +- 3 files changed, 16 insertions(+), 7 deletions(-) diff --git a/drivers/scsi/snic/snic.h b/drivers/scsi/snic/snic.h index f4c666285bba..4ec7e30678e1 100644 --- a/drivers/scsi/snic/snic.h +++ b/drivers/scsi/snic/snic.h @@ -374,7 +374,7 @@ int snic_glob_init(void); void snic_glob_cleanup(void); extern struct workqueue_struct *snic_event_queue; -extern struct device_attribute *snic_attrs[]; +extern const struct attribute_group *snic_host_groups[]; int snic_queuecommand(struct Scsi_Host *, struct scsi_cmnd *); int snic_abort_cmd(struct scsi_cmnd *); diff --git a/drivers/scsi/snic/snic_attrs.c b/drivers/scsi/snic/snic_attrs.c index 32d5d556b6f8..dc03ce1ec909 100644 --- a/drivers/scsi/snic/snic_attrs.c +++ b/drivers/scsi/snic/snic_attrs.c @@ -68,10 +68,19 @@ static DEVICE_ATTR(snic_state, S_IRUGO, snic_show_state, NULL); static DEVICE_ATTR(drv_version, S_IRUGO, snic_show_drv_version, NULL); static DEVICE_ATTR(link_state, S_IRUGO, snic_show_link_state, NULL); -struct device_attribute *snic_attrs[] = { - &dev_attr_snic_sym_name, - &dev_attr_snic_state, - &dev_attr_drv_version, - &dev_attr_link_state, +static struct attribute *snic_host_attrs[] = { + &dev_attr_snic_sym_name.attr, + &dev_attr_snic_state.attr, + &dev_attr_drv_version.attr, + &dev_attr_link_state.attr, NULL, }; + +static const struct attribute_group snic_host_attr_group = { + .attrs = snic_host_attrs +}; + +const struct attribute_group *snic_host_groups[] = { + &snic_host_attr_group, + NULL +}; diff --git a/drivers/scsi/snic/snic_main.c b/drivers/scsi/snic/snic_main.c index 14f4ce665e58..29d56396058c 100644 --- a/drivers/scsi/snic/snic_main.c +++ b/drivers/scsi/snic/snic_main.c @@ -129,7 +129,7 @@ static struct scsi_host_template snic_host_template = { .can_queue = SNIC_MAX_IO_REQ, .sg_tablesize = SNIC_MAX_SG_DESC_CNT, .max_sectors = 0x800, - .shost_attrs = snic_attrs, + .shost_groups = snic_host_groups, .track_queue_depth = 1, .cmd_size = sizeof(struct snic_internal_io_state), .proc_name = "snic_scsi", From 7ce6000a77ccbe8b1c4fd053e9800476cd38fca3 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Tue, 12 Oct 2021 16:35:56 -0700 Subject: [PATCH 243/279] scsi: staging: unisys: Remove the shost_attrs member This patch prepares for removal of the shost_attrs member from struct scsi_host_template. Link: https://lore.kernel.org/r/20211012233558.4066756-45-bvanassche@acm.org Acked-by: David Kershner Acked-by: Greg Kroah-Hartman Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/staging/unisys/visorhba/visorhba_main.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/staging/unisys/visorhba/visorhba_main.c b/drivers/staging/unisys/visorhba/visorhba_main.c index b40c8cacb813..694644112447 100644 --- a/drivers/staging/unisys/visorhba/visorhba_main.c +++ b/drivers/staging/unisys/visorhba/visorhba_main.c @@ -582,7 +582,6 @@ static struct scsi_host_template visorhba_driver_template = { .eh_device_reset_handler = visorhba_device_reset_handler, .eh_bus_reset_handler = visorhba_bus_reset_handler, .eh_host_reset_handler = visorhba_host_reset_handler, - .shost_attrs = NULL, #define visorhba_MAX_CMNDS 128 .can_queue = visorhba_MAX_CMNDS, .sg_tablesize = 64, From 01e570febaaafd74d6625476e2665238c5e47e1e Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Tue, 12 Oct 2021 16:35:57 -0700 Subject: [PATCH 244/279] scsi: usb: Switch to attribute groups struct device supports attribute groups directly but does not support struct device_attribute directly. Hence switch to attribute groups. Link: https://lore.kernel.org/r/20211012233558.4066756-46-bvanassche@acm.org Acked-by: Greg Kroah-Hartman Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/usb/storage/scsiglue.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/usb/storage/scsiglue.c b/drivers/usb/storage/scsiglue.c index 220aa1cf4b3d..8931df5a85fd 100644 --- a/drivers/usb/storage/scsiglue.c +++ b/drivers/usb/storage/scsiglue.c @@ -587,11 +587,13 @@ static ssize_t max_sectors_store(struct device *dev, struct device_attribute *at } static DEVICE_ATTR_RW(max_sectors); -static struct device_attribute *sysfs_device_attr_list[] = { - &dev_attr_max_sectors, +static struct attribute *usb_sdev_attrs[] = { + &dev_attr_max_sectors.attr, NULL, }; +ATTRIBUTE_GROUPS(usb_sdev); + /* * this defines our host template, with which we'll allocate hosts */ @@ -652,7 +654,7 @@ static const struct scsi_host_template usb_stor_host_template = { .skip_settle_delay = 1, /* sysfs device attributes */ - .sdev_attrs = sysfs_device_attr_list, + .sdev_groups = usb_sdev_groups, /* module management */ .module = THIS_MODULE From a47c6b713e89eef9e26ef9b17944fc807510bf3c Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Tue, 12 Oct 2021 16:35:58 -0700 Subject: [PATCH 245/279] scsi: core: Remove two host template members that are no longer used All SCSI drivers have been converted to use shost_groups and sdev_groups instead of shost_attrs or sdev_attrs. Hence remove shost_attrs and sdev_attrs. Additionally, remove the 'lld_attr_group' members and also the scsi_convert_dev_attrs() function. Link: https://lore.kernel.org/r/20211012233558.4066756-47-bvanassche@acm.org Cc: Greg Kroah-Hartman Reviewed-by: Benjamin Block Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/hosts.c | 9 --------- drivers/scsi/scsi_priv.h | 2 -- drivers/scsi/scsi_sysfs.c | 28 ---------------------------- include/scsi/scsi_device.h | 1 - include/scsi/scsi_host.h | 11 ----------- 5 files changed, 51 deletions(-) diff --git a/drivers/scsi/hosts.c b/drivers/scsi/hosts.c index 09157792d36b..17aef936bc90 100644 --- a/drivers/scsi/hosts.c +++ b/drivers/scsi/hosts.c @@ -483,15 +483,6 @@ struct Scsi_Host *scsi_host_alloc(struct scsi_host_template *sht, int privsize) dev_set_name(&shost->shost_dev, "host%d", shost->host_no); shost->shost_dev.groups = shost->shost_dev_attr_groups; shost->shost_dev_attr_groups[j++] = &scsi_shost_attr_group; - if (sht->shost_attrs) { - shost->lld_attr_group = (struct attribute_group){ - .attrs = scsi_convert_dev_attrs(&shost->shost_gendev, - sht->shost_attrs) - }; - if (shost->lld_attr_group.attrs) - shost->shost_dev_attr_groups[j++] = - &shost->lld_attr_group; - } if (sht->shost_groups) { for (i = 0; sht->shost_groups[i] && j < ARRAY_SIZE(shost->shost_dev_attr_groups); diff --git a/drivers/scsi/scsi_priv.h b/drivers/scsi/scsi_priv.h index 483d0ad5fe60..a278fc8948f4 100644 --- a/drivers/scsi/scsi_priv.h +++ b/drivers/scsi/scsi_priv.h @@ -138,8 +138,6 @@ extern int scsi_sysfs_add_sdev(struct scsi_device *); extern int scsi_sysfs_add_host(struct Scsi_Host *); extern int scsi_sysfs_register(void); extern void scsi_sysfs_unregister(void); -struct attribute **scsi_convert_dev_attrs(struct device *dev, - struct device_attribute **dev_attr); extern void scsi_sysfs_device_initialize(struct scsi_device *); extern int scsi_sysfs_target_initialize(struct scsi_device *); extern struct scsi_transport_template blank_transport_template; diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c index 3d98db6a97e6..c26f0e29e8cd 100644 --- a/drivers/scsi/scsi_sysfs.c +++ b/drivers/scsi/scsi_sysfs.c @@ -1563,26 +1563,6 @@ int scsi_sysfs_add_host(struct Scsi_Host *shost) return 0; } -/* - * Convert an array of struct device_attribute pointers into an array of - * struct attribute pointers. - */ -struct attribute **scsi_convert_dev_attrs(struct device *dev, - struct device_attribute **dev_attr) -{ - struct attribute **attrs; - int i; - - for (i = 0; dev_attr[i]; i++) - ; - attrs = devm_kzalloc(dev, (i + 1) * sizeof(*attrs), GFP_KERNEL); - if (!attrs) - return NULL; - for (i = 0; dev_attr[i]; i++) - attrs[i] = &dev_attr[i]->attr; - return attrs; -} - static struct device_type scsi_dev_type = { .name = "scsi_device", .release = scsi_device_dev_release, @@ -1604,14 +1584,6 @@ void scsi_sysfs_device_initialize(struct scsi_device *sdev) dev_set_name(&sdev->sdev_gendev, "%d:%d:%d:%llu", sdev->host->host_no, sdev->channel, sdev->id, sdev->lun); sdev->gendev_attr_groups[j++] = &scsi_sdev_attr_group; - if (hostt->sdev_attrs) { - sdev->lld_attr_group = (struct attribute_group){ - .attrs = scsi_convert_dev_attrs(&sdev->sdev_gendev, - hostt->sdev_attrs) - }; - if (sdev->lld_attr_group.attrs) - sdev->gendev_attr_groups[j++] = &sdev->lld_attr_group; - } if (hostt->sdev_groups) { for (i = 0; hostt->sdev_groups[i] && j < ARRAY_SIZE(sdev->gendev_attr_groups); diff --git a/include/scsi/scsi_device.h b/include/scsi/scsi_device.h index 01732aabd7c3..b1e9b3bd3a60 100644 --- a/include/scsi/scsi_device.h +++ b/include/scsi/scsi_device.h @@ -225,7 +225,6 @@ struct scsi_device { struct device sdev_gendev, sdev_dev; - struct attribute_group lld_attr_group; /* * The array size 6 provides space for one attribute group for the * SCSI core, four attribute groups defined by SCSI LLDs and one diff --git a/include/scsi/scsi_host.h b/include/scsi/scsi_host.h index bc2fcb72ff59..ae715959f886 100644 --- a/include/scsi/scsi_host.h +++ b/include/scsi/scsi_host.h @@ -473,16 +473,6 @@ struct scsi_host_template { */ #define SCSI_DEFAULT_HOST_BLOCKED 7 - /* - * Pointer to the sysfs class properties for this host, NULL terminated. - */ - struct device_attribute **shost_attrs; - - /* - * Pointer to the SCSI device properties for this host, NULL terminated. - */ - struct device_attribute **sdev_attrs; - /* * Pointer to the SCSI host sysfs attribute groups, NULL terminated. */ @@ -700,7 +690,6 @@ struct Scsi_Host { /* ldm bits */ struct device shost_gendev, shost_dev; - struct attribute_group lld_attr_group; /* * The array size 3 provides space for one attribute group defined by * the SCSI core, one attribute group defined by the SCSI LLD and one From c4da1205752dfda13571112dd964436e4cc8f348 Mon Sep 17 00:00:00 2001 From: Martin Kepplinger Date: Wed, 13 Oct 2021 09:50:50 +0200 Subject: [PATCH 246/279] scsi: sd: Print write through due to no caching mode page as warning For SD cardreaders it is extremely common not to have a cache. Consequently, the following messages do not point to a real error one could try to fix but rather describe how the disk works: sd 0:0:0:0: [sda] No Caching mode page found sd 0:0:0:0: [sda] Assuming drive cache: write through Print these messages as warnings instead of errors. Link: https://lore.kernel.org/r/20211013075050.3870354-1-martin.kepplinger@puri.sm Reviewed-by: Bart Van Assche Signed-off-by: Martin Kepplinger Signed-off-by: Martin K. Petersen --- drivers/scsi/sd.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index 4a78ab7185eb..8b19d7cb5e96 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -2792,7 +2792,8 @@ sd_read_cache_type(struct scsi_disk *sdkp, unsigned char *buffer) } } - sd_first_printk(KERN_ERR, sdkp, "No Caching mode page found\n"); + sd_first_printk(KERN_WARNING, sdkp, + "No Caching mode page found\n"); goto defaults; Page_found: @@ -2847,7 +2848,7 @@ defaults: "Assuming drive cache: write back\n"); sdkp->WCE = 1; } else { - sd_first_printk(KERN_ERR, sdkp, + sd_first_printk(KERN_WARNING, sdkp, "Assuming drive cache: write through\n"); sdkp->WCE = 0; } From 30e99f05f8b19b8274f3666afb70c9cc686ec65c Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Wed, 13 Oct 2021 11:30:05 +0300 Subject: [PATCH 247/279] scsi: mpi3mr: Use scnprintf() instead of snprintf() I intended to move from snprintf() to scnprintf() in the previous patch but I messed up and did not do that. The result of my bug is that it this function could trigger a WARN() if the buffer is too large. Link: https://lore.kernel.org/r/20211013083005.GA8592@kili Fixes: 76a4f7cc5973 ("scsi: mpi3mr: Clean up mpi3mr_print_ioc_info()") Signed-off-by: Dan Carpenter Signed-off-by: Martin K. Petersen --- drivers/scsi/mpi3mr/mpi3mr_fw.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/mpi3mr/mpi3mr_fw.c b/drivers/scsi/mpi3mr/mpi3mr_fw.c index e34417a2429a..aa5d877df6f8 100644 --- a/drivers/scsi/mpi3mr/mpi3mr_fw.c +++ b/drivers/scsi/mpi3mr/mpi3mr_fw.c @@ -3045,7 +3045,7 @@ mpi3mr_print_ioc_info(struct mpi3mr_ioc *mrioc) for (i = 0; i < ARRAY_SIZE(mpi3mr_protocols); i++) { if (mrioc->facts.protocol_flags & mpi3mr_protocols[i].protocol) { - bytes_written += snprintf(protocol + bytes_written, + bytes_written += scnprintf(protocol + bytes_written, sizeof(protocol) - bytes_written, "%s%s", bytes_written ? "," : "", mpi3mr_protocols[i].name); @@ -3056,7 +3056,7 @@ mpi3mr_print_ioc_info(struct mpi3mr_ioc *mrioc) for (i = 0; i < ARRAY_SIZE(mpi3mr_capabilities); i++) { if (mrioc->facts.protocol_flags & mpi3mr_capabilities[i].capability) { - bytes_written += snprintf(capabilities + bytes_written, + bytes_written += scnprintf(capabilities + bytes_written, sizeof(capabilities) - bytes_written, "%s%s", bytes_written ? "," : "", mpi3mr_capabilities[i].name); From 3319a8ba82b9f9c18568b18bc1febb34ae18b2c2 Mon Sep 17 00:00:00 2001 From: Tyrel Datwyler Date: Wed, 9 Jan 2019 18:59:09 -0800 Subject: [PATCH 248/279] scsi: ibmvscsi: Use GFP_KERNEL with dma_alloc_coherent() in initialize_event_pool() During driver probe we allocate a dma region for our event pool. Currently, zero is passed for the gfp_flags parameter. Driver probe callbacks are run in process context and we hold no locks so we can sleep here if necessary. Fix by passing GFP_KERNEL explicitly to dma_alloc_coherent(). Link: https://lore.kernel.org/r/1547089149-20577-1-git-send-email-tyreld@linux.vnet.ibm.com Reviewed-by: Brian King Signed-off-by: Tyrel Datwyler Signed-off-by: Martin K. Petersen --- drivers/scsi/ibmvscsi/ibmvscsi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/ibmvscsi/ibmvscsi.c b/drivers/scsi/ibmvscsi/ibmvscsi.c index 10860593c42b..1b2171b00fef 100644 --- a/drivers/scsi/ibmvscsi/ibmvscsi.c +++ b/drivers/scsi/ibmvscsi/ibmvscsi.c @@ -454,7 +454,7 @@ static int initialize_event_pool(struct event_pool *pool, pool->iu_storage = dma_alloc_coherent(hostdata->dev, pool->size * sizeof(*pool->iu_storage), - &pool->iu_token, 0); + &pool->iu_token, GFP_KERNEL); if (!pool->iu_storage) { kfree(pool->events); return -ENOMEM; From b3ef4a0e40df92538f1106fef2f9730cc6fd2ea5 Mon Sep 17 00:00:00 2001 From: MichelleJin Date: Fri, 15 Oct 2021 14:20:06 +0000 Subject: [PATCH 249/279] scsi: fcoe: Use netif_is_bond_master() instead of open code 'netdev->priv_flags & IFF_BONDING && netdev->flags & IFF_MASTER' is defined as netif_is_bond_master() in netdevice.h. Replace it to clean up code. Link: https://lore.kernel.org/r/20211015142006.540773-1-shjy180909@gmail.com Reviewed-by: Lee Duncan Signed-off-by: MichelleJin Signed-off-by: Martin K. Petersen --- drivers/scsi/fcoe/fcoe.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/fcoe/fcoe.c b/drivers/scsi/fcoe/fcoe.c index 5ae6c207d3ac..6415f88738ad 100644 --- a/drivers/scsi/fcoe/fcoe.c +++ b/drivers/scsi/fcoe/fcoe.c @@ -307,7 +307,7 @@ static int fcoe_interface_setup(struct fcoe_interface *fcoe, } /* Do not support for bonding device */ - if (netdev->priv_flags & IFF_BONDING && netdev->flags & IFF_MASTER) { + if (netif_is_bond_master(netdev)) { FCOE_NETDEV_DBG(netdev, "Bonded interfaces not supported\n"); return -EOPNOTSUPP; } From 8ecfb16c9be271dc79bfabbed9ac8ab8faba50b2 Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Wed, 13 Oct 2021 19:28:34 +0100 Subject: [PATCH 250/279] scsi: 3w-xxx: Remove redundant initialization of variable retval The variable retval is being initialized with a value that is never read, it is being updated immediately afterwards. The assignment is redundant and can be removed. Link: https://lore.kernel.org/r/20211013182834.137410-1-colin.king@canonical.com Signed-off-by: Colin Ian King Signed-off-by: Martin K. Petersen Addresses-Coverity: ("Unused value") --- drivers/scsi/3w-xxxx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/3w-xxxx.c b/drivers/scsi/3w-xxxx.c index 2ab94179530a..a853c5497af6 100644 --- a/drivers/scsi/3w-xxxx.c +++ b/drivers/scsi/3w-xxxx.c @@ -2252,7 +2252,7 @@ static int tw_probe(struct pci_dev *pdev, const struct pci_device_id *dev_id) { struct Scsi_Host *host = NULL; TW_Device_Extension *tw_dev; - int retval = -ENODEV; + int retval; retval = pci_enable_device(pdev); if (retval) { From 4e3ace0051e7e504b55d239daab8789dd89b863c Mon Sep 17 00:00:00 2001 From: Ye Bin Date: Wed, 13 Oct 2021 11:39:12 +0800 Subject: [PATCH 251/279] scsi: scsi_debug: Fix out-of-bound read in resp_readcap16() The following warning was observed running syzkaller: [ 3813.830724] sg_write: data in/out 65466/242 bytes for SCSI command 0x9e-- guessing data in; [ 3813.830724] program syz-executor not setting count and/or reply_len properly [ 3813.836956] ================================================================== [ 3813.839465] BUG: KASAN: stack-out-of-bounds in sg_copy_buffer+0x157/0x1e0 [ 3813.841773] Read of size 4096 at addr ffff8883cf80f540 by task syz-executor/1549 [ 3813.846612] Call Trace: [ 3813.846995] dump_stack+0x108/0x15f [ 3813.847524] print_address_description+0xa5/0x372 [ 3813.848243] kasan_report.cold+0x236/0x2a8 [ 3813.849439] check_memory_region+0x240/0x270 [ 3813.850094] memcpy+0x30/0x80 [ 3813.850553] sg_copy_buffer+0x157/0x1e0 [ 3813.853032] sg_copy_from_buffer+0x13/0x20 [ 3813.853660] fill_from_dev_buffer+0x135/0x370 [ 3813.854329] resp_readcap16+0x1ac/0x280 [ 3813.856917] schedule_resp+0x41f/0x1630 [ 3813.858203] scsi_debug_queuecommand+0xb32/0x17e0 [ 3813.862699] scsi_dispatch_cmd+0x330/0x950 [ 3813.863329] scsi_request_fn+0xd8e/0x1710 [ 3813.863946] __blk_run_queue+0x10b/0x230 [ 3813.864544] blk_execute_rq_nowait+0x1d8/0x400 [ 3813.865220] sg_common_write.isra.0+0xe61/0x2420 [ 3813.871637] sg_write+0x6c8/0xef0 [ 3813.878853] __vfs_write+0xe4/0x800 [ 3813.883487] vfs_write+0x17b/0x530 [ 3813.884008] ksys_write+0x103/0x270 [ 3813.886268] __x64_sys_write+0x77/0xc0 [ 3813.886841] do_syscall_64+0x106/0x360 [ 3813.887415] entry_SYSCALL_64_after_hwframe+0x44/0xa9 This issue can be reproduced with the following syzkaller log: r0 = openat(0xffffffffffffff9c, &(0x7f0000000040)='./file0\x00', 0x26e1, 0x0) r1 = syz_open_procfs(0xffffffffffffffff, &(0x7f0000000000)='fd/3\x00') open_by_handle_at(r1, &(0x7f00000003c0)=ANY=[@ANYRESHEX], 0x602000) r2 = syz_open_dev$sg(&(0x7f0000000000), 0x0, 0x40782) write$binfmt_aout(r2, &(0x7f0000000340)=ANY=[@ANYBLOB="00000000deff000000000000000000000000000000000000000000000000000047f007af9e107a41ec395f1bded7be24277a1501ff6196a83366f4e6362bc0ff2b247f68a972989b094b2da4fb3607fcf611a22dd04310d28c75039d"], 0x126) In resp_readcap16() we get "int alloc_len" value -1104926854, and then pass the huge arr_len to fill_from_dev_buffer(), but arr is only 32 bytes. This leads to OOB in sg_copy_buffer(). To solve this issue, define alloc_len as u32. Link: https://lore.kernel.org/r/20211013033913.2551004-2-yebin10@huawei.com Acked-by: Douglas Gilbert Signed-off-by: Ye Bin Signed-off-by: Martin K. Petersen --- drivers/scsi/scsi_debug.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c index 407f1ce15118..a71aa23f9773 100644 --- a/drivers/scsi/scsi_debug.c +++ b/drivers/scsi/scsi_debug.c @@ -1856,7 +1856,7 @@ static int resp_readcap16(struct scsi_cmnd *scp, { unsigned char *cmd = scp->cmnd; unsigned char arr[SDEBUG_READCAP16_ARR_SZ]; - int alloc_len; + u32 alloc_len; alloc_len = get_unaligned_be32(cmd + 10); /* following just in case virtual_gb changed */ @@ -1885,7 +1885,7 @@ static int resp_readcap16(struct scsi_cmnd *scp, } return fill_from_dev_buffer(scp, arr, - min_t(int, alloc_len, SDEBUG_READCAP16_ARR_SZ)); + min_t(u32, alloc_len, SDEBUG_READCAP16_ARR_SZ)); } #define SDEBUG_MAX_TGTPGS_ARR_SZ 1412 From f347c26836c270199de1599c3cd466bb7747caa9 Mon Sep 17 00:00:00 2001 From: Ye Bin Date: Wed, 13 Oct 2021 11:39:13 +0800 Subject: [PATCH 252/279] scsi: scsi_debug: Fix out-of-bound read in resp_report_tgtpgs() The following issue was observed running syzkaller: BUG: KASAN: slab-out-of-bounds in memcpy include/linux/string.h:377 [inline] BUG: KASAN: slab-out-of-bounds in sg_copy_buffer+0x150/0x1c0 lib/scatterlist.c:831 Read of size 2132 at addr ffff8880aea95dc8 by task syz-executor.0/9815 CPU: 0 PID: 9815 Comm: syz-executor.0 Not tainted 4.19.202-00874-gfc0fe04215a9 #2 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.10.2-1ubuntu1 04/01/2014 Call Trace: __dump_stack lib/dump_stack.c:77 [inline] dump_stack+0xe4/0x14a lib/dump_stack.c:118 print_address_description+0x73/0x280 mm/kasan/report.c:253 kasan_report_error mm/kasan/report.c:352 [inline] kasan_report+0x272/0x370 mm/kasan/report.c:410 memcpy+0x1f/0x50 mm/kasan/kasan.c:302 memcpy include/linux/string.h:377 [inline] sg_copy_buffer+0x150/0x1c0 lib/scatterlist.c:831 fill_from_dev_buffer+0x14f/0x340 drivers/scsi/scsi_debug.c:1021 resp_report_tgtpgs+0x5aa/0x770 drivers/scsi/scsi_debug.c:1772 schedule_resp+0x464/0x12f0 drivers/scsi/scsi_debug.c:4429 scsi_debug_queuecommand+0x467/0x1390 drivers/scsi/scsi_debug.c:5835 scsi_dispatch_cmd+0x3fc/0x9b0 drivers/scsi/scsi_lib.c:1896 scsi_request_fn+0x1042/0x1810 drivers/scsi/scsi_lib.c:2034 __blk_run_queue_uncond block/blk-core.c:464 [inline] __blk_run_queue+0x1a4/0x380 block/blk-core.c:484 blk_execute_rq_nowait+0x1c2/0x2d0 block/blk-exec.c:78 sg_common_write.isra.19+0xd74/0x1dc0 drivers/scsi/sg.c:847 sg_write.part.23+0x6e0/0xd00 drivers/scsi/sg.c:716 sg_write+0x64/0xa0 drivers/scsi/sg.c:622 __vfs_write+0xed/0x690 fs/read_write.c:485 kill_bdev:block_device:00000000e138492c vfs_write+0x184/0x4c0 fs/read_write.c:549 ksys_write+0x107/0x240 fs/read_write.c:599 do_syscall_64+0xc2/0x560 arch/x86/entry/common.c:293 entry_SYSCALL_64_after_hwframe+0x49/0xbe We get 'alen' from command its type is int. If userspace passes a large length we will get a negative 'alen'. Switch n, alen, and rlen to u32. Link: https://lore.kernel.org/r/20211013033913.2551004-3-yebin10@huawei.com Acked-by: Douglas Gilbert Signed-off-by: Ye Bin Signed-off-by: Martin K. Petersen --- drivers/scsi/scsi_debug.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c index a71aa23f9773..e008950c3e7f 100644 --- a/drivers/scsi/scsi_debug.c +++ b/drivers/scsi/scsi_debug.c @@ -1896,8 +1896,9 @@ static int resp_report_tgtpgs(struct scsi_cmnd *scp, unsigned char *cmd = scp->cmnd; unsigned char *arr; int host_no = devip->sdbg_host->shost->host_no; - int n, ret, alen, rlen; int port_group_a, port_group_b, port_a, port_b; + u32 alen, n, rlen; + int ret; alen = get_unaligned_be32(cmd + 6); arr = kzalloc(SDEBUG_MAX_TGTPGS_ARR_SZ, GFP_ATOMIC); @@ -1959,9 +1960,9 @@ static int resp_report_tgtpgs(struct scsi_cmnd *scp, * - The constructed command length * - The maximum array size */ - rlen = min_t(int, alen, n); + rlen = min(alen, n); ret = fill_from_dev_buffer(scp, arr, - min_t(int, rlen, SDEBUG_MAX_TGTPGS_ARR_SZ)); + min_t(u32, rlen, SDEBUG_MAX_TGTPGS_ARR_SZ)); kfree(arr); return ret; } From 7f96c7a67e4018317570bb8678e1c44265aba897 Mon Sep 17 00:00:00 2001 From: Varun Prakash Date: Wed, 13 Oct 2021 19:54:47 +0530 Subject: [PATCH 253/279] scsi: target: cxgbit: Increase max DataSegmentLength Current value of max DataSegmentLength is 8K. T5/T6 adapters support DataSegmentLength upto 16K. Increase max DataSegmentLength. Link: https://lore.kernel.org/r/1634135087-4996-1-git-send-email-varun@chelsio.com Signed-off-by: Varun Prakash Signed-off-by: Martin K. Petersen --- drivers/target/iscsi/cxgbit/cxgbit_main.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/drivers/target/iscsi/cxgbit/cxgbit_main.c b/drivers/target/iscsi/cxgbit/cxgbit_main.c index bd37f2afadea..c6678dc8dd41 100644 --- a/drivers/target/iscsi/cxgbit/cxgbit_main.c +++ b/drivers/target/iscsi/cxgbit/cxgbit_main.c @@ -33,11 +33,18 @@ static void cxgbit_set_mdsl(struct cxgbit_device *cdev) struct cxgb4_lld_info *lldi = &cdev->lldi; u32 mdsl; -#define ULP2_MAX_PKT_LEN 16224 -#define ISCSI_PDU_NONPAYLOAD_LEN 312 - mdsl = min_t(u32, lldi->iscsi_iolen - ISCSI_PDU_NONPAYLOAD_LEN, - ULP2_MAX_PKT_LEN - ISCSI_PDU_NONPAYLOAD_LEN); - mdsl = min_t(u32, mdsl, 8192); +#define CXGBIT_T5_MAX_PDU_LEN 16224 +#define CXGBIT_PDU_NONPAYLOAD_LEN 312 /* 48(BHS) + 256(AHS) + 8(Digest) */ + if (is_t5(lldi->adapter_type)) { + mdsl = min_t(u32, lldi->iscsi_iolen - CXGBIT_PDU_NONPAYLOAD_LEN, + CXGBIT_T5_MAX_PDU_LEN - CXGBIT_PDU_NONPAYLOAD_LEN); + } else { + mdsl = lldi->iscsi_iolen - CXGBIT_PDU_NONPAYLOAD_LEN; + mdsl = min(mdsl, 16384U); + } + + mdsl = round_down(mdsl, 4); + mdsl = min_t(u32, mdsl, 4 * PAGE_SIZE); mdsl = min_t(u32, mdsl, (MAX_SKB_FRAGS - 1) * PAGE_SIZE); cdev->mdsl = mdsl; From d1e51ea6bf5f72f67937f4446a5b6d56330f9d79 Mon Sep 17 00:00:00 2001 From: Varun Prakash Date: Wed, 13 Oct 2021 19:55:09 +0530 Subject: [PATCH 254/279] scsi: target: cxgbit: Enable Delayed ACK Enable Delayed ACK to reduce the number of TCP ACKs. Link: https://lore.kernel.org/r/1634135109-5044-1-git-send-email-varun@chelsio.com Signed-off-by: Varun Prakash Signed-off-by: Martin K. Petersen --- drivers/target/iscsi/cxgbit/cxgbit_cm.c | 8 +++--- drivers/target/iscsi/cxgbit/cxgbit_target.c | 28 +++++++++++++++++---- 2 files changed, 26 insertions(+), 10 deletions(-) diff --git a/drivers/target/iscsi/cxgbit/cxgbit_cm.c b/drivers/target/iscsi/cxgbit/cxgbit_cm.c index 518ded214e74..da31a308a064 100644 --- a/drivers/target/iscsi/cxgbit/cxgbit_cm.c +++ b/drivers/target/iscsi/cxgbit/cxgbit_cm.c @@ -836,11 +836,13 @@ static void cxgbit_set_tcp_window(struct cxgbit_sock *csk, struct port_info *pi) csk->rcv_win = CXGBIT_10G_RCV_WIN; if (scale) csk->rcv_win *= scale; + csk->rcv_win = min(csk->rcv_win, RCV_BUFSIZ_M << 10); #define CXGBIT_10G_SND_WIN (256 * 1024) csk->snd_win = CXGBIT_10G_SND_WIN; if (scale) csk->snd_win *= scale; + csk->snd_win = min(csk->snd_win, 512U * 1024); pr_debug("%s snd_win %d rcv_win %d\n", __func__, csk->snd_win, csk->rcv_win); @@ -1065,7 +1067,7 @@ int cxgbit_rx_data_ack(struct cxgbit_sock *csk) if (!skb) return -1; - credit_dack = RX_DACK_CHANGE_F | RX_DACK_MODE_V(1) | + credit_dack = RX_DACK_CHANGE_F | RX_DACK_MODE_V(3) | RX_CREDITS_V(csk->rx_credits); cxgb_mk_rx_data_ack(skb, len, csk->tid, csk->ctrlq_idx, @@ -1197,7 +1199,6 @@ cxgbit_pass_accept_rpl(struct cxgbit_sock *csk, struct cpl_pass_accept_req *req) if (tcph->ece && tcph->cwr) opt2 |= CCTRL_ECN_V(1); - opt2 |= RX_COALESCE_V(3); opt2 |= CONG_CNTRL_V(CONG_ALG_NEWRENO); opt2 |= T5_ISS_F; @@ -1646,9 +1647,6 @@ cxgbit_pass_establish(struct cxgbit_device *cdev, struct sk_buff *skb) csk->rcv_nxt = rcv_isn; - if (csk->rcv_win > (RCV_BUFSIZ_M << 10)) - csk->rx_credits = (csk->rcv_win - (RCV_BUFSIZ_M << 10)); - csk->snd_wscale = TCPOPT_SND_WSCALE_G(tcp_opt); cxgbit_set_emss(csk, tcp_opt); dst_confirm(csk->dst); diff --git a/drivers/target/iscsi/cxgbit/cxgbit_target.c b/drivers/target/iscsi/cxgbit/cxgbit_target.c index 282297ffc404..d314ee120a48 100644 --- a/drivers/target/iscsi/cxgbit/cxgbit_target.c +++ b/drivers/target/iscsi/cxgbit/cxgbit_target.c @@ -189,8 +189,8 @@ cxgbit_tx_data_wr(struct cxgbit_sock *csk, struct sk_buff *skb, u32 dlen, wr_ulp_mode = FW_OFLD_TX_DATA_WR_ULPMODE_V(ULP_MODE_ISCSI) | FW_OFLD_TX_DATA_WR_ULPSUBMODE_V(submode); - req->tunnel_to_proxy = htonl((wr_ulp_mode) | force | - FW_OFLD_TX_DATA_WR_SHOVE_V(skb_peek(&csk->txq) ? 0 : 1)); + req->tunnel_to_proxy = htonl(wr_ulp_mode | force | + FW_OFLD_TX_DATA_WR_SHOVE_F); } static void cxgbit_arp_failure_skb_discard(void *handle, struct sk_buff *skb) @@ -1531,7 +1531,7 @@ out: return ret; } -static int cxgbit_rx_lro_skb(struct cxgbit_sock *csk, struct sk_buff *skb) +static int cxgbit_t5_rx_lro_skb(struct cxgbit_sock *csk, struct sk_buff *skb) { struct cxgbit_lro_cb *lro_cb = cxgbit_skb_lro_cb(skb); struct cxgbit_lro_pdu_cb *pdu_cb = cxgbit_skb_lro_pdu_cb(skb, 0); @@ -1557,6 +1557,24 @@ static int cxgbit_rx_lro_skb(struct cxgbit_sock *csk, struct sk_buff *skb) return ret; } +static int cxgbit_rx_lro_skb(struct cxgbit_sock *csk, struct sk_buff *skb) +{ + struct cxgbit_lro_cb *lro_cb = cxgbit_skb_lro_cb(skb); + int ret; + + ret = cxgbit_process_lro_skb(csk, skb); + if (ret) + return ret; + + csk->rx_credits += lro_cb->pdu_totallen; + if (csk->rx_credits >= csk->rcv_win) { + csk->rx_credits = 0; + cxgbit_rx_data_ack(csk); + } + + return 0; +} + static int cxgbit_rx_skb(struct cxgbit_sock *csk, struct sk_buff *skb) { struct cxgb4_lld_info *lldi = &csk->com.cdev->lldi; @@ -1564,9 +1582,9 @@ static int cxgbit_rx_skb(struct cxgbit_sock *csk, struct sk_buff *skb) if (likely(cxgbit_skcb_flags(skb) & SKCBF_RX_LRO)) { if (is_t5(lldi->adapter_type)) - ret = cxgbit_rx_lro_skb(csk, skb); + ret = cxgbit_t5_rx_lro_skb(csk, skb); else - ret = cxgbit_process_lro_skb(csk, skb); + ret = cxgbit_rx_lro_skb(csk, skb); } __kfree_skb(skb); From 1d2ac7b69d6a984d0f58b82d0f658ebd9aa05428 Mon Sep 17 00:00:00 2001 From: Bodo Stroesser Date: Wed, 13 Oct 2021 19:16:06 +0200 Subject: [PATCH 255/279] scsi: target: tcmu: Allocate zeroed pages for data area Tcmu populates the data area (used for communication with userspace) with pages that are allocated by calling alloc_page(GFP_NOIO). Therefore previous content of the allocated pages is exposed to user space. Avoid this by adding __GFP_ZERO flag. Zeroing the pages does (nearly) not affect tcmu throughput, because allocated pages are re-used for the data transfers of later SCSI cmds. Link: https://lore.kernel.org/r/20211013171606.25197-1-bostroesser@gmail.com Signed-off-by: Bodo Stroesser Signed-off-by: Martin K. Petersen --- drivers/target/target_core_user.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/target/target_core_user.c b/drivers/target/target_core_user.c index dc220fad06fa..7b2a89a67cdb 100644 --- a/drivers/target/target_core_user.c +++ b/drivers/target/target_core_user.c @@ -523,8 +523,8 @@ static inline int tcmu_get_empty_block(struct tcmu_dev *udev, rcu_read_unlock(); for (i = cnt; i < page_cnt; i++) { - /* try to get new page from the mm */ - page = alloc_page(GFP_NOIO); + /* try to get new zeroed page from the mm */ + page = alloc_page(GFP_NOIO | __GFP_ZERO); if (!page) break; From fc65e933fbcce09eb6d0b3080694229f6add38bf Mon Sep 17 00:00:00 2001 From: Stanley Chu Date: Sat, 16 Oct 2021 08:58:00 +0800 Subject: [PATCH 256/279] scsi: ufs: ufs-mediatek: Introduce default delay for reference clock Introduce default delay time for gating or ungating reference clock instead of ambiguous magic numbers. The defined value is suitable for all current MediaTek UFS platforms. Link: https://lore.kernel.org/r/20211016005802.7729-2-stanley.chu@mediatek.com Signed-off-by: Stanley Chu Signed-off-by: Martin K. Petersen --- drivers/scsi/ufs/ufs-mediatek.c | 13 ++++++++----- drivers/scsi/ufs/ufs-mediatek.h | 1 + 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/drivers/scsi/ufs/ufs-mediatek.c b/drivers/scsi/ufs/ufs-mediatek.c index d1696db70ce8..2c7d12a30493 100644 --- a/drivers/scsi/ufs/ufs-mediatek.c +++ b/drivers/scsi/ufs/ufs-mediatek.c @@ -282,7 +282,7 @@ out: } static void ufs_mtk_setup_ref_clk_wait_us(struct ufs_hba *hba, - u16 gating_us, u16 ungating_us) + u16 gating_us) { struct ufs_mtk_host *host = ufshcd_get_variant(hba); @@ -293,7 +293,7 @@ static void ufs_mtk_setup_ref_clk_wait_us(struct ufs_hba *hba, host->ref_clk_gating_wait_us = gating_us; } - host->ref_clk_ungating_wait_us = ungating_us; + host->ref_clk_ungating_wait_us = REFCLK_DEFAULT_WAIT_US; } static void ufs_mtk_dbg_sel(struct ufs_hba *hba) @@ -1102,11 +1102,14 @@ static int ufs_mtk_apply_dev_quirks(struct ufs_hba *hba) * requirements. */ if (mid == UFS_VENDOR_SAMSUNG) - ufs_mtk_setup_ref_clk_wait_us(hba, 1, 1); + ufs_mtk_setup_ref_clk_wait_us(hba, 1); else if (mid == UFS_VENDOR_SKHYNIX) - ufs_mtk_setup_ref_clk_wait_us(hba, 30, 30); + ufs_mtk_setup_ref_clk_wait_us(hba, 30); else if (mid == UFS_VENDOR_TOSHIBA) - ufs_mtk_setup_ref_clk_wait_us(hba, 100, 32); + ufs_mtk_setup_ref_clk_wait_us(hba, 100); + else + ufs_mtk_setup_ref_clk_wait_us(hba, + REFCLK_DEFAULT_WAIT_US); return 0; } diff --git a/drivers/scsi/ufs/ufs-mediatek.h b/drivers/scsi/ufs/ufs-mediatek.h index c96b9b529ee2..414dca86c09f 100644 --- a/drivers/scsi/ufs/ufs-mediatek.h +++ b/drivers/scsi/ufs/ufs-mediatek.h @@ -34,6 +34,7 @@ #define REFCLK_ACK BIT(1) #define REFCLK_REQ_TIMEOUT_US 3000 +#define REFCLK_DEFAULT_WAIT_US 32 /* * Other attributes From 1eaff502a8f132d518946bc652d53df79a9a4cd9 Mon Sep 17 00:00:00 2001 From: Stanley Chu Date: Sat, 16 Oct 2021 08:58:01 +0800 Subject: [PATCH 257/279] scsi: ufs: ufs-mediatek: Fix build error caused by use of sched_clock() Add proper header for using sched_clock(). Link: https://lore.kernel.org/r/20211016005802.7729-3-stanley.chu@mediatek.com Signed-off-by: Stanley Chu Signed-off-by: Martin K. Petersen --- drivers/scsi/ufs/ufs-mediatek.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/scsi/ufs/ufs-mediatek.c b/drivers/scsi/ufs/ufs-mediatek.c index 2c7d12a30493..bc193ba46b31 100644 --- a/drivers/scsi/ufs/ufs-mediatek.c +++ b/drivers/scsi/ufs/ufs-mediatek.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include "ufshcd.h" From 25d542a8537455a3335448a3fa53cf3704883389 Mon Sep 17 00:00:00 2001 From: Peter Wang Date: Sat, 16 Oct 2021 08:58:02 +0800 Subject: [PATCH 258/279] scsi: ufs: ufs-mediatek: Fix wrong location for ref-clk delay Fix the location of delay for ref-clk gating and ungating in ufs_mtk_setup_ref_clk(). Link: https://lore.kernel.org/r/20211016005802.7729-4-stanley.chu@mediatek.com Reviewed-by: Stanley Chu Signed-off-by: Peter Wang Signed-off-by: Stanley Chu Signed-off-by: Martin K. Petersen --- drivers/scsi/ufs/ufs-mediatek.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/scsi/ufs/ufs-mediatek.c b/drivers/scsi/ufs/ufs-mediatek.c index bc193ba46b31..d0a8e1319ab3 100644 --- a/drivers/scsi/ufs/ufs-mediatek.c +++ b/drivers/scsi/ufs/ufs-mediatek.c @@ -247,9 +247,9 @@ static int ufs_mtk_setup_ref_clk(struct ufs_hba *hba, bool on) if (on) { ufs_mtk_ref_clk_notify(on, res); - ufshcd_delay_us(host->ref_clk_ungating_wait_us, 10); ufshcd_writel(hba, REFCLK_REQUEST, REG_UFS_REFCLK_CTRL); } else { + ufshcd_delay_us(host->ref_clk_gating_wait_us, 10); ufshcd_writel(hba, REFCLK_RELEASE, REG_UFS_REFCLK_CTRL); } @@ -274,10 +274,10 @@ static int ufs_mtk_setup_ref_clk(struct ufs_hba *hba, bool on) out: host->ref_clk_enabled = on; - if (!on) { - ufshcd_delay_us(host->ref_clk_gating_wait_us, 10); + if (on) + ufshcd_delay_us(host->ref_clk_ungating_wait_us, 10); + else ufs_mtk_ref_clk_notify(on, res); - } return 0; } From 945a160794a90442329fdd6ff30f02a5c5b39481 Mon Sep 17 00:00:00 2001 From: Mike Christie Date: Wed, 29 Sep 2021 21:04:18 -0500 Subject: [PATCH 259/279] scsi: target: Fix ordered CMD_T_SENT handling We can race where target_handle_task_attr() has put the cmd on the delayed_cmd_list. Then target_restart_delayed_cmds() has removed it and set CMD_T_SENT, but then target_execute_cmd() now clears that bit. This patch moves the clearing to before we've put the cmd on the list. Link: https://lore.kernel.org/r/20210930020422.92578-2-michael.christie@oracle.com Reviewed-by: Lee Duncan Signed-off-by: Mike Christie Signed-off-by: Martin K. Petersen --- drivers/target/target_core_transport.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c index 4a0055ab9151..64e0477c7644 100644 --- a/drivers/target/target_core_transport.c +++ b/drivers/target/target_core_transport.c @@ -2200,6 +2200,10 @@ static bool target_handle_task_attr(struct se_cmd *cmd) if (atomic_read(&dev->dev_ordered_sync) == 0) return false; + spin_lock_irq(&cmd->t_state_lock); + cmd->transport_state &= ~CMD_T_SENT; + spin_unlock_irq(&cmd->t_state_lock); + spin_lock(&dev->delayed_cmd_lock); list_add_tail(&cmd->se_delayed_node, &dev->delayed_cmd_list); spin_unlock(&dev->delayed_cmd_lock); @@ -2228,12 +2232,8 @@ void target_execute_cmd(struct se_cmd *cmd) if (target_write_prot_action(cmd)) return; - if (target_handle_task_attr(cmd)) { - spin_lock_irq(&cmd->t_state_lock); - cmd->transport_state &= ~CMD_T_SENT; - spin_unlock_irq(&cmd->t_state_lock); + if (target_handle_task_attr(cmd)) return; - } __target_execute_cmd(cmd, true); } From ed1227e080990ffec5bf39006ec8a57358e6689a Mon Sep 17 00:00:00 2001 From: Mike Christie Date: Wed, 29 Sep 2021 21:04:19 -0500 Subject: [PATCH 260/279] scsi: target: Fix ordered tag handling This patch fixes the following bugs: 1. If there are multiple ordered cmds queued and multiple simple cmds completing, target_restart_delayed_cmds() could be called on different CPUs and each instance could start a ordered cmd. They could then run in different orders than they were queued. 2. target_restart_delayed_cmds() and target_handle_task_attr() can race where: 1. target_handle_task_attr() has passed the simple_cmds == 0 check. 2. transport_complete_task_attr() then decrements simple_cmds to 0. 3. transport_complete_task_attr() runs target_restart_delayed_cmds() and it does not see any cmds on the delayed_cmd_list. 4. target_handle_task_attr() adds the cmd to the delayed_cmd_list. The cmd will then end up timing out. 3. If we are sent > 1 ordered cmds and simple_cmds == 0, we can execute them out of order, because target_handle_task_attr() will hit that simple_cmds check first and return false for all ordered cmds sent. 4. We run target_restart_delayed_cmds() after every cmd completion, so if there is more than 1 simple cmd running, we start executing ordered cmds after that first cmd instead of waiting for all of them to complete. 5. Ordered cmds are not supposed to start until HEAD OF QUEUE and all older cmds have completed, and not just simple. 6. It's not a bug but it doesn't make sense to take the delayed_cmd_lock for every cmd completion when ordered cmds are almost never used. Just replacing that lock with an atomic increases IOPs by up to 10% when completions are spread over multiple CPUs and there are multiple sessions/ mqs/thread accessing the same device. This patch moves the queued delayed handling to a per device work to serialze the cmd executions for each device and adds a new counter to track HEAD_OF_QUEUE and SIMPLE cmds. We can then check the new counter to determine when to run the work on the completion path. Link: https://lore.kernel.org/r/20210930020422.92578-3-michael.christie@oracle.com Signed-off-by: Mike Christie Signed-off-by: Martin K. Petersen --- drivers/target/target_core_device.c | 2 + drivers/target/target_core_internal.h | 1 + drivers/target/target_core_transport.c | 76 ++++++++++++++++++-------- include/target/target_core_base.h | 6 +- 4 files changed, 61 insertions(+), 24 deletions(-) diff --git a/drivers/target/target_core_device.c b/drivers/target/target_core_device.c index 8cb1fa0c0585..44bb380e7390 100644 --- a/drivers/target/target_core_device.c +++ b/drivers/target/target_core_device.c @@ -772,6 +772,8 @@ struct se_device *target_alloc_device(struct se_hba *hba, const char *name) INIT_LIST_HEAD(&dev->t10_alua.lba_map_list); spin_lock_init(&dev->t10_alua.lba_map_lock); + INIT_WORK(&dev->delayed_cmd_work, target_do_delayed_work); + dev->t10_wwn.t10_dev = dev; /* * Use OpenFabrics IEEE Company ID: 00 14 05 diff --git a/drivers/target/target_core_internal.h b/drivers/target/target_core_internal.h index a343bcfa2180..a889a6237d9c 100644 --- a/drivers/target/target_core_internal.h +++ b/drivers/target/target_core_internal.h @@ -151,6 +151,7 @@ int transport_dump_vpd_ident(struct t10_vpd *, unsigned char *, int); void transport_clear_lun_ref(struct se_lun *); sense_reason_t target_cmd_size_check(struct se_cmd *cmd, unsigned int size); void target_qf_do_work(struct work_struct *work); +void target_do_delayed_work(struct work_struct *work); bool target_check_wce(struct se_device *dev); bool target_check_fua(struct se_device *dev); void __target_execute_cmd(struct se_cmd *, bool); diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c index 64e0477c7644..4a2e749eb182 100644 --- a/drivers/target/target_core_transport.c +++ b/drivers/target/target_core_transport.c @@ -2173,32 +2173,35 @@ static bool target_handle_task_attr(struct se_cmd *cmd) */ switch (cmd->sam_task_attr) { case TCM_HEAD_TAG: + atomic_inc_mb(&dev->non_ordered); pr_debug("Added HEAD_OF_QUEUE for CDB: 0x%02x\n", cmd->t_task_cdb[0]); return false; case TCM_ORDERED_TAG: - atomic_inc_mb(&dev->dev_ordered_sync); + atomic_inc_mb(&dev->delayed_cmd_count); pr_debug("Added ORDERED for CDB: 0x%02x to ordered list\n", cmd->t_task_cdb[0]); - - /* - * Execute an ORDERED command if no other older commands - * exist that need to be completed first. - */ - if (!atomic_read(&dev->simple_cmds)) - return false; break; default: /* * For SIMPLE and UNTAGGED Task Attribute commands */ - atomic_inc_mb(&dev->simple_cmds); + atomic_inc_mb(&dev->non_ordered); + + if (atomic_read(&dev->delayed_cmd_count) == 0) + return false; break; } - if (atomic_read(&dev->dev_ordered_sync) == 0) - return false; + if (cmd->sam_task_attr != TCM_ORDERED_TAG) { + atomic_inc_mb(&dev->delayed_cmd_count); + /* + * We will account for this when we dequeue from the delayed + * list. + */ + atomic_dec_mb(&dev->non_ordered); + } spin_lock_irq(&cmd->t_state_lock); cmd->transport_state &= ~CMD_T_SENT; @@ -2210,6 +2213,12 @@ static bool target_handle_task_attr(struct se_cmd *cmd) pr_debug("Added CDB: 0x%02x Task Attr: 0x%02x to delayed CMD listn", cmd->t_task_cdb[0], cmd->sam_task_attr); + /* + * We may have no non ordered cmds when this function started or we + * could have raced with the last simple/head cmd completing, so kick + * the delayed handler here. + */ + schedule_work(&dev->delayed_cmd_work); return true; } @@ -2243,29 +2252,48 @@ EXPORT_SYMBOL(target_execute_cmd); * Process all commands up to the last received ORDERED task attribute which * requires another blocking boundary */ -static void target_restart_delayed_cmds(struct se_device *dev) +void target_do_delayed_work(struct work_struct *work) { - for (;;) { + struct se_device *dev = container_of(work, struct se_device, + delayed_cmd_work); + + spin_lock(&dev->delayed_cmd_lock); + while (!dev->ordered_sync_in_progress) { struct se_cmd *cmd; - spin_lock(&dev->delayed_cmd_lock); - if (list_empty(&dev->delayed_cmd_list)) { - spin_unlock(&dev->delayed_cmd_lock); + if (list_empty(&dev->delayed_cmd_list)) break; - } cmd = list_entry(dev->delayed_cmd_list.next, struct se_cmd, se_delayed_node); + + if (cmd->sam_task_attr == TCM_ORDERED_TAG) { + /* + * Check if we started with: + * [ordered] [simple] [ordered] + * and we are now at the last ordered so we have to wait + * for the simple cmd. + */ + if (atomic_read(&dev->non_ordered) > 0) + break; + + dev->ordered_sync_in_progress = true; + } + list_del(&cmd->se_delayed_node); + atomic_dec_mb(&dev->delayed_cmd_count); spin_unlock(&dev->delayed_cmd_lock); + if (cmd->sam_task_attr != TCM_ORDERED_TAG) + atomic_inc_mb(&dev->non_ordered); + cmd->transport_state |= CMD_T_SENT; __target_execute_cmd(cmd, true); - if (cmd->sam_task_attr == TCM_ORDERED_TAG) - break; + spin_lock(&dev->delayed_cmd_lock); } + spin_unlock(&dev->delayed_cmd_lock); } /* @@ -2283,14 +2311,17 @@ static void transport_complete_task_attr(struct se_cmd *cmd) goto restart; if (cmd->sam_task_attr == TCM_SIMPLE_TAG) { - atomic_dec_mb(&dev->simple_cmds); + atomic_dec_mb(&dev->non_ordered); dev->dev_cur_ordered_id++; } else if (cmd->sam_task_attr == TCM_HEAD_TAG) { + atomic_dec_mb(&dev->non_ordered); dev->dev_cur_ordered_id++; pr_debug("Incremented dev_cur_ordered_id: %u for HEAD_OF_QUEUE\n", dev->dev_cur_ordered_id); } else if (cmd->sam_task_attr == TCM_ORDERED_TAG) { - atomic_dec_mb(&dev->dev_ordered_sync); + spin_lock(&dev->delayed_cmd_lock); + dev->ordered_sync_in_progress = false; + spin_unlock(&dev->delayed_cmd_lock); dev->dev_cur_ordered_id++; pr_debug("Incremented dev_cur_ordered_id: %u for ORDERED\n", @@ -2299,7 +2330,8 @@ static void transport_complete_task_attr(struct se_cmd *cmd) cmd->se_cmd_flags &= ~SCF_TASK_ATTR_SET; restart: - target_restart_delayed_cmds(dev); + if (atomic_read(&dev->delayed_cmd_count) > 0) + schedule_work(&dev->delayed_cmd_work); } static void transport_complete_qf(struct se_cmd *cmd) diff --git a/include/target/target_core_base.h b/include/target/target_core_base.h index 2130f102798d..a7600b311b84 100644 --- a/include/target/target_core_base.h +++ b/include/target/target_core_base.h @@ -812,8 +812,9 @@ struct se_device { atomic_long_t read_bytes; atomic_long_t write_bytes; /* Active commands on this virtual SE device */ - atomic_t simple_cmds; - atomic_t dev_ordered_sync; + atomic_t non_ordered; + bool ordered_sync_in_progress; + atomic_t delayed_cmd_count; atomic_t dev_qf_count; u32 export_count; spinlock_t delayed_cmd_lock; @@ -834,6 +835,7 @@ struct se_device { struct list_head dev_sep_list; struct list_head dev_tmr_list; struct work_struct qf_work_queue; + struct work_struct delayed_cmd_work; struct list_head delayed_cmd_list; struct list_head qf_cmd_list; /* Pointer to associated SE HBA */ From 1283c0d1a32bb924324481586b5d6e8e76f676ba Mon Sep 17 00:00:00 2001 From: Mike Christie Date: Wed, 29 Sep 2021 21:04:20 -0500 Subject: [PATCH 261/279] scsi: target: Fix alua_tg_pt_gps_count tracking We can't free the tg_pt_gp in core_alua_set_tg_pt_gp_id() because it's still accessed via configfs. Its release must go through the normal configfs/refcount process. The max alua_tg_pt_gps_count check should probably have been done in core_alua_allocate_tg_pt_gp(), but with the current code userspace could have created 0x0000ffff + 1 groups, but only set the id for 0x0000ffff. Then it could have deleted a group with an ID set, and then set the ID for that extra group and it would work ok. It's unlikely, but just in case this patch continues to allow that type of behavior, and just fixes the kfree() while in use bug. Link: https://lore.kernel.org/r/20210930020422.92578-4-michael.christie@oracle.com Signed-off-by: Mike Christie Signed-off-by: Martin K. Petersen --- drivers/target/target_core_alua.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/target/target_core_alua.c b/drivers/target/target_core_alua.c index cb1de1ecaaa6..bd0f2ce011dd 100644 --- a/drivers/target/target_core_alua.c +++ b/drivers/target/target_core_alua.c @@ -1674,7 +1674,6 @@ int core_alua_set_tg_pt_gp_id( pr_err("Maximum ALUA alua_tg_pt_gps_count:" " 0x0000ffff reached\n"); spin_unlock(&dev->t10_alua.tg_pt_gps_lock); - kmem_cache_free(t10_alua_tg_pt_gp_cache, tg_pt_gp); return -ENOSPC; } again: From 7324f47d4293ff50f489010735a4057defb1a5d6 Mon Sep 17 00:00:00 2001 From: Mike Christie Date: Wed, 29 Sep 2021 21:04:21 -0500 Subject: [PATCH 262/279] scsi: target: Replace lun_tg_pt_gp_lock with rcu in I/O path We are only holding the lun_tg_pt_gp_lock in target_alua_state_check() to make sure tg_pt_gp is not freed from under us while we copy the state, delay, ID values. We can instead use RCU here to access the tg_pt_gp. With this patch IOPs can increase up to 10% for jobs like: fio --filename=/dev/sdX --direct=1 --rw=randrw --bs=4k \ --ioengine=libaio --iodepth=64 --numjobs=N when there are multiple sessions (running that fio command to each /dev/sdX or using multipath and there are over 8 paths), or more than 8 queues for the loop or vhost with multiple threads case and numjobs > 8. Link: https://lore.kernel.org/r/20210930020422.92578-5-michael.christie@oracle.com Signed-off-by: Mike Christie Signed-off-by: Martin K. Petersen --- drivers/target/target_core_alua.c | 61 +++++++++++++++++-------------- include/target/target_core_base.h | 2 +- 2 files changed, 35 insertions(+), 28 deletions(-) diff --git a/drivers/target/target_core_alua.c b/drivers/target/target_core_alua.c index bd0f2ce011dd..74944b914b4e 100644 --- a/drivers/target/target_core_alua.c +++ b/drivers/target/target_core_alua.c @@ -247,11 +247,11 @@ target_emulate_report_target_port_groups(struct se_cmd *cmd) * this CDB was received upon to determine this value individually * for ALUA target port group. */ - spin_lock(&cmd->se_lun->lun_tg_pt_gp_lock); - tg_pt_gp = cmd->se_lun->lun_tg_pt_gp; + rcu_read_lock(); + tg_pt_gp = rcu_dereference(cmd->se_lun->lun_tg_pt_gp); if (tg_pt_gp) buf[5] = tg_pt_gp->tg_pt_gp_implicit_trans_secs; - spin_unlock(&cmd->se_lun->lun_tg_pt_gp_lock); + rcu_read_unlock(); } transport_kunmap_data_sg(cmd); @@ -292,24 +292,24 @@ target_emulate_set_target_port_groups(struct se_cmd *cmd) * Determine if explicit ALUA via SET_TARGET_PORT_GROUPS is allowed * for the local tg_pt_gp. */ - spin_lock(&l_lun->lun_tg_pt_gp_lock); - l_tg_pt_gp = l_lun->lun_tg_pt_gp; + rcu_read_lock(); + l_tg_pt_gp = rcu_dereference(l_lun->lun_tg_pt_gp); if (!l_tg_pt_gp) { - spin_unlock(&l_lun->lun_tg_pt_gp_lock); + rcu_read_unlock(); pr_err("Unable to access l_lun->tg_pt_gp\n"); rc = TCM_UNSUPPORTED_SCSI_OPCODE; goto out; } if (!(l_tg_pt_gp->tg_pt_gp_alua_access_type & TPGS_EXPLICIT_ALUA)) { - spin_unlock(&l_lun->lun_tg_pt_gp_lock); + rcu_read_unlock(); pr_debug("Unable to process SET_TARGET_PORT_GROUPS" " while TPGS_EXPLICIT_ALUA is disabled\n"); rc = TCM_UNSUPPORTED_SCSI_OPCODE; goto out; } valid_states = l_tg_pt_gp->tg_pt_gp_alua_supported_states; - spin_unlock(&l_lun->lun_tg_pt_gp_lock); + rcu_read_unlock(); ptr = &buf[4]; /* Skip over RESERVED area in header */ @@ -662,17 +662,17 @@ target_alua_state_check(struct se_cmd *cmd) " target port\n"); return TCM_ALUA_OFFLINE; } - - if (!lun->lun_tg_pt_gp) + rcu_read_lock(); + tg_pt_gp = rcu_dereference(lun->lun_tg_pt_gp); + if (!tg_pt_gp) { + rcu_read_unlock(); return 0; + } - spin_lock(&lun->lun_tg_pt_gp_lock); - tg_pt_gp = lun->lun_tg_pt_gp; out_alua_state = tg_pt_gp->tg_pt_gp_alua_access_state; nonop_delay_msecs = tg_pt_gp->tg_pt_gp_nonop_delay_msecs; tg_pt_gp_id = tg_pt_gp->tg_pt_gp_id; - - spin_unlock(&lun->lun_tg_pt_gp_lock); + rcu_read_unlock(); /* * Process ALUA_ACCESS_STATE_ACTIVE_OPTIMIZED in a separate conditional * statement so the compiler knows explicitly to check this case first. @@ -1219,10 +1219,10 @@ static int core_alua_set_tg_pt_secondary_state( struct t10_alua_tg_pt_gp *tg_pt_gp; int trans_delay_msecs; - spin_lock(&lun->lun_tg_pt_gp_lock); - tg_pt_gp = lun->lun_tg_pt_gp; + rcu_read_lock(); + tg_pt_gp = rcu_dereference(lun->lun_tg_pt_gp); if (!tg_pt_gp) { - spin_unlock(&lun->lun_tg_pt_gp_lock); + rcu_read_unlock(); pr_err("Unable to complete secondary state" " transition\n"); return -EINVAL; @@ -1246,7 +1246,7 @@ static int core_alua_set_tg_pt_secondary_state( "implicit", config_item_name(&tg_pt_gp->tg_pt_gp_group.cg_item), tg_pt_gp->tg_pt_gp_id, (offline) ? "OFFLINE" : "ONLINE"); - spin_unlock(&lun->lun_tg_pt_gp_lock); + rcu_read_unlock(); /* * Do the optional transition delay after we set the secondary * ALUA access state. @@ -1754,13 +1754,14 @@ void core_alua_free_tg_pt_gp( __target_attach_tg_pt_gp(lun, dev->t10_alua.default_tg_pt_gp); } else - lun->lun_tg_pt_gp = NULL; + rcu_assign_pointer(lun->lun_tg_pt_gp, NULL); spin_unlock(&lun->lun_tg_pt_gp_lock); spin_lock(&tg_pt_gp->tg_pt_gp_lock); } spin_unlock(&tg_pt_gp->tg_pt_gp_lock); + synchronize_rcu(); kmem_cache_free(t10_alua_tg_pt_gp_cache, tg_pt_gp); } @@ -1805,7 +1806,7 @@ static void __target_attach_tg_pt_gp(struct se_lun *lun, assert_spin_locked(&lun->lun_tg_pt_gp_lock); spin_lock(&tg_pt_gp->tg_pt_gp_lock); - lun->lun_tg_pt_gp = tg_pt_gp; + rcu_assign_pointer(lun->lun_tg_pt_gp, tg_pt_gp); list_add_tail(&lun->lun_tg_pt_gp_link, &tg_pt_gp->tg_pt_gp_lun_list); tg_pt_gp->tg_pt_gp_members++; spin_lock(&lun->lun_deve_lock); @@ -1822,6 +1823,7 @@ void target_attach_tg_pt_gp(struct se_lun *lun, spin_lock(&lun->lun_tg_pt_gp_lock); __target_attach_tg_pt_gp(lun, tg_pt_gp); spin_unlock(&lun->lun_tg_pt_gp_lock); + synchronize_rcu(); } static void __target_detach_tg_pt_gp(struct se_lun *lun, @@ -1834,7 +1836,7 @@ static void __target_detach_tg_pt_gp(struct se_lun *lun, tg_pt_gp->tg_pt_gp_members--; spin_unlock(&tg_pt_gp->tg_pt_gp_lock); - lun->lun_tg_pt_gp = NULL; + rcu_assign_pointer(lun->lun_tg_pt_gp, NULL); } void target_detach_tg_pt_gp(struct se_lun *lun) @@ -1842,10 +1844,12 @@ void target_detach_tg_pt_gp(struct se_lun *lun) struct t10_alua_tg_pt_gp *tg_pt_gp; spin_lock(&lun->lun_tg_pt_gp_lock); - tg_pt_gp = lun->lun_tg_pt_gp; + tg_pt_gp = rcu_dereference_check(lun->lun_tg_pt_gp, + lockdep_is_held(&lun->lun_tg_pt_gp_lock)); if (tg_pt_gp) __target_detach_tg_pt_gp(lun, tg_pt_gp); spin_unlock(&lun->lun_tg_pt_gp_lock); + synchronize_rcu(); } ssize_t core_alua_show_tg_pt_gp_info(struct se_lun *lun, char *page) @@ -1854,8 +1858,8 @@ ssize_t core_alua_show_tg_pt_gp_info(struct se_lun *lun, char *page) struct t10_alua_tg_pt_gp *tg_pt_gp; ssize_t len = 0; - spin_lock(&lun->lun_tg_pt_gp_lock); - tg_pt_gp = lun->lun_tg_pt_gp; + rcu_read_lock(); + tg_pt_gp = rcu_dereference(lun->lun_tg_pt_gp); if (tg_pt_gp) { tg_pt_ci = &tg_pt_gp->tg_pt_gp_group.cg_item; len += sprintf(page, "TG Port Alias: %s\nTG Port Group ID:" @@ -1871,7 +1875,7 @@ ssize_t core_alua_show_tg_pt_gp_info(struct se_lun *lun, char *page) "Offline" : "None", core_alua_dump_status(lun->lun_tg_pt_secondary_stat)); } - spin_unlock(&lun->lun_tg_pt_gp_lock); + rcu_read_unlock(); return len; } @@ -1918,7 +1922,8 @@ ssize_t core_alua_store_tg_pt_gp_info( } spin_lock(&lun->lun_tg_pt_gp_lock); - tg_pt_gp = lun->lun_tg_pt_gp; + tg_pt_gp = rcu_dereference_check(lun->lun_tg_pt_gp, + lockdep_is_held(&lun->lun_tg_pt_gp_lock)); if (tg_pt_gp) { /* * Clearing an existing tg_pt_gp association, and replacing @@ -1941,7 +1946,7 @@ ssize_t core_alua_store_tg_pt_gp_info( dev->t10_alua.default_tg_pt_gp); spin_unlock(&lun->lun_tg_pt_gp_lock); - return count; + goto sync_rcu; } __target_detach_tg_pt_gp(lun, tg_pt_gp); move = 1; @@ -1958,6 +1963,8 @@ ssize_t core_alua_store_tg_pt_gp_info( tg_pt_gp_new->tg_pt_gp_id); core_alua_put_tg_pt_gp_from_name(tg_pt_gp_new); +sync_rcu: + synchronize_rcu(); return count; } diff --git a/include/target/target_core_base.h b/include/target/target_core_base.h index a7600b311b84..c2b36f7d917d 100644 --- a/include/target/target_core_base.h +++ b/include/target/target_core_base.h @@ -749,7 +749,7 @@ struct se_lun { /* ALUA target port group linkage */ struct list_head lun_tg_pt_gp_link; - struct t10_alua_tg_pt_gp *lun_tg_pt_gp; + struct t10_alua_tg_pt_gp __rcu *lun_tg_pt_gp; spinlock_t lun_tg_pt_gp_lock; struct se_portal_group *lun_tpg; From f9793d649c29bad86651620ec49888ee9743cbb6 Mon Sep 17 00:00:00 2001 From: Mike Christie Date: Wed, 29 Sep 2021 21:04:22 -0500 Subject: [PATCH 263/279] scsi: target: Perform ALUA group changes in one step When userspace changes the LUN's ALUA group, it will set the LUN's group to NULL then to the new group. Before the new group is set, target_alua_state_check() will return 0 and allow the I/O to execute. This has us skip the NULL stage, and just swap in the new group. Link: https://lore.kernel.org/r/20210930020422.92578-6-michael.christie@oracle.com Signed-off-by: Mike Christie Signed-off-by: Martin K. Petersen --- drivers/target/target_core_alua.c | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/drivers/target/target_core_alua.c b/drivers/target/target_core_alua.c index 74944b914b4e..b56ef8af66e7 100644 --- a/drivers/target/target_core_alua.c +++ b/drivers/target/target_core_alua.c @@ -1835,8 +1835,6 @@ static void __target_detach_tg_pt_gp(struct se_lun *lun, list_del_init(&lun->lun_tg_pt_gp_link); tg_pt_gp->tg_pt_gp_members--; spin_unlock(&tg_pt_gp->tg_pt_gp_lock); - - rcu_assign_pointer(lun->lun_tg_pt_gp, NULL); } void target_detach_tg_pt_gp(struct se_lun *lun) @@ -1846,12 +1844,25 @@ void target_detach_tg_pt_gp(struct se_lun *lun) spin_lock(&lun->lun_tg_pt_gp_lock); tg_pt_gp = rcu_dereference_check(lun->lun_tg_pt_gp, lockdep_is_held(&lun->lun_tg_pt_gp_lock)); - if (tg_pt_gp) + if (tg_pt_gp) { __target_detach_tg_pt_gp(lun, tg_pt_gp); + rcu_assign_pointer(lun->lun_tg_pt_gp, NULL); + } spin_unlock(&lun->lun_tg_pt_gp_lock); synchronize_rcu(); } +static void target_swap_tg_pt_gp(struct se_lun *lun, + struct t10_alua_tg_pt_gp *old_tg_pt_gp, + struct t10_alua_tg_pt_gp *new_tg_pt_gp) +{ + assert_spin_locked(&lun->lun_tg_pt_gp_lock); + + if (old_tg_pt_gp) + __target_detach_tg_pt_gp(lun, old_tg_pt_gp); + __target_attach_tg_pt_gp(lun, new_tg_pt_gp); +} + ssize_t core_alua_show_tg_pt_gp_info(struct se_lun *lun, char *page) { struct config_item *tg_pt_ci; @@ -1941,18 +1952,16 @@ ssize_t core_alua_store_tg_pt_gp_info( &tg_pt_gp->tg_pt_gp_group.cg_item), tg_pt_gp->tg_pt_gp_id); - __target_detach_tg_pt_gp(lun, tg_pt_gp); - __target_attach_tg_pt_gp(lun, + target_swap_tg_pt_gp(lun, tg_pt_gp, dev->t10_alua.default_tg_pt_gp); spin_unlock(&lun->lun_tg_pt_gp_lock); goto sync_rcu; } - __target_detach_tg_pt_gp(lun, tg_pt_gp); move = 1; } - __target_attach_tg_pt_gp(lun, tg_pt_gp_new); + target_swap_tg_pt_gp(lun, tg_pt_gp, tg_pt_gp_new); spin_unlock(&lun->lun_tg_pt_gp_lock); pr_debug("Target_Core_ConfigFS: %s %s/tpgt_%hu/%s to ALUA" " Target Port Group: alua/%s, ID: %hu\n", (move) ? From 2a7a891f4c406822801ecd676b076c64de072c9e Mon Sep 17 00:00:00 2001 From: Luis Chamberlain Date: Fri, 15 Oct 2021 16:30:20 -0700 Subject: [PATCH 264/279] scsi: sd: Add error handling support for add_disk() We never checked for errors on add_disk() as this function returned void. Now that this is fixed, use the shiny new error handling. As with the error handling for device_add() we follow the same logic and just put the device so that cleanup is done via the scsi_disk_release(). Link: https://lore.kernel.org/r/20211015233028.2167651-2-mcgrof@kernel.org Reviewed-by: Christoph Hellwig Acked-by: Martin K. Petersen Signed-off-by: Luis Chamberlain Signed-off-by: Martin K. Petersen --- drivers/scsi/sd.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index 8b19d7cb5e96..1ba83a892976 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -3457,7 +3457,13 @@ static int sd_probe(struct device *dev) pm_runtime_set_autosuspend_delay(dev, sdp->host->hostt->rpm_autosuspend_delay); } - device_add_disk(dev, gd, NULL); + + error = device_add_disk(dev, gd, NULL); + if (error) { + put_device(&sdkp->dev); + goto out; + } + if (sdkp->capacity) sd_dif_config_host(sdkp); From e9d658c2175b95a8f091b12ddefb271683aeacd9 Mon Sep 17 00:00:00 2001 From: Luis Chamberlain Date: Fri, 15 Oct 2021 16:30:21 -0700 Subject: [PATCH 265/279] scsi: sr: Add error handling support for add_disk() We never checked for errors on add_disk() as this function returned void. Now that this is fixed, use the shiny new error handling. Just put the cdrom kref and have the unwinding be done by sr_kref_release(). Link: https://lore.kernel.org/r/20211015233028.2167651-3-mcgrof@kernel.org Reviewed-by: Christoph Hellwig Acked-by: Martin K. Petersen Signed-off-by: Luis Chamberlain Signed-off-by: Martin K. Petersen --- drivers/scsi/sr.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c index 8b17b35283aa..d769057b25a0 100644 --- a/drivers/scsi/sr.c +++ b/drivers/scsi/sr.c @@ -727,7 +727,12 @@ static int sr_probe(struct device *dev) dev_set_drvdata(dev, cd); disk->flags |= GENHD_FL_REMOVABLE; sr_revalidate_disk(cd); - device_add_disk(&sdev->sdev_gendev, disk, NULL); + + error = device_add_disk(&sdev->sdev_gendev, disk, NULL); + if (error) { + kref_put(&cd->kref, sr_kref_release); + goto fail; + } sdev_printk(KERN_DEBUG, sdev, "Attached scsi CD-ROM %s\n", cd->cdi.name); From e6ab6113526aa485ca4256dbbfd8e6f48a4575f6 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Mon, 18 Oct 2021 08:08:02 +0200 Subject: [PATCH 266/279] scsi: aha1542: Use memcpy_{from,to}_bvec() Use the memcpy_{from,to}_bvec() helpers instead of open coding them. Link: https://lore.kernel.org/r/20211018060802.1815982-1-hch@lst.de Signed-off-by: Christoph Hellwig Signed-off-by: Martin K. Petersen --- drivers/scsi/aha1542.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/scsi/aha1542.c b/drivers/scsi/aha1542.c index 8697f4720946..f0e8ae9f5e40 100644 --- a/drivers/scsi/aha1542.c +++ b/drivers/scsi/aha1542.c @@ -268,8 +268,7 @@ static void aha1542_free_cmd(struct scsi_cmnd *cmd) struct bio_vec bv; rq_for_each_segment(bv, rq, iter) { - memcpy_to_page(bv.bv_page, bv.bv_offset, buf, - bv.bv_len); + memcpy_to_bvec(&bv, buf); buf += bv.bv_len; } } @@ -452,8 +451,7 @@ static int aha1542_queuecommand(struct Scsi_Host *sh, struct scsi_cmnd *cmd) struct bio_vec bv; rq_for_each_segment(bv, rq, iter) { - memcpy_from_page(buf, bv.bv_page, bv.bv_offset, - bv.bv_len); + memcpy_from_bvec(buf, &bv); buf += bv.bv_len; } } From 1b74ab77d62fe542af83e4cac95e8995032a30db Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Mon, 18 Oct 2021 08:50:52 +0200 Subject: [PATCH 267/279] scsi: target: core: Stop using bdevname() Just use the %pg format specifier instead. Link: https://lore.kernel.org/r/20211018065052.1822500-1-hch@lst.de Signed-off-by: Christoph Hellwig Signed-off-by: Martin K. Petersen --- drivers/target/target_core_iblock.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/target/target_core_iblock.c b/drivers/target/target_core_iblock.c index 4069a1edcfa3..3113c4440735 100644 --- a/drivers/target/target_core_iblock.c +++ b/drivers/target/target_core_iblock.c @@ -634,12 +634,10 @@ static ssize_t iblock_show_configfs_dev_params(struct se_device *dev, char *b) { struct iblock_dev *ib_dev = IBLOCK_DEV(dev); struct block_device *bd = ib_dev->ibd_bd; - char buf[BDEVNAME_SIZE]; ssize_t bl = 0; if (bd) - bl += sprintf(b + bl, "iBlock device: %s", - bdevname(bd, buf)); + bl += sprintf(b + bl, "iBlock device: %pg", bd); if (ib_dev->ibd_flags & IBDF_HAS_UDEV_PATH) bl += sprintf(b + bl, " UDEV PATH: %s", ib_dev->ibd_udev_path); From 3d8fa78ebd61aada5d55de6e04beee7fd916c62b Mon Sep 17 00:00:00 2001 From: Sreekanth Reddy Date: Mon, 18 Oct 2021 12:36:11 +0530 Subject: [PATCH 268/279] scsi: scsi_transport_sas: Add 22.5 Gbps link rate definitions Add 22.5 Gbps link rate definitions. Link: https://lore.kernel.org/r/20211018070611.26428-1-sreekanth.reddy@broadcom.com Reviewed-by: John Garry Signed-off-by: Sreekanth Reddy Signed-off-by: Martin K. Petersen --- drivers/scsi/scsi_transport_sas.c | 1 + include/scsi/scsi_transport_sas.h | 1 + 2 files changed, 2 insertions(+) diff --git a/drivers/scsi/scsi_transport_sas.c b/drivers/scsi/scsi_transport_sas.c index 4a96fb05731d..4ee578b181da 100644 --- a/drivers/scsi/scsi_transport_sas.c +++ b/drivers/scsi/scsi_transport_sas.c @@ -154,6 +154,7 @@ static struct { { SAS_LINK_RATE_3_0_GBPS, "3.0 Gbit" }, { SAS_LINK_RATE_6_0_GBPS, "6.0 Gbit" }, { SAS_LINK_RATE_12_0_GBPS, "12.0 Gbit" }, + { SAS_LINK_RATE_22_5_GBPS, "22.5 Gbit" }, }; sas_bitfield_name_search(linkspeed, sas_linkspeed_names) sas_bitfield_name_set(linkspeed, sas_linkspeed_names) diff --git a/include/scsi/scsi_transport_sas.h b/include/scsi/scsi_transport_sas.h index 05ec927a3c72..0e75b9277c8c 100644 --- a/include/scsi/scsi_transport_sas.h +++ b/include/scsi/scsi_transport_sas.h @@ -41,6 +41,7 @@ enum sas_linkrate { SAS_LINK_RATE_G2 = SAS_LINK_RATE_3_0_GBPS, SAS_LINK_RATE_6_0_GBPS = 10, SAS_LINK_RATE_12_0_GBPS = 11, + SAS_LINK_RATE_22_5_GBPS = 12, /* These are virtual to the transport class and may never * be signalled normally since the standard defined field * is only 4 bits */ From 0ae8f4785107eb7f63ac17d86d894be681427dd2 Mon Sep 17 00:00:00 2001 From: Jiapeng Chong Date: Tue, 19 Oct 2021 18:27:19 +0800 Subject: [PATCH 269/279] scsi: mpt3sas: Make mpt3sas_dev_attrs static This symbol is not used outside of mpt3sas_ctl.c, mark it static. Fixes the following sparse warning: drivers/scsi/mpt3sas/mpt3sas_ctl.c:3988:18: warning: symbol 'mpt3sas_dev_attrs' was not declared. Should it be static? Link: https://lore.kernel.org/r/1634639239-2892-1-git-send-email-jiapeng.chong@linux.alibaba.com Fixes: 1bb3ca27d2ca ("scsi: mpt3sas: Switch to attribute groups") Reported-by: Abaci Robot Reviewed-by: Bart Van Assche Reviewed-by: Himanshu Madhani Signed-off-by: Jiapeng Chong Signed-off-by: Martin K. Petersen --- drivers/scsi/mpt3sas/mpt3sas_ctl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/mpt3sas/mpt3sas_ctl.c b/drivers/scsi/mpt3sas/mpt3sas_ctl.c index 0aabc9761be1..05b6c6a073c3 100644 --- a/drivers/scsi/mpt3sas/mpt3sas_ctl.c +++ b/drivers/scsi/mpt3sas/mpt3sas_ctl.c @@ -3985,7 +3985,7 @@ sas_ncq_prio_enable_store(struct device *dev, } static DEVICE_ATTR_RW(sas_ncq_prio_enable); -struct attribute *mpt3sas_dev_attrs[] = { +static struct attribute *mpt3sas_dev_attrs[] = { &dev_attr_sas_address.attr, &dev_attr_sas_device_handle.attr, &dev_attr_sas_ncq_prio_supported.attr, From bb4a8dcb4e9498deccaf7b257449044968e514c7 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Mon, 18 Oct 2021 15:20:01 +0200 Subject: [PATCH 270/279] scsi: ufs: mediatek: Avoid sched_clock() misuse sched_clock() is not meant to be used in portable driver code, and assuming a particular clock frequency is not how this is meant to be used. It also causes a build failure because of a missing header inclusion: drivers/scsi/ufs/ufs-mediatek.c:321:12: error: implicit declaration of function 'sched_clock' [-Werror,-Wimplicit-function-declaration] timeout = sched_clock() + retry_ms * 1000000UL; A better interface to use here ktime_get_mono_fast_ns(), which works mostly like ktime_get() but is safe to use inside of a suspend callback. Link: https://lore.kernel.org/r/20211018132022.2281589-1-arnd@kernel.org Fixes: 9561f58442e4 ("scsi: ufs: mediatek: Support vops pre suspend to disable auto-hibern8") Reviewed-by: Stanley Chu Signed-off-by: Arnd Bergmann Signed-off-by: Martin K. Petersen --- drivers/scsi/ufs/ufs-mediatek.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/scsi/ufs/ufs-mediatek.c b/drivers/scsi/ufs/ufs-mediatek.c index d0a8e1319ab3..fc5b214347b3 100644 --- a/drivers/scsi/ufs/ufs-mediatek.c +++ b/drivers/scsi/ufs/ufs-mediatek.c @@ -319,15 +319,15 @@ static void ufs_mtk_wait_idle_state(struct ufs_hba *hba, u32 val, sm; bool wait_idle; - timeout = sched_clock() + retry_ms * 1000000UL; - + /* cannot use plain ktime_get() in suspend */ + timeout = ktime_get_mono_fast_ns() + retry_ms * 1000000UL; /* wait a specific time after check base */ udelay(10); wait_idle = false; do { - time_checked = sched_clock(); + time_checked = ktime_get_mono_fast_ns(); ufs_mtk_dbg_sel(hba); val = ufshcd_readl(hba, REG_UFS_PROBE); From b6ca770ae7f2c560a29bbd02c4e3d734fafaf804 Mon Sep 17 00:00:00 2001 From: Srinivas Kandagatla Date: Tue, 14 Sep 2021 10:22:14 +0100 Subject: [PATCH 271/279] scsi: ufs: ufshcd-pltfrm: Fix memory leak due to probe defer UFS drivers that probe defer will end up leaking memory allocated for clk and regulator names via kstrdup() because the structure that is holding this memory is allocated via devm_* variants which will be freed during probe defer but the names are never freed. Use same devm_* variant of kstrdup to free the memory allocated to name when driver probe defers. Kmemleak found around 11 leaks on Qualcomm Dragon Board RB5: unreferenced object 0xffff66f243fb2c00 (size 128): comm "kworker/u16:0", pid 7, jiffies 4294893319 (age 94.848s) hex dump (first 32 bytes): 63 6f 72 65 5f 63 6c 6b 00 76 69 72 74 75 61 6c core_clk.virtual 2f 77 6f 72 6b 71 75 65 75 65 2f 73 63 73 69 5f /workqueue/scsi_ backtrace: [<000000006f788cd1>] slab_post_alloc_hook+0x88/0x410 [<00000000cfd1372b>] __kmalloc_track_caller+0x138/0x230 [<00000000a92ab17b>] kstrdup+0xb0/0x110 [<0000000037263ab6>] ufshcd_pltfrm_init+0x1a8/0x500 [<00000000a20a5caa>] ufs_qcom_probe+0x20/0x58 [<00000000a5e43067>] platform_probe+0x6c/0x118 [<00000000ef686e3f>] really_probe+0xc4/0x330 [<000000005b18792c>] __driver_probe_device+0x88/0x118 [<00000000a5d295e8>] driver_probe_device+0x44/0x158 [<000000007e83f58d>] __device_attach_driver+0xb4/0x128 [<000000004bfa4470>] bus_for_each_drv+0x68/0xd0 [<00000000b89a83bc>] __device_attach+0xec/0x170 [<00000000ada2beea>] device_initial_probe+0x14/0x20 [<0000000079921612>] bus_probe_device+0x9c/0xa8 [<00000000d268bf7c>] deferred_probe_work_func+0x90/0xd0 [<000000009ef64bfa>] process_one_work+0x29c/0x788 unreferenced object 0xffff66f243fb2c80 (size 128): comm "kworker/u16:0", pid 7, jiffies 4294893319 (age 94.848s) hex dump (first 32 bytes): 62 75 73 5f 61 67 67 72 5f 63 6c 6b 00 00 00 00 bus_aggr_clk.... 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ With this patch no memory leaks are reported. Link: https://lore.kernel.org/r/20210914092214.6468-1-srinivas.kandagatla@linaro.org Fixes: aa4976130934 ("ufs: Add regulator enable support") Fixes: c6e79dacd86f ("ufs: Add clock initialization support") Reviewed-by: Bart Van Assche Signed-off-by: Srinivas Kandagatla Signed-off-by: Martin K. Petersen --- drivers/scsi/ufs/ufshcd-pltfrm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/ufs/ufshcd-pltfrm.c b/drivers/scsi/ufs/ufshcd-pltfrm.c index 8859c13f4e09..eaeae83b999f 100644 --- a/drivers/scsi/ufs/ufshcd-pltfrm.c +++ b/drivers/scsi/ufs/ufshcd-pltfrm.c @@ -91,7 +91,7 @@ static int ufshcd_parse_clock_info(struct ufs_hba *hba) clki->min_freq = clkfreq[i]; clki->max_freq = clkfreq[i+1]; - clki->name = kstrdup(name, GFP_KERNEL); + clki->name = devm_kstrdup(dev, name, GFP_KERNEL); if (!strcmp(name, "ref_clk")) clki->keep_link_active = true; dev_dbg(dev, "%s: min %u max %u name %s\n", "freq-table-hz", @@ -126,7 +126,7 @@ static int ufshcd_populate_vreg(struct device *dev, const char *name, if (!vreg) return -ENOMEM; - vreg->name = kstrdup(name, GFP_KERNEL); + vreg->name = devm_kstrdup(dev, name, GFP_KERNEL); snprintf(prop_name, MAX_PROP_SIZE, "%s-max-microamp", name); if (of_property_read_u32(np, prop_name, &vreg->max_uA)) { From a516074c20261d7a49164206579ef89a04b8fc39 Mon Sep 17 00:00:00 2001 From: James Smart Date: Wed, 20 Oct 2021 14:14:10 -0700 Subject: [PATCH 272/279] scsi: lpfc: Revert LOG_TRACE_EVENT back to LOG_INIT prior to driver_resource_setup() In cases when lpfc_enable_pci_dev() fails, lpfc_printf_log() with LOG_TRACE_EVENT set will call lpfc_dmp_dbg() which uses the phba->port_list_lock. However, phba->port_list_lock does not get initialized until lpfc_setup_driver_resource_phase1(). Thus, any initialization routine with LOG_TRACE_EVENT log message prior to lpfc_setup_driver_resource_phase1() will crash. Revert LOG_TRACE_EVENT back to LOG_INIT for all log messages in routines prior to lpfc_setup_driver_resource_phase1(). Link: https://lore.kernel.org/r/20211020211417.88754-2-jsmart2021@gmail.com CC: Zheyu Ma Co-developed-by: Justin Tee Signed-off-by: Justin Tee Signed-off-by: James Smart Signed-off-by: Martin K. Petersen --- drivers/scsi/lpfc/lpfc_init.c | 6 +++--- drivers/scsi/lpfc/lpfc_scsi.c | 2 +- drivers/scsi/lpfc/lpfc_sli.c | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index 34b5d042bfd0..469045b0cd7d 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c @@ -7385,7 +7385,7 @@ lpfc_enable_pci_dev(struct lpfc_hba *phba) out_disable_device: pci_disable_device(pdev); out_error: - lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT, + lpfc_printf_log(phba, KERN_ERR, LOG_INIT, "1401 Failed to enable pci device\n"); return -ENODEV; } @@ -8428,7 +8428,7 @@ lpfc_init_api_table_setup(struct lpfc_hba *phba, uint8_t dev_grp) phba->lpfc_stop_port = lpfc_stop_port_s4; break; default: - lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT, + lpfc_printf_log(phba, KERN_ERR, LOG_INIT, "1431 Invalid HBA PCI-device group: 0x%x\n", dev_grp); return -ENODEV; @@ -11661,7 +11661,7 @@ lpfc_sli4_pci_mem_setup(struct lpfc_hba *phba) /* There is no SLI3 failback for SLI4 devices. */ if (bf_get(lpfc_sli_intf_valid, &phba->sli4_hba.sli_intf) != LPFC_SLI_INTF_VALID) { - lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT, + lpfc_printf_log(phba, KERN_ERR, LOG_INIT, "2894 SLI_INTF reg contents invalid " "sli_intf reg 0x%x\n", phba->sli4_hba.sli_intf.word0); diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c index 67844fcc0e94..f1bd36b797ad 100644 --- a/drivers/scsi/lpfc/lpfc_scsi.c +++ b/drivers/scsi/lpfc/lpfc_scsi.c @@ -5115,7 +5115,7 @@ lpfc_scsi_api_table_setup(struct lpfc_hba *phba, uint8_t dev_grp) phba->lpfc_scsi_prep_cmnd_buf = lpfc_scsi_prep_cmnd_buf_s4; break; default: - lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT, + lpfc_printf_log(phba, KERN_ERR, LOG_INIT, "1418 Invalid HBA PCI-device group: 0x%x\n", dev_grp); return -ENODEV; diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index d800c6a69c95..244e7d68428e 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c @@ -10026,7 +10026,7 @@ lpfc_mbox_api_table_setup(struct lpfc_hba *phba, uint8_t dev_grp) phba->lpfc_sli_brdready = lpfc_sli_brdready_s4; break; default: - lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT, + lpfc_printf_log(phba, KERN_ERR, LOG_INIT, "1420 Invalid HBA PCI-device group: 0x%x\n", dev_grp); return -ENODEV; @@ -11194,7 +11194,7 @@ lpfc_sli_api_table_setup(struct lpfc_hba *phba, uint8_t dev_grp) phba->__lpfc_sli_issue_fcp_io = __lpfc_sli_issue_fcp_io_s4; break; default: - lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT, + lpfc_printf_log(phba, KERN_ERR, LOG_INIT, "1419 Invalid HBA PCI-device group: 0x%x\n", dev_grp); return -ENODEV; From d305c253af693e69a36cedec880aca6d0c6d789d Mon Sep 17 00:00:00 2001 From: James Smart Date: Wed, 20 Oct 2021 14:14:11 -0700 Subject: [PATCH 273/279] scsi: lpfc: Wait for successful restart of SLI3 adapter during host sg_reset A prior patch introduced HBA_NEEDS_CFG_PORT flag logic, but in lpfc_sli_brdrestart_s3() code path, right after HBA_NEEDS_CFG_PORT is set, the phba->hba_flag is cleared in lpfc_sli_brdreset(). Fix by calling lpfc_sli_chipset_init() to wait for successful restart of the HBA in lpfc_host_reset_handler() after lpfc_sli_brdrestart(). lpfc_sli_chipset_init() sets the HBA_NEEDS_CFG_PORT flag so that the lpfc_sli_hba_setup() routine from lpfc_online() will execute lpfc_sli_config_port() initialization step when the brdrestart is successful. Link: https://lore.kernel.org/r/20211020211417.88754-3-jsmart2021@gmail.com Fixes: d2f2547efd39 ("scsi: lpfc: Fix auto sli_mode and its effect on CONFIG_PORT for SLI3") Co-developed-by: Justin Tee Signed-off-by: Justin Tee Signed-off-by: James Smart Signed-off-by: Martin K. Petersen --- drivers/scsi/lpfc/lpfc_scsi.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c index f1bd36b797ad..5578080afef8 100644 --- a/drivers/scsi/lpfc/lpfc_scsi.c +++ b/drivers/scsi/lpfc/lpfc_scsi.c @@ -6648,6 +6648,13 @@ lpfc_host_reset_handler(struct scsi_cmnd *cmnd) if (rc) goto error; + /* Wait for successful restart of adapter */ + if (phba->sli_rev < LPFC_SLI_REV4) { + rc = lpfc_sli_chipset_init(phba); + if (rc) + goto error; + } + rc = lpfc_online(phba); if (rc) goto error; From 7a1dda943630038dbe149268b00eb6a2946d38af Mon Sep 17 00:00:00 2001 From: James Smart Date: Wed, 20 Oct 2021 14:14:12 -0700 Subject: [PATCH 274/279] scsi: lpfc: Correct sysfs reporting of loop support after SFP status change Applications determine loop support in part by querying the 'pls' sysfs node. Reporting of 'pls' (Private Loop Support) is derived from the descriptor returned by the COMMON_GET_SLI4_PARAMETERS mailbox command, which is issued during initialization or after a reset. The value of this field may change if there is a dynamic SFP change. The driver currently will not pick up the change as there was no reset scenario. Rework to commonize the sending of the COMMON_GET_SLI4_PARAMETERS command. Add the calling of the routine after receipt of an async event indicating an SFP change. Link: https://lore.kernel.org/r/20211020211417.88754-4-jsmart2021@gmail.com Co-developed-by: Justin Tee Signed-off-by: Justin Tee Signed-off-by: James Smart Signed-off-by: Martin K. Petersen --- drivers/scsi/lpfc/lpfc_crtn.h | 1 + drivers/scsi/lpfc/lpfc_init.c | 50 +++++++++++++++++++++++++++++++++++ drivers/scsi/lpfc/lpfc_sli.c | 25 +++--------------- 3 files changed, 55 insertions(+), 21 deletions(-) diff --git a/drivers/scsi/lpfc/lpfc_crtn.h b/drivers/scsi/lpfc/lpfc_crtn.h index ad4a954ecc09..87cffbc382aa 100644 --- a/drivers/scsi/lpfc/lpfc_crtn.h +++ b/drivers/scsi/lpfc/lpfc_crtn.h @@ -205,6 +205,7 @@ void lpfc_delayed_disc_timeout_handler(struct lpfc_vport *); int lpfc_config_port_prep(struct lpfc_hba *); void lpfc_update_vport_wwn(struct lpfc_vport *vport); int lpfc_config_port_post(struct lpfc_hba *); +int lpfc_sli4_refresh_params(struct lpfc_hba *phba); int lpfc_hba_down_prep(struct lpfc_hba *); int lpfc_hba_down_post(struct lpfc_hba *); void lpfc_hba_init(struct lpfc_hba *, uint32_t *); diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index 469045b0cd7d..fc58384f7fc8 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c @@ -662,6 +662,50 @@ lpfc_config_port_post(struct lpfc_hba *phba) return 0; } +/** + * lpfc_sli4_refresh_params - update driver copy of params. + * @phba: Pointer to HBA context object. + * + * This is called to refresh driver copy of dynamic fields from the + * common_get_sli4_parameters descriptor. + **/ +int +lpfc_sli4_refresh_params(struct lpfc_hba *phba) +{ + LPFC_MBOXQ_t *mboxq; + struct lpfc_mqe *mqe; + struct lpfc_sli4_parameters *mbx_sli4_parameters; + int length, rc; + + mboxq = (LPFC_MBOXQ_t *)mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); + if (!mboxq) + return -ENOMEM; + + mqe = &mboxq->u.mqe; + /* Read the port's SLI4 Config Parameters */ + length = (sizeof(struct lpfc_mbx_get_sli4_parameters) - + sizeof(struct lpfc_sli4_cfg_mhdr)); + lpfc_sli4_config(phba, mboxq, LPFC_MBOX_SUBSYSTEM_COMMON, + LPFC_MBOX_OPCODE_GET_SLI4_PARAMETERS, + length, LPFC_SLI4_MBX_EMBED); + + rc = lpfc_sli_issue_mbox(phba, mboxq, MBX_POLL); + if (unlikely(rc)) { + mempool_free(mboxq, phba->mbox_mem_pool); + return rc; + } + mbx_sli4_parameters = &mqe->un.get_sli4_parameters.sli4_parameters; + phba->sli4_hba.pc_sli4_params.mi_ver = + bf_get(cfg_mi_ver, mbx_sli4_parameters); + phba->sli4_hba.pc_sli4_params.cmf = + bf_get(cfg_cmf, mbx_sli4_parameters); + phba->sli4_hba.pc_sli4_params.pls = + bf_get(cfg_pvl, mbx_sli4_parameters); + + mempool_free(mboxq, phba->mbox_mem_pool); + return rc; +} + /** * lpfc_hba_init_link - Initialize the FC link * @phba: pointer to lpfc hba data structure. @@ -6455,6 +6499,12 @@ lpfc_sli4_async_sli_evt(struct lpfc_hba *phba, struct lpfc_acqe_sli *acqe_sli) "3194 Unable to retrieve supported " "speeds, rc = 0x%x\n", rc); } + rc = lpfc_sli4_refresh_params(phba); + if (rc) { + lpfc_printf_log(phba, KERN_ERR, LOG_SLI, + "3174 Unable to update pls support, " + "rc x%x\n", rc); + } vports = lpfc_create_vport_work_array(phba); if (vports != NULL) { for (i = 0; i <= phba->max_vports && vports[i] != NULL; diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index 244e7d68428e..f82f809617a0 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c @@ -7891,36 +7891,19 @@ static int lpfc_cmf_setup(struct lpfc_hba *phba) { LPFC_MBOXQ_t *mboxq; - struct lpfc_mqe *mqe; struct lpfc_dmabuf *mp; struct lpfc_pc_sli4_params *sli4_params; - struct lpfc_sli4_parameters *mbx_sli4_parameters; - int length; int rc, cmf, mi_ver; + rc = lpfc_sli4_refresh_params(phba); + if (unlikely(rc)) + return rc; + mboxq = (LPFC_MBOXQ_t *)mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); if (!mboxq) return -ENOMEM; - mqe = &mboxq->u.mqe; - /* Read the port's SLI4 Config Parameters */ - length = (sizeof(struct lpfc_mbx_get_sli4_parameters) - - sizeof(struct lpfc_sli4_cfg_mhdr)); - lpfc_sli4_config(phba, mboxq, LPFC_MBOX_SUBSYSTEM_COMMON, - LPFC_MBOX_OPCODE_GET_SLI4_PARAMETERS, - length, LPFC_SLI4_MBX_EMBED); - - rc = lpfc_sli_issue_mbox(phba, mboxq, MBX_POLL); - if (unlikely(rc)) { - mempool_free(mboxq, phba->mbox_mem_pool); - return rc; - } - - /* Gather info on CMF and MI support */ sli4_params = &phba->sli4_hba.pc_sli4_params; - mbx_sli4_parameters = &mqe->un.get_sli4_parameters.sli4_parameters; - sli4_params->mi_ver = bf_get(cfg_mi_ver, mbx_sli4_parameters); - sli4_params->cmf = bf_get(cfg_cmf, mbx_sli4_parameters); /* Are we forcing MI off via module parameter? */ if (!phba->cfg_enable_mi) From 79b20beccea3a3938a8500acef4e6b9d7c66142f Mon Sep 17 00:00:00 2001 From: James Smart Date: Wed, 20 Oct 2021 14:14:13 -0700 Subject: [PATCH 275/279] scsi: lpfc: Fix use-after-free in lpfc_unreg_rpi() routine An error is detected with the following report when unloading the driver: "KASAN: use-after-free in lpfc_unreg_rpi+0x1b1b" The NLP_REG_LOGIN_SEND nlp_flag is set in lpfc_reg_fab_ctrl_node(), but the flag is not cleared upon completion of the login. This allows a second call to lpfc_unreg_rpi() to proceed with nlp_rpi set to LPFC_RPI_ALLOW_ERROR. This results in a use after free access when used as an rpi_ids array index. Fix by clearing the NLP_REG_LOGIN_SEND nlp_flag in lpfc_mbx_cmpl_fc_reg_login(). Link: https://lore.kernel.org/r/20211020211417.88754-5-jsmart2021@gmail.com Co-developed-by: Justin Tee Signed-off-by: Justin Tee Signed-off-by: James Smart Signed-off-by: Martin K. Petersen --- drivers/scsi/lpfc/lpfc_hbadisc.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c index 0b1e1cc00e01..4c068fbb550a 100644 --- a/drivers/scsi/lpfc/lpfc_hbadisc.c +++ b/drivers/scsi/lpfc/lpfc_hbadisc.c @@ -4372,6 +4372,7 @@ lpfc_mbx_cmpl_fc_reg_login(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) ndlp->nlp_state); ndlp->nlp_flag |= NLP_RPI_REGISTERED; + ndlp->nlp_flag &= ~NLP_REG_LOGIN_SEND; ndlp->nlp_type |= NLP_FABRIC; lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNMAPPED_NODE); From 15af02d8a5852acd07617ad4deb2500ca2e0304c Mon Sep 17 00:00:00 2001 From: James Smart Date: Wed, 20 Oct 2021 14:14:14 -0700 Subject: [PATCH 276/279] scsi: lpfc: Allow PLOGI retry if previous PLOGI was aborted A remote nport can stop responding to PLOGI beyond the ELS I/O timeout under some fault conditions. When this happens, the non-response triggers a dev_loss_tmo event from the transport which causes the driver to abort the PLOGI and stop any retries. This was due to a policy in the ELS completion handler whenever an ELS was terminated due to driver request. Revise the ELS completion path to detect PLOGIs that were aborted and allow retries. Link: https://lore.kernel.org/r/20211020211417.88754-6-jsmart2021@gmail.com Co-developed-by: Justin Tee Signed-off-by: Justin Tee Signed-off-by: James Smart Signed-off-by: Martin K. Petersen --- drivers/scsi/lpfc/lpfc_els.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c index de38f4b886ca..746fe9772453 100644 --- a/drivers/scsi/lpfc/lpfc_els.c +++ b/drivers/scsi/lpfc/lpfc_els.c @@ -4577,6 +4577,19 @@ lpfc_els_retry(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, retry = 1; delay = 100; break; + case IOERR_SLI_ABORTED: + /* Retry ELS PLOGI command? + * Possibly the rport just wasn't ready. + */ + if (cmd == ELS_CMD_PLOGI) { + /* No retry if state change */ + if (ndlp && + ndlp->nlp_state != NLP_STE_PLOGI_ISSUE) + goto out_retry; + retry = 1; + maxretry = 2; + } + break; } break; From 1854f53ccd88ad4e7568ddfafafffe71f1ceb0a6 Mon Sep 17 00:00:00 2001 From: James Smart Date: Wed, 20 Oct 2021 14:14:15 -0700 Subject: [PATCH 277/279] scsi: lpfc: Fix link down processing to address NULL pointer dereference If an FC link down transition while PLOGIs are outstanding to fabric well known addresses, outstanding ABTS requests may result in a NULL pointer dereference. Driver unload requests may hang with repeated "2878" log messages. The Link down processing results in ABTS requests for outstanding ELS requests. The Abort WQEs are sent for the ELSs before the driver had set the link state to down. Thus the driver is sending the Abort with the expectation that an ABTS will be sent on the wire. The Abort request is stalled waiting for the link to come up. In some conditions the driver may auto-complete the ELSs thus if the link does come up, the Abort completions may reference an invalid structure. Fix by ensuring that Abort set the flag to avoid link traffic if issued due to conditions where the link failed. Link: https://lore.kernel.org/r/20211020211417.88754-7-jsmart2021@gmail.com Co-developed-by: Justin Tee Signed-off-by: Justin Tee Signed-off-by: James Smart Signed-off-by: Martin K. Petersen --- drivers/scsi/lpfc/lpfc_sli.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index f82f809617a0..5dedb3de271d 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c @@ -12403,17 +12403,17 @@ lpfc_sli_issue_abort_iotag(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, /* ABTS WQE must go to the same WQ as the WQE to be aborted */ abtsiocbp->hba_wqidx = cmdiocb->hba_wqidx; - if (cmdiocb->iocb_flag & LPFC_IO_FCP) { - abtsiocbp->iocb_flag |= LPFC_IO_FCP; - abtsiocbp->iocb_flag |= LPFC_USE_FCPWQIDX; - } + if (cmdiocb->iocb_flag & LPFC_IO_FCP) + abtsiocbp->iocb_flag |= (LPFC_IO_FCP | LPFC_USE_FCPWQIDX); if (cmdiocb->iocb_flag & LPFC_IO_FOF) abtsiocbp->iocb_flag |= LPFC_IO_FOF; - if (phba->link_state >= LPFC_LINK_UP) - iabt->ulpCommand = CMD_ABORT_XRI_CN; - else + if (phba->link_state < LPFC_LINK_UP || + (phba->sli_rev == LPFC_SLI_REV4 && + phba->sli4_hba.link_state.status == LPFC_FC_LA_TYPE_LINK_DOWN)) iabt->ulpCommand = CMD_CLOSE_XRI_CN; + else + iabt->ulpCommand = CMD_ABORT_XRI_CN; if (cmpl) abtsiocbp->iocb_cmpl = cmpl; From af984c87293b19dccbd0b16afc57c5c9a4a279c7 Mon Sep 17 00:00:00 2001 From: James Smart Date: Wed, 20 Oct 2021 14:14:16 -0700 Subject: [PATCH 278/279] scsi: lpfc: Allow fabric node recovery if recovery is in progress before devloss A link bounce to a slow fabric may observe FDISC response delays lasting longer than devloss tmo. Current logic decrements the final fabric node kref during a devloss tmo event. This results in a NULL ptr dereference crash if the FDISC completes for that fabric node after devloss tmo. Fix by adding the NLP_IN_RECOV_POST_DEV_LOSS flag, which is set when devloss tmo triggers and we've noticed that fabric node recovery has already started or finished in between the time lpfc_dev_loss_tmo_callbk queues lpfc_dev_loss_tmo_handler. If fabric node recovery succeeds, then the driver reverses the devloss tmo marked kref put with a kref get. If fabric node recovery fails, then the final kref put relies on the ELS timing out or the REG_LOGIN cmpl routine. Link: https://lore.kernel.org/r/20211020211417.88754-8-jsmart2021@gmail.com Co-developed-by: Justin Tee Signed-off-by: Justin Tee Signed-off-by: James Smart Signed-off-by: Martin K. Petersen --- drivers/scsi/lpfc/lpfc_crtn.h | 2 + drivers/scsi/lpfc/lpfc_disc.h | 12 +++- drivers/scsi/lpfc/lpfc_els.c | 7 +- drivers/scsi/lpfc/lpfc_hbadisc.c | 111 ++++++++++++++++++++++++++++++- drivers/scsi/lpfc/lpfc_init.c | 12 ++-- drivers/scsi/lpfc/lpfc_scsi.c | 10 +-- 6 files changed, 139 insertions(+), 15 deletions(-) diff --git a/drivers/scsi/lpfc/lpfc_crtn.h b/drivers/scsi/lpfc/lpfc_crtn.h index 87cffbc382aa..89e36bf14d8f 100644 --- a/drivers/scsi/lpfc/lpfc_crtn.h +++ b/drivers/scsi/lpfc/lpfc_crtn.h @@ -119,6 +119,8 @@ int lpfc_check_sli_ndlp(struct lpfc_hba *, struct lpfc_sli_ring *, struct lpfc_nodelist *lpfc_nlp_init(struct lpfc_vport *vport, uint32_t did); struct lpfc_nodelist *lpfc_nlp_get(struct lpfc_nodelist *); int lpfc_nlp_put(struct lpfc_nodelist *); +void lpfc_check_nlp_post_devloss(struct lpfc_vport *vport, + struct lpfc_nodelist *ndlp); void lpfc_ignore_els_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, struct lpfc_iocbq *rspiocb); int lpfc_nlp_not_used(struct lpfc_nodelist *ndlp); diff --git a/drivers/scsi/lpfc/lpfc_disc.h b/drivers/scsi/lpfc/lpfc_disc.h index 871b665bd72e..37a4b79010bf 100644 --- a/drivers/scsi/lpfc/lpfc_disc.h +++ b/drivers/scsi/lpfc/lpfc_disc.h @@ -85,6 +85,13 @@ enum lpfc_fc4_xpt_flags { NLP_XPT_HAS_HH = 0x10 }; +enum lpfc_nlp_save_flags { + /* devloss occurred during recovery */ + NLP_IN_RECOV_POST_DEV_LOSS = 0x1, + /* wait for outstanding LOGO to cmpl */ + NLP_WAIT_FOR_LOGO = 0x2, +}; + struct lpfc_nodelist { struct list_head nlp_listp; struct serv_parm fc_sparam; /* buffer for service params */ @@ -144,8 +151,9 @@ struct lpfc_nodelist { unsigned long *active_rrqs_xri_bitmap; struct lpfc_scsicmd_bkt *lat_data; /* Latency data */ uint32_t fc4_prli_sent; - u32 upcall_flags; -#define NLP_WAIT_FOR_LOGO 0x2 + + /* flags to keep ndlp alive until special conditions are met */ + enum lpfc_nlp_save_flags save_flags; enum lpfc_fc4_xpt_flags fc4_xpt_flags; diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c index 746fe9772453..b940e0268f96 100644 --- a/drivers/scsi/lpfc/lpfc_els.c +++ b/drivers/scsi/lpfc/lpfc_els.c @@ -2905,9 +2905,9 @@ lpfc_cmpl_els_logo(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, irsp = &(rspiocb->iocb); spin_lock_irq(&ndlp->lock); ndlp->nlp_flag &= ~NLP_LOGO_SND; - if (ndlp->upcall_flags & NLP_WAIT_FOR_LOGO) { + if (ndlp->save_flags & NLP_WAIT_FOR_LOGO) { wake_up_waiter = 1; - ndlp->upcall_flags &= ~NLP_WAIT_FOR_LOGO; + ndlp->save_flags &= ~NLP_WAIT_FOR_LOGO; } spin_unlock_irq(&ndlp->lock); @@ -10735,6 +10735,9 @@ lpfc_cmpl_els_fdisc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, irsp->ulpStatus, irsp->un.ulpWord[4]); goto fdisc_failed; } + + lpfc_check_nlp_post_devloss(vport, ndlp); + spin_lock_irq(shost->host_lock); vport->fc_flag &= ~FC_VPORT_CVL_RCVD; vport->fc_flag &= ~FC_VPORT_LOGO_RCVD; diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c index 4c068fbb550a..9fe6e5b386ce 100644 --- a/drivers/scsi/lpfc/lpfc_hbadisc.c +++ b/drivers/scsi/lpfc/lpfc_hbadisc.c @@ -209,7 +209,12 @@ lpfc_dev_loss_tmo_callbk(struct fc_rport *rport) spin_lock_irqsave(&ndlp->lock, iflags); ndlp->nlp_flag |= NLP_IN_DEV_LOSS; - ndlp->nlp_flag &= ~NLP_NPR_2B_DISC; + + /* If there is a PLOGI in progress, and we are in a + * NLP_NPR_2B_DISC state, don't turn off the flag. + */ + if (ndlp->nlp_state != NLP_STE_PLOGI_ISSUE) + ndlp->nlp_flag &= ~NLP_NPR_2B_DISC; /* * The backend does not expect any more calls associated with this @@ -340,6 +345,37 @@ static void lpfc_check_inactive_vmid(struct lpfc_hba *phba) lpfc_destroy_vport_work_array(phba, vports); } +/** + * lpfc_check_nlp_post_devloss - Check to restore ndlp refcnt after devloss + * @vport: Pointer to vport object. + * @ndlp: Pointer to remote node object. + * + * If NLP_IN_RECOV_POST_DEV_LOSS flag was set due to outstanding recovery of + * node during dev_loss_tmo processing, then this function restores the nlp_put + * kref decrement from lpfc_dev_loss_tmo_handler. + **/ +void +lpfc_check_nlp_post_devloss(struct lpfc_vport *vport, + struct lpfc_nodelist *ndlp) +{ + unsigned long iflags; + + spin_lock_irqsave(&ndlp->lock, iflags); + if (ndlp->save_flags & NLP_IN_RECOV_POST_DEV_LOSS) { + ndlp->save_flags &= ~NLP_IN_RECOV_POST_DEV_LOSS; + spin_unlock_irqrestore(&ndlp->lock, iflags); + lpfc_nlp_get(ndlp); + lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY | LOG_NODE, + "8438 Devloss timeout reversed on DID x%x " + "refcnt %d ndlp %p flag x%x " + "port_state = x%x\n", + ndlp->nlp_DID, kref_read(&ndlp->kref), ndlp, + ndlp->nlp_flag, vport->port_state); + spin_lock_irqsave(&ndlp->lock, iflags); + } + spin_unlock_irqrestore(&ndlp->lock, iflags); +} + /** * lpfc_dev_loss_tmo_handler - Remote node devloss timeout handler * @ndlp: Pointer to remote node object. @@ -358,6 +394,8 @@ lpfc_dev_loss_tmo_handler(struct lpfc_nodelist *ndlp) uint8_t *name; int warn_on = 0; int fcf_inuse = 0; + bool recovering = false; + struct fc_vport *fc_vport = NULL; unsigned long iflags; vport = ndlp->vport; @@ -394,6 +432,64 @@ lpfc_dev_loss_tmo_handler(struct lpfc_nodelist *ndlp) /* Fabric nodes are done. */ if (ndlp->nlp_type & NLP_FABRIC) { + spin_lock_irqsave(&ndlp->lock, iflags); + /* In massive vport configuration settings, it's possible + * dev_loss_tmo fired during node recovery. So, check if + * fabric nodes are in discovery states outstanding. + */ + switch (ndlp->nlp_DID) { + case Fabric_DID: + fc_vport = vport->fc_vport; + if (fc_vport && + fc_vport->vport_state == FC_VPORT_INITIALIZING) + recovering = true; + break; + case Fabric_Cntl_DID: + if (ndlp->nlp_flag & NLP_REG_LOGIN_SEND) + recovering = true; + break; + case FDMI_DID: + fallthrough; + case NameServer_DID: + if (ndlp->nlp_state >= NLP_STE_PLOGI_ISSUE && + ndlp->nlp_state <= NLP_STE_REG_LOGIN_ISSUE) + recovering = true; + break; + } + spin_unlock_irqrestore(&ndlp->lock, iflags); + + /* Mark an NLP_IN_RECOV_POST_DEV_LOSS flag to know if reversing + * the following lpfc_nlp_put is necessary after fabric node is + * recovered. + */ + if (recovering) { + lpfc_printf_vlog(vport, KERN_INFO, + LOG_DISCOVERY | LOG_NODE, + "8436 Devloss timeout marked on " + "DID x%x refcnt %d ndlp %p " + "flag x%x port_state = x%x\n", + ndlp->nlp_DID, kref_read(&ndlp->kref), + ndlp, ndlp->nlp_flag, + vport->port_state); + spin_lock_irqsave(&ndlp->lock, iflags); + ndlp->save_flags |= NLP_IN_RECOV_POST_DEV_LOSS; + spin_unlock_irqrestore(&ndlp->lock, iflags); + } else if (ndlp->nlp_state == NLP_STE_UNMAPPED_NODE) { + /* Fabric node fully recovered before this dev_loss_tmo + * queue work is processed. Thus, ignore the + * dev_loss_tmo event. + */ + lpfc_printf_vlog(vport, KERN_INFO, + LOG_DISCOVERY | LOG_NODE, + "8437 Devloss timeout ignored on " + "DID x%x refcnt %d ndlp %p " + "flag x%x port_state = x%x\n", + ndlp->nlp_DID, kref_read(&ndlp->kref), + ndlp, ndlp->nlp_flag, + vport->port_state); + return fcf_inuse; + } + lpfc_nlp_put(ndlp); return fcf_inuse; } @@ -423,6 +519,14 @@ lpfc_dev_loss_tmo_handler(struct lpfc_nodelist *ndlp) ndlp->nlp_state, ndlp->nlp_rpi); } + /* If we are devloss, but we are in the process of rediscovering the + * ndlp, don't issue a NLP_EVT_DEVICE_RM event. + */ + if (ndlp->nlp_state >= NLP_STE_PLOGI_ISSUE && + ndlp->nlp_state <= NLP_STE_PRLI_ISSUE) { + return fcf_inuse; + } + if (!(ndlp->fc4_xpt_flags & NVME_XPT_REGD)) lpfc_disc_state_machine(vport, ndlp, NULL, NLP_EVT_DEVICE_RM); @@ -4363,6 +4467,8 @@ lpfc_mbx_cmpl_fc_reg_login(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) goto out; } + lpfc_check_nlp_post_devloss(vport, ndlp); + if (phba->sli_rev < LPFC_SLI_REV4) ndlp->nlp_rpi = mb->un.varWords[0]; @@ -4540,9 +4646,10 @@ lpfc_nlp_counters(struct lpfc_vport *vport, int state, int count) void lpfc_nlp_reg_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) { - unsigned long iflags; + lpfc_check_nlp_post_devloss(vport, ndlp); + spin_lock_irqsave(&ndlp->lock, iflags); if (ndlp->fc4_xpt_flags & NLP_XPT_REGD) { /* Already registered with backend, trigger rescan */ diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index fc58384f7fc8..ba17a8f740a9 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c @@ -3753,12 +3753,16 @@ lpfc_offline_prep(struct lpfc_hba *phba, int mbx_action) lpfc_disc_state_machine(vports[i], ndlp, NULL, NLP_EVT_DEVICE_RECOVERY); - /* Don't remove the node unless the + /* Don't remove the node unless the node * has been unregistered with the - * transport. If so, let dev_loss - * take care of the node. + * transport, and we're not in recovery + * before dev_loss_tmo triggered. + * Otherwise, let dev_loss take care of + * the node. */ - if (!(ndlp->fc4_xpt_flags & + if (!(ndlp->save_flags & + NLP_IN_RECOV_POST_DEV_LOSS) && + !(ndlp->fc4_xpt_flags & (NVME_XPT_REGD | SCSI_XPT_REGD))) lpfc_disc_state_machine (vports[i], ndlp, diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c index 5578080afef8..6ccf573acdec 100644 --- a/drivers/scsi/lpfc/lpfc_scsi.c +++ b/drivers/scsi/lpfc/lpfc_scsi.c @@ -6475,28 +6475,28 @@ lpfc_target_reset_handler(struct scsi_cmnd *cmnd) /* Issue LOGO, if no LOGO is outstanding */ spin_lock_irqsave(&pnode->lock, flags); - if (!(pnode->upcall_flags & NLP_WAIT_FOR_LOGO) && + if (!(pnode->save_flags & NLP_WAIT_FOR_LOGO) && !pnode->logo_waitq) { pnode->logo_waitq = &waitq; pnode->nlp_fcp_info &= ~NLP_FCP_2_DEVICE; pnode->nlp_flag |= NLP_ISSUE_LOGO; - pnode->upcall_flags |= NLP_WAIT_FOR_LOGO; + pnode->save_flags |= NLP_WAIT_FOR_LOGO; spin_unlock_irqrestore(&pnode->lock, flags); lpfc_unreg_rpi(vport, pnode); wait_event_timeout(waitq, - (!(pnode->upcall_flags & + (!(pnode->save_flags & NLP_WAIT_FOR_LOGO)), msecs_to_jiffies(dev_loss_tmo * 1000)); - if (pnode->upcall_flags & NLP_WAIT_FOR_LOGO) { + if (pnode->save_flags & NLP_WAIT_FOR_LOGO) { lpfc_printf_vlog(vport, KERN_ERR, logit, "0725 SCSI layer TGTRST " "failed & LOGO TMO (%d, %llu) " "return x%x\n", tgt_id, lun_id, status); spin_lock_irqsave(&pnode->lock, flags); - pnode->upcall_flags &= ~NLP_WAIT_FOR_LOGO; + pnode->save_flags &= ~NLP_WAIT_FOR_LOGO; } else { spin_lock_irqsave(&pnode->lock, flags); } From 83c3a7beaef7fd261c190b69f6be6337f251bf16 Mon Sep 17 00:00:00 2001 From: James Smart Date: Wed, 20 Oct 2021 14:14:17 -0700 Subject: [PATCH 279/279] scsi: lpfc: Update lpfc version to 14.0.0.3 Update lpfc version to 14.0.0.3. Link: https://lore.kernel.org/r/20211020211417.88754-9-jsmart2021@gmail.com Co-developed-by: Justin Tee Signed-off-by: Justin Tee Signed-off-by: James Smart Signed-off-by: Martin K. Petersen --- drivers/scsi/lpfc/lpfc_version.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/lpfc/lpfc_version.h b/drivers/scsi/lpfc/lpfc_version.h index dec71775f677..5a4d3b24fbce 100644 --- a/drivers/scsi/lpfc/lpfc_version.h +++ b/drivers/scsi/lpfc/lpfc_version.h @@ -20,7 +20,7 @@ * included with this package. * *******************************************************************/ -#define LPFC_DRIVER_VERSION "14.0.0.2" +#define LPFC_DRIVER_VERSION "14.0.0.3" #define LPFC_DRIVER_NAME "lpfc" /* Used for SLI 2/3 */