diff options
317 files changed, 2255 insertions, 1843 deletions
diff --git a/Documentation/scsi/scsi_mid_low_api.rst b/Documentation/scsi/scsi_mid_low_api.rst index a8c5bd15a440..6fa3a6279501 100644 --- a/Documentation/scsi/scsi_mid_low_api.rst +++ b/Documentation/scsi/scsi_mid_low_api.rst @@ -436,7 +436,7 @@ Details:: * * Defined in: drivers/scsi/hosts.c . **/ - struct Scsi_Host * scsi_host_alloc(struct scsi_host_template * sht, + struct Scsi_Host * scsi_host_alloc(const struct scsi_host_template * sht, int privsize) diff --git a/drivers/ata/acard-ahci.c b/drivers/ata/acard-ahci.c index 993eadd173da..547f56341705 100644 --- a/drivers/ata/acard-ahci.c +++ b/drivers/ata/acard-ahci.c @@ -66,7 +66,7 @@ static int acard_ahci_pci_device_suspend(struct pci_dev *pdev, pm_message_t mesg static int acard_ahci_pci_device_resume(struct pci_dev *pdev); #endif -static struct scsi_host_template acard_ahci_sht = { +static const struct scsi_host_template acard_ahci_sht = { AHCI_SHT("acard-ahci"), }; diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index 14a1c0d14916..addba109406b 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c @@ -101,7 +101,7 @@ static int ahci_pci_device_resume(struct device *dev); #endif #endif /* CONFIG_PM */ -static struct scsi_host_template ahci_sht = { +static const struct scsi_host_template ahci_sht = { AHCI_SHT("ahci"), }; diff --git a/drivers/ata/ahci.h b/drivers/ata/ahci.h index ff8e6ae1c636..4bae95b06ae3 100644 --- a/drivers/ata/ahci.h +++ b/drivers/ata/ahci.h @@ -430,7 +430,7 @@ void ahci_set_em_messages(struct ahci_host_priv *hpriv, struct ata_port_info *pi); int ahci_reset_em(struct ata_host *host); void ahci_print_info(struct ata_host *host, const char *scc_s); -int ahci_host_activate(struct ata_host *host, struct scsi_host_template *sht); +int ahci_host_activate(struct ata_host *host, const struct scsi_host_template *sht); void ahci_error_handler(struct ata_port *ap); u32 ahci_handle_port_intr(struct ata_host *host, u32 irq_masked); diff --git a/drivers/ata/ahci_brcm.c b/drivers/ata/ahci_brcm.c index 6f216eb25610..4e3dc2b6d67f 100644 --- a/drivers/ata/ahci_brcm.c +++ b/drivers/ata/ahci_brcm.c @@ -417,7 +417,7 @@ out_disable_clks: return ret; } -static struct scsi_host_template ahci_platform_sht = { +static const struct scsi_host_template ahci_platform_sht = { AHCI_SHT(DRV_NAME), }; diff --git a/drivers/ata/ahci_ceva.c b/drivers/ata/ahci_ceva.c index cb24ecf36faf..bc027468decb 100644 --- a/drivers/ata/ahci_ceva.c +++ b/drivers/ata/ahci_ceva.c @@ -185,7 +185,7 @@ static void ahci_ceva_setup(struct ahci_host_priv *hpriv) } } -static struct scsi_host_template ahci_platform_sht = { +static const struct scsi_host_template ahci_platform_sht = { AHCI_SHT(DRV_NAME), }; diff --git a/drivers/ata/ahci_da850.c b/drivers/ata/ahci_da850.c index dc8a019b8340..ca0924dc5bd2 100644 --- a/drivers/ata/ahci_da850.c +++ b/drivers/ata/ahci_da850.c @@ -153,7 +153,7 @@ static const struct ata_port_info ahci_da850_port_info = { .port_ops = &ahci_da850_port_ops, }; -static struct scsi_host_template ahci_platform_sht = { +static const struct scsi_host_template ahci_platform_sht = { AHCI_SHT(DRV_NAME), }; diff --git a/drivers/ata/ahci_dm816.c b/drivers/ata/ahci_dm816.c index d26efcd20f64..b08547b877a1 100644 --- a/drivers/ata/ahci_dm816.c +++ b/drivers/ata/ahci_dm816.c @@ -134,7 +134,7 @@ static const struct ata_port_info ahci_dm816_port_info = { .port_ops = &ahci_dm816_port_ops, }; -static struct scsi_host_template ahci_dm816_platform_sht = { +static const struct scsi_host_template ahci_dm816_platform_sht = { AHCI_SHT(AHCI_DM816_DRV_NAME), }; diff --git a/drivers/ata/ahci_dwc.c b/drivers/ata/ahci_dwc.c index 8fb66860db31..4bfbb09cdc02 100644 --- a/drivers/ata/ahci_dwc.c +++ b/drivers/ata/ahci_dwc.c @@ -398,7 +398,7 @@ static const struct ata_port_info ahci_dwc_port_info = { .port_ops = &ahci_dwc_port_ops, }; -static struct scsi_host_template ahci_dwc_scsi_info = { +static const struct scsi_host_template ahci_dwc_scsi_info = { AHCI_SHT(DRV_NAME), }; diff --git a/drivers/ata/ahci_imx.c b/drivers/ata/ahci_imx.c index e45e91f5e703..3a8c248e7c0e 100644 --- a/drivers/ata/ahci_imx.c +++ b/drivers/ata/ahci_imx.c @@ -979,7 +979,7 @@ static u32 imx_ahci_parse_props(struct device *dev, return reg_value; } -static struct scsi_host_template ahci_platform_sht = { +static const struct scsi_host_template ahci_platform_sht = { AHCI_SHT(DRV_NAME), }; diff --git a/drivers/ata/ahci_mtk.c b/drivers/ata/ahci_mtk.c index 5714efe3f8e7..0bf83a297091 100644 --- a/drivers/ata/ahci_mtk.c +++ b/drivers/ata/ahci_mtk.c @@ -37,7 +37,7 @@ static const struct ata_port_info ahci_port_info = { .port_ops = &ahci_platform_ops, }; -static struct scsi_host_template ahci_platform_sht = { +static const struct scsi_host_template ahci_platform_sht = { AHCI_SHT(DRV_NAME), }; diff --git a/drivers/ata/ahci_mvebu.c b/drivers/ata/ahci_mvebu.c index 22ecc4f3ae79..596cf017f427 100644 --- a/drivers/ata/ahci_mvebu.c +++ b/drivers/ata/ahci_mvebu.c @@ -178,7 +178,7 @@ static const struct ata_port_info ahci_mvebu_port_info = { .port_ops = &ahci_platform_ops, }; -static struct scsi_host_template ahci_platform_sht = { +static const struct scsi_host_template ahci_platform_sht = { AHCI_SHT(DRV_NAME), }; diff --git a/drivers/ata/ahci_platform.c b/drivers/ata/ahci_platform.c index 8f5572a9f8f1..299ee686ac49 100644 --- a/drivers/ata/ahci_platform.c +++ b/drivers/ata/ahci_platform.c @@ -36,7 +36,7 @@ static const struct ata_port_info ahci_port_info_nolpm = { .port_ops = &ahci_platform_ops, }; -static struct scsi_host_template ahci_platform_sht = { +static const struct scsi_host_template ahci_platform_sht = { AHCI_SHT(DRV_NAME), }; diff --git a/drivers/ata/ahci_qoriq.c b/drivers/ata/ahci_qoriq.c index 9cf9bf36a874..0ba764d283c8 100644 --- a/drivers/ata/ahci_qoriq.c +++ b/drivers/ata/ahci_qoriq.c @@ -159,7 +159,7 @@ static const struct ata_port_info ahci_qoriq_port_info = { .port_ops = &ahci_qoriq_ops, }; -static struct scsi_host_template ahci_qoriq_sht = { +static const struct scsi_host_template ahci_qoriq_sht = { AHCI_SHT(DRV_NAME), }; diff --git a/drivers/ata/ahci_seattle.c b/drivers/ata/ahci_seattle.c index ced12705ed9d..9eda7bbd2151 100644 --- a/drivers/ata/ahci_seattle.c +++ b/drivers/ata/ahci_seattle.c @@ -72,7 +72,7 @@ static const struct ata_port_info ahci_port_seattle_info = { .port_ops = &ahci_seattle_ops, }; -static struct scsi_host_template ahci_platform_sht = { +static const struct scsi_host_template ahci_platform_sht = { AHCI_SHT(DRV_NAME), }; diff --git a/drivers/ata/ahci_st.c b/drivers/ata/ahci_st.c index 8607b68eee53..f2c1edb36986 100644 --- a/drivers/ata/ahci_st.c +++ b/drivers/ata/ahci_st.c @@ -138,7 +138,7 @@ static const struct ata_port_info st_ahci_port_info = { .port_ops = &st_ahci_port_ops, }; -static struct scsi_host_template ahci_platform_sht = { +static const struct scsi_host_template ahci_platform_sht = { AHCI_SHT(DRV_NAME), }; diff --git a/drivers/ata/ahci_sunxi.c b/drivers/ata/ahci_sunxi.c index c7273c1cb0c7..076c12b4ba08 100644 --- a/drivers/ata/ahci_sunxi.c +++ b/drivers/ata/ahci_sunxi.c @@ -206,7 +206,7 @@ static const struct ata_port_info ahci_sunxi_port_info = { .port_ops = &ahci_platform_ops, }; -static struct scsi_host_template ahci_platform_sht = { +static const struct scsi_host_template ahci_platform_sht = { AHCI_SHT(DRV_NAME), }; diff --git a/drivers/ata/ahci_tegra.c b/drivers/ata/ahci_tegra.c index 4fb94db1217d..8e5e2b359f2d 100644 --- a/drivers/ata/ahci_tegra.c +++ b/drivers/ata/ahci_tegra.c @@ -506,7 +506,7 @@ static const struct of_device_id tegra_ahci_of_match[] = { }; MODULE_DEVICE_TABLE(of, tegra_ahci_of_match); -static struct scsi_host_template ahci_platform_sht = { +static const struct scsi_host_template ahci_platform_sht = { AHCI_SHT(DRV_NAME), }; diff --git a/drivers/ata/ahci_xgene.c b/drivers/ata/ahci_xgene.c index 1e08704d5117..83f5ff54ef5b 100644 --- a/drivers/ata/ahci_xgene.c +++ b/drivers/ata/ahci_xgene.c @@ -710,7 +710,7 @@ static int xgene_ahci_mux_select(struct xgene_ahci_context *ctx) return val & CFG_SATA_ENET_SELECT_MASK ? -1 : 0; } -static struct scsi_host_template ahci_platform_sht = { +static const struct scsi_host_template ahci_platform_sht = { AHCI_SHT(DRV_NAME), }; diff --git a/drivers/ata/ata_generic.c b/drivers/ata/ata_generic.c index 20a32e4d501d..2f57ec00ab82 100644 --- a/drivers/ata/ata_generic.c +++ b/drivers/ata/ata_generic.c @@ -95,7 +95,7 @@ static int generic_set_mode(struct ata_link *link, struct ata_device **unused) return 0; } -static struct scsi_host_template generic_sht = { +static const struct scsi_host_template generic_sht = { ATA_BMDMA_SHT(DRV_NAME), }; diff --git a/drivers/ata/ata_piix.c b/drivers/ata/ata_piix.c index ade5e894563b..ec3c5bd1f813 100644 --- a/drivers/ata/ata_piix.c +++ b/drivers/ata/ata_piix.c @@ -1059,7 +1059,7 @@ static u8 piix_vmw_bmdma_status(struct ata_port *ap) return ata_bmdma_status(ap) & ~ATA_DMA_ERR; } -static struct scsi_host_template piix_sht = { +static const struct scsi_host_template piix_sht = { ATA_BMDMA_SHT(DRV_NAME), }; @@ -1095,7 +1095,7 @@ static struct attribute *piix_sidpr_shost_attrs[] = { ATTRIBUTE_GROUPS(piix_sidpr_shost); -static struct scsi_host_template piix_sidpr_sht = { +static const struct scsi_host_template piix_sidpr_sht = { ATA_BMDMA_SHT(DRV_NAME), .shost_groups = piix_sidpr_shost_groups, }; @@ -1645,7 +1645,7 @@ static int piix_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) struct device *dev = &pdev->dev; struct ata_port_info port_info[2]; const struct ata_port_info *ppi[] = { &port_info[0], &port_info[1] }; - struct scsi_host_template *sht = &piix_sht; + const struct scsi_host_template *sht = &piix_sht; unsigned long port_flags; struct ata_host *host; struct piix_host_priv *hpriv; diff --git a/drivers/ata/libahci.c b/drivers/ata/libahci.c index 8f216de76648..9c2cb6cbea76 100644 --- a/drivers/ata/libahci.c +++ b/drivers/ata/libahci.c @@ -2692,7 +2692,7 @@ void ahci_set_em_messages(struct ahci_host_priv *hpriv, EXPORT_SYMBOL_GPL(ahci_set_em_messages); static int ahci_host_activate_multi_irqs(struct ata_host *host, - struct scsi_host_template *sht) + const struct scsi_host_template *sht) { struct ahci_host_priv *hpriv = host->private_data; int i, rc; @@ -2736,7 +2736,7 @@ static int ahci_host_activate_multi_irqs(struct ata_host *host, * RETURNS: * 0 on success, -errno otherwise. */ -int ahci_host_activate(struct ata_host *host, struct scsi_host_template *sht) +int ahci_host_activate(struct ata_host *host, const struct scsi_host_template *sht) { struct ahci_host_priv *hpriv = host->private_data; int irq = hpriv->irq; diff --git a/drivers/ata/libahci_platform.c b/drivers/ata/libahci_platform.c index f00da19670b0..9a8d43f54adc 100644 --- a/drivers/ata/libahci_platform.c +++ b/drivers/ata/libahci_platform.c @@ -680,7 +680,7 @@ EXPORT_SYMBOL_GPL(ahci_platform_get_resources); int ahci_platform_init_host(struct platform_device *pdev, struct ahci_host_priv *hpriv, const struct ata_port_info *pi_template, - struct scsi_host_template *sht) + const struct scsi_host_template *sht) { struct device *dev = &pdev->dev; struct ata_port_info pi = *pi_template; diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 14c17c3bda4e..8bf612bdd61a 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -5775,7 +5775,7 @@ static void async_port_probe(void *data, async_cookie_t cookie) * RETURNS: * 0 on success, -errno otherwise. */ -int ata_host_register(struct ata_host *host, struct scsi_host_template *sht) +int ata_host_register(struct ata_host *host, const struct scsi_host_template *sht) { int i, rc; @@ -5883,7 +5883,7 @@ EXPORT_SYMBOL_GPL(ata_host_register); */ int ata_host_activate(struct ata_host *host, int irq, irq_handler_t irq_handler, unsigned long irq_flags, - struct scsi_host_template *sht) + const struct scsi_host_template *sht) { int i, rc; char *irq_desc; diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index e093c7a7deeb..7bb12deab70c 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -4186,7 +4186,7 @@ void ata_scsi_simulate(struct ata_device *dev, struct scsi_cmnd *cmd) scsi_done(cmd); } -int ata_scsi_add_hosts(struct ata_host *host, struct scsi_host_template *sht) +int ata_scsi_add_hosts(struct ata_host *host, const struct scsi_host_template *sht) { int i, rc; diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c index cd82d3b5ed14..9d28badfe41d 100644 --- a/drivers/ata/libata-sff.c +++ b/drivers/ata/libata-sff.c @@ -2281,7 +2281,7 @@ EXPORT_SYMBOL_GPL(ata_pci_sff_prepare_host); */ int ata_pci_sff_activate_host(struct ata_host *host, irq_handler_t irq_handler, - struct scsi_host_template *sht) + const struct scsi_host_template *sht) { struct device *dev = host->dev; struct pci_dev *pdev = to_pci_dev(dev); @@ -2378,7 +2378,7 @@ static const struct ata_port_info *ata_sff_find_valid_pi( static int ata_pci_init_one(struct pci_dev *pdev, const struct ata_port_info * const *ppi, - struct scsi_host_template *sht, void *host_priv, + const struct scsi_host_template *sht, void *host_priv, int hflags, bool bmdma) { struct device *dev = &pdev->dev; @@ -2452,7 +2452,7 @@ out: */ int ata_pci_sff_init_one(struct pci_dev *pdev, const struct ata_port_info * const *ppi, - struct scsi_host_template *sht, void *host_priv, int hflag) + const struct scsi_host_template *sht, void *host_priv, int hflag) { return ata_pci_init_one(pdev, ppi, sht, host_priv, hflag, 0); } @@ -3175,7 +3175,7 @@ EXPORT_SYMBOL_GPL(ata_pci_bmdma_prepare_host); */ int ata_pci_bmdma_init_one(struct pci_dev *pdev, const struct ata_port_info * const * ppi, - struct scsi_host_template *sht, void *host_priv, + const struct scsi_host_template *sht, void *host_priv, int hflags) { return ata_pci_init_one(pdev, ppi, sht, host_priv, hflags, 1); diff --git a/drivers/ata/libata.h b/drivers/ata/libata.h index 2cd6124a01e8..926d0d33cd29 100644 --- a/drivers/ata/libata.h +++ b/drivers/ata/libata.h @@ -111,7 +111,7 @@ static inline void ata_acpi_bind_dev(struct ata_device *dev) {} extern struct ata_device *ata_scsi_find_dev(struct ata_port *ap, const struct scsi_device *scsidev); extern int ata_scsi_add_hosts(struct ata_host *host, - struct scsi_host_template *sht); + const struct scsi_host_template *sht); extern void ata_scsi_scan_host(struct ata_port *ap, int sync); extern int ata_scsi_offline_dev(struct ata_device *dev); extern bool ata_scsi_sense_is_valid(u8 sk, u8 asc, u8 ascq); diff --git a/drivers/ata/pata_acpi.c b/drivers/ata/pata_acpi.c index f8706ee427d2..ab38871b5e00 100644 --- a/drivers/ata/pata_acpi.c +++ b/drivers/ata/pata_acpi.c @@ -205,7 +205,7 @@ static int pacpi_port_start(struct ata_port *ap) return ata_bmdma_port_start(ap); } -static struct scsi_host_template pacpi_sht = { +static const struct scsi_host_template pacpi_sht = { ATA_BMDMA_SHT(DRV_NAME), }; diff --git a/drivers/ata/pata_ali.c b/drivers/ata/pata_ali.c index 76ad0e73fe2a..bb790edd6036 100644 --- a/drivers/ata/pata_ali.c +++ b/drivers/ata/pata_ali.c @@ -355,7 +355,7 @@ static void ali_c2_c3_postreset(struct ata_link *link, unsigned int *classes) ata_sff_postreset(link, classes); } -static struct scsi_host_template ali_sht = { +static const struct scsi_host_template ali_sht = { ATA_BMDMA_SHT(DRV_NAME), }; diff --git a/drivers/ata/pata_amd.c b/drivers/ata/pata_amd.c index f216f9d7b9ec..5b02b89748b7 100644 --- a/drivers/ata/pata_amd.c +++ b/drivers/ata/pata_amd.c @@ -388,7 +388,7 @@ static void nv_host_stop(struct ata_host *host) pci_write_config_dword(to_pci_dev(host->dev), 0x60, udma); } -static struct scsi_host_template amd_sht = { +static const struct scsi_host_template amd_sht = { ATA_BMDMA_SHT(DRV_NAME), }; diff --git a/drivers/ata/pata_arasan_cf.c b/drivers/ata/pata_arasan_cf.c index e89617ed9175..6ab294322e79 100644 --- a/drivers/ata/pata_arasan_cf.c +++ b/drivers/ata/pata_arasan_cf.c @@ -218,7 +218,7 @@ struct arasan_cf_dev { struct ata_queued_cmd *qc; }; -static struct scsi_host_template arasan_cf_sht = { +static const struct scsi_host_template arasan_cf_sht = { ATA_BASE_SHT(DRIVER_NAME), .dma_boundary = 0xFFFFFFFFUL, }; diff --git a/drivers/ata/pata_artop.c b/drivers/ata/pata_artop.c index 20a8f31a3f57..40544282f455 100644 --- a/drivers/ata/pata_artop.c +++ b/drivers/ata/pata_artop.c @@ -292,7 +292,7 @@ static int artop6210_qc_defer(struct ata_queued_cmd *qc) return 0; } -static struct scsi_host_template artop_sht = { +static const struct scsi_host_template artop_sht = { ATA_BMDMA_SHT(DRV_NAME), }; diff --git a/drivers/ata/pata_atiixp.c b/drivers/ata/pata_atiixp.c index efdb94cff68b..8c5cc803aab3 100644 --- a/drivers/ata/pata_atiixp.c +++ b/drivers/ata/pata_atiixp.c @@ -251,7 +251,7 @@ static void atiixp_bmdma_stop(struct ata_queued_cmd *qc) ata_bmdma_stop(qc); } -static struct scsi_host_template atiixp_sht = { +static const struct scsi_host_template atiixp_sht = { ATA_BASE_SHT(DRV_NAME), .sg_tablesize = LIBATA_DUMB_MAX_PRD, .dma_boundary = ATA_DMA_BOUNDARY, diff --git a/drivers/ata/pata_atp867x.c b/drivers/ata/pata_atp867x.c index 779d660415c8..aaef5924f636 100644 --- a/drivers/ata/pata_atp867x.c +++ b/drivers/ata/pata_atp867x.c @@ -259,7 +259,7 @@ static int atp867x_cable_detect(struct ata_port *ap) return ATA_CBL_PATA_UNK; } -static struct scsi_host_template atp867x_sht = { +static const struct scsi_host_template atp867x_sht = { ATA_BMDMA_SHT(DRV_NAME), }; diff --git a/drivers/ata/pata_buddha.c b/drivers/ata/pata_buddha.c index 27d4c417fc60..49bc619b83e2 100644 --- a/drivers/ata/pata_buddha.c +++ b/drivers/ata/pata_buddha.c @@ -57,7 +57,7 @@ static unsigned int xsurf_bases[2] = { XSURF_BASE1, XSURF_BASE2 }; -static struct scsi_host_template pata_buddha_sht = { +static const struct scsi_host_template pata_buddha_sht = { ATA_PIO_SHT(DRV_NAME), }; diff --git a/drivers/ata/pata_cmd640.c b/drivers/ata/pata_cmd640.c index 1a3372a72213..45a7217b136e 100644 --- a/drivers/ata/pata_cmd640.c +++ b/drivers/ata/pata_cmd640.c @@ -172,7 +172,7 @@ static bool cmd640_sff_irq_check(struct ata_port *ap) return irq_stat & irq_mask; } -static struct scsi_host_template cmd640_sht = { +static const struct scsi_host_template cmd640_sht = { ATA_PIO_SHT(DRV_NAME), }; diff --git a/drivers/ata/pata_cmd64x.c b/drivers/ata/pata_cmd64x.c index 5baa4a7819c1..fafea2b79145 100644 --- a/drivers/ata/pata_cmd64x.c +++ b/drivers/ata/pata_cmd64x.c @@ -319,7 +319,7 @@ static void cmd646r1_bmdma_stop(struct ata_queued_cmd *qc) ata_bmdma_stop(qc); } -static struct scsi_host_template cmd64x_sht = { +static const struct scsi_host_template cmd64x_sht = { ATA_BMDMA_SHT(DRV_NAME), }; diff --git a/drivers/ata/pata_cs5520.c b/drivers/ata/pata_cs5520.c index f4289a532f87..422d42761a1d 100644 --- a/drivers/ata/pata_cs5520.c +++ b/drivers/ata/pata_cs5520.c @@ -94,7 +94,7 @@ static void cs5520_set_piomode(struct ata_port *ap, struct ata_device *adev) cs5520_set_timings(ap, adev, adev->pio_mode); } -static struct scsi_host_template cs5520_sht = { +static const struct scsi_host_template cs5520_sht = { ATA_BASE_SHT(DRV_NAME), .sg_tablesize = LIBATA_DUMB_MAX_PRD, .dma_boundary = ATA_DMA_BOUNDARY, diff --git a/drivers/ata/pata_cs5530.c b/drivers/ata/pata_cs5530.c index d5b7ac14e78f..1e67b0f8db43 100644 --- a/drivers/ata/pata_cs5530.c +++ b/drivers/ata/pata_cs5530.c @@ -146,7 +146,7 @@ static unsigned int cs5530_qc_issue(struct ata_queued_cmd *qc) return ata_bmdma_qc_issue(qc); } -static struct scsi_host_template cs5530_sht = { +static const struct scsi_host_template cs5530_sht = { ATA_BASE_SHT(DRV_NAME), .sg_tablesize = LIBATA_DUMB_MAX_PRD, .dma_boundary = ATA_DMA_BOUNDARY, diff --git a/drivers/ata/pata_cs5535.c b/drivers/ata/pata_cs5535.c index c2c3238ff84b..d793fc441b46 100644 --- a/drivers/ata/pata_cs5535.c +++ b/drivers/ata/pata_cs5535.c @@ -141,7 +141,7 @@ static void cs5535_set_dmamode(struct ata_port *ap, struct ata_device *adev) wrmsr(ATAC_CH0D0_DMA + 2 * adev->devno, reg, 0); } -static struct scsi_host_template cs5535_sht = { +static const struct scsi_host_template cs5535_sht = { ATA_BMDMA_SHT(DRV_NAME), }; diff --git a/drivers/ata/pata_cs5536.c b/drivers/ata/pata_cs5536.c index ab47aeb5587f..b811efd2cc34 100644 --- a/drivers/ata/pata_cs5536.c +++ b/drivers/ata/pata_cs5536.c @@ -217,7 +217,7 @@ static void cs5536_set_dmamode(struct ata_port *ap, struct ata_device *adev) cs5536_write(pdev, ETC, etc); } -static struct scsi_host_template cs5536_sht = { +static const struct scsi_host_template cs5536_sht = { ATA_BMDMA_SHT(DRV_NAME), }; diff --git a/drivers/ata/pata_cypress.c b/drivers/ata/pata_cypress.c index 3be5d52a777b..ae347b5c2871 100644 --- a/drivers/ata/pata_cypress.c +++ b/drivers/ata/pata_cypress.c @@ -115,7 +115,7 @@ static void cy82c693_set_dmamode(struct ata_port *ap, struct ata_device *adev) outb(0x50, 0x23); } -static struct scsi_host_template cy82c693_sht = { +static const struct scsi_host_template cy82c693_sht = { ATA_BMDMA_SHT(DRV_NAME), }; diff --git a/drivers/ata/pata_efar.c b/drivers/ata/pata_efar.c index 21da59f35b41..2e6eccf2902f 100644 --- a/drivers/ata/pata_efar.c +++ b/drivers/ata/pata_efar.c @@ -234,7 +234,7 @@ static void efar_set_dmamode (struct ata_port *ap, struct ata_device *adev) spin_unlock_irqrestore(&efar_lock, flags); } -static struct scsi_host_template efar_sht = { +static const struct scsi_host_template efar_sht = { ATA_BMDMA_SHT(DRV_NAME), }; diff --git a/drivers/ata/pata_ep93xx.c b/drivers/ata/pata_ep93xx.c index 47845d920075..c6e043e05d43 100644 --- a/drivers/ata/pata_ep93xx.c +++ b/drivers/ata/pata_ep93xx.c @@ -872,7 +872,7 @@ static int ep93xx_pata_port_start(struct ata_port *ap) return 0; } -static struct scsi_host_template ep93xx_pata_sht = { +static const struct scsi_host_template ep93xx_pata_sht = { ATA_BASE_SHT(DRV_NAME), /* ep93xx dma implementation limit */ .sg_tablesize = 32, diff --git a/drivers/ata/pata_falcon.c b/drivers/ata/pata_falcon.c index 823c88622e34..996516e64f13 100644 --- a/drivers/ata/pata_falcon.c +++ b/drivers/ata/pata_falcon.c @@ -33,7 +33,7 @@ #define DRV_NAME "pata_falcon" #define DRV_VERSION "0.1.0" -static struct scsi_host_template pata_falcon_sht = { +static const struct scsi_host_template pata_falcon_sht = { ATA_PIO_SHT(DRV_NAME), }; diff --git a/drivers/ata/pata_ftide010.c b/drivers/ata/pata_ftide010.c index 88924b5daa1a..6f6734c09b11 100644 --- a/drivers/ata/pata_ftide010.c +++ b/drivers/ata/pata_ftide010.c @@ -84,7 +84,7 @@ struct ftide010 { #define FTIDE010_CLK_MOD_DEV0_UDMA_EN BIT(4) #define FTIDE010_CLK_MOD_DEV1_UDMA_EN BIT(5) -static struct scsi_host_template pata_ftide010_sht = { +static const struct scsi_host_template pata_ftide010_sht = { ATA_BMDMA_SHT(DRV_NAME), }; diff --git a/drivers/ata/pata_gayle.c b/drivers/ata/pata_gayle.c index 65bc9f3042ce..e5aa07f92106 100644 --- a/drivers/ata/pata_gayle.c +++ b/drivers/ata/pata_gayle.c @@ -35,7 +35,7 @@ #define GAYLE_CONTROL 0x101a -static struct scsi_host_template pata_gayle_sht = { +static const struct scsi_host_template pata_gayle_sht = { ATA_PIO_SHT(DRV_NAME), }; diff --git a/drivers/ata/pata_hpt366.c b/drivers/ata/pata_hpt366.c index 7e441fb304d3..bdccd1ba1524 100644 --- a/drivers/ata/pata_hpt366.c +++ b/drivers/ata/pata_hpt366.c @@ -312,7 +312,7 @@ static int hpt366_prereset(struct ata_link *link, unsigned long deadline) return ata_sff_prereset(link, deadline); } -static struct scsi_host_template hpt36x_sht = { +static const struct scsi_host_template hpt36x_sht = { ATA_BMDMA_SHT(DRV_NAME), }; diff --git a/drivers/ata/pata_hpt37x.c b/drivers/ata/pata_hpt37x.c index ce3c5eaa7e76..c0329cf01135 100644 --- a/drivers/ata/pata_hpt37x.c +++ b/drivers/ata/pata_hpt37x.c @@ -526,7 +526,7 @@ static void hpt37x_bmdma_stop(struct ata_queued_cmd *qc) } -static struct scsi_host_template hpt37x_sht = { +static const struct scsi_host_template hpt37x_sht = { ATA_BMDMA_SHT(DRV_NAME), }; diff --git a/drivers/ata/pata_hpt3x2n.c b/drivers/ata/pata_hpt3x2n.c index 617c95522f43..5b1ecccf3c83 100644 --- a/drivers/ata/pata_hpt3x2n.c +++ b/drivers/ata/pata_hpt3x2n.c @@ -337,7 +337,7 @@ static unsigned int hpt3x2n_qc_issue(struct ata_queued_cmd *qc) return ata_bmdma_qc_issue(qc); } -static struct scsi_host_template hpt3x2n_sht = { +static const struct scsi_host_template hpt3x2n_sht = { ATA_BMDMA_SHT(DRV_NAME), }; diff --git a/drivers/ata/pata_hpt3x3.c b/drivers/ata/pata_hpt3x3.c index 83974d5eb387..d65c586b5ad0 100644 --- a/drivers/ata/pata_hpt3x3.c +++ b/drivers/ata/pata_hpt3x3.c @@ -136,7 +136,7 @@ static int hpt3x3_atapi_dma(struct ata_queued_cmd *qc) #endif /* CONFIG_PATA_HPT3X3_DMA */ -static struct scsi_host_template hpt3x3_sht = { +static const struct scsi_host_template hpt3x3_sht = { ATA_BMDMA_SHT(DRV_NAME), }; diff --git a/drivers/ata/pata_icside.c b/drivers/ata/pata_icside.c index 498383cb6e29..9cfb064782c3 100644 --- a/drivers/ata/pata_icside.c +++ b/drivers/ata/pata_icside.c @@ -298,7 +298,7 @@ static int icside_dma_init(struct pata_icside_info *info) } -static struct scsi_host_template pata_icside_sht = { +static const struct scsi_host_template pata_icside_sht = { ATA_BASE_SHT(DRV_NAME), .sg_tablesize = SG_MAX_SEGMENTS, .dma_boundary = IOMD_DMA_BOUNDARY, diff --git a/drivers/ata/pata_imx.c b/drivers/ata/pata_imx.c index 150939275b1b..4013f28679a9 100644 --- a/drivers/ata/pata_imx.c +++ b/drivers/ata/pata_imx.c @@ -97,7 +97,7 @@ static void pata_imx_set_piomode(struct ata_port *ap, struct ata_device *adev) __raw_writel(val, priv->host_regs + PATA_IMX_ATA_CONTROL); } -static struct scsi_host_template pata_imx_sht = { +static const struct scsi_host_template pata_imx_sht = { ATA_PIO_SHT(DRV_NAME), }; diff --git a/drivers/ata/pata_isapnp.c b/drivers/ata/pata_isapnp.c index 43bb224430d3..25a63d043c8e 100644 --- a/drivers/ata/pata_isapnp.c +++ b/drivers/ata/pata_isapnp.c @@ -20,7 +20,7 @@ #define DRV_NAME "pata_isapnp" #define DRV_VERSION "0.2.5" -static struct scsi_host_template isapnp_sht = { +static const struct scsi_host_template isapnp_sht = { ATA_PIO_SHT(DRV_NAME), }; diff --git a/drivers/ata/pata_it8213.c b/drivers/ata/pata_it8213.c index 8a3e8778163c..b7ac56103c8a 100644 --- a/drivers/ata/pata_it8213.c +++ b/drivers/ata/pata_it8213.c @@ -228,7 +228,7 @@ static void it8213_set_dmamode (struct ata_port *ap, struct ata_device *adev) pci_write_config_byte(dev, 0x48, udma_enable); } -static struct scsi_host_template it8213_sht = { +static const struct scsi_host_template it8213_sht = { ATA_BMDMA_SHT(DRV_NAME), }; diff --git a/drivers/ata/pata_it821x.c b/drivers/ata/pata_it821x.c index 8a5b4e0079ab..2fe3fb6102ce 100644 --- a/drivers/ata/pata_it821x.c +++ b/drivers/ata/pata_it821x.c @@ -800,7 +800,7 @@ static int it821x_rdc_cable(struct ata_port *ap) return ATA_CBL_PATA80; } -static struct scsi_host_template it821x_sht = { +static const struct scsi_host_template it821x_sht = { ATA_BMDMA_SHT(DRV_NAME), }; diff --git a/drivers/ata/pata_ixp4xx_cf.c b/drivers/ata/pata_ixp4xx_cf.c index 113087665832..99a2ce723495 100644 --- a/drivers/ata/pata_ixp4xx_cf.c +++ b/drivers/ata/pata_ixp4xx_cf.c @@ -174,7 +174,7 @@ static unsigned int ixp4xx_mmio_data_xfer(struct ata_queued_cmd *qc, return words << 1; } -static struct scsi_host_template ixp4xx_sht = { +static const struct scsi_host_template ixp4xx_sht = { ATA_PIO_SHT(DRV_NAME), }; diff --git a/drivers/ata/pata_jmicron.c b/drivers/ata/pata_jmicron.c index d1b3ce8958dd..f51fb8219762 100644 --- a/drivers/ata/pata_jmicron.c +++ b/drivers/ata/pata_jmicron.c @@ -107,7 +107,7 @@ static int jmicron_pre_reset(struct ata_link *link, unsigned long deadline) /* No PIO or DMA methods needed for this device */ -static struct scsi_host_template jmicron_sht = { +static const struct scsi_host_template jmicron_sht = { ATA_BMDMA_SHT(DRV_NAME), }; diff --git a/drivers/ata/pata_legacy.c b/drivers/ata/pata_legacy.c index 03c580625c2c..448a511cbc17 100644 --- a/drivers/ata/pata_legacy.c +++ b/drivers/ata/pata_legacy.c @@ -250,7 +250,7 @@ static int legacy_set_mode(struct ata_link *link, struct ata_device **unused) return 0; } -static struct scsi_host_template legacy_sht = { +static const struct scsi_host_template legacy_sht = { ATA_PIO_SHT(DRV_NAME), }; diff --git a/drivers/ata/pata_macio.c b/drivers/ata/pata_macio.c index 335e339a7ada..17f6ccee53c7 100644 --- a/drivers/ata/pata_macio.c +++ b/drivers/ata/pata_macio.c @@ -909,7 +909,7 @@ static int pata_macio_do_resume(struct pata_macio_priv *priv) } #endif /* CONFIG_PM_SLEEP */ -static struct scsi_host_template pata_macio_sht = { +static const struct scsi_host_template pata_macio_sht = { __ATA_BASE_SHT(DRV_NAME), .sg_tablesize = MAX_DCMDS, /* We may not need that strict one */ diff --git a/drivers/ata/pata_marvell.c b/drivers/ata/pata_marvell.c index 014ccb0f45dc..8119caaad605 100644 --- a/drivers/ata/pata_marvell.c +++ b/drivers/ata/pata_marvell.c @@ -92,7 +92,7 @@ static int marvell_cable_detect(struct ata_port *ap) /* No PIO or DMA methods needed for this device */ -static struct scsi_host_template marvell_sht = { +static const struct scsi_host_template marvell_sht = { ATA_BMDMA_SHT(DRV_NAME), }; diff --git a/drivers/ata/pata_mpc52xx.c b/drivers/ata/pata_mpc52xx.c index 3ebd6522a1fd..66c9dea4ea6e 100644 --- a/drivers/ata/pata_mpc52xx.c +++ b/drivers/ata/pata_mpc52xx.c @@ -606,7 +606,7 @@ mpc52xx_ata_task_irq(int irq, void *vpriv) return IRQ_HANDLED; } -static struct scsi_host_template mpc52xx_ata_sht = { +static const struct scsi_host_template mpc52xx_ata_sht = { ATA_PIO_SHT(DRV_NAME), }; diff --git a/drivers/ata/pata_mpiix.c b/drivers/ata/pata_mpiix.c index 8fda0e32c1ab..69e4baf27d72 100644 --- a/drivers/ata/pata_mpiix.c +++ b/drivers/ata/pata_mpiix.c @@ -136,7 +136,7 @@ static unsigned int mpiix_qc_issue(struct ata_queued_cmd *qc) return ata_sff_qc_issue(qc); } -static struct scsi_host_template mpiix_sht = { +static const struct scsi_host_template mpiix_sht = { ATA_PIO_SHT(DRV_NAME), }; diff --git a/drivers/ata/pata_netcell.c b/drivers/ata/pata_netcell.c index 06929e77c491..c0b2897fcf40 100644 --- a/drivers/ata/pata_netcell.c +++ b/drivers/ata/pata_netcell.c @@ -31,7 +31,7 @@ static unsigned int netcell_read_id(struct ata_device *adev, return err_mask; } -static struct scsi_host_template netcell_sht = { +static const struct scsi_host_template netcell_sht = { ATA_BMDMA_SHT(DRV_NAME), }; diff --git a/drivers/ata/pata_ninja32.c b/drivers/ata/pata_ninja32.c index f9255d6fd194..76a91013d27d 100644 --- a/drivers/ata/pata_ninja32.c +++ b/drivers/ata/pata_ninja32.c @@ -77,7 +77,7 @@ static void ninja32_dev_select(struct ata_port *ap, unsigned int device) } } -static struct scsi_host_template ninja32_sht = { +static const struct scsi_host_template ninja32_sht = { ATA_BMDMA_SHT(DRV_NAME), }; diff --git a/drivers/ata/pata_ns87410.c b/drivers/ata/pata_ns87410.c index ca3ab2736fef..44cc24d21d5f 100644 --- a/drivers/ata/pata_ns87410.c +++ b/drivers/ata/pata_ns87410.c @@ -114,7 +114,7 @@ static unsigned int ns87410_qc_issue(struct ata_queued_cmd *qc) return ata_sff_qc_issue(qc); } -static struct scsi_host_template ns87410_sht = { +static const struct scsi_host_template ns87410_sht = { ATA_PIO_SHT(DRV_NAME), }; diff --git a/drivers/ata/pata_ns87415.c b/drivers/ata/pata_ns87415.c index 9dd6bffefb48..d60e1f69d7b0 100644 --- a/drivers/ata/pata_ns87415.c +++ b/drivers/ata/pata_ns87415.c @@ -320,7 +320,7 @@ static struct ata_port_operations ns87560_pata_ops = { }; #endif -static struct scsi_host_template ns87415_sht = { +static const struct scsi_host_template ns87415_sht = { ATA_BMDMA_SHT(DRV_NAME), }; diff --git a/drivers/ata/pata_octeon_cf.c b/drivers/ata/pata_octeon_cf.c index 4cbcdc5da038..b1ce9f1761af 100644 --- a/drivers/ata/pata_octeon_cf.c +++ b/drivers/ata/pata_octeon_cf.c @@ -58,7 +58,7 @@ struct octeon_cf_port { u64 dma_base; }; -static struct scsi_host_template octeon_cf_sht = { +static const struct scsi_host_template octeon_cf_sht = { ATA_PIO_SHT(DRV_NAME), }; diff --git a/drivers/ata/pata_of_platform.c b/drivers/ata/pata_of_platform.c index ac5a633c00a5..178b28eff170 100644 --- a/drivers/ata/pata_of_platform.c +++ b/drivers/ata/pata_of_platform.c @@ -15,7 +15,7 @@ #define DRV_NAME "pata_of_platform" -static struct scsi_host_template pata_platform_sht = { +static const struct scsi_host_template pata_platform_sht = { ATA_PIO_SHT(DRV_NAME), }; diff --git a/drivers/ata/pata_oldpiix.c b/drivers/ata/pata_oldpiix.c index 22a020374410..dca82d92b004 100644 --- a/drivers/ata/pata_oldpiix.c +++ b/drivers/ata/pata_oldpiix.c @@ -204,7 +204,7 @@ static unsigned int oldpiix_qc_issue(struct ata_queued_cmd *qc) } -static struct scsi_host_template oldpiix_sht = { +static const struct scsi_host_template oldpiix_sht = { ATA_BMDMA_SHT(DRV_NAME), }; diff --git a/drivers/ata/pata_opti.c b/drivers/ata/pata_opti.c index 01976c4e4033..3d23f57eb128 100644 --- a/drivers/ata/pata_opti.c +++ b/drivers/ata/pata_opti.c @@ -148,7 +148,7 @@ static void opti_set_piomode(struct ata_port *ap, struct ata_device *adev) opti_write_reg(ap, 0x85, CNTRL_REG); } -static struct scsi_host_template opti_sht = { +static const struct scsi_host_template opti_sht = { ATA_PIO_SHT(DRV_NAME), }; diff --git a/drivers/ata/pata_optidma.c b/drivers/ata/pata_optidma.c index ad1090b90e52..dfc36b4ec9c6 100644 --- a/drivers/ata/pata_optidma.c +++ b/drivers/ata/pata_optidma.c @@ -334,7 +334,7 @@ static int optidma_set_mode(struct ata_link *link, struct ata_device **r_failed) return rc; } -static struct scsi_host_template optidma_sht = { +static const struct scsi_host_template optidma_sht = { ATA_BMDMA_SHT(DRV_NAME), }; diff --git a/drivers/ata/pata_parport/pata_parport.c b/drivers/ata/pata_parport/pata_parport.c index b02a7d16551c..ef2c29a75269 100644 --- a/drivers/ata/pata_parport/pata_parport.c +++ b/drivers/ata/pata_parport/pata_parport.c @@ -399,7 +399,7 @@ static struct device pata_parport_bus = { .release = pata_parport_bus_release, }; -static struct scsi_host_template pata_parport_sht = { +static const struct scsi_host_template pata_parport_sht = { PATA_PARPORT_SHT("pata_parport") }; diff --git a/drivers/ata/pata_pcmcia.c b/drivers/ata/pata_pcmcia.c index 8eb066abbd9c..5b602206c522 100644 --- a/drivers/ata/pata_pcmcia.c +++ b/drivers/ata/pata_pcmcia.c @@ -132,7 +132,7 @@ static void pcmcia_8bit_drain_fifo(struct ata_queued_cmd *qc) } -static struct scsi_host_template pcmcia_sht = { +static const struct scsi_host_template pcmcia_sht = { ATA_PIO_SHT(DRV_NAME), }; diff --git a/drivers/ata/pata_pdc2027x.c b/drivers/ata/pata_pdc2027x.c index 4191aa61c8e4..6820c5597b14 100644 --- a/drivers/ata/pata_pdc2027x.c +++ b/drivers/ata/pata_pdc2027x.c @@ -122,7 +122,7 @@ static struct pci_driver pdc2027x_pci_driver = { #endif }; -static struct scsi_host_template pdc2027x_sht = { +static const struct scsi_host_template pdc2027x_sht = { ATA_BMDMA_SHT(DRV_NAME), }; diff --git a/drivers/ata/pata_pdc202xx_old.c b/drivers/ata/pata_pdc202xx_old.c index f894ff2de0a9..a32723e46357 100644 --- a/drivers/ata/pata_pdc202xx_old.c +++ b/drivers/ata/pata_pdc202xx_old.c @@ -289,7 +289,7 @@ static int pdc2026x_check_atapi_dma(struct ata_queued_cmd *qc) return 1; } -static struct scsi_host_template pdc202xx_sht = { +static const struct scsi_host_template pdc202xx_sht = { ATA_BMDMA_SHT(DRV_NAME), }; diff --git a/drivers/ata/pata_piccolo.c b/drivers/ata/pata_piccolo.c index 389b63b13c70..ced906bf56be 100644 --- a/drivers/ata/pata_piccolo.c +++ b/drivers/ata/pata_piccolo.c @@ -62,7 +62,7 @@ static void tosh_set_dmamode(struct ata_port *ap, struct ata_device *adev) } -static struct scsi_host_template tosh_sht = { +static const struct scsi_host_template tosh_sht = { ATA_BMDMA_SHT(DRV_NAME), }; diff --git a/drivers/ata/pata_platform.c b/drivers/ata/pata_platform.c index 21fb059859bd..87479bc893b2 100644 --- a/drivers/ata/pata_platform.c +++ b/drivers/ata/pata_platform.c @@ -45,7 +45,7 @@ static int pata_platform_set_mode(struct ata_link *link, struct ata_device **unu return 0; } -static struct scsi_host_template pata_platform_sht = { +static const struct scsi_host_template pata_platform_sht = { ATA_PIO_SHT(DRV_NAME), }; @@ -97,7 +97,7 @@ static void pata_platform_setup_port(struct ata_ioports *ioaddr, int __pata_platform_probe(struct device *dev, struct resource *io_res, struct resource *ctl_res, struct resource *irq_res, unsigned int ioport_shift, int __pio_mask, - struct scsi_host_template *sht, bool use16bit) + const struct scsi_host_template *sht, bool use16bit) { struct ata_host *host; struct ata_port *ap; diff --git a/drivers/ata/pata_pxa.c b/drivers/ata/pata_pxa.c index 985f42c4fd70..ea402e02c46e 100644 --- a/drivers/ata/pata_pxa.c +++ b/drivers/ata/pata_pxa.c @@ -136,7 +136,7 @@ static int pxa_check_atapi_dma(struct ata_queued_cmd *qc) return -EOPNOTSUPP; } -static struct scsi_host_template pxa_ata_sht = { +static const struct scsi_host_template pxa_ata_sht = { ATA_BMDMA_SHT(DRV_NAME), }; diff --git a/drivers/ata/pata_radisys.c b/drivers/ata/pata_radisys.c index 3aca8fe3fdb6..84b001097093 100644 --- a/drivers/ata/pata_radisys.c +++ b/drivers/ata/pata_radisys.c @@ -183,7 +183,7 @@ static unsigned int radisys_qc_issue(struct ata_queued_cmd *qc) } -static struct scsi_host_template radisys_sht = { +static const struct scsi_host_template radisys_sht = { ATA_BMDMA_SHT(DRV_NAME), }; diff --git a/drivers/ata/pata_rb532_cf.c b/drivers/ata/pata_rb532_cf.c index 2e110aefe59b..3974d294a341 100644 --- a/drivers/ata/pata_rb532_cf.c +++ b/drivers/ata/pata_rb532_cf.c @@ -73,7 +73,7 @@ static struct ata_port_operations rb532_pata_port_ops = { /* ------------------------------------------------------------------------ */ -static struct scsi_host_template rb532_pata_sht = { +static const struct scsi_host_template rb532_pata_sht = { ATA_PIO_SHT(DRV_NAME), }; diff --git a/drivers/ata/pata_rdc.c b/drivers/ata/pata_rdc.c index ecb229c2c1a2..0a9689862f71 100644 --- a/drivers/ata/pata_rdc.c +++ b/drivers/ata/pata_rdc.c @@ -288,7 +288,7 @@ static const struct ata_port_info rdc_port_info = { .port_ops = &rdc_pata_ops, }; -static struct scsi_host_template rdc_sht = { +static const struct scsi_host_template rdc_sht = { ATA_BMDMA_SHT(DRV_NAME), }; diff --git a/drivers/ata/pata_rz1000.c b/drivers/ata/pata_rz1000.c index fb00c3e5fd19..8e2606793091 100644 --- a/drivers/ata/pata_rz1000.c +++ b/drivers/ata/pata_rz1000.c @@ -50,7 +50,7 @@ static int rz1000_set_mode(struct ata_link *link, struct ata_device **unused) } -static struct scsi_host_template rz1000_sht = { +static const struct scsi_host_template rz1000_sht = { ATA_PIO_SHT(DRV_NAME), }; diff --git a/drivers/ata/pata_sc1200.c b/drivers/ata/pata_sc1200.c index f28daf62a37d..a388dfb97ad8 100644 --- a/drivers/ata/pata_sc1200.c +++ b/drivers/ata/pata_sc1200.c @@ -192,7 +192,7 @@ static int sc1200_qc_defer(struct ata_queued_cmd *qc) return 0; } -static struct scsi_host_template sc1200_sht = { +static const struct scsi_host_template sc1200_sht = { ATA_BASE_SHT(DRV_NAME), .sg_tablesize = LIBATA_DUMB_MAX_PRD, .dma_boundary = ATA_DMA_BOUNDARY, diff --git a/drivers/ata/pata_sch.c b/drivers/ata/pata_sch.c index 4f9c2aefd807..8356f1f2a025 100644 --- a/drivers/ata/pata_sch.c +++ b/drivers/ata/pata_sch.c @@ -57,7 +57,7 @@ static struct pci_driver sch_pci_driver = { #endif }; -static struct scsi_host_template sch_sht = { +static const struct scsi_host_template sch_sht = { ATA_BMDMA_SHT(DRV_NAME), }; diff --git a/drivers/ata/pata_serverworks.c b/drivers/ata/pata_serverworks.c index c0bc4af0d196..549ff24a9823 100644 --- a/drivers/ata/pata_serverworks.c +++ b/drivers/ata/pata_serverworks.c @@ -252,13 +252,13 @@ static void serverworks_set_dmamode(struct ata_port *ap, struct ata_device *adev pci_write_config_byte(pdev, 0x54, ultra_cfg); } -static struct scsi_host_template serverworks_osb4_sht = { +static const struct scsi_host_template serverworks_osb4_sht = { ATA_BASE_SHT(DRV_NAME), .sg_tablesize = LIBATA_DUMB_MAX_PRD, .dma_boundary = ATA_DMA_BOUNDARY, }; -static struct scsi_host_template serverworks_csb_sht = { +static const struct scsi_host_template serverworks_csb_sht = { ATA_BMDMA_SHT(DRV_NAME), }; @@ -413,7 +413,7 @@ static int serverworks_init_one(struct pci_dev *pdev, const struct pci_device_id } }; const struct ata_port_info *ppi[] = { &info[id->driver_data], NULL }; - struct scsi_host_template *sht = &serverworks_csb_sht; + const struct scsi_host_template *sht = &serverworks_csb_sht; int rc; rc = pcim_enable_device(pdev); diff --git a/drivers/ata/pata_sil680.c b/drivers/ata/pata_sil680.c index 67ef2e26d7df..abe64b5f83cf 100644 --- a/drivers/ata/pata_sil680.c +++ b/drivers/ata/pata_sil680.c @@ -223,7 +223,7 @@ static bool sil680_sff_irq_check(struct ata_port *ap) return val & 0x08; } -static struct scsi_host_template sil680_sht = { +static const struct scsi_host_template sil680_sht = { ATA_BMDMA_SHT(DRV_NAME), }; diff --git a/drivers/ata/pata_sis.c b/drivers/ata/pata_sis.c index 92e4cf05de2c..31de06b66221 100644 --- a/drivers/ata/pata_sis.c +++ b/drivers/ata/pata_sis.c @@ -539,7 +539,7 @@ static unsigned int sis_133_mode_filter(struct ata_device *adev, unsigned int ma return mask; } -static struct scsi_host_template sis_sht = { +static const struct scsi_host_template sis_sht = { ATA_BMDMA_SHT(DRV_NAME), }; diff --git a/drivers/ata/pata_sl82c105.c b/drivers/ata/pata_sl82c105.c index 8487470e2e01..3b62ea482f1a 100644 --- a/drivers/ata/pata_sl82c105.c +++ b/drivers/ata/pata_sl82c105.c @@ -238,7 +238,7 @@ static bool sl82c105_sff_irq_check(struct ata_port *ap) return val & mask; } -static struct scsi_host_template sl82c105_sht = { +static const struct scsi_host_template sl82c105_sht = { ATA_BMDMA_SHT(DRV_NAME), }; diff --git a/drivers/ata/pata_triflex.c b/drivers/ata/pata_triflex.c index 782162d2f3f8..26d448a869e2 100644 --- a/drivers/ata/pata_triflex.c +++ b/drivers/ata/pata_triflex.c @@ -160,7 +160,7 @@ static void triflex_bmdma_stop(struct ata_queued_cmd *qc) triflex_load_timing(qc->ap, qc->dev, qc->dev->pio_mode); } -static struct scsi_host_template triflex_sht = { +static const struct scsi_host_template triflex_sht = { ATA_BMDMA_SHT(DRV_NAME), }; diff --git a/drivers/ata/pata_via.c b/drivers/ata/pata_via.c index 34f00f389932..696b99720dcb 100644 --- a/drivers/ata/pata_via.c +++ b/drivers/ata/pata_via.c @@ -443,7 +443,7 @@ static int via_port_start(struct ata_port *ap) return 0; } -static struct scsi_host_template via_sht = { +static const struct scsi_host_template via_sht = { ATA_BMDMA_SHT(DRV_NAME), }; diff --git a/drivers/ata/pdc_adma.c b/drivers/ata/pdc_adma.c index 35b823ac20c9..8e6b2599f0d5 100644 --- a/drivers/ata/pdc_adma.c +++ b/drivers/ata/pdc_adma.c @@ -123,7 +123,7 @@ static void adma_freeze(struct ata_port *ap); static void adma_thaw(struct ata_port *ap); static int adma_prereset(struct ata_link *link, unsigned long deadline); -static struct scsi_host_template adma_ata_sht = { +static const struct scsi_host_template adma_ata_sht = { ATA_BASE_SHT(DRV_NAME), .sg_tablesize = LIBATA_MAX_PRD, .dma_boundary = ADMA_DMA_BOUNDARY, diff --git a/drivers/ata/sata_dwc_460ex.c b/drivers/ata/sata_dwc_460ex.c index 3a30e6eff8a8..fabdd1e380f9 100644 --- a/drivers/ata/sata_dwc_460ex.c +++ b/drivers/ata/sata_dwc_460ex.c @@ -1076,7 +1076,7 @@ static void sata_dwc_dev_select(struct ata_port *ap, unsigned int device) /* * scsi mid-layer and libata interface structures */ -static struct scsi_host_template sata_dwc_sht = { +static const struct scsi_host_template sata_dwc_sht = { ATA_NCQ_SHT(DRV_NAME), /* * test-only: Currently this driver doesn't handle NCQ diff --git a/drivers/ata/sata_fsl.c b/drivers/ata/sata_fsl.c index b052c5a65c17..ccd99b9aa9ff 100644 --- a/drivers/ata/sata_fsl.c +++ b/drivers/ata/sata_fsl.c @@ -1376,7 +1376,7 @@ static void sata_fsl_host_stop(struct ata_host *host) /* * scsi mid-layer and libata interface structures */ -static struct scsi_host_template sata_fsl_sht = { +static const struct scsi_host_template sata_fsl_sht = { ATA_NCQ_SHT_QD("sata_fsl", SATA_FSL_QUEUE_DEPTH), .sg_tablesize = SATA_FSL_MAX_PRD_USABLE, .dma_boundary = ATA_DMA_BOUNDARY, diff --git a/drivers/ata/sata_highbank.c b/drivers/ata/sata_highbank.c index dfbf9493e451..8237ece4a46f 100644 --- a/drivers/ata/sata_highbank.c +++ b/drivers/ata/sata_highbank.c @@ -438,7 +438,7 @@ static const struct ata_port_info ahci_highbank_port_info = { .port_ops = &ahci_highbank_ops, }; -static struct scsi_host_template ahci_highbank_platform_sht = { +static const struct scsi_host_template ahci_highbank_platform_sht = { AHCI_SHT("sata_highbank"), }; diff --git a/drivers/ata/sata_inic162x.c b/drivers/ata/sata_inic162x.c index 2833c722118d..2c8c78ed86c1 100644 --- a/drivers/ata/sata_inic162x.c +++ b/drivers/ata/sata_inic162x.c @@ -242,7 +242,7 @@ struct inic_port_priv { dma_addr_t cpb_tbl_dma; }; -static struct scsi_host_template inic_sht = { +static const struct scsi_host_template inic_sht = { ATA_BASE_SHT(DRV_NAME), .sg_tablesize = LIBATA_MAX_PRD, /* maybe it can be larger? */ diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c index e3cff01201b8..d404e631d152 100644 --- a/drivers/ata/sata_mv.c +++ b/drivers/ata/sata_mv.c @@ -659,13 +659,13 @@ static u8 mv_sff_check_status(struct ata_port *ap); * PRDs for 64K boundaries in mv_fill_sg(). */ #ifdef CONFIG_PCI -static struct scsi_host_template mv5_sht = { +static const struct scsi_host_template mv5_sht = { ATA_BASE_SHT(DRV_NAME), .sg_tablesize = MV_MAX_SG_CT / 2, .dma_boundary = MV_DMA_BOUNDARY, }; #endif -static struct scsi_host_template mv6_sht = { +static const struct scsi_host_template mv6_sht = { __ATA_BASE_SHT(DRV_NAME), .can_queue = MV_MAX_Q_DEPTH - 1, .sg_tablesize = MV_MAX_SG_CT / 2, diff --git a/drivers/ata/sata_nv.c b/drivers/ata/sata_nv.c index 9b2d289e89e1..abf5651c87ab 100644 --- a/drivers/ata/sata_nv.c +++ b/drivers/ata/sata_nv.c @@ -371,11 +371,11 @@ static struct pci_driver nv_pci_driver = { .remove = ata_pci_remove_one, }; -static struct scsi_host_template nv_sht = { +static const struct scsi_host_template nv_sht = { ATA_BMDMA_SHT(DRV_NAME), }; -static struct scsi_host_template nv_adma_sht = { +static const struct scsi_host_template nv_adma_sht = { __ATA_BASE_SHT(DRV_NAME), .can_queue = NV_ADMA_MAX_CPBS, .sg_tablesize = NV_ADMA_SGTBL_TOTAL_LEN, @@ -386,7 +386,7 @@ static struct scsi_host_template nv_adma_sht = { .tag_alloc_policy = BLK_TAG_ALLOC_RR, }; -static struct scsi_host_template nv_swncq_sht = { +static const struct scsi_host_template nv_swncq_sht = { __ATA_BASE_SHT(DRV_NAME), .can_queue = ATA_MAX_QUEUE - 1, .sg_tablesize = LIBATA_MAX_PRD, @@ -520,7 +520,7 @@ static struct ata_port_operations nv_swncq_ops = { struct nv_pi_priv { irq_handler_t irq_handler; - struct scsi_host_template *sht; + const struct scsi_host_template *sht; }; #define NV_PI_PRIV(_irq_handler, _sht) \ diff --git a/drivers/ata/sata_promise.c b/drivers/ata/sata_promise.c index 4e60e6c4c35a..2df1a070b25a 100644 --- a/drivers/ata/sata_promise.c +++ b/drivers/ata/sata_promise.c @@ -158,7 +158,7 @@ static void pdc_error_handler(struct ata_port *ap); static void pdc_post_internal_cmd(struct ata_queued_cmd *qc); static int pdc_pata_cable_detect(struct ata_port *ap); -static struct scsi_host_template pdc_ata_sht = { +static const struct scsi_host_template pdc_ata_sht = { ATA_BASE_SHT(DRV_NAME), .sg_tablesize = PDC_MAX_PRD, .dma_boundary = ATA_DMA_BOUNDARY, diff --git a/drivers/ata/sata_qstor.c b/drivers/ata/sata_qstor.c index 8ca0810aad26..8a6286159044 100644 --- a/drivers/ata/sata_qstor.c +++ b/drivers/ata/sata_qstor.c @@ -108,7 +108,7 @@ static void qs_thaw(struct ata_port *ap); static int qs_prereset(struct ata_link *link, unsigned long deadline); static void qs_error_handler(struct ata_port *ap); -static struct scsi_host_template qs_ata_sht = { +static const struct scsi_host_template qs_ata_sht = { ATA_BASE_SHT(DRV_NAME), .sg_tablesize = QS_MAX_PRD, .dma_boundary = QS_DMA_BOUNDARY, diff --git a/drivers/ata/sata_rcar.c b/drivers/ata/sata_rcar.c index 0195eb29f6c2..34790f15c1b8 100644 --- a/drivers/ata/sata_rcar.c +++ b/drivers/ata/sata_rcar.c @@ -608,7 +608,7 @@ static u8 sata_rcar_bmdma_status(struct ata_port *ap) return host_stat; } -static struct scsi_host_template sata_rcar_sht = { +static const struct scsi_host_template sata_rcar_sht = { ATA_BASE_SHT(DRV_NAME), /* * This controller allows transfer chunks up to 512MB which cross 64KB diff --git a/drivers/ata/sata_sil.c b/drivers/ata/sata_sil.c index 3b989a52879d..cc77c0248284 100644 --- a/drivers/ata/sata_sil.c +++ b/drivers/ata/sata_sil.c @@ -156,7 +156,7 @@ static struct pci_driver sil_pci_driver = { #endif }; -static struct scsi_host_template sil_sht = { +static const struct scsi_host_template sil_sht = { ATA_BASE_SHT(DRV_NAME), /** These controllers support Large Block Transfer which allows transfer chunks up to 2GB and which cross 64KB boundaries, diff --git a/drivers/ata/sata_sil24.c b/drivers/ata/sata_sil24.c index 22cc9e9789dd..e72a0257990d 100644 --- a/drivers/ata/sata_sil24.c +++ b/drivers/ata/sata_sil24.c @@ -373,7 +373,7 @@ static struct pci_driver sil24_pci_driver = { #endif }; -static struct scsi_host_template sil24_sht = { +static const struct scsi_host_template sil24_sht = { __ATA_BASE_SHT(DRV_NAME), .can_queue = SIL24_MAX_CMDS, .sg_tablesize = SIL24_MAX_SGE, diff --git a/drivers/ata/sata_sis.c b/drivers/ata/sata_sis.c index 316237362aa9..ef8724986de3 100644 --- a/drivers/ata/sata_sis.c +++ b/drivers/ata/sata_sis.c @@ -72,7 +72,7 @@ static struct pci_driver sis_pci_driver = { #endif }; -static struct scsi_host_template sis_sht = { +static const struct scsi_host_template sis_sht = { ATA_BMDMA_SHT(DRV_NAME), }; diff --git a/drivers/ata/sata_svw.c b/drivers/ata/sata_svw.c index 2e3418a82b44..c47c3fb434d5 100644 --- a/drivers/ata/sata_svw.c +++ b/drivers/ata/sata_svw.c @@ -330,7 +330,7 @@ static int k2_sata_show_info(struct seq_file *m, struct Scsi_Host *shost) return 0; } -static struct scsi_host_template k2_sata_sht = { +static const struct scsi_host_template k2_sata_sht = { ATA_BMDMA_SHT(DRV_NAME), .show_info = k2_sata_show_info, }; diff --git a/drivers/ata/sata_sx4.c b/drivers/ata/sata_sx4.c index a92c60455b1d..ccc016072637 100644 --- a/drivers/ata/sata_sx4.c +++ b/drivers/ata/sata_sx4.c @@ -226,7 +226,7 @@ static void pdc_post_internal_cmd(struct ata_queued_cmd *qc); static int pdc_check_atapi_dma(struct ata_queued_cmd *qc); -static struct scsi_host_template pdc_sata_sht = { +static const struct scsi_host_template pdc_sata_sht = { ATA_BASE_SHT(DRV_NAME), .sg_tablesize = LIBATA_MAX_PRD, .dma_boundary = ATA_DMA_BOUNDARY, diff --git a/drivers/ata/sata_uli.c b/drivers/ata/sata_uli.c index 815e6af75310..60ea45926cd1 100644 --- a/drivers/ata/sata_uli.c +++ b/drivers/ata/sata_uli.c @@ -59,7 +59,7 @@ static struct pci_driver uli_pci_driver = { .remove = ata_pci_remove_one, }; -static struct scsi_host_template uli_sht = { +static const struct scsi_host_template uli_sht = { ATA_BMDMA_SHT(DRV_NAME), }; diff --git a/drivers/ata/sata_via.c b/drivers/ata/sata_via.c index c7891cc84ea0..57cbf2cef618 100644 --- a/drivers/ata/sata_via.c +++ b/drivers/ata/sata_via.c @@ -107,7 +107,7 @@ static struct pci_driver svia_pci_driver = { .remove = ata_pci_remove_one, }; -static struct scsi_host_template svia_sht = { +static const struct scsi_host_template svia_sht = { ATA_BMDMA_SHT(DRV_NAME), }; diff --git a/drivers/ata/sata_vsc.c b/drivers/ata/sata_vsc.c index 87e4ed66b306..d39b87537168 100644 --- a/drivers/ata/sata_vsc.c +++ b/drivers/ata/sata_vsc.c @@ -277,7 +277,7 @@ out: } -static struct scsi_host_template vsc_sata_sht = { +static const struct scsi_host_template vsc_sata_sht = { ATA_BMDMA_SHT(DRV_NAME), }; diff --git a/drivers/firewire/sbp2.c b/drivers/firewire/sbp2.c index 60051c0cabea..26db5b8dfc1e 100644 --- a/drivers/firewire/sbp2.c +++ b/drivers/firewire/sbp2.c @@ -1117,7 +1117,7 @@ static void sbp2_init_workarounds(struct sbp2_target *tgt, u32 model, tgt->workarounds = w; } -static struct scsi_host_template scsi_driver_template; +static const struct scsi_host_template scsi_driver_template; static void sbp2_remove(struct fw_unit *unit); static int sbp2_probe(struct fw_unit *unit, const struct ieee1394_device_id *id) @@ -1586,7 +1586,7 @@ static struct attribute *sbp2_scsi_sysfs_attrs[] = { ATTRIBUTE_GROUPS(sbp2_scsi_sysfs); -static struct scsi_host_template scsi_driver_template = { +static const struct scsi_host_template scsi_driver_template = { .module = THIS_MODULE, .name = "SBP-2 IEEE-1394", .proc_name = "sbp2", diff --git a/drivers/infiniband/ulp/iser/iscsi_iser.c b/drivers/infiniband/ulp/iser/iscsi_iser.c index 6b7603765383..bb9aaff92ca3 100644 --- a/drivers/infiniband/ulp/iser/iscsi_iser.c +++ b/drivers/infiniband/ulp/iser/iscsi_iser.c @@ -78,7 +78,7 @@ MODULE_DESCRIPTION("iSER (iSCSI Extensions for RDMA) Datamover"); MODULE_LICENSE("Dual BSD/GPL"); MODULE_AUTHOR("Alex Nezhinsky, Dan Bar Dov, Or Gerlitz"); -static struct scsi_host_template iscsi_iser_sht; +static const struct scsi_host_template iscsi_iser_sht; static struct iscsi_transport iscsi_iser_transport; static struct scsi_transport_template *iscsi_iser_scsi_transport; static struct workqueue_struct *release_wq; @@ -956,7 +956,7 @@ static umode_t iser_attr_is_visible(int param_type, int param) return 0; } -static struct scsi_host_template iscsi_iser_sht = { +static const struct scsi_host_template iscsi_iser_sht = { .module = THIS_MODULE, .name = "iSCSI Initiator over iSER", .queuecommand = iscsi_queuecommand, diff --git a/drivers/infiniband/ulp/isert/ib_isert.c b/drivers/infiniband/ulp/isert/ib_isert.c index 75404885cf98..f290cd49698e 100644 --- a/drivers/infiniband/ulp/isert/ib_isert.c +++ b/drivers/infiniband/ulp/isert/ib_isert.c @@ -2506,8 +2506,8 @@ isert_wait4cmds(struct iscsit_conn *conn) isert_info("iscsit_conn %p\n", conn); if (conn->sess) { - target_stop_session(conn->sess->se_sess); - target_wait_for_sess_cmds(conn->sess->se_sess); + target_stop_cmd_counter(conn->cmd_cnt); + target_wait_for_cmds(conn->cmd_cnt); } } diff --git a/drivers/infiniband/ulp/srp/ib_srp.c b/drivers/infiniband/ulp/srp/ib_srp.c index df21b30b7735..3446fbf5a560 100644 --- a/drivers/infiniband/ulp/srp/ib_srp.c +++ b/drivers/infiniband/ulp/srp/ib_srp.c @@ -3077,7 +3077,7 @@ static struct attribute *srp_host_attrs[] = { ATTRIBUTE_GROUPS(srp_host); -static struct scsi_host_template srp_template = { +static const struct scsi_host_template srp_template = { .module = THIS_MODULE, .name = "InfiniBand SRP initiator", .proc_name = DRV_NAME, diff --git a/drivers/infiniband/ulp/srpt/ib_srpt.c b/drivers/infiniband/ulp/srpt/ib_srpt.c index 3c3fae738c3e..3e9343fd2d8e 100644 --- a/drivers/infiniband/ulp/srpt/ib_srpt.c +++ b/drivers/infiniband/ulp/srpt/ib_srpt.c @@ -3300,11 +3300,6 @@ static int srpt_check_true(struct se_portal_group *se_tpg) return 1; } -static int srpt_check_false(struct se_portal_group *se_tpg) -{ - return 0; -} - static struct srpt_port *srpt_tpg_to_sport(struct se_portal_group *tpg) { return tpg->se_tpg_wwn->priv; @@ -3334,11 +3329,6 @@ static u16 srpt_get_tag(struct se_portal_group *tpg) return 1; } -static u32 srpt_tpg_get_inst_index(struct se_portal_group *se_tpg) -{ - return 1; -} - static void srpt_release_cmd(struct se_cmd *se_cmd) { struct srpt_send_ioctx *ioctx = container_of(se_cmd, @@ -3378,24 +3368,6 @@ static void srpt_close_session(struct se_session *se_sess) srpt_disconnect_ch_sync(ch); } -/** - * srpt_sess_get_index - return the value of scsiAttIntrPortIndex (SCSI-MIB) - * @se_sess: SCSI target session. - * - * A quote from RFC 4455 (SCSI-MIB) about this MIB object: - * This object represents an arbitrary integer used to uniquely identify a - * particular attached remote initiator port to a particular SCSI target port - * within a particular SCSI target device within a particular SCSI instance. - */ -static u32 srpt_sess_get_index(struct se_session *se_sess) -{ - return 0; -} - -static void srpt_set_default_node_attrs(struct se_node_acl *nacl) -{ -} - /* Note: only used from inside debug printk's by the TCM core. */ static int srpt_get_tcm_cmd_state(struct se_cmd *se_cmd) { @@ -3866,18 +3838,13 @@ static const struct target_core_fabric_ops srpt_template = { .fabric_name = "srpt", .tpg_get_wwn = srpt_get_fabric_wwn, .tpg_get_tag = srpt_get_tag, - .tpg_check_demo_mode = srpt_check_false, .tpg_check_demo_mode_cache = srpt_check_true, .tpg_check_demo_mode_write_protect = srpt_check_true, - .tpg_check_prod_mode_write_protect = srpt_check_false, - .tpg_get_inst_index = srpt_tpg_get_inst_index, .release_cmd = srpt_release_cmd, .check_stop_free = srpt_check_stop_free, .close_session = srpt_close_session, - .sess_get_index = srpt_sess_get_index, .sess_get_initiator_sid = NULL, .write_pending = srpt_write_pending, - .set_default_node_attributes = srpt_set_default_node_attrs, .get_cmd_state = srpt_get_tcm_cmd_state, .queue_data_in = srpt_queue_data_in, .queue_status = srpt_queue_status, diff --git a/drivers/message/fusion/mptbase.h b/drivers/message/fusion/mptbase.h index 4bd0682c65d3..e0ba783de368 100644 --- a/drivers/message/fusion/mptbase.h +++ b/drivers/message/fusion/mptbase.h @@ -757,7 +757,6 @@ typedef struct _MPT_ADAPTER u8 wait_on_reset_completion; MPT_SCHEDULE_TARGET_RESET schedule_target_reset; MPT_FLUSH_RUNNING_CMDS schedule_dead_ioc_flush_running_cmds; - struct work_struct sas_persist_task; struct work_struct fc_setup_reset_work; struct list_head fc_rports; diff --git a/drivers/message/fusion/mptfc.c b/drivers/message/fusion/mptfc.c index fac747109209..22e7779a332b 100644 --- a/drivers/message/fusion/mptfc.c +++ b/drivers/message/fusion/mptfc.c @@ -105,7 +105,7 @@ static int mptfc_abort(struct scsi_cmnd *SCpnt); static int mptfc_dev_reset(struct scsi_cmnd *SCpnt); static int mptfc_bus_reset(struct scsi_cmnd *SCpnt); -static struct scsi_host_template mptfc_driver_template = { +static const struct scsi_host_template mptfc_driver_template = { .module = THIS_MODULE, .proc_name = "mptfc", .show_info = mptscsih_show_info, diff --git a/drivers/message/fusion/mptlan.c b/drivers/message/fusion/mptlan.c index 142eb5d5d9df..de2e7bcf4784 100644 --- a/drivers/message/fusion/mptlan.c +++ b/drivers/message/fusion/mptlan.c @@ -1433,7 +1433,9 @@ mptlan_remove(struct pci_dev *pdev) { MPT_ADAPTER *ioc = pci_get_drvdata(pdev); struct net_device *dev = ioc->netdev; + struct mpt_lan_priv *priv = netdev_priv(dev); + cancel_delayed_work_sync(&priv->post_buckets_task); if(dev != NULL) { unregister_netdev(dev); free_netdev(dev); diff --git a/drivers/message/fusion/mptsas.c b/drivers/message/fusion/mptsas.c index 88fe4a860ae5..86f16f3ea478 100644 --- a/drivers/message/fusion/mptsas.c +++ b/drivers/message/fusion/mptsas.c @@ -1997,7 +1997,7 @@ done: } -static struct scsi_host_template mptsas_driver_template = { +static const struct scsi_host_template mptsas_driver_template = { .module = THIS_MODULE, .proc_name = "mptsas", .show_info = mptscsih_show_info, diff --git a/drivers/message/fusion/mptscsih.c b/drivers/message/fusion/mptscsih.c index 276084ed04a6..2bc17087d17d 100644 --- a/drivers/message/fusion/mptscsih.c +++ b/drivers/message/fusion/mptscsih.c @@ -1231,7 +1231,6 @@ mptscsih_suspend(struct pci_dev *pdev, pm_message_t state) MPT_ADAPTER *ioc = pci_get_drvdata(pdev); scsi_block_requests(ioc->sh); - flush_scheduled_work(); mptscsih_shutdown(pdev); return mpt_suspend(pdev,state); } diff --git a/drivers/message/fusion/mptspi.c b/drivers/message/fusion/mptspi.c index 62089a8caa2f..6c5920db1e9d 100644 --- a/drivers/message/fusion/mptspi.c +++ b/drivers/message/fusion/mptspi.c @@ -820,7 +820,7 @@ static void mptspi_slave_destroy(struct scsi_device *sdev) mptscsih_slave_destroy(sdev); } -static struct scsi_host_template mptspi_driver_template = { +static const struct scsi_host_template mptspi_driver_template = { .module = THIS_MODULE, .proc_name = "mptspi", .show_info = mptscsih_show_info, diff --git a/drivers/s390/scsi/zfcp_scsi.c b/drivers/s390/scsi/zfcp_scsi.c index 3dbf4b21d127..b2a8cd792266 100644 --- a/drivers/s390/scsi/zfcp_scsi.c +++ b/drivers/s390/scsi/zfcp_scsi.c @@ -418,7 +418,7 @@ static int zfcp_scsi_sysfs_host_reset(struct Scsi_Host *shost, int reset_type) struct scsi_transport_template *zfcp_scsi_transport_template; -static struct scsi_host_template zfcp_scsi_host_template = { +static const struct scsi_host_template zfcp_scsi_host_template = { .module = THIS_MODULE, .name = "zfcp", .queuecommand = zfcp_scsi_queuecommand, diff --git a/drivers/scsi/3w-9xxx.c b/drivers/scsi/3w-9xxx.c index 6cb9cca9565b..38d20a69ee12 100644 --- a/drivers/scsi/3w-9xxx.c +++ b/drivers/scsi/3w-9xxx.c @@ -1976,8 +1976,7 @@ static int twa_slave_configure(struct scsi_device *sdev) return 0; } /* End twa_slave_configure() */ -/* scsi_host_template initializer */ -static struct scsi_host_template driver_template = { +static const struct scsi_host_template driver_template = { .module = THIS_MODULE, .name = "3ware 9000 Storage Controller", .queuecommand = twa_scsi_queue, diff --git a/drivers/scsi/3w-sas.c b/drivers/scsi/3w-sas.c index f41c93454f0c..55989eaa2d9f 100644 --- a/drivers/scsi/3w-sas.c +++ b/drivers/scsi/3w-sas.c @@ -1530,8 +1530,7 @@ static int twl_slave_configure(struct scsi_device *sdev) return 0; } /* End twl_slave_configure() */ -/* scsi_host_template initializer */ -static struct scsi_host_template driver_template = { +static const struct scsi_host_template driver_template = { .module = THIS_MODULE, .name = "3w-sas", .queuecommand = twl_scsi_queue, diff --git a/drivers/scsi/3w-xxxx.c b/drivers/scsi/3w-xxxx.c index ffdecb12d654..36c34ced0cc1 100644 --- a/drivers/scsi/3w-xxxx.c +++ b/drivers/scsi/3w-xxxx.c @@ -2229,7 +2229,7 @@ static int tw_slave_configure(struct scsi_device *sdev) return 0; } /* End tw_slave_configure() */ -static struct scsi_host_template driver_template = { +static const struct scsi_host_template driver_template = { .module = THIS_MODULE, .name = "3ware Storage Controller", .queuecommand = tw_scsi_queue, diff --git a/drivers/scsi/BusLogic.c b/drivers/scsi/BusLogic.c index f7b7ffda1161..72ceaf650b0d 100644 --- a/drivers/scsi/BusLogic.c +++ b/drivers/scsi/BusLogic.c @@ -54,7 +54,7 @@ #define FAILURE (-1) #endif -static struct scsi_host_template blogic_template; +static const struct scsi_host_template blogic_template; /* blogic_drvr_options_count is a count of the number of BusLogic Driver @@ -3663,7 +3663,7 @@ static int __init blogic_parseopts(char *options) Get it all started */ -static struct scsi_host_template blogic_template = { +static const struct scsi_host_template blogic_template = { .module = THIS_MODULE, .proc_name = "BusLogic", .write_info = blogic_write_info, diff --git a/drivers/scsi/a100u2w.c b/drivers/scsi/a100u2w.c index d02eb5b213d0..b95147fb18b0 100644 --- a/drivers/scsi/a100u2w.c +++ b/drivers/scsi/a100u2w.c @@ -1065,7 +1065,7 @@ static irqreturn_t inia100_intr(int irqno, void *devid) return res; } -static struct scsi_host_template inia100_template = { +static const struct scsi_host_template inia100_template = { .proc_name = "inia100", .name = inia100_REVID, .queuecommand = inia100_queue, diff --git a/drivers/scsi/a2091.c b/drivers/scsi/a2091.c index 74312400468b..204448bfd04b 100644 --- a/drivers/scsi/a2091.c +++ b/drivers/scsi/a2091.c @@ -180,7 +180,7 @@ static void dma_stop(struct Scsi_Host *instance, struct scsi_cmnd *SCpnt, } } -static struct scsi_host_template a2091_scsi_template = { +static const struct scsi_host_template a2091_scsi_template = { .module = THIS_MODULE, .name = "Commodore A2091/A590 SCSI", .show_info = wd33c93_show_info, diff --git a/drivers/scsi/a3000.c b/drivers/scsi/a3000.c index 2c5cb1a02e86..c3028726bbe4 100644 --- a/drivers/scsi/a3000.c +++ b/drivers/scsi/a3000.c @@ -197,7 +197,7 @@ static void dma_stop(struct Scsi_Host *instance, struct scsi_cmnd *SCpnt, } } -static struct scsi_host_template amiga_a3000_scsi_template = { +static const struct scsi_host_template amiga_a3000_scsi_template = { .module = THIS_MODULE, .name = "Amiga 3000 built-in SCSI", .show_info = wd33c93_show_info, diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c index 5ba5c18b77b4..68f4dbcfff49 100644 --- a/drivers/scsi/aacraid/linit.c +++ b/drivers/scsi/aacraid/linit.c @@ -26,7 +26,6 @@ #include <linux/module.h> #include <linux/moduleparam.h> #include <linux/pci.h> -#include <linux/aer.h> #include <linux/slab.h> #include <linux/mutex.h> #include <linux/spinlock.h> @@ -1476,7 +1475,7 @@ static const struct file_operations aac_cfg_fops = { .llseek = noop_llseek, }; -static struct scsi_host_template aac_driver_template = { +static const struct scsi_host_template aac_driver_template = { .module = THIS_MODULE, .name = "AAC", .proc_name = AAC_DRIVERNAME, @@ -1783,7 +1782,6 @@ static int aac_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) aac_scan_host(aac); - pci_enable_pcie_error_reporting(pdev); pci_save_state(pdev); return 0; @@ -1949,7 +1947,6 @@ static pci_ers_result_t aac_pci_error_detected(struct pci_dev *pdev, scsi_host_complete_all_commands(shost, DID_NO_CONNECT); aac_release_resources(aac); - pci_disable_pcie_error_reporting(pdev); aac_adapter_ioremap(aac, 0); return PCI_ERS_RESULT_NEED_RESET; diff --git a/drivers/scsi/advansys.c b/drivers/scsi/advansys.c index f301aec044bb..ab066bb27a57 100644 --- a/drivers/scsi/advansys.c +++ b/drivers/scsi/advansys.c @@ -10602,7 +10602,7 @@ static int AdvInitGetConfig(struct pci_dev *pdev, struct Scsi_Host *shost) } #endif -static struct scsi_host_template advansys_template = { +static const struct scsi_host_template advansys_template = { .proc_name = DRV_NAME, #ifdef CONFIG_PROC_FS .show_info = advansys_show_info, diff --git a/drivers/scsi/aha152x.c b/drivers/scsi/aha152x.c index caeebfb67149..055adb349b0e 100644 --- a/drivers/scsi/aha152x.c +++ b/drivers/scsi/aha152x.c @@ -400,7 +400,7 @@ MODULE_DEVICE_TABLE(isapnp, id_table); #endif /* !AHA152X_PCMCIA */ -static struct scsi_host_template aha152x_driver_template; +static const struct scsi_host_template aha152x_driver_template; /* * internal states of the host @@ -2946,7 +2946,7 @@ static int aha152x_adjust_queue(struct scsi_device *device) return 0; } -static struct scsi_host_template aha152x_driver_template = { +static const struct scsi_host_template aha152x_driver_template = { .module = THIS_MODULE, .name = AHA152X_REVID, .proc_name = "aha152x", diff --git a/drivers/scsi/aha1542.c b/drivers/scsi/aha1542.c index 552ca95157da..9503996c6325 100644 --- a/drivers/scsi/aha1542.c +++ b/drivers/scsi/aha1542.c @@ -737,7 +737,8 @@ fail: } /* return non-zero on detection */ -static struct Scsi_Host *aha1542_hw_init(struct scsi_host_template *tpnt, struct device *pdev, int indx) +static struct Scsi_Host *aha1542_hw_init(const struct scsi_host_template *tpnt, + struct device *pdev, int indx) { unsigned int base_io = io[indx]; struct Scsi_Host *sh; @@ -1031,7 +1032,7 @@ static int aha1542_exit_cmd_priv(struct Scsi_Host *shost, struct scsi_cmnd *cmd) return 0; } -static struct scsi_host_template driver_template = { +static const struct scsi_host_template driver_template = { .module = THIS_MODULE, .proc_name = "aha1542", .name = "Adaptec 1542", diff --git a/drivers/scsi/aha1740.c b/drivers/scsi/aha1740.c index 134255751819..3d18945abaf7 100644 --- a/drivers/scsi/aha1740.c +++ b/drivers/scsi/aha1740.c @@ -543,7 +543,7 @@ static int aha1740_eh_abort_handler (struct scsi_cmnd *dummy) return SUCCESS; } -static struct scsi_host_template aha1740_template = { +static const struct scsi_host_template aha1740_template = { .module = THIS_MODULE, .proc_name = "aha1740", .show_info = aha1740_show_info, diff --git a/drivers/scsi/aic94xx/aic94xx_init.c b/drivers/scsi/aic94xx/aic94xx_init.c index 954d0c5ae2e2..f7f81f6c3fbf 100644 --- a/drivers/scsi/aic94xx/aic94xx_init.c +++ b/drivers/scsi/aic94xx/aic94xx_init.c @@ -35,7 +35,7 @@ static struct scsi_transport_template *aic94xx_transport_template; static int asd_scan_finished(struct Scsi_Host *, unsigned long); static void asd_scan_start(struct Scsi_Host *); -static struct scsi_host_template aic94xx_sht = { +static const struct scsi_host_template aic94xx_sht = { .module = THIS_MODULE, /* .name is initialized */ .name = "aic94xx", diff --git a/drivers/scsi/am53c974.c b/drivers/scsi/am53c974.c index b69edb473295..fbb29dbb1e50 100644 --- a/drivers/scsi/am53c974.c +++ b/drivers/scsi/am53c974.c @@ -371,7 +371,7 @@ static void dc390_check_eeprom(struct esp *esp) static int pci_esp_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) { - struct scsi_host_template *hostt = &scsi_esp_template; + const struct scsi_host_template *hostt = &scsi_esp_template; int err = -ENODEV; struct Scsi_Host *shost; struct esp *esp; diff --git a/drivers/scsi/arcmsr/arcmsr.h b/drivers/scsi/arcmsr/arcmsr.h index 07df255c4b1b..ed8d9319862a 100644 --- a/drivers/scsi/arcmsr/arcmsr.h +++ b/drivers/scsi/arcmsr/arcmsr.h @@ -45,11 +45,12 @@ #include <linux/interrupt.h> struct device_attribute; /*The limit of outstanding scsi command that firmware can handle*/ +#define ARCMSR_NAME "arcmsr" #define ARCMSR_MAX_FREECCB_NUM 1024 #define ARCMSR_MAX_OUTSTANDING_CMD 1024 #define ARCMSR_DEFAULT_OUTSTANDING_CMD 128 #define ARCMSR_MIN_OUTSTANDING_CMD 32 -#define ARCMSR_DRIVER_VERSION "v1.50.00.05-20210429" +#define ARCMSR_DRIVER_VERSION "v1.50.00.13-20230206" #define ARCMSR_SCSI_INITIATOR_ID 255 #define ARCMSR_MAX_XFER_SECTORS 512 #define ARCMSR_MAX_XFER_SECTORS_B 4096 diff --git a/drivers/scsi/arcmsr/arcmsr_hba.c b/drivers/scsi/arcmsr/arcmsr_hba.c index d3fb8a9c1c39..2cd12c7f06c6 100644 --- a/drivers/scsi/arcmsr/arcmsr_hba.c +++ b/drivers/scsi/arcmsr/arcmsr_hba.c @@ -57,7 +57,6 @@ #include <linux/timer.h> #include <linux/slab.h> #include <linux/pci.h> -#include <linux/aer.h> #include <linux/circ_buf.h> #include <asm/dma.h> #include <asm/io.h> @@ -152,8 +151,9 @@ static int arcmsr_adjust_disk_queue_depth(struct scsi_device *sdev, int queue_de return scsi_change_queue_depth(sdev, queue_depth); } -static struct scsi_host_template arcmsr_scsi_host_template = { +static const struct scsi_host_template arcmsr_scsi_host_template = { .module = THIS_MODULE, + .proc_name = ARCMSR_NAME, .name = "Areca SAS/SATA RAID driver", .info = arcmsr_info, .queuecommand = arcmsr_queue_command, @@ -997,6 +997,8 @@ static int arcmsr_set_dma_mask(struct AdapterControlBlock *acb) if (((acb->adapter_type == ACB_ADAPTER_TYPE_A) && !dma_mask_64) || dma_set_mask(&pcidev->dev, DMA_BIT_MASK(64))) goto dma32; + if (acb->adapter_type <= ACB_ADAPTER_TYPE_B) + return 0; if (dma_set_coherent_mask(&pcidev->dev, DMA_BIT_MASK(64)) || dma_set_mask_and_coherent(&pcidev->dev, DMA_BIT_MASK(64))) { printk("arcmsr: set DMA 64 mask failed\n"); @@ -1300,20 +1302,13 @@ static uint8_t arcmsr_abort_allcmd(struct AdapterControlBlock *acb) return rtnval; } -static void arcmsr_pci_unmap_dma(struct CommandControlBlock *ccb) -{ - struct scsi_cmnd *pcmd = ccb->pcmd; - - scsi_dma_unmap(pcmd); -} - static void arcmsr_ccb_complete(struct CommandControlBlock *ccb) { struct AdapterControlBlock *acb = ccb->acb; struct scsi_cmnd *pcmd = ccb->pcmd; unsigned long flags; atomic_dec(&acb->ccboutstandingcount); - arcmsr_pci_unmap_dma(ccb); + scsi_dma_unmap(ccb->pcmd); ccb->startdone = ARCMSR_CCB_DONE; spin_lock_irqsave(&acb->ccblist_lock, flags); list_add_tail(&ccb->list, &acb->ccb_free_list); @@ -1597,7 +1592,7 @@ static void arcmsr_remove_scsi_devices(struct AdapterControlBlock *acb) ccb = acb->pccb_pool[i]; if (ccb->startdone == ARCMSR_CCB_START) { ccb->pcmd->result = DID_NO_CONNECT << 16; - arcmsr_pci_unmap_dma(ccb); + scsi_dma_unmap(ccb->pcmd); scsi_done(ccb->pcmd); } } @@ -2260,8 +2255,11 @@ static void arcmsr_iop2drv_data_wrote_handle(struct AdapterControlBlock *acb) spin_lock_irqsave(&acb->rqbuffer_lock, flags); prbuffer = arcmsr_get_iop_rqbuffer(acb); - buf_empty_len = (acb->rqbuf_putIndex - acb->rqbuf_getIndex - 1) & - (ARCMSR_MAX_QBUFFER - 1); + if (acb->rqbuf_putIndex >= acb->rqbuf_getIndex) { + buf_empty_len = (ARCMSR_MAX_QBUFFER - 1) - + (acb->rqbuf_putIndex - acb->rqbuf_getIndex); + } else + buf_empty_len = acb->rqbuf_getIndex - acb->rqbuf_putIndex - 1; if (buf_empty_len >= readl(&prbuffer->data_len)) { if (arcmsr_Read_iop_rqbuffer_data(acb, prbuffer) == 0) acb->acb_flags |= ACB_F_IOPDATA_OVERFLOW; diff --git a/drivers/scsi/arm/acornscsi.c b/drivers/scsi/arm/acornscsi.c index 7602639da9b3..0b046e4b395c 100644 --- a/drivers/scsi/arm/acornscsi.c +++ b/drivers/scsi/arm/acornscsi.c @@ -2780,7 +2780,7 @@ static int acornscsi_show_info(struct seq_file *m, struct Scsi_Host *instance) return 0; } -static struct scsi_host_template acornscsi_template = { +static const struct scsi_host_template acornscsi_template = { .module = THIS_MODULE, .show_info = acornscsi_show_info, .name = "AcornSCSI", diff --git a/drivers/scsi/arm/arxescsi.c b/drivers/scsi/arm/arxescsi.c index 2527b542bcdd..925d0bd68aa5 100644 --- a/drivers/scsi/arm/arxescsi.c +++ b/drivers/scsi/arm/arxescsi.c @@ -238,7 +238,7 @@ arxescsi_show_info(struct seq_file *m, struct Scsi_Host *host) return 0; } -static struct scsi_host_template arxescsi_template = { +static const struct scsi_host_template arxescsi_template = { .show_info = arxescsi_show_info, .name = "ARXE SCSI card", .info = arxescsi_info, diff --git a/drivers/scsi/arm/cumana_1.c b/drivers/scsi/arm/cumana_1.c index 5d4f67ba74c0..d1a2a22ffe8c 100644 --- a/drivers/scsi/arm/cumana_1.c +++ b/drivers/scsi/arm/cumana_1.c @@ -211,7 +211,7 @@ static void cumanascsi_write(struct NCR5380_hostdata *hostdata, #include "../NCR5380.c" -static struct scsi_host_template cumanascsi_template = { +static const struct scsi_host_template cumanascsi_template = { .module = THIS_MODULE, .name = "Cumana 16-bit SCSI", .info = cumanascsi_info, diff --git a/drivers/scsi/arm/cumana_2.c b/drivers/scsi/arm/cumana_2.c index d15053f02472..c5d8f4313b31 100644 --- a/drivers/scsi/arm/cumana_2.c +++ b/drivers/scsi/arm/cumana_2.c @@ -356,7 +356,7 @@ static int cumanascsi_2_show_info(struct seq_file *m, struct Scsi_Host *host) return 0; } -static struct scsi_host_template cumanascsi2_template = { +static const struct scsi_host_template cumanascsi2_template = { .module = THIS_MODULE, .show_info = cumanascsi_2_show_info, .write_info = cumanascsi_2_set_proc_info, diff --git a/drivers/scsi/arm/eesox.c b/drivers/scsi/arm/eesox.c index 6f374af9f45f..b3ec7635bc72 100644 --- a/drivers/scsi/arm/eesox.c +++ b/drivers/scsi/arm/eesox.c @@ -473,7 +473,7 @@ static ssize_t eesoxscsi_store_term(struct device *dev, struct device_attribute static DEVICE_ATTR(bus_term, S_IRUGO | S_IWUSR, eesoxscsi_show_term, eesoxscsi_store_term); -static struct scsi_host_template eesox_template = { +static const struct scsi_host_template eesox_template = { .module = THIS_MODULE, .show_info = eesoxscsi_show_info, .write_info = eesoxscsi_set_proc_info, diff --git a/drivers/scsi/arm/oak.c b/drivers/scsi/arm/oak.c index f18a0620c808..d69245007096 100644 --- a/drivers/scsi/arm/oak.c +++ b/drivers/scsi/arm/oak.c @@ -100,7 +100,7 @@ printk("reading %p len %d\n", addr, len); #include "../NCR5380.c" -static struct scsi_host_template oakscsi_template = { +static const struct scsi_host_template oakscsi_template = { .module = THIS_MODULE, .name = "Oak 16-bit SCSI", .info = oakscsi_info, diff --git a/drivers/scsi/arm/powertec.c b/drivers/scsi/arm/powertec.c index 7586d2a03812..3b5991427886 100644 --- a/drivers/scsi/arm/powertec.c +++ b/drivers/scsi/arm/powertec.c @@ -279,7 +279,7 @@ powertecscsi_store_term(struct device *dev, struct device_attribute *attr, const static DEVICE_ATTR(bus_term, S_IRUGO | S_IWUSR, powertecscsi_show_term, powertecscsi_store_term); -static struct scsi_host_template powertecscsi_template = { +static const struct scsi_host_template powertecscsi_template = { .module = THIS_MODULE, .show_info = powertecscsi_show_info, .write_info = powertecscsi_set_proc_info, diff --git a/drivers/scsi/atp870u.c b/drivers/scsi/atp870u.c index 7143418d690f..2a748af269c2 100644 --- a/drivers/scsi/atp870u.c +++ b/drivers/scsi/atp870u.c @@ -40,7 +40,7 @@ #include "atp870u.h" -static struct scsi_host_template atp870u_template; +static const struct scsi_host_template atp870u_template; static void send_s870(struct atp_unit *dev,unsigned char c); static void atp_is(struct atp_unit *dev, unsigned char c, bool wide_chip, unsigned char lvdmode); @@ -1726,7 +1726,7 @@ static void atp870u_remove (struct pci_dev *pdev) } MODULE_LICENSE("GPL"); -static struct scsi_host_template atp870u_template = { +static const struct scsi_host_template atp870u_template = { .module = THIS_MODULE, .name = "atp870u" /* name */, .proc_name = "atp870u", diff --git a/drivers/scsi/be2iscsi/be_cmds.c b/drivers/scsi/be2iscsi/be_cmds.c index 69b1a80e3687..0b59b63bce79 100644 --- a/drivers/scsi/be2iscsi/be_cmds.c +++ b/drivers/scsi/be2iscsi/be_cmds.c @@ -1173,7 +1173,6 @@ int be_cmd_iscsi_post_sgl_pages(struct be_ctrl_info *ctrl, struct beiscsi_hba *phba = pci_get_drvdata(ctrl->pdev); int status; unsigned int curr_pages; - u32 internal_page_offset = 0; u32 temp_num_pages = num_pages; if (num_pages == 0xff) @@ -1192,7 +1191,6 @@ int be_cmd_iscsi_post_sgl_pages(struct be_ctrl_info *ctrl, req->page_offset = page_offset; be_cmd_page_addrs_prepare(req->pages, req->num_pages, q_mem); q_mem->dma = q_mem->dma + (req->num_pages * PAGE_SIZE); - internal_page_offset += req->num_pages; page_offset += req->num_pages; num_pages -= req->num_pages; diff --git a/drivers/scsi/be2iscsi/be_main.c b/drivers/scsi/be2iscsi/be_main.c index 50a577ac3bb4..e48f14ad6dfd 100644 --- a/drivers/scsi/be2iscsi/be_main.c +++ b/drivers/scsi/be2iscsi/be_main.c @@ -139,7 +139,7 @@ beiscsi_disp_param(_name)\ beiscsi_change_param(_name, _minval, _maxval, _defval)\ beiscsi_store_param(_name)\ beiscsi_init_param(_name, _minval, _maxval, _defval)\ -DEVICE_ATTR(beiscsi_##_name, S_IRUGO | S_IWUSR,\ +static DEVICE_ATTR(beiscsi_##_name, S_IRUGO | S_IWUSR,\ beiscsi_##_name##_disp, beiscsi_##_name##_store) /* @@ -155,14 +155,14 @@ BEISCSI_RW_ATTR(log_enable, 0x00, "\t\t\t\tConfiguration Path : 0x20\n" "\t\t\t\tiSCSI Protocol : 0x40\n"); -DEVICE_ATTR(beiscsi_drvr_ver, S_IRUGO, beiscsi_drvr_ver_disp, NULL); -DEVICE_ATTR(beiscsi_adapter_family, S_IRUGO, beiscsi_adap_family_disp, NULL); -DEVICE_ATTR(beiscsi_fw_ver, S_IRUGO, beiscsi_fw_ver_disp, NULL); -DEVICE_ATTR(beiscsi_phys_port, S_IRUGO, beiscsi_phys_port_disp, NULL); -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 DEVICE_ATTR(beiscsi_drvr_ver, S_IRUGO, beiscsi_drvr_ver_disp, NULL); +static DEVICE_ATTR(beiscsi_adapter_family, S_IRUGO, beiscsi_adap_family_disp, NULL); +static DEVICE_ATTR(beiscsi_fw_ver, S_IRUGO, beiscsi_fw_ver_disp, NULL); +static DEVICE_ATTR(beiscsi_phys_port, S_IRUGO, beiscsi_phys_port_disp, NULL); +static DEVICE_ATTR(beiscsi_active_session_count, S_IRUGO, + beiscsi_active_session_disp, NULL); +static DEVICE_ATTR(beiscsi_free_session_count, S_IRUGO, + beiscsi_free_session_disp, NULL); static struct attribute *beiscsi_attrs[] = { &dev_attr_beiscsi_log_enable.attr, @@ -398,7 +398,7 @@ static const struct pci_device_id beiscsi_pci_id_table[] = { MODULE_DEVICE_TABLE(pci, beiscsi_pci_id_table); -static struct scsi_host_template beiscsi_sht = { +static const struct scsi_host_template beiscsi_sht = { .module = THIS_MODULE, .name = "Emulex 10Gbe open-iscsi Initiator Driver", .proc_name = DRV_NAME, @@ -5545,13 +5545,6 @@ static int beiscsi_dev_probe(struct pci_dev *pcidev, goto disable_pci; } - /* Enable EEH reporting */ - ret = pci_enable_pcie_error_reporting(pcidev); - if (ret) - beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_INIT, - "BM_%d : PCIe Error Reporting " - "Enabling Failed\n"); - pci_save_state(pcidev); /* Initialize Driver configuration Paramters */ @@ -5736,7 +5729,6 @@ free_hba: pci_disable_msix(phba->pcidev); pci_dev_put(phba->pcidev); iscsi_host_free(phba->shost); - pci_disable_pcie_error_reporting(pcidev); pci_set_drvdata(pcidev, NULL); disable_pci: pci_release_regions(pcidev); @@ -5779,7 +5771,6 @@ static void beiscsi_remove(struct pci_dev *pcidev) pci_dev_put(phba->pcidev); iscsi_host_free(phba->shost); - pci_disable_pcie_error_reporting(pcidev); pci_set_drvdata(pcidev, NULL); pci_release_regions(pcidev); pci_disable_device(pcidev); diff --git a/drivers/scsi/be2iscsi/be_main.h b/drivers/scsi/be2iscsi/be_main.h index 98977c0700f1..71c95d144560 100644 --- a/drivers/scsi/be2iscsi/be_main.h +++ b/drivers/scsi/be2iscsi/be_main.h @@ -16,7 +16,6 @@ #include <linux/in.h> #include <linux/ctype.h> #include <linux/module.h> -#include <linux/aer.h> #include <scsi/scsi.h> #include <scsi/scsi_cmnd.h> #include <scsi/scsi_device.h> diff --git a/drivers/scsi/bfa/bfad.c b/drivers/scsi/bfa/bfad.c index e5aa982ffedc..529b73a83d69 100644 --- a/drivers/scsi/bfa/bfad.c +++ b/drivers/scsi/bfa/bfad.c @@ -738,9 +738,6 @@ bfad_pci_init(struct pci_dev *pdev, struct bfad_s *bfad) goto out_release_region; } - /* Enable PCIE Advanced Error Recovery (AER) if kernel supports */ - pci_enable_pcie_error_reporting(pdev); - bfad->pci_bar0_kva = pci_iomap(pdev, 0, pci_resource_len(pdev, 0)); bfad->pci_bar2_kva = pci_iomap(pdev, 2, pci_resource_len(pdev, 2)); @@ -801,8 +798,6 @@ bfad_pci_uninit(struct pci_dev *pdev, struct bfad_s *bfad) pci_iounmap(pdev, bfad->pci_bar0_kva); pci_iounmap(pdev, bfad->pci_bar2_kva); pci_release_regions(pdev); - /* Disable PCIE Advanced Error Recovery (AER) */ - pci_disable_pcie_error_reporting(pdev); pci_disable_device(pdev); } @@ -1562,7 +1557,6 @@ bfad_pci_slot_reset(struct pci_dev *pdev) if (restart_bfa(bfad) == -1) goto out_disable_device; - pci_enable_pcie_error_reporting(pdev); dev_printk(KERN_WARNING, &pdev->dev, "slot_reset completed flags: 0x%x!\n", bfad->bfad_flags); diff --git a/drivers/scsi/bfa/bfad_drv.h b/drivers/scsi/bfa/bfad_drv.h index eaee7c8bc2d2..7682cfa34265 100644 --- a/drivers/scsi/bfa/bfad_drv.h +++ b/drivers/scsi/bfa/bfad_drv.h @@ -30,7 +30,6 @@ #include <linux/vmalloc.h> #include <linux/workqueue.h> #include <linux/bitops.h> -#include <linux/aer.h> #include <scsi/scsi.h> #include <scsi/scsi_host.h> #include <scsi/scsi_tcq.h> diff --git a/drivers/scsi/bnx2i/bnx2i_iscsi.c b/drivers/scsi/bnx2i/bnx2i_iscsi.c index a3c800e04a2e..9971f32a663c 100644 --- a/drivers/scsi/bnx2i/bnx2i_iscsi.c +++ b/drivers/scsi/bnx2i/bnx2i_iscsi.c @@ -22,7 +22,7 @@ struct scsi_transport_template *bnx2i_scsi_xport_template; struct iscsi_transport bnx2i_iscsi_transport; -static struct scsi_host_template bnx2i_host_template; +static const struct scsi_host_template bnx2i_host_template; /* * Global endpoint resource info @@ -2250,7 +2250,7 @@ static umode_t bnx2i_attr_is_visible(int param_type, int param) * 'Scsi_Host_Template' structure and 'iscsi_tranport' structure template * used while registering with the scsi host and iSCSI transport module. */ -static struct scsi_host_template bnx2i_host_template = { +static const struct scsi_host_template bnx2i_host_template = { .module = THIS_MODULE, .name = "QLogic Offload iSCSI Initiator", .proc_name = "bnx2i", diff --git a/drivers/scsi/csiostor/csio_init.c b/drivers/scsi/csiostor/csio_init.c index ccbded3353bd..0c32faefad7c 100644 --- a/drivers/scsi/csiostor/csio_init.c +++ b/drivers/scsi/csiostor/csio_init.c @@ -38,7 +38,6 @@ #include <linux/module.h> #include <linux/init.h> #include <linux/pci.h> -#include <linux/aer.h> #include <linux/mm.h> #include <linux/notifier.h> #include <linux/kdebug.h> diff --git a/drivers/scsi/cxgbi/cxgb3i/cxgb3i.c b/drivers/scsi/cxgbi/cxgb3i/cxgb3i.c index ff9d4287937a..ec6530240707 100644 --- a/drivers/scsi/cxgbi/cxgb3i/cxgb3i.c +++ b/drivers/scsi/cxgbi/cxgb3i/cxgb3i.c @@ -80,7 +80,7 @@ static struct cxgb3_client t3_client = { .event_handler = cxgb3i_dev_event_handler, }; -static struct scsi_host_template cxgb3i_host_template = { +static const struct scsi_host_template cxgb3i_host_template = { .module = THIS_MODULE, .name = DRV_MODULE_NAME, .proc_name = DRV_MODULE_NAME, diff --git a/drivers/scsi/cxgbi/libcxgbi.c b/drivers/scsi/cxgbi/libcxgbi.c index af281e271f88..eb47c8c96d0e 100644 --- a/drivers/scsi/cxgbi/libcxgbi.c +++ b/drivers/scsi/cxgbi/libcxgbi.c @@ -337,7 +337,7 @@ void cxgbi_hbas_remove(struct cxgbi_device *cdev) EXPORT_SYMBOL_GPL(cxgbi_hbas_remove); int cxgbi_hbas_add(struct cxgbi_device *cdev, u64 max_lun, - unsigned int max_conns, struct scsi_host_template *sht, + unsigned int max_conns, const struct scsi_host_template *sht, struct scsi_transport_template *stt) { struct cxgbi_hba *chba; diff --git a/drivers/scsi/cxgbi/libcxgbi.h b/drivers/scsi/cxgbi/libcxgbi.h index d8fc7beafa20..d92cf1dccc2f 100644 --- a/drivers/scsi/cxgbi/libcxgbi.h +++ b/drivers/scsi/cxgbi/libcxgbi.h @@ -591,7 +591,7 @@ struct cxgbi_device *cxgbi_device_find_by_netdev(struct net_device *, int *); struct cxgbi_device *cxgbi_device_find_by_netdev_rcu(struct net_device *, int *); int cxgbi_hbas_add(struct cxgbi_device *, u64, unsigned int, - struct scsi_host_template *, + const struct scsi_host_template *, struct scsi_transport_template *); void cxgbi_hbas_remove(struct cxgbi_device *); diff --git a/drivers/scsi/cxlflash/superpipe.c b/drivers/scsi/cxlflash/superpipe.c index 22cfc2e1dfb9..e1b55b03e812 100644 --- a/drivers/scsi/cxlflash/superpipe.c +++ b/drivers/scsi/cxlflash/superpipe.c @@ -358,7 +358,7 @@ retry: dev_dbg(dev, "%s: %ssending cmd(%02x)\n", __func__, retry_cnt ? "re" : "", scsi_cmd[0]); - /* Drop the ioctl read semahpore across lengthy call */ + /* Drop the ioctl read semaphore across lengthy call */ up_read(&cfg->ioctl_rwsem); result = scsi_execute_cmd(sdev, scsi_cmd, REQ_OP_DRV_IN, cmd_buf, CMD_BUFSIZE, to, CMD_RETRIES, &exec_args); diff --git a/drivers/scsi/cxlflash/vlun.c b/drivers/scsi/cxlflash/vlun.c index 9caabf550436..cbd5a648a131 100644 --- a/drivers/scsi/cxlflash/vlun.c +++ b/drivers/scsi/cxlflash/vlun.c @@ -448,7 +448,7 @@ static int write_same16(struct scsi_device *sdev, put_unaligned_be32(ws_limit < left ? ws_limit : left, &scsi_cmd[10]); - /* Drop the ioctl read semahpore across lengthy call */ + /* Drop the ioctl read semaphore across lengthy call */ up_read(&cfg->ioctl_rwsem); result = scsi_execute_cmd(sdev, scsi_cmd, REQ_OP_DRV_OUT, cmd_buf, CMD_BUFSIZE, to, diff --git a/drivers/scsi/dc395x.c b/drivers/scsi/dc395x.c index 670a836a6ba1..c8e86f8a631e 100644 --- a/drivers/scsi/dc395x.c +++ b/drivers/scsi/dc395x.c @@ -4541,7 +4541,7 @@ static int dc395x_show_info(struct seq_file *m, struct Scsi_Host *host) } -static struct scsi_host_template dc395x_driver_template = { +static const struct scsi_host_template dc395x_driver_template = { .module = THIS_MODULE, .proc_name = DC395X_NAME, .show_info = dc395x_show_info, diff --git a/drivers/scsi/dmx3191d.c b/drivers/scsi/dmx3191d.c index a171ce6b70b2..dfb091d34363 100644 --- a/drivers/scsi/dmx3191d.c +++ b/drivers/scsi/dmx3191d.c @@ -39,7 +39,7 @@ #define DMX3191D_REGION_LEN 8 -static struct scsi_host_template dmx3191d_driver_template = { +static const struct scsi_host_template dmx3191d_driver_template = { .module = THIS_MODULE, .proc_name = DMX3191D_DRIVER_NAME, .name = "Domex DMX3191D", diff --git a/drivers/scsi/elx/efct/efct_lio.c b/drivers/scsi/elx/efct/efct_lio.c index be4b5c1ee32d..a982b9cf9870 100644 --- a/drivers/scsi/elx/efct/efct_lio.c +++ b/drivers/scsi/elx/efct/efct_lio.c @@ -285,11 +285,6 @@ efct_lio_npiv_check_prod_write_protect(struct se_portal_group *se_tpg) return tpg->tpg_attrib.prod_mode_write_protect; } -static u32 efct_lio_tpg_get_inst_index(struct se_portal_group *se_tpg) -{ - return 1; -} - static int efct_lio_check_stop_free(struct se_cmd *se_cmd) { struct efct_scsi_tgt_io *ocp = @@ -355,15 +350,6 @@ static void efct_lio_close_session(struct se_session *se_sess) efc_node_post_shutdown(node, NULL); } -static u32 efct_lio_sess_get_index(struct se_session *se_sess) -{ - return 0; -} - -static void efct_lio_set_default_node_attrs(struct se_node_acl *nacl) -{ -} - static int efct_lio_get_cmd_state(struct se_cmd *cmd) { struct efct_scsi_tgt_io *ocp = @@ -1607,14 +1593,11 @@ static const struct target_core_fabric_ops efct_lio_ops = { .tpg_check_demo_mode_cache = efct_lio_check_demo_mode_cache, .tpg_check_demo_mode_write_protect = efct_lio_check_demo_write_protect, .tpg_check_prod_mode_write_protect = efct_lio_check_prod_write_protect, - .tpg_get_inst_index = efct_lio_tpg_get_inst_index, .check_stop_free = efct_lio_check_stop_free, .aborted_task = efct_lio_aborted_task, .release_cmd = efct_lio_release_cmd, .close_session = efct_lio_close_session, - .sess_get_index = efct_lio_sess_get_index, .write_pending = efct_lio_write_pending, - .set_default_node_attributes = efct_lio_set_default_node_attrs, .get_cmd_state = efct_lio_get_cmd_state, .queue_data_in = efct_lio_queue_data_in, .queue_status = efct_lio_queue_status, @@ -1644,14 +1627,11 @@ static const struct target_core_fabric_ops efct_lio_npiv_ops = { efct_lio_npiv_check_demo_write_protect, .tpg_check_prod_mode_write_protect = efct_lio_npiv_check_prod_write_protect, - .tpg_get_inst_index = efct_lio_tpg_get_inst_index, .check_stop_free = efct_lio_check_stop_free, .aborted_task = efct_lio_aborted_task, .release_cmd = efct_lio_release_cmd, .close_session = efct_lio_close_session, - .sess_get_index = efct_lio_sess_get_index, .write_pending = efct_lio_write_pending, - .set_default_node_attributes = efct_lio_set_default_node_attrs, .get_cmd_state = efct_lio_get_cmd_state, .queue_data_in = efct_lio_queue_data_in, .queue_status = efct_lio_queue_status, diff --git a/drivers/scsi/elx/efct/efct_xport.c b/drivers/scsi/elx/efct/efct_xport.c index 9495cedcc0b9..cf4dced20b8b 100644 --- a/drivers/scsi/elx/efct/efct_xport.c +++ b/drivers/scsi/elx/efct/efct_xport.c @@ -10,7 +10,7 @@ static struct dentry *efct_debugfs_root; static atomic_t efct_debugfs_count; -static struct scsi_host_template efct_template = { +static const struct scsi_host_template efct_template = { .module = THIS_MODULE, .name = EFCT_DRIVER_NAME, .supported_mode = MODE_TARGET, diff --git a/drivers/scsi/esas2r/esas2r_main.c b/drivers/scsi/esas2r/esas2r_main.c index d7a2c49ff5ee..f700a16cd885 100644 --- a/drivers/scsi/esas2r/esas2r_main.c +++ b/drivers/scsi/esas2r/esas2r_main.c @@ -231,7 +231,7 @@ struct bin_attribute bin_attr_default_nvram = { .write = NULL }; -static struct scsi_host_template driver_template = { +static const struct scsi_host_template driver_template = { .module = THIS_MODULE, .show_info = esas2r_show_info, .name = ESAS2R_LONGNAME, diff --git a/drivers/scsi/esp_scsi.c b/drivers/scsi/esp_scsi.c index 64ec6bb84550..97816a0e6240 100644 --- a/drivers/scsi/esp_scsi.c +++ b/drivers/scsi/esp_scsi.c @@ -2660,7 +2660,7 @@ static const char *esp_info(struct Scsi_Host *host) return "esp"; } -struct scsi_host_template scsi_esp_template = { +const struct scsi_host_template scsi_esp_template = { .module = THIS_MODULE, .name = "esp", .info = esp_info, diff --git a/drivers/scsi/esp_scsi.h b/drivers/scsi/esp_scsi.h index c73760d3cf83..00cd7c0ccc76 100644 --- a/drivers/scsi/esp_scsi.h +++ b/drivers/scsi/esp_scsi.h @@ -572,7 +572,7 @@ struct esp { * 13) Check scsi_esp_register() return value, release all resources * if an error was returned. */ -extern struct scsi_host_template scsi_esp_template; +extern const struct scsi_host_template scsi_esp_template; extern int scsi_esp_register(struct esp *); extern void scsi_esp_unregister(struct esp *); diff --git a/drivers/scsi/fcoe/fcoe.c b/drivers/scsi/fcoe/fcoe.c index 38774a272e62..f1429f270170 100644 --- a/drivers/scsi/fcoe/fcoe.c +++ b/drivers/scsi/fcoe/fcoe.c @@ -260,7 +260,7 @@ static struct fc_function_template fcoe_vport_fc_functions = { .bsg_request = fc_lport_bsg_request, }; -static struct scsi_host_template fcoe_shost_template = { +static const struct scsi_host_template fcoe_shost_template = { .module = THIS_MODULE, .name = "FCoE Driver", .proc_name = FCOE_NAME, diff --git a/drivers/scsi/fdomain.c b/drivers/scsi/fdomain.c index 444eac9b2466..504c4e0c5d17 100644 --- a/drivers/scsi/fdomain.c +++ b/drivers/scsi/fdomain.c @@ -496,7 +496,7 @@ static int fdomain_biosparam(struct scsi_device *sdev, return 0; } -static struct scsi_host_template fdomain_template = { +static const struct scsi_host_template fdomain_template = { .module = THIS_MODULE, .name = "Future Domain TMC-16x0", .proc_name = "fdomain", diff --git a/drivers/scsi/fnic/fnic_main.c b/drivers/scsi/fnic/fnic_main.c index 1077110ab273..984bc5fc55e2 100644 --- a/drivers/scsi/fnic/fnic_main.c +++ b/drivers/scsi/fnic/fnic_main.c @@ -95,7 +95,7 @@ static int fnic_slave_alloc(struct scsi_device *sdev) return 0; } -static struct scsi_host_template fnic_host_template = { +static const struct scsi_host_template fnic_host_template = { .module = THIS_MODULE, .name = DRV_NAME, .queuecommand = fnic_queuecommand, diff --git a/drivers/scsi/fnic/fnic_trace.c b/drivers/scsi/fnic/fnic_trace.c index e03967463561..f3c3a26a1384 100644 --- a/drivers/scsi/fnic/fnic_trace.c +++ b/drivers/scsi/fnic/fnic_trace.c @@ -781,28 +781,21 @@ void copy_and_format_trace_data(struct fc_trace_hdr *tdata, fnic_dbgfs_t *fnic_dbgfs_prt, int *orig_len, u8 rdata_flag) { - struct tm tm; int j, i = 1, len; - char *fc_trace, *fmt; int ethhdr_len = sizeof(struct ethhdr) - 1; int fcoehdr_len = sizeof(struct fcoe_hdr); int fchdr_len = sizeof(struct fc_frame_header); int max_size = fnic_fc_trace_max_pages * PAGE_SIZE * 3; + char *fc_trace; tdata->frame_type = tdata->frame_type & 0x7F; len = *orig_len; - time64_to_tm(tdata->time_stamp.tv_sec, 0, &tm); - - fmt = "%02d:%02d:%04ld %02d:%02d:%02d.%09lu ns%8x %c%8x\t"; - len += scnprintf(fnic_dbgfs_prt->buffer + len, - max_size - len, - fmt, - tm.tm_mon + 1, tm.tm_mday, tm.tm_year + 1900, - tm.tm_hour, tm.tm_min, tm.tm_sec, - tdata->time_stamp.tv_nsec, tdata->host_no, - tdata->frame_type, tdata->frame_len); + len += scnprintf(fnic_dbgfs_prt->buffer + len, max_size - len, + "%ptTs.%09lu ns%8x %c%8x\t", + &tdata->time_stamp.tv_sec, tdata->time_stamp.tv_nsec, + tdata->host_no, tdata->frame_type, tdata->frame_len); fc_trace = (char *)FC_TRACE_ADDRESS(tdata); diff --git a/drivers/scsi/g_NCR5380.c b/drivers/scsi/g_NCR5380.c index 0c768e7d06b9..f6305e3e60f4 100644 --- a/drivers/scsi/g_NCR5380.c +++ b/drivers/scsi/g_NCR5380.c @@ -219,7 +219,7 @@ static int hp_c2502_irqs[] = { 9, 5, 7, 3, 4, -1 }; -static int generic_NCR5380_init_one(struct scsi_host_template *tpnt, +static int generic_NCR5380_init_one(const struct scsi_host_template *tpnt, struct device *pdev, int base, int irq, int board) { bool is_pmio = base <= 0xffff; @@ -689,7 +689,7 @@ static int generic_NCR5380_dma_residual(struct NCR5380_hostdata *hostdata) #include "NCR5380.c" -static struct scsi_host_template driver_template = { +static const struct scsi_host_template driver_template = { .module = THIS_MODULE, .proc_name = DRV_MODULE_NAME, .name = "Generic NCR5380/NCR53C400 SCSI", diff --git a/drivers/scsi/gvp11.c b/drivers/scsi/gvp11.c index 7d56a236a011..d2eddad099a2 100644 --- a/drivers/scsi/gvp11.c +++ b/drivers/scsi/gvp11.c @@ -222,7 +222,7 @@ static void dma_stop(struct Scsi_Host *instance, struct scsi_cmnd *SCpnt, } } -static struct scsi_host_template gvp11_scsi_template = { +static const struct scsi_host_template gvp11_scsi_template = { .module = THIS_MODULE, .name = "GVP Series II SCSI", .show_info = wd33c93_show_info, diff --git a/drivers/scsi/hisi_sas/hisi_sas.h b/drivers/scsi/hisi_sas/hisi_sas.h index 6f8a52a1b808..fb7c52c119df 100644 --- a/drivers/scsi/hisi_sas/hisi_sas.h +++ b/drivers/scsi/hisi_sas/hisi_sas.h @@ -207,6 +207,7 @@ struct hisi_sas_cq { int rd_point; int id; int irq_no; + spinlock_t poll_lock; }; struct hisi_sas_dq { @@ -344,7 +345,7 @@ struct hisi_sas_hw { int delay_ms, int timeout_ms); void (*debugfs_snapshot_regs)(struct hisi_hba *hisi_hba); int complete_hdr_size; - struct scsi_host_template *sht; + const struct scsi_host_template *sht; }; #define HISI_SAS_MAX_DEBUGFS_DUMP (50) @@ -484,6 +485,8 @@ struct hisi_hba { struct dentry *debugfs_dump_dentry; struct dentry *debugfs_bist_dentry; struct dentry *debugfs_fifo_dentry; + + int iopoll_q_cnt; }; /* Generic HW DMA host memory structures */ @@ -653,16 +656,18 @@ extern void hisi_sas_phy_down(struct hisi_hba *hisi_hba, int phy_no, int rdy, extern void hisi_sas_phy_bcast(struct hisi_sas_phy *phy); extern void hisi_sas_slot_task_free(struct hisi_hba *hisi_hba, struct sas_task *task, - struct hisi_sas_slot *slot); + struct hisi_sas_slot *slot, + bool need_lock); extern void hisi_sas_init_mem(struct hisi_hba *hisi_hba); extern void hisi_sas_rst_work_handler(struct work_struct *work); extern void hisi_sas_sync_rst_work_handler(struct work_struct *work); -extern void hisi_sas_sync_irqs(struct hisi_hba *hisi_hba); extern void hisi_sas_phy_oob_ready(struct hisi_hba *hisi_hba, int phy_no); extern bool hisi_sas_notify_phy_event(struct hisi_sas_phy *phy, enum hisi_sas_phy_event event); extern void hisi_sas_release_tasks(struct hisi_hba *hisi_hba); extern u8 hisi_sas_get_prog_phy_linkrate_mask(enum sas_linkrate max); +extern void hisi_sas_sync_cqs(struct hisi_hba *hisi_hba); +extern void hisi_sas_sync_poll_cqs(struct hisi_hba *hisi_hba); extern void hisi_sas_controller_reset_prepare(struct hisi_hba *hisi_hba); extern void hisi_sas_controller_reset_done(struct hisi_hba *hisi_hba); #endif diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c index 8c038ccf1c09..412431c901a7 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_main.c +++ b/drivers/scsi/hisi_sas/hisi_sas_main.c @@ -205,7 +205,7 @@ static int hisi_sas_slot_index_alloc(struct hisi_hba *hisi_hba, } void hisi_sas_slot_task_free(struct hisi_hba *hisi_hba, struct sas_task *task, - struct hisi_sas_slot *slot) + struct hisi_sas_slot *slot, bool need_lock) { int device_id = slot->device_id; struct hisi_sas_device *sas_dev = &hisi_hba->devices[device_id]; @@ -239,9 +239,13 @@ void hisi_sas_slot_task_free(struct hisi_hba *hisi_hba, struct sas_task *task, } } - spin_lock(&sas_dev->lock); - list_del_init(&slot->entry); - spin_unlock(&sas_dev->lock); + if (need_lock) { + spin_lock(&sas_dev->lock); + list_del_init(&slot->entry); + spin_unlock(&sas_dev->lock); + } else { + list_del_init(&slot->entry); + } memset(slot, 0, offsetof(struct hisi_sas_slot, buf)); @@ -529,10 +533,21 @@ static int hisi_sas_queue_command(struct sas_task *task, gfp_t gfp_flags) dq_index = blk_mq_unique_tag_to_hwq(blk_tag); dq = &hisi_hba->dq[dq_index]; } else { - struct Scsi_Host *shost = hisi_hba->shost; - struct blk_mq_queue_map *qmap = &shost->tag_set.map[HCTX_TYPE_DEFAULT]; - int queue = qmap->mq_map[raw_smp_processor_id()]; + int queue; + + if (hisi_hba->iopoll_q_cnt) { + /* + * Use interrupt queue (queue 0) to deliver and complete + * internal IOs of libsas or libata when there is at least + * one iopoll queue + */ + queue = 0; + } else { + struct Scsi_Host *shost = hisi_hba->shost; + struct blk_mq_queue_map *qmap = &shost->tag_set.map[HCTX_TYPE_DEFAULT]; + queue = qmap->mq_map[raw_smp_processor_id()]; + } dq = &hisi_hba->dq[queue]; } break; @@ -672,6 +687,55 @@ static struct hisi_sas_device *hisi_sas_alloc_dev(struct domain_device *device) return sas_dev; } +static void hisi_sas_sync_poll_cq(struct hisi_sas_cq *cq) +{ + /* make sure CQ entries being processed are processed to completion */ + spin_lock(&cq->poll_lock); + spin_unlock(&cq->poll_lock); +} + +static bool hisi_sas_queue_is_poll(struct hisi_sas_cq *cq) +{ + struct hisi_hba *hisi_hba = cq->hisi_hba; + + if (cq->id < hisi_hba->queue_count - hisi_hba->iopoll_q_cnt) + return false; + return true; +} + +static void hisi_sas_sync_cq(struct hisi_sas_cq *cq) +{ + if (hisi_sas_queue_is_poll(cq)) + hisi_sas_sync_poll_cq(cq); + else + synchronize_irq(cq->irq_no); +} + +void hisi_sas_sync_poll_cqs(struct hisi_hba *hisi_hba) +{ + int i; + + for (i = 0; i < hisi_hba->queue_count; i++) { + struct hisi_sas_cq *cq = &hisi_hba->cq[i]; + + if (hisi_sas_queue_is_poll(cq)) + hisi_sas_sync_poll_cq(cq); + } +} +EXPORT_SYMBOL_GPL(hisi_sas_sync_poll_cqs); + +void hisi_sas_sync_cqs(struct hisi_hba *hisi_hba) +{ + int i; + + for (i = 0; i < hisi_hba->queue_count; i++) { + struct hisi_sas_cq *cq = &hisi_hba->cq[i]; + + hisi_sas_sync_cq(cq); + } +} +EXPORT_SYMBOL_GPL(hisi_sas_sync_cqs); + static void hisi_sas_tmf_aborted(struct sas_task *task) { struct hisi_sas_slot *slot = task->lldd_task; @@ -683,10 +747,10 @@ static void hisi_sas_tmf_aborted(struct sas_task *task) struct hisi_sas_cq *cq = &hisi_hba->cq[slot->dlvry_queue]; /* - * sync irq to avoid free'ing task + * sync irq or poll queue to avoid free'ing task * before using task in IO completion */ - synchronize_irq(cq->irq_no); + hisi_sas_sync_cq(cq); slot->task = NULL; } } @@ -1021,7 +1085,7 @@ static void hisi_sas_port_notify_formed(struct asd_sas_phy *sas_phy) } static void hisi_sas_do_release_task(struct hisi_hba *hisi_hba, struct sas_task *task, - struct hisi_sas_slot *slot) + struct hisi_sas_slot *slot, bool need_lock) { if (task) { unsigned long flags; @@ -1038,7 +1102,7 @@ static void hisi_sas_do_release_task(struct hisi_hba *hisi_hba, struct sas_task spin_unlock_irqrestore(&task->task_state_lock, flags); } - hisi_sas_slot_task_free(hisi_hba, task, slot); + hisi_sas_slot_task_free(hisi_hba, task, slot, need_lock); } static void hisi_sas_release_task(struct hisi_hba *hisi_hba, @@ -1047,8 +1111,11 @@ static void hisi_sas_release_task(struct hisi_hba *hisi_hba, struct hisi_sas_slot *slot, *slot2; struct hisi_sas_device *sas_dev = device->lldd_dev; + spin_lock(&sas_dev->lock); list_for_each_entry_safe(slot, slot2, &sas_dev->list, entry) - hisi_sas_do_release_task(hisi_hba, slot->task, slot); + hisi_sas_do_release_task(hisi_hba, slot->task, slot, false); + + spin_unlock(&sas_dev->lock); } void hisi_sas_release_tasks(struct hisi_hba *hisi_hba) @@ -1453,13 +1520,41 @@ void hisi_sas_controller_reset_prepare(struct hisi_hba *hisi_hba) } EXPORT_SYMBOL_GPL(hisi_sas_controller_reset_prepare); +static void hisi_sas_async_init_wait_phyup(void *data, async_cookie_t cookie) +{ + struct hisi_sas_phy *phy = data; + struct hisi_hba *hisi_hba = phy->hisi_hba; + struct device *dev = hisi_hba->dev; + DECLARE_COMPLETION_ONSTACK(completion); + int phy_no = phy->sas_phy.id; + + phy->reset_completion = &completion; + hisi_sas_phy_enable(hisi_hba, phy_no, 1); + if (!wait_for_completion_timeout(&completion, + HISI_SAS_WAIT_PHYUP_TIMEOUT)) + dev_warn(dev, "phy%d wait phyup timed out\n", phy_no); + + phy->reset_completion = NULL; +} + void hisi_sas_controller_reset_done(struct hisi_hba *hisi_hba) { struct Scsi_Host *shost = hisi_hba->shost; + ASYNC_DOMAIN_EXCLUSIVE(async); + int phy_no; /* Init and wait for PHYs to come up and all libsas event finished. */ - hisi_hba->hw->phys_init(hisi_hba); - msleep(1000); + for (phy_no = 0; phy_no < hisi_hba->n_phy; phy_no++) { + struct hisi_sas_phy *phy = &hisi_hba->phy[phy_no]; + + if (!(hisi_hba->phy_state & BIT(phy_no))) + continue; + + async_schedule_domain(hisi_sas_async_init_wait_phyup, + phy, &async); + } + + async_synchronize_full_domain(&async); hisi_sas_refresh_port_id(hisi_hba); clear_bit(HISI_SAS_REJECT_CMD_BIT, &hisi_hba->flags); @@ -1540,11 +1635,11 @@ static int hisi_sas_abort_task(struct sas_task *task) if (slot) { /* - * sync irq to avoid free'ing task + * sync irq or poll queue to avoid free'ing task * before using task in IO completion */ cq = &hisi_hba->cq[slot->dlvry_queue]; - synchronize_irq(cq->irq_no); + hisi_sas_sync_cq(cq); } spin_unlock_irqrestore(&task->task_state_lock, flags); rc = TMF_RESP_FUNC_COMPLETE; @@ -1574,7 +1669,7 @@ static int hisi_sas_abort_task(struct sas_task *task) */ if (rc == TMF_RESP_FUNC_COMPLETE && rc2 != TMF_RESP_FUNC_SUCC) { if (task->lldd_task) - hisi_sas_do_release_task(hisi_hba, task, slot); + hisi_sas_do_release_task(hisi_hba, task, slot, true); } } else if (task->task_proto & SAS_PROTOCOL_SATA || task->task_proto & SAS_PROTOCOL_STP) { @@ -1594,7 +1689,7 @@ static int hisi_sas_abort_task(struct sas_task *task) */ if ((sas_dev->dev_status == HISI_SAS_DEV_NCQ_ERR) && qc && qc->scsicmd) { - hisi_sas_do_release_task(hisi_hba, task, slot); + hisi_sas_do_release_task(hisi_hba, task, slot, true); rc = TMF_RESP_FUNC_COMPLETE; } else { rc = hisi_sas_softreset_ata_disk(device); @@ -1611,10 +1706,10 @@ static int hisi_sas_abort_task(struct sas_task *task) if (((rc < 0) || (rc == TMF_RESP_FUNC_FAILED)) && task->lldd_task) { /* - * sync irq to avoid free'ing task + * sync irq or poll queue to avoid free'ing task * before using task in IO completion */ - synchronize_irq(cq->irq_no); + hisi_sas_sync_cq(cq); slot->task = NULL; } } @@ -1885,10 +1980,10 @@ static bool hisi_sas_internal_abort_timeout(struct sas_task *task, struct hisi_sas_cq *cq = &hisi_hba->cq[slot->dlvry_queue]; /* - * sync irq to avoid free'ing task + * sync irq or poll queue to avoid free'ing task * before using task in IO completion */ - synchronize_irq(cq->irq_no); + hisi_sas_sync_cq(cq); slot->task = NULL; } @@ -1992,18 +2087,6 @@ void hisi_sas_phy_bcast(struct hisi_sas_phy *phy) } EXPORT_SYMBOL_GPL(hisi_sas_phy_bcast); -void hisi_sas_sync_irqs(struct hisi_hba *hisi_hba) -{ - int i; - - for (i = 0; i < hisi_hba->cq_nvecs; i++) { - struct hisi_sas_cq *cq = &hisi_hba->cq[i]; - - synchronize_irq(cq->irq_no); - } -} -EXPORT_SYMBOL_GPL(hisi_sas_sync_irqs); - int hisi_sas_host_reset(struct Scsi_Host *shost, int reset_type) { struct hisi_hba *hisi_hba = shost_priv(shost); @@ -2101,6 +2184,7 @@ int hisi_sas_alloc(struct hisi_hba *hisi_hba) /* Completion queue structure */ cq->id = i; cq->hisi_hba = hisi_hba; + spin_lock_init(&cq->poll_lock); /* Delivery queue structure */ spin_lock_init(&dq->lock); diff --git a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c index d643c5a49aa9..0aa8c9c88535 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c +++ b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c @@ -1258,7 +1258,11 @@ static void slot_complete_v1_hw(struct hisi_hba *hisi_hba, slot_err_v1_hw(hisi_hba, task, slot); if (unlikely(slot->abort)) { - sas_task_abort(task); + if (dev_is_sata(device) && task->ata_task.use_ncq) + sas_ata_device_link_abort(device, true); + else + sas_task_abort(task); + return; } goto out; @@ -1306,7 +1310,7 @@ static void slot_complete_v1_hw(struct hisi_hba *hisi_hba, } out: - hisi_sas_slot_task_free(hisi_hba, task, slot); + hisi_sas_slot_task_free(hisi_hba, task, slot, true); if (task->task_done) task->task_done(task); @@ -1735,7 +1739,7 @@ static struct attribute *host_v1_hw_attrs[] = { ATTRIBUTE_GROUPS(host_v1_hw); -static struct scsi_host_template sht_v1_hw = { +static const struct scsi_host_template sht_v1_hw = { .name = DRV_NAME, .proc_name = DRV_NAME, .module = THIS_MODULE, diff --git a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c index cded42f4ca44..cd78e4c983aa 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c +++ b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c @@ -2404,7 +2404,11 @@ static void slot_complete_v2_hw(struct hisi_hba *hisi_hba, error_info[2], error_info[3]); if (unlikely(slot->abort)) { - sas_task_abort(task); + if (dev_is_sata(device) && task->ata_task.use_ncq) + sas_ata_device_link_abort(device, true); + else + sas_task_abort(task); + return; } goto out; @@ -2462,7 +2466,7 @@ out: } task->task_state_flags |= SAS_TASK_STATE_DONE; spin_unlock_irqrestore(&task->task_state_lock, flags); - hisi_sas_slot_task_free(hisi_hba, task, slot); + hisi_sas_slot_task_free(hisi_hba, task, slot, true); if (!is_internal && (task->task_proto != SAS_PROTOCOL_SMP)) { spin_lock_irqsave(&device->done_lock, flags); @@ -3551,7 +3555,7 @@ static void map_queues_v2_hw(struct Scsi_Host *shost) } } -static struct scsi_host_template sht_v2_hw = { +static const struct scsi_host_template sht_v2_hw = { .name = DRV_NAME, .proc_name = DRV_NAME, .module = THIS_MODULE, diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c index a63279f55d09..12d588454f5d 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c @@ -552,6 +552,11 @@ static int prot_mask; module_param(prot_mask, int, 0444); MODULE_PARM_DESC(prot_mask, " host protection capabilities mask, def=0x0 "); +/* the index of iopoll queues are bigger than interrupt queues' */ +static int experimental_iopoll_q_cnt; +module_param(experimental_iopoll_q_cnt, int, 0444); +MODULE_PARM_DESC(experimental_iopoll_q_cnt, "number of queues to be used as poll mode, def=0"); + static void debugfs_work_handler_v3_hw(struct work_struct *work); static void debugfs_snapshot_regs_v3_hw(struct hisi_hba *hisi_hba); @@ -599,6 +604,27 @@ static u32 hisi_sas_phy_read32(struct hisi_hba *hisi_hba, readl_poll_timeout_atomic(regs, val, cond, delay_us, timeout_us);\ }) +static void interrupt_enable_v3_hw(struct hisi_hba *hisi_hba) +{ + int i; + + for (i = 0; i < hisi_hba->queue_count; i++) + hisi_sas_write32(hisi_hba, OQ0_INT_SRC_MSK + 0x4 * i, 0); + + hisi_sas_write32(hisi_hba, ENT_INT_SRC_MSK1, 0xfefefefe); + hisi_sas_write32(hisi_hba, ENT_INT_SRC_MSK2, 0xfefefefe); + hisi_sas_write32(hisi_hba, ENT_INT_SRC_MSK3, 0xffc220ff); + hisi_sas_write32(hisi_hba, SAS_ECC_INTR_MSK, 0x155555); + + for (i = 0; i < hisi_hba->n_phy; i++) { + hisi_sas_phy_write32(hisi_hba, i, CHL_INT1_MSK, 0xf2057fff); + hisi_sas_phy_write32(hisi_hba, i, CHL_INT2_MSK, 0xffffbfe); + hisi_sas_phy_write32(hisi_hba, i, PHYCTRL_NOT_RDY_MSK, 0x0); + hisi_sas_phy_write32(hisi_hba, i, PHYCTRL_PHY_ENA_MSK, 0x0); + hisi_sas_phy_write32(hisi_hba, i, SL_RX_BCAST_CHK_MSK, 0x0); + } +} + static void init_reg_v3_hw(struct hisi_hba *hisi_hba) { int i, j; @@ -619,20 +645,14 @@ static void init_reg_v3_hw(struct hisi_hba *hisi_hba) hisi_sas_write32(hisi_hba, ENT_INT_SRC1, 0xffffffff); hisi_sas_write32(hisi_hba, ENT_INT_SRC2, 0xffffffff); hisi_sas_write32(hisi_hba, ENT_INT_SRC3, 0xffffffff); - hisi_sas_write32(hisi_hba, ENT_INT_SRC_MSK1, 0xfefefefe); - hisi_sas_write32(hisi_hba, ENT_INT_SRC_MSK2, 0xfefefefe); - hisi_sas_write32(hisi_hba, ENT_INT_SRC_MSK3, 0xffc220ff); hisi_sas_write32(hisi_hba, CHNL_PHYUPDOWN_INT_MSK, 0x0); hisi_sas_write32(hisi_hba, CHNL_ENT_INT_MSK, 0x0); hisi_sas_write32(hisi_hba, HGC_COM_INT_MSK, 0x0); - hisi_sas_write32(hisi_hba, SAS_ECC_INTR_MSK, 0x155555); hisi_sas_write32(hisi_hba, AWQOS_AWCACHE_CFG, 0xf0f0); hisi_sas_write32(hisi_hba, ARQOS_ARCACHE_CFG, 0xf0f0); - for (i = 0; i < hisi_hba->queue_count; i++) - hisi_sas_write32(hisi_hba, OQ0_INT_SRC_MSK + 0x4 * i, 0); - hisi_sas_write32(hisi_hba, HYPER_STREAM_ID_EN_CFG, 1); + interrupt_enable_v3_hw(hisi_hba); for (i = 0; i < hisi_hba->n_phy; i++) { enum sas_linkrate max; struct hisi_sas_phy *phy = &hisi_hba->phy[i]; @@ -655,13 +675,8 @@ static void init_reg_v3_hw(struct hisi_hba *hisi_hba) hisi_sas_phy_write32(hisi_hba, i, CHL_INT1, 0xffffffff); hisi_sas_phy_write32(hisi_hba, i, CHL_INT2, 0xffffffff); hisi_sas_phy_write32(hisi_hba, i, RXOP_CHECK_CFG_H, 0x1000); - hisi_sas_phy_write32(hisi_hba, i, CHL_INT1_MSK, 0xf2057fff); - hisi_sas_phy_write32(hisi_hba, i, CHL_INT2_MSK, 0xffffbfe); hisi_sas_phy_write32(hisi_hba, i, PHY_CTRL_RDY_MSK, 0x0); - hisi_sas_phy_write32(hisi_hba, i, PHYCTRL_NOT_RDY_MSK, 0x0); hisi_sas_phy_write32(hisi_hba, i, PHYCTRL_DWS_RESET_MSK, 0x0); - hisi_sas_phy_write32(hisi_hba, i, PHYCTRL_PHY_ENA_MSK, 0x0); - hisi_sas_phy_write32(hisi_hba, i, SL_RX_BCAST_CHK_MSK, 0x0); hisi_sas_phy_write32(hisi_hba, i, PHYCTRL_OOB_RESTART_MSK, 0x1); hisi_sas_phy_write32(hisi_hba, i, STP_LINK_TIMER, 0x7f7a120); hisi_sas_phy_write32(hisi_hba, i, CON_CFG_DRIVER, 0x2a0a01); @@ -883,6 +898,7 @@ static void dereg_device_v3_hw(struct hisi_hba *hisi_hba, cfg_abt_set_query_iptt = hisi_sas_read32(hisi_hba, CFG_ABT_SET_QUERY_IPTT); + spin_lock(&sas_dev->lock); list_for_each_entry_safe(slot, slot2, &sas_dev->list, entry) { cfg_abt_set_query_iptt &= ~CFG_SET_ABORTED_IPTT_MSK; cfg_abt_set_query_iptt |= (1 << CFG_SET_ABORTED_EN_OFF) | @@ -890,6 +906,7 @@ static void dereg_device_v3_hw(struct hisi_hba *hisi_hba, hisi_sas_write32(hisi_hba, CFG_ABT_SET_QUERY_IPTT, cfg_abt_set_query_iptt); } + spin_unlock(&sas_dev->lock); cfg_abt_set_query_iptt &= ~(1 << CFG_SET_ABORTED_EN_OFF); hisi_sas_write32(hisi_hba, CFG_ABT_SET_QUERY_IPTT, cfg_abt_set_query_iptt); @@ -2320,7 +2337,11 @@ static void slot_complete_v3_hw(struct hisi_hba *hisi_hba, error_info[0], error_info[1], error_info[2], error_info[3]); if (unlikely(slot->abort)) { - sas_task_abort(task); + if (dev_is_sata(device) && task->ata_task.use_ncq) + sas_ata_device_link_abort(device, true); + else + sas_task_abort(task); + return; } goto out; @@ -2374,7 +2395,7 @@ out: } task->task_state_flags |= SAS_TASK_STATE_DONE; spin_unlock_irqrestore(&task->task_state_lock, flags); - hisi_sas_slot_task_free(hisi_hba, task, slot); + hisi_sas_slot_task_free(hisi_hba, task, slot, true); if (!is_internal && (task->task_proto != SAS_PROTOCOL_SMP)) { spin_lock_irqsave(&device->done_lock, flags); @@ -2391,23 +2412,25 @@ out: task->task_done(task); } -static irqreturn_t cq_thread_v3_hw(int irq_no, void *p) +static int complete_v3_hw(struct hisi_sas_cq *cq) { - struct hisi_sas_cq *cq = p; - struct hisi_hba *hisi_hba = cq->hisi_hba; - struct hisi_sas_slot *slot; struct hisi_sas_complete_v3_hdr *complete_queue; - u32 rd_point = cq->rd_point, wr_point; + struct hisi_hba *hisi_hba = cq->hisi_hba; + u32 rd_point, wr_point; int queue = cq->id; + int completed; + rd_point = cq->rd_point; complete_queue = hisi_hba->complete_hdr[queue]; wr_point = hisi_sas_read32(hisi_hba, COMPL_Q_0_WR_PTR + (0x14 * queue)); + completed = (wr_point + HISI_SAS_QUEUE_SLOTS - rd_point) % HISI_SAS_QUEUE_SLOTS; while (rd_point != wr_point) { struct hisi_sas_complete_v3_hdr *complete_hdr; struct device *dev = hisi_hba->dev; + struct hisi_sas_slot *slot; u32 dw0, dw1, dw3; int iptt; @@ -2451,6 +2474,28 @@ static irqreturn_t cq_thread_v3_hw(int irq_no, void *p) cq->rd_point = rd_point; hisi_sas_write32(hisi_hba, COMPL_Q_0_RD_PTR + (0x14 * queue), rd_point); + return completed; +} + +static int queue_complete_v3_hw(struct Scsi_Host *shost, unsigned int queue) +{ + struct hisi_hba *hisi_hba = shost_priv(shost); + struct hisi_sas_cq *cq = &hisi_hba->cq[queue]; + int completed; + + spin_lock(&cq->poll_lock); + completed = complete_v3_hw(cq); + spin_unlock(&cq->poll_lock); + + return completed; +} + +static irqreturn_t cq_thread_v3_hw(int irq_no, void *p) +{ + struct hisi_sas_cq *cq = p; + + complete_v3_hw(cq); + return IRQ_HANDLED; } @@ -2474,8 +2519,9 @@ static void hisi_sas_v3_free_vectors(void *data) static int interrupt_preinit_v3_hw(struct hisi_hba *hisi_hba) { - int vectors; - int max_msi = HISI_SAS_MSI_COUNT_V3_HW, min_msi; + /* Allocate all MSI vectors to avoid re-insertion issue */ + int max_msi = HISI_SAS_MSI_COUNT_V3_HW; + int vectors, min_msi; struct Scsi_Host *shost = hisi_hba->shost; struct pci_dev *pdev = hisi_hba->pci_dev; struct irq_affinity desc = { @@ -2492,8 +2538,8 @@ static int interrupt_preinit_v3_hw(struct hisi_hba *hisi_hba) return -ENOENT; - hisi_hba->cq_nvecs = vectors - BASE_VECTORS_V3_HW; - shost->nr_hw_queues = hisi_hba->cq_nvecs; + hisi_hba->cq_nvecs = vectors - BASE_VECTORS_V3_HW - hisi_hba->iopoll_q_cnt; + shost->nr_hw_queues = hisi_hba->cq_nvecs + hisi_hba->iopoll_q_cnt; return devm_add_action(&pdev->dev, hisi_sas_v3_free_vectors, pdev); } @@ -2625,7 +2671,7 @@ static int disable_host_v3_hw(struct hisi_hba *hisi_hba) u32 status, reg_val; int rc; - interrupt_disable_v3_hw(hisi_hba); + hisi_sas_sync_poll_cqs(hisi_hba); hisi_sas_write32(hisi_hba, DLVRY_QUEUE_ENABLE, 0x0); hisi_sas_stop_phys(hisi_hba); @@ -2655,6 +2701,7 @@ static int soft_reset_v3_hw(struct hisi_hba *hisi_hba) struct device *dev = hisi_hba->dev; int rc; + interrupt_disable_v3_hw(hisi_hba); rc = disable_host_v3_hw(hisi_hba); if (rc) { dev_err(dev, "soft reset: disable host failed rc=%d\n", rc); @@ -2823,6 +2870,18 @@ static ssize_t intr_coal_count_v3_hw_store(struct device *dev, } static DEVICE_ATTR_RW(intr_coal_count_v3_hw); +static ssize_t iopoll_q_cnt_v3_hw_show(struct device *dev, + struct device_attribute + *attr, char *buf) +{ + struct Scsi_Host *shost = class_to_shost(dev); + struct hisi_hba *hisi_hba = shost_priv(shost); + + return scnprintf(buf, PAGE_SIZE, "%u\n", + hisi_hba->iopoll_q_cnt); +} +static DEVICE_ATTR_RO(iopoll_q_cnt_v3_hw); + static int slave_configure_v3_hw(struct scsi_device *sdev) { struct Scsi_Host *shost = dev_to_shost(&sdev->sdev_gendev); @@ -2852,6 +2911,7 @@ static struct attribute *host_v3_hw_attrs[] = { &dev_attr_intr_conv_v3_hw.attr, &dev_attr_intr_coal_ticks_v3_hw.attr, &dev_attr_intr_coal_count_v3_hw.attr, + &dev_attr_iopoll_q_cnt_v3_hw.attr, NULL }; @@ -3038,7 +3098,7 @@ static void debugfs_snapshot_prepare_v3_hw(struct hisi_hba *hisi_hba) wait_cmds_complete_timeout_v3_hw(hisi_hba, 100, 5000); - hisi_sas_sync_irqs(hisi_hba); + hisi_sas_sync_cqs(hisi_hba); } static void debugfs_snapshot_restore_v3_hw(struct hisi_hba *hisi_hba) @@ -3210,12 +3270,34 @@ static int debugfs_set_bist_v3_hw(struct hisi_hba *hisi_hba, bool enable) static void hisi_sas_map_queues(struct Scsi_Host *shost) { struct hisi_hba *hisi_hba = shost_priv(shost); - struct blk_mq_queue_map *qmap = &shost->tag_set.map[HCTX_TYPE_DEFAULT]; + struct blk_mq_queue_map *qmap; + int i, qoff; + + for (i = 0, qoff = 0; i < shost->nr_maps; i++) { + qmap = &shost->tag_set.map[i]; + if (i == HCTX_TYPE_DEFAULT) { + qmap->nr_queues = hisi_hba->cq_nvecs; + } else if (i == HCTX_TYPE_POLL) { + qmap->nr_queues = hisi_hba->iopoll_q_cnt; + } else { + qmap->nr_queues = 0; + continue; + } - blk_mq_pci_map_queues(qmap, hisi_hba->pci_dev, BASE_VECTORS_V3_HW); + /* At least one interrupt hardware queue */ + if (!qmap->nr_queues) + WARN_ON(i == HCTX_TYPE_DEFAULT); + qmap->queue_offset = qoff; + if (i == HCTX_TYPE_POLL) + blk_mq_map_queues(qmap); + else + blk_mq_pci_map_queues(qmap, hisi_hba->pci_dev, + BASE_VECTORS_V3_HW); + qoff += qmap->nr_queues; + } } -static struct scsi_host_template sht_v3_hw = { +static const struct scsi_host_template sht_v3_hw = { .name = DRV_NAME, .proc_name = DRV_NAME, .module = THIS_MODULE, @@ -3244,6 +3326,7 @@ static struct scsi_host_template sht_v3_hw = { .tag_alloc_policy = BLK_TAG_ALLOC_RR, .host_reset = hisi_sas_host_reset, .host_tagset = 1, + .mq_poll = queue_complete_v3_hw, }; static const struct hisi_sas_hw hisi_sas_v3_hw = { @@ -3303,6 +3386,13 @@ hisi_sas_shost_alloc_pci(struct pci_dev *pdev) if (hisi_sas_get_fw_info(hisi_hba) < 0) goto err_out; + if (experimental_iopoll_q_cnt < 0 || + experimental_iopoll_q_cnt >= hisi_hba->queue_count) + dev_err(dev, "iopoll queue count %d cannot exceed or equal 16, using default 0\n", + experimental_iopoll_q_cnt); + else + hisi_hba->iopoll_q_cnt = experimental_iopoll_q_cnt; + if (hisi_sas_alloc(hisi_hba)) { hisi_sas_free(hisi_hba); goto err_out; @@ -4858,6 +4948,10 @@ hisi_sas_v3_probe(struct pci_dev *pdev, const struct pci_device_id *id) shost->max_cmd_len = 16; shost->can_queue = HISI_SAS_UNRESERVED_IPTT; shost->cmd_per_lun = HISI_SAS_UNRESERVED_IPTT; + if (hisi_hba->iopoll_q_cnt) + shost->nr_maps = 3; + else + shost->nr_maps = 1; sha->sas_ha_name = DRV_NAME; sha->dev = dev; @@ -4976,6 +5070,7 @@ static void hisi_sas_reset_prepare_v3_hw(struct pci_dev *pdev) set_bit(HISI_SAS_RESETTING_BIT, &hisi_hba->flags); hisi_sas_controller_reset_prepare(hisi_hba); + interrupt_disable_v3_hw(hisi_hba); rc = disable_host_v3_hw(hisi_hba); if (rc) dev_err(dev, "FLR: disable host failed rc=%d\n", rc); @@ -5005,6 +5100,21 @@ enum { hip08, }; +static void enable_host_v3_hw(struct hisi_hba *hisi_hba) +{ + u32 reg_val; + + hisi_sas_write32(hisi_hba, DLVRY_QUEUE_ENABLE, + (u32)((1ULL << hisi_hba->queue_count) - 1)); + + phys_init_v3_hw(hisi_hba); + reg_val = hisi_sas_read32(hisi_hba, AXI_MASTER_CFG_BASE + + AM_CTRL_GLOBAL); + reg_val &= ~AM_CTRL_SHUTDOWN_REQ_MSK; + hisi_sas_write32(hisi_hba, AXI_MASTER_CFG_BASE + + AM_CTRL_GLOBAL, reg_val); +} + static int _suspend_v3_hw(struct device *device) { struct pci_dev *pdev = to_pci_dev(device); @@ -5027,14 +5137,20 @@ static int _suspend_v3_hw(struct device *device) scsi_block_requests(shost); set_bit(HISI_SAS_REJECT_CMD_BIT, &hisi_hba->flags); flush_workqueue(hisi_hba->wq); + interrupt_disable_v3_hw(hisi_hba); + +#ifdef CONFIG_PM + if (atomic_read(&device->power.usage_count)) { + dev_err(dev, "PM suspend: host status cannot be suspended\n"); + rc = -EBUSY; + goto err_out; + } +#endif rc = disable_host_v3_hw(hisi_hba); 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_RESETTING_BIT, &hisi_hba->flags); - scsi_unblock_requests(shost); - return rc; + goto err_out_recover_host; } hisi_sas_init_mem(hisi_hba); @@ -5045,6 +5161,17 @@ static int _suspend_v3_hw(struct device *device) dev_warn(dev, "end of suspending controller\n"); return 0; + +err_out_recover_host: + enable_host_v3_hw(hisi_hba); +#ifdef CONFIG_PM +err_out: +#endif + interrupt_enable_v3_hw(hisi_hba); + clear_bit(HISI_SAS_REJECT_CMD_BIT, &hisi_hba->flags); + clear_bit(HISI_SAS_RESETTING_BIT, &hisi_hba->flags); + scsi_unblock_requests(shost); + return rc; } static int _resume_v3_hw(struct device *device) diff --git a/drivers/scsi/hosts.c b/drivers/scsi/hosts.c index 9b6fbbe15d92..f0bc8bbb3938 100644 --- a/drivers/scsi/hosts.c +++ b/drivers/scsi/hosts.c @@ -219,7 +219,7 @@ EXPORT_SYMBOL(scsi_remove_host); int scsi_add_host_with_dma(struct Scsi_Host *shost, struct device *dev, struct device *dma_dev) { - struct scsi_host_template *sht = shost->hostt; + const struct scsi_host_template *sht = shost->hostt; int error = -EINVAL; shost_printk(KERN_INFO, shost, "%s\n", @@ -389,7 +389,7 @@ static struct device_type scsi_host_type = { * Return value: * Pointer to a new Scsi_Host **/ -struct Scsi_Host *scsi_host_alloc(struct scsi_host_template *sht, int privsize) +struct Scsi_Host *scsi_host_alloc(const struct scsi_host_template *sht, int privsize) { struct Scsi_Host *shost; int index; diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c index f6da34850af9..af18d20f3079 100644 --- a/drivers/scsi/hpsa.c +++ b/drivers/scsi/hpsa.c @@ -967,7 +967,7 @@ ATTRIBUTE_GROUPS(hpsa_shost); #define HPSA_NRESERVED_CMDS (HPSA_CMDS_RESERVED_FOR_DRIVER +\ HPSA_MAX_CONCURRENT_PASSTHRUS) -static struct scsi_host_template hpsa_driver_template = { +static const struct scsi_host_template hpsa_driver_template = { .module = THIS_MODULE, .name = HPSA, .proc_name = HPSA, @@ -9108,7 +9108,6 @@ static void hpsa_remove_one(struct pci_dev *pdev) free_percpu(h->lockup_detected); /* init_one 2 */ h->lockup_detected = NULL; /* init_one 2 */ - /* (void) pci_disable_pcie_error_reporting(pdev); */ /* init_one 1 */ hpda_free_ctlr_info(h); /* init_one 1 */ } @@ -9476,8 +9475,6 @@ static void hpsa_free_performant_mode(struct ctlr_info *h) static int hpsa_put_ctlr_into_performant_mode(struct ctlr_info *h) { u32 trans_support; - unsigned long transMethod = CFGTBL_Trans_Performant | - CFGTBL_Trans_use_short_tags; int i, rc; if (hpsa_simple_mode) @@ -9489,14 +9486,10 @@ static int hpsa_put_ctlr_into_performant_mode(struct ctlr_info *h) /* Check for I/O accelerator mode support */ if (trans_support & CFGTBL_Trans_io_accel1) { - transMethod |= CFGTBL_Trans_io_accel1 | - CFGTBL_Trans_enable_directed_msix; rc = hpsa_alloc_ioaccel1_cmd_and_bft(h); if (rc) return rc; } else if (trans_support & CFGTBL_Trans_io_accel2) { - transMethod |= CFGTBL_Trans_io_accel2 | - CFGTBL_Trans_enable_directed_msix; rc = hpsa_alloc_ioaccel2_cmd_and_bft(h); if (rc) return rc; diff --git a/drivers/scsi/hptiop.c b/drivers/scsi/hptiop.c index 7e8903718245..06ccb51bf6a9 100644 --- a/drivers/scsi/hptiop.c +++ b/drivers/scsi/hptiop.c @@ -1159,7 +1159,7 @@ static int hptiop_slave_config(struct scsi_device *sdev) return 0; } -static struct scsi_host_template driver_template = { +static const struct scsi_host_template driver_template = { .module = THIS_MODULE, .name = driver_name, .queuecommand = hptiop_queuecommand, diff --git a/drivers/scsi/ibmvscsi/ibmvfc.c b/drivers/scsi/ibmvscsi/ibmvfc.c index 1a0c0b7289d2..ce9eb00e2ca0 100644 --- a/drivers/scsi/ibmvscsi/ibmvfc.c +++ b/drivers/scsi/ibmvscsi/ibmvfc.c @@ -3611,7 +3611,7 @@ static struct attribute *ibmvfc_host_attrs[] = { ATTRIBUTE_GROUPS(ibmvfc_host); -static struct scsi_host_template driver_template = { +static const struct scsi_host_template driver_template = { .module = THIS_MODULE, .name = "IBM POWER Virtual FC Adapter", .proc_name = IBMVFC_NAME, diff --git a/drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c b/drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c index e8770310a64b..385f812b8793 100644 --- a/drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c +++ b/drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c @@ -3698,16 +3698,6 @@ static int ibmvscsis_check_true(struct se_portal_group *se_tpg) return 1; } -static int ibmvscsis_check_false(struct se_portal_group *se_tpg) -{ - return 0; -} - -static u32 ibmvscsis_tpg_get_inst_index(struct se_portal_group *se_tpg) -{ - return 1; -} - static int ibmvscsis_check_stop_free(struct se_cmd *se_cmd) { return target_put_sess_cmd(se_cmd); @@ -3726,11 +3716,6 @@ static void ibmvscsis_release_cmd(struct se_cmd *se_cmd) spin_unlock_bh(&vscsi->intr_lock); } -static u32 ibmvscsis_sess_get_index(struct se_session *se_sess) -{ - return 0; -} - static int ibmvscsis_write_pending(struct se_cmd *se_cmd) { struct ibmvscsis_cmd *cmd = container_of(se_cmd, struct ibmvscsis_cmd, @@ -3765,15 +3750,6 @@ static int ibmvscsis_write_pending(struct se_cmd *se_cmd) return 0; } -static void ibmvscsis_set_default_node_attrs(struct se_node_acl *nacl) -{ -} - -static int ibmvscsis_get_cmd_state(struct se_cmd *se_cmd) -{ - return 0; -} - static int ibmvscsis_queue_data_in(struct se_cmd *se_cmd) { struct ibmvscsis_cmd *cmd = container_of(se_cmd, struct ibmvscsis_cmd, @@ -3982,15 +3958,9 @@ static const struct target_core_fabric_ops ibmvscsis_ops = { .tpg_get_default_depth = ibmvscsis_get_default_depth, .tpg_check_demo_mode = ibmvscsis_check_true, .tpg_check_demo_mode_cache = ibmvscsis_check_true, - .tpg_check_demo_mode_write_protect = ibmvscsis_check_false, - .tpg_check_prod_mode_write_protect = ibmvscsis_check_false, - .tpg_get_inst_index = ibmvscsis_tpg_get_inst_index, .check_stop_free = ibmvscsis_check_stop_free, .release_cmd = ibmvscsis_release_cmd, - .sess_get_index = ibmvscsis_sess_get_index, .write_pending = ibmvscsis_write_pending, - .set_default_node_attributes = ibmvscsis_set_default_node_attrs, - .get_cmd_state = ibmvscsis_get_cmd_state, .queue_data_in = ibmvscsis_queue_data_in, .queue_status = ibmvscsis_queue_status, .queue_tm_rsp = ibmvscsis_queue_tm_rsp, diff --git a/drivers/scsi/imm.c b/drivers/scsi/imm.c index 7a499d621c25..07db98161a03 100644 --- a/drivers/scsi/imm.c +++ b/drivers/scsi/imm.c @@ -1096,7 +1096,7 @@ static int imm_adjust_queue(struct scsi_device *device) return 0; } -static struct scsi_host_template imm_template = { +static const struct scsi_host_template imm_template = { .module = THIS_MODULE, .proc_name = "imm", .show_info = imm_show_info, diff --git a/drivers/scsi/initio.c b/drivers/scsi/initio.c index 375261d67619..2a50fda3a628 100644 --- a/drivers/scsi/initio.c +++ b/drivers/scsi/initio.c @@ -2788,7 +2788,7 @@ static void i91uSCBPost(u8 * host_mem, u8 * cblk_mem) initio_release_scb(host, cblk); /* Release SCB for current channel */ } -static struct scsi_host_template initio_template = { +static const struct scsi_host_template initio_template = { .proc_name = "INI9100U", .name = "Initio INI-9X00U/UW SCSI device driver", .queuecommand = i91u_queuecommand, diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c index c74053f0b72f..4d3c280a7360 100644 --- a/drivers/scsi/ipr.c +++ b/drivers/scsi/ipr.c @@ -6736,7 +6736,7 @@ static const char *ipr_ioa_info(struct Scsi_Host *host) return buffer; } -static struct scsi_host_template driver_template = { +static const struct scsi_host_template driver_template = { .module = THIS_MODULE, .name = "IPR", .info = ipr_ioa_info, diff --git a/drivers/scsi/isci/init.c b/drivers/scsi/isci/init.c index e294d5d961eb..ac1e04b86d8f 100644 --- a/drivers/scsi/isci/init.c +++ b/drivers/scsi/isci/init.c @@ -149,7 +149,7 @@ static struct attribute *isci_host_attrs[] = { ATTRIBUTE_GROUPS(isci_host); -static struct scsi_host_template isci_sht = { +static const struct scsi_host_template isci_sht = { .module = THIS_MODULE, .name = DRV_NAME, diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c index 15f452908926..9637d4bc2bc9 100644 --- a/drivers/scsi/iscsi_tcp.c +++ b/drivers/scsi/iscsi_tcp.c @@ -47,7 +47,7 @@ MODULE_DESCRIPTION("iSCSI/TCP data-path"); MODULE_LICENSE("GPL"); static struct scsi_transport_template *iscsi_sw_tcp_scsi_transport; -static struct scsi_host_template iscsi_sw_tcp_sht; +static const struct scsi_host_template iscsi_sw_tcp_sht; static struct iscsi_transport iscsi_sw_tcp_transport; static unsigned int iscsi_max_lun = ~0; @@ -1071,7 +1071,7 @@ static int iscsi_sw_tcp_slave_configure(struct scsi_device *sdev) return 0; } -static struct scsi_host_template iscsi_sw_tcp_sht = { +static const struct scsi_host_template iscsi_sw_tcp_sht = { .module = THIS_MODULE, .name = "iSCSI Initiator over TCP/IP", .queuecommand = iscsi_queuecommand, diff --git a/drivers/scsi/jazz_esp.c b/drivers/scsi/jazz_esp.c index 60a88a95a8e2..0c842fb29aa0 100644 --- a/drivers/scsi/jazz_esp.c +++ b/drivers/scsi/jazz_esp.c @@ -104,7 +104,7 @@ static const struct esp_driver_ops jazz_esp_ops = { static int esp_jazz_probe(struct platform_device *dev) { - struct scsi_host_template *tpnt = &scsi_esp_template; + const struct scsi_host_template *tpnt = &scsi_esp_template; struct Scsi_Host *host; struct esp *esp; struct resource *res; diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c index 127f3d7f19dc..0fda8905eabd 100644 --- a/drivers/scsi/libiscsi.c +++ b/drivers/scsi/libiscsi.c @@ -2895,7 +2895,7 @@ EXPORT_SYMBOL_GPL(iscsi_host_add); * This should be called by partial offload and software iscsi drivers. * To access the driver specific memory use the iscsi_host_priv() macro. */ -struct Scsi_Host *iscsi_host_alloc(struct scsi_host_template *sht, +struct Scsi_Host *iscsi_host_alloc(const struct scsi_host_template *sht, int dd_data_size, bool xmit_can_sleep) { struct Scsi_Host *shost; diff --git a/drivers/scsi/libsas/sas_discover.c b/drivers/scsi/libsas/sas_discover.c index 72fdb2e5d047..8c6afe724944 100644 --- a/drivers/scsi/libsas/sas_discover.c +++ b/drivers/scsi/libsas/sas_discover.c @@ -360,6 +360,33 @@ static void sas_destruct_ports(struct asd_sas_port *port) } } +static bool sas_abort_cmd(struct request *req, void *data) +{ + struct scsi_cmnd *cmd = blk_mq_rq_to_pdu(req); + struct domain_device *dev = data; + + if (dev == cmd_to_domain_dev(cmd)) + blk_abort_request(req); + return true; +} + +static void sas_abort_device_scsi_cmds(struct domain_device *dev) +{ + struct sas_ha_struct *sas_ha = dev->port->ha; + struct Scsi_Host *shost = sas_ha->core.shost; + + if (dev_is_expander(dev->dev_type)) + return; + + /* + * For removed device with active IOs, the user space applications have + * to spend very long time waiting for the timeout. This is not + * necessary because a removed device will not return the IOs. + * Abort the inflight IOs here so that EH can be quickly kicked in. + */ + blk_mq_tagset_busy_iter(&shost->tag_set, sas_abort_cmd, dev); +} + void sas_unregister_dev(struct asd_sas_port *port, struct domain_device *dev) { if (!test_bit(SAS_DEV_DESTROY, &dev->state) && @@ -372,6 +399,8 @@ void sas_unregister_dev(struct asd_sas_port *port, struct domain_device *dev) } if (!test_and_set_bit(SAS_DEV_DESTROY, &dev->state)) { + if (test_bit(SAS_DEV_GONE, &dev->state)) + sas_abort_device_scsi_cmds(dev); sas_rphy_unlink(dev->rphy); list_move_tail(&dev->disco_list_node, &port->destroy_list); } diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h index cf55f8e3bd9f..5e3a93d13a91 100644 --- a/drivers/scsi/lpfc/lpfc.h +++ b/drivers/scsi/lpfc/lpfc.h @@ -1036,7 +1036,6 @@ struct lpfc_hba { #define FCF_TS_INPROG 0x200 /* FCF table scan in progress */ #define FCF_RR_INPROG 0x400 /* FCF roundrobin flogi in progress */ #define HBA_FIP_SUPPORT 0x800 /* FIP support in HBA */ -#define HBA_AER_ENABLED 0x1000 /* AER enabled with HBA */ #define HBA_DEVLOSS_TMO 0x2000 /* HBA in devloss timeout */ #define HBA_RRQ_ACTIVE 0x4000 /* process the rrq active list */ #define HBA_IOQ_FLUSH 0x8000 /* FCP/NVME I/O queues being flushed */ @@ -1190,7 +1189,6 @@ struct lpfc_hba { #define LPFC_MAX_ENBL_FC4_TYPE LPFC_ENABLE_FCP #define LPFC_DEF_ENBL_FC4_TYPE LPFC_ENABLE_FCP #endif - uint32_t cfg_aer_support; uint32_t cfg_sriov_nr_virtfn; uint32_t cfg_request_firmware_upgrade; uint32_t cfg_suppress_link_up; diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c index 22f2e046e8eb..3863a5341782 100644 --- a/drivers/scsi/lpfc/lpfc_attr.c +++ b/drivers/scsi/lpfc/lpfc_attr.c @@ -1644,6 +1644,12 @@ lpfc_sli4_pdev_status_reg_wait(struct lpfc_hba *phba) !bf_get(lpfc_sliport_status_err, &portstat_reg)) return -EPERM; + /* There is no point to wait if the port is in an unrecoverable + * state. + */ + if (lpfc_sli4_unrecoverable_port(&portstat_reg)) + return -EIO; + /* wait for the SLI port firmware ready after firmware reset */ for (i = 0; i < LPFC_FW_RESET_MAXIMUM_WAIT_10MS_CNT; i++) { msleep(10); @@ -4365,13 +4371,22 @@ static DEVICE_ATTR_RW(lpfc_link_speed); /* # lpfc_aer_support: Support PCIe device Advanced Error Reporting (AER) -# 0 = aer disabled or not supported # 1 = aer supported and enabled (default) -# Value range is [0,1]. Default value is 1. +# PCIe error reporting is always enabled by the PCI core, so this always +# shows 1. +# +# N.B. Parts of LPFC_ATTR open-coded since some of the underlying +# infrastructure (phba->cfg_aer_support) is gone. */ -LPFC_ATTR(aer_support, 1, 0, 1, - "Enable PCIe device AER support"); -lpfc_param_show(aer_support) +static uint lpfc_aer_support = 1; +module_param(lpfc_aer_support, uint, S_IRUGO); +MODULE_PARM_DESC(lpfc_aer_support, "Enable PCIe device AER support"); +static ssize_t +lpfc_aer_support_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + return scnprintf(buf, PAGE_SIZE, "%d\n", lpfc_aer_support); +} /** * lpfc_aer_support_store - Set the adapter for aer support @@ -4382,76 +4397,27 @@ lpfc_param_show(aer_support) * @count: unused variable. * * Description: - * If the val is 1 and currently the device's AER capability was not - * enabled, invoke the kernel's enable AER helper routine, trying to - * enable the device's AER capability. If the helper routine enabling - * AER returns success, update the device's cfg_aer_support flag to - * indicate AER is supported by the device; otherwise, if the device - * AER capability is already enabled to support AER, then do nothing. - * - * If the val is 0 and currently the device's AER support was enabled, - * invoke the kernel's disable AER helper routine. After that, update - * the device's cfg_aer_support flag to indicate AER is not supported - * by the device; otherwise, if the device AER capability is already - * disabled from supporting AER, then do nothing. + * PCIe error reporting is enabled by the PCI core, so drivers don't need + * to do anything. Retain this interface for backwards compatibility, + * but do nothing. * * Returns: - * length of the buf on success if val is in range the intended mode - * is supported. - * -EINVAL if val out of range or intended mode is not supported. + * length of the buf on success + * -EINVAL if val out of range **/ static ssize_t lpfc_aer_support_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - struct Scsi_Host *shost = class_to_shost(dev); - struct lpfc_vport *vport = (struct lpfc_vport *)shost->hostdata; - struct lpfc_hba *phba = vport->phba; - int val = 0, rc = -EINVAL; + int val = 0; if (!isdigit(buf[0])) return -EINVAL; if (sscanf(buf, "%i", &val) != 1) return -EINVAL; - switch (val) { - case 0: - if (phba->hba_flag & HBA_AER_ENABLED) { - rc = pci_disable_pcie_error_reporting(phba->pcidev); - if (!rc) { - spin_lock_irq(&phba->hbalock); - phba->hba_flag &= ~HBA_AER_ENABLED; - spin_unlock_irq(&phba->hbalock); - phba->cfg_aer_support = 0; - rc = strlen(buf); - } else - rc = -EPERM; - } else { - phba->cfg_aer_support = 0; - rc = strlen(buf); - } - break; - case 1: - if (!(phba->hba_flag & HBA_AER_ENABLED)) { - rc = pci_enable_pcie_error_reporting(phba->pcidev); - if (!rc) { - spin_lock_irq(&phba->hbalock); - phba->hba_flag |= HBA_AER_ENABLED; - spin_unlock_irq(&phba->hbalock); - phba->cfg_aer_support = 1; - rc = strlen(buf); - } else - rc = -EPERM; - } else { - phba->cfg_aer_support = 1; - rc = strlen(buf); - } - break; - default: - rc = -EINVAL; - break; - } - return rc; + dev_info_once(dev, "PCIe error reporting automatically enabled by the PCI core; sysfs write ignored\n"); + return strlen(buf); } static DEVICE_ATTR_RW(lpfc_aer_support); @@ -4464,16 +4430,16 @@ static DEVICE_ATTR_RW(lpfc_aer_support); * @count: unused variable. * * Description: - * If the @buf contains 1 and the device currently has the AER support - * enabled, then invokes the kernel AER helper routine + * If the @buf contains 1, invokes the kernel AER helper routine * pci_aer_clear_nonfatal_status() to clean up the uncorrectable * error status register. * * Notes: * * Returns: - * -EINVAL if the buf does not contain the 1 or the device is not currently - * enabled with the AER support. + * -EINVAL if the buf does not contain 1 + * -EPERM if the OS cannot clear AER error status, i.e., when platform + * firmware owns the AER Capability **/ static ssize_t lpfc_aer_cleanup_state(struct device *dev, struct device_attribute *attr, @@ -4491,8 +4457,7 @@ lpfc_aer_cleanup_state(struct device *dev, struct device_attribute *attr, if (val != 1) return -EINVAL; - if (phba->hba_flag & HBA_AER_ENABLED) - rc = pci_aer_clear_nonfatal_status(phba->pcidev); + rc = pci_aer_clear_nonfatal_status(phba->pcidev); if (rc == 0) return strlen(buf); @@ -7277,7 +7242,6 @@ lpfc_get_cfgparam(struct lpfc_hba *phba) lpfc_sg_seg_cnt_init(phba, lpfc_sg_seg_cnt); lpfc_hba_queue_depth_init(phba, lpfc_hba_queue_depth); - lpfc_aer_support_init(phba, lpfc_aer_support); lpfc_sriov_nr_virtfn_init(phba, lpfc_sriov_nr_virtfn); lpfc_request_firmware_upgrade_init(phba, lpfc_req_fw_upgrade); lpfc_suppress_link_up_init(phba, lpfc_suppress_link_up); diff --git a/drivers/scsi/lpfc/lpfc_bsg.c b/drivers/scsi/lpfc/lpfc_bsg.c index 852b025e2fec..9a322a3a2150 100644 --- a/drivers/scsi/lpfc/lpfc_bsg.c +++ b/drivers/scsi/lpfc/lpfc_bsg.c @@ -1,7 +1,7 @@ /******************************************************************* * This file is part of the Emulex Linux Device Driver for * * Fibre Channel Host Bus Adapters. * - * Copyright (C) 2017-2022 Broadcom. All Rights Reserved. The term * + * Copyright (C) 2017-2023 Broadcom. All Rights Reserved. The term * * “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. * * Copyright (C) 2009-2015 Emulex. All rights reserved. * * EMULEX and SLI are trademarks of Emulex. * @@ -134,8 +134,8 @@ lpfc_free_bsg_buffers(struct lpfc_hba *phba, struct lpfc_dmabuf *mlist) if (mlist) { list_for_each_entry_safe(mlast, next_mlast, &mlist->list, list) { - lpfc_mbuf_free(phba, mlast->virt, mlast->phys); list_del(&mlast->list); + lpfc_mbuf_free(phba, mlast->virt, mlast->phys); kfree(mlast); } lpfc_mbuf_free(phba, mlist->virt, mlist->phys); diff --git a/drivers/scsi/lpfc/lpfc_crtn.h b/drivers/scsi/lpfc/lpfc_crtn.h index 976fd5ee7f7e..b833b983e69d 100644 --- a/drivers/scsi/lpfc/lpfc_crtn.h +++ b/drivers/scsi/lpfc/lpfc_crtn.h @@ -458,6 +458,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 *); +bool lpfc_error_lost_link(struct lpfc_vport *vport, u32 ulp_status, + u32 ulp_word4); extern const struct attribute_group *lpfc_hba_groups[]; extern const struct attribute_group *lpfc_vport_groups[]; extern struct scsi_host_template lpfc_template; diff --git a/drivers/scsi/lpfc/lpfc_ct.c b/drivers/scsi/lpfc/lpfc_ct.c index e941a99aa965..f3bdcebe67f5 100644 --- a/drivers/scsi/lpfc/lpfc_ct.c +++ b/drivers/scsi/lpfc/lpfc_ct.c @@ -1,7 +1,7 @@ /******************************************************************* * This file is part of the Emulex Linux Device Driver for * * Fibre Channel Host Bus Adapters. * - * Copyright (C) 2017-2022 Broadcom. All Rights Reserved. The term * + * Copyright (C) 2017-2023 Broadcom. All Rights Reserved. The term * * “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. * * Copyright (C) 2004-2016 Emulex. All rights reserved. * * EMULEX and SLI are trademarks of Emulex. * @@ -476,8 +476,8 @@ lpfc_free_ct_rsp(struct lpfc_hba *phba, struct lpfc_dmabuf *mlist) struct lpfc_dmabuf *mlast, *next_mlast; list_for_each_entry_safe(mlast, next_mlast, &mlist->list, list) { - lpfc_mbuf_free(phba, mlast->virt, mlast->phys); list_del(&mlast->list); + lpfc_mbuf_free(phba, mlast->virt, mlast->phys); kfree(mlast); } lpfc_mbuf_free(phba, mlist->virt, mlist->phys); @@ -958,7 +958,7 @@ lpfc_cmpl_ct_cmd_gid_ft(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, lpfc_vport_set_state(vport, FC_VPORT_FAILED); goto out; } - if (lpfc_error_lost_link(ulp_status, ulp_word4)) { + if (lpfc_error_lost_link(vport, ulp_status, ulp_word4)) { lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY, "0226 NS query failed due to link event: " "ulp_status x%x ulp_word4 x%x fc_flag x%x " @@ -1181,7 +1181,7 @@ lpfc_cmpl_ct_cmd_gid_pt(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, lpfc_vport_set_state(vport, FC_VPORT_FAILED); goto out; } - if (lpfc_error_lost_link(ulp_status, ulp_word4)) { + if (lpfc_error_lost_link(vport, ulp_status, ulp_word4)) { lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY, "4166 NS query failed due to link event: " "ulp_status x%x ulp_word4 x%x fc_flag x%x " diff --git a/drivers/scsi/lpfc/lpfc_debugfs.c b/drivers/scsi/lpfc/lpfc_debugfs.c index f5252e45a48a..bdf34af4ef36 100644 --- a/drivers/scsi/lpfc/lpfc_debugfs.c +++ b/drivers/scsi/lpfc/lpfc_debugfs.c @@ -1,7 +1,7 @@ /******************************************************************* * This file is part of the Emulex Linux Device Driver for * * Fibre Channel Host Bus Adapters. * - * Copyright (C) 2017-2022 Broadcom. All Rights Reserved. The term * + * Copyright (C) 2017-2023 Broadcom. All Rights Reserved. The term * * “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. * * Copyright (C) 2007-2015 Emulex. All rights reserved. * * EMULEX and SLI are trademarks of Emulex. * @@ -2157,10 +2157,13 @@ lpfc_debugfs_lockstat_write(struct file *file, const char __user *buf, char mybuf[64]; char *pbuf; int i; + size_t bsize; memset(mybuf, 0, sizeof(mybuf)); - if (copy_from_user(mybuf, buf, nbytes)) + bsize = min(nbytes, (sizeof(mybuf) - 1)); + + if (copy_from_user(mybuf, buf, bsize)) return -EFAULT; pbuf = &mybuf[0]; @@ -2181,7 +2184,7 @@ lpfc_debugfs_lockstat_write(struct file *file, const char __user *buf, qp->lock_conflict.wq_access = 0; } } - return nbytes; + return bsize; } #endif diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c index 35b252f1ef73..6a15f879e517 100644 --- a/drivers/scsi/lpfc/lpfc_els.c +++ b/drivers/scsi/lpfc/lpfc_els.c @@ -1088,7 +1088,7 @@ stop_rr_fcf_flogi: } /* Do not register VFI if the driver aborted FLOGI */ - if (!lpfc_error_lost_link(ulp_status, ulp_word4)) + if (!lpfc_error_lost_link(vport, ulp_status, ulp_word4)) lpfc_issue_reg_vfi(vport); lpfc_nlp_put(ndlp); @@ -1207,7 +1207,7 @@ flogifail: phba->fcf.fcf_flag &= ~FCF_DISCOVERY; spin_unlock_irq(&phba->hbalock); - if (!lpfc_error_lost_link(ulp_status, ulp_word4)) { + if (!lpfc_error_lost_link(vport, ulp_status, ulp_word4)) { /* FLOGI failed, so just use loop map to make discovery list */ lpfc_disc_list_loopmap(vport); @@ -2087,7 +2087,7 @@ lpfc_cmpl_els_plogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, ulp_word4); /* Do not call DSM for lpfc_els_abort'ed ELS cmds */ - if (!lpfc_error_lost_link(ulp_status, ulp_word4)) + if (!lpfc_error_lost_link(vport, ulp_status, ulp_word4)) lpfc_disc_state_machine(vport, ndlp, cmdiocb, NLP_EVT_CMPL_PLOGI); @@ -2208,14 +2208,15 @@ lpfc_issue_els_plogi(struct lpfc_vport *vport, uint32_t did, uint8_t retry) * outstanding UNREG_RPI mbox command completes, unless we * are going offline. This logic does not apply for Fabric DIDs */ - if ((ndlp->nlp_flag & NLP_UNREG_INP) && + if ((ndlp->nlp_flag & (NLP_IGNR_REG_CMPL | NLP_UNREG_INP)) && ((ndlp->nlp_DID & Fabric_DID_MASK) != Fabric_DID_MASK) && !(vport->fc_flag & FC_OFFLINE_MODE)) { lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY, "4110 Issue PLOGI x%x deferred " - "on NPort x%x rpi x%x Data: x%px\n", + "on NPort x%x rpi x%x flg x%x Data:" + " x%px\n", ndlp->nlp_defer_did, ndlp->nlp_DID, - ndlp->nlp_rpi, ndlp); + ndlp->nlp_rpi, ndlp->nlp_flag, ndlp); /* We can only defer 1st PLOGI */ if (ndlp->nlp_defer_did == NLP_EVT_NOTHING_PENDING) @@ -2382,7 +2383,7 @@ lpfc_cmpl_els_prli(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, ndlp->fc4_prli_sent); /* Do not call DSM for lpfc_els_abort'ed ELS cmds */ - if (!lpfc_error_lost_link(ulp_status, ulp_word4)) + if (!lpfc_error_lost_link(vport, ulp_status, ulp_word4)) lpfc_disc_state_machine(vport, ndlp, cmdiocb, NLP_EVT_CMPL_PRLI); @@ -3037,15 +3038,16 @@ lpfc_cmpl_els_logo(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, ndlp->nlp_DID, ulp_status, ulp_word4); - if (lpfc_error_lost_link(ulp_status, ulp_word4)) { + if (lpfc_error_lost_link(vport, ulp_status, ulp_word4)) skip_recovery = 1; - goto out; - } } /* Call state machine. This will unregister the rpi if needed. */ lpfc_disc_state_machine(vport, ndlp, cmdiocb, NLP_EVT_CMPL_LOGO); + if (skip_recovery) + goto out; + /* The driver sets this flag for an NPIV instance that doesn't want to * log into the remote port. */ @@ -4928,7 +4930,7 @@ lpfc_els_retry(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, if ((cmd == ELS_CMD_FLOGI) && (phba->fc_topology != LPFC_TOPOLOGY_LOOP) && - !lpfc_error_lost_link(ulp_status, ulp_word4)) { + !lpfc_error_lost_link(vport, ulp_status, ulp_word4)) { /* FLOGI retry policy */ retry = 1; /* retry FLOGI forever */ @@ -4942,7 +4944,7 @@ lpfc_els_retry(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, else if (cmdiocb->retry >= 32) delay = 1000; } else if ((cmd == ELS_CMD_FDISC) && - !lpfc_error_lost_link(ulp_status, ulp_word4)) { + !lpfc_error_lost_link(vport, ulp_status, ulp_word4)) { /* retry FDISCs every second up to devloss */ retry = 1; maxretry = vport->cfg_devloss_tmo; @@ -5455,18 +5457,20 @@ out: * these conditions and release the RPI. */ 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) { - if (ndlp->nlp_state != NLP_STE_PLOGI_ISSUE && - ndlp->nlp_state != NLP_STE_REG_LOGIN_ISSUE) { - lpfc_sli4_free_rpi(phba, ndlp->nlp_rpi); - spin_lock_irq(&ndlp->lock); - ndlp->nlp_rpi = LPFC_RPI_ALLOC_ERROR; - ndlp->nlp_flag &= ~NLP_RELEASE_RPI; - spin_unlock_irq(&ndlp->lock); - lpfc_drop_node(vport, ndlp); + vport && vport->port_type == LPFC_NPIV_PORT && + !(ndlp->fc4_xpt_flags & SCSI_XPT_REGD)) { + if (ndlp->nlp_flag & NLP_RELEASE_RPI) { + if (ndlp->nlp_state != NLP_STE_PLOGI_ISSUE && + ndlp->nlp_state != NLP_STE_REG_LOGIN_ISSUE) { + lpfc_sli4_free_rpi(phba, ndlp->nlp_rpi); + spin_lock_irq(&ndlp->lock); + ndlp->nlp_rpi = LPFC_RPI_ALLOC_ERROR; + ndlp->nlp_flag &= ~NLP_RELEASE_RPI; + spin_unlock_irq(&ndlp->lock); + } } + + lpfc_drop_node(vport, ndlp); } /* Release the originating I/O reference. */ diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c index 66cd0b1dbbd0..5ba3a9ad9501 100644 --- a/drivers/scsi/lpfc/lpfc_hbadisc.c +++ b/drivers/scsi/lpfc/lpfc_hbadisc.c @@ -5755,8 +5755,8 @@ lpfc_setup_disc_node(struct lpfc_vport *vport, uint32_t did) (NLP_FCP_TARGET | NLP_NVME_TARGET))) return NULL; - ndlp->nlp_prev_state = ndlp->nlp_state; - lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE); + lpfc_disc_state_machine(vport, ndlp, NULL, + NLP_EVT_DEVICE_RECOVERY); spin_lock_irq(&ndlp->lock); ndlp->nlp_flag |= NLP_NPR_2B_DISC; @@ -7269,3 +7269,38 @@ lpfc_parse_fcoe_conf(struct lpfc_hba *phba, lpfc_read_fcf_conn_tbl(phba, rec_ptr); } + +/* + * lpfc_error_lost_link - IO failure from link event or FW reset check. + * + * @vport: Pointer to lpfc_vport data structure. + * @ulp_status: IO completion status. + * @ulp_word4: Reason code for the ulp_status. + * + * This function evaluates the ulp_status and ulp_word4 values + * for specific error values that indicate an internal link fault + * or fw reset event for the completing IO. Callers require this + * common data to decide next steps on the IO. + * + * Return: + * false - No link or reset error occurred. + * true - A link or reset error occurred. + */ +bool +lpfc_error_lost_link(struct lpfc_vport *vport, u32 ulp_status, u32 ulp_word4) +{ + /* Mask off the extra port data to get just the reason code. */ + u32 rsn_code = IOERR_PARAM_MASK & ulp_word4; + + if (ulp_status == IOSTAT_LOCAL_REJECT && + (rsn_code == IOERR_SLI_ABORTED || + rsn_code == IOERR_LINK_DOWN || + rsn_code == IOERR_SLI_DOWN)) { + lpfc_printf_vlog(vport, KERN_WARNING, LOG_SLI | LOG_ELS, + "0408 Report link error true: <x%x:x%x>\n", + ulp_status, ulp_word4); + return true; + } + + return false; +} diff --git a/drivers/scsi/lpfc/lpfc_hw.h b/drivers/scsi/lpfc/lpfc_hw.h index 5c283936ff08..19b2d2754f32 100644 --- a/drivers/scsi/lpfc/lpfc_hw.h +++ b/drivers/scsi/lpfc/lpfc_hw.h @@ -1,7 +1,7 @@ /******************************************************************* * This file is part of the Emulex Linux Device Driver for * * Fibre Channel Host Bus Adapters. * - * Copyright (C) 2017-2022 Broadcom. All Rights Reserved. The term * + * Copyright (C) 2017-2023 Broadcom. All Rights Reserved. The term * * “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. * * Copyright (C) 2004-2016 Emulex. All rights reserved. * * EMULEX and SLI are trademarks of Emulex. * @@ -4435,16 +4435,4 @@ lpfc_is_LC_HBA(unsigned short device) return 0; } -/* - * Determine if failed because of a link event or firmware reset. - */ -static inline int -lpfc_error_lost_link(u32 ulp_status, u32 ulp_word4) -{ - return (ulp_status == IOSTAT_LOCAL_REJECT && - (ulp_word4 == IOERR_SLI_ABORTED || - ulp_word4 == IOERR_LINK_DOWN || - ulp_word4 == IOERR_SLI_DOWN)); -} - #define BPL_ALIGN_SZ 8 /* 8 byte alignment for bpl and mbufs */ diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index 4f7485958c49..867b4c788f08 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c @@ -32,7 +32,6 @@ #include <linux/spinlock.h> #include <linux/sched/clock.h> #include <linux/ctype.h> -#include <linux/aer.h> #include <linux/slab.h> #include <linux/firmware.h> #include <linux/miscdevice.h> @@ -2148,7 +2147,7 @@ lpfc_handle_eratt_s4(struct lpfc_hba *phba) /* fall through for not able to recover */ lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT, "3152 Unrecoverable error\n"); - phba->link_state = LPFC_HBA_ERROR; + lpfc_sli4_offline_eratt(phba); break; case LPFC_SLI_INTF_IF_TYPE_1: default: @@ -9569,8 +9568,7 @@ lpfc_sli4_post_status_check(struct lpfc_hba *phba) /* Final checks. The port status should be clean. */ if (lpfc_readl(phba->sli4_hba.u.if_type2.STATUSregaddr, ®_data.word0) || - (bf_get(lpfc_sliport_status_err, ®_data) && - !bf_get(lpfc_sliport_status_rn, ®_data))) { + lpfc_sli4_unrecoverable_port(®_data)) { phba->work_status[0] = readl(phba->sli4_hba.u.if_type2. ERR1regaddr); @@ -12026,7 +12024,7 @@ lpfc_sli4_pci_mem_setup(struct lpfc_hba *phba) goto out_iounmap_all; } else { error = -ENOMEM; - goto out_iounmap_all; + goto out_iounmap_ctrl; } } @@ -12044,7 +12042,7 @@ lpfc_sli4_pci_mem_setup(struct lpfc_hba *phba) dev_err(&pdev->dev, "ioremap failed for SLI4 HBA dpp registers.\n"); error = -ENOMEM; - goto out_iounmap_ctrl; + goto out_iounmap_all; } phba->pci_bar4_memmap_p = phba->sli4_hba.dpp_regs_memmap_p; } @@ -12069,9 +12067,11 @@ lpfc_sli4_pci_mem_setup(struct lpfc_hba *phba) return 0; out_iounmap_all: - iounmap(phba->sli4_hba.drbl_regs_memmap_p); + if (phba->sli4_hba.drbl_regs_memmap_p) + iounmap(phba->sli4_hba.drbl_regs_memmap_p); out_iounmap_ctrl: - iounmap(phba->sli4_hba.ctrl_regs_memmap_p); + if (phba->sli4_hba.ctrl_regs_memmap_p) + iounmap(phba->sli4_hba.ctrl_regs_memmap_p); out_iounmap_conf: iounmap(phba->sli4_hba.conf_regs_memmap_p); @@ -12107,6 +12107,7 @@ lpfc_sli4_pci_mem_unset(struct lpfc_hba *phba) iounmap(phba->sli4_hba.dpp_regs_memmap_p); break; case LPFC_SLI_INTF_IF_TYPE_1: + break; default: dev_printk(KERN_ERR, &phba->pcidev->dev, "FATAL - unsupported SLI4 interface type - %d\n", diff --git a/drivers/scsi/lpfc/lpfc_nvme.c b/drivers/scsi/lpfc/lpfc_nvme.c index 152245f7cacc..adda70423c77 100644 --- a/drivers/scsi/lpfc/lpfc_nvme.c +++ b/drivers/scsi/lpfc/lpfc_nvme.c @@ -1,7 +1,7 @@ /******************************************************************* * This file is part of the Emulex Linux Device Driver for * * Fibre Channel Host Bus Adapters. * - * Copyright (C) 2017-2022 Broadcom. All Rights Reserved. The term * + * Copyright (C) 2017-2023 Broadcom. All Rights Reserved. The term * * “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. * * Copyright (C) 2004-2016 Emulex. All rights reserved. * * EMULEX and SLI are trademarks of Emulex. * @@ -2265,6 +2265,7 @@ lpfc_nvme_lport_unreg_wait(struct lpfc_vport *vport, } if (!vport->localport || test_bit(HBA_PCI_ERR, &vport->phba->bit_flags) || + phba->link_state == LPFC_HBA_ERROR || vport->load_flag & FC_UNLOADING) return; @@ -2630,7 +2631,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->link_state == LPFC_HBA_ERROR)) (void)nvme_fc_set_remoteport_devloss(remoteport, 0); ret = nvme_fc_unregister_remoteport(remoteport); diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index cf630aa6734e..8693578888f1 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c @@ -34,7 +34,6 @@ #include <scsi/scsi_host.h> #include <scsi/scsi_transport_fc.h> #include <scsi/fc/fc_fs.h> -#include <linux/aer.h> #include <linux/crash_dump.h> #ifdef CONFIG_X86 #include <asm/set_memory.h> @@ -5204,13 +5203,9 @@ lpfc_sli_brdrestart_s3(struct lpfc_hba *phba) volatile struct MAILBOX_word0 mb; struct lpfc_sli *psli; void __iomem *to_slim; - uint32_t hba_aer_enabled; spin_lock_irq(&phba->hbalock); - /* Take PCIe device Advanced Error Reporting (AER) state */ - hba_aer_enabled = phba->hba_flag & HBA_AER_ENABLED; - psli = &phba->sli; /* Restart HBA */ @@ -5251,10 +5246,6 @@ lpfc_sli_brdrestart_s3(struct lpfc_hba *phba) /* Give the INITFF and Post time to settle. */ mdelay(100); - /* Reset HBA AER if it was enabled, note hba_flag was reset above */ - if (hba_aer_enabled) - pci_disable_pcie_error_reporting(phba->pcidev); - lpfc_hba_down_post(phba); return 0; @@ -5273,7 +5264,6 @@ static int lpfc_sli_brdrestart_s4(struct lpfc_hba *phba) { struct lpfc_sli *psli = &phba->sli; - uint32_t hba_aer_enabled; int rc; /* Restart HBA */ @@ -5281,9 +5271,6 @@ lpfc_sli_brdrestart_s4(struct lpfc_hba *phba) "0296 Restart HBA Data: x%x x%x\n", phba->pport->port_state, psli->sli_flag); - /* Take PCIe device Advanced Error Reporting (AER) state */ - hba_aer_enabled = phba->hba_flag & HBA_AER_ENABLED; - rc = lpfc_sli4_brdreset(phba); if (rc) { phba->link_state = LPFC_HBA_ERROR; @@ -5301,10 +5288,6 @@ lpfc_sli_brdrestart_s4(struct lpfc_hba *phba) memset(&psli->lnk_stat_offsets, 0, sizeof(psli->lnk_stat_offsets)); psli->stats_start = ktime_get_seconds(); - /* Reset HBA AER if it was enabled, note hba_flag was reset above */ - if (hba_aer_enabled) - pci_disable_pcie_error_reporting(phba->pcidev); - hba_down_queue: lpfc_hba_down_post(phba); lpfc_sli4_queue_destroy(phba); @@ -5725,25 +5708,6 @@ lpfc_sli_hba_setup(struct lpfc_hba *phba) } phba->fcp_embed_io = 0; /* SLI4 FC support only */ - /* Enable PCIe device Advanced Error Reporting (AER) if configured */ - if (phba->cfg_aer_support == 1 && !(phba->hba_flag & HBA_AER_ENABLED)) { - rc = pci_enable_pcie_error_reporting(phba->pcidev); - if (!rc) { - lpfc_printf_log(phba, KERN_INFO, LOG_INIT, - "2709 This device supports " - "Advanced Error Reporting (AER)\n"); - spin_lock_irq(&phba->hbalock); - phba->hba_flag |= HBA_AER_ENABLED; - spin_unlock_irq(&phba->hbalock); - } else { - lpfc_printf_log(phba, KERN_INFO, LOG_INIT, - "2708 This device does not support " - "Advanced Error Reporting (AER): %d\n", - rc); - phba->cfg_aer_support = 0; - } - } - if (phba->sli_rev == 3) { phba->iocb_cmd_size = SLI3_IOCB_CMD_SIZE; phba->iocb_rsp_size = SLI3_IOCB_RSP_SIZE; @@ -8080,16 +8044,16 @@ int lpfc_rx_monitor_create_ring(struct lpfc_rx_info_monitor *rx_monitor, /** * lpfc_rx_monitor_destroy_ring - Free ring buffer for rx_monitor * @rx_monitor: Pointer to lpfc_rx_info_monitor object + * + * Called after cancellation of cmf_timer. **/ void lpfc_rx_monitor_destroy_ring(struct lpfc_rx_info_monitor *rx_monitor) { - spin_lock(&rx_monitor->lock); kfree(rx_monitor->ring); rx_monitor->ring = NULL; rx_monitor->entries = 0; rx_monitor->head_idx = 0; rx_monitor->tail_idx = 0; - spin_unlock(&rx_monitor->lock); } /** @@ -9053,25 +9017,6 @@ lpfc_sli4_hba_setup(struct lpfc_hba *phba) mod_timer(&phba->eratt_poll, jiffies + msecs_to_jiffies(1000 * phba->eratt_poll_interval)); - /* Enable PCIe device Advanced Error Reporting (AER) if configured */ - if (phba->cfg_aer_support == 1 && !(phba->hba_flag & HBA_AER_ENABLED)) { - rc = pci_enable_pcie_error_reporting(phba->pcidev); - if (!rc) { - lpfc_printf_log(phba, KERN_INFO, LOG_INIT, - "2829 This device supports " - "Advanced Error Reporting (AER)\n"); - spin_lock_irq(&phba->hbalock); - phba->hba_flag |= HBA_AER_ENABLED; - spin_unlock_irq(&phba->hbalock); - } else { - lpfc_printf_log(phba, KERN_INFO, LOG_INIT, - "2830 This device does not support " - "Advanced Error Reporting (AER)\n"); - phba->cfg_aer_support = 0; - } - rc = 0; - } - /* * The port is ready, set the host's link state to LINK_DOWN * in preparation for link interrupts. @@ -9895,7 +9840,8 @@ lpfc_sli4_async_mbox_unblock(struct lpfc_hba *phba) * port for twice the regular mailbox command timeout value. * * 0 - no timeout on waiting for bootstrap mailbox register ready. - * MBXERR_ERROR - wait for bootstrap mailbox register timed out. + * MBXERR_ERROR - wait for bootstrap mailbox register timed out or port + * is in an unrecoverable state. **/ static int lpfc_sli4_wait_bmbx_ready(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) @@ -9903,6 +9849,23 @@ lpfc_sli4_wait_bmbx_ready(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) uint32_t db_ready; unsigned long timeout; struct lpfc_register bmbx_reg; + struct lpfc_register portstat_reg = {-1}; + + /* Sanity check - there is no point to wait if the port is in an + * unrecoverable state. + */ + if (bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf) >= + LPFC_SLI_INTF_IF_TYPE_2) { + if (lpfc_readl(phba->sli4_hba.u.if_type2.STATUSregaddr, + &portstat_reg.word0) || + lpfc_sli4_unrecoverable_port(&portstat_reg)) { + lpfc_printf_log(phba, KERN_ERR, LOG_INIT, + "3858 Skipping bmbx ready because " + "Port Status x%x\n", + portstat_reg.word0); + return MBXERR_ERROR; + } + } timeout = msecs_to_jiffies(lpfc_mbox_tmo_val(phba, mboxq) * 1000) + jiffies; @@ -22325,10 +22288,10 @@ lpfc_free_sgl_per_hdwq(struct lpfc_hba *phba, /* Free sgl pool */ list_for_each_entry_safe(list_entry, tmp, buf_list, list_node) { + list_del(&list_entry->list_node); dma_pool_free(phba->lpfc_sg_dma_buf_pool, list_entry->dma_sgl, list_entry->dma_phys_sgl); - list_del(&list_entry->list_node); kfree(list_entry); } @@ -22475,10 +22438,10 @@ lpfc_free_cmd_rsp_buf_per_hdwq(struct lpfc_hba *phba, list_for_each_entry_safe(list_entry, tmp, buf_list, list_node) { + list_del(&list_entry->list_node); dma_pool_free(phba->lpfc_cmd_rsp_buf_pool, list_entry->fcp_cmnd, list_entry->fcp_cmd_rsp_dma_handle); - list_del(&list_entry->list_node); kfree(list_entry); } diff --git a/drivers/scsi/lpfc/lpfc_sli4.h b/drivers/scsi/lpfc/lpfc_sli4.h index 3b62c4032c31..2a0864e6d7cd 100644 --- a/drivers/scsi/lpfc/lpfc_sli4.h +++ b/drivers/scsi/lpfc/lpfc_sli4.h @@ -1180,3 +1180,22 @@ static inline void *lpfc_sli4_qe(struct lpfc_queue *q, uint16_t idx) return q->q_pgs[idx / q->entry_cnt_per_pg] + (q->entry_size * (idx % q->entry_cnt_per_pg)); } + +/** + * lpfc_sli4_unrecoverable_port - Check ERR and RN bits in portstat_reg + * @portstat_reg: portstat_reg pointer containing portstat_reg contents + * + * Description: + * Use only for SLI4 interface type-2 or later. If ERR is set && RN is 0, then + * port is deemed unrecoverable. + * + * Returns: + * true - ERR && !RN + * false - otherwise + */ +static inline bool +lpfc_sli4_unrecoverable_port(struct lpfc_register *portstat_reg) +{ + return bf_get(lpfc_sliport_status_err, portstat_reg) && + !bf_get(lpfc_sliport_status_rn, portstat_reg); +} diff --git a/drivers/scsi/lpfc/lpfc_version.h b/drivers/scsi/lpfc/lpfc_version.h index 0238208cdd11..c97411b0992e 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.2.0.10" +#define LPFC_DRIVER_VERSION "14.2.0.11" #define LPFC_DRIVER_NAME "lpfc" /* Used for SLI 2/3 */ diff --git a/drivers/scsi/mac53c94.c b/drivers/scsi/mac53c94.c index f75928f7773e..6a019132109c 100644 --- a/drivers/scsi/mac53c94.c +++ b/drivers/scsi/mac53c94.c @@ -392,7 +392,7 @@ static void set_dma_cmds(struct fsc_state *state, struct scsi_cmnd *cmd) mac53c94_priv(cmd)->this_residual = total; } -static struct scsi_host_template mac53c94_template = { +static const struct scsi_host_template mac53c94_template = { .proc_name = "53c94", .name = "53C94", .queuecommand = mac53c94_queue, diff --git a/drivers/scsi/mac_esp.c b/drivers/scsi/mac_esp.c index 6d23ab5aee56..3f0061b00494 100644 --- a/drivers/scsi/mac_esp.c +++ b/drivers/scsi/mac_esp.c @@ -289,7 +289,7 @@ static struct esp_driver_ops mac_esp_ops = { static int esp_mac_probe(struct platform_device *dev) { - struct scsi_host_template *tpnt = &scsi_esp_template; + const struct scsi_host_template *tpnt = &scsi_esp_template; struct Scsi_Host *host; struct esp *esp; int err; diff --git a/drivers/scsi/megaraid.c b/drivers/scsi/megaraid.c index bf491af9f0d6..e92f1a73cc9b 100644 --- a/drivers/scsi/megaraid.c +++ b/drivers/scsi/megaraid.c @@ -1441,6 +1441,7 @@ mega_cmd_done(adapter_t *adapter, u8 completed[], int nstatus, int status) */ if (cmdid == CMDID_INT_CMDS) { scb = &adapter->int_scb; + cmd = scb->cmd; list_del_init(&scb->list); scb->state = SCB_FREE; @@ -4100,7 +4101,7 @@ mega_internal_command(adapter_t *adapter, megacmd_t *mc, mega_passthru *pthru) return rval; } -static struct scsi_host_template megaraid_template = { +static const struct scsi_host_template megaraid_template = { .module = THIS_MODULE, .name = "MegaRAID", .proc_name = "megaraid_legacy", diff --git a/drivers/scsi/megaraid/megaraid_mbox.c b/drivers/scsi/megaraid/megaraid_mbox.c index 132de68c14e9..ef2b6380e19a 100644 --- a/drivers/scsi/megaraid/megaraid_mbox.c +++ b/drivers/scsi/megaraid/megaraid_mbox.c @@ -325,7 +325,7 @@ ATTRIBUTE_GROUPS(megaraid_sdev); /* * Scsi host template for megaraid unified driver */ -static struct scsi_host_template megaraid_template_g = { +static const struct scsi_host_template megaraid_template_g = { .module = THIS_MODULE, .name = "LSI Logic MegaRAID driver", .proc_name = "megaraid", diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c index c895189375e2..317c944c68e3 100644 --- a/drivers/scsi/megaraid/megaraid_sas_base.c +++ b/drivers/scsi/megaraid/megaraid_sas_base.c @@ -3505,7 +3505,7 @@ ATTRIBUTE_GROUPS(megaraid_host); /* * Scsi host template for megaraid_sas driver */ -static struct scsi_host_template megasas_template = { +static const struct scsi_host_template megasas_template = { .module = THIS_MODULE, .name = "Avago SAS based MegaRAID driver", diff --git a/drivers/scsi/mesh.c b/drivers/scsi/mesh.c index 84b541a57b7b..e276583c590c 100644 --- a/drivers/scsi/mesh.c +++ b/drivers/scsi/mesh.c @@ -1830,7 +1830,7 @@ static int mesh_shutdown(struct macio_dev *mdev) return 0; } -static struct scsi_host_template mesh_template = { +static const struct scsi_host_template mesh_template = { .proc_name = "mesh", .name = "MESH", .queuecommand = mesh_queue, diff --git a/drivers/scsi/mpi3mr/mpi/mpi30_cnfg.h b/drivers/scsi/mpi3mr/mpi/mpi30_cnfg.h index 0a2af48915a5..2fc196499c89 100644 --- a/drivers/scsi/mpi3mr/mpi/mpi30_cnfg.h +++ b/drivers/scsi/mpi3mr/mpi/mpi30_cnfg.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-or-later */ /* - * Copyright 2017-2022 Broadcom Inc. All rights reserved. + * Copyright 2017-2023 Broadcom Inc. All rights reserved. */ #ifndef MPI30_CNFG_H #define MPI30_CNFG_H 1 @@ -63,8 +63,9 @@ #define MPI3_PCIE_LINK_PGAD_LINKNUM_MASK (0x000000ff) #define MPI3_SECURITY_PGAD_FORM_MASK (0xf0000000) #define MPI3_SECURITY_PGAD_FORM_GET_NEXT_SLOT (0x00000000) -#define MPI3_SECURITY_PGAD_FORM_SOT_NUM (0x10000000) +#define MPI3_SECURITY_PGAD_FORM_SLOT_NUM (0x10000000) #define MPI3_SECURITY_PGAD_SLOT_GROUP_MASK (0x0000ff00) +#define MPI3_SECURITY_PGAD_SLOT_GROUP_SHIFT (8) #define MPI3_SECURITY_PGAD_SLOT_MASK (0x000000ff) struct mpi3_config_request { __le16 host_tag; @@ -135,7 +136,6 @@ struct mpi3_config_page_header { #define MPI3_SAS_PHYINFO_PHY_POWER_CONDITION_ACTIVE (0x00000000) #define MPI3_SAS_PHYINFO_PHY_POWER_CONDITION_PARTIAL (0x08000000) #define MPI3_SAS_PHYINFO_PHY_POWER_CONDITION_SLUMBER (0x10000000) -#define MPI3_SAS_NEG_LINK_RATE_PHYSICAL_SHIFT (0) #define MPI3_SAS_PHYINFO_REQUESTED_INSIDE_ZPSDS_CHANGED_MASK (0x04000000) #define MPI3_SAS_PHYINFO_REQUESTED_INSIDE_ZPSDS_CHANGED_SHIFT (26) #define MPI3_SAS_PHYINFO_INSIDE_ZPSDS_PERSISTENT_MASK (0x02000000) @@ -201,6 +201,11 @@ struct mpi3_config_page_header { #define MPI3_TEMP_SENSOR_LOCATION_DRAM (0x3) #define MPI3_MFGPAGE_VENDORID_BROADCOM (0x1000) #define MPI3_MFGPAGE_DEVID_SAS4116 (0x00a5) +#define MPI3_MFGPAGE_DEVID_SAS5116_MPI (0x00b3) +#define MPI3_MFGPAGE_DEVID_SAS5116_NVME (0x00b4) +#define MPI3_MFGPAGE_DEVID_SAS5116_MPI_MGMT (0x00b5) +#define MPI3_MFGPAGE_DEVID_SAS5116_NVME_MGMT (0x00b6) +#define MPI3_MFGPAGE_DEVID_SAS5116_PCIE_SWITCH (0x00b8) struct mpi3_man_page0 { struct mpi3_config_page_header header; u8 chip_revision[8]; @@ -466,7 +471,7 @@ struct mpi3_man_page9 { #define MPI3_MAN9_PAGEVERSION (0x00) struct mpi3_man10_istwi_ctrlr_entry { - __le16 slave_address; + __le16 target_address; __le16 flags; u8 scl_low_override; u8 scl_high_override; @@ -476,8 +481,8 @@ struct mpi3_man10_istwi_ctrlr_entry { #define MPI3_MAN10_ISTWI_CTRLR_FLAGS_BUS_SPEED_MASK (0x000c) #define MPI3_MAN10_ISTWI_CTRLR_FLAGS_BUS_SPEED_100K (0x0000) #define MPI3_MAN10_ISTWI_CTRLR_FLAGS_BUS_SPEED_400K (0x0004) -#define MPI3_MAN10_ISTWI_CTRLR_FLAGS_SLAVE_ENABLED (0x0002) -#define MPI3_MAN10_ISTWI_CTRLR_FLAGS_MASTER_ENABLED (0x0001) +#define MPI3_MAN10_ISTWI_CTRLR_FLAGS_TARGET_ENABLED (0x0002) +#define MPI3_MAN10_ISTWI_CTRLR_FLAGS_INITIATOR_ENABLED (0x0001) #ifndef MPI3_MAN10_ISTWI_CTRLR_MAX #define MPI3_MAN10_ISTWI_CTRLR_MAX (1) #endif @@ -1160,7 +1165,7 @@ struct mpi3_io_unit_page12 { struct mpi3_iounit13_allowed_function { __le16 sub_function; u8 function_code; - u8 fuction_flags; + u8 function_flags; }; #define MPI3_IOUNIT13_FUNCTION_FLAGS_ADMIN_BLOCKED (0x04) #define MPI3_IOUNIT13_FUNCTION_FLAGS_OOB_BLOCKED (0x02) @@ -1176,6 +1181,48 @@ struct mpi3_io_unit_page13 { #define MPI3_IOUNIT13_PAGEVERSION (0x00) #define MPI3_IOUNIT13_FLAGS_ADMIN_BLOCKED (0x0002) #define MPI3_IOUNIT13_FLAGS_OOB_BLOCKED (0x0001) +#ifndef MPI3_IOUNIT14_MD_MAX +#define MPI3_IOUNIT14_MD_MAX (1) +#endif +struct mpi3_iounit14_pagemetadata { + u8 page_type; + u8 page_number; + u8 reserved02; + u8 page_flags; +}; +#define MPI3_IOUNIT14_PAGEMETADATA_PAGEFLAGS_OOBWRITE_ALLOWED (0x02) +#define MPI3_IOUNIT14_PAGEMETADATA_PAGEFLAGS_HOSTWRITE_ALLOWED (0x01) +struct mpi3_io_unit_page14 { + struct mpi3_config_page_header header; + u8 flags; + u8 reserved09[3]; + u8 num_pages; + u8 reserved0d[3]; + struct mpi3_iounit14_pagemetadata page_metadata[MPI3_IOUNIT14_MD_MAX]; +}; +#define MPI3_IOUNIT14_PAGEVERSION (0x00) +#define MPI3_IOUNIT14_FLAGS_READONLY (0x01) +#ifndef MPI3_IOUNIT15_PBD_MAX +#define MPI3_IOUNIT15_PBD_MAX (1) +#endif +struct mpi3_io_unit_page15 { + struct mpi3_config_page_header header; + u8 flags; + u8 reserved09[3]; + __le32 reserved0c; + u8 power_budgeting_capability; + u8 reserved11[3]; + u8 num_power_budget_data; + u8 reserved15[3]; + __le32 power_budget_data[MPI3_IOUNIT15_PBD_MAX]; +}; +#define MPI3_IOUNIT15_PAGEVERSION (0x00) +#define MPI3_IOUNIT15_FLAGS_EPRINIT_INITREQUIRED (0x04) +#define MPI3_IOUNIT15_FLAGS_EPRSUPPORT_MASK (0x03) +#define MPI3_IOUNIT15_FLAGS_EPRSUPPORT_NOT_SUPPORTED (0x00) +#define MPI3_IOUNIT15_FLAGS_EPRSUPPORT_WITHOUT_POWER_BRAKE_GPIO (0x01) +#define MPI3_IOUNIT15_FLAGS_EPRSUPPORT_WITH_POWER_BRAKE_GPIO (0x02) +#define MPI3_IOUNIT15_NUMPOWERBUDGETDATA_POWER_BUDGETING_DISABLED (0x00) struct mpi3_ioc_page0 { struct mpi3_config_page_header header; __le32 reserved08; @@ -1273,6 +1320,7 @@ struct mpi3_driver_page0 { #define MPI3_DRIVER0_BSDOPTS_REGISTRATION_MASK (0x00000003) #define MPI3_DRIVER0_BSDOPTS_REGISTRATION_IOC_AND_DEVS (0x00000000) #define MPI3_DRIVER0_BSDOPTS_REGISTRATION_IOC_ONLY (0x00000001) +#define MPI3_DRIVER0_BSDOPTS_REGISTRATION_IOC_AND_INTERNAL_DEVS (0x00000002) struct mpi3_driver_page1 { struct mpi3_config_page_header header; __le32 flags; @@ -1340,7 +1388,7 @@ union mpi3_driver2_trigger_element { #define MPI3_DRIVER2_TRIGGER_FLAGS_DIAG_FW_RELEASE (0x01) struct mpi3_driver_page2 { struct mpi3_config_page_header header; - __le64 master_trigger; + __le64 global_trigger; __le32 reserved10[3]; u8 num_triggers; u8 reserved1d[3]; @@ -1348,11 +1396,13 @@ struct mpi3_driver_page2 { }; #define MPI3_DRIVER2_PAGEVERSION (0x00) -#define MPI3_DRIVER2_MASTERTRIGGER_DIAG_TRACE_RELEASE (0x8000000000000000ULL) -#define MPI3_DRIVER2_MASTERTRIGGER_DIAG_FW_RELEASE (0x4000000000000000ULL) -#define MPI3_DRIVER2_MASTERTRIGGER_SNAPDUMP (0x2000000000000000ULL) -#define MPI3_DRIVER2_MASTERTRIGGER_DEVICE_REMOVAL_ENABLED (0x0000000000000004ULL) -#define MPI3_DRIVER2_MASTERTRIGGER_TASK_MANAGEMENT_ENABLED (0x0000000000000002ULL) +#define MPI3_DRIVER2_GLOBALTRIGGER_DIAG_TRACE_RELEASE (0x8000000000000000ULL) +#define MPI3_DRIVER2_GLOBALTRIGGER_DIAG_FW_RELEASE (0x4000000000000000ULL) +#define MPI3_DRIVER2_GLOBALTRIGGER_SNAPDUMP_ENABLED (0x2000000000000000ULL) +#define MPI3_DRIVER2_GLOBALTRIGGER_POST_DIAG_TRACE_DISABLED (0x1000000000000000ULL) +#define MPI3_DRIVER2_GLOBALTRIGGER_POST_DIAG_FW_DISABLED (0x0800000000000000ULL) +#define MPI3_DRIVER2_GLOBALTRIGGER_DEVICE_REMOVAL_ENABLED (0x0000000000000004ULL) +#define MPI3_DRIVER2_GLOBALTRIGGER_TASK_MANAGEMENT_ENABLED (0x0000000000000002ULL) struct mpi3_driver_page10 { struct mpi3_config_page_header header; __le16 flags; @@ -1395,6 +1445,12 @@ union mpi3_security_nonce { u8 byte[64]; }; +union mpi3_security_root_digest { + __le32 dword[16]; + __le16 word[32]; + u8 byte[64]; +}; + union mpi3_security0_cert_chain { __le32 dword[1024]; __le16 word[2048]; @@ -1467,6 +1523,32 @@ struct mpi3_security_page1 { }; #define MPI3_SECURITY1_PAGEVERSION (0x00) +#ifndef MPI3_SECURITY2_TRUSTED_ROOT_MAX +#define MPI3_SECURITY2_TRUSTED_ROOT_MAX 1 +#endif +struct mpi3_security2_trusted_root { + u8 level; + u8 hash_algorithm; + __le16 trusted_root_flags; + __le32 reserved04[3]; + union mpi3_security_root_digest root_digest; +}; +#define MPI3_SECURITY2_TRUSTEDROOT_TRUSTEDROOTFLAGS_HASHALGOSOURCE_MASK (0x0006) +#define MPI3_SECURITY2_TRUSTEDROOT_TRUSTEDROOTFLAGS_HASHALGOSOURCE_SHIFT (1) +#define MPI3_SECURITY2_TRUSTEDROOT_TRUSTEDROOTFLAGS_HASHALGOSOURCE_HA_FIELD (0x0000) +#define MPI3_SECURITY2_TRUSTEDROOT_TRUSTEDROOTFLAGS_HASHALGOSOURCE_AKI (0x0002) +#define MPI3_SECURITY2_TRUSTEDROOT_TRUSTEDROOTFLAGS_USERPROVISIONED_YES (0x0001) +struct mpi3_security_page2 { + struct mpi3_config_page_header header; + __le32 reserved08[2]; + union mpi3_security_mac mac; + union mpi3_security_nonce nonce; + __le32 reserved90[3]; + u8 num_roots; + u8 reserved9d[3]; + struct mpi3_security2_trusted_root trusted_root[MPI3_SECURITY2_TRUSTED_ROOT_MAX]; +}; +#define MPI3_SECURITY2_PAGEVERSION (0x00) struct mpi3_sas_io_unit0_phy_data { u8 io_unit_port; u8 port_flags; @@ -2351,6 +2433,10 @@ struct mpi3_device_page0 { #define MPI3_DEVICE0_ASTATUS_NVME_MAX (0x5f) #define MPI3_DEVICE0_ASTATUS_VD_UNKNOWN (0x80) #define MPI3_DEVICE0_ASTATUS_VD_MAX (0x8f) +#define MPI3_DEVICE0_FLAGS_MAX_WRITE_SAME_MASK (0xe000) +#define MPI3_DEVICE0_FLAGS_MAX_WRITE_SAME_NO_LIMIT (0x0000) +#define MPI3_DEVICE0_FLAGS_MAX_WRITE_SAME_256_LB (0x2000) +#define MPI3_DEVICE0_FLAGS_MAX_WRITE_SAME_2048_LB (0x4000) #define MPI3_DEVICE0_FLAGS_CONTROLLER_DEV_HANDLE (0x0080) #define MPI3_DEVICE0_FLAGS_IO_THROTTLING_REQUIRED (0x0010) #define MPI3_DEVICE0_FLAGS_HIDDEN (0x0008) diff --git a/drivers/scsi/mpi3mr/mpi/mpi30_image.h b/drivers/scsi/mpi3mr/mpi/mpi30_image.h index 64c58815988a..47035b811902 100644 --- a/drivers/scsi/mpi3mr/mpi/mpi30_image.h +++ b/drivers/scsi/mpi3mr/mpi/mpi30_image.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-or-later */ /* - * Copyright 2018-2022 Broadcom Inc. All rights reserved. + * Copyright 2018-2023 Broadcom Inc. All rights reserved. */ #ifndef MPI30_IMAGE_H #define MPI30_IMAGE_H 1 diff --git a/drivers/scsi/mpi3mr/mpi/mpi30_init.h b/drivers/scsi/mpi3mr/mpi/mpi30_init.h index 3c03610ecfa6..af86d12c8e49 100644 --- a/drivers/scsi/mpi3mr/mpi/mpi30_init.h +++ b/drivers/scsi/mpi3mr/mpi/mpi30_init.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-or-later */ /* - * Copyright 2016-2022 Broadcom Inc. All rights reserved. + * Copyright 2016-2023 Broadcom Inc. All rights reserved. */ #ifndef MPI30_INIT_H #define MPI30_INIT_H 1 @@ -56,6 +56,7 @@ struct mpi3_scsi_io_request { #define MPI3_SCSIIO_FLAGS_DMAOPERATION_HOST_PI (0x00010000) #define MPI3_SCSIIO_FLAGS_DIVERT_REASON_MASK (0x000000f0) #define MPI3_SCSIIO_FLAGS_DIVERT_REASON_IO_THROTTLING (0x00000010) +#define MPI3_SCSIIO_FLAGS_DIVERT_REASON_WRITE_SAME_TOO_LARGE (0x00000020) #define MPI3_SCSIIO_FLAGS_DIVERT_REASON_PROD_SPECIFIC (0x00000080) #define MPI3_SCSIIO_METASGL_INDEX (3) struct mpi3_scsi_io_reply { @@ -114,4 +115,24 @@ struct mpi3_scsi_io_reply { #define MPI3_SCSI_RSP_ARI0_MASK (0xff000000) #define MPI3_SCSI_RSP_ARI0_SHIFT (24) #define MPI3_SCSI_TASKTAG_UNKNOWN (0xffff) +#define MPI3_SCSITASKMGMT_MSGFLAGS_DO_NOT_SEND_TASK_IU (0x08) +#define MPI3_SCSITASKMGMT_TASKTYPE_ABORT_TASK (0x01) +#define MPI3_SCSITASKMGMT_TASKTYPE_ABORT_TASK_SET (0x02) +#define MPI3_SCSITASKMGMT_TASKTYPE_TARGET_RESET (0x03) +#define MPI3_SCSITASKMGMT_TASKTYPE_LOGICAL_UNIT_RESET (0x05) +#define MPI3_SCSITASKMGMT_TASKTYPE_CLEAR_TASK_SET (0x06) +#define MPI3_SCSITASKMGMT_TASKTYPE_QUERY_TASK (0x07) +#define MPI3_SCSITASKMGMT_TASKTYPE_CLEAR_ACA (0x08) +#define MPI3_SCSITASKMGMT_TASKTYPE_QUERY_TASK_SET (0x09) +#define MPI3_SCSITASKMGMT_TASKTYPE_QUERY_ASYNC_EVENT (0x0a) +#define MPI3_SCSITASKMGMT_TASKTYPE_I_T_NEXUS_RESET (0x0b) +#define MPI3_SCSITASKMGMT_RSPCODE_TM_COMPLETE (0x00) +#define MPI3_SCSITASKMGMT_RSPCODE_INVALID_FRAME (0x02) +#define MPI3_SCSITASKMGMT_RSPCODE_TM_FUNCTION_NOT_SUPPORTED (0x04) +#define MPI3_SCSITASKMGMT_RSPCODE_TM_FAILED (0x05) +#define MPI3_SCSITASKMGMT_RSPCODE_TM_SUCCEEDED (0x08) +#define MPI3_SCSITASKMGMT_RSPCODE_TM_INVALID_LUN (0x09) +#define MPI3_SCSITASKMGMT_RSPCODE_TM_OVERLAPPED_TAG (0x0a) +#define MPI3_SCSITASKMGMT_RSPCODE_IO_QUEUED_ON_IOC (0x80) +#define MPI3_SCSITASKMGMT_RSPCODE_TM_NVME_DENIED (0x81) #endif diff --git a/drivers/scsi/mpi3mr/mpi/mpi30_ioc.h b/drivers/scsi/mpi3mr/mpi/mpi30_ioc.h index 1c6c6730df5c..f5e9c2309ce6 100644 --- a/drivers/scsi/mpi3mr/mpi/mpi30_ioc.h +++ b/drivers/scsi/mpi3mr/mpi/mpi30_ioc.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-or-later */ /* - * Copyright 2016-2022 Broadcom Inc. All rights reserved. + * Copyright 2016-2023 Broadcom Inc. All rights reserved. */ #ifndef MPI30_IOC_H #define MPI30_IOC_H 1 diff --git a/drivers/scsi/mpi3mr/mpi/mpi30_pci.h b/drivers/scsi/mpi3mr/mpi/mpi30_pci.h index b7a5df01120d..7c15e5851ce4 100644 --- a/drivers/scsi/mpi3mr/mpi/mpi30_pci.h +++ b/drivers/scsi/mpi3mr/mpi/mpi30_pci.h @@ -1,11 +1,13 @@ /* SPDX-License-Identifier: GPL-2.0-or-later */ /* - * Copyright 2016-2022 Broadcom Inc. All rights reserved. + * Copyright 2016-2023 Broadcom Inc. All rights reserved. * */ #ifndef MPI30_PCI_H #define MPI30_PCI_H 1 - +#ifndef MPI3_NVME_ENCAP_CMD_MAX +#define MPI3_NVME_ENCAP_CMD_MAX (1) +#endif #define MPI3_NVME_FLAGS_FORCE_ADMIN_ERR_REPLY_MASK (0x0002) #define MPI3_NVME_FLAGS_FORCE_ADMIN_ERR_REPLY_FAIL_ONLY (0x0000) #define MPI3_NVME_FLAGS_FORCE_ADMIN_ERR_REPLY_ALL (0x0002) diff --git a/drivers/scsi/mpi3mr/mpi/mpi30_sas.h b/drivers/scsi/mpi3mr/mpi/mpi30_sas.h index e587f77ccd68..4a93c67d335f 100644 --- a/drivers/scsi/mpi3mr/mpi/mpi30_sas.h +++ b/drivers/scsi/mpi3mr/mpi/mpi30_sas.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-or-later */ /* - * Copyright 2016-2022 Broadcom Inc. All rights reserved. + * Copyright 2016-2023 Broadcom Inc. All rights reserved. */ #ifndef MPI30_SAS_H #define MPI30_SAS_H 1 diff --git a/drivers/scsi/mpi3mr/mpi/mpi30_transport.h b/drivers/scsi/mpi3mr/mpi/mpi30_transport.h index 9b76b9632751..441cfc2c7f09 100644 --- a/drivers/scsi/mpi3mr/mpi/mpi30_transport.h +++ b/drivers/scsi/mpi3mr/mpi/mpi30_transport.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-or-later */ /* - * Copyright 2016-2022 Broadcom Inc. All rights reserved. + * Copyright 2016-2023 Broadcom Inc. All rights reserved. */ #ifndef MPI30_TRANSPORT_H #define MPI30_TRANSPORT_H 1 @@ -18,7 +18,7 @@ union mpi3_version_union { #define MPI3_VERSION_MAJOR (3) #define MPI3_VERSION_MINOR (0) -#define MPI3_VERSION_UNIT (26) +#define MPI3_VERSION_UNIT (27) #define MPI3_VERSION_DEV (0) #define MPI3_DEVHANDLE_INVALID (0xffff) struct mpi3_sysif_oper_queue_indexes { diff --git a/drivers/scsi/mpi3mr/mpi3mr.h b/drivers/scsi/mpi3mr/mpi3mr.h index 364fb1b5e45a..dfe6b87fe288 100644 --- a/drivers/scsi/mpi3mr/mpi3mr.h +++ b/drivers/scsi/mpi3mr/mpi3mr.h @@ -2,7 +2,7 @@ /* * Driver for Broadcom MPI3 Storage Controllers * - * Copyright (C) 2017-2022 Broadcom Inc. + * Copyright (C) 2017-2023 Broadcom Inc. * (mailto: mpi3mr-linuxdrv.pdl@broadcom.com) * */ @@ -55,8 +55,8 @@ extern struct list_head mrioc_list; extern int prot_mask; extern atomic64_t event_counter; -#define MPI3MR_DRIVER_VERSION "8.2.0.3.0" -#define MPI3MR_DRIVER_RELDATE "08-September-2022" +#define MPI3MR_DRIVER_VERSION "8.4.1.0.0" +#define MPI3MR_DRIVER_RELDATE "16-March-2023" #define MPI3MR_DRIVER_NAME "mpi3mr" #define MPI3MR_DRIVER_LICENSE "GPL" @@ -126,6 +126,7 @@ extern atomic64_t event_counter; #define MPI3MR_RAID_ERRREC_RESET_TIMEOUT 180 #define MPI3MR_PREPARE_FOR_RESET_TIMEOUT 180 #define MPI3MR_RESET_ACK_TIMEOUT 30 +#define MPI3MR_MUR_TIMEOUT 120 #define MPI3MR_WATCHDOG_INTERVAL 1000 /* in milli seconds */ @@ -652,7 +653,11 @@ union _form_spec_inf { struct tgt_dev_vd vd_inf; }; - +enum mpi3mr_dev_state { + MPI3MR_DEV_CREATED = 1, + MPI3MR_DEV_REMOVE_HS_STARTED = 2, + MPI3MR_DEV_DELETED = 3, +}; /** * struct mpi3mr_tgt_dev - target device data structure @@ -676,6 +681,7 @@ union _form_spec_inf { * @enclosure_logical_id: Enclosure logical identifier * @dev_spec: Device type specific information * @ref_count: Reference count + * @state: device state */ struct mpi3mr_tgt_dev { struct list_head list; @@ -697,6 +703,7 @@ struct mpi3mr_tgt_dev { u64 enclosure_logical_id; union _form_spec_inf dev_spec; struct kref ref_count; + enum mpi3mr_dev_state state; }; /** diff --git a/drivers/scsi/mpi3mr/mpi3mr_app.c b/drivers/scsi/mpi3mr/mpi3mr_app.c index d10c6afb7f9c..08645a99ad6b 100644 --- a/drivers/scsi/mpi3mr/mpi3mr_app.c +++ b/drivers/scsi/mpi3mr/mpi3mr_app.c @@ -2,7 +2,7 @@ /* * Driver for Broadcom MPI3 Storage Controllers * - * Copyright (C) 2017-2022 Broadcom Inc. + * Copyright (C) 2017-2023 Broadcom Inc. * (mailto: mpi3mr-linuxdrv.pdl@broadcom.com) * */ @@ -922,6 +922,7 @@ err_out: /** * mpi3mr_bsg_process_mpt_cmds - MPI Pass through BSG handler * @job: BSG job reference + * @reply_payload_rcv_len: length of payload recvd * * This function is the top level handler for MPI Pass through * command, this does basic validation of the input data buffers, @@ -1471,6 +1472,7 @@ static int mpi3mr_bsg_request(struct bsg_job *job) /** * mpi3mr_bsg_exit - de-registration from bsg layer + * @mrioc: Adapter instance reference * * This will be called during driver unload and all * bsg resources allocated during load will be freed. @@ -1505,6 +1507,7 @@ static void mpi3mr_bsg_node_release(struct device *dev) /** * mpi3mr_bsg_init - registration with bsg layer + * @mrioc: Adapter instance reference * * This will be called during driver load and it will * register driver with bsg layer diff --git a/drivers/scsi/mpi3mr/mpi3mr_debug.h b/drivers/scsi/mpi3mr/mpi3mr_debug.h index ee6edd8322e6..e94f7520d153 100644 --- a/drivers/scsi/mpi3mr/mpi3mr_debug.h +++ b/drivers/scsi/mpi3mr/mpi3mr_debug.h @@ -2,7 +2,7 @@ /* * Driver for Broadcom MPI3 Storage Controllers * - * Copyright (C) 2017-2022 Broadcom Inc. + * Copyright (C) 2017-2023 Broadcom Inc. * (mailto: mpi3mr-linuxdrv.pdl@broadcom.com) * */ diff --git a/drivers/scsi/mpi3mr/mpi3mr_fw.c b/drivers/scsi/mpi3mr/mpi3mr_fw.c index d109a4ceb72b..075fa67e95ee 100644 --- a/drivers/scsi/mpi3mr/mpi3mr_fw.c +++ b/drivers/scsi/mpi3mr/mpi3mr_fw.c @@ -2,7 +2,7 @@ /* * Driver for Broadcom MPI3 Storage Controllers * - * Copyright (C) 2017-2022 Broadcom Inc. + * Copyright (C) 2017-2023 Broadcom Inc. * (mailto: mpi3mr-linuxdrv.pdl@broadcom.com) * */ @@ -1098,7 +1098,7 @@ static int mpi3mr_issue_and_process_mur(struct mpi3mr_ioc *mrioc, ioc_config &= ~MPI3_SYSIF_IOC_CONFIG_ENABLE_IOC; writel(ioc_config, &mrioc->sysif_regs->ioc_configuration); - timeout = MPI3MR_RESET_ACK_TIMEOUT * 10; + timeout = MPI3MR_MUR_TIMEOUT * 10; do { ioc_status = readl(&mrioc->sysif_regs->ioc_status); if ((ioc_status & MPI3_SYSIF_IOC_STATUS_RESET_HISTORY)) { @@ -2620,14 +2620,12 @@ static int mpi3mr_setup_admin_qpair(struct mpi3mr_ioc *mrioc) mrioc->num_admin_req = mrioc->admin_req_q_sz / MPI3MR_ADMIN_REQ_FRAME_SZ; mrioc->admin_req_ci = mrioc->admin_req_pi = 0; - mrioc->admin_req_base = NULL; mrioc->admin_reply_q_sz = MPI3MR_ADMIN_REPLY_Q_SIZE; mrioc->num_admin_replies = mrioc->admin_reply_q_sz / MPI3MR_ADMIN_REPLY_FRAME_SZ; mrioc->admin_reply_ci = 0; mrioc->admin_reply_ephase = 1; - mrioc->admin_reply_base = NULL; atomic_set(&mrioc->admin_reply_q_in_use, 0); if (!mrioc->admin_req_base) { diff --git a/drivers/scsi/mpi3mr/mpi3mr_os.c b/drivers/scsi/mpi3mr/mpi3mr_os.c index 6d55698ea4d1..d627355303d7 100644 --- a/drivers/scsi/mpi3mr/mpi3mr_os.c +++ b/drivers/scsi/mpi3mr/mpi3mr_os.c @@ -2,7 +2,7 @@ /* * Driver for Broadcom MPI3 Storage Controllers * - * Copyright (C) 2017-2022 Broadcom Inc. + * Copyright (C) 2017-2023 Broadcom Inc. * (mailto: mpi3mr-linuxdrv.pdl@broadcom.com) * */ @@ -652,6 +652,7 @@ static void mpi3mr_tgtdev_add_to_list(struct mpi3mr_ioc *mrioc, mpi3mr_tgtdev_get(tgtdev); INIT_LIST_HEAD(&tgtdev->list); list_add_tail(&tgtdev->list, &mrioc->tgtdev_list); + tgtdev->state = MPI3MR_DEV_CREATED; spin_unlock_irqrestore(&mrioc->tgtdev_lock, flags); } @@ -659,20 +660,25 @@ static void mpi3mr_tgtdev_add_to_list(struct mpi3mr_ioc *mrioc, * mpi3mr_tgtdev_del_from_list -Delete tgtdevice from the list * @mrioc: Adapter instance reference * @tgtdev: Target device + * @must_delete: Must delete the target device from the list irrespective + * of the device state. * * Remove the target device from the target device list * * Return: Nothing. */ static void mpi3mr_tgtdev_del_from_list(struct mpi3mr_ioc *mrioc, - struct mpi3mr_tgt_dev *tgtdev) + struct mpi3mr_tgt_dev *tgtdev, bool must_delete) { unsigned long flags; spin_lock_irqsave(&mrioc->tgtdev_lock, flags); - if (!list_empty(&tgtdev->list)) { - list_del_init(&tgtdev->list); - mpi3mr_tgtdev_put(tgtdev); + if ((tgtdev->state == MPI3MR_DEV_REMOVE_HS_STARTED) || (must_delete == true)) { + if (!list_empty(&tgtdev->list)) { + list_del_init(&tgtdev->list); + tgtdev->state = MPI3MR_DEV_DELETED; + mpi3mr_tgtdev_put(tgtdev); + } } spin_unlock_irqrestore(&mrioc->tgtdev_lock, flags); } @@ -1036,7 +1042,7 @@ void mpi3mr_rfresh_tgtdevs(struct mpi3mr_ioc *mrioc) tgtdev->perst_id); if (tgtdev->host_exposed) mpi3mr_remove_tgtdev_from_host(mrioc, tgtdev); - mpi3mr_tgtdev_del_from_list(mrioc, tgtdev); + mpi3mr_tgtdev_del_from_list(mrioc, tgtdev, true); mpi3mr_tgtdev_put(tgtdev); } } @@ -1281,12 +1287,12 @@ static void mpi3mr_devstatuschg_evt_bh(struct mpi3mr_ioc *mrioc, if (!tgtdev->host_exposed) mpi3mr_report_tgtdev_to_host(mrioc, tgtdev->perst_id); } - if (tgtdev->starget && tgtdev->starget->hostdata) { - if (delete) - mpi3mr_remove_tgtdev_from_host(mrioc, tgtdev); - } + + if (delete) + mpi3mr_remove_tgtdev_from_host(mrioc, tgtdev); + if (cleanup) { - mpi3mr_tgtdev_del_from_list(mrioc, tgtdev); + mpi3mr_tgtdev_del_from_list(mrioc, tgtdev, false); mpi3mr_tgtdev_put(tgtdev); } @@ -1604,7 +1610,7 @@ static void mpi3mr_sastopochg_evt_bh(struct mpi3mr_ioc *mrioc, case MPI3_EVENT_SAS_TOPO_PHY_RC_TARG_NOT_RESPONDING: if (tgtdev->host_exposed) mpi3mr_remove_tgtdev_from_host(mrioc, tgtdev); - mpi3mr_tgtdev_del_from_list(mrioc, tgtdev); + mpi3mr_tgtdev_del_from_list(mrioc, tgtdev, false); mpi3mr_tgtdev_put(tgtdev); break; case MPI3_EVENT_SAS_TOPO_PHY_RC_RESPONDING: @@ -1762,7 +1768,7 @@ static void mpi3mr_pcietopochg_evt_bh(struct mpi3mr_ioc *mrioc, case MPI3_EVENT_PCIE_TOPO_PS_NOT_RESPONDING: if (tgtdev->host_exposed) mpi3mr_remove_tgtdev_from_host(mrioc, tgtdev); - mpi3mr_tgtdev_del_from_list(mrioc, tgtdev); + mpi3mr_tgtdev_del_from_list(mrioc, tgtdev, false); mpi3mr_tgtdev_put(tgtdev); break; default: @@ -2016,12 +2022,18 @@ static int mpi3mr_create_tgtdev(struct mpi3mr_ioc *mrioc, int retval = 0; struct mpi3mr_tgt_dev *tgtdev = NULL; u16 perst_id = 0; + unsigned long flags; perst_id = le16_to_cpu(dev_pg0->persistent_id); if (perst_id == MPI3_DEVICE0_PERSISTENTID_INVALID) return retval; - tgtdev = mpi3mr_get_tgtdev_by_perst_id(mrioc, perst_id); + spin_lock_irqsave(&mrioc->tgtdev_lock, flags); + tgtdev = __mpi3mr_get_tgtdev_by_perst_id(mrioc, perst_id); + if (tgtdev) + tgtdev->state = MPI3MR_DEV_CREATED; + spin_unlock_irqrestore(&mrioc->tgtdev_lock, flags); + if (tgtdev) { mpi3mr_update_tgtdev(mrioc, tgtdev, dev_pg0, true); mpi3mr_tgtdev_put(tgtdev); @@ -2219,6 +2231,14 @@ static void mpi3mr_dev_rmhs_send_tm(struct mpi3mr_ioc *mrioc, u16 handle, u8 retrycount = 5; struct mpi3mr_drv_cmd *drv_cmd = cmdparam; struct delayed_dev_rmhs_node *delayed_dev_rmhs = NULL; + struct mpi3mr_tgt_dev *tgtdev = NULL; + unsigned long flags; + + spin_lock_irqsave(&mrioc->tgtdev_lock, flags); + tgtdev = __mpi3mr_get_tgtdev_by_handle(mrioc, handle); + if (tgtdev && (iou_rc == MPI3_CTRL_OP_REMOVE_DEVICE)) + tgtdev->state = MPI3MR_DEV_REMOVE_HS_STARTED; + spin_unlock_irqrestore(&mrioc->tgtdev_lock, flags); if (drv_cmd) goto issue_cmd; @@ -3311,19 +3331,19 @@ static int mpi3mr_get_chain_idx(struct mpi3mr_ioc *mrioc) { u8 retry_count = 5; int cmd_idx = -1; + unsigned long flags; + spin_lock_irqsave(&mrioc->chain_buf_lock, flags); do { - spin_lock(&mrioc->chain_buf_lock); cmd_idx = find_first_zero_bit(mrioc->chain_bitmap, mrioc->chain_buf_count); if (cmd_idx < mrioc->chain_buf_count) { set_bit(cmd_idx, mrioc->chain_bitmap); - spin_unlock(&mrioc->chain_buf_lock); break; } - spin_unlock(&mrioc->chain_buf_lock); cmd_idx = -1; } while (retry_count--); + spin_unlock_irqrestore(&mrioc->chain_buf_lock, flags); return cmd_idx; } @@ -3996,10 +4016,14 @@ static int mpi3mr_eh_target_reset(struct scsi_cmnd *scmd) stgt_priv_data = sdev_priv_data->tgt_priv_data; dev_handle = stgt_priv_data->dev_handle; if (stgt_priv_data->dev_removed) { + struct scmd_priv *cmd_priv = scsi_cmd_priv(scmd); sdev_printk(KERN_INFO, scmd->device, "%s:target(handle = 0x%04x) is removed, target reset is not issued\n", mrioc->name, dev_handle); - retval = FAILED; + if (!cmd_priv->in_lld_scope || cmd_priv->host_tag == MPI3MR_HOSTTAG_INVALID) + retval = SUCCESS; + else + retval = FAILED; goto out; } sdev_printk(KERN_INFO, scmd->device, @@ -4064,10 +4088,14 @@ static int mpi3mr_eh_dev_reset(struct scsi_cmnd *scmd) stgt_priv_data = sdev_priv_data->tgt_priv_data; dev_handle = stgt_priv_data->dev_handle; if (stgt_priv_data->dev_removed) { + struct scmd_priv *cmd_priv = scsi_cmd_priv(scmd); sdev_printk(KERN_INFO, scmd->device, "%s: device(handle = 0x%04x) is removed, device(LUN) reset is not issued\n", mrioc->name, dev_handle); - retval = FAILED; + if (!cmd_priv->in_lld_scope || cmd_priv->host_tag == MPI3MR_HOSTTAG_INVALID) + retval = SUCCESS; + else + retval = FAILED; goto out; } sdev_printk(KERN_INFO, scmd->device, @@ -4625,13 +4653,24 @@ static int mpi3mr_qcmd(struct Scsi_Host *shost, goto out; } + stgt_priv_data = sdev_priv_data->tgt_priv_data; + dev_handle = stgt_priv_data->dev_handle; + + /* Avoid error handling escalation when device is removed or blocked */ + + if (scmd->device->host->shost_state == SHOST_RECOVERY && + scmd->cmnd[0] == TEST_UNIT_READY && + (stgt_priv_data->dev_removed || (dev_handle == MPI3MR_INVALID_DEV_HANDLE))) { + scsi_build_sense(scmd, 0, UNIT_ATTENTION, 0x29, 0x07); + scsi_done(scmd); + goto out; + } + if (mrioc->reset_in_progress) { retval = SCSI_MLQUEUE_HOST_BUSY; goto out; } - stgt_priv_data = sdev_priv_data->tgt_priv_data; - if (atomic_read(&stgt_priv_data->block_io)) { if (mrioc->stop_drv_processing) { scmd->result = DID_NO_CONNECT << 16; @@ -4642,7 +4681,6 @@ static int mpi3mr_qcmd(struct Scsi_Host *shost, goto out; } - dev_handle = stgt_priv_data->dev_handle; if (dev_handle == MPI3MR_INVALID_DEV_HANDLE) { scmd->result = DID_NO_CONNECT << 16; scsi_done(scmd); @@ -4758,7 +4796,7 @@ out: return retval; } -static struct scsi_host_template mpi3mr_driver_template = { +static const struct scsi_host_template mpi3mr_driver_template = { .module = THIS_MODULE, .name = "MPI3 Storage Controller", .proc_name = MPI3MR_DRIVER_NAME, @@ -5111,7 +5149,7 @@ static void mpi3mr_remove(struct pci_dev *pdev) list_for_each_entry_safe(tgtdev, tgtdev_next, &mrioc->tgtdev_list, list) { mpi3mr_remove_tgtdev_from_host(mrioc, tgtdev); - mpi3mr_tgtdev_del_from_list(mrioc, tgtdev); + mpi3mr_tgtdev_del_from_list(mrioc, tgtdev, true); mpi3mr_tgtdev_put(tgtdev); } mpi3mr_stop_watchdog(mrioc); diff --git a/drivers/scsi/mpi3mr/mpi3mr_transport.c b/drivers/scsi/mpi3mr/mpi3mr_transport.c index 5748bd9369ff..4d84d5bd173f 100644 --- a/drivers/scsi/mpi3mr/mpi3mr_transport.c +++ b/drivers/scsi/mpi3mr/mpi3mr_transport.c @@ -2,7 +2,7 @@ /* * Driver for Broadcom MPI3 Storage Controllers * - * Copyright (C) 2017-2022 Broadcom Inc. + * Copyright (C) 2017-2023 Broadcom Inc. * (mailto: mpi3mr-linuxdrv.pdl@broadcom.com) * */ diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c b/drivers/scsi/mpt3sas/mpt3sas_base.c index 14ae0a9c5d3d..53f5492579cb 100644 --- a/drivers/scsi/mpt3sas/mpt3sas_base.c +++ b/drivers/scsi/mpt3sas/mpt3sas_base.c @@ -60,7 +60,6 @@ #include <linux/ktime.h> #include <linux/kthread.h> #include <asm/page.h> /* To get host page size per arch */ -#include <linux/aer.h> #include "mpt3sas_base.h" @@ -3535,7 +3534,6 @@ mpt3sas_base_unmap_resources(struct MPT3SAS_ADAPTER *ioc) if (pci_is_enabled(pdev)) { pci_release_selected_regions(ioc->pdev, ioc->bars); - pci_disable_pcie_error_reporting(pdev); pci_disable_device(pdev); } } @@ -3615,9 +3613,6 @@ mpt3sas_base_map_resources(struct MPT3SAS_ADAPTER *ioc) goto out_fail; } -/* AER (Advanced Error Reporting) hooks */ - pci_enable_pcie_error_reporting(pdev); - pci_set_master(pdev); @@ -4761,21 +4756,15 @@ _base_display_ioc_capabilities(struct MPT3SAS_ADAPTER *ioc) int i = 0; char desc[17] = {0}; u32 iounit_pg1_flags; - u32 bios_version; - bios_version = le32_to_cpu(ioc->bios_pg3.BiosVersion); strncpy(desc, ioc->manu_pg0.ChipName, 16); - ioc_info(ioc, "%s: FWVersion(%02d.%02d.%02d.%02d), ChipRevision(0x%02x), BiosVersion(%02d.%02d.%02d.%02d)\n", + ioc_info(ioc, "%s: FWVersion(%02d.%02d.%02d.%02d), ChipRevision(0x%02x)\n", desc, (ioc->facts.FWVersion.Word & 0xFF000000) >> 24, (ioc->facts.FWVersion.Word & 0x00FF0000) >> 16, (ioc->facts.FWVersion.Word & 0x0000FF00) >> 8, ioc->facts.FWVersion.Word & 0x000000FF, - ioc->pdev->revision, - (bios_version & 0xFF000000) >> 24, - (bios_version & 0x00FF0000) >> 16, - (bios_version & 0x0000FF00) >> 8, - bios_version & 0x000000FF); + ioc->pdev->revision); _base_display_OEMs_branding(ioc); diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c b/drivers/scsi/mpt3sas/mpt3sas_scsih.c index 8e24ebcebfe5..c3c1f466fe01 100644 --- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c +++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c @@ -52,7 +52,6 @@ #include <linux/delay.h> #include <linux/pci.h> #include <linux/interrupt.h> -#include <linux/aer.h> #include <linux/raid_class.h> #include <linux/blk-mq-pci.h> #include <asm/unaligned.h> @@ -11926,7 +11925,7 @@ static void scsih_map_queues(struct Scsi_Host *shost) } /* shost template for SAS 2.0 HBA devices */ -static struct scsi_host_template mpt2sas_driver_template = { +static const struct scsi_host_template mpt2sas_driver_template = { .module = THIS_MODULE, .name = "Fusion MPT SAS Host", .proc_name = MPT2SAS_DRIVER_NAME, @@ -11964,7 +11963,7 @@ static struct raid_function_template mpt2sas_raid_functions = { }; /* shost template for SAS 3.0 HBA devices */ -static struct scsi_host_template mpt3sas_driver_template = { +static const struct scsi_host_template mpt3sas_driver_template = { .module = THIS_MODULE, .name = "Fusion MPT SAS Host", .proc_name = MPT3SAS_DRIVER_NAME, @@ -12930,10 +12929,10 @@ _mpt3sas_exit(void) pr_info("mpt3sas version %s unloading\n", MPT3SAS_DRIVER_VERSION); - mpt3sas_ctl_exit(hbas_to_enumerate); - pci_unregister_driver(&mpt3sas_driver); + mpt3sas_ctl_exit(hbas_to_enumerate); + scsih_exit(); } diff --git a/drivers/scsi/mvme147.c b/drivers/scsi/mvme147.c index 472fa043094f..98b99c0f5bc7 100644 --- a/drivers/scsi/mvme147.c +++ b/drivers/scsi/mvme147.c @@ -69,7 +69,7 @@ static void dma_stop(struct Scsi_Host *instance, struct scsi_cmnd *SCpnt, m147_pcc->dma_cntrl = 0; } -static struct scsi_host_template mvme147_host_template = { +static const struct scsi_host_template mvme147_host_template = { .module = THIS_MODULE, .proc_name = "MVME147", .name = "MVME147 built-in SCSI", diff --git a/drivers/scsi/mvsas/mv_init.c b/drivers/scsi/mvsas/mv_init.c index cfe84473a515..49e2a5e7ce54 100644 --- a/drivers/scsi/mvsas/mv_init.c +++ b/drivers/scsi/mvsas/mv_init.c @@ -29,7 +29,7 @@ static const struct attribute_group *mvst_host_groups[]; #define SOC_SAS_NUM 2 -static struct scsi_host_template mvs_sht = { +static const struct scsi_host_template mvs_sht = { .module = THIS_MODULE, .name = DRV_NAME, .queuecommand = sas_queuecommand, diff --git a/drivers/scsi/mvumi.c b/drivers/scsi/mvumi.c index 60c65586f30e..73aa7059b556 100644 --- a/drivers/scsi/mvumi.c +++ b/drivers/scsi/mvumi.c @@ -2168,7 +2168,7 @@ mvumi_bios_param(struct scsi_device *sdev, struct block_device *bdev, return 0; } -static struct scsi_host_template mvumi_template = { +static const struct scsi_host_template mvumi_template = { .module = THIS_MODULE, .name = "Marvell Storage Controller", diff --git a/drivers/scsi/myrb.c b/drivers/scsi/myrb.c index e885c1dbf61f..ca2e932dd9b7 100644 --- a/drivers/scsi/myrb.c +++ b/drivers/scsi/myrb.c @@ -2203,7 +2203,7 @@ static struct attribute *myrb_shost_attrs[] = { ATTRIBUTE_GROUPS(myrb_shost); -static struct scsi_host_template myrb_template = { +static const struct scsi_host_template myrb_template = { .module = THIS_MODULE, .name = "DAC960", .proc_name = "myrb", diff --git a/drivers/scsi/myrs.c b/drivers/scsi/myrs.c index 7eb8c39da366..a1eec65a9713 100644 --- a/drivers/scsi/myrs.c +++ b/drivers/scsi/myrs.c @@ -1915,7 +1915,7 @@ static void myrs_slave_destroy(struct scsi_device *sdev) kfree(sdev->hostdata); } -static struct scsi_host_template myrs_template = { +static const struct scsi_host_template myrs_template = { .module = THIS_MODULE, .name = "DAC960", .proc_name = "myrs", diff --git a/drivers/scsi/nsp32.c b/drivers/scsi/nsp32.c index 75bb0028ed74..b7987019686e 100644 --- a/drivers/scsi/nsp32.c +++ b/drivers/scsi/nsp32.c @@ -259,7 +259,7 @@ static void nsp32_dmessage(const char *, int, int, char *, ...); /* * max_sectors is currently limited up to 128. */ -static struct scsi_host_template nsp32_template = { +static const struct scsi_host_template nsp32_template = { .proc_name = "nsp32", .name = "Workbit NinjaSCSI-32Bi/UDE", .show_info = nsp32_show_info, diff --git a/drivers/scsi/pcmcia/sym53c500_cs.c b/drivers/scsi/pcmcia/sym53c500_cs.c index 5d7dfefd6f6c..278c78d066c4 100644 --- a/drivers/scsi/pcmcia/sym53c500_cs.c +++ b/drivers/scsi/pcmcia/sym53c500_cs.c @@ -668,7 +668,7 @@ ATTRIBUTE_GROUPS(SYM53C500_shost); /* * scsi_host_template initializer */ -static struct scsi_host_template sym53c500_driver_template = { +static const struct scsi_host_template sym53c500_driver_template = { .module = THIS_MODULE, .name = "SYM53C500", .info = SYM53C500_info, @@ -702,7 +702,7 @@ SYM53C500_config(struct pcmcia_device *link) int ret; int irq_level, port_base; struct Scsi_Host *host; - struct scsi_host_template *tpnt = &sym53c500_driver_template; + const struct scsi_host_template *tpnt = &sym53c500_driver_template; struct sym53c500_data *data; dev_dbg(&link->dev, "SYM53C500_config\n"); diff --git a/drivers/scsi/pm8001/pm8001_init.c b/drivers/scsi/pm8001/pm8001_init.c index 7e589fe3e010..8b9490011e36 100644 --- a/drivers/scsi/pm8001/pm8001_init.c +++ b/drivers/scsi/pm8001/pm8001_init.c @@ -96,7 +96,7 @@ static void pm8001_map_queues(struct Scsi_Host *shost) /* * The main structure which LLDD must register for scsi core. */ -static struct scsi_host_template pm8001_sht = { +static const struct scsi_host_template pm8001_sht = { .module = THIS_MODULE, .name = DRV_NAME, .proc_name = DRV_NAME, diff --git a/drivers/scsi/pmcraid.c b/drivers/scsi/pmcraid.c index 836ddc476764..23c5230dbed4 100644 --- a/drivers/scsi/pmcraid.c +++ b/drivers/scsi/pmcraid.c @@ -3611,7 +3611,7 @@ static struct attribute *pmcraid_host_attrs[] = { ATTRIBUTE_GROUPS(pmcraid_host); /* host template structure for pmcraid driver */ -static struct scsi_host_template pmcraid_host_template = { +static const struct scsi_host_template pmcraid_host_template = { .module = THIS_MODULE, .name = PMCRAID_DRIVER_NAME, .queuecommand = pmcraid_queuecommand, diff --git a/drivers/scsi/ppa.c b/drivers/scsi/ppa.c index c6c1bc608224..909c49541984 100644 --- a/drivers/scsi/ppa.c +++ b/drivers/scsi/ppa.c @@ -972,7 +972,7 @@ static int ppa_adjust_queue(struct scsi_device *device) return 0; } -static struct scsi_host_template ppa_template = { +static const struct scsi_host_template ppa_template = { .module = THIS_MODULE, .proc_name = "ppa", .show_info = ppa_show_info, diff --git a/drivers/scsi/ps3rom.c b/drivers/scsi/ps3rom.c index 2b80cab70333..90495a832f34 100644 --- a/drivers/scsi/ps3rom.c +++ b/drivers/scsi/ps3rom.c @@ -323,7 +323,7 @@ done: return IRQ_HANDLED; } -static struct scsi_host_template ps3rom_host_template = { +static const struct scsi_host_template ps3rom_host_template = { .name = DEVICE_NAME, .slave_configure = ps3rom_slave_configure, .queuecommand = ps3rom_queuecommand, diff --git a/drivers/scsi/qedf/qedf_main.c b/drivers/scsi/qedf/qedf_main.c index 35e16600fc63..3b64de81ea0d 100644 --- a/drivers/scsi/qedf/qedf_main.c +++ b/drivers/scsi/qedf/qedf_main.c @@ -979,7 +979,7 @@ static int qedf_slave_configure(struct scsi_device *sdev) return 0; } -static struct scsi_host_template qedf_host_template = { +static const struct scsi_host_template qedf_host_template = { .module = THIS_MODULE, .name = QEDF_MODULE_NAME, .this_id = -1, @@ -2224,7 +2224,6 @@ static bool qedf_process_completions(struct qedf_fastpath *fp) u16 prod_idx; struct fcoe_cqe *cqe; struct qedf_io_work *io_work; - int num_handled = 0; unsigned int cpu; struct qedf_ioreq *io_req = NULL; u16 xid; @@ -2247,7 +2246,6 @@ static bool qedf_process_completions(struct qedf_fastpath *fp) while (new_cqes) { fp->completions++; - num_handled++; cqe = &que->cq[que->cq_cons_idx]; comp_type = (cqe->cqe_data >> FCOE_CQE_CQE_TYPE_SHIFT) & diff --git a/drivers/scsi/qedi/qedi_gbl.h b/drivers/scsi/qedi/qedi_gbl.h index 72942772b198..0e316cc24b19 100644 --- a/drivers/scsi/qedi/qedi_gbl.h +++ b/drivers/scsi/qedi/qedi_gbl.h @@ -17,7 +17,7 @@ extern int qedi_do_not_recover; extern uint qedi_io_tracing; -extern struct scsi_host_template qedi_host_template; +extern const struct scsi_host_template qedi_host_template; extern struct iscsi_transport qedi_iscsi_transport; extern const struct qed_iscsi_ops *qedi_ops; extern const struct qedi_debugfs_ops qedi_debugfs_ops[]; diff --git a/drivers/scsi/qedi/qedi_iscsi.c b/drivers/scsi/qedi/qedi_iscsi.c index 31ec429104e2..6ed8ef97642c 100644 --- a/drivers/scsi/qedi/qedi_iscsi.c +++ b/drivers/scsi/qedi/qedi_iscsi.c @@ -40,7 +40,7 @@ static int qedi_eh_host_reset(struct scsi_cmnd *cmd) return qedi_recover_all_conns(qedi); } -struct scsi_host_template qedi_host_template = { +const struct scsi_host_template qedi_host_template = { .module = THIS_MODULE, .name = "QLogic QEDI 25/40/100Gb iSCSI Initiator Driver", .proc_name = QEDI_MODULE_NAME, diff --git a/drivers/scsi/qla1280.c b/drivers/scsi/qla1280.c index 1e7f4d138e06..6e5e89aaa283 100644 --- a/drivers/scsi/qla1280.c +++ b/drivers/scsi/qla1280.c @@ -4115,7 +4115,7 @@ qla1280_get_token(char *str) } -static struct scsi_host_template qla1280_driver_template = { +static const struct scsi_host_template qla1280_driver_template = { .module = THIS_MODULE, .proc_name = "qla1280", .name = "Qlogic ISP 1280/12160", diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h index ec0e987b71fa..df5e5b7fdcfe 100644 --- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h @@ -22,7 +22,6 @@ #include <linux/interrupt.h> #include <linux/workqueue.h> #include <linux/firmware.h> -#include <linux/aer.h> #include <linux/mutex.h> #include <linux/btree.h> diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h index 9aba07c7bde4..391c8b3623a6 100644 --- a/drivers/scsi/qla2xxx/qla_gbl.h +++ b/drivers/scsi/qla2xxx/qla_gbl.h @@ -214,7 +214,7 @@ extern void qla2x00_free_exchoffld_buffer(struct qla_hw_data *); extern int qla81xx_restart_mpi_firmware(scsi_qla_host_t *); -extern struct scsi_qla_host *qla2x00_create_host(struct scsi_host_template *, +extern struct scsi_qla_host *qla2x00_create_host(const struct scsi_host_template *, struct qla_hw_data *); extern void qla2x00_free_host(struct scsi_qla_host *); extern void qla2x00_relogin(struct scsi_qla_host *); diff --git a/drivers/scsi/qla2xxx/qla_mid.c b/drivers/scsi/qla2xxx/qla_mid.c index 78661b658dcd..b67416951a5f 100644 --- a/drivers/scsi/qla2xxx/qla_mid.c +++ b/drivers/scsi/qla2xxx/qla_mid.c @@ -496,7 +496,7 @@ qla24xx_create_vhost(struct fc_vport *fc_vport) scsi_qla_host_t *base_vha = shost_priv(fc_vport->shost); struct qla_hw_data *ha = base_vha->hw; scsi_qla_host_t *vha; - struct scsi_host_template *sht = &qla2xxx_driver_template; + const struct scsi_host_template *sht = &qla2xxx_driver_template; struct Scsi_Host *host; vha = qla2x00_create_host(sht, ha); diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index d0cdbfe771a9..2fa695bf38b7 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c @@ -2958,9 +2958,6 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) ql2xallocfwdump = 0; } - /* This may fail but that's ok */ - pci_enable_pcie_error_reporting(pdev); - ha = kzalloc(sizeof(struct qla_hw_data), GFP_KERNEL); if (!ha) { ql_log_pci(ql_log_fatal, pdev, 0x0009, @@ -3968,8 +3965,6 @@ qla2x00_remove_one(struct pci_dev *pdev) pci_release_selected_regions(ha->pdev, ha->bars); kfree(ha); - pci_disable_pcie_error_reporting(pdev); - pci_disable_device(pdev); } @@ -5024,8 +5019,8 @@ qla2x00_mem_free(struct qla_hw_data *ha) ha->vp_map = NULL; } -struct scsi_qla_host *qla2x00_create_host(struct scsi_host_template *sht, - struct qla_hw_data *ha) +struct scsi_qla_host *qla2x00_create_host(const struct scsi_host_template *sht, + struct qla_hw_data *ha) { struct Scsi_Host *host; struct scsi_qla_host *vha = NULL; @@ -6845,7 +6840,6 @@ qla2x00_disable_board_on_pci_error(struct work_struct *work) qla2x00_unmap_iobases(ha); pci_release_selected_regions(ha->pdev, ha->bars); - pci_disable_pcie_error_reporting(pdev); pci_disable_device(pdev); /* diff --git a/drivers/scsi/qla2xxx/qla_target.c b/drivers/scsi/qla2xxx/qla_target.c index aa0cf5ca6c1c..5258b07687a9 100644 --- a/drivers/scsi/qla2xxx/qla_target.c +++ b/drivers/scsi/qla2xxx/qla_target.c @@ -6395,8 +6395,7 @@ int qlt_add_target(struct qla_hw_data *ha, struct scsi_qla_host *base_vha) return -ENOMEM; } - if (!(base_vha->host->hostt->supported_mode & MODE_TARGET)) - base_vha->host->hostt->supported_mode |= MODE_TARGET; + qla2xxx_driver_template.supported_mode |= MODE_TARGET; rc = btree_init64(&tgt->lun_qpair_map); if (rc) { diff --git a/drivers/scsi/qla2xxx/tcm_qla2xxx.c b/drivers/scsi/qla2xxx/tcm_qla2xxx.c index 8024322c9c5a..3b5ba4b47b3b 100644 --- a/drivers/scsi/qla2xxx/tcm_qla2xxx.c +++ b/drivers/scsi/qla2xxx/tcm_qla2xxx.c @@ -377,11 +377,6 @@ static void tcm_qla2xxx_close_session(struct se_session *se_sess) tcm_qla2xxx_put_sess(sess); } -static u32 tcm_qla2xxx_sess_get_index(struct se_session *se_sess) -{ - return 0; -} - static int tcm_qla2xxx_write_pending(struct se_cmd *se_cmd) { struct qla_tgt_cmd *cmd = container_of(se_cmd, @@ -421,11 +416,6 @@ static int tcm_qla2xxx_write_pending(struct se_cmd *se_cmd) return qlt_rdy_to_xfer(cmd); } -static void tcm_qla2xxx_set_default_node_attrs(struct se_node_acl *nacl) -{ - return; -} - static int tcm_qla2xxx_get_cmd_state(struct se_cmd *se_cmd) { if (!(se_cmd->se_cmd_flags & SCF_SCSI_TMR_CDB)) { @@ -1811,10 +1801,8 @@ static const struct target_core_fabric_ops tcm_qla2xxx_ops = { .check_stop_free = tcm_qla2xxx_check_stop_free, .release_cmd = tcm_qla2xxx_release_cmd, .close_session = tcm_qla2xxx_close_session, - .sess_get_index = tcm_qla2xxx_sess_get_index, .sess_get_initiator_sid = NULL, .write_pending = tcm_qla2xxx_write_pending, - .set_default_node_attributes = tcm_qla2xxx_set_default_node_attrs, .get_cmd_state = tcm_qla2xxx_get_cmd_state, .queue_data_in = tcm_qla2xxx_queue_data_in, .queue_status = tcm_qla2xxx_queue_status, @@ -1852,10 +1840,8 @@ static const struct target_core_fabric_ops tcm_qla2xxx_npiv_ops = { .check_stop_free = tcm_qla2xxx_check_stop_free, .release_cmd = tcm_qla2xxx_release_cmd, .close_session = tcm_qla2xxx_close_session, - .sess_get_index = tcm_qla2xxx_sess_get_index, .sess_get_initiator_sid = NULL, .write_pending = tcm_qla2xxx_write_pending, - .set_default_node_attributes = tcm_qla2xxx_set_default_node_attrs, .get_cmd_state = tcm_qla2xxx_get_cmd_state, .queue_data_in = tcm_qla2xxx_queue_data_in, .queue_status = tcm_qla2xxx_queue_status, diff --git a/drivers/scsi/qla4xxx/ql4_def.h b/drivers/scsi/qla4xxx/ql4_def.h index 5f82c8afd5e0..5e683ba49fa5 100644 --- a/drivers/scsi/qla4xxx/ql4_def.h +++ b/drivers/scsi/qla4xxx/ql4_def.h @@ -23,7 +23,6 @@ #include <linux/delay.h> #include <linux/interrupt.h> #include <linux/mutex.h> -#include <linux/aer.h> #include <linux/bsg-lib.h> #include <linux/vmalloc.h> diff --git a/drivers/scsi/qla4xxx/ql4_isr.c b/drivers/scsi/qla4xxx/ql4_isr.c index 6f0e77dc2a34..cf52258ecdde 100644 --- a/drivers/scsi/qla4xxx/ql4_isr.c +++ b/drivers/scsi/qla4xxx/ql4_isr.c @@ -472,14 +472,12 @@ static void qla4xxx_mbox_status_entry(struct scsi_qla_host *ha, **/ void qla4xxx_process_response_queue(struct scsi_qla_host *ha) { - uint32_t count = 0; struct srb *srb = NULL; struct status_entry *sts_entry; /* Process all responses from response queue */ while ((ha->response_ptr->signature != RESPONSE_PROCESSED)) { sts_entry = (struct status_entry *) ha->response_ptr; - count++; /* Advance pointers for next entry */ if (ha->response_out == (RESPONSE_QUEUE_DEPTH - 1)) { diff --git a/drivers/scsi/qla4xxx/ql4_os.c b/drivers/scsi/qla4xxx/ql4_os.c index 005502125b27..ee6d784c095c 100644 --- a/drivers/scsi/qla4xxx/ql4_os.c +++ b/drivers/scsi/qla4xxx/ql4_os.c @@ -8639,8 +8639,6 @@ static int qla4xxx_probe_adapter(struct pci_dev *pdev, ha->host_no = host->host_no; ha->func_num = PCI_FUNC(ha->pdev->devfn); - pci_enable_pcie_error_reporting(pdev); - /* Setup Runtime configurable options */ if (is_qla8022(ha)) { ha->isp_ops = &qla4_82xx_isp_ops; @@ -8867,7 +8865,6 @@ probe_failed: qla4xxx_free_adapter(ha); probe_failed_ioconfig: - pci_disable_pcie_error_reporting(pdev); scsi_host_put(ha->host); probe_disable_device: @@ -9022,7 +9019,6 @@ static void qla4xxx_remove_adapter(struct pci_dev *pdev) scsi_host_put(ha->host); - pci_disable_pcie_error_reporting(pdev); pci_disable_device(pdev); } diff --git a/drivers/scsi/qlogicpti.c b/drivers/scsi/qlogicpti.c index 8c961ff03fcd..1e8fbd457248 100644 --- a/drivers/scsi/qlogicpti.c +++ b/drivers/scsi/qlogicpti.c @@ -513,7 +513,7 @@ static int qlogicpti_load_firmware(struct qlogicpti *qpti) qpti->qpti_id); err = 1; goto out; - } + } sbus_writew(SBUS_CTRL_RESET, qpti->qregs + SBUS_CTRL); sbus_writew((DMA_CTRL_CCLEAR | DMA_CTRL_CIRQ), qpti->qregs + CMD_DMA_CTRL); sbus_writew((DMA_CTRL_CCLEAR | DMA_CTRL_CIRQ), qpti->qregs + DATA_DMA_CTRL); @@ -563,7 +563,7 @@ static int qlogicpti_load_firmware(struct qlogicpti *qpti) qpti->qpti_id); err = 1; goto out; - } + } /* Load it up.. */ for (i = 0; i < risc_code_length; i++) { @@ -1136,7 +1136,7 @@ static struct scsi_cmnd *qlogicpti_intr_handler(struct qlogicpti *qpti) if (!(sbus_readw(qpti->qregs + SBUS_STAT) & SBUS_STAT_RINT)) return NULL; - + in_ptr = sbus_readw(qpti->qregs + MBOX5); sbus_writew(HCCTRL_CRIRQ, qpti->qregs + HCCTRL); if (sbus_readw(qpti->qregs + SBUS_SEMAPHORE) & SBUS_SEMAPHORE_LCK) { @@ -1287,7 +1287,7 @@ static int qlogicpti_reset(struct scsi_cmnd *Cmnd) return return_status; } -static struct scsi_host_template qpti_template = { +static const struct scsi_host_template qpti_template = { .module = THIS_MODULE, .name = "qlogicpti", .info = qlogicpti_info, @@ -1362,9 +1362,8 @@ static int qpti_sbus_probe(struct platform_device *op) fcode = of_get_property(dp, "isp-fcode", NULL); if (fcode && fcode[0]) printk("(FCode %s)", fcode); - if (of_find_property(dp, "differential", NULL) != NULL) - qpti->differential = 1; - + qpti->differential = of_property_read_bool(dp, "differential"); + printk("\nqlogicpti%d: [%s Wide, using %s interface]\n", qpti->qpti_id, (qpti->ultra ? "Ultra" : "Fast"), diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c index 8553277effb3..f4fa1035a191 100644 --- a/drivers/scsi/scsi_debug.c +++ b/drivers/scsi/scsi_debug.c @@ -250,6 +250,11 @@ static const char *sdebug_version_date = "20210520"; #define SDEB_XA_NOT_IN_USE XA_MARK_1 +static struct kmem_cache *queued_cmd_cache; + +#define TO_QUEUED_CMD(scmd) ((void *)(scmd)->host_scribble) +#define ASSIGN_QUEUED_CMD(scmnd, qc) { (scmnd)->host_scribble = (void *) qc; } + /* Zone types (zbcr05 table 25) */ enum sdebug_z_type { ZBC_ZTYPE_CNV = 0x1, @@ -288,7 +293,6 @@ struct sdebug_dev_info { uuid_t lu_name; struct sdebug_host_info *sdbg_host; unsigned long uas_bm[1]; - atomic_t num_in_q; atomic_t stopped; /* 1: by SSU, 2: device start */ bool used; @@ -324,9 +328,12 @@ struct sdeb_store_info { void *map_storep; /* provisioning map */ }; -#define to_sdebug_host(d) \ +#define dev_to_sdebug_host(d) \ container_of(d, struct sdebug_host_info, dev) +#define shost_to_sdebug_host(shost) \ + dev_to_sdebug_host(shost->dma_dev) + enum sdeb_defer_type {SDEB_DEFER_NONE = 0, SDEB_DEFER_HRT = 1, SDEB_DEFER_WQ = 2, SDEB_DEFER_POLL = 3}; @@ -334,13 +341,7 @@ struct sdebug_defer { struct hrtimer hrt; struct execute_work ew; ktime_t cmpl_ts;/* time since boot to complete this cmd */ - int sqa_idx; /* index of sdebug_queue array */ - int qc_idx; /* index of sdebug_queued_cmd array within sqa_idx */ - int hc_idx; /* hostwide tag index */ int issuing_cpu; - bool init_hrt; - bool init_wq; - bool init_poll; bool aborted; /* true when blk_abort_request() already called */ enum sdeb_defer_type defer_t; }; @@ -349,15 +350,12 @@ struct sdebug_queued_cmd { /* corresponding bit set in in_use_bm[] in owning struct sdebug_queue * instance indicates this slot is in use. */ - struct sdebug_defer *sd_dp; - struct scsi_cmnd *a_cmnd; + struct sdebug_defer sd_dp; + struct scsi_cmnd *scmd; }; -struct sdebug_queue { - struct sdebug_queued_cmd qc_arr[SDEBUG_CANQUEUE]; - unsigned long in_use_bm[SDEBUG_CANQUEUE_WORDS]; - spinlock_t qc_lock; - atomic_t blocked; /* to temporarily stop more being queued */ +struct sdebug_scsi_cmd { + spinlock_t lock; }; static atomic_t sdebug_cmnd_count; /* number of incoming commands */ @@ -507,6 +505,8 @@ static int sdebug_add_store(void); static void sdebug_erase_store(int idx, struct sdeb_store_info *sip); static void sdebug_erase_all_stores(bool apart_from_first); +static void sdebug_free_queued_cmd(struct sdebug_queued_cmd *sqcp); + /* * The following are overflow arrays for cdbs that "hit" the same index in * the opcode_info_arr array. The most time sensitive (or commonly used) cdb @@ -754,7 +754,6 @@ static int sdebug_max_luns = DEF_MAX_LUNS; static int sdebug_max_queue = SDEBUG_CANQUEUE; /* per submit queue */ static unsigned int sdebug_medium_error_start = OPT_MEDIUM_ERR_ADDR; static int sdebug_medium_error_count = OPT_MEDIUM_ERR_NUM; -static atomic_t retired_max_queue; /* if > 0 then was prior max_queue */ static int sdebug_ndelay = DEF_NDELAY; /* if > 0 then unit is nanoseconds */ static int sdebug_no_lun_0 = DEF_NO_LUN_0; static int sdebug_no_uld; @@ -814,7 +813,7 @@ static int sdebug_cylinders_per; /* cylinders per surface */ static int sdebug_sectors_per; /* sectors per cylinder */ static LIST_HEAD(sdebug_host_list); -static DEFINE_SPINLOCK(sdebug_host_list_lock); +static DEFINE_MUTEX(sdebug_host_list_mutex); static struct xarray per_store_arr; static struct xarray *per_store_ap = &per_store_arr; @@ -841,7 +840,6 @@ static int sdeb_zbc_nr_conv = DEF_ZBC_NR_CONV_ZONES; static int submit_queues = DEF_SUBMIT_QUEUES; /* > 1 for multi-queue (mq) */ static int poll_queues; /* iouring iopoll interface.*/ -static struct sdebug_queue *sdebug_q_arr; /* ptr to array of submit queues */ static DEFINE_RWLOCK(atomic_rw); static DEFINE_RWLOCK(atomic_rw2); @@ -906,7 +904,7 @@ static void sdebug_max_tgts_luns(void) struct sdebug_host_info *sdbg_host; struct Scsi_Host *hpnt; - spin_lock(&sdebug_host_list_lock); + mutex_lock(&sdebug_host_list_mutex); list_for_each_entry(sdbg_host, &sdebug_host_list, host_list) { hpnt = sdbg_host->shost; if ((hpnt->this_id >= 0) && @@ -917,7 +915,7 @@ static void sdebug_max_tgts_luns(void) /* sdebug_max_luns; */ hpnt->max_lun = SCSI_W_LUN_REPORT_LUNS + 1; } - spin_unlock(&sdebug_host_list_lock); + mutex_unlock(&sdebug_host_list_mutex); } enum sdeb_cmd_data {SDEB_IN_DATA = 0, SDEB_IN_CDB = 1}; @@ -1049,30 +1047,27 @@ static void all_config_cdb_len(void) struct Scsi_Host *shost; struct scsi_device *sdev; - spin_lock(&sdebug_host_list_lock); + mutex_lock(&sdebug_host_list_mutex); list_for_each_entry(sdbg_host, &sdebug_host_list, host_list) { shost = sdbg_host->shost; shost_for_each_device(sdev, shost) { config_cdb_len(sdev); } } - spin_unlock(&sdebug_host_list_lock); + mutex_unlock(&sdebug_host_list_mutex); } static void clear_luns_changed_on_target(struct sdebug_dev_info *devip) { - struct sdebug_host_info *sdhp; + struct sdebug_host_info *sdhp = devip->sdbg_host; struct sdebug_dev_info *dp; - spin_lock(&sdebug_host_list_lock); - list_for_each_entry(sdhp, &sdebug_host_list, host_list) { - list_for_each_entry(dp, &sdhp->dev_info_list, dev_list) { - if ((devip->sdbg_host == dp->sdbg_host) && - (devip->target == dp->target)) - clear_bit(SDEBUG_UA_LUNS_CHANGED, dp->uas_bm); + list_for_each_entry(dp, &sdhp->dev_info_list, dev_list) { + if ((devip->sdbg_host == dp->sdbg_host) && + (devip->target == dp->target)) { + clear_bit(SDEBUG_UA_LUNS_CHANGED, dp->uas_bm); } } - spin_unlock(&sdebug_host_list_lock); } static int make_ua(struct scsi_cmnd *scp, struct sdebug_dev_info *devip) @@ -4899,20 +4894,6 @@ fini: return res; } -static struct sdebug_queue *get_queue(struct scsi_cmnd *cmnd) -{ - u16 hwq; - u32 tag = blk_mq_unique_tag(scsi_cmd_to_rq(cmnd)); - - hwq = blk_mq_unique_tag_to_hwq(tag); - - pr_debug("tag=%#x, hwq=%d\n", tag, hwq); - if (WARN_ON_ONCE(hwq >= submit_queues)) - hwq = 0; - - return sdebug_q_arr + hwq; -} - static u32 get_tag(struct scsi_cmnd *cmnd) { return blk_mq_unique_tag(scsi_cmd_to_rq(cmnd)); @@ -4921,75 +4902,41 @@ static u32 get_tag(struct scsi_cmnd *cmnd) /* Queued (deferred) command completions converge here. */ static void sdebug_q_cmd_complete(struct sdebug_defer *sd_dp) { - bool aborted = sd_dp->aborted; - int qc_idx; - int retiring = 0; - unsigned long iflags; - struct sdebug_queue *sqp; - struct sdebug_queued_cmd *sqcp; - struct scsi_cmnd *scp; - struct sdebug_dev_info *devip; + struct sdebug_queued_cmd *sqcp = container_of(sd_dp, struct sdebug_queued_cmd, sd_dp); + unsigned long flags; + struct scsi_cmnd *scp = sqcp->scmd; + struct sdebug_scsi_cmd *sdsc; + bool aborted; - if (unlikely(aborted)) - sd_dp->aborted = false; - qc_idx = sd_dp->qc_idx; - sqp = sdebug_q_arr + sd_dp->sqa_idx; if (sdebug_statistics) { atomic_inc(&sdebug_completions); if (raw_smp_processor_id() != sd_dp->issuing_cpu) atomic_inc(&sdebug_miss_cpus); } - if (unlikely((qc_idx < 0) || (qc_idx >= SDEBUG_CANQUEUE))) { - pr_err("wild qc_idx=%d\n", qc_idx); - return; - } - spin_lock_irqsave(&sqp->qc_lock, iflags); - WRITE_ONCE(sd_dp->defer_t, SDEB_DEFER_NONE); - sqcp = &sqp->qc_arr[qc_idx]; - scp = sqcp->a_cmnd; - if (unlikely(scp == NULL)) { - spin_unlock_irqrestore(&sqp->qc_lock, iflags); - pr_err("scp is NULL, sqa_idx=%d, qc_idx=%d, hc_idx=%d\n", - sd_dp->sqa_idx, qc_idx, sd_dp->hc_idx); - return; - } - devip = (struct sdebug_dev_info *)scp->device->hostdata; - if (likely(devip)) - atomic_dec(&devip->num_in_q); - else - pr_err("devip=NULL\n"); - if (unlikely(atomic_read(&retired_max_queue) > 0)) - retiring = 1; - - sqcp->a_cmnd = NULL; - if (unlikely(!test_and_clear_bit(qc_idx, sqp->in_use_bm))) { - spin_unlock_irqrestore(&sqp->qc_lock, iflags); - pr_err("Unexpected completion\n"); - return; + + if (!scp) { + pr_err("scmd=NULL\n"); + goto out; } - if (unlikely(retiring)) { /* user has reduced max_queue */ - int k, retval; + sdsc = scsi_cmd_priv(scp); + spin_lock_irqsave(&sdsc->lock, flags); + aborted = sd_dp->aborted; + if (unlikely(aborted)) + sd_dp->aborted = false; + ASSIGN_QUEUED_CMD(scp, NULL); + + spin_unlock_irqrestore(&sdsc->lock, flags); - retval = atomic_read(&retired_max_queue); - if (qc_idx >= retval) { - spin_unlock_irqrestore(&sqp->qc_lock, iflags); - pr_err("index %d too large\n", retval); - return; - } - k = find_last_bit(sqp->in_use_bm, retval); - if ((k < sdebug_max_queue) || (k == retval)) - atomic_set(&retired_max_queue, 0); - else - atomic_set(&retired_max_queue, k + 1); - } - spin_unlock_irqrestore(&sqp->qc_lock, iflags); - if (unlikely(aborted)) { - if (sdebug_verbose) - pr_info("bypassing scsi_done() due to aborted cmd\n"); - return; + if (aborted) { + pr_info("bypassing scsi_done() due to aborted cmd, kicking-off EH\n"); + blk_abort_request(scsi_cmd_to_rq(scp)); + goto out; } + scsi_done(scp); /* callback to mid level */ +out: + sdebug_free_queued_cmd(sqcp); } /* When high resolution timer goes off this function is called. */ @@ -5152,7 +5099,6 @@ static struct sdebug_dev_info *sdebug_device_create( } else { devip->zmodel = BLK_ZONED_NONE; } - devip->sdbg_host = sdbg_host; devip->create_ts = ktime_get_boottime(); atomic_set(&devip->stopped, (sdeb_tur_ms_to_ready > 0 ? 2 : 0)); list_add_tail(&devip->dev_list, &sdbg_host->dev_info_list); @@ -5166,11 +5112,7 @@ static struct sdebug_dev_info *find_build_dev_info(struct scsi_device *sdev) struct sdebug_dev_info *open_devip = NULL; struct sdebug_dev_info *devip; - sdbg_host = *(struct sdebug_host_info **)shost_priv(sdev->host); - if (!sdbg_host) { - pr_err("Host info NULL\n"); - return NULL; - } + sdbg_host = shost_to_sdebug_host(sdev->host); list_for_each_entry(devip, &sdbg_host->dev_info_list, dev_list) { if ((devip->used) && (devip->channel == sdev->channel) && @@ -5194,7 +5136,6 @@ static struct sdebug_dev_info *find_build_dev_info(struct scsi_device *sdev) open_devip->target = sdev->id; open_devip->lun = sdev->lun; open_devip->sdbg_host = sdbg_host; - atomic_set(&open_devip->num_in_q, 0); set_bit(SDEBUG_UA_POOCCUR, open_devip->uas_bm); open_devip->used = true; return open_devip; @@ -5245,215 +5186,171 @@ static void scsi_debug_slave_destroy(struct scsi_device *sdp) } } -static void stop_qc_helper(struct sdebug_defer *sd_dp, +/* Returns true if we require the queued memory to be freed by the caller. */ +static bool stop_qc_helper(struct sdebug_defer *sd_dp, enum sdeb_defer_type defer_t) { - if (!sd_dp) - return; - if (defer_t == SDEB_DEFER_HRT) - hrtimer_cancel(&sd_dp->hrt); - else if (defer_t == SDEB_DEFER_WQ) - cancel_work_sync(&sd_dp->ew.work); -} - -/* If @cmnd found deletes its timer or work queue and returns true; else - returns false */ -static bool stop_queued_cmnd(struct scsi_cmnd *cmnd) -{ - unsigned long iflags; - int j, k, qmax, r_qmax; - enum sdeb_defer_type l_defer_t; - struct sdebug_queue *sqp; - struct sdebug_queued_cmd *sqcp; - struct sdebug_dev_info *devip; - struct sdebug_defer *sd_dp; + if (defer_t == SDEB_DEFER_HRT) { + int res = hrtimer_try_to_cancel(&sd_dp->hrt); - for (j = 0, sqp = sdebug_q_arr; j < submit_queues; ++j, ++sqp) { - spin_lock_irqsave(&sqp->qc_lock, iflags); - qmax = sdebug_max_queue; - r_qmax = atomic_read(&retired_max_queue); - if (r_qmax > qmax) - qmax = r_qmax; - for (k = 0; k < qmax; ++k) { - if (test_bit(k, sqp->in_use_bm)) { - sqcp = &sqp->qc_arr[k]; - if (cmnd != sqcp->a_cmnd) - continue; - /* found */ - devip = (struct sdebug_dev_info *) - cmnd->device->hostdata; - if (devip) - atomic_dec(&devip->num_in_q); - sqcp->a_cmnd = NULL; - sd_dp = sqcp->sd_dp; - if (sd_dp) { - l_defer_t = READ_ONCE(sd_dp->defer_t); - WRITE_ONCE(sd_dp->defer_t, SDEB_DEFER_NONE); - } else - l_defer_t = SDEB_DEFER_NONE; - spin_unlock_irqrestore(&sqp->qc_lock, iflags); - stop_qc_helper(sd_dp, l_defer_t); - clear_bit(k, sqp->in_use_bm); - return true; - } + switch (res) { + case 0: /* Not active, it must have already run */ + case -1: /* -1 It's executing the CB */ + return false; + case 1: /* Was active, we've now cancelled */ + default: + return true; } - spin_unlock_irqrestore(&sqp->qc_lock, iflags); + } else if (defer_t == SDEB_DEFER_WQ) { + /* Cancel if pending */ + if (cancel_work_sync(&sd_dp->ew.work)) + return true; + /* Was not pending, so it must have run */ + return false; + } else if (defer_t == SDEB_DEFER_POLL) { + return true; } + return false; } -/* Deletes (stops) timers or work queues of all queued commands */ -static void stop_all_queued(void) + +static bool scsi_debug_stop_cmnd(struct scsi_cmnd *cmnd) { - unsigned long iflags; - int j, k; enum sdeb_defer_type l_defer_t; - struct sdebug_queue *sqp; - struct sdebug_queued_cmd *sqcp; - struct sdebug_dev_info *devip; struct sdebug_defer *sd_dp; + struct sdebug_scsi_cmd *sdsc = scsi_cmd_priv(cmnd); + struct sdebug_queued_cmd *sqcp = TO_QUEUED_CMD(cmnd); - for (j = 0, sqp = sdebug_q_arr; j < submit_queues; ++j, ++sqp) { - spin_lock_irqsave(&sqp->qc_lock, iflags); - for (k = 0; k < SDEBUG_CANQUEUE; ++k) { - if (test_bit(k, sqp->in_use_bm)) { - sqcp = &sqp->qc_arr[k]; - if (sqcp->a_cmnd == NULL) - continue; - devip = (struct sdebug_dev_info *) - sqcp->a_cmnd->device->hostdata; - if (devip) - atomic_dec(&devip->num_in_q); - sqcp->a_cmnd = NULL; - sd_dp = sqcp->sd_dp; - if (sd_dp) { - l_defer_t = READ_ONCE(sd_dp->defer_t); - WRITE_ONCE(sd_dp->defer_t, SDEB_DEFER_NONE); - } else - l_defer_t = SDEB_DEFER_NONE; - spin_unlock_irqrestore(&sqp->qc_lock, iflags); - stop_qc_helper(sd_dp, l_defer_t); - clear_bit(k, sqp->in_use_bm); - spin_lock_irqsave(&sqp->qc_lock, iflags); - } - } - spin_unlock_irqrestore(&sqp->qc_lock, iflags); - } + lockdep_assert_held(&sdsc->lock); + + if (!sqcp) + return false; + sd_dp = &sqcp->sd_dp; + l_defer_t = READ_ONCE(sd_dp->defer_t); + ASSIGN_QUEUED_CMD(cmnd, NULL); + + if (stop_qc_helper(sd_dp, l_defer_t)) + sdebug_free_queued_cmd(sqcp); + + return true; +} + +/* + * Called from scsi_debug_abort() only, which is for timed-out cmd. + */ +static bool scsi_debug_abort_cmnd(struct scsi_cmnd *cmnd) +{ + struct sdebug_scsi_cmd *sdsc = scsi_cmd_priv(cmnd); + unsigned long flags; + bool res; + + spin_lock_irqsave(&sdsc->lock, flags); + res = scsi_debug_stop_cmnd(cmnd); + spin_unlock_irqrestore(&sdsc->lock, flags); + + return res; } -/* Free queued command memory on heap */ -static void free_all_queued(void) +/* + * All we can do is set the cmnd as internally aborted and wait for it to + * finish. We cannot call scsi_done() as normal completion path may do that. + */ +static bool sdebug_stop_cmnd(struct request *rq, void *data) { - int j, k; - struct sdebug_queue *sqp; - struct sdebug_queued_cmd *sqcp; + scsi_debug_abort_cmnd(blk_mq_rq_to_pdu(rq)); - for (j = 0, sqp = sdebug_q_arr; j < submit_queues; ++j, ++sqp) { - for (k = 0; k < SDEBUG_CANQUEUE; ++k) { - sqcp = &sqp->qc_arr[k]; - kfree(sqcp->sd_dp); - sqcp->sd_dp = NULL; - } + return true; +} + +/* Deletes (stops) timers or work queues of all queued commands */ +static void stop_all_queued(void) +{ + struct sdebug_host_info *sdhp; + + mutex_lock(&sdebug_host_list_mutex); + list_for_each_entry(sdhp, &sdebug_host_list, host_list) { + struct Scsi_Host *shost = sdhp->shost; + + blk_mq_tagset_busy_iter(&shost->tag_set, sdebug_stop_cmnd, NULL); } + mutex_unlock(&sdebug_host_list_mutex); } static int scsi_debug_abort(struct scsi_cmnd *SCpnt) { - bool ok; + bool ok = scsi_debug_abort_cmnd(SCpnt); ++num_aborts; - if (SCpnt) { - ok = stop_queued_cmnd(SCpnt); - if (SCpnt->device && (SDEBUG_OPT_ALL_NOISE & sdebug_opts)) - sdev_printk(KERN_INFO, SCpnt->device, - "%s: command%s found\n", __func__, - ok ? "" : " not"); - } + + if (SDEBUG_OPT_ALL_NOISE & sdebug_opts) + sdev_printk(KERN_INFO, SCpnt->device, + "%s: command%s found\n", __func__, + ok ? "" : " not"); + return SUCCESS; } static int scsi_debug_device_reset(struct scsi_cmnd *SCpnt) { + struct scsi_device *sdp = SCpnt->device; + struct sdebug_dev_info *devip = sdp->hostdata; + ++num_dev_resets; - if (SCpnt && SCpnt->device) { - struct scsi_device *sdp = SCpnt->device; - struct sdebug_dev_info *devip = - (struct sdebug_dev_info *)sdp->hostdata; - if (SDEBUG_OPT_ALL_NOISE & sdebug_opts) - sdev_printk(KERN_INFO, sdp, "%s\n", __func__); - if (devip) - set_bit(SDEBUG_UA_POR, devip->uas_bm); - } + if (SDEBUG_OPT_ALL_NOISE & sdebug_opts) + sdev_printk(KERN_INFO, sdp, "%s\n", __func__); + if (devip) + set_bit(SDEBUG_UA_POR, devip->uas_bm); + return SUCCESS; } static int scsi_debug_target_reset(struct scsi_cmnd *SCpnt) { - struct sdebug_host_info *sdbg_host; + struct scsi_device *sdp = SCpnt->device; + struct sdebug_host_info *sdbg_host = shost_to_sdebug_host(sdp->host); struct sdebug_dev_info *devip; - struct scsi_device *sdp; - struct Scsi_Host *hp; int k = 0; ++num_target_resets; - if (!SCpnt) - goto lie; - sdp = SCpnt->device; - if (!sdp) - goto lie; if (SDEBUG_OPT_ALL_NOISE & sdebug_opts) sdev_printk(KERN_INFO, sdp, "%s\n", __func__); - hp = sdp->host; - if (!hp) - goto lie; - sdbg_host = *(struct sdebug_host_info **)shost_priv(hp); - if (sdbg_host) { - list_for_each_entry(devip, - &sdbg_host->dev_info_list, - dev_list) - if (devip->target == sdp->id) { - set_bit(SDEBUG_UA_BUS_RESET, devip->uas_bm); - ++k; - } + + list_for_each_entry(devip, &sdbg_host->dev_info_list, dev_list) { + if (devip->target == sdp->id) { + set_bit(SDEBUG_UA_BUS_RESET, devip->uas_bm); + ++k; + } } + if (SDEBUG_OPT_RESET_NOISE & sdebug_opts) sdev_printk(KERN_INFO, sdp, "%s: %d device(s) found in target\n", __func__, k); -lie: + return SUCCESS; } static int scsi_debug_bus_reset(struct scsi_cmnd *SCpnt) { - struct sdebug_host_info *sdbg_host; + struct scsi_device *sdp = SCpnt->device; + struct sdebug_host_info *sdbg_host = shost_to_sdebug_host(sdp->host); struct sdebug_dev_info *devip; - struct scsi_device *sdp; - struct Scsi_Host *hp; int k = 0; ++num_bus_resets; - if (!(SCpnt && SCpnt->device)) - goto lie; - sdp = SCpnt->device; + if (SDEBUG_OPT_ALL_NOISE & sdebug_opts) sdev_printk(KERN_INFO, sdp, "%s\n", __func__); - hp = sdp->host; - if (hp) { - sdbg_host = *(struct sdebug_host_info **)shost_priv(hp); - if (sdbg_host) { - list_for_each_entry(devip, - &sdbg_host->dev_info_list, - dev_list) { - set_bit(SDEBUG_UA_BUS_RESET, devip->uas_bm); - ++k; - } - } + + list_for_each_entry(devip, &sdbg_host->dev_info_list, dev_list) { + set_bit(SDEBUG_UA_BUS_RESET, devip->uas_bm); + ++k; } + if (SDEBUG_OPT_RESET_NOISE & sdebug_opts) sdev_printk(KERN_INFO, sdp, "%s: %d device(s) found in host\n", __func__, k); -lie: return SUCCESS; } @@ -5464,9 +5361,9 @@ static int scsi_debug_host_reset(struct scsi_cmnd *SCpnt) int k = 0; ++num_host_resets; - if ((SCpnt->device) && (SDEBUG_OPT_ALL_NOISE & sdebug_opts)) + if (SDEBUG_OPT_ALL_NOISE & sdebug_opts) sdev_printk(KERN_INFO, SCpnt->device, "%s\n", __func__); - spin_lock(&sdebug_host_list_lock); + mutex_lock(&sdebug_host_list_mutex); list_for_each_entry(sdbg_host, &sdebug_host_list, host_list) { list_for_each_entry(devip, &sdbg_host->dev_info_list, dev_list) { @@ -5474,7 +5371,7 @@ static int scsi_debug_host_reset(struct scsi_cmnd *SCpnt) ++k; } } - spin_unlock(&sdebug_host_list_lock); + mutex_unlock(&sdebug_host_list_mutex); stop_all_queued(); if (SDEBUG_OPT_RESET_NOISE & sdebug_opts) sdev_printk(KERN_INFO, SCpnt->device, @@ -5537,11 +5434,18 @@ static void sdebug_build_parts(unsigned char *ramp, unsigned long store_size) static void block_unblock_all_queues(bool block) { - int j; - struct sdebug_queue *sqp; + struct sdebug_host_info *sdhp; - for (j = 0, sqp = sdebug_q_arr; j < submit_queues; ++j, ++sqp) - atomic_set(&sqp->blocked, (int)block); + lockdep_assert_held(&sdebug_host_list_mutex); + + list_for_each_entry(sdhp, &sdebug_host_list, host_list) { + struct Scsi_Host *shost = sdhp->shost; + + if (block) + scsi_block_requests(shost); + else + scsi_unblock_requests(shost); + } } /* Adjust (by rounding down) the sdebug_cmnd_count so abs(every_nth)-1 @@ -5554,10 +5458,13 @@ static void tweak_cmnd_count(void) modulo = abs(sdebug_every_nth); if (modulo < 2) return; + + mutex_lock(&sdebug_host_list_mutex); block_unblock_all_queues(true); count = atomic_read(&sdebug_cmnd_count); atomic_set(&sdebug_cmnd_count, (count / modulo) * modulo); block_unblock_all_queues(false); + mutex_unlock(&sdebug_host_list_mutex); } static void clear_queue_stats(void) @@ -5577,6 +5484,33 @@ static bool inject_on_this_cmd(void) #define INCLUSIVE_TIMING_MAX_NS 1000000 /* 1 millisecond */ + +void sdebug_free_queued_cmd(struct sdebug_queued_cmd *sqcp) +{ + if (sqcp) + kmem_cache_free(queued_cmd_cache, sqcp); +} + +static struct sdebug_queued_cmd *sdebug_alloc_queued_cmd(struct scsi_cmnd *scmd) +{ + struct sdebug_queued_cmd *sqcp; + struct sdebug_defer *sd_dp; + + sqcp = kmem_cache_zalloc(queued_cmd_cache, GFP_ATOMIC); + if (!sqcp) + return NULL; + + sd_dp = &sqcp->sd_dp; + + hrtimer_init(&sd_dp->hrt, CLOCK_MONOTONIC, HRTIMER_MODE_REL_PINNED); + sd_dp->hrt.function = sdebug_q_cmd_hrt_complete; + INIT_WORK(&sd_dp->ew.work, sdebug_q_cmd_wq_complete); + + sqcp->scmd = scmd; + + return sqcp; +} + /* Complete the processing of the thread that queued a SCSI command to this * driver. It either completes the command by calling cmnd_done() or * schedules a hr timer or work queue then returns 0. Returns @@ -5588,13 +5522,11 @@ static int schedule_resp(struct scsi_cmnd *cmnd, struct sdebug_dev_info *devip, struct sdebug_dev_info *), int delta_jiff, int ndelay) { - bool new_sd_dp; - bool inject = false; - bool polled = scsi_cmd_to_rq(cmnd)->cmd_flags & REQ_POLLED; - int k, num_in_q, qdepth; - unsigned long iflags; + struct request *rq = scsi_cmd_to_rq(cmnd); + bool polled = rq->cmd_flags & REQ_POLLED; + struct sdebug_scsi_cmd *sdsc = scsi_cmd_priv(cmnd); + unsigned long flags; u64 ns_from_boot = 0; - struct sdebug_queue *sqp; struct sdebug_queued_cmd *sqcp; struct scsi_device *sdp; struct sdebug_defer *sd_dp; @@ -5609,66 +5541,30 @@ static int schedule_resp(struct scsi_cmnd *cmnd, struct sdebug_dev_info *devip, if (delta_jiff == 0) goto respond_in_thread; - sqp = get_queue(cmnd); - spin_lock_irqsave(&sqp->qc_lock, iflags); - if (unlikely(atomic_read(&sqp->blocked))) { - spin_unlock_irqrestore(&sqp->qc_lock, iflags); - return SCSI_MLQUEUE_HOST_BUSY; - } - num_in_q = atomic_read(&devip->num_in_q); - qdepth = cmnd->device->queue_depth; - if (unlikely((qdepth > 0) && (num_in_q >= qdepth))) { - if (scsi_result) { - spin_unlock_irqrestore(&sqp->qc_lock, iflags); - goto respond_in_thread; - } else - scsi_result = device_qfull_result; - } else if (unlikely(sdebug_every_nth && - (SDEBUG_OPT_RARE_TSF & sdebug_opts) && - (scsi_result == 0))) { - if ((num_in_q == (qdepth - 1)) && + + if (unlikely(sdebug_every_nth && (SDEBUG_OPT_RARE_TSF & sdebug_opts) && + (scsi_result == 0))) { + int num_in_q = scsi_device_busy(sdp); + int qdepth = cmnd->device->queue_depth; + + if ((num_in_q == qdepth) && (atomic_inc_return(&sdebug_a_tsf) >= abs(sdebug_every_nth))) { atomic_set(&sdebug_a_tsf, 0); - inject = true; scsi_result = device_qfull_result; - } - } - k = find_first_zero_bit(sqp->in_use_bm, sdebug_max_queue); - if (unlikely(k >= sdebug_max_queue)) { - spin_unlock_irqrestore(&sqp->qc_lock, iflags); - if (scsi_result) - goto respond_in_thread; - scsi_result = device_qfull_result; - if (SDEBUG_OPT_Q_NOISE & sdebug_opts) - sdev_printk(KERN_INFO, sdp, "%s: max_queue=%d exceeded: TASK SET FULL\n", - __func__, sdebug_max_queue); - goto respond_in_thread; - } - set_bit(k, sqp->in_use_bm); - atomic_inc(&devip->num_in_q); - sqcp = &sqp->qc_arr[k]; - sqcp->a_cmnd = cmnd; - cmnd->host_scribble = (unsigned char *)sqcp; - sd_dp = sqcp->sd_dp; - spin_unlock_irqrestore(&sqp->qc_lock, iflags); - - if (!sd_dp) { - sd_dp = kzalloc(sizeof(*sd_dp), GFP_ATOMIC); - if (!sd_dp) { - atomic_dec(&devip->num_in_q); - clear_bit(k, sqp->in_use_bm); - return SCSI_MLQUEUE_HOST_BUSY; + if (unlikely(SDEBUG_OPT_Q_NOISE & sdebug_opts)) + sdev_printk(KERN_INFO, sdp, "%s: num_in_q=%d +1, <inject> status: TASK SET FULL\n", + __func__, num_in_q); } - new_sd_dp = true; - } else { - new_sd_dp = false; } - /* Set the hostwide tag */ - if (sdebug_host_max_queue) - sd_dp->hc_idx = get_tag(cmnd); + sqcp = sdebug_alloc_queued_cmd(cmnd); + if (!sqcp) { + pr_err("%s no alloc\n", __func__); + return SCSI_MLQUEUE_HOST_BUSY; + } + sd_dp = &sqcp->sd_dp; if (polled) ns_from_boot = ktime_get_boottime_ns(); @@ -5715,14 +5611,8 @@ static int schedule_resp(struct scsi_cmnd *cmnd, struct sdebug_dev_info *devip, u64 d = ktime_get_boottime_ns() - ns_from_boot; if (kt <= d) { /* elapsed duration >= kt */ - spin_lock_irqsave(&sqp->qc_lock, iflags); - sqcp->a_cmnd = NULL; - atomic_dec(&devip->num_in_q); - clear_bit(k, sqp->in_use_bm); - spin_unlock_irqrestore(&sqp->qc_lock, iflags); - if (new_sd_dp) - kfree(sd_dp); /* call scsi_done() from this thread */ + sdebug_free_queued_cmd(sqcp); scsi_done(cmnd); return 0; } @@ -5730,72 +5620,54 @@ static int schedule_resp(struct scsi_cmnd *cmnd, struct sdebug_dev_info *devip, kt -= d; } } + if (sdebug_statistics) + sd_dp->issuing_cpu = raw_smp_processor_id(); if (polled) { + spin_lock_irqsave(&sdsc->lock, flags); sd_dp->cmpl_ts = ktime_add(ns_to_ktime(ns_from_boot), kt); - spin_lock_irqsave(&sqp->qc_lock, iflags); - if (!sd_dp->init_poll) { - sd_dp->init_poll = true; - sqcp->sd_dp = sd_dp; - sd_dp->sqa_idx = sqp - sdebug_q_arr; - sd_dp->qc_idx = k; - } + ASSIGN_QUEUED_CMD(cmnd, sqcp); WRITE_ONCE(sd_dp->defer_t, SDEB_DEFER_POLL); - spin_unlock_irqrestore(&sqp->qc_lock, iflags); + spin_unlock_irqrestore(&sdsc->lock, flags); } else { - if (!sd_dp->init_hrt) { - sd_dp->init_hrt = true; - sqcp->sd_dp = sd_dp; - hrtimer_init(&sd_dp->hrt, CLOCK_MONOTONIC, - HRTIMER_MODE_REL_PINNED); - sd_dp->hrt.function = sdebug_q_cmd_hrt_complete; - sd_dp->sqa_idx = sqp - sdebug_q_arr; - sd_dp->qc_idx = k; - } - WRITE_ONCE(sd_dp->defer_t, SDEB_DEFER_HRT); /* schedule the invocation of scsi_done() for a later time */ + spin_lock_irqsave(&sdsc->lock, flags); + ASSIGN_QUEUED_CMD(cmnd, sqcp); + WRITE_ONCE(sd_dp->defer_t, SDEB_DEFER_HRT); hrtimer_start(&sd_dp->hrt, kt, HRTIMER_MODE_REL_PINNED); + /* + * The completion handler will try to grab sqcp->lock, + * so there is no chance that the completion handler + * will call scsi_done() until we release the lock + * here (so ok to keep referencing sdsc). + */ + spin_unlock_irqrestore(&sdsc->lock, flags); } - if (sdebug_statistics) - sd_dp->issuing_cpu = raw_smp_processor_id(); } else { /* jdelay < 0, use work queue */ if (unlikely((sdebug_opts & SDEBUG_OPT_CMD_ABORT) && - atomic_read(&sdeb_inject_pending))) + atomic_read(&sdeb_inject_pending))) { sd_dp->aborted = true; + atomic_set(&sdeb_inject_pending, 0); + sdev_printk(KERN_INFO, sdp, "abort request tag=%#x\n", + blk_mq_unique_tag_to_tag(get_tag(cmnd))); + } + + if (sdebug_statistics) + sd_dp->issuing_cpu = raw_smp_processor_id(); if (polled) { + spin_lock_irqsave(&sdsc->lock, flags); + ASSIGN_QUEUED_CMD(cmnd, sqcp); sd_dp->cmpl_ts = ns_to_ktime(ns_from_boot); - spin_lock_irqsave(&sqp->qc_lock, iflags); - if (!sd_dp->init_poll) { - sd_dp->init_poll = true; - sqcp->sd_dp = sd_dp; - sd_dp->sqa_idx = sqp - sdebug_q_arr; - sd_dp->qc_idx = k; - } WRITE_ONCE(sd_dp->defer_t, SDEB_DEFER_POLL); - spin_unlock_irqrestore(&sqp->qc_lock, iflags); + spin_unlock_irqrestore(&sdsc->lock, flags); } else { - if (!sd_dp->init_wq) { - sd_dp->init_wq = true; - sqcp->sd_dp = sd_dp; - sd_dp->sqa_idx = sqp - sdebug_q_arr; - sd_dp->qc_idx = k; - INIT_WORK(&sd_dp->ew.work, sdebug_q_cmd_wq_complete); - } + spin_lock_irqsave(&sdsc->lock, flags); + ASSIGN_QUEUED_CMD(cmnd, sqcp); WRITE_ONCE(sd_dp->defer_t, SDEB_DEFER_WQ); schedule_work(&sd_dp->ew.work); - } - if (sdebug_statistics) - sd_dp->issuing_cpu = raw_smp_processor_id(); - if (unlikely(sd_dp->aborted)) { - sdev_printk(KERN_INFO, sdp, "abort request tag %d\n", - scsi_cmd_to_rq(cmnd)->tag); - blk_abort_request(scsi_cmd_to_rq(cmnd)); - atomic_set(&sdeb_inject_pending, 0); - sd_dp->aborted = false; + spin_unlock_irqrestore(&sdsc->lock, flags); } } - if (unlikely((SDEBUG_OPT_Q_NOISE & sdebug_opts) && scsi_result == device_qfull_result)) - sdev_printk(KERN_INFO, sdp, "%s: num_in_q=%d +1, %s%s\n", __func__, - num_in_q, (inject ? "<inject> " : ""), "status: TASK SET FULL"); + return 0; respond_in_thread: /* call back to mid-layer using invocation thread */ @@ -5996,14 +5868,39 @@ static int scsi_debug_write_info(struct Scsi_Host *host, char *buffer, return length; } +struct sdebug_submit_queue_data { + int *first; + int *last; + int queue_num; +}; + +static bool sdebug_submit_queue_iter(struct request *rq, void *opaque) +{ + struct sdebug_submit_queue_data *data = opaque; + u32 unique_tag = blk_mq_unique_tag(rq); + u16 hwq = blk_mq_unique_tag_to_hwq(unique_tag); + u16 tag = blk_mq_unique_tag_to_tag(unique_tag); + int queue_num = data->queue_num; + + if (hwq != queue_num) + return true; + + /* Rely on iter'ing in ascending tag order */ + if (*data->first == -1) + *data->first = *data->last = tag; + else + *data->last = tag; + + return true; +} + /* Output seen with 'cat /proc/scsi/scsi_debug/<host_id>'. It will be the * same for each scsi_debug host (if more than one). Some of the counters * output are not atomics so might be inaccurate in a busy system. */ static int scsi_debug_show_info(struct seq_file *m, struct Scsi_Host *host) { - int f, j, l; - struct sdebug_queue *sqp; struct sdebug_host_info *sdhp; + int j; seq_printf(m, "scsi_debug adapter driver, version %s [%s]\n", SDEBUG_VERSION, sdebug_version_date); @@ -6031,11 +5928,17 @@ static int scsi_debug_show_info(struct seq_file *m, struct Scsi_Host *host) atomic_read(&sdeb_mq_poll_count)); seq_printf(m, "submit_queues=%d\n", submit_queues); - for (j = 0, sqp = sdebug_q_arr; j < submit_queues; ++j, ++sqp) { + for (j = 0; j < submit_queues; ++j) { + int f = -1, l = -1; + struct sdebug_submit_queue_data data = { + .queue_num = j, + .first = &f, + .last = &l, + }; seq_printf(m, " queue %d:\n", j); - f = find_first_bit(sqp->in_use_bm, sdebug_max_queue); - if (f != sdebug_max_queue) { - l = find_last_bit(sqp->in_use_bm, sdebug_max_queue); + blk_mq_tagset_busy_iter(&host->tag_set, sdebug_submit_queue_iter, + &data); + if (f >= 0) { seq_printf(m, " in_use_bm BUSY: %s: %d,%d\n", "first,last bits", f, l); } @@ -6086,15 +5989,15 @@ static ssize_t delay_store(struct device_driver *ddp, const char *buf, if (count > 0 && sscanf(buf, "%d", &jdelay) == 1) { res = count; if (sdebug_jdelay != jdelay) { - int j, k; - struct sdebug_queue *sqp; + struct sdebug_host_info *sdhp; + mutex_lock(&sdebug_host_list_mutex); block_unblock_all_queues(true); - for (j = 0, sqp = sdebug_q_arr; j < submit_queues; - ++j, ++sqp) { - k = find_first_bit(sqp->in_use_bm, - sdebug_max_queue); - if (k != sdebug_max_queue) { + + list_for_each_entry(sdhp, &sdebug_host_list, host_list) { + struct Scsi_Host *shost = sdhp->shost; + + if (scsi_host_busy(shost)) { res = -EBUSY; /* queued commands */ break; } @@ -6104,6 +6007,7 @@ static ssize_t delay_store(struct device_driver *ddp, const char *buf, sdebug_ndelay = 0; } block_unblock_all_queues(false); + mutex_unlock(&sdebug_host_list_mutex); } return res; } @@ -6126,25 +6030,27 @@ static ssize_t ndelay_store(struct device_driver *ddp, const char *buf, (ndelay >= 0) && (ndelay < (1000 * 1000 * 1000))) { res = count; if (sdebug_ndelay != ndelay) { - int j, k; - struct sdebug_queue *sqp; + struct sdebug_host_info *sdhp; + mutex_lock(&sdebug_host_list_mutex); block_unblock_all_queues(true); - for (j = 0, sqp = sdebug_q_arr; j < submit_queues; - ++j, ++sqp) { - k = find_first_bit(sqp->in_use_bm, - sdebug_max_queue); - if (k != sdebug_max_queue) { + + list_for_each_entry(sdhp, &sdebug_host_list, host_list) { + struct Scsi_Host *shost = sdhp->shost; + + if (scsi_host_busy(shost)) { res = -EBUSY; /* queued commands */ break; } } + if (res > 0) { sdebug_ndelay = ndelay; sdebug_jdelay = ndelay ? JDELAY_OVERRIDDEN : DEF_JDELAY; } block_unblock_all_queues(false); + mutex_unlock(&sdebug_host_list_mutex); } return res; } @@ -6390,13 +6296,13 @@ static ssize_t lun_format_store(struct device_driver *ddp, const char *buf, struct sdebug_host_info *sdhp; struct sdebug_dev_info *dp; - spin_lock(&sdebug_host_list_lock); + mutex_lock(&sdebug_host_list_mutex); list_for_each_entry(sdhp, &sdebug_host_list, host_list) { list_for_each_entry(dp, &sdhp->dev_info_list, dev_list) { set_bit(SDEBUG_UA_LUNS_CHANGED, dp->uas_bm); } } - spin_unlock(&sdebug_host_list_lock); + mutex_unlock(&sdebug_host_list_mutex); } return count; } @@ -6426,7 +6332,7 @@ static ssize_t max_luns_store(struct device_driver *ddp, const char *buf, struct sdebug_host_info *sdhp; struct sdebug_dev_info *dp; - spin_lock(&sdebug_host_list_lock); + mutex_lock(&sdebug_host_list_mutex); list_for_each_entry(sdhp, &sdebug_host_list, host_list) { list_for_each_entry(dp, &sdhp->dev_info_list, @@ -6435,7 +6341,7 @@ static ssize_t max_luns_store(struct device_driver *ddp, const char *buf, dp->uas_bm); } } - spin_unlock(&sdebug_host_list_lock); + mutex_unlock(&sdebug_host_list_mutex); } return count; } @@ -6452,28 +6358,19 @@ static ssize_t max_queue_show(struct device_driver *ddp, char *buf) static ssize_t max_queue_store(struct device_driver *ddp, const char *buf, size_t count) { - int j, n, k, a; - struct sdebug_queue *sqp; + int n; if ((count > 0) && (1 == sscanf(buf, "%d", &n)) && (n > 0) && (n <= SDEBUG_CANQUEUE) && (sdebug_host_max_queue == 0)) { - block_unblock_all_queues(true); - k = 0; - for (j = 0, sqp = sdebug_q_arr; j < submit_queues; - ++j, ++sqp) { - a = find_last_bit(sqp->in_use_bm, SDEBUG_CANQUEUE); - if (a > k) - k = a; - } - sdebug_max_queue = n; - if (k == SDEBUG_CANQUEUE) - atomic_set(&retired_max_queue, 0); - else if (k >= n) - atomic_set(&retired_max_queue, k + 1); + mutex_lock(&sdebug_host_list_mutex); + + /* We may only change sdebug_max_queue when we have no shosts */ + if (list_empty(&sdebug_host_list)) + sdebug_max_queue = n; else - atomic_set(&retired_max_queue, 0); - block_unblock_all_queues(false); + count = -EBUSY; + mutex_unlock(&sdebug_host_list_mutex); return count; } return -EINVAL; @@ -6542,7 +6439,7 @@ static ssize_t virtual_gb_store(struct device_driver *ddp, const char *buf, struct sdebug_host_info *sdhp; struct sdebug_dev_info *dp; - spin_lock(&sdebug_host_list_lock); + mutex_lock(&sdebug_host_list_mutex); list_for_each_entry(sdhp, &sdebug_host_list, host_list) { list_for_each_entry(dp, &sdhp->dev_info_list, @@ -6551,7 +6448,7 @@ static ssize_t virtual_gb_store(struct device_driver *ddp, const char *buf, dp->uas_bm); } } - spin_unlock(&sdebug_host_list_lock); + mutex_unlock(&sdebug_host_list_mutex); } return count; } @@ -6901,7 +6798,6 @@ static int __init scsi_debug_init(void) ramdisk_lck_a[0] = &atomic_rw; ramdisk_lck_a[1] = &atomic_rw2; - atomic_set(&retired_max_queue, 0); if (sdebug_ndelay >= 1000 * 1000 * 1000) { pr_warn("ndelay must be less than 1 second, ignored\n"); @@ -6997,13 +6893,6 @@ static int __init scsi_debug_init(void) sdebug_max_queue); } - sdebug_q_arr = kcalloc(submit_queues, sizeof(struct sdebug_queue), - GFP_KERNEL); - if (sdebug_q_arr == NULL) - return -ENOMEM; - for (k = 0; k < submit_queues; ++k) - spin_lock_init(&sdebug_q_arr[k].qc_lock); - /* * check for host managed zoned block device specified with * ptype=0x14 or zbc=XXX. @@ -7012,10 +6901,8 @@ static int __init scsi_debug_init(void) sdeb_zbc_model = BLK_ZONED_HM; } else if (sdeb_zbc_model_s && *sdeb_zbc_model_s) { k = sdeb_zbc_model_str(sdeb_zbc_model_s); - if (k < 0) { - ret = k; - goto free_q_arr; - } + if (k < 0) + return k; sdeb_zbc_model = k; switch (sdeb_zbc_model) { case BLK_ZONED_NONE: @@ -7027,8 +6914,7 @@ static int __init scsi_debug_init(void) break; default: pr_err("Invalid ZBC model\n"); - ret = -EINVAL; - goto free_q_arr; + return -EINVAL; } } if (sdeb_zbc_model != BLK_ZONED_NONE) { @@ -7075,17 +6961,14 @@ static int __init scsi_debug_init(void) sdebug_unmap_granularity <= sdebug_unmap_alignment) { pr_err("ERR: unmap_granularity <= unmap_alignment\n"); - ret = -EINVAL; - goto free_q_arr; + return -EINVAL; } } xa_init_flags(per_store_ap, XA_FLAGS_ALLOC | XA_FLAGS_LOCK_IRQ); if (want_store) { idx = sdebug_add_store(); - if (idx < 0) { - ret = idx; - goto free_q_arr; - } + if (idx < 0) + return idx; } pseudo_primary = root_device_register("pseudo_0"); @@ -7108,6 +6991,12 @@ static int __init scsi_debug_init(void) hosts_to_add = sdebug_add_host; sdebug_add_host = 0; + queued_cmd_cache = KMEM_CACHE(sdebug_queued_cmd, SLAB_HWCACHE_ALIGN); + if (!queued_cmd_cache) { + ret = -ENOMEM; + goto driver_unreg; + } + for (k = 0; k < hosts_to_add; k++) { if (want_store && k == 0) { ret = sdebug_add_host_helper(idx); @@ -7130,14 +7019,14 @@ static int __init scsi_debug_init(void) return 0; +driver_unreg: + driver_unregister(&sdebug_driverfs_driver); bus_unreg: bus_unregister(&pseudo_lld_bus); dev_unreg: root_device_unregister(pseudo_primary); free_vm: sdebug_erase_store(idx, NULL); -free_q_arr: - kfree(sdebug_q_arr); return ret; } @@ -7145,17 +7034,15 @@ static void __exit scsi_debug_exit(void) { int k = sdebug_num_hosts; - stop_all_queued(); for (; k; k--) sdebug_do_remove_host(true); - free_all_queued(); + kmem_cache_destroy(queued_cmd_cache); driver_unregister(&sdebug_driverfs_driver); bus_unregister(&pseudo_lld_bus); root_device_unregister(pseudo_primary); sdebug_erase_all_stores(false); xa_destroy(per_store_ap); - kfree(sdebug_q_arr); } device_initcall(scsi_debug_init); @@ -7165,7 +7052,7 @@ static void sdebug_release_adapter(struct device *dev) { struct sdebug_host_info *sdbg_host; - sdbg_host = to_sdebug_host(dev); + sdbg_host = dev_to_sdebug_host(dev); kfree(sdbg_host); } @@ -7311,9 +7198,9 @@ static int sdebug_add_host_helper(int per_host_idx) goto clean; } - spin_lock(&sdebug_host_list_lock); + mutex_lock(&sdebug_host_list_mutex); list_add_tail(&sdbg_host->host_list, &sdebug_host_list); - spin_unlock(&sdebug_host_list_lock); + mutex_unlock(&sdebug_host_list_mutex); sdbg_host->dev.bus = &pseudo_lld_bus; sdbg_host->dev.parent = pseudo_primary; @@ -7322,9 +7209,9 @@ static int sdebug_add_host_helper(int per_host_idx) error = device_register(&sdbg_host->dev); if (error) { - spin_lock(&sdebug_host_list_lock); + mutex_lock(&sdebug_host_list_mutex); list_del(&sdbg_host->host_list); - spin_unlock(&sdebug_host_list_lock); + mutex_unlock(&sdebug_host_list_mutex); goto clean; } @@ -7364,7 +7251,7 @@ static void sdebug_do_remove_host(bool the_end) struct sdebug_host_info *sdbg_host = NULL; struct sdebug_host_info *sdbg_host2; - spin_lock(&sdebug_host_list_lock); + mutex_lock(&sdebug_host_list_mutex); if (!list_empty(&sdebug_host_list)) { sdbg_host = list_entry(sdebug_host_list.prev, struct sdebug_host_info, host_list); @@ -7389,7 +7276,7 @@ static void sdebug_do_remove_host(bool the_end) } if (sdbg_host) list_del(&sdbg_host->host_list); - spin_unlock(&sdebug_host_list_lock); + mutex_unlock(&sdebug_host_list_mutex); if (!sdbg_host) return; @@ -7400,16 +7287,13 @@ static void sdebug_do_remove_host(bool the_end) static int sdebug_change_qdepth(struct scsi_device *sdev, int qdepth) { - int num_in_q = 0; - struct sdebug_dev_info *devip; + struct sdebug_dev_info *devip = sdev->hostdata; - block_unblock_all_queues(true); - devip = (struct sdebug_dev_info *)sdev->hostdata; - if (NULL == devip) { - block_unblock_all_queues(false); + if (!devip) return -ENODEV; - } - num_in_q = atomic_read(&devip->num_in_q); + + mutex_lock(&sdebug_host_list_mutex); + block_unblock_all_queues(true); if (qdepth > SDEBUG_CANQUEUE) { qdepth = SDEBUG_CANQUEUE; @@ -7421,11 +7305,12 @@ static int sdebug_change_qdepth(struct scsi_device *sdev, int qdepth) if (qdepth != sdev->queue_depth) scsi_change_queue_depth(sdev, qdepth); - if (SDEBUG_OPT_Q_NOISE & sdebug_opts) { - sdev_printk(KERN_INFO, sdev, "%s: qdepth=%d, num_in_q=%d\n", - __func__, qdepth, num_in_q); - } block_unblock_all_queues(false); + mutex_unlock(&sdebug_host_list_mutex); + + if (SDEBUG_OPT_Q_NOISE & sdebug_opts) + sdev_printk(KERN_INFO, sdev, "%s: qdepth=%d\n", __func__, qdepth); + return sdev->queue_depth; } @@ -7515,94 +7400,82 @@ static void sdebug_map_queues(struct Scsi_Host *shost) } } -static int sdebug_blk_mq_poll(struct Scsi_Host *shost, unsigned int queue_num) +struct sdebug_blk_mq_poll_data { + unsigned int queue_num; + int *num_entries; +}; + +/* + * We don't handle aborted commands here, but it does not seem possible to have + * aborted polled commands from schedule_resp() + */ +static bool sdebug_blk_mq_poll_iter(struct request *rq, void *opaque) { - bool first; - bool retiring = false; - int num_entries = 0; - unsigned int qc_idx = 0; - unsigned long iflags; - ktime_t kt_from_boot = ktime_get_boottime(); - struct sdebug_queue *sqp; - struct sdebug_queued_cmd *sqcp; - struct scsi_cmnd *scp; - struct sdebug_dev_info *devip; + struct sdebug_blk_mq_poll_data *data = opaque; + struct scsi_cmnd *cmd = blk_mq_rq_to_pdu(rq); + struct sdebug_scsi_cmd *sdsc = scsi_cmd_priv(cmd); struct sdebug_defer *sd_dp; + u32 unique_tag = blk_mq_unique_tag(rq); + u16 hwq = blk_mq_unique_tag_to_hwq(unique_tag); + struct sdebug_queued_cmd *sqcp; + unsigned long flags; + int queue_num = data->queue_num; + ktime_t time; - sqp = sdebug_q_arr + queue_num; + /* We're only interested in one queue for this iteration */ + if (hwq != queue_num) + return true; - spin_lock_irqsave(&sqp->qc_lock, iflags); + /* Subsequent checks would fail if this failed, but check anyway */ + if (!test_bit(SCMD_STATE_INFLIGHT, &cmd->state)) + return true; - qc_idx = find_first_bit(sqp->in_use_bm, sdebug_max_queue); - if (qc_idx >= sdebug_max_queue) - goto unlock; + time = ktime_get_boottime(); - for (first = true; first || qc_idx + 1 < sdebug_max_queue; ) { - if (first) { - first = false; - if (!test_bit(qc_idx, sqp->in_use_bm)) - continue; - } else { - qc_idx = find_next_bit(sqp->in_use_bm, sdebug_max_queue, qc_idx + 1); - } - if (qc_idx >= sdebug_max_queue) - break; + spin_lock_irqsave(&sdsc->lock, flags); + sqcp = TO_QUEUED_CMD(cmd); + if (!sqcp) { + spin_unlock_irqrestore(&sdsc->lock, flags); + return true; + } - sqcp = &sqp->qc_arr[qc_idx]; - sd_dp = sqcp->sd_dp; - if (unlikely(!sd_dp)) - continue; - scp = sqcp->a_cmnd; - if (unlikely(scp == NULL)) { - pr_err("scp is NULL, queue_num=%d, qc_idx=%u from %s\n", - queue_num, qc_idx, __func__); - break; - } - if (READ_ONCE(sd_dp->defer_t) == SDEB_DEFER_POLL) { - if (kt_from_boot < sd_dp->cmpl_ts) - continue; + sd_dp = &sqcp->sd_dp; + if (READ_ONCE(sd_dp->defer_t) != SDEB_DEFER_POLL) { + spin_unlock_irqrestore(&sdsc->lock, flags); + return true; + } - } else /* ignoring non REQ_POLLED requests */ - continue; - devip = (struct sdebug_dev_info *)scp->device->hostdata; - if (likely(devip)) - atomic_dec(&devip->num_in_q); - else - pr_err("devip=NULL from %s\n", __func__); - if (unlikely(atomic_read(&retired_max_queue) > 0)) - retiring = true; - - sqcp->a_cmnd = NULL; - if (unlikely(!test_and_clear_bit(qc_idx, sqp->in_use_bm))) { - pr_err("Unexpected completion sqp %p queue_num=%d qc_idx=%u from %s\n", - sqp, queue_num, qc_idx, __func__); - break; - } - if (unlikely(retiring)) { /* user has reduced max_queue */ - int k, retval; + if (time < sd_dp->cmpl_ts) { + spin_unlock_irqrestore(&sdsc->lock, flags); + return true; + } - retval = atomic_read(&retired_max_queue); - if (qc_idx >= retval) { - pr_err("index %d too large\n", retval); - break; - } - k = find_last_bit(sqp->in_use_bm, retval); - if ((k < sdebug_max_queue) || (k == retval)) - atomic_set(&retired_max_queue, 0); - else - atomic_set(&retired_max_queue, k + 1); - } - WRITE_ONCE(sd_dp->defer_t, SDEB_DEFER_NONE); - spin_unlock_irqrestore(&sqp->qc_lock, iflags); - scsi_done(scp); /* callback to mid level */ - num_entries++; - spin_lock_irqsave(&sqp->qc_lock, iflags); - if (find_first_bit(sqp->in_use_bm, sdebug_max_queue) >= sdebug_max_queue) - break; + ASSIGN_QUEUED_CMD(cmd, NULL); + spin_unlock_irqrestore(&sdsc->lock, flags); + + if (sdebug_statistics) { + atomic_inc(&sdebug_completions); + if (raw_smp_processor_id() != sd_dp->issuing_cpu) + atomic_inc(&sdebug_miss_cpus); } -unlock: - spin_unlock_irqrestore(&sqp->qc_lock, iflags); + sdebug_free_queued_cmd(sqcp); + + scsi_done(cmd); /* callback to mid level */ + (*data->num_entries)++; + return true; +} + +static int sdebug_blk_mq_poll(struct Scsi_Host *shost, unsigned int queue_num) +{ + int num_entries = 0; + struct sdebug_blk_mq_poll_data data = { + .queue_num = queue_num, + .num_entries = &num_entries, + }; + + blk_mq_tagset_busy_iter(&shost->tag_set, sdebug_blk_mq_poll_iter, + &data); if (num_entries > 0) atomic_add(num_entries, &sdeb_mq_poll_count); @@ -7776,6 +7649,16 @@ err_out: return schedule_resp(scp, NULL, DID_NO_CONNECT << 16, NULL, 0, 0); } +static int sdebug_init_cmd_priv(struct Scsi_Host *shost, struct scsi_cmnd *cmd) +{ + struct sdebug_scsi_cmd *sdsc = scsi_cmd_priv(cmd); + + spin_lock_init(&sdsc->lock); + + return 0; +} + + static struct scsi_host_template sdebug_driver_template = { .show_info = scsi_debug_show_info, .write_info = scsi_debug_write_info, @@ -7803,6 +7686,8 @@ static struct scsi_host_template sdebug_driver_template = { .max_segment_size = -1U, .module = THIS_MODULE, .track_queue_depth = 1, + .cmd_size = sizeof(struct sdebug_scsi_cmd), + .init_cmd_priv = sdebug_init_cmd_priv, }; static int sdebug_driver_probe(struct device *dev) @@ -7812,14 +7697,14 @@ static int sdebug_driver_probe(struct device *dev) struct Scsi_Host *hpnt; int hprot; - sdbg_host = to_sdebug_host(dev); + sdbg_host = dev_to_sdebug_host(dev); sdebug_driver_template.can_queue = sdebug_max_queue; sdebug_driver_template.cmd_per_lun = sdebug_max_queue; if (!sdebug_clustering) sdebug_driver_template.dma_boundary = PAGE_SIZE - 1; - hpnt = scsi_host_alloc(&sdebug_driver_template, sizeof(sdbg_host)); + hpnt = scsi_host_alloc(&sdebug_driver_template, 0); if (NULL == hpnt) { pr_err("scsi_host_alloc failed\n"); error = -ENODEV; @@ -7862,7 +7747,6 @@ static int sdebug_driver_probe(struct device *dev) hpnt->nr_maps = 3; sdbg_host->shost = hpnt; - *((struct sdebug_host_info **)hpnt->hostdata) = sdbg_host; if ((hpnt->this_id >= 0) && (sdebug_num_tgts > hpnt->this_id)) hpnt->max_id = sdebug_num_tgts + 1; else @@ -7936,7 +7820,7 @@ static void sdebug_driver_remove(struct device *dev) struct sdebug_host_info *sdbg_host; struct sdebug_dev_info *sdbg_devinfo, *tmp; - sdbg_host = to_sdebug_host(dev); + sdbg_host = dev_to_sdebug_host(dev); scsi_remove_host(sdbg_host->shost); @@ -7950,15 +7834,8 @@ static void sdebug_driver_remove(struct device *dev) scsi_host_put(sdbg_host->shost); } -static int pseudo_lld_bus_match(struct device *dev, - struct device_driver *dev_driver) -{ - return 1; -} - static struct bus_type pseudo_lld_bus = { .name = "pseudo", - .match = pseudo_lld_bus_match, .probe = sdebug_driver_probe, .remove = sdebug_driver_remove, .drv_groups = sdebug_drv_groups, diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c index 2aa2c2aee6e7..3ec8bfd4090f 100644 --- a/drivers/scsi/scsi_error.c +++ b/drivers/scsi/scsi_error.c @@ -58,7 +58,7 @@ #define HOST_RESET_SETTLE_TIME (10) static int scsi_eh_try_stu(struct scsi_cmnd *scmd); -static enum scsi_disposition scsi_try_to_abort_cmd(struct scsi_host_template *, +static enum scsi_disposition scsi_try_to_abort_cmd(const struct scsi_host_template *, struct scsi_cmnd *); void scsi_eh_wakeup(struct Scsi_Host *shost) @@ -699,7 +699,7 @@ EXPORT_SYMBOL_GPL(scsi_check_sense); static void scsi_handle_queue_ramp_up(struct scsi_device *sdev) { - struct scsi_host_template *sht = sdev->host->hostt; + const struct scsi_host_template *sht = sdev->host->hostt; struct scsi_device *tmp_sdev; if (!sht->track_queue_depth || @@ -731,7 +731,7 @@ static void scsi_handle_queue_ramp_up(struct scsi_device *sdev) static void scsi_handle_queue_full(struct scsi_device *sdev) { - struct scsi_host_template *sht = sdev->host->hostt; + const struct scsi_host_template *sht = sdev->host->hostt; struct scsi_device *tmp_sdev; if (!sht->track_queue_depth) @@ -840,7 +840,7 @@ static enum scsi_disposition scsi_try_host_reset(struct scsi_cmnd *scmd) unsigned long flags; enum scsi_disposition rtn; struct Scsi_Host *host = scmd->device->host; - struct scsi_host_template *hostt = host->hostt; + const struct scsi_host_template *hostt = host->hostt; SCSI_LOG_ERROR_RECOVERY(3, shost_printk(KERN_INFO, host, "Snd Host RST\n")); @@ -870,7 +870,7 @@ static enum scsi_disposition scsi_try_bus_reset(struct scsi_cmnd *scmd) unsigned long flags; enum scsi_disposition rtn; struct Scsi_Host *host = scmd->device->host; - struct scsi_host_template *hostt = host->hostt; + const struct scsi_host_template *hostt = host->hostt; SCSI_LOG_ERROR_RECOVERY(3, scmd_printk(KERN_INFO, scmd, "%s: Snd Bus RST\n", __func__)); @@ -912,7 +912,7 @@ static enum scsi_disposition scsi_try_target_reset(struct scsi_cmnd *scmd) unsigned long flags; enum scsi_disposition rtn; struct Scsi_Host *host = scmd->device->host; - struct scsi_host_template *hostt = host->hostt; + const struct scsi_host_template *hostt = host->hostt; if (!hostt->eh_target_reset_handler) return FAILED; @@ -941,7 +941,7 @@ static enum scsi_disposition scsi_try_target_reset(struct scsi_cmnd *scmd) static enum scsi_disposition scsi_try_bus_device_reset(struct scsi_cmnd *scmd) { enum scsi_disposition rtn; - struct scsi_host_template *hostt = scmd->device->host->hostt; + const struct scsi_host_template *hostt = scmd->device->host->hostt; if (!hostt->eh_device_reset_handler) return FAILED; @@ -970,7 +970,7 @@ static enum scsi_disposition scsi_try_bus_device_reset(struct scsi_cmnd *scmd) * link down on FibreChannel) */ static enum scsi_disposition -scsi_try_to_abort_cmd(struct scsi_host_template *hostt, struct scsi_cmnd *scmd) +scsi_try_to_abort_cmd(const struct scsi_host_template *hostt, struct scsi_cmnd *scmd) { if (!hostt->eh_abort_handler) return FAILED; diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c index ee28f73af4d4..603e8fcfcb8a 100644 --- a/drivers/scsi/scsi_sysfs.c +++ b/drivers/scsi/scsi_sysfs.c @@ -296,7 +296,7 @@ store_host_reset(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct Scsi_Host *shost = class_to_shost(dev); - struct scsi_host_template *sht = shost->hostt; + const struct scsi_host_template *sht = shost->hostt; int ret = -EINVAL; int type; @@ -1025,7 +1025,7 @@ sdev_store_queue_depth(struct device *dev, struct device_attribute *attr, { int depth, retval; struct scsi_device *sdev = to_scsi_device(dev); - struct scsi_host_template *sht = sdev->host->hostt; + const struct scsi_host_template *sht = sdev->host->hostt; if (!sht->change_queue_depth) return -EINVAL; @@ -1606,7 +1606,7 @@ void scsi_sysfs_device_initialize(struct scsi_device *sdev) { unsigned long flags; struct Scsi_Host *shost = sdev->host; - struct scsi_host_template *hostt = shost->hostt; + const struct scsi_host_template *hostt = shost->hostt; struct scsi_target *starget = sdev->sdev_target; device_initialize(&sdev->sdev_gendev); diff --git a/drivers/scsi/scsi_transport_fc.c b/drivers/scsi/scsi_transport_fc.c index f12e9467ebb4..64ff2629eaf9 100644 --- a/drivers/scsi/scsi_transport_fc.c +++ b/drivers/scsi/scsi_transport_fc.c @@ -905,7 +905,7 @@ fc_host_fpin_rcv(struct Scsi_Host *shost, u32 fpin_len, char *fpin_buf, { struct fc_els_fpin *fpin = (struct fc_els_fpin *)fpin_buf; struct fc_tlv_desc *tlv; - u32 desc_cnt = 0, bytes_remain; + u32 bytes_remain; u32 dtag; enum fc_host_event_code event_code = event_acknowledge ? FCH_EVT_LINK_FPIN_ACK : FCH_EVT_LINK_FPIN; @@ -932,7 +932,6 @@ fc_host_fpin_rcv(struct Scsi_Host *shost, u32 fpin_len, char *fpin_buf, fc_fpin_congn_stats_update(shost, tlv); } - desc_cnt++; bytes_remain -= FC_TLV_DESC_SZ_FROM_LENGTH(tlv); tlv = fc_tlv_next_desc(tlv); } diff --git a/drivers/scsi/sgiwd93.c b/drivers/scsi/sgiwd93.c index 57d5dff62f63..88e2b5eb9caa 100644 --- a/drivers/scsi/sgiwd93.c +++ b/drivers/scsi/sgiwd93.c @@ -204,7 +204,7 @@ static inline void init_hpc_chain(struct ip22_hostdata *hdata) * arguments not with pointers. So this is going to blow up beautyfully * on 64-bit systems with memory outside the compat address spaces. */ -static struct scsi_host_template sgiwd93_template = { +static const struct scsi_host_template sgiwd93_template = { .module = THIS_MODULE, .proc_name = "SGIWD93", .name = "SGI WD93", diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c index 49a8f91810b6..03de97cd72c2 100644 --- a/drivers/scsi/smartpqi/smartpqi_init.c +++ b/drivers/scsi/smartpqi/smartpqi_init.c @@ -7403,7 +7403,7 @@ static struct attribute *pqi_sdev_attrs[] = { ATTRIBUTE_GROUPS(pqi_sdev); -static struct scsi_host_template pqi_driver_template = { +static const struct scsi_host_template pqi_driver_template = { .module = THIS_MODULE, .name = DRIVER_NAME_SHORT, .proc_name = DRIVER_NAME_SHORT, diff --git a/drivers/scsi/snic/snic_main.c b/drivers/scsi/snic/snic_main.c index 174f7811fe50..cc824dcfe7da 100644 --- a/drivers/scsi/snic/snic_main.c +++ b/drivers/scsi/snic/snic_main.c @@ -100,7 +100,7 @@ snic_change_queue_depth(struct scsi_device *sdev, int qdepth) return sdev->queue_depth; } -static struct scsi_host_template snic_host_template = { +static const struct scsi_host_template snic_host_template = { .module = THIS_MODULE, .name = SNIC_DRV_NAME, .queuecommand = snic_queuecommand, diff --git a/drivers/scsi/snic/snic_scsi.c b/drivers/scsi/snic/snic_scsi.c index 961af6fc21bc..c50ede326cc4 100644 --- a/drivers/scsi/snic/snic_scsi.c +++ b/drivers/scsi/snic/snic_scsi.c @@ -487,7 +487,6 @@ snic_process_icmnd_cmpl_status(struct snic *snic, struct scsi_cmnd *sc) { u8 scsi_stat = icmnd_cmpl->scsi_status; - u64 xfer_len = 0; int ret = 0; /* Mark the IO as complete */ @@ -496,15 +495,11 @@ snic_process_icmnd_cmpl_status(struct snic *snic, if (likely(cmpl_stat == SNIC_STAT_IO_SUCCESS)) { sc->result = (DID_OK << 16) | scsi_stat; - xfer_len = scsi_bufflen(sc); - /* Update SCSI Cmd with resid value */ scsi_set_resid(sc, le32_to_cpu(icmnd_cmpl->resid)); - if (icmnd_cmpl->flags & SNIC_ICMND_CMPL_UNDR_RUN) { - xfer_len -= le32_to_cpu(icmnd_cmpl->resid); + if (icmnd_cmpl->flags & SNIC_ICMND_CMPL_UNDR_RUN) atomic64_inc(&snic->s_stats.misc.io_under_run); - } if (icmnd_cmpl->scsi_status == SAM_STAT_TASK_SET_FULL) atomic64_inc(&snic->s_stats.misc.qfull); diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c index 9e51dcd30bfd..12869e6d4ebd 100644 --- a/drivers/scsi/sr.c +++ b/drivers/scsi/sr.c @@ -590,20 +590,15 @@ static int sr_open(struct cdrom_device_info *cdi, int purpose) { struct scsi_cd *cd = cdi->handle; struct scsi_device *sdev = cd->device; - int retval; /* * If the device is in error recovery, wait until it is done. * If the device is offline, then disallow any access to it. */ - retval = -ENXIO; if (!scsi_block_when_processing_errors(sdev)) - goto error_out; + return -ENXIO; return 0; - -error_out: - return retval; } static void sr_release(struct cdrom_device_info *cdi) diff --git a/drivers/scsi/stex.c b/drivers/scsi/stex.c index 8def242675ef..5b230e149c3d 100644 --- a/drivers/scsi/stex.c +++ b/drivers/scsi/stex.c @@ -1472,7 +1472,7 @@ static int stex_biosparam(struct scsi_device *sdev, return 0; } -static struct scsi_host_template driver_template = { +static const struct scsi_host_template driver_template = { .module = THIS_MODULE, .name = DRV_NAME, .proc_name = DRV_NAME, diff --git a/drivers/scsi/sun3x_esp.c b/drivers/scsi/sun3x_esp.c index d3489ac7ab28..30f67cbf4a7a 100644 --- a/drivers/scsi/sun3x_esp.c +++ b/drivers/scsi/sun3x_esp.c @@ -169,7 +169,7 @@ static const struct esp_driver_ops sun3x_esp_ops = { static int esp_sun3x_probe(struct platform_device *dev) { - struct scsi_host_template *tpnt = &scsi_esp_template; + const struct scsi_host_template *tpnt = &scsi_esp_template; struct Scsi_Host *host; struct esp *esp; struct resource *res; diff --git a/drivers/scsi/sun_esp.c b/drivers/scsi/sun_esp.c index 5dc38d35745b..d06e933191a2 100644 --- a/drivers/scsi/sun_esp.c +++ b/drivers/scsi/sun_esp.c @@ -146,7 +146,7 @@ static void esp_get_differential(struct esp *esp) struct device_node *dp; dp = op->dev.of_node; - if (of_find_property(dp, "differential", NULL)) + if (of_property_read_bool(dp, "differential")) esp->flags |= ESP_FLAG_DIFFERENTIAL; else esp->flags &= ~ESP_FLAG_DIFFERENTIAL; @@ -451,7 +451,7 @@ static const struct esp_driver_ops sbus_esp_ops = { static int esp_sbus_probe_one(struct platform_device *op, struct platform_device *espdma, int hme) { - struct scsi_host_template *tpnt = &scsi_esp_template; + const struct scsi_host_template *tpnt = &scsi_esp_template; struct Scsi_Host *host; struct esp *esp; int err; diff --git a/drivers/scsi/sym53c8xx_2/sym_glue.c b/drivers/scsi/sym53c8xx_2/sym_glue.c index 2e2852bd5860..ee36a9c15d9c 100644 --- a/drivers/scsi/sym53c8xx_2/sym_glue.c +++ b/drivers/scsi/sym53c8xx_2/sym_glue.c @@ -1224,7 +1224,7 @@ static void sym_free_resources(struct sym_hcb *np, struct pci_dev *pdev, * If all is OK, install interrupt handling and * start the timer daemon. */ -static struct Scsi_Host *sym_attach(struct scsi_host_template *tpnt, int unit, +static struct Scsi_Host *sym_attach(const struct scsi_host_template *tpnt, int unit, struct sym_device *dev) { struct sym_data *sym_data; @@ -1625,7 +1625,7 @@ static int sym_detach(struct Scsi_Host *shost, struct pci_dev *pdev) /* * Driver host template. */ -static struct scsi_host_template sym2_template = { +static const struct scsi_host_template sym2_template = { .module = THIS_MODULE, .name = "sym53c8xx", .info = sym53c8xx_info, diff --git a/drivers/scsi/virtio_scsi.c b/drivers/scsi/virtio_scsi.c index c5558c45ab3a..58498da9869a 100644 --- a/drivers/scsi/virtio_scsi.c +++ b/drivers/scsi/virtio_scsi.c @@ -746,7 +746,7 @@ static enum scsi_timeout_action virtscsi_eh_timed_out(struct scsi_cmnd *scmnd) return SCSI_EH_RESET_TIMER; } -static struct scsi_host_template virtscsi_host_template = { +static const struct scsi_host_template virtscsi_host_template = { .module = THIS_MODULE, .name = "Virtio SCSI HBA", .proc_name = "virtio_scsi", diff --git a/drivers/scsi/wd719x.c b/drivers/scsi/wd719x.c index ff1b22077251..5a380eecfc75 100644 --- a/drivers/scsi/wd719x.c +++ b/drivers/scsi/wd719x.c @@ -878,7 +878,7 @@ fail_free_params: return ret; } -static struct scsi_host_template wd719x_template = { +static const struct scsi_host_template wd719x_template = { .module = THIS_MODULE, .name = "Western Digital 719x", .cmd_size = sizeof(struct wd719x_scb), diff --git a/drivers/scsi/xen-scsifront.c b/drivers/scsi/xen-scsifront.c index 71a3bb83984c..caae61aa2afe 100644 --- a/drivers/scsi/xen-scsifront.c +++ b/drivers/scsi/xen-scsifront.c @@ -770,7 +770,7 @@ static void scsifront_sdev_destroy(struct scsi_device *sdev) } } -static struct scsi_host_template scsifront_sht = { +static const struct scsi_host_template scsifront_sht = { .module = THIS_MODULE, .name = "Xen SCSI frontend driver", .queuecommand = scsifront_queuecommand, diff --git a/drivers/scsi/zorro_esp.c b/drivers/scsi/zorro_esp.c index 928c8adf5cb3..56cae22a4242 100644 --- a/drivers/scsi/zorro_esp.c +++ b/drivers/scsi/zorro_esp.c @@ -713,7 +713,7 @@ MODULE_DEVICE_TABLE(zorro, zorro_esp_zorro_tbl); static int zorro_esp_probe(struct zorro_dev *z, const struct zorro_device_id *ent) { - struct scsi_host_template *tpnt = &scsi_esp_template; + const struct scsi_host_template *tpnt = &scsi_esp_template; struct Scsi_Host *host; struct esp *esp; const struct zorro_driver_data *zdd; diff --git a/drivers/staging/rts5208/rtsx.c b/drivers/staging/rts5208/rtsx.c index 2284a96abcff..db2dd0baa8be 100644 --- a/drivers/staging/rts5208/rtsx.c +++ b/drivers/staging/rts5208/rtsx.c @@ -191,7 +191,7 @@ static int device_reset(struct scsi_cmnd *srb) * this defines our host template, with which we'll allocate hosts */ -static struct scsi_host_template rtsx_host_template = { +static const struct scsi_host_template rtsx_host_template = { /* basic userland interface stuff */ .name = CR_DRIVER_NAME, .proc_name = CR_DRIVER_NAME, diff --git a/drivers/target/Kconfig b/drivers/target/Kconfig index 72171ea3dd53..92641d39126a 100644 --- a/drivers/target/Kconfig +++ b/drivers/target/Kconfig @@ -47,5 +47,6 @@ source "drivers/target/loopback/Kconfig" source "drivers/target/tcm_fc/Kconfig" source "drivers/target/iscsi/Kconfig" source "drivers/target/sbp/Kconfig" +source "drivers/target/tcm_remote/Kconfig" endif diff --git a/drivers/target/Makefile b/drivers/target/Makefile index 45634747377e..431b84abfb94 100644 --- a/drivers/target/Makefile +++ b/drivers/target/Makefile @@ -30,3 +30,4 @@ obj-$(CONFIG_LOOPBACK_TARGET) += loopback/ obj-$(CONFIG_TCM_FC) += tcm_fc/ obj-$(CONFIG_ISCSI_TARGET) += iscsi/ obj-$(CONFIG_SBP_TARGET) += sbp/ +obj-$(CONFIG_REMOTE_TARGET) += tcm_remote/ diff --git a/drivers/target/iscsi/iscsi_target.c b/drivers/target/iscsi/iscsi_target.c index baf4da7bb3b4..834cce50f9b0 100644 --- a/drivers/target/iscsi/iscsi_target.c +++ b/drivers/target/iscsi/iscsi_target.c @@ -26,6 +26,7 @@ #include <target/target_core_base.h> #include <target/target_core_fabric.h> +#include <target/target_core_backend.h> #include <target/iscsi/iscsi_target_core.h> #include "iscsi_target_parameters.h" #include "iscsi_target_seq_pdu_list.h" @@ -1190,9 +1191,10 @@ int iscsit_setup_scsi_cmd(struct iscsit_conn *conn, struct iscsit_cmd *cmd, * Initialize struct se_cmd descriptor from target_core_mod infrastructure */ __target_init_cmd(&cmd->se_cmd, &iscsi_ops, - conn->sess->se_sess, be32_to_cpu(hdr->data_length), - cmd->data_direction, sam_task_attr, - cmd->sense_buffer + 2, scsilun_to_int(&hdr->lun)); + conn->sess->se_sess, be32_to_cpu(hdr->data_length), + cmd->data_direction, sam_task_attr, + cmd->sense_buffer + 2, scsilun_to_int(&hdr->lun), + conn->cmd_cnt); pr_debug("Got SCSI Command, ITT: 0x%08x, CmdSN: 0x%08x," " ExpXferLen: %u, Length: %u, CID: %hu\n", hdr->itt, @@ -2055,7 +2057,8 @@ iscsit_handle_task_mgt_cmd(struct iscsit_conn *conn, struct iscsit_cmd *cmd, __target_init_cmd(&cmd->se_cmd, &iscsi_ops, conn->sess->se_sess, 0, DMA_NONE, TCM_SIMPLE_TAG, cmd->sense_buffer + 2, - scsilun_to_int(&hdr->lun)); + scsilun_to_int(&hdr->lun), + conn->cmd_cnt); target_get_sess_cmd(&cmd->se_cmd, true); @@ -4218,9 +4221,12 @@ static void iscsit_release_commands_from_conn(struct iscsit_conn *conn) list_for_each_entry_safe(cmd, cmd_tmp, &tmp_list, i_conn_node) { struct se_cmd *se_cmd = &cmd->se_cmd; - if (se_cmd->se_tfo != NULL) { - spin_lock_irq(&se_cmd->t_state_lock); - if (se_cmd->transport_state & CMD_T_ABORTED) { + if (!se_cmd->se_tfo) + continue; + + spin_lock_irq(&se_cmd->t_state_lock); + if (se_cmd->transport_state & CMD_T_ABORTED) { + if (!(se_cmd->transport_state & CMD_T_TAS)) /* * LIO's abort path owns the cleanup for this, * so put it back on the list and let @@ -4228,11 +4234,20 @@ static void iscsit_release_commands_from_conn(struct iscsit_conn *conn) */ list_move_tail(&cmd->i_conn_node, &conn->conn_cmd_list); - } else { - se_cmd->transport_state |= CMD_T_FABRIC_STOP; - } + } else { + se_cmd->transport_state |= CMD_T_FABRIC_STOP; + } + + if (cmd->se_cmd.t_state == TRANSPORT_WRITE_PENDING) { + /* + * We never submitted the cmd to LIO core, so we have + * to tell LIO to perform the completion process. + */ spin_unlock_irq(&se_cmd->t_state_lock); + target_complete_cmd(&cmd->se_cmd, SAM_STAT_TASK_ABORTED); + continue; } + spin_unlock_irq(&se_cmd->t_state_lock); } spin_unlock_bh(&conn->cmd_lock); @@ -4243,6 +4258,16 @@ static void iscsit_release_commands_from_conn(struct iscsit_conn *conn) iscsit_free_cmd(cmd, true); } + + /* + * Wait on commands that were cleaned up via the aborted_task path. + * LLDs that implement iscsit_wait_conn will already have waited for + * commands. + */ + if (!conn->conn_transport->iscsit_wait_conn) { + target_stop_cmd_counter(conn->cmd_cnt); + target_wait_for_cmds(conn->cmd_cnt); + } } static void iscsit_stop_timers_for_cmds( @@ -4517,6 +4542,9 @@ int iscsit_close_session(struct iscsit_session *sess, bool can_sleep) iscsit_stop_time2retain_timer(sess); spin_unlock_bh(&se_tpg->session_lock); + if (sess->sess_ops->ErrorRecoveryLevel == 2) + iscsit_free_connection_recovery_entries(sess); + /* * transport_deregister_session_configfs() will clear the * struct se_node_acl->nacl_sess pointer now as a iscsi_np process context @@ -4540,9 +4568,6 @@ int iscsit_close_session(struct iscsit_session *sess, bool can_sleep) transport_deregister_session(sess->se_sess); - if (sess->sess_ops->ErrorRecoveryLevel == 2) - iscsit_free_connection_recovery_entries(sess); - iscsit_free_all_ooo_cmdsns(sess); spin_lock_bh(&se_tpg->session_lock); diff --git a/drivers/target/iscsi/iscsi_target_login.c b/drivers/target/iscsi/iscsi_target_login.c index 27e448c2d066..274bdd7845ca 100644 --- a/drivers/target/iscsi/iscsi_target_login.c +++ b/drivers/target/iscsi/iscsi_target_login.c @@ -1147,8 +1147,14 @@ static struct iscsit_conn *iscsit_alloc_conn(struct iscsi_np *np) goto free_conn_cpumask; } + conn->cmd_cnt = target_alloc_cmd_counter(); + if (!conn->cmd_cnt) + goto free_conn_allowed_cpumask; + return conn; +free_conn_allowed_cpumask: + free_cpumask_var(conn->allowed_cpumask); free_conn_cpumask: free_cpumask_var(conn->conn_cpumask); free_conn_ops: @@ -1162,6 +1168,7 @@ free_conn: void iscsit_free_conn(struct iscsit_conn *conn) { + target_free_cmd_counter(conn->cmd_cnt); free_cpumask_var(conn->allowed_cpumask); free_cpumask_var(conn->conn_cpumask); kfree(conn->conn_ops); diff --git a/drivers/target/loopback/tcm_loop.c b/drivers/target/loopback/tcm_loop.c index 139031ccb700..4ec99a55ac30 100644 --- a/drivers/target/loopback/tcm_loop.c +++ b/drivers/target/loopback/tcm_loop.c @@ -83,15 +83,8 @@ static int tcm_loop_show_info(struct seq_file *m, struct Scsi_Host *host) static int tcm_loop_driver_probe(struct device *); static void tcm_loop_driver_remove(struct device *); -static int pseudo_lld_bus_match(struct device *dev, - struct device_driver *dev_driver) -{ - return 1; -} - static struct bus_type tcm_loop_lld_bus = { .name = "tcm_loop_bus", - .match = pseudo_lld_bus_match, .probe = tcm_loop_driver_probe, .remove = tcm_loop_driver_remove, }; @@ -298,7 +291,7 @@ static int tcm_loop_target_reset(struct scsi_cmnd *sc) return FAILED; } -static struct scsi_host_template tcm_loop_driver_template = { +static const struct scsi_host_template tcm_loop_driver_template = { .show_info = tcm_loop_show_info, .proc_name = "tcm_loopback", .name = "TCM_Loopback", @@ -480,30 +473,6 @@ static int tcm_loop_check_demo_mode(struct se_portal_group *se_tpg) return 1; } -static int tcm_loop_check_demo_mode_cache(struct se_portal_group *se_tpg) -{ - return 0; -} - -/* - * Allow I_T Nexus full READ-WRITE access without explict Initiator Node ACLs for - * local virtual Linux/SCSI LLD passthrough into VM hypervisor guest - */ -static int tcm_loop_check_demo_mode_write_protect(struct se_portal_group *se_tpg) -{ - return 0; -} - -/* - * Because TCM_Loop does not use explict ACLs and MappedLUNs, this will - * never be called for TCM_Loop by target_core_fabric_configfs.c code. - * It has been added here as a nop for target_fabric_tf_ops_check() - */ -static int tcm_loop_check_prod_mode_write_protect(struct se_portal_group *se_tpg) -{ - return 0; -} - static int tcm_loop_check_prot_fabric_only(struct se_portal_group *se_tpg) { struct tcm_loop_tpg *tl_tpg = container_of(se_tpg, struct tcm_loop_tpg, @@ -511,21 +480,11 @@ static int tcm_loop_check_prot_fabric_only(struct se_portal_group *se_tpg) return tl_tpg->tl_fabric_prot_type; } -static u32 tcm_loop_get_inst_index(struct se_portal_group *se_tpg) -{ - return 1; -} - static u32 tcm_loop_sess_get_index(struct se_session *se_sess) { return 1; } -static void tcm_loop_set_default_node_attributes(struct se_node_acl *se_acl) -{ - return; -} - static int tcm_loop_get_cmd_state(struct se_cmd *se_cmd) { struct tcm_loop_cmd *tl_cmd = container_of(se_cmd, @@ -1124,18 +1083,11 @@ static const struct target_core_fabric_ops loop_ops = { .tpg_get_wwn = tcm_loop_get_endpoint_wwn, .tpg_get_tag = tcm_loop_get_tag, .tpg_check_demo_mode = tcm_loop_check_demo_mode, - .tpg_check_demo_mode_cache = tcm_loop_check_demo_mode_cache, - .tpg_check_demo_mode_write_protect = - tcm_loop_check_demo_mode_write_protect, - .tpg_check_prod_mode_write_protect = - tcm_loop_check_prod_mode_write_protect, .tpg_check_prot_fabric_only = tcm_loop_check_prot_fabric_only, - .tpg_get_inst_index = tcm_loop_get_inst_index, .check_stop_free = tcm_loop_check_stop_free, .release_cmd = tcm_loop_release_cmd, .sess_get_index = tcm_loop_sess_get_index, .write_pending = tcm_loop_write_pending, - .set_default_node_attributes = tcm_loop_set_default_node_attributes, .get_cmd_state = tcm_loop_get_cmd_state, .queue_data_in = tcm_loop_queue_data_in, .queue_status = tcm_loop_queue_status, diff --git a/drivers/target/sbp/sbp_target.c b/drivers/target/sbp/sbp_target.c index 504670994fb4..2a761bc09193 100644 --- a/drivers/target/sbp/sbp_target.c +++ b/drivers/target/sbp/sbp_target.c @@ -1673,11 +1673,6 @@ static int sbp_check_true(struct se_portal_group *se_tpg) return 1; } -static int sbp_check_false(struct se_portal_group *se_tpg) -{ - return 0; -} - static char *sbp_get_fabric_wwn(struct se_portal_group *se_tpg) { struct sbp_tpg *tpg = container_of(se_tpg, struct sbp_tpg, se_tpg); @@ -1692,11 +1687,6 @@ static u16 sbp_get_tag(struct se_portal_group *se_tpg) return tpg->tport_tpgt; } -static u32 sbp_tpg_get_inst_index(struct se_portal_group *se_tpg) -{ - return 1; -} - static void sbp_release_cmd(struct se_cmd *se_cmd) { struct sbp_target_request *req = container_of(se_cmd, @@ -1705,11 +1695,6 @@ static void sbp_release_cmd(struct se_cmd *se_cmd) sbp_free_request(req); } -static u32 sbp_sess_get_index(struct se_session *se_sess) -{ - return 0; -} - static int sbp_write_pending(struct se_cmd *se_cmd) { struct sbp_target_request *req = container_of(se_cmd, @@ -1733,16 +1718,6 @@ static int sbp_write_pending(struct se_cmd *se_cmd) return 0; } -static void sbp_set_default_node_attrs(struct se_node_acl *nacl) -{ - return; -} - -static int sbp_get_cmd_state(struct se_cmd *se_cmd) -{ - return 0; -} - static int sbp_queue_data_in(struct se_cmd *se_cmd) { struct sbp_target_request *req = container_of(se_cmd, @@ -2281,14 +2256,8 @@ static const struct target_core_fabric_ops sbp_ops = { .tpg_get_tag = sbp_get_tag, .tpg_check_demo_mode = sbp_check_true, .tpg_check_demo_mode_cache = sbp_check_true, - .tpg_check_demo_mode_write_protect = sbp_check_false, - .tpg_check_prod_mode_write_protect = sbp_check_false, - .tpg_get_inst_index = sbp_tpg_get_inst_index, .release_cmd = sbp_release_cmd, - .sess_get_index = sbp_sess_get_index, .write_pending = sbp_write_pending, - .set_default_node_attributes = sbp_set_default_node_attrs, - .get_cmd_state = sbp_get_cmd_state, .queue_data_in = sbp_queue_data_in, .queue_status = sbp_queue_status, .queue_tm_rsp = sbp_queue_tm_rsp, diff --git a/drivers/target/target_core_alua.c b/drivers/target/target_core_alua.c index c8470e7c0e10..3372856319f7 100644 --- a/drivers/target/target_core_alua.c +++ b/drivers/target/target_core_alua.c @@ -225,7 +225,7 @@ target_emulate_report_target_port_groups(struct se_cmd *cmd) /* * Set RELATIVE TARGET PORT IDENTIFIER */ - put_unaligned_be16(lun->lun_rtpi, &buf[off]); + put_unaligned_be16(lun->lun_tpg->tpg_rtpi, &buf[off]); off += 2; rd_len += 4; } @@ -399,7 +399,7 @@ target_emulate_set_target_port_groups(struct se_cmd *cmd) spin_lock(&dev->se_port_lock); list_for_each_entry(lun, &dev->dev_sep_list, lun_dev_link) { - if (lun->lun_rtpi != rtpi) + if (lun->lun_tpg->tpg_rtpi != rtpi) continue; // XXX: racy unlock diff --git a/drivers/target/target_core_configfs.c b/drivers/target/target_core_configfs.c index 611b0424e305..74b67c346dfe 100644 --- a/drivers/target/target_core_configfs.c +++ b/drivers/target/target_core_configfs.c @@ -335,6 +335,29 @@ EXPORT_SYMBOL(target_undepend_item); /*############################################################################## // Start functions called by external Target Fabrics Modules //############################################################################*/ +static int target_disable_feature(struct se_portal_group *se_tpg) +{ + return 0; +} + +static u32 target_default_get_inst_index(struct se_portal_group *se_tpg) +{ + return 1; +} + +static u32 target_default_sess_get_index(struct se_session *se_sess) +{ + return 0; +} + +static void target_set_default_node_attributes(struct se_node_acl *se_acl) +{ +} + +static int target_default_get_cmd_state(struct se_cmd *se_cmd) +{ + return 0; +} static int target_fabric_tf_ops_check(const struct target_core_fabric_ops *tfo) { @@ -362,46 +385,14 @@ static int target_fabric_tf_ops_check(const struct target_core_fabric_ops *tfo) pr_err("Missing tfo->tpg_get_tag()\n"); return -EINVAL; } - if (!tfo->tpg_check_demo_mode) { - pr_err("Missing tfo->tpg_check_demo_mode()\n"); - return -EINVAL; - } - if (!tfo->tpg_check_demo_mode_cache) { - pr_err("Missing tfo->tpg_check_demo_mode_cache()\n"); - return -EINVAL; - } - if (!tfo->tpg_check_demo_mode_write_protect) { - pr_err("Missing tfo->tpg_check_demo_mode_write_protect()\n"); - return -EINVAL; - } - if (!tfo->tpg_check_prod_mode_write_protect) { - pr_err("Missing tfo->tpg_check_prod_mode_write_protect()\n"); - return -EINVAL; - } - if (!tfo->tpg_get_inst_index) { - pr_err("Missing tfo->tpg_get_inst_index()\n"); - return -EINVAL; - } if (!tfo->release_cmd) { pr_err("Missing tfo->release_cmd()\n"); return -EINVAL; } - if (!tfo->sess_get_index) { - pr_err("Missing tfo->sess_get_index()\n"); - return -EINVAL; - } if (!tfo->write_pending) { pr_err("Missing tfo->write_pending()\n"); return -EINVAL; } - if (!tfo->set_default_node_attributes) { - pr_err("Missing tfo->set_default_node_attributes()\n"); - return -EINVAL; - } - if (!tfo->get_cmd_state) { - pr_err("Missing tfo->get_cmd_state()\n"); - return -EINVAL; - } if (!tfo->queue_data_in) { pr_err("Missing tfo->queue_data_in()\n"); return -EINVAL; @@ -447,8 +438,36 @@ static int target_fabric_tf_ops_check(const struct target_core_fabric_ops *tfo) return 0; } +static void target_set_default_ops(struct target_core_fabric_ops *tfo) +{ + if (!tfo->tpg_check_demo_mode) + tfo->tpg_check_demo_mode = target_disable_feature; + + if (!tfo->tpg_check_demo_mode_cache) + tfo->tpg_check_demo_mode_cache = target_disable_feature; + + if (!tfo->tpg_check_demo_mode_write_protect) + tfo->tpg_check_demo_mode_write_protect = target_disable_feature; + + if (!tfo->tpg_check_prod_mode_write_protect) + tfo->tpg_check_prod_mode_write_protect = target_disable_feature; + + if (!tfo->tpg_get_inst_index) + tfo->tpg_get_inst_index = target_default_get_inst_index; + + if (!tfo->sess_get_index) + tfo->sess_get_index = target_default_sess_get_index; + + if (!tfo->set_default_node_attributes) + tfo->set_default_node_attributes = target_set_default_node_attributes; + + if (!tfo->get_cmd_state) + tfo->get_cmd_state = target_default_get_cmd_state; +} + int target_register_template(const struct target_core_fabric_ops *fo) { + struct target_core_fabric_ops *tfo; struct target_fabric_configfs *tf; int ret; @@ -461,10 +480,18 @@ int target_register_template(const struct target_core_fabric_ops *fo) pr_err("%s: could not allocate memory!\n", __func__); return -ENOMEM; } + tfo = kzalloc(sizeof(struct target_core_fabric_ops), GFP_KERNEL); + if (!tfo) { + kfree(tf); + pr_err("%s: could not allocate memory!\n", __func__); + return -ENOMEM; + } + memcpy(tfo, fo, sizeof(*tfo)); + target_set_default_ops(tfo); INIT_LIST_HEAD(&tf->tf_list); atomic_set(&tf->tf_access_cnt, 0); - tf->tf_ops = fo; + tf->tf_ops = tfo; target_fabric_setup_cits(tf); mutex_lock(&g_tf_lock); @@ -492,6 +519,7 @@ void target_unregister_template(const struct target_core_fabric_ops *fo) */ rcu_barrier(); kfree(t->tf_tpg_base_cit.ct_attrs); + kfree(t->tf_ops); kfree(t); return; } diff --git a/drivers/target/target_core_device.c b/drivers/target/target_core_device.c index f6e58410ec3f..90f3f4926172 100644 --- a/drivers/target/target_core_device.c +++ b/drivers/target/target_core_device.c @@ -223,7 +223,7 @@ struct se_dev_entry *core_get_se_deve_from_rtpi( tpg->se_tpg_tfo->fabric_name); continue; } - if (lun->lun_rtpi != rtpi) + if (lun->lun_tpg->tpg_rtpi != rtpi) continue; kref_get(&deve->pr_kref); @@ -479,47 +479,6 @@ void core_clear_lun_from_tpg(struct se_lun *lun, struct se_portal_group *tpg) mutex_unlock(&tpg->acl_node_mutex); } -int core_alloc_rtpi(struct se_lun *lun, struct se_device *dev) -{ - struct se_lun *tmp; - - spin_lock(&dev->se_port_lock); - if (dev->export_count == 0x0000ffff) { - pr_warn("Reached dev->dev_port_count ==" - " 0x0000ffff\n"); - spin_unlock(&dev->se_port_lock); - return -ENOSPC; - } -again: - /* - * Allocate the next RELATIVE TARGET PORT IDENTIFIER for this struct se_device - * Here is the table from spc4r17 section 7.7.3.8. - * - * Table 473 -- RELATIVE TARGET PORT IDENTIFIER field - * - * Code Description - * 0h Reserved - * 1h Relative port 1, historically known as port A - * 2h Relative port 2, historically known as port B - * 3h to FFFFh Relative port 3 through 65 535 - */ - lun->lun_rtpi = dev->dev_rpti_counter++; - if (!lun->lun_rtpi) - goto again; - - list_for_each_entry(tmp, &dev->dev_sep_list, lun_dev_link) { - /* - * Make sure RELATIVE TARGET PORT IDENTIFIER is unique - * for 16-bit wrap.. - */ - if (lun->lun_rtpi == tmp->lun_rtpi) - goto again; - } - spin_unlock(&dev->se_port_lock); - - return 0; -} - static void se_release_vpd_for_dev(struct se_device *dev) { struct t10_vpd *vpd, *vpd_tmp; @@ -782,6 +741,7 @@ struct se_device *target_alloc_device(struct se_hba *hba, const char *name) spin_lock_init(&dev->t10_alua.lba_map_lock); INIT_WORK(&dev->delayed_cmd_work, target_do_delayed_work); + mutex_init(&dev->lun_reset_mutex); dev->t10_wwn.t10_dev = dev; /* diff --git a/drivers/target/target_core_fabric_configfs.c b/drivers/target/target_core_fabric_configfs.c index 67b18a67317a..b7c637644cd4 100644 --- a/drivers/target/target_core_fabric_configfs.c +++ b/drivers/target/target_core_fabric_configfs.c @@ -836,17 +836,49 @@ static ssize_t target_fabric_tpg_base_enable_store(struct config_item *item, if (se_tpg->enabled == op) return count; - - ret = se_tpg->se_tpg_tfo->fabric_enable_tpg(se_tpg, op); + if (op) + ret = target_tpg_enable(se_tpg); + else + ret = target_tpg_disable(se_tpg); if (ret) return ret; + return count; +} +static ssize_t target_fabric_tpg_base_rtpi_show(struct config_item *item, char *page) +{ + struct se_portal_group *se_tpg = to_tpg(item); - se_tpg->enabled = op; + return sysfs_emit(page, "%#x\n", se_tpg->tpg_rtpi); +} + +static ssize_t target_fabric_tpg_base_rtpi_store(struct config_item *item, + const char *page, size_t count) +{ + struct se_portal_group *se_tpg = to_tpg(item); + u16 val; + int ret; + + ret = kstrtou16(page, 0, &val); + if (ret < 0) + return ret; + if (val == 0) + return -EINVAL; + + if (se_tpg->enabled) { + pr_info("%s_TPG[%hu] - Can not change RTPI on enabled TPG", + se_tpg->se_tpg_tfo->fabric_name, + se_tpg->se_tpg_tfo->tpg_get_tag(se_tpg)); + return -EINVAL; + } + + se_tpg->tpg_rtpi = val; + se_tpg->rtpi_manual = true; return count; } CONFIGFS_ATTR(target_fabric_tpg_base_, enable); +CONFIGFS_ATTR(target_fabric_tpg_base_, rtpi); static int target_fabric_setup_tpg_base_cit(struct target_fabric_configfs *tf) @@ -863,8 +895,8 @@ target_fabric_setup_tpg_base_cit(struct target_fabric_configfs *tf) if (tf->tf_ops->fabric_enable_tpg) nr_attrs++; - if (nr_attrs == 0) - goto done; + /* + 1 for target_fabric_tpg_base_attr_rtpi */ + nr_attrs++; /* + 1 for final NULL in the array */ attrs = kcalloc(nr_attrs + 1, sizeof(*attrs), GFP_KERNEL); @@ -876,9 +908,10 @@ target_fabric_setup_tpg_base_cit(struct target_fabric_configfs *tf) 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; + attrs[i++] = &target_fabric_tpg_base_attr_enable; + + attrs[i++] = &target_fabric_tpg_base_attr_rtpi; -done: cit->ct_item_ops = &target_fabric_tpg_base_item_ops; cit->ct_attrs = attrs; cit->ct_owner = tf->tf_ops->module; diff --git a/drivers/target/target_core_internal.h b/drivers/target/target_core_internal.h index 38a6d08f75b3..408be26d2e9b 100644 --- a/drivers/target/target_core_internal.h +++ b/drivers/target/target_core_internal.h @@ -59,7 +59,6 @@ struct target_fabric_configfs { extern struct t10_alua_lu_gp *default_lu_gp; /* target_core_device.c */ -int core_alloc_rtpi(struct se_lun *lun, struct se_device *dev); struct se_dev_entry *core_get_se_deve_from_rtpi(struct se_node_acl *, u16); void target_pr_kref_release(struct kref *); void core_free_device_list_for_node(struct se_node_acl *, @@ -132,13 +131,14 @@ void core_tpg_remove_lun(struct se_portal_group *, struct se_lun *); struct se_node_acl *core_tpg_add_initiator_node_acl(struct se_portal_group *tpg, const char *initiatorname); void core_tpg_del_initiator_node_acl(struct se_node_acl *acl); +int target_tpg_enable(struct se_portal_group *se_tpg); +int target_tpg_disable(struct se_portal_group *se_tpg); /* target_core_transport.c */ int init_se_kmem_caches(void); void release_se_kmem_caches(void); u32 scsi_get_new_index(scsi_index_t); void transport_subsystem_check_init(void); -void transport_uninit_session(struct se_session *); unsigned char *transport_dump_cmd_direction(struct se_cmd *); void transport_dump_dev_state(struct se_device *, char *, int *); void transport_dump_dev_info(struct se_device *, struct se_lun *, diff --git a/drivers/target/target_core_pr.c b/drivers/target/target_core_pr.c index 1493b1d01194..d19ec4e6a4c0 100644 --- a/drivers/target/target_core_pr.c +++ b/drivers/target/target_core_pr.c @@ -663,7 +663,7 @@ static struct t10_pr_registration *__core_scsi3_do_alloc_registration( } pr_reg->pr_res_mapped_lun = mapped_lun; pr_reg->pr_aptpl_target_lun = lun->unpacked_lun; - pr_reg->tg_pt_sep_rtpi = lun->lun_rtpi; + pr_reg->tg_pt_sep_rtpi = lun->lun_tpg->tpg_rtpi; pr_reg->pr_res_key = sa_res_key; pr_reg->pr_reg_all_tg_pt = all_tg_pt; pr_reg->pr_reg_aptpl = aptpl; @@ -967,7 +967,7 @@ static int __core_scsi3_check_aptpl_registration( rcu_read_unlock(); pr_reg->pr_reg_nacl = nacl; - pr_reg->tg_pt_sep_rtpi = lun->lun_rtpi; + pr_reg->tg_pt_sep_rtpi = lun->lun_tpg->tpg_rtpi; list_del(&pr_reg->pr_reg_aptpl_list); spin_unlock(&pr_tmpl->aptpl_reg_lock); /* @@ -1567,7 +1567,7 @@ core_scsi3_decode_spec_i_port( */ if (tmp_tpg->proto_id != proto_ident) continue; - dest_rtpi = tmp_lun->lun_rtpi; + dest_rtpi = tmp_lun->lun_tpg->tpg_rtpi; iport_ptr = NULL; i_str = target_parse_pr_out_transport_id(tmp_tpg, @@ -3225,7 +3225,7 @@ core_scsi3_emulate_pro_register_and_move(struct se_cmd *cmd, u64 res_key, spin_lock(&dev->se_port_lock); list_for_each_entry(tmp_lun, &dev->dev_sep_list, lun_dev_link) { - if (tmp_lun->lun_rtpi != rtpi) + if (tmp_lun->lun_tpg->tpg_rtpi != rtpi) continue; dest_se_tpg = tmp_lun->lun_tpg; dest_tf_ops = dest_se_tpg->se_tpg_tfo; diff --git a/drivers/target/target_core_spc.c b/drivers/target/target_core_spc.c index fcc7b10a7ae3..89c0d56294cc 100644 --- a/drivers/target/target_core_spc.c +++ b/drivers/target/target_core_spc.c @@ -226,7 +226,6 @@ spc_emulate_evpd_83(struct se_cmd *cmd, unsigned char *buf) struct t10_alua_lu_gp_member *lu_gp_mem; struct t10_alua_tg_pt_gp *tg_pt_gp; unsigned char *prod = &dev->t10_wwn.model[0]; - u32 prod_len; u32 off = 0; u16 len = 0, id_len; @@ -267,10 +266,6 @@ check_t10_vend_desc: * T10 Vendor Identifier Page, see spc4r17 section 7.7.3.4 */ id_len = 8; /* For Vendor field */ - prod_len = 4; /* For VPD Header */ - prod_len += 8; /* For Vendor field */ - prod_len += strlen(prod); - prod_len++; /* For : */ if (dev->dev_flags & DF_EMULATED_VPD_UNIT_SERIAL) id_len += sprintf(&buf[off+12], "%s:%s", prod, @@ -317,7 +312,7 @@ check_t10_vend_desc: /* Skip over Obsolete field in RTPI payload * in Table 472 */ off += 2; - put_unaligned_be16(lun->lun_rtpi, &buf[off]); + put_unaligned_be16(lun->lun_tpg->tpg_rtpi, &buf[off]); off += 2; len += 8; /* Header size + Designation descriptor */ /* diff --git a/drivers/target/target_core_stat.c b/drivers/target/target_core_stat.c index f85ee5b0fd80..c42cbde8a31b 100644 --- a/drivers/target/target_core_stat.c +++ b/drivers/target/target_core_stat.c @@ -455,7 +455,7 @@ static ssize_t target_stat_port_indx_show(struct config_item *item, char *page) rcu_read_lock(); dev = rcu_dereference(lun->lun_se_dev); if (dev) - ret = snprintf(page, PAGE_SIZE, "%u\n", lun->lun_rtpi); + ret = snprintf(page, PAGE_SIZE, "%u\n", lun->lun_tpg->tpg_rtpi); rcu_read_unlock(); return ret; } @@ -561,7 +561,7 @@ static ssize_t target_stat_tgt_port_indx_show(struct config_item *item, rcu_read_lock(); dev = rcu_dereference(lun->lun_se_dev); if (dev) - ret = snprintf(page, PAGE_SIZE, "%u\n", lun->lun_rtpi); + ret = snprintf(page, PAGE_SIZE, "%u\n", lun->lun_tpg->tpg_rtpi); rcu_read_unlock(); return ret; } @@ -579,7 +579,7 @@ static ssize_t target_stat_tgt_port_name_show(struct config_item *item, if (dev) ret = snprintf(page, PAGE_SIZE, "%sPort#%u\n", tpg->se_tpg_tfo->fabric_name, - lun->lun_rtpi); + lun->lun_tpg->tpg_rtpi); rcu_read_unlock(); return ret; } diff --git a/drivers/target/target_core_tmr.c b/drivers/target/target_core_tmr.c index 2b95b4550a63..4718db628222 100644 --- a/drivers/target/target_core_tmr.c +++ b/drivers/target/target_core_tmr.c @@ -188,14 +188,23 @@ static void core_tmr_drain_tmr_list( * LUN_RESET tmr.. */ spin_lock_irqsave(&dev->se_tmr_lock, flags); - if (tmr) - list_del_init(&tmr->tmr_list); list_for_each_entry_safe(tmr_p, tmr_pp, &dev->dev_tmr_list, tmr_list) { + if (tmr_p == tmr) + continue; + cmd = tmr_p->task_cmd; if (!cmd) { pr_err("Unable to locate struct se_cmd for TMR\n"); continue; } + + /* + * We only execute one LUN_RESET at a time so we can't wait + * on them below. + */ + if (tmr_p->function == TMR_LUN_RESET) + continue; + /* * If this function was called with a valid pr_res_key * parameter (eg: for PROUT PREEMPT_AND_ABORT service action @@ -379,14 +388,25 @@ int core_tmr_lun_reset( tmr_nacl->initiatorname); } } + + + /* + * We only allow one reset or preempt and abort to execute at a time + * to prevent one call from claiming all the cmds causing a second + * call from returning while cmds it should have waited on are still + * running. + */ + mutex_lock(&dev->lun_reset_mutex); + pr_debug("LUN_RESET: %s starting for [%s], tas: %d\n", (preempt_and_abort_list) ? "Preempt" : "TMR", dev->transport->name, tas); - core_tmr_drain_tmr_list(dev, tmr, preempt_and_abort_list); core_tmr_drain_state_list(dev, prout_cmd, tmr_sess, tas, preempt_and_abort_list); + mutex_unlock(&dev->lun_reset_mutex); + /* * Clear any legacy SPC-2 reservation when called during * LOGICAL UNIT RESET diff --git a/drivers/target/target_core_tpg.c b/drivers/target/target_core_tpg.c index 736847c933e5..c0e429e5ef31 100644 --- a/drivers/target/target_core_tpg.c +++ b/drivers/target/target_core_tpg.c @@ -31,6 +31,7 @@ #include "target_core_ua.h" extern struct se_device *g_lun0_dev; +static DEFINE_XARRAY_ALLOC(tpg_xa); /* __core_tpg_get_initiator_node_acl(): * @@ -328,7 +329,7 @@ static void target_shutdown_sessions(struct se_node_acl *acl) restart: spin_lock_irqsave(&acl->nacl_sess_lock, flags); list_for_each_entry(sess, &acl->acl_sess_list, sess_acl_list) { - if (atomic_read(&sess->stopped)) + if (sess->cmd_cnt && atomic_read(&sess->cmd_cnt->stopped)) continue; list_del_init(&sess->sess_acl_list); @@ -439,6 +440,68 @@ static void core_tpg_lun_ref_release(struct percpu_ref *ref) complete(&lun->lun_shutdown_comp); } +static int target_tpg_register_rtpi(struct se_portal_group *se_tpg) +{ + u32 val; + int ret; + + if (se_tpg->rtpi_manual) { + ret = xa_insert(&tpg_xa, se_tpg->tpg_rtpi, se_tpg, GFP_KERNEL); + if (ret) { + pr_info("%s_TPG[%hu] - Can not set RTPI %#x, it is already busy", + se_tpg->se_tpg_tfo->fabric_name, + se_tpg->se_tpg_tfo->tpg_get_tag(se_tpg), + se_tpg->tpg_rtpi); + return -EINVAL; + } + } else { + ret = xa_alloc(&tpg_xa, &val, se_tpg, + XA_LIMIT(1, USHRT_MAX), GFP_KERNEL); + if (!ret) + se_tpg->tpg_rtpi = val; + } + + return ret; +} + +static void target_tpg_deregister_rtpi(struct se_portal_group *se_tpg) +{ + if (se_tpg->tpg_rtpi && se_tpg->enabled) + xa_erase(&tpg_xa, se_tpg->tpg_rtpi); +} + +int target_tpg_enable(struct se_portal_group *se_tpg) +{ + int ret; + + ret = target_tpg_register_rtpi(se_tpg); + if (ret) + return ret; + + ret = se_tpg->se_tpg_tfo->fabric_enable_tpg(se_tpg, true); + if (ret) { + target_tpg_deregister_rtpi(se_tpg); + return ret; + } + + se_tpg->enabled = true; + + return 0; +} + +int target_tpg_disable(struct se_portal_group *se_tpg) +{ + int ret; + + target_tpg_deregister_rtpi(se_tpg); + + ret = se_tpg->se_tpg_tfo->fabric_enable_tpg(se_tpg, false); + if (!ret) + se_tpg->enabled = false; + + return ret; +} + /* Does not change se_wwn->priv. */ int core_tpg_register( struct se_wwn *se_wwn, @@ -535,6 +598,8 @@ int core_tpg_deregister(struct se_portal_group *se_tpg) kfree_rcu(se_tpg->tpg_virt_lun0, rcu_head); } + target_tpg_deregister_rtpi(se_tpg); + return 0; } EXPORT_SYMBOL(core_tpg_deregister); @@ -578,10 +643,6 @@ int core_tpg_add_lun( if (ret < 0) goto out; - ret = core_alloc_rtpi(lun, dev); - if (ret) - goto out_kill_ref; - if (!(dev->transport_flags & TRANSPORT_FLAG_PASSTHROUGH_ALUA) && !(dev->se_hba->hba_flags & HBA_FLAGS_INTERNAL_USE)) target_attach_tg_pt_gp(lun, dev->t10_alua.default_tg_pt_gp); @@ -605,8 +666,6 @@ int core_tpg_add_lun( return 0; -out_kill_ref: - percpu_ref_exit(&lun->lun_ref); out: return ret; } diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c index 5926316252eb..86adff2a86ed 100644 --- a/drivers/target/target_core_transport.c +++ b/drivers/target/target_core_transport.c @@ -220,12 +220,52 @@ void transport_subsystem_check_init(void) sub_api_initialized = 1; } -static void target_release_sess_cmd_refcnt(struct percpu_ref *ref) +static void target_release_cmd_refcnt(struct percpu_ref *ref) { - struct se_session *sess = container_of(ref, typeof(*sess), cmd_count); + struct target_cmd_counter *cmd_cnt = container_of(ref, + typeof(*cmd_cnt), + refcnt); + wake_up(&cmd_cnt->refcnt_wq); +} + +struct target_cmd_counter *target_alloc_cmd_counter(void) +{ + struct target_cmd_counter *cmd_cnt; + int rc; + + cmd_cnt = kzalloc(sizeof(*cmd_cnt), GFP_KERNEL); + if (!cmd_cnt) + return NULL; + + init_completion(&cmd_cnt->stop_done); + init_waitqueue_head(&cmd_cnt->refcnt_wq); + atomic_set(&cmd_cnt->stopped, 0); - wake_up(&sess->cmd_count_wq); + rc = percpu_ref_init(&cmd_cnt->refcnt, target_release_cmd_refcnt, 0, + GFP_KERNEL); + if (rc) + goto free_cmd_cnt; + + return cmd_cnt; + +free_cmd_cnt: + kfree(cmd_cnt); + return NULL; } +EXPORT_SYMBOL_GPL(target_alloc_cmd_counter); + +void target_free_cmd_counter(struct target_cmd_counter *cmd_cnt) +{ + /* + * Drivers like loop do not call target_stop_session during session + * shutdown so we have to drop the ref taken at init time here. + */ + if (!atomic_read(&cmd_cnt->stopped)) + percpu_ref_put(&cmd_cnt->refcnt); + + percpu_ref_exit(&cmd_cnt->refcnt); +} +EXPORT_SYMBOL_GPL(target_free_cmd_counter); /** * transport_init_session - initialize a session object @@ -233,32 +273,14 @@ static void target_release_sess_cmd_refcnt(struct percpu_ref *ref) * * The caller must have zero-initialized @se_sess before calling this function. */ -int transport_init_session(struct se_session *se_sess) +void transport_init_session(struct se_session *se_sess) { INIT_LIST_HEAD(&se_sess->sess_list); INIT_LIST_HEAD(&se_sess->sess_acl_list); spin_lock_init(&se_sess->sess_cmd_lock); - init_waitqueue_head(&se_sess->cmd_count_wq); - init_completion(&se_sess->stop_done); - atomic_set(&se_sess->stopped, 0); - return percpu_ref_init(&se_sess->cmd_count, - target_release_sess_cmd_refcnt, 0, GFP_KERNEL); } EXPORT_SYMBOL(transport_init_session); -void transport_uninit_session(struct se_session *se_sess) -{ - /* - * Drivers like iscsi and loop do not call target_stop_session - * during session shutdown so we have to drop the ref taken at init - * time here. - */ - if (!atomic_read(&se_sess->stopped)) - percpu_ref_put(&se_sess->cmd_count); - - percpu_ref_exit(&se_sess->cmd_count); -} - /** * transport_alloc_session - allocate a session object and initialize it * @sup_prot_ops: bitmask that defines which T10-PI modes are supported. @@ -266,7 +288,6 @@ void transport_uninit_session(struct se_session *se_sess) struct se_session *transport_alloc_session(enum target_prot_op sup_prot_ops) { struct se_session *se_sess; - int ret; se_sess = kmem_cache_zalloc(se_sess_cache, GFP_KERNEL); if (!se_sess) { @@ -274,11 +295,7 @@ struct se_session *transport_alloc_session(enum target_prot_op sup_prot_ops) " se_sess_cache\n"); return ERR_PTR(-ENOMEM); } - ret = transport_init_session(se_sess); - if (ret < 0) { - kmem_cache_free(se_sess_cache, se_sess); - return ERR_PTR(ret); - } + transport_init_session(se_sess); se_sess->sup_prot_ops = sup_prot_ops; return se_sess; @@ -444,8 +461,13 @@ target_setup_session(struct se_portal_group *tpg, int (*callback)(struct se_portal_group *, struct se_session *, void *)) { + struct target_cmd_counter *cmd_cnt; struct se_session *sess; + int rc; + cmd_cnt = target_alloc_cmd_counter(); + if (!cmd_cnt) + return ERR_PTR(-ENOMEM); /* * If the fabric driver is using percpu-ida based pre allocation * of I/O descriptor tags, go ahead and perform that setup now.. @@ -455,29 +477,36 @@ target_setup_session(struct se_portal_group *tpg, else sess = transport_alloc_session(prot_op); - if (IS_ERR(sess)) - return sess; + if (IS_ERR(sess)) { + rc = PTR_ERR(sess); + goto free_cnt; + } + sess->cmd_cnt = cmd_cnt; sess->se_node_acl = core_tpg_check_initiator_node_acl(tpg, (unsigned char *)initiatorname); if (!sess->se_node_acl) { - transport_free_session(sess); - return ERR_PTR(-EACCES); + rc = -EACCES; + goto free_sess; } /* * Go ahead and perform any remaining fabric setup that is * required before transport_register_session(). */ if (callback != NULL) { - int rc = callback(tpg, sess, private); - if (rc) { - transport_free_session(sess); - return ERR_PTR(rc); - } + rc = callback(tpg, sess, private); + if (rc) + goto free_sess; } transport_register_session(tpg, sess->se_node_acl, sess, private); return sess; + +free_sess: + transport_free_session(sess); +free_cnt: + target_free_cmd_counter(cmd_cnt); + return ERR_PTR(rc); } EXPORT_SYMBOL(target_setup_session); @@ -602,7 +631,8 @@ void transport_free_session(struct se_session *se_sess) sbitmap_queue_free(&se_sess->sess_tag_pool); kvfree(se_sess->sess_cmd_map); } - transport_uninit_session(se_sess); + if (se_sess->cmd_cnt) + target_free_cmd_counter(se_sess->cmd_cnt); kmem_cache_free(se_sess_cache, se_sess); } EXPORT_SYMBOL(transport_free_session); @@ -1412,14 +1442,12 @@ target_cmd_size_check(struct se_cmd *cmd, unsigned int size) * * Preserves the value of @cmd->tag. */ -void __target_init_cmd( - struct se_cmd *cmd, - const struct target_core_fabric_ops *tfo, - struct se_session *se_sess, - u32 data_length, - int data_direction, - int task_attr, - unsigned char *sense_buffer, u64 unpacked_lun) +void __target_init_cmd(struct se_cmd *cmd, + const struct target_core_fabric_ops *tfo, + struct se_session *se_sess, u32 data_length, + int data_direction, int task_attr, + unsigned char *sense_buffer, u64 unpacked_lun, + struct target_cmd_counter *cmd_cnt) { INIT_LIST_HEAD(&cmd->se_delayed_node); INIT_LIST_HEAD(&cmd->se_qf_node); @@ -1439,6 +1467,7 @@ void __target_init_cmd( cmd->sam_task_attr = task_attr; cmd->sense_buffer = sense_buffer; cmd->orig_fe_lun = unpacked_lun; + cmd->cmd_cnt = cmd_cnt; if (!(cmd->se_cmd_flags & SCF_USE_CPUID)) cmd->cpuid = raw_smp_processor_id(); @@ -1658,7 +1687,8 @@ int target_init_cmd(struct se_cmd *se_cmd, struct se_session *se_sess, * target_core_fabric_ops->queue_status() callback */ __target_init_cmd(se_cmd, se_tpg->se_tpg_tfo, se_sess, data_length, - data_dir, task_attr, sense, unpacked_lun); + data_dir, task_attr, sense, unpacked_lun, + se_sess->cmd_cnt); /* * Obtain struct se_cmd->cmd_kref reference. A second kref_get here is @@ -1953,7 +1983,8 @@ int target_submit_tmr(struct se_cmd *se_cmd, struct se_session *se_sess, BUG_ON(!se_tpg); __target_init_cmd(se_cmd, se_tpg->se_tpg_tfo, se_sess, - 0, DMA_NONE, TCM_SIMPLE_TAG, sense, unpacked_lun); + 0, DMA_NONE, TCM_SIMPLE_TAG, sense, unpacked_lun, + se_sess->cmd_cnt); /* * FIXME: Currently expect caller to handle se_cmd->se_tmr_req * allocation failure. @@ -2957,7 +2988,6 @@ EXPORT_SYMBOL(transport_generic_free_cmd); */ int target_get_sess_cmd(struct se_cmd *se_cmd, bool ack_kref) { - struct se_session *se_sess = se_cmd->se_sess; int ret = 0; /* @@ -2970,9 +3000,14 @@ int target_get_sess_cmd(struct se_cmd *se_cmd, bool ack_kref) se_cmd->se_cmd_flags |= SCF_ACK_KREF; } - if (!percpu_ref_tryget_live(&se_sess->cmd_count)) - ret = -ESHUTDOWN; - + /* + * Users like xcopy do not use counters since they never do a stop + * and wait. + */ + if (se_cmd->cmd_cnt) { + if (!percpu_ref_tryget_live(&se_cmd->cmd_cnt->refcnt)) + ret = -ESHUTDOWN; + } if (ret && ack_kref) target_put_sess_cmd(se_cmd); @@ -2993,7 +3028,7 @@ static void target_free_cmd_mem(struct se_cmd *cmd) static void target_release_cmd_kref(struct kref *kref) { struct se_cmd *se_cmd = container_of(kref, struct se_cmd, cmd_kref); - struct se_session *se_sess = se_cmd->se_sess; + struct target_cmd_counter *cmd_cnt = se_cmd->cmd_cnt; struct completion *free_compl = se_cmd->free_compl; struct completion *abrt_compl = se_cmd->abrt_compl; @@ -3004,7 +3039,8 @@ static void target_release_cmd_kref(struct kref *kref) if (abrt_compl) complete(abrt_compl); - percpu_ref_put(&se_sess->cmd_count); + if (cmd_cnt) + percpu_ref_put(&cmd_cnt->refcnt); } /** @@ -3123,46 +3159,67 @@ void target_show_cmd(const char *pfx, struct se_cmd *cmd) } EXPORT_SYMBOL(target_show_cmd); -static void target_stop_session_confirm(struct percpu_ref *ref) +static void target_stop_cmd_counter_confirm(struct percpu_ref *ref) +{ + struct target_cmd_counter *cmd_cnt = container_of(ref, + struct target_cmd_counter, + refcnt); + complete_all(&cmd_cnt->stop_done); +} + +/** + * target_stop_cmd_counter - Stop new IO from being added to the counter. + * @cmd_cnt: counter to stop + */ +void target_stop_cmd_counter(struct target_cmd_counter *cmd_cnt) { - struct se_session *se_sess = container_of(ref, struct se_session, - cmd_count); - complete_all(&se_sess->stop_done); + pr_debug("Stopping command counter.\n"); + if (!atomic_cmpxchg(&cmd_cnt->stopped, 0, 1)) + percpu_ref_kill_and_confirm(&cmd_cnt->refcnt, + target_stop_cmd_counter_confirm); } +EXPORT_SYMBOL_GPL(target_stop_cmd_counter); /** * target_stop_session - Stop new IO from being queued on the session. - * @se_sess: session to stop + * @se_sess: session to stop */ void target_stop_session(struct se_session *se_sess) { - pr_debug("Stopping session queue.\n"); - if (atomic_cmpxchg(&se_sess->stopped, 0, 1) == 0) - percpu_ref_kill_and_confirm(&se_sess->cmd_count, - target_stop_session_confirm); + target_stop_cmd_counter(se_sess->cmd_cnt); } EXPORT_SYMBOL(target_stop_session); /** - * target_wait_for_sess_cmds - Wait for outstanding commands - * @se_sess: session to wait for active I/O + * target_wait_for_cmds - Wait for outstanding cmds. + * @cmd_cnt: counter to wait for active I/O for. */ -void target_wait_for_sess_cmds(struct se_session *se_sess) +void target_wait_for_cmds(struct target_cmd_counter *cmd_cnt) { int ret; - WARN_ON_ONCE(!atomic_read(&se_sess->stopped)); + WARN_ON_ONCE(!atomic_read(&cmd_cnt->stopped)); do { pr_debug("Waiting for running cmds to complete.\n"); - ret = wait_event_timeout(se_sess->cmd_count_wq, - percpu_ref_is_zero(&se_sess->cmd_count), - 180 * HZ); + ret = wait_event_timeout(cmd_cnt->refcnt_wq, + percpu_ref_is_zero(&cmd_cnt->refcnt), + 180 * HZ); } while (ret <= 0); - wait_for_completion(&se_sess->stop_done); + wait_for_completion(&cmd_cnt->stop_done); pr_debug("Waiting for cmds done.\n"); } +EXPORT_SYMBOL_GPL(target_wait_for_cmds); + +/** + * target_wait_for_sess_cmds - Wait for outstanding commands + * @se_sess: session to wait for active I/O + */ +void target_wait_for_sess_cmds(struct se_session *se_sess) +{ + target_wait_for_cmds(se_sess->cmd_cnt); +} EXPORT_SYMBOL(target_wait_for_sess_cmds); /* diff --git a/drivers/target/target_core_xcopy.c b/drivers/target/target_core_xcopy.c index 49eaee022ef1..91ed015b588c 100644 --- a/drivers/target/target_core_xcopy.c +++ b/drivers/target/target_core_xcopy.c @@ -461,8 +461,6 @@ static const struct target_core_fabric_ops xcopy_pt_tfo = { int target_xcopy_setup_pt(void) { - int ret; - xcopy_wq = alloc_workqueue("xcopy_wq", WQ_MEM_RECLAIM, 0); if (!xcopy_wq) { pr_err("Unable to allocate xcopy_wq\n"); @@ -479,9 +477,7 @@ int target_xcopy_setup_pt(void) INIT_LIST_HEAD(&xcopy_pt_nacl.acl_list); INIT_LIST_HEAD(&xcopy_pt_nacl.acl_sess_list); memset(&xcopy_pt_sess, 0, sizeof(struct se_session)); - ret = transport_init_session(&xcopy_pt_sess); - if (ret < 0) - goto destroy_wq; + transport_init_session(&xcopy_pt_sess); xcopy_pt_nacl.se_tpg = &xcopy_pt_tpg; xcopy_pt_nacl.nacl_sess = &xcopy_pt_sess; @@ -490,19 +486,12 @@ int target_xcopy_setup_pt(void) xcopy_pt_sess.se_node_acl = &xcopy_pt_nacl; return 0; - -destroy_wq: - destroy_workqueue(xcopy_wq); - xcopy_wq = NULL; - return ret; } void target_xcopy_release_pt(void) { - if (xcopy_wq) { + if (xcopy_wq) destroy_workqueue(xcopy_wq); - transport_uninit_session(&xcopy_pt_sess); - } } /* @@ -602,8 +591,8 @@ static int target_xcopy_read_source( (unsigned long long)src_lba, transfer_length_block, src_bytes); __target_init_cmd(se_cmd, &xcopy_pt_tfo, &xcopy_pt_sess, src_bytes, - DMA_FROM_DEVICE, 0, &xpt_cmd.sense_buffer[0], 0); - + DMA_FROM_DEVICE, 0, &xpt_cmd.sense_buffer[0], 0, + NULL); rc = target_xcopy_setup_pt_cmd(&xpt_cmd, xop, src_dev, &cdb[0], remote_port); if (rc < 0) { @@ -647,8 +636,8 @@ static int target_xcopy_write_destination( (unsigned long long)dst_lba, transfer_length_block, dst_bytes); __target_init_cmd(se_cmd, &xcopy_pt_tfo, &xcopy_pt_sess, dst_bytes, - DMA_TO_DEVICE, 0, &xpt_cmd.sense_buffer[0], 0); - + DMA_TO_DEVICE, 0, &xpt_cmd.sense_buffer[0], 0, + NULL); rc = target_xcopy_setup_pt_cmd(&xpt_cmd, xop, dst_dev, &cdb[0], remote_port); if (rc < 0) { diff --git a/drivers/target/tcm_fc/tcm_fc.h b/drivers/target/tcm_fc/tcm_fc.h index 2ff716d8cbdd..00e5573c6296 100644 --- a/drivers/target/tcm_fc/tcm_fc.h +++ b/drivers/target/tcm_fc/tcm_fc.h @@ -146,7 +146,6 @@ void ft_release_cmd(struct se_cmd *); int ft_queue_status(struct se_cmd *); int ft_queue_data_in(struct se_cmd *); int ft_write_pending(struct se_cmd *); -int ft_get_cmd_state(struct se_cmd *); void ft_queue_tm_resp(struct se_cmd *); void ft_aborted_task(struct se_cmd *); diff --git a/drivers/target/tcm_fc/tfc_cmd.c b/drivers/target/tcm_fc/tfc_cmd.c index 410b723f9d79..21783cd71c15 100644 --- a/drivers/target/tcm_fc/tfc_cmd.c +++ b/drivers/target/tcm_fc/tfc_cmd.c @@ -223,11 +223,6 @@ int ft_write_pending(struct se_cmd *se_cmd) return 0; } -int ft_get_cmd_state(struct se_cmd *se_cmd) -{ - return 0; -} - /* * FC sequence response handler for follow-on sequences (data) and aborts. */ diff --git a/drivers/target/tcm_fc/tfc_conf.c b/drivers/target/tcm_fc/tfc_conf.c index 1a38c98f681b..6ac3fc1a7d39 100644 --- a/drivers/target/tcm_fc/tfc_conf.c +++ b/drivers/target/tcm_fc/tfc_conf.c @@ -398,15 +398,6 @@ static u16 ft_get_tag(struct se_portal_group *se_tpg) return ft_tpg(se_tpg)->index; } -static int ft_check_false(struct se_portal_group *se_tpg) -{ - return 0; -} - -static void ft_set_default_node_attr(struct se_node_acl *se_nacl) -{ -} - static u32 ft_tpg_get_inst_index(struct se_portal_group *se_tpg) { return ft_tpg(se_tpg)->index; @@ -418,10 +409,6 @@ static const struct target_core_fabric_ops ft_fabric_ops = { .node_acl_size = sizeof(struct ft_node_acl), .tpg_get_wwn = ft_get_fabric_wwn, .tpg_get_tag = ft_get_tag, - .tpg_check_demo_mode = ft_check_false, - .tpg_check_demo_mode_cache = ft_check_false, - .tpg_check_demo_mode_write_protect = ft_check_false, - .tpg_check_prod_mode_write_protect = ft_check_false, .tpg_get_inst_index = ft_tpg_get_inst_index, .check_stop_free = ft_check_stop_free, .release_cmd = ft_release_cmd, @@ -429,8 +416,6 @@ static const struct target_core_fabric_ops ft_fabric_ops = { .sess_get_index = ft_sess_get_index, .sess_get_initiator_sid = NULL, .write_pending = ft_write_pending, - .set_default_node_attributes = ft_set_default_node_attr, - .get_cmd_state = ft_get_cmd_state, .queue_data_in = ft_queue_data_in, .queue_status = ft_queue_status, .queue_tm_rsp = ft_queue_tm_resp, diff --git a/drivers/target/tcm_remote/Kconfig b/drivers/target/tcm_remote/Kconfig new file mode 100644 index 000000000000..e6bebb5fe6f1 --- /dev/null +++ b/drivers/target/tcm_remote/Kconfig @@ -0,0 +1,8 @@ +# SPDX-License-Identifier: GPL-2.0-only +config REMOTE_TARGET + tristate "TCM Virtual Remote target" + depends on SCSI + help + Say Y here to enable the TCM Virtual Remote fabric + That fabric is a dummy fabric to tell TCM about configuration + of TPG/ACL/LUN on peer nodes in a cluster. diff --git a/drivers/target/tcm_remote/Makefile b/drivers/target/tcm_remote/Makefile new file mode 100644 index 000000000000..5818ffd0b0fa --- /dev/null +++ b/drivers/target/tcm_remote/Makefile @@ -0,0 +1,2 @@ +# SPDX-License-Identifier: GPL-2.0-only +obj-$(CONFIG_REMOTE_TARGET) += tcm_remote.o diff --git a/drivers/target/tcm_remote/tcm_remote.c b/drivers/target/tcm_remote/tcm_remote.c new file mode 100644 index 000000000000..cb8db2558056 --- /dev/null +++ b/drivers/target/tcm_remote/tcm_remote.c @@ -0,0 +1,268 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + +#include <linux/module.h> +#include <linux/moduleparam.h> +#include <linux/init.h> +#include <linux/slab.h> +#include <linux/types.h> +#include <linux/configfs.h> +#include <scsi/scsi.h> +#include <scsi/scsi_tcq.h> +#include <scsi/scsi_host.h> +#include <scsi/scsi_device.h> +#include <scsi/scsi_cmnd.h> + +#include <target/target_core_base.h> +#include <target/target_core_fabric.h> + +#include "tcm_remote.h" + +static inline struct tcm_remote_tpg *remote_tpg(struct se_portal_group *se_tpg) +{ + return container_of(se_tpg, struct tcm_remote_tpg, remote_se_tpg); +} + +static char *tcm_remote_get_endpoint_wwn(struct se_portal_group *se_tpg) +{ + /* + * Return the passed NAA identifier for the Target Port + */ + return &remote_tpg(se_tpg)->remote_hba->remote_wwn_address[0]; +} + +static u16 tcm_remote_get_tag(struct se_portal_group *se_tpg) +{ + /* + * This Tag is used when forming SCSI Name identifier in EVPD=1 0x83 + * to represent the SCSI Target Port. + */ + return remote_tpg(se_tpg)->remote_tpgt; +} + +static int tcm_remote_dummy_cmd_fn(struct se_cmd *se_cmd) +{ + return 0; +} + +static void tcm_remote_dummy_cmd_void_fn(struct se_cmd *se_cmd) +{ + +} + +static char *tcm_remote_dump_proto_id(struct tcm_remote_hba *remote_hba) +{ + switch (remote_hba->remote_proto_id) { + case SCSI_PROTOCOL_SAS: + return "SAS"; + case SCSI_PROTOCOL_SRP: + return "SRP"; + case SCSI_PROTOCOL_FCP: + return "FCP"; + case SCSI_PROTOCOL_ISCSI: + return "iSCSI"; + default: + break; + } + + return "Unknown"; +} + +static int tcm_remote_port_link( + struct se_portal_group *se_tpg, + struct se_lun *lun) +{ + pr_debug("TCM_Remote_ConfigFS: Port Link LUN %lld Successful\n", + lun->unpacked_lun); + return 0; +} + +static void tcm_remote_port_unlink( + struct se_portal_group *se_tpg, + struct se_lun *lun) +{ + pr_debug("TCM_Remote_ConfigFS: Port Unlink LUN %lld Successful\n", + lun->unpacked_lun); +} + +static struct se_portal_group *tcm_remote_make_tpg( + struct se_wwn *wwn, + const char *name) +{ + struct tcm_remote_hba *remote_hba = container_of(wwn, + struct tcm_remote_hba, remote_hba_wwn); + struct tcm_remote_tpg *remote_tpg; + unsigned long tpgt; + int ret; + + if (strstr(name, "tpgt_") != name) { + pr_err("Unable to locate \"tpgt_#\" directory group\n"); + return ERR_PTR(-EINVAL); + } + if (kstrtoul(name + 5, 10, &tpgt)) + return ERR_PTR(-EINVAL); + + if (tpgt >= TL_TPGS_PER_HBA) { + pr_err("Passed tpgt: %lu exceeds TL_TPGS_PER_HBA: %u\n", + tpgt, TL_TPGS_PER_HBA); + return ERR_PTR(-EINVAL); + } + remote_tpg = &remote_hba->remote_hba_tpgs[tpgt]; + remote_tpg->remote_hba = remote_hba; + remote_tpg->remote_tpgt = tpgt; + /* + * Register the remote_tpg as a emulated TCM Target Endpoint + */ + ret = core_tpg_register(wwn, &remote_tpg->remote_se_tpg, + remote_hba->remote_proto_id); + if (ret < 0) + return ERR_PTR(-ENOMEM); + + pr_debug("TCM_Remote_ConfigFS: Allocated Emulated %s Target Port %s,t,0x%04lx\n", + tcm_remote_dump_proto_id(remote_hba), + config_item_name(&wwn->wwn_group.cg_item), tpgt); + return &remote_tpg->remote_se_tpg; +} + +static void tcm_remote_drop_tpg(struct se_portal_group *se_tpg) +{ + struct se_wwn *wwn = se_tpg->se_tpg_wwn; + struct tcm_remote_tpg *remote_tpg = container_of(se_tpg, + struct tcm_remote_tpg, remote_se_tpg); + struct tcm_remote_hba *remote_hba; + unsigned short tpgt; + + remote_hba = remote_tpg->remote_hba; + tpgt = remote_tpg->remote_tpgt; + + /* + * Deregister the remote_tpg as a emulated TCM Target Endpoint + */ + core_tpg_deregister(se_tpg); + + remote_tpg->remote_hba = NULL; + remote_tpg->remote_tpgt = 0; + + pr_debug("TCM_Remote_ConfigFS: Deallocated Emulated %s Target Port %s,t,0x%04x\n", + tcm_remote_dump_proto_id(remote_hba), + config_item_name(&wwn->wwn_group.cg_item), tpgt); +} + +static struct se_wwn *tcm_remote_make_wwn( + struct target_fabric_configfs *tf, + struct config_group *group, + const char *name) +{ + struct tcm_remote_hba *remote_hba; + char *ptr; + int ret, off = 0; + + remote_hba = kzalloc(sizeof(*remote_hba), GFP_KERNEL); + if (!remote_hba) + return ERR_PTR(-ENOMEM); + + /* + * Determine the emulated Protocol Identifier and Target Port Name + * based on the incoming configfs directory name. + */ + ptr = strstr(name, "naa."); + if (ptr) { + remote_hba->remote_proto_id = SCSI_PROTOCOL_SAS; + goto check_len; + } + ptr = strstr(name, "fc."); + if (ptr) { + remote_hba->remote_proto_id = SCSI_PROTOCOL_FCP; + off = 3; /* Skip over "fc." */ + goto check_len; + } + ptr = strstr(name, "0x"); + if (ptr) { + remote_hba->remote_proto_id = SCSI_PROTOCOL_SRP; + off = 2; /* Skip over "0x" */ + goto check_len; + } + ptr = strstr(name, "iqn."); + if (!ptr) { + pr_err("Unable to locate prefix for emulated Target Port: %s\n", + name); + ret = -EINVAL; + goto out; + } + remote_hba->remote_proto_id = SCSI_PROTOCOL_ISCSI; + +check_len: + if (strlen(name) >= TL_WWN_ADDR_LEN) { + pr_err("Emulated NAA %s Address: %s, exceeds max: %d\n", + name, tcm_remote_dump_proto_id(remote_hba), TL_WWN_ADDR_LEN); + ret = -EINVAL; + goto out; + } + snprintf(&remote_hba->remote_wwn_address[0], TL_WWN_ADDR_LEN, "%s", &name[off]); + + pr_debug("TCM_Remote_ConfigFS: Allocated emulated Target %s Address: %s\n", + tcm_remote_dump_proto_id(remote_hba), name); + return &remote_hba->remote_hba_wwn; +out: + kfree(remote_hba); + return ERR_PTR(ret); +} + +static void tcm_remote_drop_wwn(struct se_wwn *wwn) +{ + struct tcm_remote_hba *remote_hba = container_of(wwn, + struct tcm_remote_hba, remote_hba_wwn); + + pr_debug("TCM_Remote_ConfigFS: Deallocating emulated Target %s Address: %s\n", + tcm_remote_dump_proto_id(remote_hba), + remote_hba->remote_wwn_address); + kfree(remote_hba); +} + +static ssize_t tcm_remote_wwn_version_show(struct config_item *item, char *page) +{ + return sprintf(page, "TCM Remote Fabric module %s\n", TCM_REMOTE_VERSION); +} + +CONFIGFS_ATTR_RO(tcm_remote_wwn_, version); + +static struct configfs_attribute *tcm_remote_wwn_attrs[] = { + &tcm_remote_wwn_attr_version, + NULL, +}; + +static const struct target_core_fabric_ops remote_ops = { + .module = THIS_MODULE, + .fabric_name = "remote", + .tpg_get_wwn = tcm_remote_get_endpoint_wwn, + .tpg_get_tag = tcm_remote_get_tag, + .check_stop_free = tcm_remote_dummy_cmd_fn, + .release_cmd = tcm_remote_dummy_cmd_void_fn, + .write_pending = tcm_remote_dummy_cmd_fn, + .queue_data_in = tcm_remote_dummy_cmd_fn, + .queue_status = tcm_remote_dummy_cmd_fn, + .queue_tm_rsp = tcm_remote_dummy_cmd_void_fn, + .aborted_task = tcm_remote_dummy_cmd_void_fn, + .fabric_make_wwn = tcm_remote_make_wwn, + .fabric_drop_wwn = tcm_remote_drop_wwn, + .fabric_make_tpg = tcm_remote_make_tpg, + .fabric_drop_tpg = tcm_remote_drop_tpg, + .fabric_post_link = tcm_remote_port_link, + .fabric_pre_unlink = tcm_remote_port_unlink, + .tfc_wwn_attrs = tcm_remote_wwn_attrs, +}; + +static int __init tcm_remote_fabric_init(void) +{ + return target_register_template(&remote_ops); +} + +static void __exit tcm_remote_fabric_exit(void) +{ + target_unregister_template(&remote_ops); +} + +MODULE_DESCRIPTION("TCM virtual remote target"); +MODULE_AUTHOR("Dmitry Bogdanov <d.bogdanov@yadro.com>"); +MODULE_LICENSE("GPL"); +module_init(tcm_remote_fabric_init); +module_exit(tcm_remote_fabric_exit); diff --git a/drivers/target/tcm_remote/tcm_remote.h b/drivers/target/tcm_remote/tcm_remote.h new file mode 100644 index 000000000000..913d1a6eb3a2 --- /dev/null +++ b/drivers/target/tcm_remote/tcm_remote.h @@ -0,0 +1,20 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#include <linux/types.h> +#include <linux/device.h> + +#define TCM_REMOTE_VERSION "v0.1" +#define TL_WWN_ADDR_LEN 256 +#define TL_TPGS_PER_HBA 32 + +struct tcm_remote_tpg { + unsigned short remote_tpgt; + struct se_portal_group remote_se_tpg; + struct tcm_remote_hba *remote_hba; +}; + +struct tcm_remote_hba { + u8 remote_proto_id; + unsigned char remote_wwn_address[TL_WWN_ADDR_LEN]; + struct tcm_remote_tpg remote_hba_tpgs[TL_TPGS_PER_HBA]; + struct se_wwn remote_hba_wwn; +}; diff --git a/drivers/ufs/core/ufshcd-priv.h b/drivers/ufs/core/ufshcd-priv.h index 529f8507a5e4..d53b93c21a0c 100644 --- a/drivers/ufs/core/ufshcd-priv.h +++ b/drivers/ufs/core/ufshcd-priv.h @@ -364,6 +364,7 @@ static inline bool ufs_is_valid_unit_desc_lun(struct ufs_dev_info *dev_info, u8 } static inline void ufshcd_inc_sq_tail(struct ufs_hw_queue *q) + __must_hold(&q->sq_lock) { u32 mask = q->max_entries - 1; u32 val; diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c index 70b112038792..17d7bb875fee 100644 --- a/drivers/ufs/core/ufshcd.c +++ b/drivers/ufs/core/ufshcd.c @@ -422,7 +422,9 @@ static void ufshcd_add_command_trace(struct ufs_hba *hba, unsigned int tag, { u64 lba = 0; u8 opcode = 0, group_id = 0; - u32 intr, doorbell; + u32 doorbell = 0; + u32 intr; + int hwq_id = -1; struct ufshcd_lrb *lrbp = &hba->lrb[tag]; struct scsi_cmnd *cmd = lrbp->cmd; struct request *rq = scsi_cmd_to_rq(cmd); @@ -456,9 +458,16 @@ static void ufshcd_add_command_trace(struct ufs_hba *hba, unsigned int tag, } intr = ufshcd_readl(hba, REG_INTERRUPT_STATUS); - doorbell = ufshcd_readl(hba, REG_UTP_TRANSFER_REQ_DOOR_BELL); + + if (is_mcq_enabled(hba)) { + struct ufs_hw_queue *hwq = ufshcd_mcq_req_to_hwq(hba, rq); + + hwq_id = hwq->id; + } else { + doorbell = ufshcd_readl(hba, REG_UTP_TRANSFER_REQ_DOOR_BELL); + } trace_ufshcd_command(dev_name(hba->dev), str_t, tag, - doorbell, transfer_len, intr, lba, opcode, group_id); + doorbell, hwq_id, transfer_len, intr, lba, opcode, group_id); } static void ufshcd_print_clk_freqs(struct ufs_hba *hba) @@ -533,48 +542,66 @@ static void ufshcd_print_evt_hist(struct ufs_hba *hba) } static -void ufshcd_print_trs(struct ufs_hba *hba, unsigned long bitmap, bool pr_prdt) +void ufshcd_print_tr(struct ufs_hba *hba, int tag, bool pr_prdt) { const struct ufshcd_lrb *lrbp; int prdt_length; - int tag; - for_each_set_bit(tag, &bitmap, hba->nutrs) { - lrbp = &hba->lrb[tag]; + lrbp = &hba->lrb[tag]; - dev_err(hba->dev, "UPIU[%d] - issue time %lld us\n", - tag, div_u64(lrbp->issue_time_stamp_local_clock, 1000)); - dev_err(hba->dev, "UPIU[%d] - complete time %lld us\n", - tag, div_u64(lrbp->compl_time_stamp_local_clock, 1000)); - dev_err(hba->dev, - "UPIU[%d] - Transfer Request Descriptor phys@0x%llx\n", - tag, (u64)lrbp->utrd_dma_addr); - - ufshcd_hex_dump("UPIU TRD: ", lrbp->utr_descriptor_ptr, - sizeof(struct utp_transfer_req_desc)); - dev_err(hba->dev, "UPIU[%d] - Request UPIU phys@0x%llx\n", tag, - (u64)lrbp->ucd_req_dma_addr); - ufshcd_hex_dump("UPIU REQ: ", lrbp->ucd_req_ptr, - sizeof(struct utp_upiu_req)); - dev_err(hba->dev, "UPIU[%d] - Response UPIU phys@0x%llx\n", tag, - (u64)lrbp->ucd_rsp_dma_addr); - ufshcd_hex_dump("UPIU RSP: ", lrbp->ucd_rsp_ptr, - sizeof(struct utp_upiu_rsp)); - - prdt_length = le16_to_cpu( - lrbp->utr_descriptor_ptr->prd_table_length); - if (hba->quirks & UFSHCD_QUIRK_PRDT_BYTE_GRAN) - prdt_length /= ufshcd_sg_entry_size(hba); + dev_err(hba->dev, "UPIU[%d] - issue time %lld us\n", + tag, div_u64(lrbp->issue_time_stamp_local_clock, 1000)); + dev_err(hba->dev, "UPIU[%d] - complete time %lld us\n", + tag, div_u64(lrbp->compl_time_stamp_local_clock, 1000)); + dev_err(hba->dev, + "UPIU[%d] - Transfer Request Descriptor phys@0x%llx\n", + tag, (u64)lrbp->utrd_dma_addr); + + ufshcd_hex_dump("UPIU TRD: ", lrbp->utr_descriptor_ptr, + sizeof(struct utp_transfer_req_desc)); + dev_err(hba->dev, "UPIU[%d] - Request UPIU phys@0x%llx\n", tag, + (u64)lrbp->ucd_req_dma_addr); + ufshcd_hex_dump("UPIU REQ: ", lrbp->ucd_req_ptr, + sizeof(struct utp_upiu_req)); + dev_err(hba->dev, "UPIU[%d] - Response UPIU phys@0x%llx\n", tag, + (u64)lrbp->ucd_rsp_dma_addr); + ufshcd_hex_dump("UPIU RSP: ", lrbp->ucd_rsp_ptr, + sizeof(struct utp_upiu_rsp)); + + prdt_length = le16_to_cpu( + lrbp->utr_descriptor_ptr->prd_table_length); + if (hba->quirks & UFSHCD_QUIRK_PRDT_BYTE_GRAN) + prdt_length /= ufshcd_sg_entry_size(hba); - dev_err(hba->dev, - "UPIU[%d] - PRDT - %d entries phys@0x%llx\n", - tag, prdt_length, - (u64)lrbp->ucd_prdt_dma_addr); + dev_err(hba->dev, + "UPIU[%d] - PRDT - %d entries phys@0x%llx\n", + tag, prdt_length, + (u64)lrbp->ucd_prdt_dma_addr); - if (pr_prdt) - ufshcd_hex_dump("UPIU PRDT: ", lrbp->ucd_prdt_ptr, - ufshcd_sg_entry_size(hba) * prdt_length); - } + if (pr_prdt) + ufshcd_hex_dump("UPIU PRDT: ", lrbp->ucd_prdt_ptr, + ufshcd_sg_entry_size(hba) * prdt_length); +} + +static bool ufshcd_print_tr_iter(struct request *req, void *priv) +{ + struct scsi_device *sdev = req->q->queuedata; + struct Scsi_Host *shost = sdev->host; + struct ufs_hba *hba = shost_priv(shost); + + ufshcd_print_tr(hba, req->tag, *(bool *)priv); + + return true; +} + +/** + * ufshcd_print_trs_all - print trs for all started requests. + * @hba: per-adapter instance. + * @pr_prdt: need to print prdt or not. + */ +static void ufshcd_print_trs_all(struct ufs_hba *hba, bool pr_prdt) +{ + blk_mq_tagset_busy_iter(&hba->host->tag_set, ufshcd_print_tr_iter, &pr_prdt); } static void ufshcd_print_tmrs(struct ufs_hba *hba, unsigned long bitmap) @@ -1242,7 +1269,7 @@ static int ufshcd_scale_gear(struct ufs_hba *hba, bool scale_up) struct ufs_pa_layer_attr new_pwr_info; if (scale_up) { - memcpy(&new_pwr_info, &hba->clk_scaling.saved_pwr_info.info, + memcpy(&new_pwr_info, &hba->clk_scaling.saved_pwr_info, sizeof(struct ufs_pa_layer_attr)); } else { memcpy(&new_pwr_info, &hba->pwr_info, @@ -1251,7 +1278,7 @@ static int ufshcd_scale_gear(struct ufs_hba *hba, bool scale_up) if (hba->pwr_info.gear_tx > hba->clk_scaling.min_gear || hba->pwr_info.gear_rx > hba->clk_scaling.min_gear) { /* save the current power mode */ - memcpy(&hba->clk_scaling.saved_pwr_info.info, + memcpy(&hba->clk_scaling.saved_pwr_info, &hba->pwr_info, sizeof(struct ufs_pa_layer_attr)); @@ -2208,10 +2235,11 @@ void ufshcd_send_command(struct ufs_hba *hba, unsigned int task_tag, if (is_mcq_enabled(hba)) { int utrd_size = sizeof(struct utp_transfer_req_desc); + struct utp_transfer_req_desc *src = lrbp->utr_descriptor_ptr; + struct utp_transfer_req_desc *dest = hwq->sqe_base_addr + hwq->sq_tail_slot; spin_lock(&hwq->sq_lock); - memcpy(hwq->sqe_base_addr + (hwq->sq_tail_slot * utrd_size), - lrbp->utr_descriptor_ptr, utrd_size); + memcpy(dest, src, utrd_size); ufshcd_inc_sq_tail(hwq); spin_unlock(&hwq->sq_lock); } else { @@ -5231,6 +5259,9 @@ ufshcd_transfer_rsp_status(struct ufs_hba *hba, struct ufshcd_lrb *lrbp, int scsi_status; enum utp_ocs ocs; + scsi_set_resid(lrbp->cmd, + be32_to_cpu(lrbp->ucd_rsp_ptr->sr.residual_transfer_count)); + /* overall command status of utrd */ ocs = ufshcd_get_tr_ocs(lrbp, cqe); @@ -5321,7 +5352,7 @@ ufshcd_transfer_rsp_status(struct ufs_hba *hba, struct ufshcd_lrb *lrbp, if ((host_byte(result) != DID_OK) && (host_byte(result) != DID_REQUEUE) && !hba->silence_err_logs) - ufshcd_print_trs(hba, 1 << lrbp->task_tag, true); + ufshcd_print_tr(hba, lrbp->task_tag, true); return result; } @@ -6405,7 +6436,7 @@ again: ufshcd_print_pwr_info(hba); ufshcd_print_evt_hist(hba); ufshcd_print_tmrs(hba, hba->outstanding_tasks); - ufshcd_print_trs(hba, hba->outstanding_reqs, pr_prdt); + ufshcd_print_trs_all(hba, pr_prdt); spin_lock_irqsave(hba->host->host_lock, flags); } @@ -7434,9 +7465,9 @@ static int ufshcd_abort(struct scsi_cmnd *cmd) ufshcd_print_evt_hist(hba); ufshcd_print_host_state(hba); ufshcd_print_pwr_info(hba); - ufshcd_print_trs(hba, 1 << tag, true); + ufshcd_print_tr(hba, tag, true); } else { - ufshcd_print_trs(hba, 1 << tag, false); + ufshcd_print_tr(hba, tag, false); } hba->req_abort_count++; @@ -8394,10 +8425,9 @@ static int ufshcd_add_lus(struct ufs_hba *hba) /* Initialize devfreq after UFS device is detected */ if (ufshcd_is_clkscaling_supported(hba)) { - memcpy(&hba->clk_scaling.saved_pwr_info.info, + memcpy(&hba->clk_scaling.saved_pwr_info, &hba->pwr_info, sizeof(struct ufs_pa_layer_attr)); - hba->clk_scaling.saved_pwr_info.is_valid = true; hba->clk_scaling.is_allowed = true; ret = ufshcd_devfreq_init(hba); @@ -8724,7 +8754,7 @@ static struct ufs_hba_variant_params ufs_hba_vps = { .ondemand_data.downdifferential = 5, }; -static struct scsi_host_template ufshcd_driver_template = { +static const struct scsi_host_template ufshcd_driver_template = { .module = THIS_MODULE, .name = UFSHCD, .proc_name = UFSHCD, @@ -8747,6 +8777,7 @@ static struct scsi_host_template ufshcd_driver_template = { .max_sectors = (1 << 20) / SECTOR_SIZE, /* 1 MiB */ .max_host_blocked = 1, .track_queue_depth = 1, + .skip_settle_delay = 1, .sdev_groups = ufshcd_driver_groups, .rpm_autosuspend_delay = RPM_AUTOSUSPEND_DELAY_MS, }; diff --git a/drivers/ufs/host/ufs-exynos.c b/drivers/ufs/host/ufs-exynos.c index 7c985fc38db1..0bf5390739e1 100644 --- a/drivers/ufs/host/ufs-exynos.c +++ b/drivers/ufs/host/ufs-exynos.c @@ -1761,7 +1761,7 @@ static struct platform_driver exynos_ufs_pltform = { .driver = { .name = "exynos-ufshc", .pm = &exynos_ufs_pm_ops, - .of_match_table = of_match_ptr(exynos_ufs_of_match), + .of_match_table = exynos_ufs_of_match, }, }; module_platform_driver(exynos_ufs_pltform); diff --git a/drivers/ufs/host/ufs-hisi.c b/drivers/ufs/host/ufs-hisi.c index 2eed13bc82ca..4c423eba8aa9 100644 --- a/drivers/ufs/host/ufs-hisi.c +++ b/drivers/ufs/host/ufs-hisi.c @@ -597,7 +597,7 @@ static struct platform_driver ufs_hisi_pltform = { .driver = { .name = "ufshcd-hisi", .pm = &ufs_hisi_pm_ops, - .of_match_table = of_match_ptr(ufs_hisi_of_match), + .of_match_table = ufs_hisi_of_match, }, }; module_platform_driver(ufs_hisi_pltform); diff --git a/drivers/ufs/host/ufs-qcom.c b/drivers/ufs/host/ufs-qcom.c index a02cd866e2f8..82d02e7f3b4f 100644 --- a/drivers/ufs/host/ufs-qcom.c +++ b/drivers/ufs/host/ufs-qcom.c @@ -1693,7 +1693,7 @@ static int ufs_qcom_remove(struct platform_device *pdev) return 0; } -static const struct of_device_id ufs_qcom_of_match[] = { +static const struct of_device_id ufs_qcom_of_match[] __maybe_unused = { { .compatible = "qcom,ufshc"}, {}, }; diff --git a/drivers/ufs/host/ufshcd-pci.c b/drivers/ufs/host/ufshcd-pci.c index 1c91f43e15c8..9c911787f84c 100644 --- a/drivers/ufs/host/ufshcd-pci.c +++ b/drivers/ufs/host/ufshcd-pci.c @@ -607,6 +607,7 @@ static const struct pci_device_id ufshcd_pci_tbl[] = { { PCI_VDEVICE(INTEL, 0x51FF), (kernel_ulong_t)&ufs_intel_adl_hba_vops }, { PCI_VDEVICE(INTEL, 0x54FF), (kernel_ulong_t)&ufs_intel_adl_hba_vops }, { PCI_VDEVICE(INTEL, 0x7E47), (kernel_ulong_t)&ufs_intel_mtl_hba_vops }, + { PCI_VDEVICE(INTEL, 0xA847), (kernel_ulong_t)&ufs_intel_mtl_hba_vops }, { } /* terminate list */ }; diff --git a/drivers/usb/gadget/function/f_tcm.c b/drivers/usb/gadget/function/f_tcm.c index 658e2e21fdd0..79ed2e6e576a 100644 --- a/drivers/usb/gadget/function/f_tcm.c +++ b/drivers/usb/gadget/function/f_tcm.c @@ -1054,7 +1054,7 @@ static void usbg_cmd_work(struct work_struct *work) tv_nexus->tvn_se_sess->se_tpg->se_tpg_tfo, tv_nexus->tvn_se_sess, cmd->data_len, DMA_NONE, cmd->prio_attr, cmd->sense_iu.sense, - cmd->unpacked_lun); + cmd->unpacked_lun, NULL); goto out; } @@ -1183,7 +1183,7 @@ static void bot_cmd_work(struct work_struct *work) tv_nexus->tvn_se_sess->se_tpg->se_tpg_tfo, tv_nexus->tvn_se_sess, cmd->data_len, DMA_NONE, cmd->prio_attr, cmd->sense_iu.sense, - cmd->unpacked_lun); + cmd->unpacked_lun, NULL); goto out; } @@ -1253,11 +1253,6 @@ static int usbg_check_true(struct se_portal_group *se_tpg) return 1; } -static int usbg_check_false(struct se_portal_group *se_tpg) -{ - return 0; -} - static char *usbg_get_fabric_wwn(struct se_portal_group *se_tpg) { struct usbg_tpg *tpg = container_of(se_tpg, @@ -1274,11 +1269,6 @@ static u16 usbg_get_tag(struct se_portal_group *se_tpg) return tpg->tport_tpgt; } -static u32 usbg_tpg_get_inst_index(struct se_portal_group *se_tpg) -{ - return 1; -} - static void usbg_release_cmd(struct se_cmd *se_cmd) { struct usbg_cmd *cmd = container_of(se_cmd, struct usbg_cmd, @@ -1289,20 +1279,6 @@ static void usbg_release_cmd(struct se_cmd *se_cmd) target_free_tag(se_sess, se_cmd); } -static u32 usbg_sess_get_index(struct se_session *se_sess) -{ - return 0; -} - -static void usbg_set_default_node_attrs(struct se_node_acl *nacl) -{ -} - -static int usbg_get_cmd_state(struct se_cmd *se_cmd) -{ - return 0; -} - static void usbg_queue_tm_rsp(struct se_cmd *se_cmd) { } @@ -1691,16 +1667,9 @@ static const struct target_core_fabric_ops usbg_ops = { .tpg_get_wwn = usbg_get_fabric_wwn, .tpg_get_tag = usbg_get_tag, .tpg_check_demo_mode = usbg_check_true, - .tpg_check_demo_mode_cache = usbg_check_false, - .tpg_check_demo_mode_write_protect = usbg_check_false, - .tpg_check_prod_mode_write_protect = usbg_check_false, - .tpg_get_inst_index = usbg_tpg_get_inst_index, .release_cmd = usbg_release_cmd, - .sess_get_index = usbg_sess_get_index, .sess_get_initiator_sid = NULL, .write_pending = usbg_send_write_request, - .set_default_node_attributes = usbg_set_default_node_attrs, - .get_cmd_state = usbg_get_cmd_state, .queue_data_in = usbg_send_read_response, .queue_status = usbg_send_status_response, .queue_tm_rsp = usbg_queue_tm_rsp, diff --git a/drivers/usb/image/microtek.c b/drivers/usb/image/microtek.c index 874ea4b54ced..8c8fa71c69c4 100644 --- a/drivers/usb/image/microtek.c +++ b/drivers/usb/image/microtek.c @@ -620,7 +620,7 @@ out: static DEF_SCSI_QCMD(mts_scsi_queuecommand) -static struct scsi_host_template mts_scsi_host_template = { +static const struct scsi_host_template mts_scsi_host_template = { .module = THIS_MODULE, .name = "microtekX6", .proc_name = "microtekX6", diff --git a/drivers/usb/storage/uas.c b/drivers/usb/storage/uas.c index de3836412bf3..2583ee9815c5 100644 --- a/drivers/usb/storage/uas.c +++ b/drivers/usb/storage/uas.c @@ -894,7 +894,7 @@ static int uas_slave_configure(struct scsi_device *sdev) return 0; } -static struct scsi_host_template uas_host_template = { +static const struct scsi_host_template uas_host_template = { .module = THIS_MODULE, .name = "uas", .queuecommand = uas_queuecommand, diff --git a/drivers/usb/storage/usb.c b/drivers/usb/storage/usb.c index ed7c6ad96a74..7b36a3334fb3 100644 --- a/drivers/usb/storage/usb.c +++ b/drivers/usb/storage/usb.c @@ -937,7 +937,7 @@ int usb_stor_probe1(struct us_data **pus, struct usb_interface *intf, const struct usb_device_id *id, const struct us_unusual_dev *unusual_dev, - struct scsi_host_template *sht) + const struct scsi_host_template *sht) { struct Scsi_Host *host; struct us_data *us; diff --git a/drivers/usb/storage/usb.h b/drivers/usb/storage/usb.h index 0451fac1adce..fd3f32670873 100644 --- a/drivers/usb/storage/usb.h +++ b/drivers/usb/storage/usb.h @@ -187,7 +187,7 @@ extern int usb_stor_probe1(struct us_data **pus, struct usb_interface *intf, const struct usb_device_id *id, const struct us_unusual_dev *unusual_dev, - struct scsi_host_template *sht); + const struct scsi_host_template *sht); extern int usb_stor_probe2(struct us_data *us); extern void usb_stor_disconnect(struct usb_interface *intf); diff --git a/drivers/vhost/scsi.c b/drivers/vhost/scsi.c index e68f7d226bc9..139ad52d0aa1 100644 --- a/drivers/vhost/scsi.c +++ b/drivers/vhost/scsi.c @@ -291,11 +291,6 @@ static int vhost_scsi_check_true(struct se_portal_group *se_tpg) return 1; } -static int vhost_scsi_check_false(struct se_portal_group *se_tpg) -{ - return 0; -} - static char *vhost_scsi_get_fabric_wwn(struct se_portal_group *se_tpg) { struct vhost_scsi_tpg *tpg = container_of(se_tpg, @@ -320,11 +315,6 @@ static int vhost_scsi_check_prot_fabric_only(struct se_portal_group *se_tpg) return tpg->tv_fabric_prot_type; } -static u32 vhost_scsi_tpg_get_inst_index(struct se_portal_group *se_tpg) -{ - return 1; -} - static void vhost_scsi_release_cmd_res(struct se_cmd *se_cmd) { struct vhost_scsi_cmd *tv_cmd = container_of(se_cmd, @@ -372,11 +362,6 @@ static void vhost_scsi_release_cmd(struct se_cmd *se_cmd) } } -static u32 vhost_scsi_sess_get_index(struct se_session *se_sess) -{ - return 0; -} - static int vhost_scsi_write_pending(struct se_cmd *se_cmd) { /* Go ahead and process the write immediately */ @@ -384,16 +369,6 @@ static int vhost_scsi_write_pending(struct se_cmd *se_cmd) return 0; } -static void vhost_scsi_set_default_node_attrs(struct se_node_acl *nacl) -{ - return; -} - -static int vhost_scsi_get_cmd_state(struct se_cmd *se_cmd) -{ - return 0; -} - static int vhost_scsi_queue_data_in(struct se_cmd *se_cmd) { transport_generic_free_cmd(se_cmd, 0); @@ -2435,17 +2410,11 @@ static const struct target_core_fabric_ops vhost_scsi_ops = { .tpg_get_tag = vhost_scsi_get_tpgt, .tpg_check_demo_mode = vhost_scsi_check_true, .tpg_check_demo_mode_cache = vhost_scsi_check_true, - .tpg_check_demo_mode_write_protect = vhost_scsi_check_false, - .tpg_check_prod_mode_write_protect = vhost_scsi_check_false, .tpg_check_prot_fabric_only = vhost_scsi_check_prot_fabric_only, - .tpg_get_inst_index = vhost_scsi_tpg_get_inst_index, .release_cmd = vhost_scsi_release_cmd, .check_stop_free = vhost_scsi_check_stop_free, - .sess_get_index = vhost_scsi_sess_get_index, .sess_get_initiator_sid = NULL, .write_pending = vhost_scsi_write_pending, - .set_default_node_attributes = vhost_scsi_set_default_node_attrs, - .get_cmd_state = vhost_scsi_get_cmd_state, .queue_data_in = vhost_scsi_queue_data_in, .queue_status = vhost_scsi_queue_status, .queue_tm_rsp = vhost_scsi_queue_tm_rsp, diff --git a/drivers/xen/xen-scsiback.c b/drivers/xen/xen-scsiback.c index 954188b0b858..a7e7e02c415d 100644 --- a/drivers/xen/xen-scsiback.c +++ b/drivers/xen/xen-scsiback.c @@ -1406,11 +1406,6 @@ static void scsiback_drop_tport(struct se_wwn *wwn) kfree(tport); } -static u32 scsiback_tpg_get_inst_index(struct se_portal_group *se_tpg) -{ - return 1; -} - static int scsiback_check_stop_free(struct se_cmd *se_cmd) { return transport_generic_free_cmd(se_cmd, 0); @@ -1421,11 +1416,6 @@ static void scsiback_release_cmd(struct se_cmd *se_cmd) target_free_tag(se_cmd->se_sess, se_cmd); } -static u32 scsiback_sess_get_index(struct se_session *se_sess) -{ - return 0; -} - static int scsiback_write_pending(struct se_cmd *se_cmd) { /* Go ahead and process the write immediately */ @@ -1434,15 +1424,6 @@ static int scsiback_write_pending(struct se_cmd *se_cmd) return 0; } -static void scsiback_set_default_node_attrs(struct se_node_acl *nacl) -{ -} - -static int scsiback_get_cmd_state(struct se_cmd *se_cmd) -{ - return 0; -} - static int scsiback_queue_data_in(struct se_cmd *se_cmd) { struct vscsibk_pend *pending_req = container_of(se_cmd, @@ -1822,11 +1803,6 @@ static int scsiback_check_true(struct se_portal_group *se_tpg) return 1; } -static int scsiback_check_false(struct se_portal_group *se_tpg) -{ - return 0; -} - static const struct target_core_fabric_ops scsiback_ops = { .module = THIS_MODULE, .fabric_name = "xen-pvscsi", @@ -1834,16 +1810,10 @@ static const struct target_core_fabric_ops scsiback_ops = { .tpg_get_tag = scsiback_get_tag, .tpg_check_demo_mode = scsiback_check_true, .tpg_check_demo_mode_cache = scsiback_check_true, - .tpg_check_demo_mode_write_protect = scsiback_check_false, - .tpg_check_prod_mode_write_protect = scsiback_check_false, - .tpg_get_inst_index = scsiback_tpg_get_inst_index, .check_stop_free = scsiback_check_stop_free, .release_cmd = scsiback_release_cmd, - .sess_get_index = scsiback_sess_get_index, .sess_get_initiator_sid = NULL, .write_pending = scsiback_write_pending, - .set_default_node_attributes = scsiback_set_default_node_attrs, - .get_cmd_state = scsiback_get_cmd_state, .queue_data_in = scsiback_queue_data_in, .queue_status = scsiback_queue_status, .queue_tm_rsp = scsiback_queue_tm_rsp, diff --git a/include/linux/ahci_platform.h b/include/linux/ahci_platform.h index 17fa26215292..fe0760ce34c8 100644 --- a/include/linux/ahci_platform.h +++ b/include/linux/ahci_platform.h @@ -37,7 +37,7 @@ struct ahci_host_priv *ahci_platform_get_resources( int ahci_platform_init_host(struct platform_device *pdev, struct ahci_host_priv *hpriv, const struct ata_port_info *pi_template, - struct scsi_host_template *sht); + const struct scsi_host_template *sht); void ahci_platform_shutdown(struct platform_device *pdev); diff --git a/include/linux/ata_platform.h b/include/linux/ata_platform.h index 9cafec92282d..b9745cc08e38 100644 --- a/include/linux/ata_platform.h +++ b/include/linux/ata_platform.h @@ -19,7 +19,7 @@ extern int __pata_platform_probe(struct device *dev, struct resource *irq_res, unsigned int ioport_shift, int __pio_mask, - struct scsi_host_template *sht, + const struct scsi_host_template *sht, bool use16bit); /* diff --git a/include/linux/libata.h b/include/linux/libata.h index a759dfbdcc91..311cd93377c7 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -1065,10 +1065,10 @@ extern void ata_host_get(struct ata_host *host); extern void ata_host_put(struct ata_host *host); extern int ata_host_start(struct ata_host *host); extern int ata_host_register(struct ata_host *host, - struct scsi_host_template *sht); + const struct scsi_host_template *sht); extern int ata_host_activate(struct ata_host *host, int irq, irq_handler_t irq_handler, unsigned long irq_flags, - struct scsi_host_template *sht); + const struct scsi_host_template *sht); extern void ata_host_detach(struct ata_host *host); extern void ata_host_init(struct ata_host *, struct device *, struct ata_port_operations *); extern int ata_scsi_detect(struct scsi_host_template *sht); @@ -1980,10 +1980,10 @@ extern int ata_pci_sff_prepare_host(struct pci_dev *pdev, struct ata_host **r_host); extern int ata_pci_sff_activate_host(struct ata_host *host, irq_handler_t irq_handler, - struct scsi_host_template *sht); + const struct scsi_host_template *sht); extern int ata_pci_sff_init_one(struct pci_dev *pdev, const struct ata_port_info * const * ppi, - struct scsi_host_template *sht, void *host_priv, int hflags); + const struct scsi_host_template *sht, void *host_priv, int hflags); #endif /* CONFIG_PCI */ #ifdef CONFIG_ATA_BMDMA @@ -2019,7 +2019,7 @@ extern int ata_pci_bmdma_prepare_host(struct pci_dev *pdev, struct ata_host **r_host); extern int ata_pci_bmdma_init_one(struct pci_dev *pdev, const struct ata_port_info * const * ppi, - struct scsi_host_template *sht, + const struct scsi_host_template *sht, void *host_priv, int hflags); #endif /* CONFIG_PCI */ #endif /* CONFIG_ATA_BMDMA */ diff --git a/include/linux/raid_class.h b/include/linux/raid_class.h index 5cdfcb873a8f..6a9b177d5c41 100644 --- a/include/linux/raid_class.h +++ b/include/linux/raid_class.h @@ -11,7 +11,7 @@ struct raid_template { }; struct raid_function_template { - void *cookie; + const void *cookie; int (*is_raid)(struct device *); void (*get_resync)(struct device *); void (*get_state)(struct device *); diff --git a/include/scsi/libfc.h b/include/scsi/libfc.h index 6e29e1719db1..eca6fd42d7f7 100644 --- a/include/scsi/libfc.h +++ b/include/scsi/libfc.h @@ -866,7 +866,7 @@ static inline void *lport_priv(const struct fc_lport *lport) * Returns: libfc lport */ static inline struct fc_lport * -libfc_host_alloc(struct scsi_host_template *sht, int priv_size) +libfc_host_alloc(const struct scsi_host_template *sht, int priv_size) { struct fc_lport *lport; struct Scsi_Host *shost; diff --git a/include/scsi/libiscsi.h b/include/scsi/libiscsi.h index e39fb0736ade..7282555adfd5 100644 --- a/include/scsi/libiscsi.h +++ b/include/scsi/libiscsi.h @@ -407,7 +407,7 @@ extern int iscsi_host_set_param(struct Scsi_Host *shost, extern int iscsi_host_get_param(struct Scsi_Host *shost, enum iscsi_host_param param, char *buf); extern int iscsi_host_add(struct Scsi_Host *shost, struct device *pdev); -extern struct Scsi_Host *iscsi_host_alloc(struct scsi_host_template *sht, +extern struct Scsi_Host *iscsi_host_alloc(const struct scsi_host_template *sht, int dd_data_size, bool xmit_can_sleep); extern void iscsi_host_remove(struct Scsi_Host *shost, bool is_shutdown); diff --git a/include/scsi/scsi_host.h b/include/scsi/scsi_host.h index 587cc767bb67..0f29799efa02 100644 --- a/include/scsi/scsi_host.h +++ b/include/scsi/scsi_host.h @@ -554,7 +554,7 @@ struct Scsi_Host { struct completion * eh_action; /* Wait for specific actions on the host. */ wait_queue_head_t host_wait; - struct scsi_host_template *hostt; + const struct scsi_host_template *hostt; struct scsi_transport_template *transportt; struct kref tagset_refcnt; @@ -747,7 +747,7 @@ static inline int scsi_host_in_recovery(struct Scsi_Host *shost) extern int scsi_queue_work(struct Scsi_Host *, struct work_struct *); extern void scsi_flush_work(struct Scsi_Host *); -extern struct Scsi_Host *scsi_host_alloc(struct scsi_host_template *, int); +extern struct Scsi_Host *scsi_host_alloc(const struct scsi_host_template *, int); extern int __must_check scsi_add_host_with_dma(struct Scsi_Host *, struct device *, struct device *); diff --git a/include/target/iscsi/iscsi_target_core.h b/include/target/iscsi/iscsi_target_core.h index 94d06ddfd80a..229118156a1f 100644 --- a/include/target/iscsi/iscsi_target_core.h +++ b/include/target/iscsi/iscsi_target_core.h @@ -600,6 +600,7 @@ struct iscsit_conn { struct iscsi_tpg_np *tpg_np; /* Pointer to parent session */ struct iscsit_session *sess; + struct target_cmd_counter *cmd_cnt; int bitmap_id; int rx_thread_active; struct task_struct *rx_thread; diff --git a/include/target/target_core_base.h b/include/target/target_core_base.h index 12c9ba16217e..5f8e96f1516f 100644 --- a/include/target/target_core_base.h +++ b/include/target/target_core_base.h @@ -494,6 +494,7 @@ struct se_cmd { struct se_lun *se_lun; /* Only used for internal passthrough and legacy TCM fabric modules */ struct se_session *se_sess; + struct target_cmd_counter *cmd_cnt; struct se_tmr_req *se_tmr_req; struct llist_node se_cmd_list; struct completion *free_compl; @@ -619,22 +620,26 @@ static inline struct se_node_acl *fabric_stat_to_nacl(struct config_item *item) acl_fabric_stat_group); } -struct se_session { +struct target_cmd_counter { + struct percpu_ref refcnt; + wait_queue_head_t refcnt_wq; + struct completion stop_done; atomic_t stopped; +}; + +struct se_session { u64 sess_bin_isid; enum target_prot_op sup_prot_ops; enum target_prot_type sess_prot_type; struct se_node_acl *se_node_acl; struct se_portal_group *se_tpg; void *fabric_sess_ptr; - struct percpu_ref cmd_count; struct list_head sess_list; struct list_head sess_acl_list; spinlock_t sess_cmd_lock; - wait_queue_head_t cmd_count_wq; - struct completion stop_done; void *sess_cmd_map; struct sbitmap_queue sess_tag_pool; + struct target_cmd_counter *cmd_cnt; }; struct se_device; @@ -735,8 +740,6 @@ struct se_lun { bool lun_access_ro; u32 lun_index; - /* RELATIVE TARGET PORT IDENTIFER */ - u16 lun_rtpi; atomic_t lun_acl_count; struct se_device __rcu *lun_se_dev; @@ -788,8 +791,6 @@ struct se_device_queue { }; struct se_device { - /* RELATIVE TARGET PORT IDENTIFER Counter */ - u16 dev_rpti_counter; /* Used for SAM Task Attribute ordering */ u32 dev_cur_ordered_id; u32 dev_flags; @@ -867,6 +868,7 @@ struct se_device { struct rcu_head rcu_head; int queue_cnt; struct se_device_queue *queues; + struct mutex lun_reset_mutex; }; struct target_opcode_descriptor { @@ -920,6 +922,9 @@ struct se_portal_group { */ int proto_id; bool enabled; + /* RELATIVE TARGET PORT IDENTIFIER */ + u16 tpg_rtpi; + bool rtpi_manual; /* 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 38f0662476d1..b188b1e90e1e 100644 --- a/include/target/target_core_fabric.h +++ b/include/target/target_core_fabric.h @@ -133,7 +133,12 @@ struct se_session *target_setup_session(struct se_portal_group *, struct se_session *, void *)); void target_remove_session(struct se_session *); -int transport_init_session(struct se_session *se_sess); +void target_stop_cmd_counter(struct target_cmd_counter *cmd_cnt); +void target_wait_for_cmds(struct target_cmd_counter *cmd_cnt); +struct target_cmd_counter *target_alloc_cmd_counter(void); +void target_free_cmd_counter(struct target_cmd_counter *cmd_cnt); + +void transport_init_session(struct se_session *se_sess); struct se_session *transport_alloc_session(enum target_prot_op); int transport_alloc_session_tags(struct se_session *, unsigned int, unsigned int); @@ -149,9 +154,11 @@ void transport_deregister_session_configfs(struct se_session *); void transport_deregister_session(struct se_session *); -void __target_init_cmd(struct se_cmd *, - const struct target_core_fabric_ops *, - struct se_session *, u32, int, int, unsigned char *, u64); +void __target_init_cmd(struct se_cmd *cmd, + const struct target_core_fabric_ops *tfo, + struct se_session *sess, u32 data_length, int data_direction, + int task_attr, unsigned char *sense_buffer, u64 unpacked_lun, + struct target_cmd_counter *cmd_cnt); int target_init_cmd(struct se_cmd *se_cmd, struct se_session *se_sess, unsigned char *sense, u64 unpacked_lun, u32 data_length, int task_attr, int data_dir, int flags); diff --git a/include/trace/events/ufs.h b/include/trace/events/ufs.h index 599739ee7b20..992517ac3292 100644 --- a/include/trace/events/ufs.h +++ b/include/trace/events/ufs.h @@ -268,20 +268,21 @@ DEFINE_EVENT(ufshcd_template, ufshcd_wl_runtime_resume, TRACE_EVENT(ufshcd_command, TP_PROTO(const char *dev_name, enum ufs_trace_str_t str_t, - unsigned int tag, u32 doorbell, int transfer_len, u32 intr, - u64 lba, u8 opcode, u8 group_id), + unsigned int tag, u32 doorbell, u32 hwq_id, int transfer_len, + u32 intr, u64 lba, u8 opcode, u8 group_id), - TP_ARGS(dev_name, str_t, tag, doorbell, transfer_len, - intr, lba, opcode, group_id), + TP_ARGS(dev_name, str_t, tag, doorbell, hwq_id, transfer_len, + intr, lba, opcode, group_id), TP_STRUCT__entry( __string(dev_name, dev_name) __field(enum ufs_trace_str_t, str_t) __field(unsigned int, tag) __field(u32, doorbell) - __field(int, transfer_len) + __field(u32, hwq_id) __field(u32, intr) __field(u64, lba) + __field(int, transfer_len) __field(u8, opcode) __field(u8, group_id) ), @@ -291,19 +292,20 @@ TRACE_EVENT(ufshcd_command, __entry->str_t = str_t; __entry->tag = tag; __entry->doorbell = doorbell; - __entry->transfer_len = transfer_len; + __entry->hwq_id = hwq_id; __entry->intr = intr; __entry->lba = lba; + __entry->transfer_len = transfer_len; __entry->opcode = opcode; __entry->group_id = group_id; ), TP_printk( - "%s: %s: tag: %u, DB: 0x%x, size: %d, IS: %u, LBA: %llu, opcode: 0x%x (%s), group_id: 0x%x", + "%s: %s: tag: %u, DB: 0x%x, size: %d, IS: %u, LBA: %llu, opcode: 0x%x (%s), group_id: 0x%x, hwq_id: %d", show_ufs_cmd_trace_str(__entry->str_t), __get_str(dev_name), - __entry->tag, __entry->doorbell, __entry->transfer_len, - __entry->intr, __entry->lba, (u32)__entry->opcode, - str_opcode(__entry->opcode), (u32)__entry->group_id + __entry->tag, __entry->doorbell, __entry->transfer_len, __entry->intr, + __entry->lba, (u32)__entry->opcode, str_opcode(__entry->opcode), + (u32)__entry->group_id, __entry->hwq_id ) ); diff --git a/include/uapi/linux/target_core_user.h b/include/uapi/linux/target_core_user.h index fbd8ca67e107..f925a77f19ed 100644 --- a/include/uapi/linux/target_core_user.h +++ b/include/uapi/linux/target_core_user.h @@ -119,7 +119,7 @@ struct tcmu_cmd_entry { __u64 cdb_off; __u64 __pad1; __u64 __pad2; - struct iovec iov[0]; + __DECLARE_FLEX_ARRAY(struct iovec, iov); } req; struct { __u8 scsi_status; diff --git a/include/ufs/ufshcd.h b/include/ufs/ufshcd.h index 431c3afb2ce0..f7553293ba98 100644 --- a/include/ufs/ufshcd.h +++ b/include/ufs/ufshcd.h @@ -394,11 +394,6 @@ struct ufs_clk_gating { struct workqueue_struct *clk_gating_workq; }; -struct ufs_saved_pwr_info { - struct ufs_pa_layer_attr info; - bool is_valid; -}; - /** * struct ufs_clk_scaling - UFS clock scaling related data * @active_reqs: number of requests that are pending. If this is zero when @@ -428,7 +423,7 @@ struct ufs_clk_scaling { ktime_t window_start_t; ktime_t busy_start_t; struct device_attribute enable_attr; - struct ufs_saved_pwr_info saved_pwr_info; + struct ufs_pa_layer_attr saved_pwr_info; struct workqueue_struct *workq; struct work_struct suspend_work; struct work_struct resume_work; @@ -1099,7 +1094,7 @@ struct ufs_hw_queue { void __iomem *mcq_cq_head; void __iomem *mcq_cq_tail; - void *sqe_base_addr; + struct utp_transfer_req_desc *sqe_base_addr; dma_addr_t sqe_dma_addr; struct cq_entry *cqe_base_addr; dma_addr_t cqe_dma_addr; |