From 638a9e433ecd61e64761352dbec1fa4f5874c941 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 7 Aug 2024 15:18:06 +0200 Subject: Merging upstream version 6.10.3. Signed-off-by: Daniel Baumann --- drivers/scsi/FlashPoint.c | 1 - drivers/scsi/Kconfig | 4 +- drivers/scsi/a3000.c | 8 +- drivers/scsi/a4000t.c | 8 +- drivers/scsi/aha152x.c | 8 +- drivers/scsi/aic7xxx/Kconfig.aic79xx | 75 ++--- drivers/scsi/aic7xxx/Kconfig.aic7xxx | 97 +++--- drivers/scsi/aic7xxx/Makefile | 12 +- drivers/scsi/aic94xx/aic94xx_init.c | 29 +- drivers/scsi/arcmsr/arcmsr_hba.c | 2 +- drivers/scsi/atari_scsi.c | 8 +- drivers/scsi/bfa/bfad_attr.c | 28 +- drivers/scsi/bnx2fc/bnx2fc_tgt.c | 4 +- drivers/scsi/csiostor/csio_init.c | 3 - drivers/scsi/cxlflash/lunmgt.c | 6 +- drivers/scsi/cxlflash/main.c | 18 +- drivers/scsi/cxlflash/superpipe.c | 40 ++- drivers/scsi/cxlflash/superpipe.h | 11 +- drivers/scsi/cxlflash/vlun.c | 9 +- drivers/scsi/hisi_sas/hisi_sas.h | 3 +- drivers/scsi/hisi_sas/hisi_sas_main.c | 7 +- drivers/scsi/hisi_sas/hisi_sas_v1_hw.c | 20 +- drivers/scsi/hisi_sas/hisi_sas_v2_hw.c | 26 +- drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 31 +- drivers/scsi/hosts.c | 6 + drivers/scsi/hpsa.c | 2 +- drivers/scsi/hptiop.c | 8 +- drivers/scsi/ibmvscsi/ibmvfc.c | 5 +- drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c | 11 +- drivers/scsi/imm.c | 12 +- drivers/scsi/ipr.c | 12 +- drivers/scsi/isci/init.c | 29 +- drivers/scsi/iscsi_tcp.c | 2 +- drivers/scsi/libsas/sas_ata.c | 84 +++++ drivers/scsi/libsas/sas_expander.c | 35 ++- drivers/scsi/libsas/sas_internal.h | 15 - drivers/scsi/libsas/sas_scsi_host.c | 7 +- drivers/scsi/lpfc/lpfc.h | 62 ++-- drivers/scsi/lpfc/lpfc_attr.c | 36 ++- drivers/scsi/lpfc/lpfc_bsg.c | 3 +- drivers/scsi/lpfc/lpfc_ct.c | 24 +- drivers/scsi/lpfc/lpfc_els.c | 43 +-- drivers/scsi/lpfc/lpfc_hbadisc.c | 135 ++++---- drivers/scsi/lpfc/lpfc_hw4.h | 8 + drivers/scsi/lpfc/lpfc_init.c | 119 ++++--- drivers/scsi/lpfc/lpfc_nportdisc.c | 63 ++-- drivers/scsi/lpfc/lpfc_nvme.c | 27 +- drivers/scsi/lpfc/lpfc_nvmet.c | 9 +- drivers/scsi/lpfc/lpfc_scsi.c | 71 +++-- drivers/scsi/lpfc/lpfc_scsi.h | 32 +- drivers/scsi/lpfc/lpfc_sli.c | 233 +++++++------- drivers/scsi/lpfc/lpfc_version.h | 2 +- drivers/scsi/mac_scsi.c | 8 +- drivers/scsi/megaraid/Kconfig.megaraid | 113 ++++--- drivers/scsi/megaraid/megaraid_sas.h | 2 +- drivers/scsi/megaraid/megaraid_sas_base.c | 33 +- drivers/scsi/megaraid/megaraid_sas_fusion.c | 3 +- drivers/scsi/mpi3mr/mpi/mpi30_cnfg.h | 3 + drivers/scsi/mpi3mr/mpi/mpi30_image.h | 20 +- drivers/scsi/mpi3mr/mpi/mpi30_ioc.h | 20 +- drivers/scsi/mpi3mr/mpi/mpi30_transport.h | 2 +- drivers/scsi/mpi3mr/mpi3mr.h | 15 +- drivers/scsi/mpi3mr/mpi3mr_app.c | 33 +- drivers/scsi/mpi3mr/mpi3mr_fw.c | 42 ++- drivers/scsi/mpi3mr/mpi3mr_os.c | 86 +++-- drivers/scsi/mpi3mr/mpi3mr_transport.c | 16 +- drivers/scsi/mpt3sas/mpt3sas_base.c | 4 +- drivers/scsi/mpt3sas/mpt3sas_scsih.c | 22 +- drivers/scsi/mpt3sas/mpt3sas_transport.c | 14 +- drivers/scsi/mvsas/mv_init.c | 36 +-- drivers/scsi/pm8001/pm8001_ctl.c | 5 + drivers/scsi/pm8001/pm8001_init.c | 21 +- drivers/scsi/pm8001/pm8001_sas.h | 1 + drivers/scsi/pmcraid.c | 13 +- drivers/scsi/ppa.c | 8 +- drivers/scsi/qedf/qedf_main.c | 2 +- drivers/scsi/qla2xxx/Kconfig | 42 +-- drivers/scsi/qla2xxx/qla_attr.c | 11 +- drivers/scsi/qla2xxx/qla_bsg.c | 98 +++--- drivers/scsi/qla2xxx/qla_def.h | 17 +- drivers/scsi/qla2xxx/qla_gbl.h | 6 +- drivers/scsi/qla2xxx/qla_gs.c | 467 +++++++++++++--------------- drivers/scsi/qla2xxx/qla_init.c | 92 ++++-- drivers/scsi/qla2xxx/qla_inline.h | 8 + drivers/scsi/qla2xxx/qla_mid.c | 2 +- drivers/scsi/qla2xxx/qla_mr.c | 6 +- drivers/scsi/qla2xxx/qla_nvme.c | 5 +- drivers/scsi/qla2xxx/qla_os.c | 28 +- drivers/scsi/qla2xxx/qla_sup.c | 108 +++++-- drivers/scsi/qla4xxx/ql4_mbx.c | 17 +- drivers/scsi/qla4xxx/ql4_os.c | 14 +- drivers/scsi/scsi_debug.c | 6 +- drivers/scsi/scsi_debugfs.c | 56 ++-- drivers/scsi/scsi_devinfo.c | 18 +- drivers/scsi/scsi_lib.c | 41 +-- drivers/scsi/scsi_scan.c | 74 +++-- drivers/scsi/scsi_sysfs.c | 5 +- drivers/scsi/scsi_transport_fc.c | 15 +- drivers/scsi/scsi_transport_iscsi.c | 7 +- drivers/scsi/scsi_transport_sas.c | 4 +- drivers/scsi/scsicam.c | 2 +- drivers/scsi/sd.c | 14 +- drivers/scsi/sd.h | 19 -- drivers/scsi/sd_zbc.c | 335 +------------------- drivers/scsi/ses.c | 1 - drivers/scsi/smartpqi/smartpqi_init.c | 16 +- drivers/scsi/snic/snic_attrs.c | 11 +- drivers/scsi/sr.c | 1 - drivers/scsi/sr_ioctl.c | 2 +- drivers/scsi/st.c | 1 - drivers/scsi/virtio_scsi.c | 1 - drivers/scsi/vmw_pvscsi.c | 2 +- drivers/scsi/wd33c93.c | 4 +- 113 files changed, 1688 insertions(+), 1943 deletions(-) (limited to 'drivers/scsi') diff --git a/drivers/scsi/FlashPoint.c b/drivers/scsi/FlashPoint.c index 3d9c56ac82..9e77b8e1ea 100644 --- a/drivers/scsi/FlashPoint.c +++ b/drivers/scsi/FlashPoint.c @@ -2631,7 +2631,6 @@ static void FPT_sres(u32 port, unsigned char p_card, WRW_HARPOON((port + hp_fiforead), (unsigned short)0x00); our_target = (unsigned char)(RD_HARPOON(port + hp_select_id) >> 4); - currTar_Info = &FPT_sccbMgrTbl[p_card][our_target]; msgRetryCount = 0; do { diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig index 634f2f501c..065db86d60 100644 --- a/drivers/scsi/Kconfig +++ b/drivers/scsi/Kconfig @@ -53,7 +53,7 @@ config SCSI_ESP_PIO config SCSI_NETLINK bool - default n + default n depends on NET config SCSI_PROC_FS @@ -327,7 +327,7 @@ config ISCSI_TCP config ISCSI_BOOT_SYSFS tristate "iSCSI Boot Sysfs Interface" - default n + default n help This option enables support for exposing iSCSI boot information via sysfs to userspace. If you wish to export this information, diff --git a/drivers/scsi/a3000.c b/drivers/scsi/a3000.c index 378906f779..ad39797890 100644 --- a/drivers/scsi/a3000.c +++ b/drivers/scsi/a3000.c @@ -295,7 +295,13 @@ static void __exit amiga_a3000_scsi_remove(struct platform_device *pdev) release_mem_region(res->start, resource_size(res)); } -static struct platform_driver amiga_a3000_scsi_driver = { +/* + * amiga_a3000_scsi_remove() lives in .exit.text. For drivers registered via + * module_platform_driver_probe() this is ok because they cannot get unbound at + * runtime. So mark the driver struct with __refdata to prevent modpost + * triggering a section mismatch warning. + */ +static struct platform_driver amiga_a3000_scsi_driver __refdata = { .remove_new = __exit_p(amiga_a3000_scsi_remove), .driver = { .name = "amiga-a3000-scsi", diff --git a/drivers/scsi/a4000t.c b/drivers/scsi/a4000t.c index e435fc06a6..d9103adc87 100644 --- a/drivers/scsi/a4000t.c +++ b/drivers/scsi/a4000t.c @@ -108,7 +108,13 @@ static void __exit amiga_a4000t_scsi_remove(struct platform_device *pdev) release_mem_region(res->start, resource_size(res)); } -static struct platform_driver amiga_a4000t_scsi_driver = { +/* + * amiga_a4000t_scsi_remove() lives in .exit.text. For drivers registered via + * module_platform_driver_probe() this is ok because they cannot get unbound at + * runtime. So mark the driver struct with __refdata to prevent modpost + * triggering a section mismatch warning. + */ +static struct platform_driver amiga_a4000t_scsi_driver __refdata = { .remove_new = __exit_p(amiga_a4000t_scsi_remove), .driver = { .name = "amiga-a4000t-scsi", diff --git a/drivers/scsi/aha152x.c b/drivers/scsi/aha152x.c index 055adb349b..83f16fc14d 100644 --- a/drivers/scsi/aha152x.c +++ b/drivers/scsi/aha152x.c @@ -746,6 +746,7 @@ struct Scsi_Host *aha152x_probe_one(struct aha152x_setup *setup) /* need to have host registered before triggering any interrupt */ list_add_tail(&HOSTDATA(shpnt)->host_list, &aha152x_host_list); + shpnt->no_highmem = true; shpnt->io_port = setup->io_port; shpnt->n_io_port = IO_RANGE; shpnt->irq = setup->irq; @@ -2940,12 +2941,6 @@ static int aha152x_show_info(struct seq_file *m, struct Scsi_Host *shpnt) return 0; } -static int aha152x_adjust_queue(struct scsi_device *device) -{ - blk_queue_bounce_limit(device->request_queue, BLK_BOUNCE_HIGH); - return 0; -} - static const struct scsi_host_template aha152x_driver_template = { .module = THIS_MODULE, .name = AHA152X_REVID, @@ -2961,7 +2956,6 @@ static const struct scsi_host_template aha152x_driver_template = { .this_id = 7, .sg_tablesize = SG_ALL, .dma_boundary = PAGE_SIZE - 1, - .slave_alloc = aha152x_adjust_queue, .cmd_size = sizeof(struct aha152x_cmd_priv), }; diff --git a/drivers/scsi/aic7xxx/Kconfig.aic79xx b/drivers/scsi/aic7xxx/Kconfig.aic79xx index 4bc53eec4c..863f0932ef 100644 --- a/drivers/scsi/aic7xxx/Kconfig.aic79xx +++ b/drivers/scsi/aic7xxx/Kconfig.aic79xx @@ -8,79 +8,80 @@ config SCSI_AIC79XX depends on PCI && HAS_IOPORT && SCSI select SCSI_SPI_ATTRS help - This driver supports all of Adaptec's Ultra 320 PCI-X - based SCSI controllers. + This driver supports all of Adaptec's Ultra 320 PCI-X + based SCSI controllers. config AIC79XX_CMDS_PER_DEVICE int "Maximum number of TCQ commands per device" depends on SCSI_AIC79XX default "32" help - Specify the number of commands you would like to allocate per SCSI - device when Tagged Command Queueing (TCQ) is enabled on that device. + Specify the number of commands you would like to allocate per SCSI + device when Tagged Command Queueing (TCQ) is enabled on that device. - This is an upper bound value for the number of tagged transactions - to be used for any device. The aic7xxx driver will automatically - vary this number based on device behavior. For devices with a - fixed maximum, the driver will eventually lock to this maximum - and display a console message indicating this value. + This is an upper bound value for the number of tagged transactions + to be used for any device. The aic7xxx driver will automatically + vary this number based on device behavior. For devices with a + fixed maximum, the driver will eventually lock to this maximum + and display a console message indicating this value. - Due to resource allocation issues in the Linux SCSI mid-layer, using - a high number of commands per device may result in memory allocation - failures when many devices are attached to the system. For this reason, - the default is set to 32. Higher values may result in higher performance - on some devices. The upper bound is 253. 0 disables tagged queueing. + Due to resource allocation issues in the Linux SCSI mid-layer, using + a high number of commands per device may result in memory allocation + failures when many devices are attached to the system. For this + reason, the default is set to 32. Higher values may result in higher + performance on some devices. The upper bound is 253. 0 disables + tagged queueing. - Per device tag depth can be controlled via the kernel command line - "tag_info" option. See Documentation/scsi/aic79xx.rst for details. + Per device tag depth can be controlled via the kernel command line + "tag_info" option. See Documentation/scsi/aic79xx.rst for details. config AIC79XX_RESET_DELAY_MS int "Initial bus reset delay in milli-seconds" depends on SCSI_AIC79XX default "5000" help - The number of milliseconds to delay after an initial bus reset. - The bus settle delay following all error recovery actions is - dictated by the SCSI layer and is not affected by this value. + The number of milliseconds to delay after an initial bus reset. + The bus settle delay following all error recovery actions is + dictated by the SCSI layer and is not affected by this value. - Default: 5000 (5 seconds) + Default: 5000 (5 seconds) config AIC79XX_BUILD_FIRMWARE bool "Build Adapter Firmware with Kernel Build" depends on SCSI_AIC79XX && !PREVENT_FIRMWARE_BUILD help - This option should only be enabled if you are modifying the firmware - source to the aic79xx driver and wish to have the generated firmware - include files updated during a normal kernel build. The assembler - for the firmware requires lex and yacc or their equivalents, as well - as the db v1 library. You may have to install additional packages - or modify the assembler Makefile or the files it includes if your - build environment is different than that of the author. + This option should only be enabled if you are modifying the firmware + source to the aic79xx driver and wish to have the generated firmware + include files updated during a normal kernel build. The assembler + for the firmware requires lex and yacc or their equivalents, as well + as the db v1 library. You may have to install additional packages + or modify the assembler Makefile or the files it includes if your + build environment is different than that of the author. config AIC79XX_DEBUG_ENABLE bool "Compile in Debugging Code" depends on SCSI_AIC79XX default y help - Compile in aic79xx debugging code that can be useful in diagnosing - driver errors. + Compile in aic79xx debugging code that can be useful in diagnosing + driver errors. config AIC79XX_DEBUG_MASK int "Debug code enable mask (16383 for all debugging)" depends on SCSI_AIC79XX default "0" help - Bit mask of debug options that is only valid if the - CONFIG_AIC79XX_DEBUG_ENABLE option is enabled. The bits in this mask - are defined in the drivers/scsi/aic7xxx/aic79xx.h - search for the - variable ahd_debug in that file to find them. + Bit mask of debug options that is only valid if the + CONFIG_AIC79XX_DEBUG_ENABLE option is enabled. The bits in this mask + are defined in the drivers/scsi/aic7xxx/aic79xx.h - search for the + variable ahd_debug in that file to find them. config AIC79XX_REG_PRETTY_PRINT bool "Decode registers during diagnostics" depends on SCSI_AIC79XX default y help - Compile in register value tables for the output of expanded register - contents in diagnostics. This make it much easier to understand debug - output without having to refer to a data book and/or the aic7xxx.reg - file. + Compile in register value tables for the output of expanded register + contents in diagnostics. This make it much easier to understand debug + output without having to refer to a data book and/or the aic7xxx.reg + file. diff --git a/drivers/scsi/aic7xxx/Kconfig.aic7xxx b/drivers/scsi/aic7xxx/Kconfig.aic7xxx index f0425145a5..8f87f2d8ba 100644 --- a/drivers/scsi/aic7xxx/Kconfig.aic7xxx +++ b/drivers/scsi/aic7xxx/Kconfig.aic7xxx @@ -8,84 +8,85 @@ config SCSI_AIC7XXX depends on (PCI || EISA) && HAS_IOPORT && SCSI select SCSI_SPI_ATTRS help - This driver supports all of Adaptec's Fast through Ultra 160 PCI - based SCSI controllers as well as the aic7770 based EISA and VLB - SCSI controllers (the 274x and 284x series). For AAA and ARO based - configurations, only SCSI functionality is provided. + This driver supports all of Adaptec's Fast through Ultra 160 PCI + based SCSI controllers as well as the aic7770 based EISA and VLB + SCSI controllers (the 274x and 284x series). For AAA and ARO based + configurations, only SCSI functionality is provided. - To compile this driver as a module, choose M here: the - module will be called aic7xxx. + To compile this driver as a module, choose M here: the + module will be called aic7xxx. config AIC7XXX_CMDS_PER_DEVICE int "Maximum number of TCQ commands per device" depends on SCSI_AIC7XXX default "32" help - Specify the number of commands you would like to allocate per SCSI - device when Tagged Command Queueing (TCQ) is enabled on that device. + Specify the number of commands you would like to allocate per SCSI + device when Tagged Command Queueing (TCQ) is enabled on that device. - This is an upper bound value for the number of tagged transactions - to be used for any device. The aic7xxx driver will automatically - vary this number based on device behavior. For devices with a - fixed maximum, the driver will eventually lock to this maximum - and display a console message indicating this value. + This is an upper bound value for the number of tagged transactions + to be used for any device. The aic7xxx driver will automatically + vary this number based on device behavior. For devices with a + fixed maximum, the driver will eventually lock to this maximum + and display a console message indicating this value. - Due to resource allocation issues in the Linux SCSI mid-layer, using - a high number of commands per device may result in memory allocation - failures when many devices are attached to the system. For this reason, - the default is set to 32. Higher values may result in higher performance - on some devices. The upper bound is 253. 0 disables tagged queueing. + Due to resource allocation issues in the Linux SCSI mid-layer, using + a high number of commands per device may result in memory allocation + failures when many devices are attached to the system. For this + reason, the default is set to 32. Higher values may result in higher + performance on some devices. The upper bound is 253. 0 disables tagged + queueing. - Per device tag depth can be controlled via the kernel command line - "tag_info" option. See Documentation/scsi/aic7xxx.rst for details. + Per device tag depth can be controlled via the kernel command line + "tag_info" option. See Documentation/scsi/aic7xxx.rst for details. config AIC7XXX_RESET_DELAY_MS int "Initial bus reset delay in milli-seconds" depends on SCSI_AIC7XXX default "5000" help - The number of milliseconds to delay after an initial bus reset. - The bus settle delay following all error recovery actions is - dictated by the SCSI layer and is not affected by this value. + The number of milliseconds to delay after an initial bus reset. + The bus settle delay following all error recovery actions is + dictated by the SCSI layer and is not affected by this value. - Default: 5000 (5 seconds) + Default: 5000 (5 seconds) config AIC7XXX_BUILD_FIRMWARE bool "Build Adapter Firmware with Kernel Build" depends on SCSI_AIC7XXX && !PREVENT_FIRMWARE_BUILD help - This option should only be enabled if you are modifying the firmware - source to the aic7xxx driver and wish to have the generated firmware - include files updated during a normal kernel build. The assembler - for the firmware requires lex and yacc or their equivalents, as well - as the db v1 library. You may have to install additional packages - or modify the assembler Makefile or the files it includes if your - build environment is different than that of the author. + This option should only be enabled if you are modifying the firmware + source to the aic7xxx driver and wish to have the generated firmware + include files updated during a normal kernel build. The assembler + for the firmware requires lex and yacc or their equivalents, as well + as the db v1 library. You may have to install additional packages + or modify the assembler Makefile or the files it includes if your + build environment is different than that of the author. config AIC7XXX_DEBUG_ENABLE bool "Compile in Debugging Code" depends on SCSI_AIC7XXX default y help - Compile in aic7xxx debugging code that can be useful in diagnosing - driver errors. + Compile in aic7xxx debugging code that can be useful in diagnosing + driver errors. config AIC7XXX_DEBUG_MASK - int "Debug code enable mask (2047 for all debugging)" - depends on SCSI_AIC7XXX - default "0" - help - Bit mask of debug options that is only valid if the - CONFIG_AIC7XXX_DEBUG_ENABLE option is enabled. The bits in this mask - are defined in the drivers/scsi/aic7xxx/aic7xxx.h - search for the - variable ahc_debug in that file to find them. + int "Debug code enable mask (2047 for all debugging)" + depends on SCSI_AIC7XXX + default "0" + help + Bit mask of debug options that is only valid if the + CONFIG_AIC7XXX_DEBUG_ENABLE option is enabled. The bits in this mask + are defined in the drivers/scsi/aic7xxx/aic7xxx.h - search for the + variable ahc_debug in that file to find them. config AIC7XXX_REG_PRETTY_PRINT - bool "Decode registers during diagnostics" - depends on SCSI_AIC7XXX + bool "Decode registers during diagnostics" + depends on SCSI_AIC7XXX default y - help - Compile in register value tables for the output of expanded register - contents in diagnostics. This make it much easier to understand debug - output without having to refer to a data book and/or the aic7xxx.reg - file. + help + Compile in register value tables for the output of expanded register + contents in diagnostics. This make it much easier to understand debug + output without having to refer to a data book and/or the aic7xxx.reg + file. diff --git a/drivers/scsi/aic7xxx/Makefile b/drivers/scsi/aic7xxx/Makefile index e0188ecd85..853c72a81a 100644 --- a/drivers/scsi/aic7xxx/Makefile +++ b/drivers/scsi/aic7xxx/Makefile @@ -55,9 +55,9 @@ aicasm-7xxx-opts-$(CONFIG_AIC7XXX_REG_PRETTY_PRINT) := \ ifeq ($(CONFIG_AIC7XXX_BUILD_FIRMWARE),y) $(obj)/aic7xxx_seq.h: $(src)/aic7xxx.seq $(src)/aic7xxx.reg $(obj)/aicasm/aicasm - $(obj)/aicasm/aicasm -I$(srctree)/$(src) -r $(obj)/aic7xxx_reg.h \ + $(obj)/aicasm/aicasm -I $(src) -r $(obj)/aic7xxx_reg.h \ $(aicasm-7xxx-opts-y) -o $(obj)/aic7xxx_seq.h \ - $(srctree)/$(src)/aic7xxx.seq + $(src)/aic7xxx.seq $(aic7xxx-gen-y): $(objtree)/$(obj)/aic7xxx_seq.h @true @@ -73,9 +73,9 @@ aicasm-79xx-opts-$(CONFIG_AIC79XX_REG_PRETTY_PRINT) := \ ifeq ($(CONFIG_AIC79XX_BUILD_FIRMWARE),y) $(obj)/aic79xx_seq.h: $(src)/aic79xx.seq $(src)/aic79xx.reg $(obj)/aicasm/aicasm - $(obj)/aicasm/aicasm -I$(srctree)/$(src) -r $(obj)/aic79xx_reg.h \ + $(obj)/aicasm/aicasm -I $(src) -r $(obj)/aic79xx_reg.h \ $(aicasm-79xx-opts-y) -o $(obj)/aic79xx_seq.h \ - $(srctree)/$(src)/aic79xx.seq + $(src)/aic79xx.seq $(aic79xx-gen-y): $(objtree)/$(obj)/aic79xx_seq.h @true @@ -83,5 +83,5 @@ else $(obj)/aic79xx_reg_print.c: $(src)/aic79xx_reg_print.c_shipped endif -$(obj)/aicasm/aicasm: $(srctree)/$(src)/aicasm/*.[chyl] - $(MAKE) -C $(srctree)/$(src)/aicasm OUTDIR=$(shell pwd)/$(obj)/aicasm/ +$(obj)/aicasm/aicasm: $(src)/aicasm/*.[chyl] + $(MAKE) -C $(src)/aicasm OUTDIR=$(shell pwd)/$(obj)/aicasm/ diff --git a/drivers/scsi/aic94xx/aic94xx_init.c b/drivers/scsi/aic94xx/aic94xx_init.c index 8a3340d8d7..538a5867e8 100644 --- a/drivers/scsi/aic94xx/aic94xx_init.c +++ b/drivers/scsi/aic94xx/aic94xx_init.c @@ -14,6 +14,7 @@ #include #include +#include #include #include "aic94xx.h" @@ -24,6 +25,7 @@ /* The format is "version.release.patchlevel" */ #define ASD_DRIVER_VERSION "1.0.3" +#define DRV_NAME "aic94xx" static int use_msi = 0; module_param_named(use_msi, use_msi, int, S_IRUGO); @@ -34,32 +36,16 @@ MODULE_PARM_DESC(use_msi, "\n" 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 const struct attribute_group *asd_sdev_groups[]; static const struct scsi_host_template aic94xx_sht = { - .module = THIS_MODULE, - /* .name is initialized */ - .name = "aic94xx", - .queuecommand = sas_queuecommand, - .dma_need_drain = ata_scsi_dma_need_drain, - .target_alloc = sas_target_alloc, - .slave_configure = sas_slave_configure, + LIBSAS_SHT_BASE .scan_finished = asd_scan_finished, .scan_start = asd_scan_start, - .change_queue_depth = sas_change_queue_depth, - .bios_param = sas_bios_param, .can_queue = 1, - .this_id = -1, .sg_tablesize = SG_ALL, - .max_sectors = SCSI_DEFAULT_MAX_SECTORS, - .eh_device_reset_handler = sas_eh_device_reset_handler, - .eh_target_reset_handler = sas_eh_target_reset_handler, - .slave_alloc = sas_slave_alloc, - .target_destroy = sas_target_destroy, - .ioctl = sas_ioctl, -#ifdef CONFIG_COMPAT - .compat_ioctl = sas_ioctl, -#endif .track_queue_depth = 1, + .sdev_groups = asd_sdev_groups, }; static int asd_map_memio(struct asd_ha_struct *asd_ha) @@ -951,6 +937,11 @@ static void asd_remove_driver_attrs(struct device_driver *driver) driver_remove_file(driver, &driver_attr_version); } +static const struct attribute_group *asd_sdev_groups[] = { + &sas_ata_sdev_attr_group, + NULL +}; + static struct sas_domain_function_template aic94xx_transport_functions = { .lldd_dev_found = asd_dev_found, .lldd_dev_gone = asd_dev_gone, diff --git a/drivers/scsi/arcmsr/arcmsr_hba.c b/drivers/scsi/arcmsr/arcmsr_hba.c index ad227e6cb1..35860c6146 100644 --- a/drivers/scsi/arcmsr/arcmsr_hba.c +++ b/drivers/scsi/arcmsr/arcmsr_hba.c @@ -1007,7 +1007,7 @@ msi_int0: goto msi_int1; } } - nvec = pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_LEGACY); + nvec = pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_INTX); if (nvec < 1) return FAILED; msi_int1: diff --git a/drivers/scsi/atari_scsi.c b/drivers/scsi/atari_scsi.c index d99e709148..742625ac7d 100644 --- a/drivers/scsi/atari_scsi.c +++ b/drivers/scsi/atari_scsi.c @@ -878,7 +878,13 @@ static void __exit atari_scsi_remove(struct platform_device *pdev) atari_stram_free(atari_dma_buffer); } -static struct platform_driver atari_scsi_driver = { +/* + * atari_scsi_remove() lives in .exit.text. For drivers registered via + * module_platform_driver_probe() this is ok because they cannot get unbound at + * runtime. So mark the driver struct with __refdata to prevent modpost + * triggering a section mismatch warning. + */ +static struct platform_driver atari_scsi_driver __refdata = { .remove_new = __exit_p(atari_scsi_remove), .driver = { .name = DRV_MODULE_NAME, diff --git a/drivers/scsi/bfa/bfad_attr.c b/drivers/scsi/bfa/bfad_attr.c index e96e4b6df2..54bc1539e1 100644 --- a/drivers/scsi/bfa/bfad_attr.c +++ b/drivers/scsi/bfa/bfad_attr.c @@ -853,13 +853,6 @@ bfad_im_hw_version_show(struct device *dev, struct device_attribute *attr, return sysfs_emit(buf, "%s\n", hw_ver); } -static ssize_t -bfad_im_drv_version_show(struct device *dev, struct device_attribute *attr, - char *buf) -{ - return sysfs_emit(buf, "%s\n", BFAD_DRIVER_VERSION); -} - static ssize_t bfad_im_optionrom_version_show(struct device *dev, struct device_attribute *attr, char *buf) @@ -901,13 +894,6 @@ bfad_im_num_of_ports_show(struct device *dev, struct device_attribute *attr, bfa_get_nports(&bfad->bfa)); } -static ssize_t -bfad_im_drv_name_show(struct device *dev, struct device_attribute *attr, - char *buf) -{ - return sysfs_emit(buf, "%s\n", BFAD_DRIVER_NAME); -} - static ssize_t bfad_im_num_of_discovered_ports_show(struct device *dev, struct device_attribute *attr, char *buf) @@ -944,15 +930,15 @@ static DEVICE_ATTR(symbolic_name, S_IRUGO, bfad_im_symbolic_name_show, NULL); static DEVICE_ATTR(hardware_version, S_IRUGO, bfad_im_hw_version_show, NULL); -static DEVICE_ATTR(driver_version, S_IRUGO, - bfad_im_drv_version_show, NULL); +static DEVICE_STRING_ATTR_RO(driver_version, S_IRUGO, + BFAD_DRIVER_VERSION); static DEVICE_ATTR(option_rom_version, S_IRUGO, bfad_im_optionrom_version_show, NULL); static DEVICE_ATTR(firmware_version, S_IRUGO, bfad_im_fw_version_show, NULL); static DEVICE_ATTR(number_of_ports, S_IRUGO, bfad_im_num_of_ports_show, NULL); -static DEVICE_ATTR(driver_name, S_IRUGO, bfad_im_drv_name_show, NULL); +static DEVICE_STRING_ATTR_RO(driver_name, S_IRUGO, BFAD_DRIVER_NAME); static DEVICE_ATTR(number_of_discovered_ports, S_IRUGO, bfad_im_num_of_discovered_ports_show, NULL); @@ -963,11 +949,11 @@ static struct attribute *bfad_im_host_attrs[] = { &dev_attr_node_name.attr, &dev_attr_symbolic_name.attr, &dev_attr_hardware_version.attr, - &dev_attr_driver_version.attr, + &dev_attr_driver_version.attr.attr, &dev_attr_option_rom_version.attr, &dev_attr_firmware_version.attr, &dev_attr_number_of_ports.attr, - &dev_attr_driver_name.attr, + &dev_attr_driver_name.attr.attr, &dev_attr_number_of_discovered_ports.attr, NULL, }; @@ -988,11 +974,11 @@ static struct attribute *bfad_im_vport_attrs[] = { &dev_attr_node_name.attr, &dev_attr_symbolic_name.attr, &dev_attr_hardware_version.attr, - &dev_attr_driver_version.attr, + &dev_attr_driver_version.attr.attr, &dev_attr_option_rom_version.attr, &dev_attr_firmware_version.attr, &dev_attr_number_of_ports.attr, - &dev_attr_driver_name.attr, + &dev_attr_driver_name.attr.attr, &dev_attr_number_of_discovered_ports.attr, NULL, }; diff --git a/drivers/scsi/bnx2fc/bnx2fc_tgt.c b/drivers/scsi/bnx2fc/bnx2fc_tgt.c index d91659811e..eb32091033 100644 --- a/drivers/scsi/bnx2fc/bnx2fc_tgt.c +++ b/drivers/scsi/bnx2fc/bnx2fc_tgt.c @@ -128,10 +128,8 @@ retry_ofld: BNX2FC_TGT_DBG(tgt, "ctx_alloc_failure, " "retry ofld..%d\n", i++); msleep_interruptible(1000); - if (i > 3) { - i = 0; + if (i > 3) goto ofld_err; - } goto retry_ofld; } goto ofld_err; diff --git a/drivers/scsi/csiostor/csio_init.c b/drivers/scsi/csiostor/csio_init.c index d649b7a2a8..9a3f2ed050 100644 --- a/drivers/scsi/csiostor/csio_init.c +++ b/drivers/scsi/csiostor/csio_init.c @@ -1185,9 +1185,6 @@ static struct pci_error_handlers csio_err_handler = { static struct pci_driver csio_pci_driver = { .name = KBUILD_MODNAME, - .driver = { - .owner = THIS_MODULE, - }, .id_table = csio_pci_tbl, .probe = csio_probe_one, .remove = csio_remove_one, diff --git a/drivers/scsi/cxlflash/lunmgt.c b/drivers/scsi/cxlflash/lunmgt.c index e0e15b44a2..52405c6462 100644 --- a/drivers/scsi/cxlflash/lunmgt.c +++ b/drivers/scsi/cxlflash/lunmgt.c @@ -216,7 +216,7 @@ void cxlflash_term_global_luns(void) /** * cxlflash_manage_lun() - handles LUN management activities * @sdev: SCSI device associated with LUN. - * @manage: Manage ioctl data structure. + * @arg: Manage ioctl data structure. * * This routine is used to notify the driver about a LUN's WWID and associate * SCSI devices (sdev) with a global LUN instance. Additionally it serves to @@ -224,9 +224,9 @@ void cxlflash_term_global_luns(void) * * Return: 0 on success, -errno on failure */ -int cxlflash_manage_lun(struct scsi_device *sdev, - struct dk_cxlflash_manage_lun *manage) +int cxlflash_manage_lun(struct scsi_device *sdev, void *arg) { + struct dk_cxlflash_manage_lun *manage = arg; struct cxlflash_cfg *cfg = shost_priv(sdev->host); struct device *dev = &cfg->dev->dev; struct llun_info *lli = NULL; diff --git a/drivers/scsi/cxlflash/main.c b/drivers/scsi/cxlflash/main.c index e8382cc5cf..e4b45b7e32 100644 --- a/drivers/scsi/cxlflash/main.c +++ b/drivers/scsi/cxlflash/main.c @@ -3280,13 +3280,13 @@ static char *decode_hioctl(unsigned int cmd) /** * cxlflash_lun_provision() - host LUN provisioning handler * @cfg: Internal structure associated with the host. - * @lunprov: Kernel copy of userspace ioctl data structure. + * @arg: Kernel copy of userspace ioctl data structure. * * Return: 0 on success, -errno on failure */ -static int cxlflash_lun_provision(struct cxlflash_cfg *cfg, - struct ht_cxlflash_lun_provision *lunprov) +static int cxlflash_lun_provision(struct cxlflash_cfg *cfg, void *arg) { + struct ht_cxlflash_lun_provision *lunprov = arg; struct afu *afu = cfg->afu; struct device *dev = &cfg->dev->dev; struct sisl_ioarcb rcb; @@ -3371,16 +3371,16 @@ out: /** * cxlflash_afu_debug() - host AFU debug handler * @cfg: Internal structure associated with the host. - * @afu_dbg: Kernel copy of userspace ioctl data structure. + * @arg: Kernel copy of userspace ioctl data structure. * * For debug requests requiring a data buffer, always provide an aligned * (cache line) buffer to the AFU to appease any alignment requirements. * * Return: 0 on success, -errno on failure */ -static int cxlflash_afu_debug(struct cxlflash_cfg *cfg, - struct ht_cxlflash_afu_debug *afu_dbg) +static int cxlflash_afu_debug(struct cxlflash_cfg *cfg, void *arg) { + struct ht_cxlflash_afu_debug *afu_dbg = arg; struct afu *afu = cfg->afu; struct device *dev = &cfg->dev->dev; struct sisl_ioarcb rcb; @@ -3494,10 +3494,8 @@ static long cxlflash_chr_ioctl(struct file *file, unsigned int cmd, size_t size; hioctl ioctl; } ioctl_tbl[] = { /* NOTE: order matters here */ - { sizeof(struct ht_cxlflash_lun_provision), - (hioctl)cxlflash_lun_provision }, - { sizeof(struct ht_cxlflash_afu_debug), - (hioctl)cxlflash_afu_debug }, + { sizeof(struct ht_cxlflash_lun_provision), cxlflash_lun_provision }, + { sizeof(struct ht_cxlflash_afu_debug), cxlflash_afu_debug }, }; /* Hold read semaphore so we can drain if needed */ diff --git a/drivers/scsi/cxlflash/superpipe.c b/drivers/scsi/cxlflash/superpipe.c index e1b55b03e8..2d356fe245 100644 --- a/drivers/scsi/cxlflash/superpipe.c +++ b/drivers/scsi/cxlflash/superpipe.c @@ -729,8 +729,7 @@ out: return rc; } -int cxlflash_disk_release(struct scsi_device *sdev, - struct dk_cxlflash_release *release) +int cxlflash_disk_release(struct scsi_device *sdev, void *release) { return _cxlflash_disk_release(sdev, NULL, release); } @@ -955,8 +954,7 @@ out: return rc; } -static int cxlflash_disk_detach(struct scsi_device *sdev, - struct dk_cxlflash_detach *detach) +static int cxlflash_disk_detach(struct scsi_device *sdev, void *detach) { return _cxlflash_disk_detach(sdev, NULL, detach); } @@ -1305,7 +1303,7 @@ retry: /** * cxlflash_disk_attach() - attach a LUN to a context * @sdev: SCSI device associated with LUN. - * @attach: Attach ioctl data structure. + * @arg: Attach ioctl data structure. * * Creates a context and attaches LUN to it. A LUN can only be attached * one time to a context (subsequent attaches for the same context/LUN pair @@ -1314,9 +1312,9 @@ retry: * * Return: 0 on success, -errno on failure */ -static int cxlflash_disk_attach(struct scsi_device *sdev, - struct dk_cxlflash_attach *attach) +static int cxlflash_disk_attach(struct scsi_device *sdev, void *arg) { + struct dk_cxlflash_attach *attach = arg; struct cxlflash_cfg *cfg = shost_priv(sdev->host); struct device *dev = &cfg->dev->dev; struct afu *afu = cfg->afu; @@ -1621,7 +1619,7 @@ err1: /** * cxlflash_afu_recover() - initiates AFU recovery * @sdev: SCSI device associated with LUN. - * @recover: Recover ioctl data structure. + * @arg: Recover ioctl data structure. * * Only a single recovery is allowed at a time to avoid exhausting CXL * resources (leading to recovery failure) in the event that we're up @@ -1648,9 +1646,9 @@ err1: * * Return: 0 on success, -errno on failure */ -static int cxlflash_afu_recover(struct scsi_device *sdev, - struct dk_cxlflash_recover_afu *recover) +static int cxlflash_afu_recover(struct scsi_device *sdev, void *arg) { + struct dk_cxlflash_recover_afu *recover = arg; struct cxlflash_cfg *cfg = shost_priv(sdev->host); struct device *dev = &cfg->dev->dev; struct llun_info *lli = sdev->hostdata; @@ -1829,13 +1827,13 @@ out: /** * cxlflash_disk_verify() - verifies a LUN is the same and handle size changes * @sdev: SCSI device associated with LUN. - * @verify: Verify ioctl data structure. + * @arg: Verify ioctl data structure. * * Return: 0 on success, -errno on failure */ -static int cxlflash_disk_verify(struct scsi_device *sdev, - struct dk_cxlflash_verify *verify) +static int cxlflash_disk_verify(struct scsi_device *sdev, void *arg) { + struct dk_cxlflash_verify *verify = arg; int rc = 0; struct ctx_info *ctxi = NULL; struct cxlflash_cfg *cfg = shost_priv(sdev->host); @@ -2111,16 +2109,16 @@ int cxlflash_ioctl(struct scsi_device *sdev, unsigned int cmd, void __user *arg) size_t size; sioctl ioctl; } ioctl_tbl[] = { /* NOTE: order matters here */ - {sizeof(struct dk_cxlflash_attach), (sioctl)cxlflash_disk_attach}, + {sizeof(struct dk_cxlflash_attach), cxlflash_disk_attach}, {sizeof(struct dk_cxlflash_udirect), cxlflash_disk_direct_open}, - {sizeof(struct dk_cxlflash_release), (sioctl)cxlflash_disk_release}, - {sizeof(struct dk_cxlflash_detach), (sioctl)cxlflash_disk_detach}, - {sizeof(struct dk_cxlflash_verify), (sioctl)cxlflash_disk_verify}, - {sizeof(struct dk_cxlflash_recover_afu), (sioctl)cxlflash_afu_recover}, - {sizeof(struct dk_cxlflash_manage_lun), (sioctl)cxlflash_manage_lun}, + {sizeof(struct dk_cxlflash_release), cxlflash_disk_release}, + {sizeof(struct dk_cxlflash_detach), cxlflash_disk_detach}, + {sizeof(struct dk_cxlflash_verify), cxlflash_disk_verify}, + {sizeof(struct dk_cxlflash_recover_afu), cxlflash_afu_recover}, + {sizeof(struct dk_cxlflash_manage_lun), cxlflash_manage_lun}, {sizeof(struct dk_cxlflash_uvirtual), cxlflash_disk_virtual_open}, - {sizeof(struct dk_cxlflash_resize), (sioctl)cxlflash_vlun_resize}, - {sizeof(struct dk_cxlflash_clone), (sioctl)cxlflash_disk_clone}, + {sizeof(struct dk_cxlflash_resize), cxlflash_vlun_resize}, + {sizeof(struct dk_cxlflash_clone), cxlflash_disk_clone}, }; /* Hold read semaphore so we can drain if needed */ diff --git a/drivers/scsi/cxlflash/superpipe.h b/drivers/scsi/cxlflash/superpipe.h index 0e3b459640..fe8c975d13 100644 --- a/drivers/scsi/cxlflash/superpipe.h +++ b/drivers/scsi/cxlflash/superpipe.h @@ -114,18 +114,16 @@ struct cxlflash_global { struct page *err_page; /* One page of all 0xF for error notification */ }; -int cxlflash_vlun_resize(struct scsi_device *sdev, - struct dk_cxlflash_resize *resize); +int cxlflash_vlun_resize(struct scsi_device *sdev, void *resize); int _cxlflash_vlun_resize(struct scsi_device *sdev, struct ctx_info *ctxi, struct dk_cxlflash_resize *resize); int cxlflash_disk_release(struct scsi_device *sdev, - struct dk_cxlflash_release *release); + void *release); int _cxlflash_disk_release(struct scsi_device *sdev, struct ctx_info *ctxi, struct dk_cxlflash_release *release); -int cxlflash_disk_clone(struct scsi_device *sdev, - struct dk_cxlflash_clone *clone); +int cxlflash_disk_clone(struct scsi_device *sdev, void *arg); int cxlflash_disk_virtual_open(struct scsi_device *sdev, void *arg); @@ -145,8 +143,7 @@ void rhte_checkin(struct ctx_info *ctxi, struct sisl_rht_entry *rhte); void cxlflash_ba_terminate(struct ba_lun *ba_lun); -int cxlflash_manage_lun(struct scsi_device *sdev, - struct dk_cxlflash_manage_lun *manage); +int cxlflash_manage_lun(struct scsi_device *sdev, void *manage); int check_state(struct cxlflash_cfg *cfg); diff --git a/drivers/scsi/cxlflash/vlun.c b/drivers/scsi/cxlflash/vlun.c index cbd5a648a1..35326e3119 100644 --- a/drivers/scsi/cxlflash/vlun.c +++ b/drivers/scsi/cxlflash/vlun.c @@ -819,8 +819,7 @@ out: return rc; } -int cxlflash_vlun_resize(struct scsi_device *sdev, - struct dk_cxlflash_resize *resize) +int cxlflash_vlun_resize(struct scsi_device *sdev, void *resize) { return _cxlflash_vlun_resize(sdev, NULL, resize); } @@ -1178,7 +1177,7 @@ err: /** * cxlflash_disk_clone() - clone a context by making snapshot of another * @sdev: SCSI device associated with LUN owning virtual LUN. - * @clone: Clone ioctl data structure. + * @arg: Clone ioctl data structure. * * This routine effectively performs cxlflash_disk_open operation for each * in-use virtual resource in the source context. Note that the destination @@ -1187,9 +1186,9 @@ err: * * Return: 0 on success, -errno on failure */ -int cxlflash_disk_clone(struct scsi_device *sdev, - struct dk_cxlflash_clone *clone) +int cxlflash_disk_clone(struct scsi_device *sdev, void *arg) { + struct dk_cxlflash_clone *clone = arg; struct cxlflash_cfg *cfg = shost_priv(sdev->host); struct device *dev = &cfg->dev->dev; struct llun_info *lli = sdev->hostdata; diff --git a/drivers/scsi/hisi_sas/hisi_sas.h b/drivers/scsi/hisi_sas/hisi_sas.h index 1e4550156b..d223f48248 100644 --- a/drivers/scsi/hisi_sas/hisi_sas.h +++ b/drivers/scsi/hisi_sas/hisi_sas.h @@ -643,7 +643,8 @@ extern int hisi_sas_probe(struct platform_device *pdev, const struct hisi_sas_hw *ops); extern void hisi_sas_remove(struct platform_device *pdev); -extern int hisi_sas_slave_configure(struct scsi_device *sdev); +int hisi_sas_device_configure(struct scsi_device *sdev, + struct queue_limits *lim); extern int hisi_sas_slave_alloc(struct scsi_device *sdev); extern int hisi_sas_scan_finished(struct Scsi_Host *shost, unsigned long time); extern void hisi_sas_scan_start(struct Scsi_Host *shost); diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c index 35f8e00850..ec1a3e7ee9 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_main.c +++ b/drivers/scsi/hisi_sas/hisi_sas_main.c @@ -868,10 +868,11 @@ err_out: return rc; } -int hisi_sas_slave_configure(struct scsi_device *sdev) +int hisi_sas_device_configure(struct scsi_device *sdev, + struct queue_limits *lim) { struct domain_device *dev = sdev_to_domain_dev(sdev); - int ret = sas_slave_configure(sdev); + int ret = sas_device_configure(sdev, lim); if (ret) return ret; @@ -880,7 +881,7 @@ int hisi_sas_slave_configure(struct scsi_device *sdev) return 0; } -EXPORT_SYMBOL_GPL(hisi_sas_slave_configure); +EXPORT_SYMBOL_GPL(hisi_sas_device_configure); void hisi_sas_scan_start(struct Scsi_Host *shost) { diff --git a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c index 3c555579f9..71b5008c35 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c +++ b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c @@ -1735,28 +1735,12 @@ static struct attribute *host_v1_hw_attrs[] = { ATTRIBUTE_GROUPS(host_v1_hw); static const struct scsi_host_template sht_v1_hw = { - .name = DRV_NAME, - .proc_name = DRV_NAME, - .module = THIS_MODULE, - .queuecommand = sas_queuecommand, - .dma_need_drain = ata_scsi_dma_need_drain, - .target_alloc = sas_target_alloc, - .slave_configure = hisi_sas_slave_configure, + LIBSAS_SHT_BASE_NO_SLAVE_INIT + .device_configure = hisi_sas_device_configure, .scan_finished = hisi_sas_scan_finished, .scan_start = hisi_sas_scan_start, - .change_queue_depth = sas_change_queue_depth, - .bios_param = sas_bios_param, - .this_id = -1, .sg_tablesize = HISI_SAS_SGE_PAGE_CNT, - .max_sectors = SCSI_DEFAULT_MAX_SECTORS, - .eh_device_reset_handler = sas_eh_device_reset_handler, - .eh_target_reset_handler = sas_eh_target_reset_handler, .slave_alloc = hisi_sas_slave_alloc, - .target_destroy = sas_target_destroy, - .ioctl = sas_ioctl, -#ifdef CONFIG_COMPAT - .compat_ioctl = sas_ioctl, -#endif .shost_groups = host_v1_hw_groups, .host_reset = hisi_sas_host_reset, }; diff --git a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c index 73b378837d..342d75f120 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c +++ b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c @@ -3544,6 +3544,11 @@ static struct attribute *host_v2_hw_attrs[] = { ATTRIBUTE_GROUPS(host_v2_hw); +static const struct attribute_group *sdev_groups_v2_hw[] = { + &sas_ata_sdev_attr_group, + NULL +}; + static void map_queues_v2_hw(struct Scsi_Host *shost) { struct hisi_hba *hisi_hba = shost_priv(shost); @@ -3562,29 +3567,14 @@ static void map_queues_v2_hw(struct Scsi_Host *shost) } static const struct scsi_host_template sht_v2_hw = { - .name = DRV_NAME, - .proc_name = DRV_NAME, - .module = THIS_MODULE, - .queuecommand = sas_queuecommand, - .dma_need_drain = ata_scsi_dma_need_drain, - .target_alloc = sas_target_alloc, - .slave_configure = hisi_sas_slave_configure, + LIBSAS_SHT_BASE_NO_SLAVE_INIT + .device_configure = hisi_sas_device_configure, .scan_finished = hisi_sas_scan_finished, .scan_start = hisi_sas_scan_start, - .change_queue_depth = sas_change_queue_depth, - .bios_param = sas_bios_param, - .this_id = -1, .sg_tablesize = HISI_SAS_SGE_PAGE_CNT, - .max_sectors = SCSI_DEFAULT_MAX_SECTORS, - .eh_device_reset_handler = sas_eh_device_reset_handler, - .eh_target_reset_handler = sas_eh_target_reset_handler, .slave_alloc = hisi_sas_slave_alloc, - .target_destroy = sas_target_destroy, - .ioctl = sas_ioctl, -#ifdef CONFIG_COMPAT - .compat_ioctl = sas_ioctl, -#endif .shost_groups = host_v2_hw_groups, + .sdev_groups = sdev_groups_v2_hw, .host_reset = hisi_sas_host_reset, .map_queues = map_queues_v2_hw, .host_tagset = 1, diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c index 34f96cc353..feda9b54b4 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c @@ -2902,11 +2902,12 @@ static ssize_t iopoll_q_cnt_v3_hw_show(struct device *dev, } static DEVICE_ATTR_RO(iopoll_q_cnt_v3_hw); -static int slave_configure_v3_hw(struct scsi_device *sdev) +static int device_configure_v3_hw(struct scsi_device *sdev, + struct queue_limits *lim) { struct Scsi_Host *shost = dev_to_shost(&sdev->sdev_gendev); struct hisi_hba *hisi_hba = shost_priv(shost); - int ret = hisi_sas_slave_configure(sdev); + int ret = hisi_sas_device_configure(sdev, lim); struct device *dev = hisi_hba->dev; if (ret) @@ -2937,6 +2938,11 @@ static struct attribute *host_v3_hw_attrs[] = { ATTRIBUTE_GROUPS(host_v3_hw); +static const struct attribute_group *sdev_groups_v3_hw[] = { + &sas_ata_sdev_attr_group, + NULL +}; + #define HISI_SAS_DEBUGFS_REG(x) {#x, x} struct hisi_sas_debugfs_reg_lu { @@ -3323,31 +3329,16 @@ static void hisi_sas_map_queues(struct Scsi_Host *shost) } static const struct scsi_host_template sht_v3_hw = { - .name = DRV_NAME, - .proc_name = DRV_NAME, - .module = THIS_MODULE, - .queuecommand = sas_queuecommand, - .dma_need_drain = ata_scsi_dma_need_drain, - .target_alloc = sas_target_alloc, - .slave_configure = slave_configure_v3_hw, + LIBSAS_SHT_BASE_NO_SLAVE_INIT + .device_configure = device_configure_v3_hw, .scan_finished = hisi_sas_scan_finished, .scan_start = hisi_sas_scan_start, .map_queues = hisi_sas_map_queues, - .change_queue_depth = sas_change_queue_depth, - .bios_param = sas_bios_param, - .this_id = -1, .sg_tablesize = HISI_SAS_SGE_PAGE_CNT, .sg_prot_tablesize = HISI_SAS_SGE_PAGE_CNT, - .max_sectors = SCSI_DEFAULT_MAX_SECTORS, - .eh_device_reset_handler = sas_eh_device_reset_handler, - .eh_target_reset_handler = sas_eh_target_reset_handler, .slave_alloc = hisi_sas_slave_alloc, - .target_destroy = sas_target_destroy, - .ioctl = sas_ioctl, -#ifdef CONFIG_COMPAT - .compat_ioctl = sas_ioctl, -#endif .shost_groups = host_v3_hw_groups, + .sdev_groups = sdev_groups_v3_hw, .tag_alloc_policy = BLK_TAG_ALLOC_RR, .host_reset = hisi_sas_host_reset, .host_tagset = 1, diff --git a/drivers/scsi/hosts.c b/drivers/scsi/hosts.c index 2d92549e52..7f987335b4 100644 --- a/drivers/scsi/hosts.c +++ b/drivers/scsi/hosts.c @@ -479,6 +479,12 @@ struct Scsi_Host *scsi_host_alloc(const struct scsi_host_template *sht, int priv else shost->max_segment_size = BLK_MAX_SEGMENT_SIZE; + /* 32-byte (dword) is a common minimum for HBAs. */ + if (sht->dma_alignment) + shost->dma_alignment = sht->dma_alignment; + else + shost->dma_alignment = 3; + /* * assume a 4GB boundary, if not set */ diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c index 49c57a9c11..e044ed09d7 100644 --- a/drivers/scsi/hpsa.c +++ b/drivers/scsi/hpsa.c @@ -7509,7 +7509,7 @@ fallback: */ static int hpsa_interrupt_mode(struct ctlr_info *h) { - unsigned int flags = PCI_IRQ_LEGACY; + unsigned int flags = PCI_IRQ_INTX; int ret; /* Some boards advertise MSI but don't really support it */ diff --git a/drivers/scsi/hptiop.c b/drivers/scsi/hptiop.c index f5334ccbf2..e889f26860 100644 --- a/drivers/scsi/hptiop.c +++ b/drivers/scsi/hptiop.c @@ -1151,11 +1151,11 @@ static struct attribute *hptiop_host_attrs[] = { ATTRIBUTE_GROUPS(hptiop_host); -static int hptiop_slave_config(struct scsi_device *sdev) +static int hptiop_device_configure(struct scsi_device *sdev, + struct queue_limits *lim) { if (sdev->type == TYPE_TAPE) - blk_queue_max_hw_sectors(sdev->request_queue, 8192); - + lim->max_hw_sectors = 8192; return 0; } @@ -1168,7 +1168,7 @@ static const struct scsi_host_template driver_template = { .emulated = 0, .proc_name = driver_name, .shost_groups = hptiop_host_groups, - .slave_configure = hptiop_slave_config, + .device_configure = hptiop_device_configure, .this_id = -1, .change_queue_depth = hptiop_adjust_disk_queue_depth, .cmd_size = sizeof(struct hpt_cmd_priv), diff --git a/drivers/scsi/ibmvscsi/ibmvfc.c b/drivers/scsi/ibmvscsi/ibmvfc.c index 05b126bfd1..a3d1013c83 100644 --- a/drivers/scsi/ibmvscsi/ibmvfc.c +++ b/drivers/scsi/ibmvscsi/ibmvfc.c @@ -5541,8 +5541,6 @@ static void ibmvfc_tgt_add_rport(struct ibmvfc_target *tgt) rport->supported_classes |= FC_COS_CLASS2; if (be32_to_cpu(tgt->service_parms.class3_parms[0]) & 0x80000000) rport->supported_classes |= FC_COS_CLASS3; - if (rport->rqst_q) - blk_queue_max_segments(rport->rqst_q, 1); } else tgt_dbg(tgt, "rport add failed\n"); spin_unlock_irqrestore(vhost->host->host_lock, flags); @@ -6391,8 +6389,6 @@ static int ibmvfc_probe(struct vio_dev *vdev, const struct vio_device_id *id) ibmvfc_init_sub_crqs(vhost); - if (shost_to_fc_host(shost)->rqst_q) - blk_queue_max_segments(shost_to_fc_host(shost)->rqst_q, 1); dev_set_drvdata(dev, vhost); spin_lock(&ibmvfc_driver_lock); list_add_tail(&vhost->queue, &ibmvfc_head); @@ -6547,6 +6543,7 @@ static struct fc_function_template ibmvfc_transport_functions = { .get_starget_port_id = ibmvfc_get_starget_port_id, .show_starget_port_id = 1, + .max_bsg_segments = 1, .bsg_request = ibmvfc_bsg_request, .bsg_timeout = ibmvfc_bsg_timeout, }; diff --git a/drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c b/drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c index 68b99924ee..2fca17cf8b 100644 --- a/drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c +++ b/drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c @@ -3613,12 +3613,6 @@ static void ibmvscsis_remove(struct vio_dev *vdev) kfree(vscsi); } -static ssize_t system_id_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - return sysfs_emit(buf, "%s\n", system_id); -} - static ssize_t partition_number_show(struct device *dev, struct device_attribute *attr, char *buf) { @@ -3982,8 +3976,7 @@ static const struct target_core_fabric_ops ibmvscsis_ops = { static void ibmvscsis_dev_release(struct device *dev) {}; -static struct device_attribute dev_attr_system_id = - __ATTR(system_id, S_IRUGO, system_id_show, NULL); +static DEVICE_STRING_ATTR_RO(system_id, S_IRUGO, system_id); static struct device_attribute dev_attr_partition_number = __ATTR(partition_number, S_IRUGO, partition_number_show, NULL); @@ -3992,7 +3985,7 @@ static struct device_attribute dev_attr_unit_address = __ATTR(unit_address, S_IRUGO, unit_address_show, NULL); static struct attribute *ibmvscsis_dev_attrs[] = { - &dev_attr_system_id.attr, + &dev_attr_system_id.attr.attr, &dev_attr_partition_number.attr, &dev_attr_unit_address.attr, }; diff --git a/drivers/scsi/imm.c b/drivers/scsi/imm.c index 180a5ddedb..21339da505 100644 --- a/drivers/scsi/imm.c +++ b/drivers/scsi/imm.c @@ -1100,16 +1100,6 @@ static int device_check(imm_struct *dev, bool autodetect) return -ENODEV; } -/* - * imm cannot deal with highmem, so this causes all IO pages for this host - * to reside in low memory (hence mapped) - */ -static int imm_adjust_queue(struct scsi_device *device) -{ - blk_queue_bounce_limit(device->request_queue, BLK_BOUNCE_HIGH); - return 0; -} - static const struct scsi_host_template imm_template = { .module = THIS_MODULE, .proc_name = "imm", @@ -1123,7 +1113,6 @@ static const struct scsi_host_template imm_template = { .this_id = 7, .sg_tablesize = SG_ALL, .can_queue = 1, - .slave_alloc = imm_adjust_queue, .cmd_size = sizeof(struct scsi_pointer), }; @@ -1235,6 +1224,7 @@ static int __imm_attach(struct parport *pb) host = scsi_host_alloc(&imm_template, sizeof(imm_struct *)); if (!host) goto out1; + host->no_highmem = true; host->io_port = pb->base; host->n_io_port = ports; host->dma_channel = -1; diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c index 3819f7c427..31cf2d31cc 100644 --- a/drivers/scsi/ipr.c +++ b/drivers/scsi/ipr.c @@ -4769,15 +4769,17 @@ static void ipr_slave_destroy(struct scsi_device *sdev) } /** - * ipr_slave_configure - Configure a SCSI device + * ipr_device_configure - Configure a SCSI device * @sdev: scsi device struct + * @lim: queue limits * * This function configures the specified scsi device. * * Return value: * 0 on success **/ -static int ipr_slave_configure(struct scsi_device *sdev) +static int ipr_device_configure(struct scsi_device *sdev, + struct queue_limits *lim) { struct ipr_ioa_cfg *ioa_cfg = (struct ipr_ioa_cfg *) sdev->host->hostdata; struct ipr_resource_entry *res; @@ -4798,7 +4800,7 @@ static int ipr_slave_configure(struct scsi_device *sdev) sdev->no_report_opcodes = 1; blk_queue_rq_timeout(sdev->request_queue, IPR_VSET_RW_TIMEOUT); - blk_queue_max_hw_sectors(sdev->request_queue, IPR_VSET_MAX_SECTORS); + lim->max_hw_sectors = IPR_VSET_MAX_SECTORS; } spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); @@ -6397,7 +6399,7 @@ static const struct scsi_host_template driver_template = { .eh_device_reset_handler = ipr_eh_dev_reset, .eh_host_reset_handler = ipr_eh_host_reset, .slave_alloc = ipr_slave_alloc, - .slave_configure = ipr_slave_configure, + .device_configure = ipr_device_configure, .slave_destroy = ipr_slave_destroy, .scan_finished = ipr_scan_finished, .target_destroy = ipr_target_destroy, @@ -9463,7 +9465,7 @@ static int ipr_probe_ioa(struct pci_dev *pdev, ipr_number_of_msix = IPR_MAX_MSIX_VECTORS; } - irq_flag = PCI_IRQ_LEGACY; + irq_flag = PCI_IRQ_INTX; if (ioa_cfg->ipr_chip->has_msi) irq_flag |= PCI_IRQ_MSI | PCI_IRQ_MSIX; rc = pci_alloc_irq_vectors(pdev, 1, ipr_number_of_msix, irq_flag); diff --git a/drivers/scsi/isci/init.c b/drivers/scsi/isci/init.c index c582a3932c..de2aefcf20 100644 --- a/drivers/scsi/isci/init.c +++ b/drivers/scsi/isci/init.c @@ -149,33 +149,20 @@ static struct attribute *isci_host_attrs[] = { ATTRIBUTE_GROUPS(isci_host); -static const struct scsi_host_template isci_sht = { +static const struct attribute_group *isci_sdev_groups[] = { + &sas_ata_sdev_attr_group, + NULL +}; - .module = THIS_MODULE, - .name = DRV_NAME, - .proc_name = DRV_NAME, - .queuecommand = sas_queuecommand, - .dma_need_drain = ata_scsi_dma_need_drain, - .target_alloc = sas_target_alloc, - .slave_configure = sas_slave_configure, +static const struct scsi_host_template isci_sht = { + LIBSAS_SHT_BASE .scan_finished = isci_host_scan_finished, .scan_start = isci_host_start, - .change_queue_depth = sas_change_queue_depth, - .bios_param = sas_bios_param, .can_queue = ISCI_CAN_QUEUE_VAL, - .this_id = -1, .sg_tablesize = SG_ALL, - .max_sectors = SCSI_DEFAULT_MAX_SECTORS, - .eh_abort_handler = sas_eh_abort_handler, - .eh_device_reset_handler = sas_eh_device_reset_handler, - .eh_target_reset_handler = sas_eh_target_reset_handler, - .slave_alloc = sas_slave_alloc, - .target_destroy = sas_target_destroy, - .ioctl = sas_ioctl, -#ifdef CONFIG_COMPAT - .compat_ioctl = sas_ioctl, -#endif + .eh_abort_handler = sas_eh_abort_handler, .shost_groups = isci_host_groups, + .sdev_groups = isci_sdev_groups, .track_queue_depth = 1, }; diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c index 8e14cea15f..60688f18fa 100644 --- a/drivers/scsi/iscsi_tcp.c +++ b/drivers/scsi/iscsi_tcp.c @@ -943,6 +943,7 @@ iscsi_sw_tcp_session_create(struct iscsi_endpoint *ep, uint16_t cmds_max, shost->max_id = 0; shost->max_channel = 0; shost->max_cmd_len = SCSI_MAX_VARLEN_CDB_SIZE; + shost->dma_alignment = 0; rc = iscsi_host_get_max_scsi_cmds(shost, cmds_max); if (rc < 0) @@ -1065,7 +1066,6 @@ static int iscsi_sw_tcp_slave_configure(struct scsi_device *sdev) if (conn->datadgst_en) blk_queue_flag_set(QUEUE_FLAG_STABLE_WRITES, sdev->request_queue); - blk_queue_dma_alignment(sdev->request_queue, 0); return 0; } diff --git a/drivers/scsi/libsas/sas_ata.c b/drivers/scsi/libsas/sas_ata.c index 70891a1e98..cbbe43d8ef 100644 --- a/drivers/scsi/libsas/sas_ata.c +++ b/drivers/scsi/libsas/sas_ata.c @@ -964,3 +964,87 @@ int sas_execute_ata_cmd(struct domain_device *device, u8 *fis, int force_phy_id) force_phy_id, &tmf_task); } EXPORT_SYMBOL_GPL(sas_execute_ata_cmd); + +static ssize_t sas_ncq_prio_supported_show(struct device *device, + struct device_attribute *attr, + char *buf) +{ + struct scsi_device *sdev = to_scsi_device(device); + struct domain_device *ddev = sdev_to_domain_dev(sdev); + bool supported; + int rc; + + rc = ata_ncq_prio_supported(ddev->sata_dev.ap, sdev, &supported); + if (rc) + return rc; + + return sysfs_emit(buf, "%d\n", supported); +} + +static struct device_attribute dev_attr_sas_ncq_prio_supported = + __ATTR(ncq_prio_supported, S_IRUGO, sas_ncq_prio_supported_show, NULL); + +static ssize_t sas_ncq_prio_enable_show(struct device *device, + struct device_attribute *attr, + char *buf) +{ + struct scsi_device *sdev = to_scsi_device(device); + struct domain_device *ddev = sdev_to_domain_dev(sdev); + bool enabled; + int rc; + + rc = ata_ncq_prio_enabled(ddev->sata_dev.ap, sdev, &enabled); + if (rc) + return rc; + + return sysfs_emit(buf, "%d\n", enabled); +} + +static ssize_t sas_ncq_prio_enable_store(struct device *device, + struct device_attribute *attr, + const char *buf, size_t len) +{ + struct scsi_device *sdev = to_scsi_device(device); + struct domain_device *ddev = sdev_to_domain_dev(sdev); + bool enable; + int rc; + + rc = kstrtobool(buf, &enable); + if (rc) + return rc; + + rc = ata_ncq_prio_enable(ddev->sata_dev.ap, sdev, enable); + if (rc) + return rc; + + return len; +} + +static struct device_attribute dev_attr_sas_ncq_prio_enable = + __ATTR(ncq_prio_enable, S_IRUGO | S_IWUSR, + sas_ncq_prio_enable_show, sas_ncq_prio_enable_store); + +static struct attribute *sas_ata_sdev_attrs[] = { + &dev_attr_sas_ncq_prio_supported.attr, + &dev_attr_sas_ncq_prio_enable.attr, + NULL +}; + +static umode_t sas_ata_attr_is_visible(struct kobject *kobj, + struct attribute *attr, int i) +{ + struct device *dev = kobj_to_dev(kobj); + struct scsi_device *sdev = to_scsi_device(dev); + struct domain_device *ddev = sdev_to_domain_dev(sdev); + + if (!dev_is_sata(ddev)) + return 0; + + return attr->mode; +} + +const struct attribute_group sas_ata_sdev_attr_group = { + .attrs = sas_ata_sdev_attrs, + .is_visible = sas_ata_attr_is_visible, +}; +EXPORT_SYMBOL_GPL(sas_ata_sdev_attr_group); diff --git a/drivers/scsi/libsas/sas_expander.c b/drivers/scsi/libsas/sas_expander.c index e97f4e01a8..4e6bb3d0f1 100644 --- a/drivers/scsi/libsas/sas_expander.c +++ b/drivers/scsi/libsas/sas_expander.c @@ -26,6 +26,28 @@ static int sas_configure_phy(struct domain_device *dev, int phy_id, u8 *sas_addr, int include); static int sas_disable_routing(struct domain_device *dev, u8 *sas_addr); +static void sas_port_add_ex_phy(struct sas_port *port, struct ex_phy *ex_phy) +{ + sas_port_add_phy(port, ex_phy->phy); + ex_phy->port = port; + ex_phy->phy_state = PHY_DEVICE_DISCOVERED; +} + +static void sas_ex_add_parent_port(struct domain_device *dev, int phy_id) +{ + struct expander_device *ex = &dev->ex_dev; + struct ex_phy *ex_phy = &ex->ex_phy[phy_id]; + + if (!ex->parent_port) { + ex->parent_port = sas_port_alloc(&dev->rphy->dev, phy_id); + /* FIXME: error handling */ + BUG_ON(!ex->parent_port); + BUG_ON(sas_port_add(ex->parent_port)); + sas_port_mark_backlink(ex->parent_port); + } + sas_port_add_ex_phy(ex->parent_port, ex_phy); +} + /* ---------- SMP task management ---------- */ /* Give it some long enough timeout. In seconds. */ @@ -856,9 +878,7 @@ static bool sas_ex_join_wide_port(struct domain_device *parent, int phy_id) if (!memcmp(phy->attached_sas_addr, ephy->attached_sas_addr, SAS_ADDR_SIZE) && ephy->port) { - sas_port_add_phy(ephy->port, phy->phy); - phy->port = ephy->port; - phy->phy_state = PHY_DEVICE_DISCOVERED; + sas_port_add_ex_phy(ephy->port, phy); return true; } } @@ -962,11 +982,11 @@ static int sas_ex_discover_dev(struct domain_device *dev, int phy_id) /* Parent and domain coherency */ if (!dev->parent && sas_phy_match_port_addr(dev->port, ex_phy)) { - sas_add_parent_port(dev, phy_id); + sas_ex_add_parent_port(dev, phy_id); return 0; } if (dev->parent && sas_phy_match_dev_addr(dev->parent, ex_phy)) { - sas_add_parent_port(dev, phy_id); + sas_ex_add_parent_port(dev, phy_id); if (ex_phy->routing_attr == TABLE_ROUTING) sas_configure_phy(dev, phy_id, dev->port->sas_addr, 1); return 0; @@ -1848,9 +1868,12 @@ static void sas_unregister_devs_sas_addr(struct domain_device *parent, if (phy->port) { sas_port_delete_phy(phy->port, phy->phy); sas_device_set_phy(found, phy->port); - if (phy->port->num_phys == 0) + if (phy->port->num_phys == 0) { list_add_tail(&phy->port->del_list, &parent->port->sas_port_del_list); + if (ex_dev->parent_port == phy->port) + ex_dev->parent_port = NULL; + } phy->port = NULL; } } diff --git a/drivers/scsi/libsas/sas_internal.h b/drivers/scsi/libsas/sas_internal.h index 164086c582..03d6ec1eb9 100644 --- a/drivers/scsi/libsas/sas_internal.h +++ b/drivers/scsi/libsas/sas_internal.h @@ -203,21 +203,6 @@ static inline void sas_phy_set_target(struct asd_sas_phy *p, struct domain_devic } } -static inline void sas_add_parent_port(struct domain_device *dev, int phy_id) -{ - struct expander_device *ex = &dev->ex_dev; - struct ex_phy *ex_phy = &ex->ex_phy[phy_id]; - - if (!ex->parent_port) { - ex->parent_port = sas_port_alloc(&dev->rphy->dev, phy_id); - /* FIXME: error handling */ - BUG_ON(!ex->parent_port); - BUG_ON(sas_port_add(ex->parent_port)); - sas_port_mark_backlink(ex->parent_port); - } - sas_port_add_phy(ex->parent_port, ex_phy->phy); -} - static inline struct domain_device *sas_alloc_device(void) { struct domain_device *dev = kzalloc(sizeof(*dev), GFP_KERNEL); diff --git a/drivers/scsi/libsas/sas_scsi_host.c b/drivers/scsi/libsas/sas_scsi_host.c index 9047cfcd10..da11d32840 100644 --- a/drivers/scsi/libsas/sas_scsi_host.c +++ b/drivers/scsi/libsas/sas_scsi_host.c @@ -804,14 +804,15 @@ EXPORT_SYMBOL_GPL(sas_target_alloc); #define SAS_DEF_QD 256 -int sas_slave_configure(struct scsi_device *scsi_dev) +int sas_device_configure(struct scsi_device *scsi_dev, + struct queue_limits *lim) { struct domain_device *dev = sdev_to_domain_dev(scsi_dev); BUG_ON(dev->rphy->identify.device_type != SAS_END_DEVICE); if (dev_is_sata(dev)) { - ata_sas_slave_configure(scsi_dev, dev->sata_dev.ap); + ata_sas_device_configure(scsi_dev, lim, dev->sata_dev.ap); return 0; } @@ -829,7 +830,7 @@ int sas_slave_configure(struct scsi_device *scsi_dev) return 0; } -EXPORT_SYMBOL_GPL(sas_slave_configure); +EXPORT_SYMBOL_GPL(sas_device_configure); int sas_change_queue_depth(struct scsi_device *sdev, int depth) { diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h index 98ca7df003..7c147d6ea8 100644 --- a/drivers/scsi/lpfc/lpfc.h +++ b/drivers/scsi/lpfc/lpfc.h @@ -393,6 +393,37 @@ enum hba_state { LPFC_HBA_ERROR = -1 }; +enum lpfc_hba_flag { /* hba generic flags */ + HBA_ERATT_HANDLED = 0, /* This flag is set when eratt handled */ + DEFER_ERATT = 1, /* Deferred error attn in progress */ + HBA_FCOE_MODE = 2, /* HBA function in FCoE Mode */ + HBA_SP_QUEUE_EVT = 3, /* Slow-path qevt posted to worker thread*/ + HBA_POST_RECEIVE_BUFFER = 4, /* Rcv buffers need to be posted */ + HBA_PERSISTENT_TOPO = 5, /* Persistent topology support in hba */ + ELS_XRI_ABORT_EVENT = 6, /* ELS_XRI abort event was queued */ + ASYNC_EVENT = 7, + LINK_DISABLED = 8, /* Link disabled by user */ + FCF_TS_INPROG = 9, /* FCF table scan in progress */ + FCF_RR_INPROG = 10, /* FCF roundrobin flogi in progress */ + HBA_FIP_SUPPORT = 11, /* FIP support in HBA */ + HBA_DEVLOSS_TMO = 13, /* HBA in devloss timeout */ + HBA_RRQ_ACTIVE = 14, /* process the rrq active list */ + HBA_IOQ_FLUSH = 15, /* I/O queues being flushed */ + HBA_RECOVERABLE_UE = 17, /* FW supports recoverable UE */ + HBA_FORCED_LINK_SPEED = 18, /* + * Firmware supports Forced Link + * Speed capability + */ + HBA_FLOGI_ISSUED = 20, /* FLOGI was issued */ + HBA_DEFER_FLOGI = 23, /* Defer FLOGI till read_sparm cmpl */ + HBA_SETUP = 24, /* HBA setup completed */ + HBA_NEEDS_CFG_PORT = 25, /* SLI3: CONFIG_PORT mbox needed */ + HBA_HBEAT_INP = 26, /* mbox HBEAT is in progress */ + HBA_HBEAT_TMO = 27, /* HBEAT initiated after timeout */ + HBA_FLOGI_OUTSTANDING = 28, /* FLOGI is outstanding */ + HBA_RHBA_CMPL = 29, /* RHBA FDMI cmd is successful */ +}; + struct lpfc_trunk_link_state { enum hba_state state; uint8_t fault; @@ -1007,35 +1038,7 @@ struct lpfc_hba { #define LS_CT_VEN_RPA 0x20 /* Vendor RPA sent to switch */ #define LS_EXTERNAL_LOOPBACK 0x40 /* External loopback plug inserted */ - uint32_t hba_flag; /* hba generic flags */ -#define HBA_ERATT_HANDLED 0x1 /* This flag is set when eratt handled */ -#define DEFER_ERATT 0x2 /* Deferred error attention in progress */ -#define HBA_FCOE_MODE 0x4 /* HBA function in FCoE Mode */ -#define HBA_SP_QUEUE_EVT 0x8 /* Slow-path qevt posted to worker thread*/ -#define HBA_POST_RECEIVE_BUFFER 0x10 /* Rcv buffers need to be posted */ -#define HBA_PERSISTENT_TOPO 0x20 /* Persistent topology support in hba */ -#define ELS_XRI_ABORT_EVENT 0x40 /* ELS_XRI abort event was queued */ -#define ASYNC_EVENT 0x80 -#define LINK_DISABLED 0x100 /* Link disabled by user */ -#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_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 */ -#define HBA_RECOVERABLE_UE 0x20000 /* Firmware supports recoverable UE */ -#define HBA_FORCED_LINK_SPEED 0x40000 /* - * Firmware supports Forced Link Speed - * capability - */ -#define HBA_FLOGI_ISSUED 0x100000 /* FLOGI was issued */ -#define HBA_DEFER_FLOGI 0x800000 /* Defer FLOGI till read_sparm cmpl */ -#define HBA_SETUP 0x1000000 /* Signifies HBA setup is completed */ -#define HBA_NEEDS_CFG_PORT 0x2000000 /* SLI3 - needs a CONFIG_PORT mbox */ -#define HBA_HBEAT_INP 0x4000000 /* mbox HBEAT is in progress */ -#define HBA_HBEAT_TMO 0x8000000 /* HBEAT initiated after timeout */ -#define HBA_FLOGI_OUTSTANDING 0x10000000 /* FLOGI is outstanding */ -#define HBA_RHBA_CMPL 0x20000000 /* RHBA FDMI command is successful */ + unsigned long hba_flag; /* hba generic flags */ struct completion *fw_dump_cmpl; /* cmpl event tracker for fw_dump */ uint32_t fcp_ring_in_use; /* When polling test if intr-hndlr active*/ @@ -1284,6 +1287,7 @@ struct lpfc_hba { uint32_t total_scsi_bufs; struct list_head lpfc_iocb_list; uint32_t total_iocbq_bufs; + spinlock_t rrq_list_lock; /* lock for active_rrq_list */ struct list_head active_rrq_list; spinlock_t hbalock; struct work_struct unblock_request_work; /* SCSI layer unblock IOs */ diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c index 3c534b3cfe..0a9d6978cb 100644 --- a/drivers/scsi/lpfc/lpfc_attr.c +++ b/drivers/scsi/lpfc/lpfc_attr.c @@ -322,7 +322,7 @@ lpfc_enable_fip_show(struct device *dev, struct device_attribute *attr, struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; struct lpfc_hba *phba = vport->phba; - if (phba->hba_flag & HBA_FIP_SUPPORT) + if (test_bit(HBA_FIP_SUPPORT, &phba->hba_flag)) return scnprintf(buf, PAGE_SIZE, "1\n"); else return scnprintf(buf, PAGE_SIZE, "0\n"); @@ -1049,7 +1049,7 @@ lpfc_link_state_show(struct device *dev, struct device_attribute *attr, case LPFC_INIT_MBX_CMDS: case LPFC_LINK_DOWN: case LPFC_HBA_ERROR: - if (phba->hba_flag & LINK_DISABLED) + if (test_bit(LINK_DISABLED, &phba->hba_flag)) len += scnprintf(buf + len, PAGE_SIZE-len, "Link Down - User disabled\n"); else @@ -1292,7 +1292,7 @@ lpfc_issue_lip(struct Scsi_Host *shost) * it doesn't make any sense to allow issue_lip */ if (test_bit(FC_OFFLINE_MODE, &vport->fc_flag) || - (phba->hba_flag & LINK_DISABLED) || + test_bit(LINK_DISABLED, &phba->hba_flag) || (phba->sli.sli_flag & LPFC_BLOCK_MGMT_IO)) return -EPERM; @@ -1907,6 +1907,11 @@ lpfc_xcvr_data_show(struct device *dev, struct device_attribute *attr, /* Get transceiver information */ rdp_context = kmalloc(sizeof(*rdp_context), GFP_KERNEL); + if (!rdp_context) { + len = scnprintf(buf, PAGE_SIZE - len, + "SPF info NA: alloc failure\n"); + return len; + } rc = lpfc_get_sfp_info_wait(phba, rdp_context); if (rc) { @@ -3635,7 +3640,8 @@ lpfc_pt_show(struct device *dev, struct device_attribute *attr, char *buf) struct lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba; return scnprintf(buf, PAGE_SIZE, "%d\n", - (phba->hba_flag & HBA_PERSISTENT_TOPO) ? 1 : 0); + test_bit(HBA_PERSISTENT_TOPO, + &phba->hba_flag) ? 1 : 0); } static DEVICE_ATTR(pt, 0444, lpfc_pt_show, NULL); @@ -4205,8 +4211,8 @@ lpfc_topology_store(struct device *dev, struct device_attribute *attr, &phba->sli4_hba.sli_intf); if_type = bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf); - if ((phba->hba_flag & HBA_PERSISTENT_TOPO || - (!phba->sli4_hba.pc_sli4_params.pls && + if ((test_bit(HBA_PERSISTENT_TOPO, &phba->hba_flag) || + (!phba->sli4_hba.pc_sli4_params.pls && (sli_family == LPFC_SLI_INTF_FAMILY_G6 || if_type == LPFC_SLI_INTF_IF_TYPE_6))) && val == 4) { @@ -4309,7 +4315,7 @@ lpfc_link_speed_store(struct device *dev, struct device_attribute *attr, if_type = bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf); if (if_type >= LPFC_SLI_INTF_IF_TYPE_2 && - phba->hba_flag & HBA_FORCED_LINK_SPEED) + test_bit(HBA_FORCED_LINK_SPEED, &phba->hba_flag)) return -EPERM; if (!strncmp(buf, "nolip ", strlen("nolip "))) { @@ -6497,7 +6503,8 @@ lpfc_get_host_speed(struct Scsi_Host *shost) struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; struct lpfc_hba *phba = vport->phba; - if ((lpfc_is_link_up(phba)) && (!(phba->hba_flag & HBA_FCOE_MODE))) { + if ((lpfc_is_link_up(phba)) && + !test_bit(HBA_FCOE_MODE, &phba->hba_flag)) { switch(phba->fc_linkspeed) { case LPFC_LINK_SPEED_1GHZ: fc_host_speed(shost) = FC_PORTSPEED_1GBIT; @@ -6533,7 +6540,8 @@ lpfc_get_host_speed(struct Scsi_Host *shost) fc_host_speed(shost) = FC_PORTSPEED_UNKNOWN; break; } - } else if (lpfc_is_link_up(phba) && (phba->hba_flag & HBA_FCOE_MODE)) { + } else if (lpfc_is_link_up(phba) && + test_bit(HBA_FCOE_MODE, &phba->hba_flag)) { switch (phba->fc_linkspeed) { case LPFC_ASYNC_LINK_SPEED_1GBPS: fc_host_speed(shost) = FC_PORTSPEED_1GBIT; @@ -6718,7 +6726,7 @@ lpfc_get_stats(struct Scsi_Host *shost) hs->invalid_crc_count -= lso->invalid_crc_count; hs->error_frames -= lso->error_frames; - if (phba->hba_flag & HBA_FCOE_MODE) { + if (test_bit(HBA_FCOE_MODE, &phba->hba_flag)) { hs->lip_count = -1; hs->nos_count = (phba->link_events >> 1); hs->nos_count -= lso->link_events; @@ -6816,7 +6824,7 @@ lpfc_reset_stats(struct Scsi_Host *shost) lso->invalid_tx_word_count = pmb->un.varRdLnk.invalidXmitWord; lso->invalid_crc_count = pmb->un.varRdLnk.crcCnt; lso->error_frames = pmb->un.varRdLnk.crcCnt; - if (phba->hba_flag & HBA_FCOE_MODE) + if (test_bit(HBA_FCOE_MODE, &phba->hba_flag)) lso->link_events = (phba->link_events >> 1); else lso->link_events = (phba->fc_eventTag >> 1); @@ -7161,11 +7169,11 @@ lpfc_get_hba_function_mode(struct lpfc_hba *phba) case PCI_DEVICE_ID_ZEPHYR_DCSP: case PCI_DEVICE_ID_TIGERSHARK: case PCI_DEVICE_ID_TOMCAT: - phba->hba_flag |= HBA_FCOE_MODE; + set_bit(HBA_FCOE_MODE, &phba->hba_flag); break; default: /* for others, clear the flag */ - phba->hba_flag &= ~HBA_FCOE_MODE; + clear_bit(HBA_FCOE_MODE, &phba->hba_flag); } } @@ -7236,7 +7244,7 @@ lpfc_get_cfgparam(struct lpfc_hba *phba) lpfc_get_hba_function_mode(phba); /* BlockGuard allowed for FC only. */ - if (phba->cfg_enable_bg && phba->hba_flag & HBA_FCOE_MODE) { + if (phba->cfg_enable_bg && test_bit(HBA_FCOE_MODE, &phba->hba_flag)) { lpfc_printf_log(phba, KERN_INFO, LOG_INIT, "0581 BlockGuard feature not supported\n"); /* If set, clear the BlockGuard support param */ diff --git a/drivers/scsi/lpfc/lpfc_bsg.c b/drivers/scsi/lpfc/lpfc_bsg.c index 529df1768f..4156419c52 100644 --- a/drivers/scsi/lpfc/lpfc_bsg.c +++ b/drivers/scsi/lpfc/lpfc_bsg.c @@ -5002,7 +5002,8 @@ lpfc_forced_link_speed(struct bsg_job *job) goto job_error; } - forced_reply->supported = (phba->hba_flag & HBA_FORCED_LINK_SPEED) + forced_reply->supported = test_bit(HBA_FORCED_LINK_SPEED, + &phba->hba_flag) ? LPFC_FORCED_LINK_SPEED_SUPPORTED : LPFC_FORCED_LINK_SPEED_NOT_SUPPORTED; job_error: diff --git a/drivers/scsi/lpfc/lpfc_ct.c b/drivers/scsi/lpfc/lpfc_ct.c index 8cc08e58dc..376d0f958b 100644 --- a/drivers/scsi/lpfc/lpfc_ct.c +++ b/drivers/scsi/lpfc/lpfc_ct.c @@ -291,9 +291,9 @@ lpfc_ct_handle_mibreq(struct lpfc_hba *phba, struct lpfc_iocbq *ctiocbq) did = bf_get(els_rsp64_sid, &ctiocbq->wqe.xmit_els_rsp); if (ulp_status) { - lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS, - "6438 Unsol CT: status:x%x/x%x did : x%x\n", - ulp_status, ulp_word4, did); + lpfc_vlog_msg(vport, KERN_WARNING, LOG_ELS, + "6438 Unsol CT: status:x%x/x%x did : x%x\n", + ulp_status, ulp_word4, did); return; } @@ -303,17 +303,17 @@ lpfc_ct_handle_mibreq(struct lpfc_hba *phba, struct lpfc_iocbq *ctiocbq) ndlp = lpfc_findnode_did(vport, did); if (!ndlp) { - lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS, - "6439 Unsol CT: NDLP Not Found for DID : x%x", - did); + lpfc_vlog_msg(vport, KERN_WARNING, LOG_ELS, + "6439 Unsol CT: NDLP Not Found for DID : x%x", + did); return; } ct_req = (struct lpfc_sli_ct_request *)ctiocbq->cmd_dmabuf->virt; mi_cmd = be16_to_cpu(ct_req->CommandResponse.bits.CmdRsp); - lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS, - "6442 : MI Cmd : x%x Not Supported\n", mi_cmd); + lpfc_vlog_msg(vport, KERN_WARNING, LOG_ELS, + "6442 MI Cmd : x%x Not Supported\n", mi_cmd); lpfc_ct_reject_event(ndlp, ct_req, bf_get(wqe_ctxt_tag, &ctiocbq->wqe.xmit_els_rsp.wqe_com), @@ -2173,7 +2173,7 @@ lpfc_fdmi_rprt_defer(struct lpfc_hba *phba, uint32_t mask) struct lpfc_nodelist *ndlp; int i; - phba->hba_flag |= HBA_RHBA_CMPL; + set_bit(HBA_RHBA_CMPL, &phba->hba_flag); vports = lpfc_create_vport_work_array(phba); if (vports) { for (i = 0; i <= phba->max_vports && vports[i] != NULL; i++) { @@ -2368,7 +2368,7 @@ lpfc_cmpl_ct_disc_fdmi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, * for the physical port completes successfully. * We may have to defer the RPRT accordingly. */ - if (phba->hba_flag & HBA_RHBA_CMPL) { + if (test_bit(HBA_RHBA_CMPL, &phba->hba_flag)) { lpfc_fdmi_cmd(vport, ndlp, SLI_MGMT_RPRT, 0); } else { lpfc_printf_vlog(vport, KERN_INFO, @@ -2785,7 +2785,7 @@ lpfc_fdmi_port_attr_support_speed(struct lpfc_vport *vport, void *attr) u32 tcfg; u8 i, cnt; - if (!(phba->hba_flag & HBA_FCOE_MODE)) { + if (!test_bit(HBA_FCOE_MODE, &phba->hba_flag)) { cnt = 0; if (phba->sli_rev == LPFC_SLI_REV4) { tcfg = phba->sli4_hba.conf_trunk; @@ -2859,7 +2859,7 @@ lpfc_fdmi_port_attr_speed(struct lpfc_vport *vport, void *attr) struct lpfc_hba *phba = vport->phba; u32 speeds = 0; - if (!(phba->hba_flag & HBA_FCOE_MODE)) { + if (!test_bit(HBA_FCOE_MODE, &phba->hba_flag)) { switch (phba->fc_linkspeed) { case LPFC_LINK_SPEED_1GHZ: speeds = HBA_PORTSPEED_1GFC; diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c index f7c28dc73b..c32bc773ab 100644 --- a/drivers/scsi/lpfc/lpfc_els.c +++ b/drivers/scsi/lpfc/lpfc_els.c @@ -189,11 +189,11 @@ lpfc_prep_els_iocb(struct lpfc_vport *vport, u8 expect_rsp, * If this command is for fabric controller and HBA running * in FIP mode send FLOGI, FDISC and LOGO as FIP frames. */ - if ((did == Fabric_DID) && - (phba->hba_flag & HBA_FIP_SUPPORT) && - ((elscmd == ELS_CMD_FLOGI) || - (elscmd == ELS_CMD_FDISC) || - (elscmd == ELS_CMD_LOGO))) + if (did == Fabric_DID && + test_bit(HBA_FIP_SUPPORT, &phba->hba_flag) && + (elscmd == ELS_CMD_FLOGI || + elscmd == ELS_CMD_FDISC || + elscmd == ELS_CMD_LOGO)) switch (elscmd) { case ELS_CMD_FLOGI: elsiocb->cmd_flag |= @@ -965,7 +965,7 @@ lpfc_cmpl_els_flogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, * In case of FIP mode, perform roundrobin FCF failover * due to new FCF discovery */ - if ((phba->hba_flag & HBA_FIP_SUPPORT) && + if (test_bit(HBA_FIP_SUPPORT, &phba->hba_flag) && (phba->fcf.fcf_flag & FCF_DISCOVERY)) { if (phba->link_state < LPFC_LINK_UP) goto stop_rr_fcf_flogi; @@ -999,7 +999,7 @@ stop_rr_fcf_flogi: IOERR_LOOP_OPEN_FAILURE))) lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT, "2858 FLOGI failure Status:x%x/x%x TMO" - ":x%x Data x%x x%x\n", + ":x%x Data x%lx x%x\n", ulp_status, ulp_word4, tmo, phba->hba_flag, phba->fcf.fcf_flag); @@ -1119,7 +1119,7 @@ stop_rr_fcf_flogi: if (sp->cmn.fPort) rc = lpfc_cmpl_els_flogi_fabric(vport, ndlp, sp, ulp_word4); - else if (!(phba->hba_flag & HBA_FCOE_MODE)) + else if (!test_bit(HBA_FCOE_MODE, &phba->hba_flag)) rc = lpfc_cmpl_els_flogi_nport(vport, ndlp, sp); else { lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT, @@ -1149,14 +1149,15 @@ stop_rr_fcf_flogi: lpfc_nlp_put(ndlp); spin_lock_irq(&phba->hbalock); phba->fcf.fcf_flag &= ~FCF_DISCOVERY; - phba->hba_flag &= ~(FCF_RR_INPROG | HBA_DEVLOSS_TMO); spin_unlock_irq(&phba->hbalock); + clear_bit(FCF_RR_INPROG, &phba->hba_flag); + clear_bit(HBA_DEVLOSS_TMO, &phba->hba_flag); phba->fcf.fcf_redisc_attempted = 0; /* reset */ goto out; } if (!rc) { /* Mark the FCF discovery process done */ - if (phba->hba_flag & HBA_FIP_SUPPORT) + if (test_bit(HBA_FIP_SUPPORT, &phba->hba_flag)) lpfc_printf_vlog(vport, KERN_INFO, LOG_FIP | LOG_ELS, "2769 FLOGI to FCF (x%x) " @@ -1164,8 +1165,9 @@ stop_rr_fcf_flogi: phba->fcf.current_rec.fcf_indx); spin_lock_irq(&phba->hbalock); phba->fcf.fcf_flag &= ~FCF_DISCOVERY; - phba->hba_flag &= ~(FCF_RR_INPROG | HBA_DEVLOSS_TMO); spin_unlock_irq(&phba->hbalock); + clear_bit(FCF_RR_INPROG, &phba->hba_flag); + clear_bit(HBA_DEVLOSS_TMO, &phba->hba_flag); phba->fcf.fcf_redisc_attempted = 0; /* reset */ goto out; } @@ -1202,7 +1204,7 @@ flogifail: } out: if (!flogi_in_retry) - phba->hba_flag &= ~HBA_FLOGI_OUTSTANDING; + clear_bit(HBA_FLOGI_OUTSTANDING, &phba->hba_flag); lpfc_els_free_iocb(phba, cmdiocb); lpfc_nlp_put(ndlp); @@ -1372,11 +1374,13 @@ lpfc_issue_els_flogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, } /* Avoid race with FLOGI completion and hba_flags. */ - phba->hba_flag |= (HBA_FLOGI_ISSUED | HBA_FLOGI_OUTSTANDING); + set_bit(HBA_FLOGI_ISSUED, &phba->hba_flag); + set_bit(HBA_FLOGI_OUTSTANDING, &phba->hba_flag); rc = lpfc_issue_fabric_iocb(phba, elsiocb); if (rc == IOCB_ERROR) { - phba->hba_flag &= ~(HBA_FLOGI_ISSUED | HBA_FLOGI_OUTSTANDING); + clear_bit(HBA_FLOGI_ISSUED, &phba->hba_flag); + clear_bit(HBA_FLOGI_OUTSTANDING, &phba->hba_flag); lpfc_els_free_iocb(phba, elsiocb); lpfc_nlp_put(ndlp); return 1; @@ -1413,7 +1417,7 @@ lpfc_issue_els_flogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS, "3354 Xmit deferred FLOGI ACC: rx_id: x%x," - " ox_id: x%x, hba_flag x%x\n", + " ox_id: x%x, hba_flag x%lx\n", phba->defer_flogi_acc_rx_id, phba->defer_flogi_acc_ox_id, phba->hba_flag); @@ -7415,7 +7419,8 @@ lpfc_els_rcv_rdp(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, goto error; } - if (phba->sli_rev < LPFC_SLI_REV4 || (phba->hba_flag & HBA_FCOE_MODE)) { + if (phba->sli_rev < LPFC_SLI_REV4 || + test_bit(HBA_FCOE_MODE, &phba->hba_flag)) { rjt_err = LSRJT_UNABLE_TPC; rjt_expl = LSEXP_REQ_UNSUPPORTED; goto error; @@ -7738,7 +7743,7 @@ lpfc_els_rcv_lcb(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, } if (phba->sli_rev < LPFC_SLI_REV4 || - phba->hba_flag & HBA_FCOE_MODE || + test_bit(HBA_FCOE_MODE, &phba->hba_flag) || (bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf) < LPFC_SLI_INTF_IF_TYPE_2)) { rjt_err = LSRJT_CMD_UNSUPPORTED; @@ -8443,7 +8448,7 @@ lpfc_els_rcv_flogi(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, memcpy(&phba->fc_fabparam, sp, sizeof(struct serv_parm)); /* Defer ACC response until AFTER we issue a FLOGI */ - if (!(phba->hba_flag & HBA_FLOGI_ISSUED)) { + if (!test_bit(HBA_FLOGI_ISSUED, &phba->hba_flag)) { phba->defer_flogi_acc_rx_id = bf_get(wqe_ctxt_tag, &wqe->xmit_els_rsp.wqe_com); phba->defer_flogi_acc_ox_id = bf_get(wqe_rcvoxid, @@ -8453,7 +8458,7 @@ lpfc_els_rcv_flogi(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS, "3344 Deferring FLOGI ACC: rx_id: x%x," - " ox_id: x%x, hba_flag x%x\n", + " ox_id: x%x, hba_flag x%lx\n", phba->defer_flogi_acc_rx_id, phba->defer_flogi_acc_ox_id, phba->hba_flag); diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c index e42fa9c822..13b08c8544 100644 --- a/drivers/scsi/lpfc/lpfc_hbadisc.c +++ b/drivers/scsi/lpfc/lpfc_hbadisc.c @@ -487,7 +487,8 @@ lpfc_dev_loss_tmo_handler(struct lpfc_nodelist *ndlp) recovering = true; } else { /* Physical port path. */ - if (phba->hba_flag & HBA_FLOGI_OUTSTANDING) + if (test_bit(HBA_FLOGI_OUTSTANDING, + &phba->hba_flag)) recovering = true; } break; @@ -652,14 +653,15 @@ lpfc_sli4_post_dev_loss_tmo_handler(struct lpfc_hba *phba, int fcf_inuse, if (!fcf_inuse) return; - if ((phba->hba_flag & HBA_FIP_SUPPORT) && !lpfc_fcf_inuse(phba)) { + if (test_bit(HBA_FIP_SUPPORT, &phba->hba_flag) && + !lpfc_fcf_inuse(phba)) { spin_lock_irq(&phba->hbalock); if (phba->fcf.fcf_flag & FCF_DISCOVERY) { - if (phba->hba_flag & HBA_DEVLOSS_TMO) { + if (test_and_set_bit(HBA_DEVLOSS_TMO, + &phba->hba_flag)) { spin_unlock_irq(&phba->hbalock); return; } - phba->hba_flag |= HBA_DEVLOSS_TMO; lpfc_printf_log(phba, KERN_INFO, LOG_FIP, "2847 Last remote node (x%x) using " "FCF devloss tmo\n", nlp_did); @@ -671,8 +673,9 @@ lpfc_sli4_post_dev_loss_tmo_handler(struct lpfc_hba *phba, int fcf_inuse, "in progress\n"); return; } - if (!(phba->hba_flag & (FCF_TS_INPROG | FCF_RR_INPROG))) { - spin_unlock_irq(&phba->hbalock); + spin_unlock_irq(&phba->hbalock); + if (!test_bit(FCF_TS_INPROG, &phba->hba_flag) && + !test_bit(FCF_RR_INPROG, &phba->hba_flag)) { lpfc_printf_log(phba, KERN_INFO, LOG_FIP, "2869 Devloss tmo to idle FIP engine, " "unreg in-use FCF and rescan.\n"); @@ -680,11 +683,10 @@ lpfc_sli4_post_dev_loss_tmo_handler(struct lpfc_hba *phba, int fcf_inuse, lpfc_unregister_fcf_rescan(phba); return; } - spin_unlock_irq(&phba->hbalock); - if (phba->hba_flag & FCF_TS_INPROG) + if (test_bit(FCF_TS_INPROG, &phba->hba_flag)) lpfc_printf_log(phba, KERN_INFO, LOG_FIP, "2870 FCF table scan in progress\n"); - if (phba->hba_flag & FCF_RR_INPROG) + if (test_bit(FCF_RR_INPROG, &phba->hba_flag)) lpfc_printf_log(phba, KERN_INFO, LOG_FIP, "2871 FLOGI roundrobin FCF failover " "in progress\n"); @@ -978,18 +980,15 @@ lpfc_work_done(struct lpfc_hba *phba) /* Process SLI4 events */ if (phba->pci_dev_grp == LPFC_PCI_DEV_OC) { - if (phba->hba_flag & HBA_RRQ_ACTIVE) + if (test_bit(HBA_RRQ_ACTIVE, &phba->hba_flag)) lpfc_handle_rrq_active(phba); - if (phba->hba_flag & ELS_XRI_ABORT_EVENT) + if (test_bit(ELS_XRI_ABORT_EVENT, &phba->hba_flag)) lpfc_sli4_els_xri_abort_event_proc(phba); - if (phba->hba_flag & ASYNC_EVENT) + if (test_bit(ASYNC_EVENT, &phba->hba_flag)) lpfc_sli4_async_event_proc(phba); - if (phba->hba_flag & HBA_POST_RECEIVE_BUFFER) { - spin_lock_irq(&phba->hbalock); - phba->hba_flag &= ~HBA_POST_RECEIVE_BUFFER; - spin_unlock_irq(&phba->hbalock); + if (test_and_clear_bit(HBA_POST_RECEIVE_BUFFER, + &phba->hba_flag)) lpfc_sli_hbqbuf_add_hbqs(phba, LPFC_ELS_HBQ); - } if (phba->fcf.fcf_flag & FCF_REDISC_EVT) lpfc_sli4_fcf_redisc_event_proc(phba); } @@ -1035,11 +1034,11 @@ lpfc_work_done(struct lpfc_hba *phba) status >>= (4*LPFC_ELS_RING); if (pring && (status & HA_RXMASK || pring->flag & LPFC_DEFERRED_RING_EVENT || - phba->hba_flag & HBA_SP_QUEUE_EVT)) { + test_bit(HBA_SP_QUEUE_EVT, &phba->hba_flag))) { if (pring->flag & LPFC_STOP_IOCB_EVENT) { pring->flag |= LPFC_DEFERRED_RING_EVENT; /* Preserve legacy behavior. */ - if (!(phba->hba_flag & HBA_SP_QUEUE_EVT)) + if (!test_bit(HBA_SP_QUEUE_EVT, &phba->hba_flag)) set_bit(LPFC_DATA_READY, &phba->data_flags); } else { /* Driver could have abort request completed in queue @@ -1420,7 +1419,8 @@ lpfc_linkup(struct lpfc_hba *phba) spin_unlock_irq(shost->host_lock); /* reinitialize initial HBA flag */ - phba->hba_flag &= ~(HBA_FLOGI_ISSUED | HBA_RHBA_CMPL); + clear_bit(HBA_FLOGI_ISSUED, &phba->hba_flag); + clear_bit(HBA_RHBA_CMPL, &phba->hba_flag); return 0; } @@ -1505,7 +1505,7 @@ lpfc_mbx_cmpl_local_config_link(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) /* don't perform discovery for SLI4 loopback diagnostic test */ if ((phba->sli_rev == LPFC_SLI_REV4) && - !(phba->hba_flag & HBA_FCOE_MODE) && + !test_bit(HBA_FCOE_MODE, &phba->hba_flag) && (phba->link_flag & LS_LOOPBACK_MODE)) return; @@ -1548,7 +1548,7 @@ lpfc_mbx_cmpl_local_config_link(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) goto sparam_out; } - phba->hba_flag |= HBA_DEFER_FLOGI; + set_bit(HBA_DEFER_FLOGI, &phba->hba_flag); } else { lpfc_initial_flogi(vport); } @@ -1617,27 +1617,23 @@ lpfc_mbx_cmpl_reg_fcfi(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) spin_unlock_irq(&phba->hbalock); /* If there is a pending FCoE event, restart FCF table scan. */ - if ((!(phba->hba_flag & FCF_RR_INPROG)) && - lpfc_check_pending_fcoe_event(phba, LPFC_UNREG_FCF)) + if (!test_bit(FCF_RR_INPROG, &phba->hba_flag) && + lpfc_check_pending_fcoe_event(phba, LPFC_UNREG_FCF)) goto fail_out; /* Mark successful completion of FCF table scan */ spin_lock_irq(&phba->hbalock); phba->fcf.fcf_flag |= (FCF_SCAN_DONE | FCF_IN_USE); - phba->hba_flag &= ~FCF_TS_INPROG; + spin_unlock_irq(&phba->hbalock); + clear_bit(FCF_TS_INPROG, &phba->hba_flag); if (vport->port_state != LPFC_FLOGI) { - phba->hba_flag |= FCF_RR_INPROG; - spin_unlock_irq(&phba->hbalock); + set_bit(FCF_RR_INPROG, &phba->hba_flag); lpfc_issue_init_vfi(vport); - goto out; } - spin_unlock_irq(&phba->hbalock); goto out; fail_out: - spin_lock_irq(&phba->hbalock); - phba->hba_flag &= ~FCF_RR_INPROG; - spin_unlock_irq(&phba->hbalock); + clear_bit(FCF_RR_INPROG, &phba->hba_flag); out: mempool_free(mboxq, phba->mbox_mem_pool); } @@ -1867,32 +1863,31 @@ lpfc_register_fcf(struct lpfc_hba *phba) spin_lock_irq(&phba->hbalock); /* If the FCF is not available do nothing. */ if (!(phba->fcf.fcf_flag & FCF_AVAILABLE)) { - phba->hba_flag &= ~(FCF_TS_INPROG | FCF_RR_INPROG); spin_unlock_irq(&phba->hbalock); + clear_bit(FCF_TS_INPROG, &phba->hba_flag); + clear_bit(FCF_RR_INPROG, &phba->hba_flag); return; } /* The FCF is already registered, start discovery */ if (phba->fcf.fcf_flag & FCF_REGISTERED) { phba->fcf.fcf_flag |= (FCF_SCAN_DONE | FCF_IN_USE); - phba->hba_flag &= ~FCF_TS_INPROG; + spin_unlock_irq(&phba->hbalock); + clear_bit(FCF_TS_INPROG, &phba->hba_flag); if (phba->pport->port_state != LPFC_FLOGI && test_bit(FC_FABRIC, &phba->pport->fc_flag)) { - phba->hba_flag |= FCF_RR_INPROG; - spin_unlock_irq(&phba->hbalock); + set_bit(FCF_RR_INPROG, &phba->hba_flag); lpfc_initial_flogi(phba->pport); return; } - spin_unlock_irq(&phba->hbalock); return; } spin_unlock_irq(&phba->hbalock); fcf_mbxq = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); if (!fcf_mbxq) { - spin_lock_irq(&phba->hbalock); - phba->hba_flag &= ~(FCF_TS_INPROG | FCF_RR_INPROG); - spin_unlock_irq(&phba->hbalock); + clear_bit(FCF_TS_INPROG, &phba->hba_flag); + clear_bit(FCF_RR_INPROG, &phba->hba_flag); return; } @@ -1901,9 +1896,8 @@ lpfc_register_fcf(struct lpfc_hba *phba) fcf_mbxq->mbox_cmpl = lpfc_mbx_cmpl_reg_fcfi; rc = lpfc_sli_issue_mbox(phba, fcf_mbxq, MBX_NOWAIT); if (rc == MBX_NOT_FINISHED) { - spin_lock_irq(&phba->hbalock); - phba->hba_flag &= ~(FCF_TS_INPROG | FCF_RR_INPROG); - spin_unlock_irq(&phba->hbalock); + clear_bit(FCF_TS_INPROG, &phba->hba_flag); + clear_bit(FCF_RR_INPROG, &phba->hba_flag); mempool_free(fcf_mbxq, phba->mbox_mem_pool); } @@ -1956,7 +1950,7 @@ lpfc_match_fcf_conn_list(struct lpfc_hba *phba, bf_get(lpfc_fcf_record_fcf_sol, new_fcf_record)) return 0; - if (!(phba->hba_flag & HBA_FIP_SUPPORT)) { + if (!test_bit(HBA_FIP_SUPPORT, &phba->hba_flag)) { *boot_flag = 0; *addr_mode = bf_get(lpfc_fcf_record_mac_addr_prov, new_fcf_record); @@ -2151,8 +2145,9 @@ lpfc_check_pending_fcoe_event(struct lpfc_hba *phba, uint8_t unreg_fcf) lpfc_printf_log(phba, KERN_INFO, LOG_FIP | LOG_DISCOVERY, "2833 Stop FCF discovery process due to link " "state change (x%x)\n", phba->link_state); + clear_bit(FCF_TS_INPROG, &phba->hba_flag); + clear_bit(FCF_RR_INPROG, &phba->hba_flag); spin_lock_irq(&phba->hbalock); - phba->hba_flag &= ~(FCF_TS_INPROG | FCF_RR_INPROG); phba->fcf.fcf_flag &= ~(FCF_REDISC_FOV | FCF_DISCOVERY); spin_unlock_irq(&phba->hbalock); } @@ -2380,9 +2375,7 @@ int lpfc_sli4_fcf_rr_next_proc(struct lpfc_vport *vport, uint16_t fcf_index) int rc; if (fcf_index == LPFC_FCOE_FCF_NEXT_NONE) { - spin_lock_irq(&phba->hbalock); - if (phba->hba_flag & HBA_DEVLOSS_TMO) { - spin_unlock_irq(&phba->hbalock); + if (test_bit(HBA_DEVLOSS_TMO, &phba->hba_flag)) { lpfc_printf_log(phba, KERN_INFO, LOG_FIP, "2872 Devloss tmo with no eligible " "FCF, unregister in-use FCF (x%x) " @@ -2392,8 +2385,9 @@ int lpfc_sli4_fcf_rr_next_proc(struct lpfc_vport *vport, uint16_t fcf_index) goto stop_flogi_current_fcf; } /* Mark the end to FLOGI roundrobin failover */ - phba->hba_flag &= ~FCF_RR_INPROG; + clear_bit(FCF_RR_INPROG, &phba->hba_flag); /* Allow action to new fcf asynchronous event */ + spin_lock_irq(&phba->hbalock); phba->fcf.fcf_flag &= ~(FCF_AVAILABLE | FCF_SCAN_DONE); spin_unlock_irq(&phba->hbalock); lpfc_printf_log(phba, KERN_INFO, LOG_FIP, @@ -2630,9 +2624,7 @@ lpfc_mbx_cmpl_fcf_scan_read_fcf_rec(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) "2765 Mailbox command READ_FCF_RECORD " "failed to retrieve a FCF record.\n"); /* Let next new FCF event trigger fast failover */ - spin_lock_irq(&phba->hbalock); - phba->hba_flag &= ~FCF_TS_INPROG; - spin_unlock_irq(&phba->hbalock); + clear_bit(FCF_TS_INPROG, &phba->hba_flag); lpfc_sli4_mbox_cmd_free(phba, mboxq); return; } @@ -2873,10 +2865,10 @@ read_next_fcf: phba->fcoe_eventtag_at_fcf_scan, bf_get(lpfc_fcf_record_fcf_index, new_fcf_record)); - spin_lock_irq(&phba->hbalock); - if (phba->hba_flag & HBA_DEVLOSS_TMO) { - phba->hba_flag &= ~FCF_TS_INPROG; - spin_unlock_irq(&phba->hbalock); + if (test_bit(HBA_DEVLOSS_TMO, + &phba->hba_flag)) { + clear_bit(FCF_TS_INPROG, + &phba->hba_flag); /* Unregister in-use FCF and rescan */ lpfc_printf_log(phba, KERN_INFO, LOG_FIP, @@ -2889,8 +2881,7 @@ read_next_fcf: /* * Let next new FCF event trigger fast failover */ - phba->hba_flag &= ~FCF_TS_INPROG; - spin_unlock_irq(&phba->hbalock); + clear_bit(FCF_TS_INPROG, &phba->hba_flag); return; } /* @@ -2996,8 +2987,8 @@ lpfc_mbx_cmpl_fcf_rr_read_fcf_rec(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) if (phba->link_state < LPFC_LINK_UP) { spin_lock_irq(&phba->hbalock); phba->fcf.fcf_flag &= ~FCF_DISCOVERY; - phba->hba_flag &= ~FCF_RR_INPROG; spin_unlock_irq(&phba->hbalock); + clear_bit(FCF_RR_INPROG, &phba->hba_flag); goto out; } @@ -3008,7 +2999,7 @@ lpfc_mbx_cmpl_fcf_rr_read_fcf_rec(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) lpfc_printf_log(phba, KERN_WARNING, LOG_FIP, "2766 Mailbox command READ_FCF_RECORD " "failed to retrieve a FCF record. " - "hba_flg x%x fcf_flg x%x\n", phba->hba_flag, + "hba_flg x%lx fcf_flg x%x\n", phba->hba_flag, phba->fcf.fcf_flag); lpfc_unregister_fcf_rescan(phba); goto out; @@ -3471,9 +3462,9 @@ lpfc_mbx_cmpl_read_sparam(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) /* Check if sending the FLOGI is being deferred to after we get * up to date CSPs from MBX_READ_SPARAM. */ - if (phba->hba_flag & HBA_DEFER_FLOGI) { + if (test_bit(HBA_DEFER_FLOGI, &phba->hba_flag)) { lpfc_initial_flogi(vport); - phba->hba_flag &= ~HBA_DEFER_FLOGI; + clear_bit(HBA_DEFER_FLOGI, &phba->hba_flag); } return; @@ -3495,7 +3486,7 @@ lpfc_mbx_process_link_up(struct lpfc_hba *phba, struct lpfc_mbx_read_top *la) spin_lock_irqsave(&phba->hbalock, iflags); phba->fc_linkspeed = bf_get(lpfc_mbx_read_top_link_spd, la); - if (!(phba->hba_flag & HBA_FCOE_MODE)) { + if (!test_bit(HBA_FCOE_MODE, &phba->hba_flag)) { switch (bf_get(lpfc_mbx_read_top_link_spd, la)) { case LPFC_LINK_SPEED_1GHZ: case LPFC_LINK_SPEED_2GHZ: @@ -3611,7 +3602,7 @@ lpfc_mbx_process_link_up(struct lpfc_hba *phba, struct lpfc_mbx_read_top *la) goto out; } - if (!(phba->hba_flag & HBA_FCOE_MODE)) { + if (!test_bit(HBA_FCOE_MODE, &phba->hba_flag)) { cfglink_mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); if (!cfglink_mbox) goto out; @@ -3631,7 +3622,7 @@ lpfc_mbx_process_link_up(struct lpfc_hba *phba, struct lpfc_mbx_read_top *la) * is phase 1 implementation that support FCF index 0 and driver * defaults. */ - if (!(phba->hba_flag & HBA_FIP_SUPPORT)) { + if (!test_bit(HBA_FIP_SUPPORT, &phba->hba_flag)) { fcf_record = kzalloc(sizeof(struct fcf_record), GFP_KERNEL); if (unlikely(!fcf_record)) { @@ -3661,12 +3652,10 @@ lpfc_mbx_process_link_up(struct lpfc_hba *phba, struct lpfc_mbx_read_top *la) * The driver is expected to do FIP/FCF. Call the port * and get the FCF Table. */ - spin_lock_irqsave(&phba->hbalock, iflags); - if (phba->hba_flag & FCF_TS_INPROG) { - spin_unlock_irqrestore(&phba->hbalock, iflags); + if (test_bit(FCF_TS_INPROG, &phba->hba_flag)) return; - } /* This is the initial FCF discovery scan */ + spin_lock_irqsave(&phba->hbalock, iflags); phba->fcf.fcf_flag |= FCF_INIT_DISC; spin_unlock_irqrestore(&phba->hbalock, iflags); lpfc_printf_log(phba, KERN_INFO, LOG_FIP | LOG_DISCOVERY, @@ -5736,7 +5725,7 @@ lpfc_setup_disc_node(struct lpfc_vport *vport, uint32_t did) return ndlp; if (ndlp->nlp_state > NLP_STE_UNUSED_NODE && - ndlp->nlp_state < NLP_STE_PRLI_ISSUE) { + ndlp->nlp_state <= NLP_STE_PRLI_ISSUE) { lpfc_disc_state_machine(vport, ndlp, NULL, NLP_EVT_DEVICE_RECOVERY); } @@ -6997,11 +6986,11 @@ lpfc_unregister_unused_fcf(struct lpfc_hba *phba) * registered, do nothing. */ spin_lock_irq(&phba->hbalock); - if (!(phba->hba_flag & HBA_FCOE_MODE) || + if (!test_bit(HBA_FCOE_MODE, &phba->hba_flag) || !(phba->fcf.fcf_flag & FCF_REGISTERED) || - !(phba->hba_flag & HBA_FIP_SUPPORT) || + !test_bit(HBA_FIP_SUPPORT, &phba->hba_flag) || (phba->fcf.fcf_flag & FCF_DISCOVERY) || - (phba->pport->port_state == LPFC_FLOGI)) { + phba->pport->port_state == LPFC_FLOGI) { spin_unlock_irq(&phba->hbalock); return; } diff --git a/drivers/scsi/lpfc/lpfc_hw4.h b/drivers/scsi/lpfc/lpfc_hw4.h index 367e6b066d..500253007b 100644 --- a/drivers/scsi/lpfc/lpfc_hw4.h +++ b/drivers/scsi/lpfc/lpfc_hw4.h @@ -2146,6 +2146,14 @@ struct sli4_sge { /* SLI-4 */ uint32_t sge_len; }; +struct sli4_sge_le { + __le32 addr_hi; + __le32 addr_lo; + + __le32 word2; + __le32 sge_len; +}; + struct sli4_hybrid_sgl { struct list_head list_node; struct sli4_sge *dma_sgl; diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index f7a0aa3625..e1dfa96c2a 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c @@ -567,7 +567,7 @@ lpfc_config_port_post(struct lpfc_hba *phba) spin_lock_irq(&phba->hbalock); /* Initialize ERATT handling flag */ - phba->hba_flag &= ~HBA_ERATT_HANDLED; + clear_bit(HBA_ERATT_HANDLED, &phba->hba_flag); /* Enable appropriate host interrupts */ if (lpfc_readl(phba->HCregaddr, &status)) { @@ -599,13 +599,14 @@ lpfc_config_port_post(struct lpfc_hba *phba) /* Set up heart beat (HB) timer */ mod_timer(&phba->hb_tmofunc, jiffies + msecs_to_jiffies(1000 * LPFC_HB_MBOX_INTERVAL)); - phba->hba_flag &= ~(HBA_HBEAT_INP | HBA_HBEAT_TMO); + clear_bit(HBA_HBEAT_INP, &phba->hba_flag); + clear_bit(HBA_HBEAT_TMO, &phba->hba_flag); phba->last_completion_time = jiffies; /* Set up error attention (ERATT) polling timer */ mod_timer(&phba->eratt_poll, jiffies + msecs_to_jiffies(1000 * phba->eratt_poll_interval)); - if (phba->hba_flag & LINK_DISABLED) { + if (test_bit(LINK_DISABLED, &phba->hba_flag)) { lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT, "2598 Adapter Link is disabled.\n"); lpfc_down_link(phba, pmb); @@ -925,9 +926,7 @@ lpfc_sli4_free_sp_events(struct lpfc_hba *phba) struct hbq_dmabuf *dmabuf; struct lpfc_cq_event *cq_event; - spin_lock_irq(&phba->hbalock); - phba->hba_flag &= ~HBA_SP_QUEUE_EVT; - spin_unlock_irq(&phba->hbalock); + clear_bit(HBA_SP_QUEUE_EVT, &phba->hba_flag); while (!list_empty(&phba->sli4_hba.sp_queue_event)) { /* Get the response iocb from the head of work queue */ @@ -1228,18 +1227,15 @@ static void lpfc_rrq_timeout(struct timer_list *t) { struct lpfc_hba *phba; - unsigned long iflag; phba = from_timer(phba, t, rrq_tmr); - spin_lock_irqsave(&phba->pport->work_port_lock, iflag); - if (!test_bit(FC_UNLOADING, &phba->pport->load_flag)) - phba->hba_flag |= HBA_RRQ_ACTIVE; - else - phba->hba_flag &= ~HBA_RRQ_ACTIVE; - spin_unlock_irqrestore(&phba->pport->work_port_lock, iflag); + if (test_bit(FC_UNLOADING, &phba->pport->load_flag)) { + clear_bit(HBA_RRQ_ACTIVE, &phba->hba_flag); + return; + } - if (!test_bit(FC_UNLOADING, &phba->pport->load_flag)) - lpfc_worker_wake_up(phba); + set_bit(HBA_RRQ_ACTIVE, &phba->hba_flag); + lpfc_worker_wake_up(phba); } /** @@ -1261,11 +1257,8 @@ lpfc_rrq_timeout(struct timer_list *t) static void lpfc_hb_mbox_cmpl(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmboxq) { - unsigned long drvr_flag; - - spin_lock_irqsave(&phba->hbalock, drvr_flag); - phba->hba_flag &= ~(HBA_HBEAT_INP | HBA_HBEAT_TMO); - spin_unlock_irqrestore(&phba->hbalock, drvr_flag); + clear_bit(HBA_HBEAT_INP, &phba->hba_flag); + clear_bit(HBA_HBEAT_TMO, &phba->hba_flag); /* Check and reset heart-beat timer if necessary */ mempool_free(pmboxq, phba->mbox_mem_pool); @@ -1457,7 +1450,7 @@ lpfc_issue_hb_mbox(struct lpfc_hba *phba) int retval; /* Is a Heartbeat mbox already in progress */ - if (phba->hba_flag & HBA_HBEAT_INP) + if (test_bit(HBA_HBEAT_INP, &phba->hba_flag)) return 0; pmboxq = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); @@ -1473,7 +1466,7 @@ lpfc_issue_hb_mbox(struct lpfc_hba *phba) mempool_free(pmboxq, phba->mbox_mem_pool); return -ENXIO; } - phba->hba_flag |= HBA_HBEAT_INP; + set_bit(HBA_HBEAT_INP, &phba->hba_flag); return 0; } @@ -1493,7 +1486,7 @@ lpfc_issue_hb_tmo(struct lpfc_hba *phba) { if (phba->cfg_enable_hba_heartbeat) return; - phba->hba_flag |= HBA_HBEAT_TMO; + set_bit(HBA_HBEAT_TMO, &phba->hba_flag); } /** @@ -1565,7 +1558,7 @@ lpfc_hb_timeout_handler(struct lpfc_hba *phba) msecs_to_jiffies(1000 * LPFC_HB_MBOX_INTERVAL), jiffies)) { spin_unlock_irq(&phba->pport->work_port_lock); - if (phba->hba_flag & HBA_HBEAT_INP) + if (test_bit(HBA_HBEAT_INP, &phba->hba_flag)) tmo = (1000 * LPFC_HB_MBOX_TIMEOUT); else tmo = (1000 * LPFC_HB_MBOX_INTERVAL); @@ -1574,7 +1567,7 @@ lpfc_hb_timeout_handler(struct lpfc_hba *phba) spin_unlock_irq(&phba->pport->work_port_lock); /* Check if a MBX_HEARTBEAT is already in progress */ - if (phba->hba_flag & HBA_HBEAT_INP) { + if (test_bit(HBA_HBEAT_INP, &phba->hba_flag)) { /* * If heart beat timeout called with HBA_HBEAT_INP set * we need to give the hb mailbox cmd a chance to @@ -1611,7 +1604,7 @@ lpfc_hb_timeout_handler(struct lpfc_hba *phba) } } else { /* Check to see if we want to force a MBX_HEARTBEAT */ - if (phba->hba_flag & HBA_HBEAT_TMO) { + if (test_bit(HBA_HBEAT_TMO, &phba->hba_flag)) { retval = lpfc_issue_hb_mbox(phba); if (retval) tmo = (1000 * LPFC_HB_MBOX_INTERVAL); @@ -1699,9 +1692,7 @@ lpfc_handle_deferred_eratt(struct lpfc_hba *phba) * since we cannot communicate with the pci card anyway. */ if (pci_channel_offline(phba->pcidev)) { - spin_lock_irq(&phba->hbalock); - phba->hba_flag &= ~DEFER_ERATT; - spin_unlock_irq(&phba->hbalock); + clear_bit(DEFER_ERATT, &phba->hba_flag); return; } @@ -1752,9 +1743,7 @@ lpfc_handle_deferred_eratt(struct lpfc_hba *phba) if (!phba->work_hs && !test_bit(FC_UNLOADING, &phba->pport->load_flag)) phba->work_hs = old_host_status & ~HS_FFER1; - spin_lock_irq(&phba->hbalock); - phba->hba_flag &= ~DEFER_ERATT; - spin_unlock_irq(&phba->hbalock); + clear_bit(DEFER_ERATT, &phba->hba_flag); phba->work_status[0] = readl(phba->MBslimaddr + 0xa8); phba->work_status[1] = readl(phba->MBslimaddr + 0xac); } @@ -1798,9 +1787,7 @@ lpfc_handle_eratt_s3(struct lpfc_hba *phba) * since we cannot communicate with the pci card anyway. */ if (pci_channel_offline(phba->pcidev)) { - spin_lock_irq(&phba->hbalock); - phba->hba_flag &= ~DEFER_ERATT; - spin_unlock_irq(&phba->hbalock); + clear_bit(DEFER_ERATT, &phba->hba_flag); return; } @@ -1811,7 +1798,7 @@ lpfc_handle_eratt_s3(struct lpfc_hba *phba) /* Send an internal error event to mgmt application */ lpfc_board_errevt_to_mgmt(phba); - if (phba->hba_flag & DEFER_ERATT) + if (test_bit(DEFER_ERATT, &phba->hba_flag)) lpfc_handle_deferred_eratt(phba); if ((phba->work_hs & HS_FFER6) || (phba->work_hs & HS_FFER8)) { @@ -2026,7 +2013,7 @@ lpfc_handle_eratt_s4(struct lpfc_hba *phba) /* consider PCI bus read error as pci_channel_offline */ if (pci_rd_rc1 == -EIO && pci_rd_rc2 == -EIO) return; - if (!(phba->hba_flag & HBA_RECOVERABLE_UE)) { + if (!test_bit(HBA_RECOVERABLE_UE, &phba->hba_flag)) { lpfc_sli4_offline_eratt(phba); return; } @@ -3319,9 +3306,10 @@ lpfc_stop_hba_timers(struct lpfc_hba *phba) del_timer_sync(&phba->hb_tmofunc); if (phba->sli_rev == LPFC_SLI_REV4) { del_timer_sync(&phba->rrq_tmr); - phba->hba_flag &= ~HBA_RRQ_ACTIVE; + clear_bit(HBA_RRQ_ACTIVE, &phba->hba_flag); } - phba->hba_flag &= ~(HBA_HBEAT_INP | HBA_HBEAT_TMO); + clear_bit(HBA_HBEAT_INP, &phba->hba_flag); + clear_bit(HBA_HBEAT_TMO, &phba->hba_flag); switch (phba->pci_dev_grp) { case LPFC_PCI_DEV_LP: @@ -4785,7 +4773,10 @@ lpfc_create_port(struct lpfc_hba *phba, int instance, struct device *dev) shost->max_id = LPFC_MAX_TARGET; shost->max_lun = vport->cfg_max_luns; shost->this_id = -1; - shost->max_cmd_len = 16; + if (phba->sli_rev == LPFC_SLI_REV4) + shost->max_cmd_len = LPFC_FCP_CDB_LEN_32; + else + shost->max_cmd_len = LPFC_FCP_CDB_LEN; if (phba->sli_rev == LPFC_SLI_REV4) { if (!phba->cfg_fcp_mq_threshold || @@ -4976,7 +4967,7 @@ static void lpfc_host_supported_speeds_set(struct Scsi_Host *shost) * Avoid reporting supported link speed for FCoE as it can't be * controlled via FCoE. */ - if (phba->hba_flag & HBA_FCOE_MODE) + if (test_bit(HBA_FCOE_MODE, &phba->hba_flag)) return; if (phba->lmt & LMT_256Gb) @@ -5490,7 +5481,7 @@ lpfc_sli4_async_link_evt(struct lpfc_hba *phba, * For FC Mode: issue the READ_TOPOLOGY mailbox command to fetch * topology info. Note: Optional for non FC-AL ports. */ - if (!(phba->hba_flag & HBA_FCOE_MODE)) { + if (!test_bit(HBA_FCOE_MODE, &phba->hba_flag)) { rc = lpfc_sli_issue_mbox(phba, pmb, MBX_NOWAIT); if (rc == MBX_NOT_FINISHED) goto out_free_pmb; @@ -6025,7 +6016,7 @@ lpfc_cmf_timer(struct hrtimer *timer) */ if (phba->cmf_active_mode == LPFC_CFG_MANAGED && phba->link_state != LPFC_LINK_DOWN && - phba->hba_flag & HBA_SETUP) { + test_bit(HBA_SETUP, &phba->hba_flag)) { mbpi = phba->cmf_last_sync_bw; phba->cmf_last_sync_bw = 0; extra = 0; @@ -6778,11 +6769,9 @@ lpfc_sli4_async_fip_evt(struct lpfc_hba *phba, } /* If the FCF discovery is in progress, do nothing. */ - spin_lock_irq(&phba->hbalock); - if (phba->hba_flag & FCF_TS_INPROG) { - spin_unlock_irq(&phba->hbalock); + if (test_bit(FCF_TS_INPROG, &phba->hba_flag)) break; - } + spin_lock_irq(&phba->hbalock); /* If fast FCF failover rescan event is pending, do nothing */ if (phba->fcf.fcf_flag & (FCF_REDISC_EVT | FCF_REDISC_PEND)) { spin_unlock_irq(&phba->hbalock); @@ -7321,9 +7310,7 @@ void lpfc_sli4_async_event_proc(struct lpfc_hba *phba) unsigned long iflags; /* First, declare the async event has been handled */ - spin_lock_irqsave(&phba->hbalock, iflags); - phba->hba_flag &= ~ASYNC_EVENT; - spin_unlock_irqrestore(&phba->hbalock, iflags); + clear_bit(ASYNC_EVENT, &phba->hba_flag); /* Now, handle all the async events */ spin_lock_irqsave(&phba->sli4_hba.asynce_list_lock, iflags); @@ -8247,7 +8234,7 @@ lpfc_sli4_driver_resource_setup(struct lpfc_hba *phba) * our max amount and we need to limit lpfc_sg_seg_cnt * to minimize the risk of running out. */ - phba->cfg_sg_dma_buf_size = sizeof(struct fcp_cmnd) + + phba->cfg_sg_dma_buf_size = sizeof(struct fcp_cmnd32) + sizeof(struct fcp_rsp) + max_buf_size; /* Total SGEs for scsi_sg_list and scsi_sg_prot_list */ @@ -8269,7 +8256,7 @@ lpfc_sli4_driver_resource_setup(struct lpfc_hba *phba) * the FCP rsp, a SGE for each, and a SGE for up to * cfg_sg_seg_cnt data segments. */ - phba->cfg_sg_dma_buf_size = sizeof(struct fcp_cmnd) + + phba->cfg_sg_dma_buf_size = sizeof(struct fcp_cmnd32) + sizeof(struct fcp_rsp) + ((phba->cfg_sg_seg_cnt + extra) * sizeof(struct sli4_sge)); @@ -8332,7 +8319,7 @@ lpfc_sli4_driver_resource_setup(struct lpfc_hba *phba) phba->lpfc_cmd_rsp_buf_pool = dma_pool_create("lpfc_cmd_rsp_buf_pool", &phba->pcidev->dev, - sizeof(struct fcp_cmnd) + + sizeof(struct fcp_cmnd32) + sizeof(struct fcp_rsp), i, 0); if (!phba->lpfc_cmd_rsp_buf_pool) { @@ -9869,41 +9856,38 @@ lpfc_map_topology(struct lpfc_hba *phba, struct lpfc_mbx_read_config *rd_config) return; } /* FW supports persistent topology - override module parameter value */ - phba->hba_flag |= HBA_PERSISTENT_TOPO; + set_bit(HBA_PERSISTENT_TOPO, &phba->hba_flag); /* if ASIC_GEN_NUM >= 0xC) */ if ((bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf) == LPFC_SLI_INTF_IF_TYPE_6) || (bf_get(lpfc_sli_intf_sli_family, &phba->sli4_hba.sli_intf) == LPFC_SLI_INTF_FAMILY_G6)) { - if (!tf) { + if (!tf) phba->cfg_topology = ((pt == LINK_FLAGS_LOOP) ? FLAGS_TOPOLOGY_MODE_LOOP : FLAGS_TOPOLOGY_MODE_PT_PT); - } else { - phba->hba_flag &= ~HBA_PERSISTENT_TOPO; - } + else + clear_bit(HBA_PERSISTENT_TOPO, &phba->hba_flag); } else { /* G5 */ - if (tf) { + if (tf) /* If topology failover set - pt is '0' or '1' */ phba->cfg_topology = (pt ? FLAGS_TOPOLOGY_MODE_PT_LOOP : FLAGS_TOPOLOGY_MODE_LOOP_PT); - } else { + else phba->cfg_topology = ((pt == LINK_FLAGS_P2P) ? FLAGS_TOPOLOGY_MODE_PT_PT : FLAGS_TOPOLOGY_MODE_LOOP); - } } - if (phba->hba_flag & HBA_PERSISTENT_TOPO) { + if (test_bit(HBA_PERSISTENT_TOPO, &phba->hba_flag)) lpfc_printf_log(phba, KERN_INFO, LOG_SLI, "2020 Using persistent topology value [%s]", lpfc_topo_to_str[phba->cfg_topology]); - } else { + else lpfc_printf_log(phba, KERN_WARNING, LOG_SLI, "2021 Invalid topology values from FW " "Using driver parameter defined value [%s]", lpfc_topo_to_str[phba->cfg_topology]); - } } /** @@ -10146,7 +10130,7 @@ lpfc_sli4_read_config(struct lpfc_hba *phba) forced_link_speed = bf_get(lpfc_mbx_rd_conf_link_speed, rd_config); if (forced_link_speed) { - phba->hba_flag |= HBA_FORCED_LINK_SPEED; + set_bit(HBA_FORCED_LINK_SPEED, &phba->hba_flag); switch (forced_link_speed) { case LINK_SPEED_1G: @@ -12241,7 +12225,7 @@ lpfc_sli_enable_intr(struct lpfc_hba *phba, uint32_t cfg_mode) retval = lpfc_sli_config_port(phba, LPFC_SLI_REV3); if (retval) return intr_mode; - phba->hba_flag &= ~HBA_NEEDS_CFG_PORT; + clear_bit(HBA_NEEDS_CFG_PORT, &phba->hba_flag); if (cfg_mode == 2) { /* Now, try to enable MSI-X interrupt mode */ @@ -14812,6 +14796,7 @@ lpfc_pci_probe_one_s4(struct pci_dev *pdev, const struct pci_device_id *pid) goto out_unset_pci_mem_s4; } + spin_lock_init(&phba->rrq_list_lock); INIT_LIST_HEAD(&phba->active_rrq_list); INIT_LIST_HEAD(&phba->fcf.fcf_pri_list); @@ -15528,7 +15513,7 @@ lpfc_io_error_detected(struct pci_dev *pdev, pci_channel_state_t state) pci_ers_result_t rc = PCI_ERS_RESULT_DISCONNECT; if (phba->link_state == LPFC_HBA_ERROR && - phba->hba_flag & HBA_IOQ_FLUSH) + test_bit(HBA_IOQ_FLUSH, &phba->hba_flag)) return PCI_ERS_RESULT_NEED_RESET; switch (phba->pci_dev_grp) { diff --git a/drivers/scsi/lpfc/lpfc_nportdisc.c b/drivers/scsi/lpfc/lpfc_nportdisc.c index c4172791c2..f6a53446e5 100644 --- a/drivers/scsi/lpfc/lpfc_nportdisc.c +++ b/drivers/scsi/lpfc/lpfc_nportdisc.c @@ -47,6 +47,18 @@ #include "lpfc_debugfs.h" +/* Called to clear RSCN discovery flags when driver is unloading. */ +static bool +lpfc_check_unload_and_clr_rscn(unsigned long *fc_flag) +{ + /* If unloading, then clear the FC_RSCN_DEFERRED flag */ + if (test_bit(FC_UNLOADING, fc_flag)) { + clear_bit(FC_RSCN_DEFERRED, fc_flag); + return false; + } + return test_bit(FC_RSCN_DEFERRED, fc_flag); +} + /* Called to verify a rcv'ed ADISC was intended for us. */ static int lpfc_check_adisc(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, @@ -213,8 +225,10 @@ void lpfc_els_abort(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp) { LIST_HEAD(abort_list); + LIST_HEAD(drv_cmpl_list); struct lpfc_sli_ring *pring; struct lpfc_iocbq *iocb, *next_iocb; + int retval = 0; pring = lpfc_phba_elsring(phba); @@ -250,11 +264,20 @@ lpfc_els_abort(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp) /* Abort the targeted IOs and remove them from the abort list. */ list_for_each_entry_safe(iocb, next_iocb, &abort_list, dlist) { - spin_lock_irq(&phba->hbalock); - list_del_init(&iocb->dlist); - lpfc_sli_issue_abort_iotag(phba, pring, iocb, NULL); - spin_unlock_irq(&phba->hbalock); + spin_lock_irq(&phba->hbalock); + list_del_init(&iocb->dlist); + retval = lpfc_sli_issue_abort_iotag(phba, pring, iocb, NULL); + spin_unlock_irq(&phba->hbalock); + + if (retval && test_bit(FC_UNLOADING, &phba->pport->load_flag)) { + list_del_init(&iocb->list); + list_add_tail(&iocb->list, &drv_cmpl_list); + } } + + lpfc_sli_cancel_iocbs(phba, &drv_cmpl_list, IOSTAT_LOCAL_REJECT, + IOERR_SLI_ABORTED); + /* Make sure HBA is alive */ lpfc_issue_hb_tmo(phba); @@ -481,7 +504,7 @@ lpfc_rcv_plogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, * must have ACCed the remote NPorts FLOGI to us * to make it here. */ - if (phba->hba_flag & HBA_FLOGI_OUTSTANDING) + if (test_bit(HBA_FLOGI_OUTSTANDING, &phba->hba_flag)) lpfc_els_abort_flogi(phba); ed_tov = be32_to_cpu(sp->cmn.e_d_tov); @@ -1604,10 +1627,8 @@ lpfc_device_recov_plogi_issue(struct lpfc_vport *vport, { struct lpfc_hba *phba = vport->phba; - /* Don't do anything that will mess up processing of the - * previous RSCN. - */ - if (test_bit(FC_RSCN_DEFERRED, &vport->fc_flag)) + /* Don't do anything that disrupts the RSCN unless lpfc is unloading. */ + if (lpfc_check_unload_and_clr_rscn(&vport->fc_flag)) return ndlp->nlp_state; /* software abort outstanding PLOGI */ @@ -1790,10 +1811,8 @@ lpfc_device_recov_adisc_issue(struct lpfc_vport *vport, { struct lpfc_hba *phba = vport->phba; - /* Don't do anything that will mess up processing of the - * previous RSCN. - */ - if (test_bit(FC_RSCN_DEFERRED, &vport->fc_flag)) + /* Don't do anything that disrupts the RSCN unless lpfc is unloading. */ + if (lpfc_check_unload_and_clr_rscn(&vport->fc_flag)) return ndlp->nlp_state; /* software abort outstanding ADISC */ @@ -2059,10 +2078,8 @@ lpfc_device_recov_reglogin_issue(struct lpfc_vport *vport, void *arg, uint32_t evt) { - /* Don't do anything that will mess up processing of the - * previous RSCN. - */ - if (test_bit(FC_RSCN_DEFERRED, &vport->fc_flag)) + /* Don't do anything that disrupts the RSCN unless lpfc is unloading. */ + if (lpfc_check_unload_and_clr_rscn(&vport->fc_flag)) return ndlp->nlp_state; ndlp->nlp_prev_state = NLP_STE_REG_LOGIN_ISSUE; @@ -2375,10 +2392,8 @@ lpfc_device_recov_prli_issue(struct lpfc_vport *vport, { struct lpfc_hba *phba = vport->phba; - /* Don't do anything that will mess up processing of the - * previous RSCN. - */ - if (test_bit(FC_RSCN_DEFERRED, &vport->fc_flag)) + /* Don't do anything that disrupts the RSCN unless lpfc is unloading. */ + if (lpfc_check_unload_and_clr_rscn(&vport->fc_flag)) return ndlp->nlp_state; /* software abort outstanding PRLI */ @@ -2894,10 +2909,8 @@ static uint32_t lpfc_device_recov_npr_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, void *arg, uint32_t evt) { - /* Don't do anything that will mess up processing of the - * previous RSCN. - */ - if (test_bit(FC_RSCN_DEFERRED, &vport->fc_flag)) + /* Don't do anything that disrupts the RSCN unless lpfc is unloading. */ + if (lpfc_check_unload_and_clr_rscn(&vport->fc_flag)) return ndlp->nlp_state; lpfc_cancel_retry_delay_tmo(vport, ndlp); diff --git a/drivers/scsi/lpfc/lpfc_nvme.c b/drivers/scsi/lpfc/lpfc_nvme.c index c5792eaf3f..d70da2736c 100644 --- a/drivers/scsi/lpfc/lpfc_nvme.c +++ b/drivers/scsi/lpfc/lpfc_nvme.c @@ -95,7 +95,7 @@ lpfc_nvme_create_queue(struct nvme_fc_local_port *pnvme_lport, vport = lport->vport; if (!vport || test_bit(FC_UNLOADING, &vport->load_flag) || - vport->phba->hba_flag & HBA_IOQ_FLUSH) + test_bit(HBA_IOQ_FLUSH, &vport->phba->hba_flag)) return -ENODEV; qhandle = kzalloc(sizeof(struct lpfc_nvme_qhandle), GFP_KERNEL); @@ -272,7 +272,7 @@ lpfc_nvme_handle_lsreq(struct lpfc_hba *phba, remoteport = lpfc_rport->remoteport; if (!vport->localport || - vport->phba->hba_flag & HBA_IOQ_FLUSH) + test_bit(HBA_IOQ_FLUSH, &vport->phba->hba_flag)) return -EINVAL; lport = vport->localport->private; @@ -569,7 +569,7 @@ __lpfc_nvme_ls_req(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, ndlp->nlp_DID, ntype, nstate); return -ENODEV; } - if (vport->phba->hba_flag & HBA_IOQ_FLUSH) + if (test_bit(HBA_IOQ_FLUSH, &vport->phba->hba_flag)) return -ENODEV; if (!vport->phba->sli4_hba.nvmels_wq) @@ -675,7 +675,7 @@ lpfc_nvme_ls_req(struct nvme_fc_local_port *pnvme_lport, vport = lport->vport; if (test_bit(FC_UNLOADING, &vport->load_flag) || - vport->phba->hba_flag & HBA_IOQ_FLUSH) + test_bit(HBA_IOQ_FLUSH, &vport->phba->hba_flag)) return -ENODEV; atomic_inc(&lport->fc4NvmeLsRequests); @@ -1568,7 +1568,7 @@ lpfc_nvme_fcp_io_submit(struct nvme_fc_local_port *pnvme_lport, phba = vport->phba; if ((unlikely(test_bit(FC_UNLOADING, &vport->load_flag))) || - phba->hba_flag & HBA_IOQ_FLUSH) { + test_bit(HBA_IOQ_FLUSH, &phba->hba_flag)) { lpfc_printf_vlog(vport, KERN_INFO, LOG_NVME_IOERR, "6124 Fail IO, Driver unload\n"); atomic_inc(&lport->xmt_fcp_err); @@ -1909,24 +1909,19 @@ lpfc_nvme_fcp_abort(struct nvme_fc_local_port *pnvme_lport, return; } - /* Guard against IO completion being called at same time */ - spin_lock_irqsave(&lpfc_nbuf->buf_lock, flags); - - /* If the hba is getting reset, this flag is set. It is - * cleared when the reset is complete and rings reestablished. - */ - spin_lock(&phba->hbalock); /* driver queued commands are in process of being flushed */ - if (phba->hba_flag & HBA_IOQ_FLUSH) { - spin_unlock(&phba->hbalock); - spin_unlock_irqrestore(&lpfc_nbuf->buf_lock, flags); + if (test_bit(HBA_IOQ_FLUSH, &phba->hba_flag)) { lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT, "6139 Driver in reset cleanup - flushing " - "NVME Req now. hba_flag x%x\n", + "NVME Req now. hba_flag x%lx\n", phba->hba_flag); return; } + /* Guard against IO completion being called at same time */ + spin_lock_irqsave(&lpfc_nbuf->buf_lock, flags); + spin_lock(&phba->hbalock); + nvmereq_wqe = &lpfc_nbuf->cur_iocbq; /* diff --git a/drivers/scsi/lpfc/lpfc_nvmet.c b/drivers/scsi/lpfc/lpfc_nvmet.c index 561ced5503..5297cacc8b 100644 --- a/drivers/scsi/lpfc/lpfc_nvmet.c +++ b/drivers/scsi/lpfc/lpfc_nvmet.c @@ -1811,7 +1811,9 @@ lpfc_sli4_nvmet_xri_aborted(struct lpfc_hba *phba, ctxp->flag &= ~LPFC_NVME_XBUSY; spin_unlock_irqrestore(&ctxp->ctxlock, iflag); + spin_lock_irqsave(&phba->rrq_list_lock, iflag); rrq_empty = list_empty(&phba->active_rrq_list); + spin_unlock_irqrestore(&phba->rrq_list_lock, iflag); ndlp = lpfc_findnode_did(phba->pport, ctxp->sid); if (ndlp && (ndlp->nlp_state == NLP_STE_UNMAPPED_NODE || @@ -3393,14 +3395,12 @@ lpfc_nvmet_sol_fcp_issue_abort(struct lpfc_hba *phba, /* If the hba is getting reset, this flag is set. It is * cleared when the reset is complete and rings reestablished. */ - spin_lock_irqsave(&phba->hbalock, flags); /* driver queued commands are in process of being flushed */ - if (phba->hba_flag & HBA_IOQ_FLUSH) { - spin_unlock_irqrestore(&phba->hbalock, flags); + if (test_bit(HBA_IOQ_FLUSH, &phba->hba_flag)) { atomic_inc(&tgtp->xmt_abort_rsp_error); lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT, "6163 Driver in reset cleanup - flushing " - "NVME Req now. hba_flag x%x oxid x%x\n", + "NVME Req now. hba_flag x%lx oxid x%x\n", phba->hba_flag, ctxp->oxid); lpfc_sli_release_iocbq(phba, abts_wqeq); spin_lock_irqsave(&ctxp->ctxlock, flags); @@ -3409,6 +3409,7 @@ lpfc_nvmet_sol_fcp_issue_abort(struct lpfc_hba *phba, return 0; } + spin_lock_irqsave(&phba->hbalock, flags); /* Outstanding abort is in progress */ if (abts_wqeq->cmd_flag & LPFC_DRIVER_ABORTED) { spin_unlock_irqrestore(&phba->hbalock, flags); diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c index 4a6e5223a2..98ce9d97a2 100644 --- a/drivers/scsi/lpfc/lpfc_scsi.c +++ b/drivers/scsi/lpfc/lpfc_scsi.c @@ -474,9 +474,11 @@ lpfc_sli4_io_xri_aborted(struct lpfc_hba *phba, ndlp = psb->rdata->pnode; else ndlp = NULL; + spin_unlock_irqrestore(&phba->hbalock, iflag); + spin_lock_irqsave(&phba->rrq_list_lock, iflag); rrq_empty = list_empty(&phba->active_rrq_list); - spin_unlock_irqrestore(&phba->hbalock, iflag); + spin_unlock_irqrestore(&phba->rrq_list_lock, iflag); if (ndlp && !offline) { lpfc_set_rrq_active(phba, ndlp, psb->cur_iocbq.sli4_lxritag, rxid, 1); @@ -598,7 +600,7 @@ lpfc_get_scsi_buf_s4(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp, { struct lpfc_io_buf *lpfc_cmd; struct lpfc_sli4_hdw_queue *qp; - struct sli4_sge *sgl; + struct sli4_sge_le *sgl; dma_addr_t pdma_phys_fcp_rsp; dma_addr_t pdma_phys_fcp_cmd; uint32_t cpu, idx; @@ -649,23 +651,23 @@ lpfc_get_scsi_buf_s4(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp, * The balance are sg list bdes. Initialize the * first two and leave the rest for queuecommand. */ - sgl = (struct sli4_sge *)lpfc_cmd->dma_sgl; + sgl = (struct sli4_sge_le *)lpfc_cmd->dma_sgl; pdma_phys_fcp_cmd = tmp->fcp_cmd_rsp_dma_handle; sgl->addr_hi = cpu_to_le32(putPaddrHigh(pdma_phys_fcp_cmd)); sgl->addr_lo = cpu_to_le32(putPaddrLow(pdma_phys_fcp_cmd)); - sgl->word2 = le32_to_cpu(sgl->word2); - bf_set(lpfc_sli4_sge_last, sgl, 0); - sgl->word2 = cpu_to_le32(sgl->word2); - sgl->sge_len = cpu_to_le32(sizeof(struct fcp_cmnd)); + bf_set_le32(lpfc_sli4_sge_last, sgl, 0); + if (cmnd && cmnd->cmd_len > LPFC_FCP_CDB_LEN) + sgl->sge_len = cpu_to_le32(sizeof(struct fcp_cmnd32)); + else + sgl->sge_len = cpu_to_le32(sizeof(struct fcp_cmnd)); + sgl++; /* Setup the physical region for the FCP RSP */ - pdma_phys_fcp_rsp = pdma_phys_fcp_cmd + sizeof(struct fcp_cmnd); + pdma_phys_fcp_rsp = pdma_phys_fcp_cmd + sizeof(struct fcp_cmnd32); sgl->addr_hi = cpu_to_le32(putPaddrHigh(pdma_phys_fcp_rsp)); sgl->addr_lo = cpu_to_le32(putPaddrLow(pdma_phys_fcp_rsp)); - sgl->word2 = le32_to_cpu(sgl->word2); - bf_set(lpfc_sli4_sge_last, sgl, 1); - sgl->word2 = cpu_to_le32(sgl->word2); + bf_set_le32(lpfc_sli4_sge_last, sgl, 1); sgl->sge_len = cpu_to_le32(sizeof(struct fcp_rsp)); if (lpfc_ndlp_check_qdepth(phba, ndlp)) { @@ -2606,7 +2608,7 @@ lpfc_bg_scsi_prep_dma_buf_s3(struct lpfc_hba *phba, iocb_cmd->ulpLe = 1; fcpdl = lpfc_bg_scsi_adjust_dl(phba, lpfc_cmd); - fcp_cmnd->fcpDl = be32_to_cpu(fcpdl); + fcp_cmnd->fcpDl = cpu_to_be32(fcpdl); /* * Due to difference in data length between DIF/non-DIF paths, @@ -3223,14 +3225,18 @@ lpfc_scsi_prep_dma_buf_s4(struct lpfc_hba *phba, struct lpfc_io_buf *lpfc_cmd) * explicitly reinitialized. * all iocb memory resources are reused. */ - fcp_cmnd->fcpDl = cpu_to_be32(scsi_bufflen(scsi_cmnd)); + if (scsi_cmnd->cmd_len > LPFC_FCP_CDB_LEN) + ((struct fcp_cmnd32 *)fcp_cmnd)->fcpDl = + cpu_to_be32(scsi_bufflen(scsi_cmnd)); + else + fcp_cmnd->fcpDl = cpu_to_be32(scsi_bufflen(scsi_cmnd)); /* Set first-burst provided it was successfully negotiated */ - if (!(phba->hba_flag & HBA_FCOE_MODE) && + if (!test_bit(HBA_FCOE_MODE, &phba->hba_flag) && vport->cfg_first_burst_size && scsi_cmnd->sc_data_direction == DMA_TO_DEVICE) { u32 init_len, total_len; - total_len = be32_to_cpu(fcp_cmnd->fcpDl); + total_len = scsi_bufflen(scsi_cmnd); init_len = min(total_len, vport->cfg_first_burst_size); /* Word 4 & 5 */ @@ -3418,15 +3424,18 @@ lpfc_bg_scsi_prep_dma_buf_s4(struct lpfc_hba *phba, } fcpdl = lpfc_bg_scsi_adjust_dl(phba, lpfc_cmd); - fcp_cmnd->fcpDl = be32_to_cpu(fcpdl); + if (lpfc_cmd->pCmd->cmd_len > LPFC_FCP_CDB_LEN) + ((struct fcp_cmnd32 *)fcp_cmnd)->fcpDl = cpu_to_be32(fcpdl); + else + fcp_cmnd->fcpDl = cpu_to_be32(fcpdl); /* Set first-burst provided it was successfully negotiated */ - if (!(phba->hba_flag & HBA_FCOE_MODE) && + if (!test_bit(HBA_FCOE_MODE, &phba->hba_flag) && vport->cfg_first_burst_size && scsi_cmnd->sc_data_direction == DMA_TO_DEVICE) { u32 init_len, total_len; - total_len = be32_to_cpu(fcp_cmnd->fcpDl); + total_len = fcpdl; init_len = min(total_len, vport->cfg_first_burst_size); /* Word 4 & 5 */ @@ -3434,8 +3443,7 @@ lpfc_bg_scsi_prep_dma_buf_s4(struct lpfc_hba *phba, wqe->fcp_iwrite.total_xfer_len = total_len; } else { /* Word 4 */ - wqe->fcp_iwrite.total_xfer_len = - be32_to_cpu(fcp_cmnd->fcpDl); + wqe->fcp_iwrite.total_xfer_len = fcpdl; } /* @@ -3892,7 +3900,10 @@ lpfc_handle_fcp_err(struct lpfc_vport *vport, struct lpfc_io_buf *lpfc_cmd, fcprsp->rspInfo3); scsi_set_resid(cmnd, 0); - fcpDl = be32_to_cpu(fcpcmd->fcpDl); + if (cmnd->cmd_len > LPFC_FCP_CDB_LEN) + fcpDl = be32_to_cpu(((struct fcp_cmnd32 *)fcpcmd)->fcpDl); + else + fcpDl = be32_to_cpu(fcpcmd->fcpDl); if (resp_info & RESID_UNDER) { scsi_set_resid(cmnd, be32_to_cpu(fcprsp->rspResId)); @@ -4721,6 +4732,14 @@ static int lpfc_scsi_prep_cmnd_buf_s4(struct lpfc_vport *vport, bf_set(wqe_iod, &wqe->fcp_iread.wqe_com, LPFC_WQE_IOD_NONE); } + + /* Additional fcp cdb length field calculation. + * LPFC_FCP_CDB_LEN_32 - normal 16 byte cdb length, + * then divide by 4 for the word count. + * shift 2 because of the RDDATA/WRDATA. + */ + if (scsi_cmnd->cmd_len > LPFC_FCP_CDB_LEN) + fcp_cmnd->fcpCntl3 |= 4 << 2; } else { /* From the icmnd template, initialize words 4 - 11 */ memcpy(&wqe->words[4], &lpfc_icmnd_cmd_template.words[4], @@ -4741,7 +4760,7 @@ static int lpfc_scsi_prep_cmnd_buf_s4(struct lpfc_vport *vport, /* Word 3 */ bf_set(payload_offset_len, &wqe->fcp_icmd, - sizeof(struct fcp_cmnd) + sizeof(struct fcp_rsp)); + sizeof(struct fcp_cmnd32) + sizeof(struct fcp_rsp)); /* Word 6 */ bf_set(wqe_ctxt_tag, &wqe->generic.wqe_com, @@ -4796,7 +4815,7 @@ lpfc_scsi_prep_cmnd(struct lpfc_vport *vport, struct lpfc_io_buf *lpfc_cmd, int_to_scsilun(lpfc_cmd->pCmd->device->lun, &lpfc_cmd->fcp_cmnd->fcp_lun); - ptr = &fcp_cmnd->fcpCdb[0]; + ptr = &((struct fcp_cmnd32 *)fcp_cmnd)->fcpCdb[0]; memcpy(ptr, scsi_cmnd->cmnd, scsi_cmnd->cmd_len); if (scsi_cmnd->cmd_len < LPFC_FCP_CDB_LEN) { ptr += scsi_cmnd->cmd_len; @@ -5041,7 +5060,7 @@ lpfc_check_pci_resettable(struct lpfc_hba *phba) /* Check for valid Emulex Device ID */ if (phba->sli_rev != LPFC_SLI_REV4 || - phba->hba_flag & HBA_FCOE_MODE) { + test_bit(HBA_FCOE_MODE, &phba->hba_flag)) { lpfc_printf_log(phba, KERN_INFO, LOG_INIT, "8347 Incapable PCI reset device: " "0x%04x\n", ptr->device); @@ -5327,7 +5346,7 @@ lpfc_queuecommand(struct Scsi_Host *shost, struct scsi_cmnd *cmnd) cmnd->cmnd[0], scsi_prot_ref_tag(cmnd), scsi_logical_block_count(cmnd), - (cmnd->cmnd[1]>>5)); + scsi_get_prot_type(cmnd)); } err = lpfc_bg_scsi_prep_dma_buf(phba, lpfc_cmd); } else { @@ -5518,7 +5537,7 @@ lpfc_abort_handler(struct scsi_cmnd *cmnd) spin_lock(&phba->hbalock); /* driver queued commands are in process of being flushed */ - if (phba->hba_flag & HBA_IOQ_FLUSH) { + if (test_bit(HBA_IOQ_FLUSH, &phba->hba_flag)) { lpfc_printf_vlog(vport, KERN_WARNING, LOG_FCP, "3168 SCSI Layer abort requested I/O has been " "flushed by LLD.\n"); diff --git a/drivers/scsi/lpfc/lpfc_scsi.h b/drivers/scsi/lpfc/lpfc_scsi.h index eae56944f3..a05d203e47 100644 --- a/drivers/scsi/lpfc/lpfc_scsi.h +++ b/drivers/scsi/lpfc/lpfc_scsi.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-2024 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. * @@ -24,6 +24,7 @@ struct lpfc_hba; #define LPFC_FCP_CDB_LEN 16 +#define LPFC_FCP_CDB_LEN_32 32 #define list_remove_head(list, entry, type, member) \ do { \ @@ -99,17 +100,11 @@ struct fcp_rsp { #define SNSCOD_BADCMD 0x20 /* sense code is byte 13 ([12]) */ }; -struct fcp_cmnd { - struct scsi_lun fcp_lun; - - uint8_t fcpCntl0; /* FCP_CNTL byte 0 (reserved) */ - uint8_t fcpCntl1; /* FCP_CNTL byte 1 task codes */ #define SIMPLE_Q 0x00 #define HEAD_OF_Q 0x01 #define ORDERED_Q 0x02 #define ACA_Q 0x04 #define UNTAGGED 0x05 - uint8_t fcpCntl2; /* FCP_CTL byte 2 task management codes */ #define FCP_ABORT_TASK_SET 0x02 /* Bit 1 */ #define FCP_CLEAR_TASK_SET 0x04 /* bit 2 */ #define FCP_BUS_RESET 0x08 /* bit 3 */ @@ -117,12 +112,31 @@ struct fcp_cmnd { #define FCP_TARGET_RESET 0x20 /* bit 5 */ #define FCP_CLEAR_ACA 0x40 /* bit 6 */ #define FCP_TERMINATE_TASK 0x80 /* bit 7 */ - uint8_t fcpCntl3; #define WRITE_DATA 0x01 /* Bit 0 */ #define READ_DATA 0x02 /* Bit 1 */ +struct fcp_cmnd { + struct scsi_lun fcp_lun; + + uint8_t fcpCntl0; /* FCP_CNTL byte 0 (reserved) */ + uint8_t fcpCntl1; /* FCP_CNTL byte 1 task codes */ + uint8_t fcpCntl2; /* FCP_CTL byte 2 task management codes */ + uint8_t fcpCntl3; + uint8_t fcpCdb[LPFC_FCP_CDB_LEN]; /* SRB cdb field is copied here */ - uint32_t fcpDl; /* Total transfer length */ + __be32 fcpDl; /* Total transfer length */ + +}; +struct fcp_cmnd32 { + struct scsi_lun fcp_lun; + + uint8_t fcpCntl0; /* FCP_CNTL byte 0 (reserved) */ + uint8_t fcpCntl1; /* FCP_CNTL byte 1 task codes */ + uint8_t fcpCntl2; /* FCP_CTL byte 2 task management codes */ + uint8_t fcpCntl3; + + uint8_t fcpCdb[LPFC_FCP_CDB_LEN_32]; /* SRB cdb field is copied here */ + __be32 fcpDl; /* Total transfer length */ }; diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index a028e008dd..3e55d5edd6 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c @@ -1024,9 +1024,9 @@ lpfc_handle_rrq_active(struct lpfc_hba *phba) unsigned long iflags; LIST_HEAD(send_rrq); - spin_lock_irqsave(&phba->hbalock, iflags); - phba->hba_flag &= ~HBA_RRQ_ACTIVE; + clear_bit(HBA_RRQ_ACTIVE, &phba->hba_flag); next_time = jiffies + msecs_to_jiffies(1000 * (phba->fc_ratov + 1)); + spin_lock_irqsave(&phba->rrq_list_lock, iflags); list_for_each_entry_safe(rrq, nextrrq, &phba->active_rrq_list, list) { if (time_after(jiffies, rrq->rrq_stop_time)) @@ -1034,7 +1034,7 @@ lpfc_handle_rrq_active(struct lpfc_hba *phba) else if (time_before(rrq->rrq_stop_time, next_time)) next_time = rrq->rrq_stop_time; } - spin_unlock_irqrestore(&phba->hbalock, iflags); + spin_unlock_irqrestore(&phba->rrq_list_lock, iflags); if ((!list_empty(&phba->active_rrq_list)) && (!test_bit(FC_UNLOADING, &phba->pport->load_flag))) mod_timer(&phba->rrq_tmr, next_time); @@ -1072,16 +1072,16 @@ lpfc_get_active_rrq(struct lpfc_vport *vport, uint16_t xri, uint32_t did) if (phba->sli_rev != LPFC_SLI_REV4) return NULL; - spin_lock_irqsave(&phba->hbalock, iflags); + spin_lock_irqsave(&phba->rrq_list_lock, iflags); list_for_each_entry_safe(rrq, nextrrq, &phba->active_rrq_list, list) { if (rrq->vport == vport && rrq->xritag == xri && rrq->nlp_DID == did){ list_del(&rrq->list); - spin_unlock_irqrestore(&phba->hbalock, iflags); + spin_unlock_irqrestore(&phba->rrq_list_lock, iflags); return rrq; } } - spin_unlock_irqrestore(&phba->hbalock, iflags); + spin_unlock_irqrestore(&phba->rrq_list_lock, iflags); return NULL; } @@ -1109,7 +1109,7 @@ lpfc_cleanup_vports_rrqs(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) lpfc_sli4_vport_delete_els_xri_aborted(vport); lpfc_sli4_vport_delete_fcp_xri_aborted(vport); } - spin_lock_irqsave(&phba->hbalock, iflags); + spin_lock_irqsave(&phba->rrq_list_lock, iflags); list_for_each_entry_safe(rrq, nextrrq, &phba->active_rrq_list, list) { if (rrq->vport != vport) continue; @@ -1118,7 +1118,7 @@ lpfc_cleanup_vports_rrqs(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) list_move(&rrq->list, &rrq_list); } - spin_unlock_irqrestore(&phba->hbalock, iflags); + spin_unlock_irqrestore(&phba->rrq_list_lock, iflags); list_for_each_entry_safe(rrq, nextrrq, &rrq_list, list) { list_del(&rrq->list); @@ -1179,12 +1179,12 @@ lpfc_set_rrq_active(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp, if (!phba->cfg_enable_rrq) return -EINVAL; - spin_lock_irqsave(&phba->hbalock, iflags); if (test_bit(FC_UNLOADING, &phba->pport->load_flag)) { - phba->hba_flag &= ~HBA_RRQ_ACTIVE; - goto out; + clear_bit(HBA_RRQ_ACTIVE, &phba->hba_flag); + goto outnl; } + spin_lock_irqsave(&phba->hbalock, iflags); if (ndlp->vport && test_bit(FC_UNLOADING, &ndlp->vport->load_flag)) goto out; @@ -1213,16 +1213,18 @@ lpfc_set_rrq_active(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp, rrq->nlp_DID = ndlp->nlp_DID; rrq->vport = ndlp->vport; rrq->rxid = rxid; - spin_lock_irqsave(&phba->hbalock, iflags); + + spin_lock_irqsave(&phba->rrq_list_lock, iflags); empty = list_empty(&phba->active_rrq_list); list_add_tail(&rrq->list, &phba->active_rrq_list); - phba->hba_flag |= HBA_RRQ_ACTIVE; - spin_unlock_irqrestore(&phba->hbalock, iflags); + spin_unlock_irqrestore(&phba->rrq_list_lock, iflags); + set_bit(HBA_RRQ_ACTIVE, &phba->hba_flag); if (empty) lpfc_worker_wake_up(phba); return 0; out: spin_unlock_irqrestore(&phba->hbalock, iflags); +outnl: lpfc_printf_log(phba, KERN_INFO, LOG_SLI, "2921 Can't set rrq active xri:0x%x rxid:0x%x" " DID:0x%x Send:%d\n", @@ -3937,7 +3939,7 @@ void lpfc_poll_eratt(struct timer_list *t) uint64_t sli_intr, cnt; phba = from_timer(phba, t, eratt_poll); - if (!(phba->hba_flag & HBA_SETUP)) + if (!test_bit(HBA_SETUP, &phba->hba_flag)) return; if (test_bit(FC_UNLOADING, &phba->pport->load_flag)) @@ -4522,9 +4524,7 @@ lpfc_sli_handle_slow_ring_event_s4(struct lpfc_hba *phba, unsigned long iflag; int count = 0; - spin_lock_irqsave(&phba->hbalock, iflag); - phba->hba_flag &= ~HBA_SP_QUEUE_EVT; - spin_unlock_irqrestore(&phba->hbalock, iflag); + clear_bit(HBA_SP_QUEUE_EVT, &phba->hba_flag); while (!list_empty(&phba->sli4_hba.sp_queue_event)) { /* Get the response iocb from the head of work queue */ spin_lock_irqsave(&phba->hbalock, iflag); @@ -4681,10 +4681,8 @@ lpfc_sli_flush_io_rings(struct lpfc_hba *phba) uint32_t i; struct lpfc_iocbq *piocb, *next_iocb; - spin_lock_irq(&phba->hbalock); /* Indicate the I/O queues are flushed */ - phba->hba_flag |= HBA_IOQ_FLUSH; - spin_unlock_irq(&phba->hbalock); + set_bit(HBA_IOQ_FLUSH, &phba->hba_flag); /* Look on all the FCP Rings for the iotag */ if (phba->sli_rev >= LPFC_SLI_REV4) { @@ -4762,7 +4760,7 @@ lpfc_sli_brdready_s3(struct lpfc_hba *phba, uint32_t mask) if (lpfc_readl(phba->HSregaddr, &status)) return 1; - phba->hba_flag |= HBA_NEEDS_CFG_PORT; + set_bit(HBA_NEEDS_CFG_PORT, &phba->hba_flag); /* * Check status register every 100ms for 5 retries, then every @@ -4841,7 +4839,7 @@ lpfc_sli_brdready_s4(struct lpfc_hba *phba, uint32_t mask) } else phba->sli4_hba.intr_enable = 0; - phba->hba_flag &= ~HBA_SETUP; + clear_bit(HBA_SETUP, &phba->hba_flag); return retval; } @@ -5093,7 +5091,7 @@ lpfc_sli_brdreset(struct lpfc_hba *phba) /* perform board reset */ phba->fc_eventTag = 0; phba->link_events = 0; - phba->hba_flag |= HBA_NEEDS_CFG_PORT; + set_bit(HBA_NEEDS_CFG_PORT, &phba->hba_flag); if (phba->pport) { phba->pport->fc_myDID = 0; phba->pport->fc_prevDID = 0; @@ -5153,7 +5151,7 @@ lpfc_sli4_brdreset(struct lpfc_hba *phba) /* Reset HBA */ lpfc_printf_log(phba, KERN_INFO, LOG_SLI, - "0295 Reset HBA Data: x%x x%x x%x\n", + "0295 Reset HBA Data: x%x x%x x%lx\n", phba->pport->port_state, psli->sli_flag, phba->hba_flag); @@ -5162,7 +5160,7 @@ lpfc_sli4_brdreset(struct lpfc_hba *phba) phba->link_events = 0; phba->pport->fc_myDID = 0; phba->pport->fc_prevDID = 0; - phba->hba_flag &= ~HBA_SETUP; + clear_bit(HBA_SETUP, &phba->hba_flag); spin_lock_irq(&phba->hbalock); psli->sli_flag &= ~(LPFC_PROCESS_LA); @@ -5406,7 +5404,7 @@ lpfc_sli_chipset_init(struct lpfc_hba *phba) return -EIO; } - phba->hba_flag |= HBA_NEEDS_CFG_PORT; + set_bit(HBA_NEEDS_CFG_PORT, &phba->hba_flag); /* Clear all interrupt enable conditions */ writel(0, phba->HCregaddr); @@ -5708,11 +5706,11 @@ lpfc_sli_hba_setup(struct lpfc_hba *phba) int longs; /* Enable ISR already does config_port because of config_msi mbx */ - if (phba->hba_flag & HBA_NEEDS_CFG_PORT) { + if (test_bit(HBA_NEEDS_CFG_PORT, &phba->hba_flag)) { rc = lpfc_sli_config_port(phba, LPFC_SLI_REV3); if (rc) return -EIO; - phba->hba_flag &= ~HBA_NEEDS_CFG_PORT; + clear_bit(HBA_NEEDS_CFG_PORT, &phba->hba_flag); } phba->fcp_embed_io = 0; /* SLI4 FC support only */ @@ -7759,7 +7757,7 @@ lpfc_set_host_data(struct lpfc_hba *phba, LPFC_MBOXQ_t *mbox) snprintf(mbox->u.mqe.un.set_host_data.un.data, LPFC_HOST_OS_DRIVER_VERSION_SIZE, "Linux %s v"LPFC_DRIVER_VERSION, - (phba->hba_flag & HBA_FCOE_MODE) ? "FCoE" : "FC"); + test_bit(HBA_FCOE_MODE, &phba->hba_flag) ? "FCoE" : "FC"); } int @@ -8487,7 +8485,7 @@ lpfc_sli4_hba_setup(struct lpfc_hba *phba) spin_unlock_irq(&phba->hbalock); } } - phba->hba_flag &= ~HBA_SETUP; + clear_bit(HBA_SETUP, &phba->hba_flag); lpfc_sli4_dip(phba); @@ -8516,25 +8514,26 @@ lpfc_sli4_hba_setup(struct lpfc_hba *phba) mqe = &mboxq->u.mqe; phba->sli_rev = bf_get(lpfc_mbx_rd_rev_sli_lvl, &mqe->un.read_rev); if (bf_get(lpfc_mbx_rd_rev_fcoe, &mqe->un.read_rev)) { - phba->hba_flag |= HBA_FCOE_MODE; + set_bit(HBA_FCOE_MODE, &phba->hba_flag); phba->fcp_embed_io = 0; /* SLI4 FC support only */ } else { - phba->hba_flag &= ~HBA_FCOE_MODE; + clear_bit(HBA_FCOE_MODE, &phba->hba_flag); } if (bf_get(lpfc_mbx_rd_rev_cee_ver, &mqe->un.read_rev) == LPFC_DCBX_CEE_MODE) - phba->hba_flag |= HBA_FIP_SUPPORT; + set_bit(HBA_FIP_SUPPORT, &phba->hba_flag); else - phba->hba_flag &= ~HBA_FIP_SUPPORT; + clear_bit(HBA_FIP_SUPPORT, &phba->hba_flag); - phba->hba_flag &= ~HBA_IOQ_FLUSH; + clear_bit(HBA_IOQ_FLUSH, &phba->hba_flag); if (phba->sli_rev != LPFC_SLI_REV4) { lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT, "0376 READ_REV Error. SLI Level %d " "FCoE enabled %d\n", - phba->sli_rev, phba->hba_flag & HBA_FCOE_MODE); + phba->sli_rev, + test_bit(HBA_FCOE_MODE, &phba->hba_flag) ? 1 : 0); rc = -EIO; kfree(vpd); goto out_free_mbox; @@ -8549,7 +8548,7 @@ lpfc_sli4_hba_setup(struct lpfc_hba *phba) * to read FCoE param config regions, only read parameters if the * board is FCoE */ - if (phba->hba_flag & HBA_FCOE_MODE && + if (test_bit(HBA_FCOE_MODE, &phba->hba_flag) && lpfc_sli4_read_fcoe_params(phba)) lpfc_printf_log(phba, KERN_WARNING, LOG_MBOX | LOG_INIT, "2570 Failed to read FCoE parameters\n"); @@ -8626,7 +8625,7 @@ lpfc_sli4_hba_setup(struct lpfc_hba *phba) lpfc_set_features(phba, mboxq, LPFC_SET_UE_RECOVERY); rc = lpfc_sli_issue_mbox(phba, mboxq, MBX_POLL); if (rc == MBX_SUCCESS) { - phba->hba_flag |= HBA_RECOVERABLE_UE; + set_bit(HBA_RECOVERABLE_UE, &phba->hba_flag); /* Set 1Sec interval to detect UE */ phba->eratt_poll_interval = 1; phba->sli4_hba.ue_to_sr = bf_get( @@ -8677,7 +8676,7 @@ lpfc_sli4_hba_setup(struct lpfc_hba *phba) } /* Performance Hints are ONLY for FCoE */ - if (phba->hba_flag & HBA_FCOE_MODE) { + if (test_bit(HBA_FCOE_MODE, &phba->hba_flag)) { if (bf_get(lpfc_mbx_rq_ftr_rsp_perfh, &mqe->un.req_ftrs)) phba->sli3_options |= LPFC_SLI4_PERFH_ENABLED; else @@ -8936,7 +8935,7 @@ lpfc_sli4_hba_setup(struct lpfc_hba *phba) } lpfc_sli4_node_prep(phba); - if (!(phba->hba_flag & HBA_FCOE_MODE)) { + if (!test_bit(HBA_FCOE_MODE, &phba->hba_flag)) { if ((phba->nvmet_support == 0) || (phba->cfg_nvmet_mrq == 1)) { /* * The FC Port needs to register FCFI (index 0) @@ -9012,7 +9011,8 @@ lpfc_sli4_hba_setup(struct lpfc_hba *phba) /* Start heart beat timer */ mod_timer(&phba->hb_tmofunc, jiffies + msecs_to_jiffies(1000 * LPFC_HB_MBOX_INTERVAL)); - phba->hba_flag &= ~(HBA_HBEAT_INP | HBA_HBEAT_TMO); + clear_bit(HBA_HBEAT_INP, &phba->hba_flag); + clear_bit(HBA_HBEAT_TMO, &phba->hba_flag); phba->last_completion_time = jiffies; /* start eq_delay heartbeat */ @@ -9054,8 +9054,8 @@ lpfc_sli4_hba_setup(struct lpfc_hba *phba) /* Setup CMF after HBA is initialized */ lpfc_cmf_setup(phba); - if (!(phba->hba_flag & HBA_FCOE_MODE) && - (phba->hba_flag & LINK_DISABLED)) { + if (!test_bit(HBA_FCOE_MODE, &phba->hba_flag) && + test_bit(LINK_DISABLED, &phba->hba_flag)) { lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT, "3103 Adapter Link is disabled.\n"); lpfc_down_link(phba, mboxq); @@ -9079,7 +9079,7 @@ lpfc_sli4_hba_setup(struct lpfc_hba *phba) /* Enable RAS FW log support */ lpfc_sli4_ras_setup(phba); - phba->hba_flag |= HBA_SETUP; + set_bit(HBA_SETUP, &phba->hba_flag); return rc; out_io_buff_free: @@ -9383,7 +9383,7 @@ lpfc_sli_issue_mbox_s3(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmbox, } /* If HBA has a deferred error attention, fail the iocb. */ - if (unlikely(phba->hba_flag & DEFER_ERATT)) { + if (unlikely(test_bit(DEFER_ERATT, &phba->hba_flag))) { spin_unlock_irqrestore(&phba->hbalock, drvr_flag); goto out_not_finished; } @@ -10447,7 +10447,7 @@ __lpfc_sli_issue_iocb_s3(struct lpfc_hba *phba, uint32_t ring_number, return IOCB_ERROR; /* If HBA has a deferred error attention, fail the iocb. */ - if (unlikely(phba->hba_flag & DEFER_ERATT)) + if (unlikely(test_bit(DEFER_ERATT, &phba->hba_flag))) return IOCB_ERROR; /* @@ -10579,10 +10579,11 @@ lpfc_prep_embed_io(struct lpfc_hba *phba, struct lpfc_io_buf *lpfc_cmd) { struct lpfc_iocbq *piocb = &lpfc_cmd->cur_iocbq; union lpfc_wqe128 *wqe = &lpfc_cmd->cur_iocbq.wqe; - struct sli4_sge *sgl; + struct sli4_sge_le *sgl; + u32 type_size; /* 128 byte wqe support here */ - sgl = (struct sli4_sge *)lpfc_cmd->dma_sgl; + sgl = (struct sli4_sge_le *)lpfc_cmd->dma_sgl; if (phba->fcp_embed_io) { struct fcp_cmnd *fcp_cmnd; @@ -10591,24 +10592,24 @@ lpfc_prep_embed_io(struct lpfc_hba *phba, struct lpfc_io_buf *lpfc_cmd) fcp_cmnd = lpfc_cmd->fcp_cmnd; /* Word 0-2 - FCP_CMND */ - wqe->generic.bde.tus.f.bdeFlags = - BUFF_TYPE_BDE_IMMED; - wqe->generic.bde.tus.f.bdeSize = sgl->sge_len; + type_size = le32_to_cpu(sgl->sge_len); + type_size |= ULP_BDE64_TYPE_BDE_IMMED; + wqe->generic.bde.tus.w = type_size; wqe->generic.bde.addrHigh = 0; - wqe->generic.bde.addrLow = 88; /* Word 22 */ + wqe->generic.bde.addrLow = 72; /* Word 18 */ bf_set(wqe_wqes, &wqe->fcp_iwrite.wqe_com, 1); bf_set(wqe_dbde, &wqe->fcp_iwrite.wqe_com, 0); - /* Word 22-29 FCP CMND Payload */ - ptr = &wqe->words[22]; - memcpy(ptr, fcp_cmnd, sizeof(struct fcp_cmnd)); + /* Word 18-29 FCP CMND Payload */ + ptr = &wqe->words[18]; + lpfc_sli_pcimem_bcopy(fcp_cmnd, ptr, le32_to_cpu(sgl->sge_len)); } else { /* Word 0-2 - Inline BDE */ wqe->generic.bde.tus.f.bdeFlags = BUFF_TYPE_BDE_64; - wqe->generic.bde.tus.f.bdeSize = sizeof(struct fcp_cmnd); - wqe->generic.bde.addrHigh = sgl->addr_hi; - wqe->generic.bde.addrLow = sgl->addr_lo; + wqe->generic.bde.tus.f.bdeSize = le32_to_cpu(sgl->sge_len); + wqe->generic.bde.addrHigh = le32_to_cpu(sgl->addr_hi); + wqe->generic.bde.addrLow = le32_to_cpu(sgl->addr_lo); /* Word 10 */ bf_set(wqe_dbde, &wqe->generic.wqe_com, 1); @@ -12361,10 +12362,10 @@ lpfc_ignore_els_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, /* ELS cmd tag completes */ lpfc_printf_log(phba, KERN_INFO, LOG_ELS, - "0139 Ignoring ELS cmd code x%x completion Data: " + "0139 Ignoring ELS cmd code x%x ref cnt x%x Data: " "x%x x%x x%x x%px\n", - ulp_command, ulp_status, ulp_word4, iotag, - cmdiocb->ndlp); + ulp_command, kref_read(&cmdiocb->ndlp->kref), + ulp_status, ulp_word4, iotag, cmdiocb->ndlp); /* * Deref the ndlp after free_iocb. sli_release_iocb will access the ndlp * if exchange is busy. @@ -12460,7 +12461,9 @@ lpfc_sli_issue_abort_iotag(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, } } - if (phba->link_state < LPFC_LINK_UP || + /* Just close the exchange under certain conditions. */ + if (test_bit(FC_UNLOADING, &vport->load_flag) || + phba->link_state < LPFC_LINK_UP || (phba->sli_rev == LPFC_SLI_REV4 && phba->sli4_hba.link_state.status == LPFC_FC_LA_TYPE_LINK_DOWN) || (phba->link_flag & LS_EXTERNAL_LOOPBACK)) @@ -12507,10 +12510,10 @@ abort_iotag_exit: lpfc_printf_vlog(vport, KERN_INFO, LOG_SLI, "0339 Abort IO XRI x%x, Original iotag x%x, " "abort tag x%x Cmdjob : x%px Abortjob : x%px " - "retval x%x\n", + "retval x%x : IA %d\n", ulp_context, (phba->sli_rev == LPFC_SLI_REV4) ? cmdiocb->iotag : iotag, iotag, cmdiocb, abtsiocbp, - retval); + retval, ia); if (retval) { cmdiocb->cmd_flag &= ~LPFC_DRIVER_ABORTED; __lpfc_sli_release_iocbq(phba, abtsiocbp); @@ -12775,7 +12778,7 @@ lpfc_sli_abort_iocb(struct lpfc_vport *vport, u16 tgt_id, u64 lun_id, int i; /* all I/Os are in process of being flushed */ - if (phba->hba_flag & HBA_IOQ_FLUSH) + if (test_bit(HBA_IOQ_FLUSH, &phba->hba_flag)) return errcnt; for (i = 1; i <= phba->sli.last_iotag; i++) { @@ -12845,15 +12848,13 @@ lpfc_sli_abort_taskmgmt(struct lpfc_vport *vport, struct lpfc_sli_ring *pring, u16 ulp_context, iotag, cqid = LPFC_WQE_CQ_ID_DEFAULT; bool ia; - spin_lock_irqsave(&phba->hbalock, iflags); - /* all I/Os are in process of being flushed */ - if (phba->hba_flag & HBA_IOQ_FLUSH) { - spin_unlock_irqrestore(&phba->hbalock, iflags); + if (test_bit(HBA_IOQ_FLUSH, &phba->hba_flag)) return 0; - } + sum = 0; + spin_lock_irqsave(&phba->hbalock, iflags); for (i = 1; i <= phba->sli.last_iotag; i++) { iocbq = phba->sli.iocbq_lookup[i]; @@ -13385,7 +13386,7 @@ lpfc_sli_eratt_read(struct lpfc_hba *phba) if ((HS_FFER1 & phba->work_hs) && ((HS_FFER2 | HS_FFER3 | HS_FFER4 | HS_FFER5 | HS_FFER6 | HS_FFER7 | HS_FFER8) & phba->work_hs)) { - phba->hba_flag |= DEFER_ERATT; + set_bit(DEFER_ERATT, &phba->hba_flag); /* Clear all interrupt enable conditions */ writel(0, phba->HCregaddr); readl(phba->HCregaddr); @@ -13394,7 +13395,7 @@ lpfc_sli_eratt_read(struct lpfc_hba *phba) /* Set the driver HA work bitmap */ phba->work_ha |= HA_ERATT; /* Indicate polling handles this ERATT */ - phba->hba_flag |= HBA_ERATT_HANDLED; + set_bit(HBA_ERATT_HANDLED, &phba->hba_flag); return 1; } return 0; @@ -13405,7 +13406,7 @@ unplug_err: /* Set the driver HA work bitmap */ phba->work_ha |= HA_ERATT; /* Indicate polling handles this ERATT */ - phba->hba_flag |= HBA_ERATT_HANDLED; + set_bit(HBA_ERATT_HANDLED, &phba->hba_flag); return 1; } @@ -13441,7 +13442,7 @@ lpfc_sli4_eratt_read(struct lpfc_hba *phba) &uerr_sta_hi)) { phba->work_hs |= UNPLUG_ERR; phba->work_ha |= HA_ERATT; - phba->hba_flag |= HBA_ERATT_HANDLED; + set_bit(HBA_ERATT_HANDLED, &phba->hba_flag); return 1; } if ((~phba->sli4_hba.ue_mask_lo & uerr_sta_lo) || @@ -13457,7 +13458,7 @@ lpfc_sli4_eratt_read(struct lpfc_hba *phba) phba->work_status[0] = uerr_sta_lo; phba->work_status[1] = uerr_sta_hi; phba->work_ha |= HA_ERATT; - phba->hba_flag |= HBA_ERATT_HANDLED; + set_bit(HBA_ERATT_HANDLED, &phba->hba_flag); return 1; } break; @@ -13469,7 +13470,7 @@ lpfc_sli4_eratt_read(struct lpfc_hba *phba) &portsmphr)){ phba->work_hs |= UNPLUG_ERR; phba->work_ha |= HA_ERATT; - phba->hba_flag |= HBA_ERATT_HANDLED; + set_bit(HBA_ERATT_HANDLED, &phba->hba_flag); return 1; } if (bf_get(lpfc_sliport_status_err, &portstat_reg)) { @@ -13492,7 +13493,7 @@ lpfc_sli4_eratt_read(struct lpfc_hba *phba) phba->work_status[0], phba->work_status[1]); phba->work_ha |= HA_ERATT; - phba->hba_flag |= HBA_ERATT_HANDLED; + set_bit(HBA_ERATT_HANDLED, &phba->hba_flag); return 1; } break; @@ -13529,22 +13530,18 @@ lpfc_sli_check_eratt(struct lpfc_hba *phba) return 0; /* Check if interrupt handler handles this ERATT */ - spin_lock_irq(&phba->hbalock); - if (phba->hba_flag & HBA_ERATT_HANDLED) { + if (test_bit(HBA_ERATT_HANDLED, &phba->hba_flag)) /* Interrupt handler has handled ERATT */ - spin_unlock_irq(&phba->hbalock); return 0; - } /* * If there is deferred error attention, do not check for error * attention */ - if (unlikely(phba->hba_flag & DEFER_ERATT)) { - spin_unlock_irq(&phba->hbalock); + if (unlikely(test_bit(DEFER_ERATT, &phba->hba_flag))) return 0; - } + spin_lock_irq(&phba->hbalock); /* If PCI channel is offline, don't process it */ if (unlikely(pci_channel_offline(phba->pcidev))) { spin_unlock_irq(&phba->hbalock); @@ -13666,19 +13663,17 @@ lpfc_sli_sp_intr_handler(int irq, void *dev_id) ha_copy &= ~HA_ERATT; /* Check the need for handling ERATT in interrupt handler */ if (ha_copy & HA_ERATT) { - if (phba->hba_flag & HBA_ERATT_HANDLED) + if (test_and_set_bit(HBA_ERATT_HANDLED, + &phba->hba_flag)) /* ERATT polling has handled ERATT */ ha_copy &= ~HA_ERATT; - else - /* Indicate interrupt handler handles ERATT */ - phba->hba_flag |= HBA_ERATT_HANDLED; } /* * If there is deferred error attention, do not check for any * interrupt. */ - if (unlikely(phba->hba_flag & DEFER_ERATT)) { + if (unlikely(test_bit(DEFER_ERATT, &phba->hba_flag))) { spin_unlock_irqrestore(&phba->hbalock, iflag); return IRQ_NONE; } @@ -13774,7 +13769,7 @@ lpfc_sli_sp_intr_handler(int irq, void *dev_id) ((HS_FFER2 | HS_FFER3 | HS_FFER4 | HS_FFER5 | HS_FFER6 | HS_FFER7 | HS_FFER8) & phba->work_hs)) { - phba->hba_flag |= DEFER_ERATT; + set_bit(DEFER_ERATT, &phba->hba_flag); /* Clear all interrupt enable conditions */ writel(0, phba->HCregaddr); readl(phba->HCregaddr); @@ -13961,16 +13956,16 @@ lpfc_sli_fp_intr_handler(int irq, void *dev_id) /* Need to read HA REG for FCP ring and other ring events */ if (lpfc_readl(phba->HAregaddr, &ha_copy)) return IRQ_HANDLED; - /* Clear up only attention source related to fast-path */ - spin_lock_irqsave(&phba->hbalock, iflag); + /* * If there is deferred error attention, do not check for * any interrupt. */ - if (unlikely(phba->hba_flag & DEFER_ERATT)) { - spin_unlock_irqrestore(&phba->hbalock, iflag); + if (unlikely(test_bit(DEFER_ERATT, &phba->hba_flag))) return IRQ_NONE; - } + + /* Clear up only attention source related to fast-path */ + spin_lock_irqsave(&phba->hbalock, iflag); writel((ha_copy & (HA_R0_CLR_MSK | HA_R1_CLR_MSK)), phba->HAregaddr); readl(phba->HAregaddr); /* flush */ @@ -14053,18 +14048,15 @@ lpfc_sli_intr_handler(int irq, void *dev_id) spin_unlock(&phba->hbalock); return IRQ_NONE; } else if (phba->ha_copy & HA_ERATT) { - if (phba->hba_flag & HBA_ERATT_HANDLED) + if (test_and_set_bit(HBA_ERATT_HANDLED, &phba->hba_flag)) /* ERATT polling has handled ERATT */ phba->ha_copy &= ~HA_ERATT; - else - /* Indicate interrupt handler handles ERATT */ - phba->hba_flag |= HBA_ERATT_HANDLED; } /* * If there is deferred error attention, do not check for any interrupt. */ - if (unlikely(phba->hba_flag & DEFER_ERATT)) { + if (unlikely(test_bit(DEFER_ERATT, &phba->hba_flag))) { spin_unlock(&phba->hbalock); return IRQ_NONE; } @@ -14135,9 +14127,7 @@ void lpfc_sli4_els_xri_abort_event_proc(struct lpfc_hba *phba) unsigned long iflags; /* First, declare the els xri abort event has been handled */ - spin_lock_irqsave(&phba->hbalock, iflags); - phba->hba_flag &= ~ELS_XRI_ABORT_EVENT; - spin_unlock_irqrestore(&phba->hbalock, iflags); + clear_bit(ELS_XRI_ABORT_EVENT, &phba->hba_flag); /* Now, handle all the els xri abort events */ spin_lock_irqsave(&phba->sli4_hba.els_xri_abrt_list_lock, iflags); @@ -14263,9 +14253,7 @@ lpfc_sli4_sp_handle_async_event(struct lpfc_hba *phba, struct lpfc_mcqe *mcqe) spin_unlock_irqrestore(&phba->sli4_hba.asynce_list_lock, iflags); /* Set the async event flag */ - spin_lock_irqsave(&phba->hbalock, iflags); - phba->hba_flag |= ASYNC_EVENT; - spin_unlock_irqrestore(&phba->hbalock, iflags); + set_bit(ASYNC_EVENT, &phba->hba_flag); return true; } @@ -14505,8 +14493,8 @@ lpfc_sli4_sp_handle_els_wcqe(struct lpfc_hba *phba, struct lpfc_queue *cq, spin_lock_irqsave(&phba->hbalock, iflags); list_add_tail(&irspiocbq->cq_event.list, &phba->sli4_hba.sp_queue_event); - phba->hba_flag |= HBA_SP_QUEUE_EVT; spin_unlock_irqrestore(&phba->hbalock, iflags); + set_bit(HBA_SP_QUEUE_EVT, &phba->hba_flag); return true; } @@ -14580,7 +14568,7 @@ lpfc_sli4_sp_handle_abort_xri_wcqe(struct lpfc_hba *phba, list_add_tail(&cq_event->list, &phba->sli4_hba.sp_els_xri_aborted_work_queue); /* Set the els xri abort event flag */ - phba->hba_flag |= ELS_XRI_ABORT_EVENT; + set_bit(ELS_XRI_ABORT_EVENT, &phba->hba_flag); spin_unlock_irqrestore(&phba->sli4_hba.els_xri_abrt_list_lock, iflags); workposted = true; @@ -14667,9 +14655,9 @@ lpfc_sli4_sp_handle_rcqe(struct lpfc_hba *phba, struct lpfc_rcqe *rcqe) /* save off the frame for the work thread to process */ list_add_tail(&dma_buf->cq_event.list, &phba->sli4_hba.sp_queue_event); - /* Frame received */ - phba->hba_flag |= HBA_SP_QUEUE_EVT; spin_unlock_irqrestore(&phba->hbalock, iflags); + /* Frame received */ + set_bit(HBA_SP_QUEUE_EVT, &phba->hba_flag); workposted = true; break; case FC_STATUS_INSUFF_BUF_FRM_DISC: @@ -14689,9 +14677,7 @@ lpfc_sli4_sp_handle_rcqe(struct lpfc_hba *phba, struct lpfc_rcqe *rcqe) case FC_STATUS_INSUFF_BUF_NEED_BUF: hrq->RQ_no_posted_buf++; /* Post more buffers if possible */ - spin_lock_irqsave(&phba->hbalock, iflags); - phba->hba_flag |= HBA_POST_RECEIVE_BUFFER; - spin_unlock_irqrestore(&phba->hbalock, iflags); + set_bit(HBA_POST_RECEIVE_BUFFER, &phba->hba_flag); workposted = true; break; case FC_STATUS_RQ_DMA_FAILURE: @@ -19349,8 +19335,8 @@ lpfc_sli4_handle_mds_loopback(struct lpfc_vport *vport, spin_lock_irqsave(&phba->hbalock, iflags); list_add_tail(&dmabuf->cq_event.list, &phba->sli4_hba.sp_queue_event); - phba->hba_flag |= HBA_SP_QUEUE_EVT; spin_unlock_irqrestore(&phba->hbalock, iflags); + set_bit(HBA_SP_QUEUE_EVT, &phba->hba_flag); lpfc_worker_wake_up(phba); return; } @@ -20102,9 +20088,7 @@ lpfc_sli4_fcf_scan_read_fcf_rec(struct lpfc_hba *phba, uint16_t fcf_index) mboxq->vport = phba->pport; mboxq->mbox_cmpl = lpfc_mbx_cmpl_fcf_scan_read_fcf_rec; - spin_lock_irq(&phba->hbalock); - phba->hba_flag |= FCF_TS_INPROG; - spin_unlock_irq(&phba->hbalock); + set_bit(FCF_TS_INPROG, &phba->hba_flag); rc = lpfc_sli_issue_mbox(phba, mboxq, MBX_NOWAIT); if (rc == MBX_NOT_FINISHED) @@ -20120,9 +20104,7 @@ fail_fcf_scan: if (mboxq) lpfc_sli4_mbox_cmd_free(phba, mboxq); /* FCF scan failed, clear FCF_TS_INPROG flag */ - spin_lock_irq(&phba->hbalock); - phba->hba_flag &= ~FCF_TS_INPROG; - spin_unlock_irq(&phba->hbalock); + clear_bit(FCF_TS_INPROG, &phba->hba_flag); } return error; } @@ -20779,7 +20761,7 @@ lpfc_sli_read_link_ste(struct lpfc_hba *phba) /* This HBA contains PORT_STE configured */ if (!rgn23_data[offset + 2]) - phba->hba_flag |= LINK_DISABLED; + set_bit(LINK_DISABLED, &phba->hba_flag); goto out; } @@ -22488,7 +22470,7 @@ lpfc_get_cmd_rsp_buf_per_hdwq(struct lpfc_hba *phba, } tmp->fcp_rsp = (struct fcp_rsp *)((uint8_t *)tmp->fcp_cmnd + - sizeof(struct fcp_cmnd)); + sizeof(struct fcp_cmnd32)); spin_lock_irqsave(&hdwq->hdwq_lock, iflags); list_add_tail(&tmp->list_node, &lpfc_buf->dma_cmd_rsp_list); @@ -22593,12 +22575,13 @@ lpfc_sli_prep_wqe(struct lpfc_hba *phba, struct lpfc_iocbq *job) u8 cmnd; u32 *pcmd; u32 if_type = 0; - u32 fip, abort_tag; + u32 abort_tag; + bool fip; struct lpfc_nodelist *ndlp = NULL; union lpfc_wqe128 *wqe = &job->wqe; u8 command_type = ELS_COMMAND_NON_FIP; - fip = phba->hba_flag & HBA_FIP_SUPPORT; + fip = test_bit(HBA_FIP_SUPPORT, &phba->hba_flag); /* The fcp commands will set command type */ if (job->cmd_flag & LPFC_IO_FCP) command_type = FCP_COMMAND; diff --git a/drivers/scsi/lpfc/lpfc_version.h b/drivers/scsi/lpfc/lpfc_version.h index 915f2f11fb..f06087e478 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.4.0.1" +#define LPFC_DRIVER_VERSION "14.4.0.2" #define LPFC_DRIVER_NAME "lpfc" /* Used for SLI 2/3 */ diff --git a/drivers/scsi/mac_scsi.c b/drivers/scsi/mac_scsi.c index 181f16899f..a402c4dc46 100644 --- a/drivers/scsi/mac_scsi.c +++ b/drivers/scsi/mac_scsi.c @@ -534,7 +534,13 @@ static void __exit mac_scsi_remove(struct platform_device *pdev) scsi_host_put(instance); } -static struct platform_driver mac_scsi_driver = { +/* + * mac_scsi_remove() lives in .exit.text. For drivers registered via + * module_platform_driver_probe() this is ok because they cannot get unbound at + * runtime. So mark the driver struct with __refdata to prevent modpost + * triggering a section mismatch warning. + */ +static struct platform_driver mac_scsi_driver __refdata = { .remove_new = __exit_p(mac_scsi_remove), .driver = { .name = DRV_MODULE_NAME, diff --git a/drivers/scsi/megaraid/Kconfig.megaraid b/drivers/scsi/megaraid/Kconfig.megaraid index 3f2ce1eb08..56b76d7389 100644 --- a/drivers/scsi/megaraid/Kconfig.megaraid +++ b/drivers/scsi/megaraid/Kconfig.megaraid @@ -3,85 +3,84 @@ config MEGARAID_NEWGEN bool "LSI Logic New Generation RAID Device Drivers" depends on PCI && HAS_IOPORT && SCSI help - LSI Logic RAID Device Drivers + LSI Logic RAID Device Drivers config MEGARAID_MM tristate "LSI Logic Management Module (New Driver)" depends on PCI && HAS_IOPORT && SCSI && MEGARAID_NEWGEN help - Management Module provides ioctl, sysfs support for LSI Logic - RAID controllers. - To compile this driver as a module, choose M here: the - module will be called megaraid_mm + Management Module provides ioctl, sysfs support for LSI Logic + RAID controllers. + To compile this driver as a module, choose M here: the + module will be called megaraid_mm config MEGARAID_MAILBOX tristate "LSI Logic MegaRAID Driver (New Driver)" depends on PCI && SCSI && MEGARAID_MM help - List of supported controllers + List of supported controllers - OEM Product Name VID :DID :SVID:SSID - --- ------------ ---- ---- ---- ---- - Dell PERC3/QC 101E:1960:1028:0471 - Dell PERC3/DC 101E:1960:1028:0493 - Dell PERC3/SC 101E:1960:1028:0475 - Dell PERC3/Di 1028:000E:1028:0123 - Dell PERC4/SC 1000:1960:1028:0520 - Dell PERC4/DC 1000:1960:1028:0518 - Dell PERC4/QC 1000:0407:1028:0531 - Dell PERC4/Di 1028:000F:1028:014A - Dell PERC 4e/Si 1028:0013:1028:016c - Dell PERC 4e/Di 1028:0013:1028:016d - Dell PERC 4e/Di 1028:0013:1028:016e - Dell PERC 4e/Di 1028:0013:1028:016f - Dell PERC 4e/Di 1028:0013:1028:0170 - Dell PERC 4e/DC 1000:0408:1028:0002 - Dell PERC 4e/SC 1000:0408:1028:0001 - LSI MegaRAID SCSI 320-0 1000:1960:1000:A520 - LSI MegaRAID SCSI 320-1 1000:1960:1000:0520 - LSI MegaRAID SCSI 320-2 1000:1960:1000:0518 - LSI MegaRAID SCSI 320-0X 1000:0407:1000:0530 - LSI MegaRAID SCSI 320-2X 1000:0407:1000:0532 - LSI MegaRAID SCSI 320-4X 1000:0407:1000:0531 - LSI MegaRAID SCSI 320-1E 1000:0408:1000:0001 - LSI MegaRAID SCSI 320-2E 1000:0408:1000:0002 - LSI MegaRAID SATA 150-4 1000:1960:1000:4523 - LSI MegaRAID SATA 150-6 1000:1960:1000:0523 - LSI MegaRAID SATA 300-4X 1000:0409:1000:3004 - LSI MegaRAID SATA 300-8X 1000:0409:1000:3008 - INTEL RAID Controller SRCU42X 1000:0407:8086:0532 - INTEL RAID Controller SRCS16 1000:1960:8086:0523 - INTEL RAID Controller SRCU42E 1000:0408:8086:0002 - INTEL RAID Controller SRCZCRX 1000:0407:8086:0530 - INTEL RAID Controller SRCS28X 1000:0409:8086:3008 - INTEL RAID Controller SROMBU42E 1000:0408:8086:3431 - INTEL RAID Controller SROMBU42E 1000:0408:8086:3499 - INTEL RAID Controller SRCU51L 1000:1960:8086:0520 - FSC MegaRAID PCI Express ROMB 1000:0408:1734:1065 - ACER MegaRAID ROMB-2E 1000:0408:1025:004D - NEC MegaRAID PCI Express ROMB 1000:0408:1033:8287 + OEM Product Name VID :DID :SVID:SSID + --- ------------ ---- ---- ---- ---- + Dell PERC3/QC 101E:1960:1028:0471 + Dell PERC3/DC 101E:1960:1028:0493 + Dell PERC3/SC 101E:1960:1028:0475 + Dell PERC3/Di 1028:000E:1028:0123 + Dell PERC4/SC 1000:1960:1028:0520 + Dell PERC4/DC 1000:1960:1028:0518 + Dell PERC4/QC 1000:0407:1028:0531 + Dell PERC4/Di 1028:000F:1028:014A + Dell PERC 4e/Si 1028:0013:1028:016c + Dell PERC 4e/Di 1028:0013:1028:016d + Dell PERC 4e/Di 1028:0013:1028:016e + Dell PERC 4e/Di 1028:0013:1028:016f + Dell PERC 4e/Di 1028:0013:1028:0170 + Dell PERC 4e/DC 1000:0408:1028:0002 + Dell PERC 4e/SC 1000:0408:1028:0001 + LSI MegaRAID SCSI 320-0 1000:1960:1000:A520 + LSI MegaRAID SCSI 320-1 1000:1960:1000:0520 + LSI MegaRAID SCSI 320-2 1000:1960:1000:0518 + LSI MegaRAID SCSI 320-0X 1000:0407:1000:0530 + LSI MegaRAID SCSI 320-2X 1000:0407:1000:0532 + LSI MegaRAID SCSI 320-4X 1000:0407:1000:0531 + LSI MegaRAID SCSI 320-1E 1000:0408:1000:0001 + LSI MegaRAID SCSI 320-2E 1000:0408:1000:0002 + LSI MegaRAID SATA 150-4 1000:1960:1000:4523 + LSI MegaRAID SATA 150-6 1000:1960:1000:0523 + LSI MegaRAID SATA 300-4X 1000:0409:1000:3004 + LSI MegaRAID SATA 300-8X 1000:0409:1000:3008 + INTEL RAID Controller SRCU42X 1000:0407:8086:0532 + INTEL RAID Controller SRCS16 1000:1960:8086:0523 + INTEL RAID Controller SRCU42E 1000:0408:8086:0002 + INTEL RAID Controller SRCZCRX 1000:0407:8086:0530 + INTEL RAID Controller SRCS28X 1000:0409:8086:3008 + INTEL RAID Controller SROMBU42E 1000:0408:8086:3431 + INTEL RAID Controller SROMBU42E 1000:0408:8086:3499 + INTEL RAID Controller SRCU51L 1000:1960:8086:0520 + FSC MegaRAID PCI Express ROMB 1000:0408:1734:1065 + ACER MegaRAID ROMB-2E 1000:0408:1025:004D + NEC MegaRAID PCI Express ROMB 1000:0408:1033:8287 - To compile this driver as a module, choose M here: the - module will be called megaraid_mbox + To compile this driver as a module, choose M here: the + module will be called megaraid_mbox config MEGARAID_LEGACY tristate "LSI Logic Legacy MegaRAID Driver" depends on PCI && HAS_IOPORT && SCSI help - This driver supports the LSI MegaRAID 418, 428, 438, 466, 762, 490 - and 467 SCSI host adapters. This driver also support the all U320 - RAID controllers + This driver supports the LSI MegaRAID 418, 428, 438, 466, 762, 490 + and 467 SCSI host adapters. This driver also support the all U320 + RAID controllers - To compile this driver as a module, choose M here: the - module will be called megaraid + To compile this driver as a module, choose M here: the + module will be called megaraid config MEGARAID_SAS tristate "LSI Logic MegaRAID SAS RAID Module" depends on PCI && SCSI select IRQ_POLL help - Module for LSI Logic's SAS based RAID controllers. - To compile this driver as a module, choose 'm' here. - Module will be called megaraid_sas - + Module for LSI Logic's SAS based RAID controllers. + To compile this driver as a module, choose 'm' here. + Module will be called megaraid_sas diff --git a/drivers/scsi/megaraid/megaraid_sas.h b/drivers/scsi/megaraid/megaraid_sas.h index 56624cbf7f..5680c6cdb2 100644 --- a/drivers/scsi/megaraid/megaraid_sas.h +++ b/drivers/scsi/megaraid/megaraid_sas.h @@ -2701,7 +2701,7 @@ int megasas_get_ctrl_info(struct megasas_instance *instance); int megasas_sync_pd_seq_num(struct megasas_instance *instance, bool pend); void megasas_set_dynamic_target_properties(struct scsi_device *sdev, - bool is_target_prop); + struct queue_limits *lim, bool is_target_prop); int megasas_get_target_prop(struct megasas_instance *instance, struct scsi_device *sdev); void megasas_get_snapdump_properties(struct megasas_instance *instance); diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c index 3d4f13da1a..88acefbf9a 100644 --- a/drivers/scsi/megaraid/megaraid_sas_base.c +++ b/drivers/scsi/megaraid/megaraid_sas_base.c @@ -1888,7 +1888,7 @@ static struct megasas_instance *megasas_lookup_instance(u16 host_no) * Returns void */ void megasas_set_dynamic_target_properties(struct scsi_device *sdev, - bool is_target_prop) + struct queue_limits *lim, bool is_target_prop) { u16 pd_index = 0, ld; u32 device_id; @@ -1915,8 +1915,10 @@ void megasas_set_dynamic_target_properties(struct scsi_device *sdev, return; raid = MR_LdRaidGet(ld, local_map_ptr); - if (raid->capability.ldPiMode == MR_PROT_INFO_TYPE_CONTROLLER) - blk_queue_update_dma_alignment(sdev->request_queue, 0x7); + if (raid->capability.ldPiMode == MR_PROT_INFO_TYPE_CONTROLLER) { + if (lim) + lim->dma_alignment = 0x7; + } mr_device_priv_data->is_tm_capable = raid->capability.tmCapable; @@ -1967,7 +1969,8 @@ void megasas_set_dynamic_target_properties(struct scsi_device *sdev, * */ static inline void -megasas_set_nvme_device_properties(struct scsi_device *sdev, u32 max_io_size) +megasas_set_nvme_device_properties(struct scsi_device *sdev, + struct queue_limits *lim, u32 max_io_size) { struct megasas_instance *instance; u32 mr_nvme_pg_size; @@ -1976,10 +1979,10 @@ megasas_set_nvme_device_properties(struct scsi_device *sdev, u32 max_io_size) mr_nvme_pg_size = max_t(u32, instance->nvme_page_size, MR_DEFAULT_NVME_PAGE_SIZE); - blk_queue_max_hw_sectors(sdev->request_queue, (max_io_size / 512)); + lim->max_hw_sectors = max_io_size / 512; + lim->virt_boundary_mask = mr_nvme_pg_size - 1; blk_queue_flag_set(QUEUE_FLAG_NOMERGES, sdev->request_queue); - blk_queue_virt_boundary(sdev->request_queue, mr_nvme_pg_size - 1); } /* @@ -2041,7 +2044,7 @@ static void megasas_set_fw_assisted_qd(struct scsi_device *sdev, * @is_target_prop true, if fw provided target properties. */ static void megasas_set_static_target_properties(struct scsi_device *sdev, - bool is_target_prop) + struct queue_limits *lim, bool is_target_prop) { u32 max_io_size_kb = MR_DEFAULT_NVME_MDTS_KB; struct megasas_instance *instance; @@ -2060,13 +2063,15 @@ static void megasas_set_static_target_properties(struct scsi_device *sdev, max_io_size_kb = le32_to_cpu(instance->tgt_prop->max_io_size_kb); if (instance->nvme_page_size && max_io_size_kb) - megasas_set_nvme_device_properties(sdev, (max_io_size_kb << 10)); + megasas_set_nvme_device_properties(sdev, lim, + max_io_size_kb << 10); megasas_set_fw_assisted_qd(sdev, is_target_prop); } -static int megasas_slave_configure(struct scsi_device *sdev) +static int megasas_device_configure(struct scsi_device *sdev, + struct queue_limits *lim) { u16 pd_index = 0; struct megasas_instance *instance; @@ -2096,10 +2101,10 @@ static int megasas_slave_configure(struct scsi_device *sdev) ret_target_prop = megasas_get_target_prop(instance, sdev); is_target_prop = (ret_target_prop == DCMD_SUCCESS) ? true : false; - megasas_set_static_target_properties(sdev, is_target_prop); + megasas_set_static_target_properties(sdev, lim, is_target_prop); /* This sdev property may change post OCR */ - megasas_set_dynamic_target_properties(sdev, is_target_prop); + megasas_set_dynamic_target_properties(sdev, lim, is_target_prop); mutex_unlock(&instance->reset_mutex); @@ -3507,7 +3512,7 @@ static const struct scsi_host_template megasas_template = { .module = THIS_MODULE, .name = "Avago SAS based MegaRAID driver", .proc_name = "megaraid_sas", - .slave_configure = megasas_slave_configure, + .device_configure = megasas_device_configure, .slave_alloc = megasas_slave_alloc, .slave_destroy = megasas_slave_destroy, .queuecommand = megasas_queue_command, @@ -6300,7 +6305,7 @@ static int megasas_init_fw(struct megasas_instance *instance) } if (!instance->msix_vectors) { - i = pci_alloc_irq_vectors(instance->pdev, 1, 1, PCI_IRQ_LEGACY); + i = pci_alloc_irq_vectors(instance->pdev, 1, 1, PCI_IRQ_INTX); if (i < 0) goto fail_init_adapter; } @@ -7839,7 +7844,7 @@ megasas_resume(struct device *dev) if (!instance->msix_vectors) { rval = pci_alloc_irq_vectors(instance->pdev, 1, 1, - PCI_IRQ_LEGACY); + PCI_IRQ_INTX); if (rval < 0) goto fail_reenable_msix; } diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c index c60014e07b..6c1fb81495 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fusion.c +++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c @@ -5119,7 +5119,8 @@ int megasas_reset_fusion(struct Scsi_Host *shost, int reason) ret_target_prop = megasas_get_target_prop(instance, sdev); is_target_prop = (ret_target_prop == DCMD_SUCCESS) ? true : false; - megasas_set_dynamic_target_properties(sdev, is_target_prop); + megasas_set_dynamic_target_properties(sdev, NULL, + is_target_prop); } status_reg = instance->instancet->read_fw_status_reg diff --git a/drivers/scsi/mpi3mr/mpi/mpi30_cnfg.h b/drivers/scsi/mpi3mr/mpi/mpi30_cnfg.h index 35f81af40f..6a19e17eb1 100644 --- a/drivers/scsi/mpi3mr/mpi/mpi30_cnfg.h +++ b/drivers/scsi/mpi3mr/mpi/mpi30_cnfg.h @@ -309,6 +309,7 @@ struct mpi3_man6_gpio_entry { #define MPI3_MAN6_GPIO_EXTINT_PARAM1_FLAGS_SOURCE_GENERIC (0x00) #define MPI3_MAN6_GPIO_EXTINT_PARAM1_FLAGS_SOURCE_CABLE_MGMT (0x10) #define MPI3_MAN6_GPIO_EXTINT_PARAM1_FLAGS_SOURCE_ACTIVE_CABLE_OVERCURRENT (0x20) +#define MPI3_MAN6_GPIO_EXTINT_PARAM1_FLAGS_ACK_REQUIRED (0x02) #define MPI3_MAN6_GPIO_EXTINT_PARAM1_FLAGS_TRIGGER_MASK (0x01) #define MPI3_MAN6_GPIO_EXTINT_PARAM1_FLAGS_TRIGGER_EDGE (0x00) #define MPI3_MAN6_GPIO_EXTINT_PARAM1_FLAGS_TRIGGER_LEVEL (0x01) @@ -1315,6 +1316,8 @@ struct mpi3_driver_page0 { __le32 reserved18; }; #define MPI3_DRIVER0_PAGEVERSION (0x00) +#define MPI3_DRIVER0_BSDOPTS_DEVICEEXPOSURE_DISABLE (0x00000020) +#define MPI3_DRIVER0_BSDOPTS_WRITECACHE_DISABLE (0x00000010) #define MPI3_DRIVER0_BSDOPTS_HEADLESS_MODE_ENABLE (0x00000008) #define MPI3_DRIVER0_BSDOPTS_DIS_HII_CONFIG_UTIL (0x00000004) #define MPI3_DRIVER0_BSDOPTS_REGISTRATION_MASK (0x00000003) diff --git a/drivers/scsi/mpi3mr/mpi/mpi30_image.h b/drivers/scsi/mpi3mr/mpi/mpi30_image.h index 47035b8119..7df2421901 100644 --- a/drivers/scsi/mpi3mr/mpi/mpi30_image.h +++ b/drivers/scsi/mpi3mr/mpi/mpi30_image.h @@ -198,16 +198,17 @@ struct mpi3_supported_devices_data { struct mpi3_supported_device supported_device[MPI3_SUPPORTED_DEVICE_MAX]; }; -#ifndef MPI3_ENCRYPTED_HASH_MAX -#define MPI3_ENCRYPTED_HASH_MAX (1) +#ifndef MPI3_PUBLIC_KEY_MAX +#define MPI3_PUBLIC_KEY_MAX (1) #endif struct mpi3_encrypted_hash_entry { u8 hash_image_type; u8 hash_algorithm; u8 encryption_algorithm; u8 reserved03; - __le32 reserved04; - __le32 encrypted_hash[MPI3_ENCRYPTED_HASH_MAX]; + __le16 public_key_size; + __le16 signature_size; + __le32 public_key[MPI3_PUBLIC_KEY_MAX]; }; #define MPI3_HASH_IMAGE_TYPE_KEY_WITH_SIGNATURE (0x03) @@ -228,17 +229,6 @@ struct mpi3_encrypted_hash_entry { #define MPI3_ENCRYPTION_ALGORITHM_RSA2048 (0x04) #define MPI3_ENCRYPTION_ALGORITHM_RSA4096 (0x05) #define MPI3_ENCRYPTION_ALGORITHM_RSA3072 (0x06) -#ifndef MPI3_PUBLIC_KEY_MAX -#define MPI3_PUBLIC_KEY_MAX (1) -#endif -struct mpi3_encrypted_key_with_hash_entry { - u8 hash_image_type; - u8 hash_algorithm; - u8 encryption_algorithm; - u8 reserved03; - __le32 reserved04; - __le32 public_key[MPI3_PUBLIC_KEY_MAX]; -}; #ifndef MPI3_ENCRYPTED_HASH_ENTRY_MAX #define MPI3_ENCRYPTED_HASH_ENTRY_MAX (1) diff --git a/drivers/scsi/mpi3mr/mpi/mpi30_ioc.h b/drivers/scsi/mpi3mr/mpi/mpi30_ioc.h index 0cb24fc036..0287849498 100644 --- a/drivers/scsi/mpi3mr/mpi/mpi30_ioc.h +++ b/drivers/scsi/mpi3mr/mpi/mpi30_ioc.h @@ -27,7 +27,7 @@ struct mpi3_ioc_init_request { __le64 sense_buffer_free_queue_address; __le64 driver_information_address; }; - +#define MPI3_IOCINIT_MSGFLAGS_WRITESAMEDIVERT_SUPPORTED (0x08) #define MPI3_IOCINIT_MSGFLAGS_SCSIIOSTATUSREPLY_SUPPORTED (0x04) #define MPI3_IOCINIT_MSGFLAGS_HOSTMETADATA_MASK (0x03) #define MPI3_IOCINIT_MSGFLAGS_HOSTMETADATA_NOT_USED (0x00) @@ -101,6 +101,8 @@ struct mpi3_ioc_facts_data { __le16 max_io_throttle_group; __le16 io_throttle_low; __le16 io_throttle_high; + __le32 diag_fdl_size; + __le32 diag_tty_size; }; #define MPI3_IOCFACTS_CAPABILITY_NON_SUPERVISOR_MASK (0x80000000) #define MPI3_IOCFACTS_CAPABILITY_SUPERVISOR_IOC (0x00000000) @@ -108,13 +110,13 @@ struct mpi3_ioc_facts_data { #define MPI3_IOCFACTS_CAPABILITY_INT_COALESCE_MASK (0x00000600) #define MPI3_IOCFACTS_CAPABILITY_INT_COALESCE_FIXED_THRESHOLD (0x00000000) #define MPI3_IOCFACTS_CAPABILITY_INT_COALESCE_OUTSTANDING_IO (0x00000200) -#define MPI3_IOCFACTS_CAPABILITY_COMPLETE_RESET_CAPABLE (0x00000100) -#define MPI3_IOCFACTS_CAPABILITY_SEG_DIAG_TRACE_ENABLED (0x00000080) -#define MPI3_IOCFACTS_CAPABILITY_SEG_DIAG_FW_ENABLED (0x00000040) -#define MPI3_IOCFACTS_CAPABILITY_SEG_DIAG_DRIVER_ENABLED (0x00000020) -#define MPI3_IOCFACTS_CAPABILITY_ADVANCED_HOST_PD_ENABLED (0x00000010) -#define MPI3_IOCFACTS_CAPABILITY_RAID_CAPABLE (0x00000008) -#define MPI3_IOCFACTS_CAPABILITY_MULTIPATH_ENABLED (0x00000002) +#define MPI3_IOCFACTS_CAPABILITY_COMPLETE_RESET_SUPPORTED (0x00000100) +#define MPI3_IOCFACTS_CAPABILITY_SEG_DIAG_TRACE_SUPPORTED (0x00000080) +#define MPI3_IOCFACTS_CAPABILITY_SEG_DIAG_FW_SUPPORTED (0x00000040) +#define MPI3_IOCFACTS_CAPABILITY_SEG_DIAG_DRIVER_SUPPORTED (0x00000020) +#define MPI3_IOCFACTS_CAPABILITY_ADVANCED_HOST_PD_SUPPORTED (0x00000010) +#define MPI3_IOCFACTS_CAPABILITY_RAID_SUPPORTED (0x00000008) +#define MPI3_IOCFACTS_CAPABILITY_MULTIPATH_SUPPORTED (0x00000002) #define MPI3_IOCFACTS_CAPABILITY_COALESCE_CTRL_SUPPORTED (0x00000001) #define MPI3_IOCFACTS_PID_TYPE_MASK (0xf000) #define MPI3_IOCFACTS_PID_TYPE_SHIFT (12) @@ -159,6 +161,8 @@ struct mpi3_ioc_facts_data { #define MPI3_IOCFACTS_FLAGS_PERSONALITY_RAID_DDR (0x00000002) #define MPI3_IOCFACTS_IO_THROTTLE_DATA_LENGTH_NOT_REQUIRED (0x0000) #define MPI3_IOCFACTS_MAX_IO_THROTTLE_GROUP_NOT_REQUIRED (0x0000) +#define MPI3_IOCFACTS_DIAGFDLSIZE_NOT_SUPPORTED (0x00000000) +#define MPI3_IOCFACTS_DIAGTTYSIZE_NOT_SUPPORTED (0x00000000) struct mpi3_mgmt_passthrough_request { __le16 host_tag; u8 ioc_use_only02; diff --git a/drivers/scsi/mpi3mr/mpi/mpi30_transport.h b/drivers/scsi/mpi3mr/mpi/mpi30_transport.h index 1e0a3dcaf7..fdc3d1968e 100644 --- a/drivers/scsi/mpi3mr/mpi/mpi30_transport.h +++ b/drivers/scsi/mpi3mr/mpi/mpi30_transport.h @@ -18,7 +18,7 @@ union mpi3_version_union { #define MPI3_VERSION_MAJOR (3) #define MPI3_VERSION_MINOR (0) -#define MPI3_VERSION_UNIT (28) +#define MPI3_VERSION_UNIT (31) #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 3de1ee05c4..f5a1529fa5 100644 --- a/drivers/scsi/mpi3mr/mpi3mr.h +++ b/drivers/scsi/mpi3mr/mpi3mr.h @@ -55,15 +55,15 @@ extern struct list_head mrioc_list; extern int prot_mask; extern atomic64_t event_counter; -#define MPI3MR_DRIVER_VERSION "8.5.1.0.0" -#define MPI3MR_DRIVER_RELDATE "5-December-2023" +#define MPI3MR_DRIVER_VERSION "8.8.1.0.50" +#define MPI3MR_DRIVER_RELDATE "5-March-2024" #define MPI3MR_DRIVER_NAME "mpi3mr" #define MPI3MR_DRIVER_LICENSE "GPL" #define MPI3MR_DRIVER_AUTHOR "Broadcom Inc. " #define MPI3MR_DRIVER_DESC "MPI3 Storage Controller Device Driver" -#define MPI3MR_NAME_LENGTH 32 +#define MPI3MR_NAME_LENGTH 64 #define IOCNAME "%s: " #define MPI3MR_DEFAULT_MAX_IO_SIZE (1 * 1024 * 1024) @@ -294,6 +294,10 @@ enum mpi3mr_reset_reason { MPI3MR_RESET_FROM_SAS_TRANSPORT_TIMEOUT = 30, }; +#define MPI3MR_RESET_REASON_OSTYPE_LINUX 1 +#define MPI3MR_RESET_REASON_OSTYPE_SHIFT 28 +#define MPI3MR_RESET_REASON_IOCNUM_SHIFT 20 + /* Queue type definitions */ enum queue_type { MPI3MR_DEFAULT_QUEUE = 0, @@ -1142,7 +1146,7 @@ struct mpi3mr_ioc { spinlock_t fwevt_lock; struct list_head fwevt_list; - char watchdog_work_q_name[20]; + char watchdog_work_q_name[50]; struct workqueue_struct *watchdog_work_q; struct delayed_work watchdog_work; spinlock_t watchdog_lock; @@ -1336,7 +1340,7 @@ void mpi3mr_start_watchdog(struct mpi3mr_ioc *mrioc); void mpi3mr_stop_watchdog(struct mpi3mr_ioc *mrioc); int mpi3mr_soft_reset_handler(struct mpi3mr_ioc *mrioc, - u32 reset_reason, u8 snapdump); + u16 reset_reason, u8 snapdump); void mpi3mr_ioc_disable_intr(struct mpi3mr_ioc *mrioc); void mpi3mr_ioc_enable_intr(struct mpi3mr_ioc *mrioc); @@ -1348,7 +1352,6 @@ void mpi3mr_wait_for_host_io(struct mpi3mr_ioc *mrioc, u32 timeout); void mpi3mr_cleanup_fwevt_list(struct mpi3mr_ioc *mrioc); void mpi3mr_flush_host_io(struct mpi3mr_ioc *mrioc); void mpi3mr_invalidate_devhandles(struct mpi3mr_ioc *mrioc); -void mpi3mr_rfresh_tgtdevs(struct mpi3mr_ioc *mrioc); void mpi3mr_flush_delayed_cmd_lists(struct mpi3mr_ioc *mrioc); void mpi3mr_check_rh_fault_ioc(struct mpi3mr_ioc *mrioc, u32 reason_code); void mpi3mr_print_fault_info(struct mpi3mr_ioc *mrioc); diff --git a/drivers/scsi/mpi3mr/mpi3mr_app.c b/drivers/scsi/mpi3mr/mpi3mr_app.c index 6a3db7032c..cd261b48eb 100644 --- a/drivers/scsi/mpi3mr/mpi3mr_app.c +++ b/drivers/scsi/mpi3mr/mpi3mr_app.c @@ -1598,26 +1598,33 @@ static long mpi3mr_bsg_process_mpt_cmds(struct bsg_job *job) rval = -EAGAIN; if (mrioc->bsg_cmds.state & MPI3MR_CMD_RESET) goto out_unlock; - dprint_bsg_err(mrioc, - "%s: bsg request timedout after %d seconds\n", __func__, - karg->timeout); - if (mrioc->logging_level & MPI3_DEBUG_BSG_ERROR) { - dprint_dump(mpi_req, MPI3MR_ADMIN_REQ_FRAME_SZ, + if (((mpi_header->function != MPI3_FUNCTION_SCSI_IO) && + (mpi_header->function != MPI3_FUNCTION_NVME_ENCAPSULATED)) + || (mrioc->logging_level & MPI3_DEBUG_BSG_ERROR)) { + ioc_info(mrioc, "%s: bsg request timedout after %d seconds\n", + __func__, karg->timeout); + if (!(mrioc->logging_level & MPI3_DEBUG_BSG_INFO)) { + dprint_dump(mpi_req, MPI3MR_ADMIN_REQ_FRAME_SZ, "bsg_mpi3_req"); if (mpi_header->function == - MPI3_BSG_FUNCTION_MGMT_PASSTHROUGH) { + MPI3_FUNCTION_MGMT_PASSTHROUGH) { drv_buf_iter = &drv_bufs[0]; dprint_dump(drv_buf_iter->kern_buf, rmc_size, "mpi3_mgmt_req"); + } } } if ((mpi_header->function == MPI3_BSG_FUNCTION_NVME_ENCAPSULATED) || - (mpi_header->function == MPI3_BSG_FUNCTION_SCSI_IO)) + (mpi_header->function == MPI3_BSG_FUNCTION_SCSI_IO)) { + dprint_bsg_err(mrioc, "%s: bsg request timedout after %d seconds,\n" + "issuing target reset to (0x%04x)\n", __func__, + karg->timeout, mpi_header->function_dependent); mpi3mr_issue_tm(mrioc, MPI3_SCSITASKMGMT_TASKTYPE_TARGET_RESET, mpi_header->function_dependent, 0, MPI3MR_HOSTTAG_BLK_TMS, MPI3MR_RESETTM_TIMEOUT, &mrioc->host_tm_cmds, &resp_code, NULL); + } if (!(mrioc->bsg_cmds.state & MPI3MR_CMD_COMPLETE) && !(mrioc->bsg_cmds.state & MPI3MR_CMD_RESET)) mpi3mr_soft_reset_handler(mrioc, @@ -1838,6 +1845,10 @@ void mpi3mr_bsg_init(struct mpi3mr_ioc *mrioc) { struct device *bsg_dev = &mrioc->bsg_dev; struct device *parent = &mrioc->shost->shost_gendev; + struct queue_limits lim = { + .max_hw_sectors = MPI3MR_MAX_APP_XFER_SECTORS, + .max_segments = MPI3MR_MAX_APP_XFER_SEGMENTS, + }; device_initialize(bsg_dev); @@ -1853,20 +1864,14 @@ void mpi3mr_bsg_init(struct mpi3mr_ioc *mrioc) return; } - mrioc->bsg_queue = bsg_setup_queue(bsg_dev, dev_name(bsg_dev), + mrioc->bsg_queue = bsg_setup_queue(bsg_dev, dev_name(bsg_dev), &lim, mpi3mr_bsg_request, NULL, 0); if (IS_ERR(mrioc->bsg_queue)) { ioc_err(mrioc, "%s: bsg registration failed\n", dev_name(bsg_dev)); device_del(bsg_dev); put_device(bsg_dev); - return; } - - blk_queue_max_segments(mrioc->bsg_queue, MPI3MR_MAX_APP_XFER_SEGMENTS); - blk_queue_max_hw_sectors(mrioc->bsg_queue, MPI3MR_MAX_APP_XFER_SECTORS); - - return; } /** diff --git a/drivers/scsi/mpi3mr/mpi3mr_fw.c b/drivers/scsi/mpi3mr/mpi3mr_fw.c index 528f19f782..c2a22e96f7 100644 --- a/drivers/scsi/mpi3mr/mpi3mr_fw.c +++ b/drivers/scsi/mpi3mr/mpi3mr_fw.c @@ -11,7 +11,7 @@ #include static int -mpi3mr_issue_reset(struct mpi3mr_ioc *mrioc, u16 reset_type, u32 reset_reason); +mpi3mr_issue_reset(struct mpi3mr_ioc *mrioc, u16 reset_type, u16 reset_reason); static int mpi3mr_setup_admin_qpair(struct mpi3mr_ioc *mrioc); static void mpi3mr_process_factsdata(struct mpi3mr_ioc *mrioc, struct mpi3_ioc_facts_data *facts_data); @@ -1195,7 +1195,7 @@ static inline void mpi3mr_clear_reset_history(struct mpi3mr_ioc *mrioc) static int mpi3mr_issue_and_process_mur(struct mpi3mr_ioc *mrioc, u32 reset_reason) { - u32 ioc_config, timeout, ioc_status; + u32 ioc_config, timeout, ioc_status, scratch_pad0; int retval = -1; ioc_info(mrioc, "Issuing Message unit Reset(MUR)\n"); @@ -1204,7 +1204,11 @@ static int mpi3mr_issue_and_process_mur(struct mpi3mr_ioc *mrioc, return retval; } mpi3mr_clear_reset_history(mrioc); - writel(reset_reason, &mrioc->sysif_regs->scratchpad[0]); + scratch_pad0 = ((MPI3MR_RESET_REASON_OSTYPE_LINUX << + MPI3MR_RESET_REASON_OSTYPE_SHIFT) | + (mrioc->facts.ioc_num << + MPI3MR_RESET_REASON_IOCNUM_SHIFT) | reset_reason); + writel(scratch_pad0, &mrioc->sysif_regs->scratchpad[0]); ioc_config = readl(&mrioc->sysif_regs->ioc_configuration); ioc_config &= ~MPI3_SYSIF_IOC_CONFIG_ENABLE_IOC; writel(ioc_config, &mrioc->sysif_regs->ioc_configuration); @@ -1276,7 +1280,7 @@ mpi3mr_revalidate_factsdata(struct mpi3mr_ioc *mrioc) mrioc->shost->max_sectors * 512, mrioc->facts.max_data_length); if ((mrioc->sas_transport_enabled) && (mrioc->facts.ioc_capabilities & - MPI3_IOCFACTS_CAPABILITY_MULTIPATH_ENABLED)) + MPI3_IOCFACTS_CAPABILITY_MULTIPATH_SUPPORTED)) ioc_err(mrioc, "critical error: multipath capability is enabled at the\n" "\tcontroller while sas transport support is enabled at the\n" @@ -1520,11 +1524,11 @@ static inline void mpi3mr_set_diagsave(struct mpi3mr_ioc *mrioc) * Return: 0 on success, non-zero on failure. */ static int mpi3mr_issue_reset(struct mpi3mr_ioc *mrioc, u16 reset_type, - u32 reset_reason) + u16 reset_reason) { int retval = -1; u8 unlock_retry_count = 0; - u32 host_diagnostic, ioc_status, ioc_config; + u32 host_diagnostic, ioc_status, ioc_config, scratch_pad0; u32 timeout = MPI3MR_RESET_ACK_TIMEOUT * 10; if ((reset_type != MPI3_SYSIF_HOST_DIAG_RESET_ACTION_SOFT_RESET) && @@ -1576,6 +1580,9 @@ static int mpi3mr_issue_reset(struct mpi3mr_ioc *mrioc, u16 reset_type, unlock_retry_count, host_diagnostic); } while (!(host_diagnostic & MPI3_SYSIF_HOST_DIAG_DIAG_WRITE_ENABLE)); + scratch_pad0 = ((MPI3MR_RESET_REASON_OSTYPE_LINUX << + MPI3MR_RESET_REASON_OSTYPE_SHIFT) | (mrioc->facts.ioc_num << + MPI3MR_RESET_REASON_IOCNUM_SHIFT) | reset_reason); writel(reset_reason, &mrioc->sysif_regs->scratchpad[0]); writel(host_diagnostic | reset_type, &mrioc->sysif_regs->host_diagnostic); @@ -2581,7 +2588,7 @@ static void mpi3mr_watchdog_work(struct work_struct *work) unsigned long flags; enum mpi3mr_iocstate ioc_state; u32 fault, host_diagnostic, ioc_status; - u32 reset_reason = MPI3MR_RESET_FROM_FAULT_WATCH; + u16 reset_reason = MPI3MR_RESET_FROM_FAULT_WATCH; if (mrioc->reset_in_progress) return; @@ -3302,6 +3309,8 @@ static int mpi3mr_issue_iocinit(struct mpi3mr_ioc *mrioc) iocinit_req.msg_flags |= MPI3_IOCINIT_MSGFLAGS_SCSIIOSTATUSREPLY_SUPPORTED; + iocinit_req.msg_flags |= + MPI3_IOCINIT_MSGFLAGS_WRITESAMEDIVERT_SUPPORTED; init_completion(&mrioc->init_cmds.done); retval = mpi3mr_admin_request_post(mrioc, &iocinit_req, @@ -3668,15 +3677,15 @@ static const struct { u32 capability; char *name; } mpi3mr_capabilities[] = { - { MPI3_IOCFACTS_CAPABILITY_RAID_CAPABLE, "RAID" }, - { MPI3_IOCFACTS_CAPABILITY_MULTIPATH_ENABLED, "MultiPath" }, + { MPI3_IOCFACTS_CAPABILITY_RAID_SUPPORTED, "RAID" }, + { MPI3_IOCFACTS_CAPABILITY_MULTIPATH_SUPPORTED, "MultiPath" }, }; /** * mpi3mr_print_ioc_info - Display controller information * @mrioc: Adapter instance reference * - * Display controller personalit, capability, supported + * Display controller personality, capability, supported * protocols etc. * * Return: Nothing @@ -3685,20 +3694,20 @@ static void mpi3mr_print_ioc_info(struct mpi3mr_ioc *mrioc) { int i = 0, bytes_written = 0; - char personality[16]; + const char *personality; char protocol[50] = {0}; char capabilities[100] = {0}; struct mpi3mr_compimg_ver *fwver = &mrioc->facts.fw_ver; switch (mrioc->facts.personality) { case MPI3_IOCFACTS_FLAGS_PERSONALITY_EHBA: - strncpy(personality, "Enhanced HBA", sizeof(personality)); + personality = "Enhanced HBA"; break; case MPI3_IOCFACTS_FLAGS_PERSONALITY_RAID_DDR: - strncpy(personality, "RAID", sizeof(personality)); + personality = "RAID"; break; default: - strncpy(personality, "Unknown", sizeof(personality)); + personality = "Unknown"; break; } @@ -3951,7 +3960,7 @@ retry_init: MPI3MR_HOST_IOS_KDUMP); if (!(mrioc->facts.ioc_capabilities & - MPI3_IOCFACTS_CAPABILITY_MULTIPATH_ENABLED)) { + MPI3_IOCFACTS_CAPABILITY_MULTIPATH_SUPPORTED)) { mrioc->sas_transport_enabled = 1; mrioc->scsi_device_channel = 1; mrioc->shost->max_channel = 1; @@ -4966,7 +4975,7 @@ cleanup_drv_cmd: * Return: 0 on success, non-zero on failure. */ int mpi3mr_soft_reset_handler(struct mpi3mr_ioc *mrioc, - u32 reset_reason, u8 snapdump) + u16 reset_reason, u8 snapdump) { int retval = 0, i; unsigned long flags; @@ -5102,6 +5111,7 @@ out: mrioc->device_refresh_on = 0; mrioc->unrecoverable = 1; mrioc->reset_in_progress = 0; + mrioc->stop_bsgs = 0; retval = -1; mpi3mr_flush_cmds_for_unrecovered_controller(mrioc); } diff --git a/drivers/scsi/mpi3mr/mpi3mr_os.c b/drivers/scsi/mpi3mr/mpi3mr_os.c index 73c831a97d..bce639a6cc 100644 --- a/drivers/scsi/mpi3mr/mpi3mr_os.c +++ b/drivers/scsi/mpi3mr/mpi3mr_os.c @@ -986,6 +986,25 @@ static int mpi3mr_change_queue_depth(struct scsi_device *sdev, return retval; } +static void mpi3mr_configure_nvme_dev(struct mpi3mr_tgt_dev *tgt_dev, + struct queue_limits *lim) +{ + u8 pgsz = tgt_dev->dev_spec.pcie_inf.pgsz ? : MPI3MR_DEFAULT_PGSZEXP; + + lim->max_hw_sectors = tgt_dev->dev_spec.pcie_inf.mdts / 512; + lim->virt_boundary_mask = (1 << pgsz) - 1; +} + +static void mpi3mr_configure_tgt_dev(struct mpi3mr_tgt_dev *tgt_dev, + struct queue_limits *lim) +{ + if (tgt_dev->dev_type == MPI3_DEVICE_DEVFORM_PCIE && + (tgt_dev->dev_spec.pcie_inf.dev_info & + MPI3_DEVICE0_PCIE_DEVICE_INFO_TYPE_MASK) == + MPI3_DEVICE0_PCIE_DEVICE_INFO_TYPE_NVME_DEVICE) + mpi3mr_configure_nvme_dev(tgt_dev, lim); +} + /** * mpi3mr_update_sdev - Update SCSI device information * @sdev: SCSI device reference @@ -1001,35 +1020,21 @@ static void mpi3mr_update_sdev(struct scsi_device *sdev, void *data) { struct mpi3mr_tgt_dev *tgtdev; + struct queue_limits lim; tgtdev = (struct mpi3mr_tgt_dev *)data; if (!tgtdev) return; mpi3mr_change_queue_depth(sdev, tgtdev->q_depth); - switch (tgtdev->dev_type) { - case MPI3_DEVICE_DEVFORM_PCIE: - /*The block layer hw sector size = 512*/ - if ((tgtdev->dev_spec.pcie_inf.dev_info & - MPI3_DEVICE0_PCIE_DEVICE_INFO_TYPE_MASK) == - MPI3_DEVICE0_PCIE_DEVICE_INFO_TYPE_NVME_DEVICE) { - blk_queue_max_hw_sectors(sdev->request_queue, - tgtdev->dev_spec.pcie_inf.mdts / 512); - if (tgtdev->dev_spec.pcie_inf.pgsz == 0) - blk_queue_virt_boundary(sdev->request_queue, - ((1 << MPI3MR_DEFAULT_PGSZEXP) - 1)); - else - blk_queue_virt_boundary(sdev->request_queue, - ((1 << tgtdev->dev_spec.pcie_inf.pgsz) - 1)); - } - break; - default: - break; - } + + lim = queue_limits_start_update(sdev->request_queue); + mpi3mr_configure_tgt_dev(tgtdev, &lim); + WARN_ON_ONCE(queue_limits_commit_update(sdev->request_queue, &lim)); } /** - * mpi3mr_rfresh_tgtdevs - Refresh target device exposure + * mpi3mr_refresh_tgtdevs - Refresh target device exposure * @mrioc: Adapter instance reference * * This is executed post controller reset to identify any @@ -1038,8 +1043,7 @@ mpi3mr_update_sdev(struct scsi_device *sdev, void *data) * * Return: Nothing. */ - -void mpi3mr_rfresh_tgtdevs(struct mpi3mr_ioc *mrioc) +static void mpi3mr_refresh_tgtdevs(struct mpi3mr_ioc *mrioc) { struct mpi3mr_tgt_dev *tgtdev, *tgtdev_next; struct mpi3mr_stgt_priv_data *tgt_priv; @@ -1047,8 +1051,8 @@ void mpi3mr_rfresh_tgtdevs(struct mpi3mr_ioc *mrioc) dprint_reset(mrioc, "refresh target devices: check for removals\n"); list_for_each_entry_safe(tgtdev, tgtdev_next, &mrioc->tgtdev_list, list) { - if ((tgtdev->dev_handle == MPI3MR_INVALID_DEV_HANDLE) && - tgtdev->is_hidden && + if (((tgtdev->dev_handle == MPI3MR_INVALID_DEV_HANDLE) || + tgtdev->is_hidden) && tgtdev->host_exposed && tgtdev->starget && tgtdev->starget->hostdata) { tgt_priv = tgtdev->starget->hostdata; @@ -2010,7 +2014,7 @@ static void mpi3mr_fwevt_bh(struct mpi3mr_ioc *mrioc, mpi3mr_refresh_sas_ports(mrioc); mpi3mr_refresh_expanders(mrioc); } - mpi3mr_rfresh_tgtdevs(mrioc); + mpi3mr_refresh_tgtdevs(mrioc); ioc_info(mrioc, "scan for non responding and newly added devices after soft reset completed\n"); break; @@ -4393,15 +4397,17 @@ static void mpi3mr_target_destroy(struct scsi_target *starget) } /** - * mpi3mr_slave_configure - Slave configure callback handler + * mpi3mr_device_configure - Slave configure callback handler * @sdev: SCSI device reference + * @lim: queue limits * * Configure queue depth, max hardware sectors and virt boundary * as required * * Return: 0 always. */ -static int mpi3mr_slave_configure(struct scsi_device *sdev) +static int mpi3mr_device_configure(struct scsi_device *sdev, + struct queue_limits *lim) { struct scsi_target *starget; struct Scsi_Host *shost; @@ -4432,28 +4438,8 @@ static int mpi3mr_slave_configure(struct scsi_device *sdev) sdev->eh_timeout = MPI3MR_EH_SCMD_TIMEOUT; blk_queue_rq_timeout(sdev->request_queue, MPI3MR_SCMD_TIMEOUT); - switch (tgt_dev->dev_type) { - case MPI3_DEVICE_DEVFORM_PCIE: - /*The block layer hw sector size = 512*/ - if ((tgt_dev->dev_spec.pcie_inf.dev_info & - MPI3_DEVICE0_PCIE_DEVICE_INFO_TYPE_MASK) == - MPI3_DEVICE0_PCIE_DEVICE_INFO_TYPE_NVME_DEVICE) { - blk_queue_max_hw_sectors(sdev->request_queue, - tgt_dev->dev_spec.pcie_inf.mdts / 512); - if (tgt_dev->dev_spec.pcie_inf.pgsz == 0) - blk_queue_virt_boundary(sdev->request_queue, - ((1 << MPI3MR_DEFAULT_PGSZEXP) - 1)); - else - blk_queue_virt_boundary(sdev->request_queue, - ((1 << tgt_dev->dev_spec.pcie_inf.pgsz) - 1)); - } - break; - default: - break; - } - + mpi3mr_configure_tgt_dev(tgt_dev, lim); mpi3mr_tgtdev_put(tgt_dev); - return retval; } @@ -4895,7 +4881,7 @@ static int mpi3mr_qcmd(struct Scsi_Host *shost, MPI3_SCSIIO_MSGFLAGS_DIVERT_TO_FIRMWARE; scsiio_flags |= MPI3_SCSIIO_FLAGS_DIVERT_REASON_IO_THROTTLING; } - scsiio_req->flags = cpu_to_le32(scsiio_flags); + scsiio_req->flags |= cpu_to_le32(scsiio_flags); if (mpi3mr_op_request_post(mrioc, op_req_q, scmd_priv_data->mpi3mr_scsiio_req)) { @@ -4921,7 +4907,7 @@ static const struct scsi_host_template mpi3mr_driver_template = { .queuecommand = mpi3mr_qcmd, .target_alloc = mpi3mr_target_alloc, .slave_alloc = mpi3mr_slave_alloc, - .slave_configure = mpi3mr_slave_configure, + .device_configure = mpi3mr_device_configure, .target_destroy = mpi3mr_target_destroy, .slave_destroy = mpi3mr_slave_destroy, .scan_finished = mpi3mr_scan_finished, diff --git a/drivers/scsi/mpi3mr/mpi3mr_transport.c b/drivers/scsi/mpi3mr/mpi3mr_transport.c index 5d261c2f2d..82aa4e418c 100644 --- a/drivers/scsi/mpi3mr/mpi3mr_transport.c +++ b/drivers/scsi/mpi3mr/mpi3mr_transport.c @@ -7,6 +7,8 @@ * */ +#include + #include "mpi3mr.h" /** @@ -209,17 +211,13 @@ static int mpi3mr_report_manufacture(struct mpi3mr_ioc *mrioc, goto out; } - strscpy(edev->vendor_id, manufacture_reply->vendor_id, - SAS_EXPANDER_VENDOR_ID_LEN); - strscpy(edev->product_id, manufacture_reply->product_id, - SAS_EXPANDER_PRODUCT_ID_LEN); - strscpy(edev->product_rev, manufacture_reply->product_rev, - SAS_EXPANDER_PRODUCT_REV_LEN); + memtostr(edev->vendor_id, manufacture_reply->vendor_id); + memtostr(edev->product_id, manufacture_reply->product_id); + memtostr(edev->product_rev, manufacture_reply->product_rev); edev->level = manufacture_reply->sas_format & 1; if (edev->level) { - strscpy(edev->component_vendor_id, - manufacture_reply->component_vendor_id, - SAS_EXPANDER_COMPONENT_VENDOR_ID_LEN); + memtostr(edev->component_vendor_id, + manufacture_reply->component_vendor_id); tmp = (u8 *)&manufacture_reply->component_id; edev->component_id = tmp[0] << 8 | tmp[1]; edev->component_revision_id = diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c b/drivers/scsi/mpt3sas/mpt3sas_base.c index 86f553c617..b2bcf4a27d 100644 --- a/drivers/scsi/mpt3sas/mpt3sas_base.c +++ b/drivers/scsi/mpt3sas/mpt3sas_base.c @@ -3515,7 +3515,7 @@ _base_enable_msix(struct MPT3SAS_ADAPTER *ioc) ioc_info(ioc, "High IOPs queues : disabled\n"); ioc->reply_queue_count = 1; ioc->iopoll_q_start_index = ioc->reply_queue_count - 0; - r = pci_alloc_irq_vectors(ioc->pdev, 1, 1, PCI_IRQ_LEGACY); + r = pci_alloc_irq_vectors(ioc->pdev, 1, 1, PCI_IRQ_INTX); if (r < 0) { dfailprintk(ioc, ioc_info(ioc, "pci_alloc_irq_vector(legacy) failed (r=%d) !!!\n", @@ -4774,7 +4774,7 @@ _base_display_ioc_capabilities(struct MPT3SAS_ADAPTER *ioc) char desc[17] = {0}; u32 iounit_pg1_flags; - strncpy(desc, ioc->manu_pg0.ChipName, 16); + memtostr(desc, ioc->manu_pg0.ChipName); ioc_info(ioc, "%s: FWVersion(%02d.%02d.%02d.%02d), ChipRevision(0x%02x)\n", desc, (ioc->facts.FWVersion.Word & 0xFF000000) >> 24, diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c b/drivers/scsi/mpt3sas/mpt3sas_scsih.c index 7e923e0249..870ec2cb4a 100644 --- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c +++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c @@ -302,8 +302,8 @@ struct _scsi_io_transfer { /** * _scsih_set_debug_level - global setting of ioc->logging_level. - * @val: ? - * @kp: ? + * @val: value of the parameter to be set + * @kp: pointer to kernel_param structure * * Note: The logging levels are defined in mpt3sas_debug.h. */ @@ -2497,14 +2497,15 @@ _scsih_enable_tlr(struct MPT3SAS_ADAPTER *ioc, struct scsi_device *sdev) } /** - * scsih_slave_configure - device configure routine. + * scsih_device_configure - device configure routine. * @sdev: scsi device struct + * @lim: queue limits * * Return: 0 if ok. Any other return is assumed to be an error and * the device is ignored. */ static int -scsih_slave_configure(struct scsi_device *sdev) +scsih_device_configure(struct scsi_device *sdev, struct queue_limits *lim) { struct Scsi_Host *shost = sdev->host; struct MPT3SAS_ADAPTER *ioc = shost_priv(shost); @@ -2609,8 +2610,7 @@ scsih_slave_configure(struct scsi_device *sdev) raid_device->num_pds, ds); if (shost->max_sectors > MPT3SAS_RAID_MAX_SECTORS) { - blk_queue_max_hw_sectors(sdev->request_queue, - MPT3SAS_RAID_MAX_SECTORS); + lim->max_hw_sectors = MPT3SAS_RAID_MAX_SECTORS; sdev_printk(KERN_INFO, sdev, "Set queue's max_sector to: %u\n", MPT3SAS_RAID_MAX_SECTORS); @@ -2675,8 +2675,7 @@ scsih_slave_configure(struct scsi_device *sdev) pcie_device->connector_name); if (pcie_device->nvme_mdts) - blk_queue_max_hw_sectors(sdev->request_queue, - pcie_device->nvme_mdts/512); + lim->max_hw_sectors = pcie_device->nvme_mdts / 512; pcie_device_put(pcie_device); spin_unlock_irqrestore(&ioc->pcie_device_lock, flags); @@ -2687,8 +2686,7 @@ scsih_slave_configure(struct scsi_device *sdev) **/ blk_queue_flag_set(QUEUE_FLAG_NOMERGES, sdev->request_queue); - blk_queue_virt_boundary(sdev->request_queue, - ioc->page_size - 1); + lim->virt_boundary_mask = ioc->page_size - 1; return 0; } @@ -11914,7 +11912,7 @@ static const struct scsi_host_template mpt2sas_driver_template = { .queuecommand = scsih_qcmd, .target_alloc = scsih_target_alloc, .slave_alloc = scsih_slave_alloc, - .slave_configure = scsih_slave_configure, + .device_configure = scsih_device_configure, .target_destroy = scsih_target_destroy, .slave_destroy = scsih_slave_destroy, .scan_finished = scsih_scan_finished, @@ -11952,7 +11950,7 @@ static const struct scsi_host_template mpt3sas_driver_template = { .queuecommand = scsih_qcmd, .target_alloc = scsih_target_alloc, .slave_alloc = scsih_slave_alloc, - .slave_configure = scsih_slave_configure, + .device_configure = scsih_device_configure, .target_destroy = scsih_target_destroy, .slave_destroy = scsih_slave_destroy, .scan_finished = scsih_scan_finished, diff --git a/drivers/scsi/mpt3sas/mpt3sas_transport.c b/drivers/scsi/mpt3sas/mpt3sas_transport.c index 421ea511b6..d84413b77d 100644 --- a/drivers/scsi/mpt3sas/mpt3sas_transport.c +++ b/drivers/scsi/mpt3sas/mpt3sas_transport.c @@ -458,17 +458,13 @@ _transport_expander_report_manufacture(struct MPT3SAS_ADAPTER *ioc, goto out; manufacture_reply = data_out + sizeof(struct rep_manu_request); - strncpy(edev->vendor_id, manufacture_reply->vendor_id, - SAS_EXPANDER_VENDOR_ID_LEN); - strncpy(edev->product_id, manufacture_reply->product_id, - SAS_EXPANDER_PRODUCT_ID_LEN); - strncpy(edev->product_rev, manufacture_reply->product_rev, - SAS_EXPANDER_PRODUCT_REV_LEN); + memtostr(edev->vendor_id, manufacture_reply->vendor_id); + memtostr(edev->product_id, manufacture_reply->product_id); + memtostr(edev->product_rev, manufacture_reply->product_rev); edev->level = manufacture_reply->sas_format & 1; if (edev->level) { - strncpy(edev->component_vendor_id, - manufacture_reply->component_vendor_id, - SAS_EXPANDER_COMPONENT_VENDOR_ID_LEN); + memtostr(edev->component_vendor_id, + manufacture_reply->component_vendor_id); tmp = (u8 *)&manufacture_reply->component_id; edev->component_id = tmp[0] << 8 | tmp[1]; edev->component_revision_id = diff --git a/drivers/scsi/mvsas/mv_init.c b/drivers/scsi/mvsas/mv_init.c index 43ebb331e2..020037cbf0 100644 --- a/drivers/scsi/mvsas/mv_init.c +++ b/drivers/scsi/mvsas/mv_init.c @@ -26,33 +26,18 @@ static const struct mvs_chip_info mvs_chips[] = { }; static const struct attribute_group *mvst_host_groups[]; +static const struct attribute_group *mvst_sdev_groups[]; #define SOC_SAS_NUM 2 static const struct scsi_host_template mvs_sht = { - .module = THIS_MODULE, - .name = DRV_NAME, - .queuecommand = sas_queuecommand, - .dma_need_drain = ata_scsi_dma_need_drain, - .target_alloc = sas_target_alloc, - .slave_configure = sas_slave_configure, + LIBSAS_SHT_BASE .scan_finished = mvs_scan_finished, .scan_start = mvs_scan_start, - .change_queue_depth = sas_change_queue_depth, - .bios_param = sas_bios_param, .can_queue = 1, - .this_id = -1, .sg_tablesize = SG_ALL, - .max_sectors = SCSI_DEFAULT_MAX_SECTORS, - .eh_device_reset_handler = sas_eh_device_reset_handler, - .eh_target_reset_handler = sas_eh_target_reset_handler, - .slave_alloc = sas_slave_alloc, - .target_destroy = sas_target_destroy, - .ioctl = sas_ioctl, -#ifdef CONFIG_COMPAT - .compat_ioctl = sas_ioctl, -#endif .shost_groups = mvst_host_groups, + .sdev_groups = mvst_sdev_groups, .track_queue_depth = 1, }; @@ -691,13 +676,7 @@ static struct pci_driver mvs_pci_driver = { .remove = mvs_pci_remove, }; -static ssize_t driver_version_show(struct device *cdev, - struct device_attribute *attr, char *buffer) -{ - return sysfs_emit(buffer, "%s\n", DRV_VERSION); -} - -static DEVICE_ATTR_RO(driver_version); +static DEVICE_STRING_ATTR_RO(driver_version, 0444, DRV_VERSION); static ssize_t interrupt_coalescing_store(struct device *cdev, struct device_attribute *attr, @@ -772,13 +751,18 @@ static void __exit mvs_exit(void) } static struct attribute *mvst_host_attrs[] = { - &dev_attr_driver_version.attr, + &dev_attr_driver_version.attr.attr, &dev_attr_interrupt_coalescing.attr, NULL, }; ATTRIBUTE_GROUPS(mvst_host); +static const struct attribute_group *mvst_sdev_groups[] = { + &sas_ata_sdev_attr_group, + NULL +}; + module_init(mvs_init); module_exit(mvs_exit); diff --git a/drivers/scsi/pm8001/pm8001_ctl.c b/drivers/scsi/pm8001/pm8001_ctl.c index 7b27618fd7..85ff95c654 100644 --- a/drivers/scsi/pm8001/pm8001_ctl.c +++ b/drivers/scsi/pm8001/pm8001_ctl.c @@ -1039,3 +1039,8 @@ const struct attribute_group *pm8001_host_groups[] = { &pm8001_host_attr_group, NULL }; + +const struct attribute_group *pm8001_sdev_groups[] = { + &sas_ata_sdev_attr_group, + NULL +}; diff --git a/drivers/scsi/pm8001/pm8001_init.c b/drivers/scsi/pm8001/pm8001_init.c index ed6b7d954d..1e63cb6cd8 100644 --- a/drivers/scsi/pm8001/pm8001_init.c +++ b/drivers/scsi/pm8001/pm8001_init.c @@ -110,30 +110,13 @@ static void pm8001_map_queues(struct Scsi_Host *shost) * The main structure which LLDD must register for scsi core. */ static const struct scsi_host_template pm8001_sht = { - .module = THIS_MODULE, - .name = DRV_NAME, - .proc_name = DRV_NAME, - .queuecommand = sas_queuecommand, - .dma_need_drain = ata_scsi_dma_need_drain, - .target_alloc = sas_target_alloc, - .slave_configure = sas_slave_configure, + LIBSAS_SHT_BASE .scan_finished = pm8001_scan_finished, .scan_start = pm8001_scan_start, - .change_queue_depth = sas_change_queue_depth, - .bios_param = sas_bios_param, .can_queue = 1, - .this_id = -1, .sg_tablesize = PM8001_MAX_DMA_SG, - .max_sectors = SCSI_DEFAULT_MAX_SECTORS, - .eh_device_reset_handler = sas_eh_device_reset_handler, - .eh_target_reset_handler = sas_eh_target_reset_handler, - .slave_alloc = sas_slave_alloc, - .target_destroy = sas_target_destroy, - .ioctl = sas_ioctl, -#ifdef CONFIG_COMPAT - .compat_ioctl = sas_ioctl, -#endif .shost_groups = pm8001_host_groups, + .sdev_groups = pm8001_sdev_groups, .track_queue_depth = 1, .cmd_per_lun = 32, .map_queues = pm8001_map_queues, diff --git a/drivers/scsi/pm8001/pm8001_sas.h b/drivers/scsi/pm8001/pm8001_sas.h index 3ccb737190..ced6721380 100644 --- a/drivers/scsi/pm8001/pm8001_sas.h +++ b/drivers/scsi/pm8001/pm8001_sas.h @@ -717,6 +717,7 @@ int pm80xx_fatal_errors(struct pm8001_hba_info *pm8001_ha); void pm8001_free_dev(struct pm8001_device *pm8001_dev); /* ctl shared API */ extern const struct attribute_group *pm8001_host_groups[]; +extern const struct attribute_group *pm8001_sdev_groups[]; #define PM8001_INVALID_TAG ((u32)-1) diff --git a/drivers/scsi/pmcraid.c b/drivers/scsi/pmcraid.c index 0614b7e366..a2a084c807 100644 --- a/drivers/scsi/pmcraid.c +++ b/drivers/scsi/pmcraid.c @@ -197,8 +197,9 @@ static int pmcraid_slave_alloc(struct scsi_device *scsi_dev) } /** - * pmcraid_slave_configure - Configures a SCSI device + * pmcraid_device_configure - Configures a SCSI device * @scsi_dev: scsi device struct + * @lim: queue limits * * This function is executed by SCSI mid layer just after a device is first * scanned (i.e. it has responded to an INQUIRY). For VSET resources, the @@ -209,7 +210,8 @@ static int pmcraid_slave_alloc(struct scsi_device *scsi_dev) * Return value: * 0 on success */ -static int pmcraid_slave_configure(struct scsi_device *scsi_dev) +static int pmcraid_device_configure(struct scsi_device *scsi_dev, + struct queue_limits *lim) { struct pmcraid_resource_entry *res = scsi_dev->hostdata; @@ -233,8 +235,7 @@ static int pmcraid_slave_configure(struct scsi_device *scsi_dev) scsi_dev->allow_restart = 1; blk_queue_rq_timeout(scsi_dev->request_queue, PMCRAID_VSET_IO_TIMEOUT); - blk_queue_max_hw_sectors(scsi_dev->request_queue, - PMCRAID_VSET_MAX_SECTORS); + lim->max_hw_sectors = PMCRAID_VSET_MAX_SECTORS; } /* @@ -3668,7 +3669,7 @@ static const struct scsi_host_template pmcraid_host_template = { .eh_host_reset_handler = pmcraid_eh_host_reset_handler, .slave_alloc = pmcraid_slave_alloc, - .slave_configure = pmcraid_slave_configure, + .device_configure = pmcraid_device_configure, .slave_destroy = pmcraid_slave_destroy, .change_queue_depth = pmcraid_change_queue_depth, .can_queue = PMCRAID_MAX_IO_CMD, @@ -4035,7 +4036,7 @@ static int pmcraid_register_interrupt_handler(struct pmcraid_instance *pinstance) { struct pci_dev *pdev = pinstance->pdev; - unsigned int irq_flag = PCI_IRQ_LEGACY, flag; + unsigned int irq_flag = PCI_IRQ_INTX, flag; int num_hrrq, rc, i; irq_handler_t isr; diff --git a/drivers/scsi/ppa.c b/drivers/scsi/ppa.c index d592ee9170..8300f0bddd 100644 --- a/drivers/scsi/ppa.c +++ b/drivers/scsi/ppa.c @@ -986,12 +986,6 @@ second_pass: return -ENODEV; } -static int ppa_adjust_queue(struct scsi_device *device) -{ - blk_queue_bounce_limit(device->request_queue, BLK_BOUNCE_HIGH); - return 0; -} - static const struct scsi_host_template ppa_template = { .module = THIS_MODULE, .proc_name = "ppa", @@ -1005,7 +999,6 @@ static const struct scsi_host_template ppa_template = { .this_id = -1, .sg_tablesize = SG_ALL, .can_queue = 1, - .slave_alloc = ppa_adjust_queue, .cmd_size = sizeof(struct scsi_pointer), }; @@ -1111,6 +1104,7 @@ static int __ppa_attach(struct parport *pb) host = scsi_host_alloc(&ppa_template, sizeof(ppa_struct *)); if (!host) goto out1; + host->no_highmem = true; host->io_port = pb->base; host->n_io_port = ports; host->dma_channel = -1; diff --git a/drivers/scsi/qedf/qedf_main.c b/drivers/scsi/qedf/qedf_main.c index b97a8712d3..49adddf978 100644 --- a/drivers/scsi/qedf/qedf_main.c +++ b/drivers/scsi/qedf/qedf_main.c @@ -3479,7 +3479,7 @@ retry_probe: slowpath_params.drv_minor = QEDF_DRIVER_MINOR_VER; slowpath_params.drv_rev = QEDF_DRIVER_REV_VER; slowpath_params.drv_eng = QEDF_DRIVER_ENG_VER; - strncpy(slowpath_params.name, "qedf", QED_DRV_VER_STR_SIZE); + strscpy(slowpath_params.name, "qedf", sizeof(slowpath_params.name)); rc = qed_ops->common->slowpath_start(qedf->cdev, &slowpath_params); if (rc) { QEDF_ERR(&(qedf->dbg_ctx), "Cannot start slowpath.\n"); diff --git a/drivers/scsi/qla2xxx/Kconfig b/drivers/scsi/qla2xxx/Kconfig index a584708d30..a8b4314bfd 100644 --- a/drivers/scsi/qla2xxx/Kconfig +++ b/drivers/scsi/qla2xxx/Kconfig @@ -7,29 +7,29 @@ config SCSI_QLA_FC select FW_LOADER select BTREE help - This qla2xxx driver supports all QLogic Fibre Channel - PCI and PCIe host adapters. + This qla2xxx driver supports all QLogic Fibre Channel + PCI and PCIe host adapters. - By default, firmware for the ISP parts will be loaded - via the Firmware Loader interface. + By default, firmware for the ISP parts will be loaded + via the Firmware Loader interface. - ISP Firmware Filename - ---------- ----------------- - 21xx ql2100_fw.bin - 22xx ql2200_fw.bin - 2300, 2312, 6312 ql2300_fw.bin - 2322, 6322 ql2322_fw.bin - 24xx, 54xx ql2400_fw.bin - 25xx ql2500_fw.bin + ISP Firmware Filename + ---------- ----------------- + 21xx ql2100_fw.bin + 22xx ql2200_fw.bin + 2300, 2312, 6312 ql2300_fw.bin + 2322, 6322 ql2322_fw.bin + 24xx, 54xx ql2400_fw.bin + 25xx ql2500_fw.bin - Upon request, the driver caches the firmware image until - the driver is unloaded. + Upon request, the driver caches the firmware image until + the driver is unloaded. - Firmware images can be retrieved from: + Firmware images can be retrieved from: - http://ldriver.qlogic.com/firmware/ + http://ldriver.qlogic.com/firmware/ - They are also included in the linux-firmware tree as well. + They are also included in the linux-firmware tree as well. config TCM_QLA2XXX tristate "TCM_QLA2XXX fabric module for QLogic 24xx+ series target mode HBAs" @@ -38,13 +38,15 @@ config TCM_QLA2XXX select BTREE default n help - Say Y here to enable the TCM_QLA2XXX fabric module for QLogic 24xx+ series target mode HBAs + Say Y here to enable the TCM_QLA2XXX fabric module for QLogic 24xx+ + series target mode HBAs. if TCM_QLA2XXX config TCM_QLA2XXX_DEBUG bool "TCM_QLA2XXX fabric module DEBUG mode for QLogic 24xx+ series target mode HBAs" default n help - Say Y here to enable the TCM_QLA2XXX fabric module DEBUG for QLogic 24xx+ series target mode HBAs - This will include code to enable the SCSI command jammer + Say Y here to enable the TCM_QLA2XXX fabric module DEBUG for + QLogic 24xx+ series target mode HBAs. + This will include code to enable the SCSI command jammer. endif diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c index 76eeba435f..2810608acd 100644 --- a/drivers/scsi/qla2xxx/qla_attr.c +++ b/drivers/scsi/qla2xxx/qla_attr.c @@ -1067,13 +1067,6 @@ qla2x00_free_sysfs_attr(scsi_qla_host_t *vha, bool stop_beacon) /* Scsi_Host attributes. */ -static ssize_t -qla2x00_driver_version_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - return scnprintf(buf, PAGE_SIZE, "%s\n", qla2x00_version_str); -} - static ssize_t qla2x00_fw_version_show(struct device *dev, struct device_attribute *attr, char *buf) @@ -2412,7 +2405,7 @@ qla2x00_dport_diagnostics_show(struct device *dev, static DEVICE_ATTR(dport_diagnostics, 0444, qla2x00_dport_diagnostics_show, NULL); -static DEVICE_ATTR(driver_version, S_IRUGO, qla2x00_driver_version_show, NULL); +static DEVICE_STRING_ATTR_RO(driver_version, S_IRUGO, qla2x00_version_str); static DEVICE_ATTR(fw_version, S_IRUGO, qla2x00_fw_version_show, NULL); static DEVICE_ATTR(serial_num, S_IRUGO, qla2x00_serial_num_show, NULL); static DEVICE_ATTR(isp_name, S_IRUGO, qla2x00_isp_name_show, NULL); @@ -2478,7 +2471,7 @@ static DEVICE_ATTR(port_no, 0444, qla2x00_port_no_show, NULL); static DEVICE_ATTR(fw_attr, 0444, qla2x00_fw_attr_show, NULL); static struct attribute *qla2x00_host_attrs[] = { - &dev_attr_driver_version.attr, + &dev_attr_driver_version.attr.attr, &dev_attr_fw_version.attr, &dev_attr_serial_num.attr, &dev_attr_isp_name.attr, diff --git a/drivers/scsi/qla2xxx/qla_bsg.c b/drivers/scsi/qla2xxx/qla_bsg.c index 19bb64bdd8..52dc9604f5 100644 --- a/drivers/scsi/qla2xxx/qla_bsg.c +++ b/drivers/scsi/qla2xxx/qla_bsg.c @@ -324,7 +324,7 @@ qla2x00_process_els(struct bsg_job *bsg_job) "request_sg_cnt=%x reply_sg_cnt=%x.\n", bsg_job->request_payload.sg_cnt, bsg_job->reply_payload.sg_cnt); - rval = -EPERM; + rval = -ENOBUFS; goto done; } @@ -3059,17 +3059,61 @@ skip_chip_chk: return ret; } -int -qla24xx_bsg_timeout(struct bsg_job *bsg_job) +static bool qla_bsg_found(struct qla_qpair *qpair, struct bsg_job *bsg_job) { + bool found = false; struct fc_bsg_reply *bsg_reply = bsg_job->reply; scsi_qla_host_t *vha = shost_priv(fc_bsg_to_shost(bsg_job)); struct qla_hw_data *ha = vha->hw; - srb_t *sp; - int cnt, que; + srb_t *sp = NULL; + int cnt; unsigned long flags; struct req_que *req; + spin_lock_irqsave(qpair->qp_lock_ptr, flags); + req = qpair->req; + + for (cnt = 1; cnt < req->num_outstanding_cmds; cnt++) { + sp = req->outstanding_cmds[cnt]; + if (sp && + (sp->type == SRB_CT_CMD || + sp->type == SRB_ELS_CMD_HST || + sp->type == SRB_ELS_CMD_HST_NOLOGIN) && + sp->u.bsg_job == bsg_job) { + req->outstanding_cmds[cnt] = NULL; + spin_unlock_irqrestore(qpair->qp_lock_ptr, flags); + + if (!ha->flags.eeh_busy && ha->isp_ops->abort_command(sp)) { + ql_log(ql_log_warn, vha, 0x7089, + "mbx abort_command failed.\n"); + bsg_reply->result = -EIO; + } else { + ql_dbg(ql_dbg_user, vha, 0x708a, + "mbx abort_command success.\n"); + bsg_reply->result = 0; + } + /* ref: INIT */ + kref_put(&sp->cmd_kref, qla2x00_sp_release); + + found = true; + goto done; + } + } + spin_unlock_irqrestore(qpair->qp_lock_ptr, flags); + +done: + return found; +} + +int +qla24xx_bsg_timeout(struct bsg_job *bsg_job) +{ + struct fc_bsg_reply *bsg_reply = bsg_job->reply; + scsi_qla_host_t *vha = shost_priv(fc_bsg_to_shost(bsg_job)); + struct qla_hw_data *ha = vha->hw; + int i; + struct qla_qpair *qpair; + ql_log(ql_log_info, vha, 0x708b, "%s CMD timeout. bsg ptr %p.\n", __func__, bsg_job); @@ -3079,48 +3123,22 @@ qla24xx_bsg_timeout(struct bsg_job *bsg_job) qla_pci_set_eeh_busy(vha); } + if (qla_bsg_found(ha->base_qpair, bsg_job)) + goto done; + /* find the bsg job from the active list of commands */ - spin_lock_irqsave(&ha->hardware_lock, flags); - for (que = 0; que < ha->max_req_queues; que++) { - req = ha->req_q_map[que]; - if (!req) + for (i = 0; i < ha->max_qpairs; i++) { + qpair = vha->hw->queue_pair_map[i]; + if (!qpair) continue; - - for (cnt = 1; cnt < req->num_outstanding_cmds; cnt++) { - sp = req->outstanding_cmds[cnt]; - if (sp && - (sp->type == SRB_CT_CMD || - sp->type == SRB_ELS_CMD_HST || - sp->type == SRB_ELS_CMD_HST_NOLOGIN || - sp->type == SRB_FXIOCB_BCMD) && - sp->u.bsg_job == bsg_job) { - req->outstanding_cmds[cnt] = NULL; - spin_unlock_irqrestore(&ha->hardware_lock, flags); - - if (!ha->flags.eeh_busy && ha->isp_ops->abort_command(sp)) { - ql_log(ql_log_warn, vha, 0x7089, - "mbx abort_command failed.\n"); - bsg_reply->result = -EIO; - } else { - ql_dbg(ql_dbg_user, vha, 0x708a, - "mbx abort_command success.\n"); - bsg_reply->result = 0; - } - spin_lock_irqsave(&ha->hardware_lock, flags); - goto done; - - } - } + if (qla_bsg_found(qpair, bsg_job)) + goto done; } - spin_unlock_irqrestore(&ha->hardware_lock, flags); + ql_log(ql_log_info, vha, 0x708b, "SRB not found to abort.\n"); bsg_reply->result = -ENXIO; - return 0; done: - spin_unlock_irqrestore(&ha->hardware_lock, flags); - /* ref: INIT */ - kref_put(&sp->cmd_kref, qla2x00_sp_release); return 0; } diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h index 2f49baf131..7cf998e3cc 100644 --- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h @@ -3309,9 +3309,20 @@ struct fab_scan_rp { u8 node_name[8]; }; +enum scan_step { + FAB_SCAN_START, + FAB_SCAN_GPNFT_FCP, + FAB_SCAN_GNNFT_FCP, + FAB_SCAN_GPNFT_NVME, + FAB_SCAN_GNNFT_NVME, +}; + struct fab_scan { struct fab_scan_rp *l; u32 size; + u32 rscn_gen_start; + u32 rscn_gen_end; + enum scan_step step; u16 scan_retry; #define MAX_SCAN_RETRIES 5 enum scan_flags_t scan_flags; @@ -3537,9 +3548,8 @@ enum qla_work_type { QLA_EVT_RELOGIN, QLA_EVT_ASYNC_PRLO, QLA_EVT_ASYNC_PRLO_DONE, - QLA_EVT_GPNFT, - QLA_EVT_GPNFT_DONE, - QLA_EVT_GNNFT_DONE, + QLA_EVT_SCAN_CMD, + QLA_EVT_SCAN_FINISH, QLA_EVT_GFPNID, QLA_EVT_SP_RETRY, QLA_EVT_IIDMA, @@ -5030,6 +5040,7 @@ typedef struct scsi_qla_host { /* Counter to detect races between ELS and RSCN events */ atomic_t generation_tick; + atomic_t rscn_gen; /* Time when global fcport update has been scheduled */ int total_fcport_update_gen; /* List of pending LOGOs, protected by tgt_mutex */ diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h index 7309310d2a..cededfda9d 100644 --- a/drivers/scsi/qla2xxx/qla_gbl.h +++ b/drivers/scsi/qla2xxx/qla_gbl.h @@ -728,9 +728,9 @@ int qla24xx_async_gpsc(scsi_qla_host_t *, fc_port_t *); void qla24xx_handle_gpsc_event(scsi_qla_host_t *, struct event_arg *); int qla2x00_mgmt_svr_login(scsi_qla_host_t *); int qla24xx_async_gffid(scsi_qla_host_t *vha, fc_port_t *fcport, bool); -int qla24xx_async_gpnft(scsi_qla_host_t *, u8, srb_t *); -void qla24xx_async_gpnft_done(scsi_qla_host_t *, srb_t *); -void qla24xx_async_gnnft_done(scsi_qla_host_t *, srb_t *); +int qla_fab_async_scan(scsi_qla_host_t *, srb_t *); +void qla_fab_scan_start(struct scsi_qla_host *); +void qla_fab_scan_finish(scsi_qla_host_t *, srb_t *); int qla24xx_post_gfpnid_work(struct scsi_qla_host *, fc_port_t *); int qla24xx_async_gfpnid(scsi_qla_host_t *, fc_port_t *); void qla24xx_handle_gfpnid_event(scsi_qla_host_t *, struct event_arg *); diff --git a/drivers/scsi/qla2xxx/qla_gs.c b/drivers/scsi/qla2xxx/qla_gs.c index 1cf9d200d5..d2bddca704 100644 --- a/drivers/scsi/qla2xxx/qla_gs.c +++ b/drivers/scsi/qla2xxx/qla_gs.c @@ -1710,7 +1710,7 @@ qla2x00_hba_attributes(scsi_qla_host_t *vha, void *entries, eiter->type = cpu_to_be16(FDMI_HBA_OPTION_ROM_VERSION); alen = scnprintf( eiter->a.orom_version, sizeof(eiter->a.orom_version), - "%d.%02d", ha->bios_revision[1], ha->bios_revision[0]); + "%d.%02d", ha->efi_revision[1], ha->efi_revision[0]); alen += FDMI_ATTR_ALIGNMENT(alen); alen += FDMI_ATTR_TYPELEN(eiter); eiter->len = cpu_to_be16(alen); @@ -3168,7 +3168,30 @@ static int qla2x00_is_a_vp(scsi_qla_host_t *vha, u64 wwn) return rc; } -void qla24xx_async_gnnft_done(scsi_qla_host_t *vha, srb_t *sp) +static bool qla_ok_to_clear_rscn(scsi_qla_host_t *vha, fc_port_t *fcport) +{ + u32 rscn_gen; + + rscn_gen = atomic_read(&vha->rscn_gen); + ql_dbg(ql_dbg_disc + ql_dbg_verbose, vha, 0x2017, + "%s %d %8phC rscn_gen %x start %x end %x current %x\n", + __func__, __LINE__, fcport->port_name, fcport->rscn_gen, + vha->scan.rscn_gen_start, vha->scan.rscn_gen_end, rscn_gen); + + if (val_is_in_range(fcport->rscn_gen, vha->scan.rscn_gen_start, + vha->scan.rscn_gen_end)) + /* rscn came in before fabric scan */ + return true; + + if (val_is_in_range(fcport->rscn_gen, vha->scan.rscn_gen_end, rscn_gen)) + /* rscn came in after fabric scan */ + return false; + + /* rare: fcport's scan_needed + rscn_gen must be stale */ + return true; +} + +void qla_fab_scan_finish(scsi_qla_host_t *vha, srb_t *sp) { fc_port_t *fcport; u32 i, rc; @@ -3281,10 +3304,10 @@ void qla24xx_async_gnnft_done(scsi_qla_host_t *vha, srb_t *sp) (fcport->scan_needed && fcport->port_type != FCT_INITIATOR && fcport->port_type != FCT_NVME_INITIATOR)) { + fcport->scan_needed = 0; qlt_schedule_sess_for_deletion(fcport); } fcport->d_id.b24 = rp->id.b24; - fcport->scan_needed = 0; break; } @@ -3325,7 +3348,9 @@ login_logout: do_delete = true; } - fcport->scan_needed = 0; + if (qla_ok_to_clear_rscn(vha, fcport)) + fcport->scan_needed = 0; + if (((qla_dual_mode_enabled(vha) || qla_ini_mode_enabled(vha)) && atomic_read(&fcport->state) == FCS_ONLINE) || @@ -3355,7 +3380,9 @@ login_logout: fcport->port_name, fcport->loop_id, fcport->login_retry); } - fcport->scan_needed = 0; + + if (qla_ok_to_clear_rscn(vha, fcport)) + fcport->scan_needed = 0; qla24xx_fcport_handle_login(vha, fcport); } } @@ -3379,14 +3406,11 @@ out: } } -static int qla2x00_post_gnnft_gpnft_done_work(struct scsi_qla_host *vha, +static int qla2x00_post_next_scan_work(struct scsi_qla_host *vha, srb_t *sp, int cmd) { struct qla_work_evt *e; - if (cmd != QLA_EVT_GPNFT_DONE && cmd != QLA_EVT_GNNFT_DONE) - return QLA_PARAMETER_ERROR; - e = qla2x00_alloc_work(vha, cmd); if (!e) return QLA_FUNCTION_FAILED; @@ -3396,37 +3420,15 @@ static int qla2x00_post_gnnft_gpnft_done_work(struct scsi_qla_host *vha, return qla2x00_post_work(vha, e); } -static int qla2x00_post_nvme_gpnft_work(struct scsi_qla_host *vha, - srb_t *sp, int cmd) -{ - struct qla_work_evt *e; - - if (cmd != QLA_EVT_GPNFT) - return QLA_PARAMETER_ERROR; - - e = qla2x00_alloc_work(vha, cmd); - if (!e) - return QLA_FUNCTION_FAILED; - - e->u.gpnft.fc4_type = FC4_TYPE_NVME; - e->u.gpnft.sp = sp; - - return qla2x00_post_work(vha, e); -} - static void qla2x00_find_free_fcp_nvme_slot(struct scsi_qla_host *vha, struct srb *sp) { struct qla_hw_data *ha = vha->hw; int num_fibre_dev = ha->max_fibre_devices; - struct ct_sns_req *ct_req = - (struct ct_sns_req *)sp->u.iocb_cmd.u.ctarg.req; struct ct_sns_gpnft_rsp *ct_rsp = (struct ct_sns_gpnft_rsp *)sp->u.iocb_cmd.u.ctarg.rsp; struct ct_sns_gpn_ft_data *d; struct fab_scan_rp *rp; - u16 cmd = be16_to_cpu(ct_req->command); - u8 fc4_type = sp->gen2; int i, j, k; port_id_t id; u8 found; @@ -3445,85 +3447,83 @@ static void qla2x00_find_free_fcp_nvme_slot(struct scsi_qla_host *vha, if (id.b24 == 0 || wwn == 0) continue; - if (fc4_type == FC4_TYPE_FCP_SCSI) { - if (cmd == GPN_FT_CMD) { - rp = &vha->scan.l[j]; - rp->id = id; - memcpy(rp->port_name, d->port_name, 8); - j++; - rp->fc4type = FS_FC4TYPE_FCP; - } else { - for (k = 0; k < num_fibre_dev; k++) { - rp = &vha->scan.l[k]; - if (id.b24 == rp->id.b24) { - memcpy(rp->node_name, - d->port_name, 8); - break; - } + ql_dbg(ql_dbg_disc + ql_dbg_verbose, vha, 0x2025, + "%s %06x %8ph \n", + __func__, id.b24, d->port_name); + + switch (vha->scan.step) { + case FAB_SCAN_GPNFT_FCP: + rp = &vha->scan.l[j]; + rp->id = id; + memcpy(rp->port_name, d->port_name, 8); + j++; + rp->fc4type = FS_FC4TYPE_FCP; + break; + case FAB_SCAN_GNNFT_FCP: + for (k = 0; k < num_fibre_dev; k++) { + rp = &vha->scan.l[k]; + if (id.b24 == rp->id.b24) { + memcpy(rp->node_name, + d->port_name, 8); + break; } } - } else { - /* Search if the fibre device supports FC4_TYPE_NVME */ - if (cmd == GPN_FT_CMD) { - found = 0; - - for (k = 0; k < num_fibre_dev; k++) { - rp = &vha->scan.l[k]; - if (!memcmp(rp->port_name, - d->port_name, 8)) { - /* - * Supports FC-NVMe & FCP - */ - rp->fc4type |= FS_FC4TYPE_NVME; - found = 1; - break; - } + break; + case FAB_SCAN_GPNFT_NVME: + found = 0; + + for (k = 0; k < num_fibre_dev; k++) { + rp = &vha->scan.l[k]; + if (!memcmp(rp->port_name, d->port_name, 8)) { + /* + * Supports FC-NVMe & FCP + */ + rp->fc4type |= FS_FC4TYPE_NVME; + found = 1; + break; } + } - /* We found new FC-NVMe only port */ - if (!found) { - for (k = 0; k < num_fibre_dev; k++) { - rp = &vha->scan.l[k]; - if (wwn_to_u64(rp->port_name)) { - continue; - } else { - rp->id = id; - memcpy(rp->port_name, - d->port_name, 8); - rp->fc4type = - FS_FC4TYPE_NVME; - break; - } - } - } - } else { + /* We found new FC-NVMe only port */ + if (!found) { for (k = 0; k < num_fibre_dev; k++) { rp = &vha->scan.l[k]; - if (id.b24 == rp->id.b24) { - memcpy(rp->node_name, - d->port_name, 8); + if (wwn_to_u64(rp->port_name)) { + continue; + } else { + rp->id = id; + memcpy(rp->port_name, d->port_name, 8); + rp->fc4type = FS_FC4TYPE_NVME; break; } } } + break; + case FAB_SCAN_GNNFT_NVME: + for (k = 0; k < num_fibre_dev; k++) { + rp = &vha->scan.l[k]; + if (id.b24 == rp->id.b24) { + memcpy(rp->node_name, d->port_name, 8); + break; + } + } + break; + default: + break; } } } -static void qla2x00_async_gpnft_gnnft_sp_done(srb_t *sp, int res) +static void qla_async_scan_sp_done(srb_t *sp, int res) { struct scsi_qla_host *vha = sp->vha; - struct ct_sns_req *ct_req = - (struct ct_sns_req *)sp->u.iocb_cmd.u.ctarg.req; - u16 cmd = be16_to_cpu(ct_req->command); - u8 fc4_type = sp->gen2; unsigned long flags; int rc; /* gen2 field is holding the fc4type */ - ql_dbg(ql_dbg_disc, vha, 0xffff, - "Async done-%s res %x FC4Type %x\n", - sp->name, res, sp->gen2); + ql_dbg(ql_dbg_disc, vha, 0x2026, + "Async done-%s res %x step %x\n", + sp->name, res, vha->scan.step); sp->rc = res; if (res) { @@ -3547,8 +3547,7 @@ static void qla2x00_async_gpnft_gnnft_sp_done(srb_t *sp, int res) * sp for GNNFT_DONE work. This will allow all * the resource to get freed up. */ - rc = qla2x00_post_gnnft_gpnft_done_work(vha, sp, - QLA_EVT_GNNFT_DONE); + rc = qla2x00_post_next_scan_work(vha, sp, QLA_EVT_SCAN_FINISH); if (rc) { /* Cleanup here to prevent memory leak */ qla24xx_sp_unmap(vha, sp); @@ -3573,28 +3572,30 @@ static void qla2x00_async_gpnft_gnnft_sp_done(srb_t *sp, int res) qla2x00_find_free_fcp_nvme_slot(vha, sp); - if ((fc4_type == FC4_TYPE_FCP_SCSI) && vha->flags.nvme_enabled && - cmd == GNN_FT_CMD) { - spin_lock_irqsave(&vha->work_lock, flags); - vha->scan.scan_flags &= ~SF_SCANNING; - spin_unlock_irqrestore(&vha->work_lock, flags); + spin_lock_irqsave(&vha->work_lock, flags); + vha->scan.scan_flags &= ~SF_SCANNING; + spin_unlock_irqrestore(&vha->work_lock, flags); - sp->rc = res; - rc = qla2x00_post_nvme_gpnft_work(vha, sp, QLA_EVT_GPNFT); - if (rc) { - qla24xx_sp_unmap(vha, sp); - set_bit(LOCAL_LOOP_UPDATE, &vha->dpc_flags); - set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags); - } - return; - } + switch (vha->scan.step) { + case FAB_SCAN_GPNFT_FCP: + case FAB_SCAN_GPNFT_NVME: + rc = qla2x00_post_next_scan_work(vha, sp, QLA_EVT_SCAN_CMD); + break; + case FAB_SCAN_GNNFT_FCP: + if (vha->flags.nvme_enabled) + rc = qla2x00_post_next_scan_work(vha, sp, QLA_EVT_SCAN_CMD); + else + rc = qla2x00_post_next_scan_work(vha, sp, QLA_EVT_SCAN_FINISH); - if (cmd == GPN_FT_CMD) { - rc = qla2x00_post_gnnft_gpnft_done_work(vha, sp, - QLA_EVT_GPNFT_DONE); - } else { - rc = qla2x00_post_gnnft_gpnft_done_work(vha, sp, - QLA_EVT_GNNFT_DONE); + break; + case FAB_SCAN_GNNFT_NVME: + rc = qla2x00_post_next_scan_work(vha, sp, QLA_EVT_SCAN_FINISH); + break; + default: + /* should not be here */ + WARN_ON(1); + rc = QLA_FUNCTION_FAILED; + break; } if (rc) { @@ -3605,127 +3606,16 @@ static void qla2x00_async_gpnft_gnnft_sp_done(srb_t *sp, int res) } } -/* - * Get WWNN list for fc4_type - * - * It is assumed the same SRB is re-used from GPNFT to avoid - * mem free & re-alloc - */ -static int qla24xx_async_gnnft(scsi_qla_host_t *vha, struct srb *sp, - u8 fc4_type) -{ - int rval = QLA_FUNCTION_FAILED; - struct ct_sns_req *ct_req; - struct ct_sns_pkt *ct_sns; - unsigned long flags; - - if (!vha->flags.online) { - spin_lock_irqsave(&vha->work_lock, flags); - vha->scan.scan_flags &= ~SF_SCANNING; - spin_unlock_irqrestore(&vha->work_lock, flags); - goto done_free_sp; - } - - if (!sp->u.iocb_cmd.u.ctarg.req || !sp->u.iocb_cmd.u.ctarg.rsp) { - ql_log(ql_log_warn, vha, 0xffff, - "%s: req %p rsp %p are not setup\n", - __func__, sp->u.iocb_cmd.u.ctarg.req, - sp->u.iocb_cmd.u.ctarg.rsp); - spin_lock_irqsave(&vha->work_lock, flags); - vha->scan.scan_flags &= ~SF_SCANNING; - spin_unlock_irqrestore(&vha->work_lock, flags); - WARN_ON(1); - set_bit(LOCAL_LOOP_UPDATE, &vha->dpc_flags); - set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags); - goto done_free_sp; - } - - ql_dbg(ql_dbg_disc, vha, 0xfffff, - "%s: FC4Type %x, CT-PASSTHRU %s command ctarg rsp size %d, ctarg req size %d\n", - __func__, fc4_type, sp->name, sp->u.iocb_cmd.u.ctarg.rsp_size, - sp->u.iocb_cmd.u.ctarg.req_size); - - sp->type = SRB_CT_PTHRU_CMD; - sp->name = "gnnft"; - sp->gen1 = vha->hw->base_qpair->chip_reset; - sp->gen2 = fc4_type; - qla2x00_init_async_sp(sp, qla2x00_get_async_timeout(vha) + 2, - qla2x00_async_gpnft_gnnft_sp_done); - - memset(sp->u.iocb_cmd.u.ctarg.rsp, 0, sp->u.iocb_cmd.u.ctarg.rsp_size); - memset(sp->u.iocb_cmd.u.ctarg.req, 0, sp->u.iocb_cmd.u.ctarg.req_size); - - ct_sns = (struct ct_sns_pkt *)sp->u.iocb_cmd.u.ctarg.req; - /* CT_IU preamble */ - ct_req = qla2x00_prep_ct_req(ct_sns, GNN_FT_CMD, - sp->u.iocb_cmd.u.ctarg.rsp_size); - - /* GPN_FT req */ - ct_req->req.gpn_ft.port_type = fc4_type; - - sp->u.iocb_cmd.u.ctarg.req_size = GNN_FT_REQ_SIZE; - sp->u.iocb_cmd.u.ctarg.nport_handle = NPH_SNS; - - ql_dbg(ql_dbg_disc, vha, 0xffff, - "Async-%s hdl=%x FC4Type %x.\n", sp->name, - sp->handle, ct_req->req.gpn_ft.port_type); - - rval = qla2x00_start_sp(sp); - if (rval != QLA_SUCCESS) { - goto done_free_sp; - } - - return rval; - -done_free_sp: - if (sp->u.iocb_cmd.u.ctarg.req) { - dma_free_coherent(&vha->hw->pdev->dev, - sp->u.iocb_cmd.u.ctarg.req_allocated_size, - sp->u.iocb_cmd.u.ctarg.req, - sp->u.iocb_cmd.u.ctarg.req_dma); - sp->u.iocb_cmd.u.ctarg.req = NULL; - } - if (sp->u.iocb_cmd.u.ctarg.rsp) { - dma_free_coherent(&vha->hw->pdev->dev, - sp->u.iocb_cmd.u.ctarg.rsp_allocated_size, - sp->u.iocb_cmd.u.ctarg.rsp, - sp->u.iocb_cmd.u.ctarg.rsp_dma); - sp->u.iocb_cmd.u.ctarg.rsp = NULL; - } - /* ref: INIT */ - kref_put(&sp->cmd_kref, qla2x00_sp_release); - - spin_lock_irqsave(&vha->work_lock, flags); - vha->scan.scan_flags &= ~SF_SCANNING; - if (vha->scan.scan_flags == 0) { - ql_dbg(ql_dbg_disc, vha, 0xffff, - "%s: schedule\n", __func__); - vha->scan.scan_flags |= SF_QUEUED; - schedule_delayed_work(&vha->scan.scan_work, 5); - } - spin_unlock_irqrestore(&vha->work_lock, flags); - - - return rval; -} /* GNNFT */ - -void qla24xx_async_gpnft_done(scsi_qla_host_t *vha, srb_t *sp) -{ - ql_dbg(ql_dbg_disc + ql_dbg_verbose, vha, 0xffff, - "%s enter\n", __func__); - qla24xx_async_gnnft(vha, sp, sp->gen2); -} - /* Get WWPN list for certain fc4_type */ -int qla24xx_async_gpnft(scsi_qla_host_t *vha, u8 fc4_type, srb_t *sp) +int qla_fab_async_scan(scsi_qla_host_t *vha, srb_t *sp) { int rval = QLA_FUNCTION_FAILED; struct ct_sns_req *ct_req; struct ct_sns_pkt *ct_sns; - u32 rspsz; + u32 rspsz = 0; unsigned long flags; - ql_dbg(ql_dbg_disc + ql_dbg_verbose, vha, 0xffff, + ql_dbg(ql_dbg_disc + ql_dbg_verbose, vha, 0x200c, "%s enter\n", __func__); if (!vha->flags.online) @@ -3734,22 +3624,21 @@ int qla24xx_async_gpnft(scsi_qla_host_t *vha, u8 fc4_type, srb_t *sp) spin_lock_irqsave(&vha->work_lock, flags); if (vha->scan.scan_flags & SF_SCANNING) { spin_unlock_irqrestore(&vha->work_lock, flags); - ql_dbg(ql_dbg_disc + ql_dbg_verbose, vha, 0xffff, + ql_dbg(ql_dbg_disc + ql_dbg_verbose, vha, 0x2012, "%s: scan active\n", __func__); return rval; } vha->scan.scan_flags |= SF_SCANNING; + if (!sp) + vha->scan.step = FAB_SCAN_START; + spin_unlock_irqrestore(&vha->work_lock, flags); - if (fc4_type == FC4_TYPE_FCP_SCSI) { - ql_dbg(ql_dbg_disc + ql_dbg_verbose, vha, 0xffff, + switch (vha->scan.step) { + case FAB_SCAN_START: + ql_dbg(ql_dbg_disc + ql_dbg_verbose, vha, 0x2018, "%s: Performing FCP Scan\n", __func__); - if (sp) { - /* ref: INIT */ - kref_put(&sp->cmd_kref, qla2x00_sp_release); - } - /* ref: INIT */ sp = qla2x00_get_sp(vha, NULL, GFP_KERNEL); if (!sp) { @@ -3765,7 +3654,7 @@ int qla24xx_async_gpnft(scsi_qla_host_t *vha, u8 fc4_type, srb_t *sp) GFP_KERNEL); sp->u.iocb_cmd.u.ctarg.req_allocated_size = sizeof(struct ct_sns_pkt); if (!sp->u.iocb_cmd.u.ctarg.req) { - ql_log(ql_log_warn, vha, 0xffff, + ql_log(ql_log_warn, vha, 0x201a, "Failed to allocate ct_sns request.\n"); spin_lock_irqsave(&vha->work_lock, flags); vha->scan.scan_flags &= ~SF_SCANNING; @@ -3773,7 +3662,6 @@ int qla24xx_async_gpnft(scsi_qla_host_t *vha, u8 fc4_type, srb_t *sp) qla2x00_rel_sp(sp); return rval; } - sp->u.iocb_cmd.u.ctarg.req_size = GPN_FT_REQ_SIZE; rspsz = sizeof(struct ct_sns_gpnft_rsp) + vha->hw->max_fibre_devices * @@ -3785,7 +3673,7 @@ int qla24xx_async_gpnft(scsi_qla_host_t *vha, u8 fc4_type, srb_t *sp) GFP_KERNEL); sp->u.iocb_cmd.u.ctarg.rsp_allocated_size = rspsz; if (!sp->u.iocb_cmd.u.ctarg.rsp) { - ql_log(ql_log_warn, vha, 0xffff, + ql_log(ql_log_warn, vha, 0x201b, "Failed to allocate ct_sns request.\n"); spin_lock_irqsave(&vha->work_lock, flags); vha->scan.scan_flags &= ~SF_SCANNING; @@ -3805,35 +3693,95 @@ int qla24xx_async_gpnft(scsi_qla_host_t *vha, u8 fc4_type, srb_t *sp) "%s scan list size %d\n", __func__, vha->scan.size); memset(vha->scan.l, 0, vha->scan.size); - } else if (!sp) { - ql_dbg(ql_dbg_disc, vha, 0xffff, - "NVME scan did not provide SP\n"); + + vha->scan.step = FAB_SCAN_GPNFT_FCP; + break; + case FAB_SCAN_GPNFT_FCP: + vha->scan.step = FAB_SCAN_GNNFT_FCP; + break; + case FAB_SCAN_GNNFT_FCP: + vha->scan.step = FAB_SCAN_GPNFT_NVME; + break; + case FAB_SCAN_GPNFT_NVME: + vha->scan.step = FAB_SCAN_GNNFT_NVME; + break; + case FAB_SCAN_GNNFT_NVME: + default: + /* should not be here */ + WARN_ON(1); + goto done_free_sp; + } + + if (!sp) { + ql_dbg(ql_dbg_disc, vha, 0x201c, + "scan did not provide SP\n"); return rval; } + if (!sp->u.iocb_cmd.u.ctarg.req || !sp->u.iocb_cmd.u.ctarg.rsp) { + ql_log(ql_log_warn, vha, 0x201d, + "%s: req %p rsp %p are not setup\n", + __func__, sp->u.iocb_cmd.u.ctarg.req, + sp->u.iocb_cmd.u.ctarg.rsp); + spin_lock_irqsave(&vha->work_lock, flags); + vha->scan.scan_flags &= ~SF_SCANNING; + spin_unlock_irqrestore(&vha->work_lock, flags); + WARN_ON(1); + set_bit(LOCAL_LOOP_UPDATE, &vha->dpc_flags); + set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags); + goto done_free_sp; + } + + rspsz = sp->u.iocb_cmd.u.ctarg.rsp_size; + memset(sp->u.iocb_cmd.u.ctarg.req, 0, sp->u.iocb_cmd.u.ctarg.req_size); + memset(sp->u.iocb_cmd.u.ctarg.rsp, 0, sp->u.iocb_cmd.u.ctarg.rsp_size); + sp->type = SRB_CT_PTHRU_CMD; - sp->name = "gpnft"; sp->gen1 = vha->hw->base_qpair->chip_reset; - sp->gen2 = fc4_type; qla2x00_init_async_sp(sp, qla2x00_get_async_timeout(vha) + 2, - qla2x00_async_gpnft_gnnft_sp_done); - - rspsz = sp->u.iocb_cmd.u.ctarg.rsp_size; - memset(sp->u.iocb_cmd.u.ctarg.rsp, 0, sp->u.iocb_cmd.u.ctarg.rsp_size); - memset(sp->u.iocb_cmd.u.ctarg.req, 0, sp->u.iocb_cmd.u.ctarg.req_size); + qla_async_scan_sp_done); ct_sns = (struct ct_sns_pkt *)sp->u.iocb_cmd.u.ctarg.req; - /* CT_IU preamble */ - ct_req = qla2x00_prep_ct_req(ct_sns, GPN_FT_CMD, rspsz); - /* GPN_FT req */ - ct_req->req.gpn_ft.port_type = fc4_type; + /* CT_IU preamble */ + switch (vha->scan.step) { + case FAB_SCAN_GPNFT_FCP: + sp->name = "gpnft"; + ct_req = qla2x00_prep_ct_req(ct_sns, GPN_FT_CMD, rspsz); + ct_req->req.gpn_ft.port_type = FC4_TYPE_FCP_SCSI; + sp->u.iocb_cmd.u.ctarg.req_size = GPN_FT_REQ_SIZE; + break; + case FAB_SCAN_GNNFT_FCP: + sp->name = "gnnft"; + ct_req = qla2x00_prep_ct_req(ct_sns, GNN_FT_CMD, rspsz); + ct_req->req.gpn_ft.port_type = FC4_TYPE_FCP_SCSI; + sp->u.iocb_cmd.u.ctarg.req_size = GNN_FT_REQ_SIZE; + break; + case FAB_SCAN_GPNFT_NVME: + sp->name = "gpnft"; + ct_req = qla2x00_prep_ct_req(ct_sns, GPN_FT_CMD, rspsz); + ct_req->req.gpn_ft.port_type = FC4_TYPE_NVME; + sp->u.iocb_cmd.u.ctarg.req_size = GPN_FT_REQ_SIZE; + break; + case FAB_SCAN_GNNFT_NVME: + sp->name = "gnnft"; + ct_req = qla2x00_prep_ct_req(ct_sns, GNN_FT_CMD, rspsz); + ct_req->req.gpn_ft.port_type = FC4_TYPE_NVME; + sp->u.iocb_cmd.u.ctarg.req_size = GNN_FT_REQ_SIZE; + break; + default: + /* should not be here */ + WARN_ON(1); + goto done_free_sp; + } sp->u.iocb_cmd.u.ctarg.nport_handle = NPH_SNS; - ql_dbg(ql_dbg_disc, vha, 0xffff, - "Async-%s hdl=%x FC4Type %x.\n", sp->name, - sp->handle, ct_req->req.gpn_ft.port_type); + ql_dbg(ql_dbg_disc, vha, 0x2003, + "%s: step %d, rsp size %d, req size %d hdl %x %s FC4TYPE %x \n", + __func__, vha->scan.step, sp->u.iocb_cmd.u.ctarg.rsp_size, + sp->u.iocb_cmd.u.ctarg.req_size, sp->handle, sp->name, + ct_req->req.gpn_ft.port_type); rval = qla2x00_start_sp(sp); if (rval != QLA_SUCCESS) { @@ -3864,7 +3812,7 @@ done_free_sp: spin_lock_irqsave(&vha->work_lock, flags); vha->scan.scan_flags &= ~SF_SCANNING; if (vha->scan.scan_flags == 0) { - ql_dbg(ql_dbg_disc + ql_dbg_verbose, vha, 0xffff, + ql_dbg(ql_dbg_disc + ql_dbg_verbose, vha, 0x2007, "%s: Scan scheduled.\n", __func__); vha->scan.scan_flags |= SF_QUEUED; schedule_delayed_work(&vha->scan.scan_work, 5); @@ -3875,6 +3823,15 @@ done_free_sp: return rval; } +void qla_fab_scan_start(struct scsi_qla_host *vha) +{ + int rval; + + rval = qla_fab_async_scan(vha, NULL); + if (rval) + set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags); +} + void qla_scan_work_fn(struct work_struct *work) { struct fab_scan *s = container_of(to_delayed_work(work), diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index 8377624d76..eda3bdab93 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c @@ -1842,10 +1842,18 @@ int qla24xx_post_newsess_work(struct scsi_qla_host *vha, port_id_t *id, return qla2x00_post_work(vha, e); } +static void qla_rscn_gen_tick(scsi_qla_host_t *vha, u32 *ret_rscn_gen) +{ + *ret_rscn_gen = atomic_inc_return(&vha->rscn_gen); + /* memory barrier */ + wmb(); +} + void qla2x00_handle_rscn(scsi_qla_host_t *vha, struct event_arg *ea) { fc_port_t *fcport; unsigned long flags; + u32 rscn_gen; switch (ea->id.b.rsvd_1) { case RSCN_PORT_ADDR: @@ -1875,15 +1883,16 @@ void qla2x00_handle_rscn(scsi_qla_host_t *vha, struct event_arg *ea) * Otherwise we're already in the middle of a relogin */ fcport->scan_needed = 1; - fcport->rscn_gen++; + qla_rscn_gen_tick(vha, &fcport->rscn_gen); } } else { fcport->scan_needed = 1; - fcport->rscn_gen++; + qla_rscn_gen_tick(vha, &fcport->rscn_gen); } } break; case RSCN_AREA_ADDR: + qla_rscn_gen_tick(vha, &rscn_gen); list_for_each_entry(fcport, &vha->vp_fcports, list) { if (fcport->flags & FCF_FCP2_DEVICE && atomic_read(&fcport->state) == FCS_ONLINE) @@ -1891,11 +1900,12 @@ void qla2x00_handle_rscn(scsi_qla_host_t *vha, struct event_arg *ea) if ((ea->id.b24 & 0xffff00) == (fcport->d_id.b24 & 0xffff00)) { fcport->scan_needed = 1; - fcport->rscn_gen++; + fcport->rscn_gen = rscn_gen; } } break; case RSCN_DOM_ADDR: + qla_rscn_gen_tick(vha, &rscn_gen); list_for_each_entry(fcport, &vha->vp_fcports, list) { if (fcport->flags & FCF_FCP2_DEVICE && atomic_read(&fcport->state) == FCS_ONLINE) @@ -1903,19 +1913,20 @@ void qla2x00_handle_rscn(scsi_qla_host_t *vha, struct event_arg *ea) if ((ea->id.b24 & 0xff0000) == (fcport->d_id.b24 & 0xff0000)) { fcport->scan_needed = 1; - fcport->rscn_gen++; + fcport->rscn_gen = rscn_gen; } } break; case RSCN_FAB_ADDR: default: + qla_rscn_gen_tick(vha, &rscn_gen); list_for_each_entry(fcport, &vha->vp_fcports, list) { if (fcport->flags & FCF_FCP2_DEVICE && atomic_read(&fcport->state) == FCS_ONLINE) continue; fcport->scan_needed = 1; - fcport->rscn_gen++; + fcport->rscn_gen = rscn_gen; } break; } @@ -1924,6 +1935,7 @@ void qla2x00_handle_rscn(scsi_qla_host_t *vha, struct event_arg *ea) if (vha->scan.scan_flags == 0) { ql_dbg(ql_dbg_disc, vha, 0xffff, "%s: schedule\n", __func__); vha->scan.scan_flags |= SF_QUEUED; + vha->scan.rscn_gen_start = atomic_read(&vha->rscn_gen); schedule_delayed_work(&vha->scan.scan_work, 5); } spin_unlock_irqrestore(&vha->work_lock, flags); @@ -6393,10 +6405,9 @@ qla2x00_configure_fabric(scsi_qla_host_t *vha) qlt_do_generation_tick(vha, &discovery_gen); if (USE_ASYNC_SCAN(ha)) { - rval = qla24xx_async_gpnft(vha, FC4_TYPE_FCP_SCSI, - NULL); - if (rval) - set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags); + /* start of scan begins here */ + vha->scan.rscn_gen_end = atomic_read(&vha->rscn_gen); + qla_fab_scan_start(vha); } else { list_for_each_entry(fcport, &vha->vp_fcports, list) fcport->scan_state = QLA_FCPORT_SCAN; @@ -8207,15 +8218,21 @@ qla28xx_get_aux_images( struct qla27xx_image_status pri_aux_image_status, sec_aux_image_status; bool valid_pri_image = false, valid_sec_image = false; bool active_pri_image = false, active_sec_image = false; + int rc; if (!ha->flt_region_aux_img_status_pri) { ql_dbg(ql_dbg_init, vha, 0x018a, "Primary aux image not addressed\n"); goto check_sec_image; } - qla24xx_read_flash_data(vha, (uint32_t *)&pri_aux_image_status, + rc = qla24xx_read_flash_data(vha, (uint32_t *)&pri_aux_image_status, ha->flt_region_aux_img_status_pri, sizeof(pri_aux_image_status) >> 2); + if (rc) { + ql_log(ql_log_info, vha, 0x01a1, + "Unable to read Primary aux image(%x).\n", rc); + goto check_sec_image; + } qla27xx_print_image(vha, "Primary aux image", &pri_aux_image_status); if (qla28xx_check_aux_image_status_signature(&pri_aux_image_status)) { @@ -8246,9 +8263,15 @@ check_sec_image: goto check_valid_image; } - qla24xx_read_flash_data(vha, (uint32_t *)&sec_aux_image_status, + rc = qla24xx_read_flash_data(vha, (uint32_t *)&sec_aux_image_status, ha->flt_region_aux_img_status_sec, sizeof(sec_aux_image_status) >> 2); + if (rc) { + ql_log(ql_log_info, vha, 0x01a2, + "Unable to read Secondary aux image(%x).\n", rc); + goto check_valid_image; + } + qla27xx_print_image(vha, "Secondary aux image", &sec_aux_image_status); if (qla28xx_check_aux_image_status_signature(&sec_aux_image_status)) { @@ -8306,6 +8329,7 @@ qla27xx_get_active_image(struct scsi_qla_host *vha, struct qla27xx_image_status pri_image_status, sec_image_status; bool valid_pri_image = false, valid_sec_image = false; bool active_pri_image = false, active_sec_image = false; + int rc; if (!ha->flt_region_img_status_pri) { ql_dbg(ql_dbg_init, vha, 0x018a, "Primary image not addressed\n"); @@ -8347,8 +8371,14 @@ check_sec_image: goto check_valid_image; } - qla24xx_read_flash_data(vha, (uint32_t *)(&sec_image_status), + rc = qla24xx_read_flash_data(vha, (uint32_t *)(&sec_image_status), ha->flt_region_img_status_sec, sizeof(sec_image_status) >> 2); + if (rc) { + ql_log(ql_log_info, vha, 0x01a3, + "Unable to read Secondary image status(%x).\n", rc); + goto check_valid_image; + } + qla27xx_print_image(vha, "Secondary image", &sec_image_status); if (qla27xx_check_image_status_signature(&sec_image_status)) { @@ -8420,11 +8450,10 @@ qla24xx_load_risc_flash(scsi_qla_host_t *vha, uint32_t *srisc_addr, "FW: Loading firmware from flash (%x).\n", faddr); dcode = (uint32_t *)req->ring; - qla24xx_read_flash_data(vha, dcode, faddr, 8); - if (qla24xx_risc_firmware_invalid(dcode)) { + rval = qla24xx_read_flash_data(vha, dcode, faddr, 8); + if (rval || qla24xx_risc_firmware_invalid(dcode)) { ql_log(ql_log_fatal, vha, 0x008c, - "Unable to verify the integrity of flash firmware " - "image.\n"); + "Unable to verify the integrity of flash firmware image (rval %x).\n", rval); ql_log(ql_log_fatal, vha, 0x008d, "Firmware data: %08x %08x %08x %08x.\n", dcode[0], dcode[1], dcode[2], dcode[3]); @@ -8438,7 +8467,12 @@ qla24xx_load_risc_flash(scsi_qla_host_t *vha, uint32_t *srisc_addr, for (j = 0; j < segments; j++) { ql_dbg(ql_dbg_init, vha, 0x008d, "-> Loading segment %u...\n", j); - qla24xx_read_flash_data(vha, dcode, faddr, 10); + rval = qla24xx_read_flash_data(vha, dcode, faddr, 10); + if (rval) { + ql_log(ql_log_fatal, vha, 0x016a, + "-> Unable to read segment addr + size .\n"); + return QLA_FUNCTION_FAILED; + } risc_addr = be32_to_cpu((__force __be32)dcode[2]); risc_size = be32_to_cpu((__force __be32)dcode[3]); if (!*srisc_addr) { @@ -8454,7 +8488,13 @@ qla24xx_load_risc_flash(scsi_qla_host_t *vha, uint32_t *srisc_addr, ql_dbg(ql_dbg_init, vha, 0x008e, "-> Loading fragment %u: %#x <- %#x (%#lx dwords)...\n", fragment, risc_addr, faddr, dlen); - qla24xx_read_flash_data(vha, dcode, faddr, dlen); + rval = qla24xx_read_flash_data(vha, dcode, faddr, dlen); + if (rval) { + ql_log(ql_log_fatal, vha, 0x016b, + "-> Unable to read fragment(faddr %#x dlen %#lx).\n", + faddr, dlen); + return QLA_FUNCTION_FAILED; + } for (i = 0; i < dlen; i++) dcode[i] = swab32(dcode[i]); @@ -8483,7 +8523,14 @@ qla24xx_load_risc_flash(scsi_qla_host_t *vha, uint32_t *srisc_addr, fwdt->length = 0; dcode = (uint32_t *)req->ring; - qla24xx_read_flash_data(vha, dcode, faddr, 7); + + rval = qla24xx_read_flash_data(vha, dcode, faddr, 7); + if (rval) { + ql_log(ql_log_fatal, vha, 0x016c, + "-> Unable to read template size.\n"); + goto failed; + } + risc_size = be32_to_cpu((__force __be32)dcode[2]); ql_dbg(ql_dbg_init, vha, 0x0161, "-> fwdt%u template array at %#x (%#x dwords)\n", @@ -8509,11 +8556,12 @@ qla24xx_load_risc_flash(scsi_qla_host_t *vha, uint32_t *srisc_addr, } dcode = fwdt->template; - qla24xx_read_flash_data(vha, dcode, faddr, risc_size); + rval = qla24xx_read_flash_data(vha, dcode, faddr, risc_size); - if (!qla27xx_fwdt_template_valid(dcode)) { + if (rval || !qla27xx_fwdt_template_valid(dcode)) { ql_log(ql_log_warn, vha, 0x0165, - "-> fwdt%u failed template validate\n", j); + "-> fwdt%u failed template validate (rval %x)\n", + j, rval); goto failed; } diff --git a/drivers/scsi/qla2xxx/qla_inline.h b/drivers/scsi/qla2xxx/qla_inline.h index a4a56ab0ba..ef4b3cc1cd 100644 --- a/drivers/scsi/qla2xxx/qla_inline.h +++ b/drivers/scsi/qla2xxx/qla_inline.h @@ -631,3 +631,11 @@ static inline int qla_mapq_alloc_qp_cpu_map(struct qla_hw_data *ha) } return 0; } + +static inline bool val_is_in_range(u32 val, u32 start, u32 end) +{ + if (val >= start && val <= end) + return true; + else + return false; +} diff --git a/drivers/scsi/qla2xxx/qla_mid.c b/drivers/scsi/qla2xxx/qla_mid.c index b67416951a..76703f2706 100644 --- a/drivers/scsi/qla2xxx/qla_mid.c +++ b/drivers/scsi/qla2xxx/qla_mid.c @@ -180,7 +180,7 @@ qla24xx_disable_vp(scsi_qla_host_t *vha) atomic_set(&vha->loop_state, LOOP_DOWN); atomic_set(&vha->loop_down_timer, LOOP_DOWN_TIME); list_for_each_entry(fcport, &vha->vp_fcports, list) - fcport->logout_on_delete = 0; + fcport->logout_on_delete = 1; if (!vha->hw->flags.edif_enabled) qla2x00_wait_for_sess_deletion(vha); diff --git a/drivers/scsi/qla2xxx/qla_mr.c b/drivers/scsi/qla2xxx/qla_mr.c index 083f94e43f..82a7e21ddc 100644 --- a/drivers/scsi/qla2xxx/qla_mr.c +++ b/drivers/scsi/qla2xxx/qla_mr.c @@ -1909,10 +1909,8 @@ qlafx00_fx_disc(scsi_qla_host_t *vha, fc_port_t *fcport, uint16_t fx_type) if (fx_type == FXDISC_GET_CONFIG_INFO) { struct config_info_data *pinfo = (struct config_info_data *) fdisc->u.fxiocb.rsp_addr; - strscpy(vha->hw->model_number, pinfo->model_num, - ARRAY_SIZE(vha->hw->model_number)); - strscpy(vha->hw->model_desc, pinfo->model_description, - ARRAY_SIZE(vha->hw->model_desc)); + memtostr(vha->hw->model_number, pinfo->model_num); + memtostr(vha->hw->model_desc, pinfo->model_description); memcpy(&vha->hw->mr.symbolic_name, pinfo->symbolic_name, sizeof(vha->hw->mr.symbolic_name)); memcpy(&vha->hw->mr.serial_num, pinfo->serial_num, diff --git a/drivers/scsi/qla2xxx/qla_nvme.c b/drivers/scsi/qla2xxx/qla_nvme.c index a8ddf356e6..8f4cc136a9 100644 --- a/drivers/scsi/qla2xxx/qla_nvme.c +++ b/drivers/scsi/qla2xxx/qla_nvme.c @@ -49,7 +49,10 @@ int qla_nvme_register_remote(struct scsi_qla_host *vha, struct fc_port *fcport) return 0; } - if (!vha->nvme_local_port && qla_nvme_register_hba(vha)) + if (qla_nvme_register_hba(vha)) + return 0; + + if (!vha->nvme_local_port) return 0; if (!(fcport->nvme_prli_service_param & diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index 1e2f52210f..bc3b2aea3f 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c @@ -1875,14 +1875,9 @@ __qla2x00_abort_all_cmds(struct qla_qpair *qp, int res) for (cnt = 1; cnt < req->num_outstanding_cmds; cnt++) { sp = req->outstanding_cmds[cnt]; if (sp) { - /* - * perform lockless completion during driver unload - */ if (qla2x00_chip_is_down(vha)) { req->outstanding_cmds[cnt] = NULL; - spin_unlock_irqrestore(qp->qp_lock_ptr, flags); sp->done(sp, res); - spin_lock_irqsave(qp->qp_lock_ptr, flags); continue; } @@ -1957,9 +1952,6 @@ qla2xxx_slave_configure(struct scsi_device *sdev) scsi_qla_host_t *vha = shost_priv(sdev->host); struct req_que *req = vha->req; - if (IS_T10_PI_CAPABLE(vha->hw)) - blk_queue_update_dma_alignment(sdev->request_queue, 0x7); - scsi_change_queue_depth(sdev, req->max_q_depth); return 0; } @@ -3575,6 +3567,9 @@ skip_dpc: QLA_SG_ALL : 128; } + if (IS_T10_PI_CAPABLE(base_vha->hw)) + host->dma_alignment = 0x7; + ret = scsi_add_host(host, &pdev->dev); if (ret) goto probe_failed; @@ -4689,7 +4684,7 @@ static void qla2x00_number_of_exch(scsi_qla_host_t *vha, u32 *ret_cnt, u16 max_cnt) { u32 temp; - struct init_cb_81xx *icb = (struct init_cb_81xx *)&vha->hw->init_cb; + struct init_cb_81xx *icb = (struct init_cb_81xx *)vha->hw->init_cb; *ret_cnt = FW_DEF_EXCHANGES_CNT; if (max_cnt > vha->hw->max_exchg) @@ -5563,15 +5558,11 @@ qla2x00_do_work(struct scsi_qla_host *vha) qla2x00_async_prlo_done(vha, e->u.logio.fcport, e->u.logio.data); break; - case QLA_EVT_GPNFT: - qla24xx_async_gpnft(vha, e->u.gpnft.fc4_type, - e->u.gpnft.sp); - break; - case QLA_EVT_GPNFT_DONE: - qla24xx_async_gpnft_done(vha, e->u.iosb.sp); + case QLA_EVT_SCAN_CMD: + qla_fab_async_scan(vha, e->u.iosb.sp); break; - case QLA_EVT_GNNFT_DONE: - qla24xx_async_gnnft_done(vha, e->u.iosb.sp); + case QLA_EVT_SCAN_FINISH: + qla_fab_scan_finish(vha, e->u.iosb.sp); break; case QLA_EVT_GFPNID: qla24xx_async_gfpnid(vha, e->u.fcport.fcport); @@ -8156,9 +8147,6 @@ MODULE_DEVICE_TABLE(pci, qla2xxx_pci_tbl); static struct pci_driver qla2xxx_pci_driver = { .name = QLA2XXX_DRIVER_NAME, - .driver = { - .owner = THIS_MODULE, - }, .id_table = qla2xxx_pci_tbl, .probe = qla2x00_probe_one, .remove = qla2x00_remove_one, diff --git a/drivers/scsi/qla2xxx/qla_sup.c b/drivers/scsi/qla2xxx/qla_sup.c index c092a6b1ce..6d16546e17 100644 --- a/drivers/scsi/qla2xxx/qla_sup.c +++ b/drivers/scsi/qla2xxx/qla_sup.c @@ -555,6 +555,7 @@ qla2xxx_find_flt_start(scsi_qla_host_t *vha, uint32_t *start) struct qla_flt_location *fltl = (void *)req->ring; uint32_t *dcode = (uint32_t *)req->ring; uint8_t *buf = (void *)req->ring, *bcode, last_image; + int rc; /* * FLT-location structure resides after the last PCI region. @@ -584,14 +585,24 @@ qla2xxx_find_flt_start(scsi_qla_host_t *vha, uint32_t *start) pcihdr = 0; do { /* Verify PCI expansion ROM header. */ - qla24xx_read_flash_data(vha, dcode, pcihdr >> 2, 0x20); + rc = qla24xx_read_flash_data(vha, dcode, pcihdr >> 2, 0x20); + if (rc) { + ql_log(ql_log_info, vha, 0x016d, + "Unable to read PCI Expansion Rom Header (%x).\n", rc); + return QLA_FUNCTION_FAILED; + } bcode = buf + (pcihdr % 4); if (bcode[0x0] != 0x55 || bcode[0x1] != 0xaa) goto end; /* Locate PCI data structure. */ pcids = pcihdr + ((bcode[0x19] << 8) | bcode[0x18]); - qla24xx_read_flash_data(vha, dcode, pcids >> 2, 0x20); + rc = qla24xx_read_flash_data(vha, dcode, pcids >> 2, 0x20); + if (rc) { + ql_log(ql_log_info, vha, 0x0179, + "Unable to read PCI Data Structure (%x).\n", rc); + return QLA_FUNCTION_FAILED; + } bcode = buf + (pcihdr % 4); /* Validate signature of PCI data structure. */ @@ -606,7 +617,12 @@ qla2xxx_find_flt_start(scsi_qla_host_t *vha, uint32_t *start) } while (!last_image); /* Now verify FLT-location structure. */ - qla24xx_read_flash_data(vha, dcode, pcihdr >> 2, sizeof(*fltl) >> 2); + rc = qla24xx_read_flash_data(vha, dcode, pcihdr >> 2, sizeof(*fltl) >> 2); + if (rc) { + ql_log(ql_log_info, vha, 0x017a, + "Unable to read FLT (%x).\n", rc); + return QLA_FUNCTION_FAILED; + } if (memcmp(fltl->sig, "QFLT", 4)) goto end; @@ -2605,13 +2621,18 @@ qla24xx_read_optrom_data(struct scsi_qla_host *vha, void *buf, uint32_t offset, uint32_t length) { struct qla_hw_data *ha = vha->hw; + int rc; /* Suspend HBA. */ scsi_block_requests(vha->host); set_bit(MBX_UPDATE_FLASH_ACTIVE, &ha->mbx_cmd_flags); /* Go with read. */ - qla24xx_read_flash_data(vha, buf, offset >> 2, length >> 2); + rc = qla24xx_read_flash_data(vha, buf, offset >> 2, length >> 2); + if (rc) { + ql_log(ql_log_info, vha, 0x01a0, + "Unable to perform optrom read(%x).\n", rc); + } /* Resume HBA. */ clear_bit(MBX_UPDATE_FLASH_ACTIVE, &ha->mbx_cmd_flags); @@ -3412,7 +3433,7 @@ qla24xx_get_flash_version(scsi_qla_host_t *vha, void *mbuf) struct active_regions active_regions = { }; if (IS_P3P_TYPE(ha)) - return ret; + return QLA_SUCCESS; if (!mbuf) return QLA_FUNCTION_FAILED; @@ -3432,20 +3453,31 @@ qla24xx_get_flash_version(scsi_qla_host_t *vha, void *mbuf) do { /* Verify PCI expansion ROM header. */ - qla24xx_read_flash_data(vha, dcode, pcihdr >> 2, 0x20); + ret = qla24xx_read_flash_data(vha, dcode, pcihdr >> 2, 0x20); + if (ret) { + ql_log(ql_log_info, vha, 0x017d, + "Unable to read PCI EXP Rom Header(%x).\n", ret); + return QLA_FUNCTION_FAILED; + } + bcode = mbuf + (pcihdr % 4); if (memcmp(bcode, "\x55\xaa", 2)) { /* No signature */ ql_log(ql_log_fatal, vha, 0x0059, "No matching ROM signature.\n"); - ret = QLA_FUNCTION_FAILED; - break; + return QLA_FUNCTION_FAILED; } /* Locate PCI data structure. */ pcids = pcihdr + ((bcode[0x19] << 8) | bcode[0x18]); - qla24xx_read_flash_data(vha, dcode, pcids >> 2, 0x20); + ret = qla24xx_read_flash_data(vha, dcode, pcids >> 2, 0x20); + if (ret) { + ql_log(ql_log_info, vha, 0x018e, + "Unable to read PCI Data Structure (%x).\n", ret); + return QLA_FUNCTION_FAILED; + } + bcode = mbuf + (pcihdr % 4); /* Validate signature of PCI data structure. */ @@ -3454,8 +3486,7 @@ qla24xx_get_flash_version(scsi_qla_host_t *vha, void *mbuf) ql_log(ql_log_fatal, vha, 0x005a, "PCI data struct not found pcir_adr=%x.\n", pcids); ql_dump_buffer(ql_dbg_init, vha, 0x0059, dcode, 32); - ret = QLA_FUNCTION_FAILED; - break; + return QLA_FUNCTION_FAILED; } /* Read version */ @@ -3507,20 +3538,26 @@ qla24xx_get_flash_version(scsi_qla_host_t *vha, void *mbuf) faddr = ha->flt_region_fw_sec; } - qla24xx_read_flash_data(vha, dcode, faddr, 8); - if (qla24xx_risc_firmware_invalid(dcode)) { - ql_log(ql_log_warn, vha, 0x005f, - "Unrecognized fw revision at %x.\n", - ha->flt_region_fw * 4); - ql_dump_buffer(ql_dbg_init, vha, 0x005f, dcode, 32); + ret = qla24xx_read_flash_data(vha, dcode, faddr, 8); + if (ret) { + ql_log(ql_log_info, vha, 0x019e, + "Unable to read FW version (%x).\n", ret); + return ret; } else { - for (i = 0; i < 4; i++) - ha->fw_revision[i] = + if (qla24xx_risc_firmware_invalid(dcode)) { + ql_log(ql_log_warn, vha, 0x005f, + "Unrecognized fw revision at %x.\n", + ha->flt_region_fw * 4); + ql_dump_buffer(ql_dbg_init, vha, 0x005f, dcode, 32); + } else { + for (i = 0; i < 4; i++) + ha->fw_revision[i] = be32_to_cpu((__force __be32)dcode[4+i]); - ql_dbg(ql_dbg_init, vha, 0x0060, - "Firmware revision (flash) %u.%u.%u (%x).\n", - ha->fw_revision[0], ha->fw_revision[1], - ha->fw_revision[2], ha->fw_revision[3]); + ql_dbg(ql_dbg_init, vha, 0x0060, + "Firmware revision (flash) %u.%u.%u (%x).\n", + ha->fw_revision[0], ha->fw_revision[1], + ha->fw_revision[2], ha->fw_revision[3]); + } } /* Check for golden firmware and get version if available */ @@ -3531,18 +3568,23 @@ qla24xx_get_flash_version(scsi_qla_host_t *vha, void *mbuf) memset(ha->gold_fw_version, 0, sizeof(ha->gold_fw_version)); faddr = ha->flt_region_gold_fw; - qla24xx_read_flash_data(vha, dcode, ha->flt_region_gold_fw, 8); - if (qla24xx_risc_firmware_invalid(dcode)) { - ql_log(ql_log_warn, vha, 0x0056, - "Unrecognized golden fw at %#x.\n", faddr); - ql_dump_buffer(ql_dbg_init, vha, 0x0056, dcode, 32); + ret = qla24xx_read_flash_data(vha, dcode, ha->flt_region_gold_fw, 8); + if (ret) { + ql_log(ql_log_info, vha, 0x019f, + "Unable to read Gold FW version (%x).\n", ret); return ret; - } - - for (i = 0; i < 4; i++) - ha->gold_fw_version[i] = - be32_to_cpu((__force __be32)dcode[4+i]); + } else { + if (qla24xx_risc_firmware_invalid(dcode)) { + ql_log(ql_log_warn, vha, 0x0056, + "Unrecognized golden fw at %#x.\n", faddr); + ql_dump_buffer(ql_dbg_init, vha, 0x0056, dcode, 32); + return QLA_FUNCTION_FAILED; + } + for (i = 0; i < 4; i++) + ha->gold_fw_version[i] = + be32_to_cpu((__force __be32)dcode[4+i]); + } return ret; } diff --git a/drivers/scsi/qla4xxx/ql4_mbx.c b/drivers/scsi/qla4xxx/ql4_mbx.c index 249f1d7021..75125d2021 100644 --- a/drivers/scsi/qla4xxx/ql4_mbx.c +++ b/drivers/scsi/qla4xxx/ql4_mbx.c @@ -1641,6 +1641,7 @@ int qla4xxx_set_chap(struct scsi_qla_host *ha, char *username, char *password, struct ql4_chap_table *chap_table; uint32_t chap_size = 0; dma_addr_t chap_dma; + ssize_t secret_len; chap_table = dma_pool_zalloc(ha->chap_dma_pool, GFP_KERNEL, &chap_dma); if (chap_table == NULL) { @@ -1652,9 +1653,13 @@ int qla4xxx_set_chap(struct scsi_qla_host *ha, char *username, char *password, chap_table->flags |= BIT_6; /* peer */ else chap_table->flags |= BIT_7; /* local */ - chap_table->secret_len = strlen(password); - strncpy(chap_table->secret, password, MAX_CHAP_SECRET_LEN - 1); - strncpy(chap_table->name, username, MAX_CHAP_NAME_LEN - 1); + + secret_len = strscpy(chap_table->secret, password, + sizeof(chap_table->secret)); + if (secret_len < MIN_CHAP_SECRET_LEN) + goto cleanup_chap_table; + chap_table->secret_len = (uint8_t)secret_len; + strscpy(chap_table->name, username, sizeof(chap_table->name)); chap_table->cookie = cpu_to_le16(CHAP_VALID_COOKIE); if (is_qla40XX(ha)) { @@ -1679,6 +1684,8 @@ int qla4xxx_set_chap(struct scsi_qla_host *ha, char *username, char *password, memcpy((struct ql4_chap_table *)ha->chap_list + idx, chap_table, sizeof(struct ql4_chap_table)); } + +cleanup_chap_table: dma_pool_free(ha->chap_dma_pool, chap_table, chap_dma); if (rval != QLA_SUCCESS) ret = -EINVAL; @@ -2281,8 +2288,8 @@ int qla4_8xxx_set_param(struct scsi_qla_host *ha, int param) mbox_cmd[0] = MBOX_CMD_SET_PARAM; if (param == SET_DRVR_VERSION) { mbox_cmd[1] = SET_DRVR_VERSION; - strncpy((char *)&mbox_cmd[2], QLA4XXX_DRIVER_VERSION, - MAX_DRVR_VER_LEN - 1); + strscpy((char *)&mbox_cmd[2], QLA4XXX_DRIVER_VERSION, + MAX_DRVR_VER_LEN); } else { ql4_printk(KERN_ERR, ha, "%s: invalid parameter 0x%x\n", __func__, param); diff --git a/drivers/scsi/qla4xxx/ql4_os.c b/drivers/scsi/qla4xxx/ql4_os.c index 675332e49a..17cccd1476 100644 --- a/drivers/scsi/qla4xxx/ql4_os.c +++ b/drivers/scsi/qla4xxx/ql4_os.c @@ -799,10 +799,10 @@ static int qla4xxx_get_chap_list(struct Scsi_Host *shost, uint16_t chap_tbl_idx, chap_rec->chap_tbl_idx = i; strscpy(chap_rec->username, chap_table->name, - ISCSI_CHAP_AUTH_NAME_MAX_LEN); - strscpy(chap_rec->password, chap_table->secret, - QL4_CHAP_MAX_SECRET_LEN); - chap_rec->password_length = chap_table->secret_len; + sizeof(chap_rec->username)); + chap_rec->password_length = strscpy(chap_rec->password, + chap_table->secret, + sizeof(chap_rec->password)); if (chap_table->flags & BIT_7) /* local */ chap_rec->chap_type = CHAP_TYPE_OUT; @@ -6291,8 +6291,8 @@ static void qla4xxx_get_param_ddb(struct ddb_entry *ddb_entry, tddb->tpgt = sess->tpgt; tddb->port = conn->persistent_port; - strscpy(tddb->iscsi_name, sess->targetname, ISCSI_NAME_SIZE); - strscpy(tddb->ip_addr, conn->persistent_address, DDB_IPADDR_LEN); + strscpy(tddb->iscsi_name, sess->targetname, sizeof(tddb->iscsi_name)); + strscpy(tddb->ip_addr, conn->persistent_address, sizeof(tddb->ip_addr)); } static void qla4xxx_convert_param_ddb(struct dev_db_entry *fw_ddb_entry, @@ -7792,7 +7792,7 @@ static int qla4xxx_sysfs_ddb_logout(struct iscsi_bus_flash_session *fnode_sess, } strscpy(flash_tddb->iscsi_name, fnode_sess->targetname, - ISCSI_NAME_SIZE); + sizeof(flash_tddb->iscsi_name)); if (!strncmp(fnode_sess->portal_type, PORTAL_TYPE_IPV6, 4)) sprintf(flash_tddb->ip_addr, "%pI6", fnode_conn->ipaddress); diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c index acf0592d63..91f022fb8d 100644 --- a/drivers/scsi/scsi_debug.c +++ b/drivers/scsi/scsi_debug.c @@ -926,6 +926,7 @@ static const int device_qfull_result = static const int condition_met_result = SAM_STAT_CONDITION_MET; static struct dentry *sdebug_debugfs_root; +static ASYNC_DOMAIN_EXCLUSIVE(sdebug_async_domain); static void sdebug_err_free(struct rcu_head *head) { @@ -1148,6 +1149,8 @@ static int sdebug_target_alloc(struct scsi_target *starget) if (!targetip) return -ENOMEM; + async_synchronize_full_domain(&sdebug_async_domain); + targetip->debugfs_entry = debugfs_create_dir(dev_name(&starget->dev), sdebug_debugfs_root); @@ -1174,7 +1177,8 @@ static void sdebug_target_destroy(struct scsi_target *starget) targetip = (struct sdebug_target_info *)starget->hostdata; if (targetip) { starget->hostdata = NULL; - async_schedule(sdebug_tartget_cleanup_async, targetip); + async_schedule_domain(sdebug_tartget_cleanup_async, targetip, + &sdebug_async_domain); } } diff --git a/drivers/scsi/scsi_debugfs.c b/drivers/scsi/scsi_debugfs.c index f795848b31..eb52e39f37 100644 --- a/drivers/scsi/scsi_debugfs.c +++ b/drivers/scsi/scsi_debugfs.c @@ -1,5 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 #include +#include #include #include #include @@ -32,38 +33,43 @@ static int scsi_flags_show(struct seq_file *m, const unsigned long flags, return 0; } -void scsi_show_rq(struct seq_file *m, struct request *rq) +static const char *scsi_cmd_list_info(struct scsi_cmnd *cmd) { - struct scsi_cmnd *cmd = blk_mq_rq_to_pdu(rq), *cmd2; struct Scsi_Host *shost = cmd->device->host; + struct scsi_cmnd *cmd2; + + guard(spinlock_irq)(shost->host_lock); + + list_for_each_entry(cmd2, &shost->eh_abort_list, eh_entry) + if (cmd == cmd2) + return "on eh_abort_list"; + + list_for_each_entry(cmd2, &shost->eh_cmd_q, eh_entry) + if (cmd == cmd2) + return "on eh_cmd_q"; + + return NULL; +} + +void scsi_show_rq(struct seq_file *m, struct request *rq) +{ + struct scsi_cmnd *cmd = blk_mq_rq_to_pdu(rq); int alloc_ms = jiffies_to_msecs(jiffies - cmd->jiffies_at_alloc); int timeout_ms = jiffies_to_msecs(rq->timeout); - const char *list_info = NULL; char buf[80] = "(?)"; - spin_lock_irq(shost->host_lock); - list_for_each_entry(cmd2, &shost->eh_abort_list, eh_entry) { - if (cmd == cmd2) { - list_info = "on eh_abort_list"; - goto unlock; - } - } - list_for_each_entry(cmd2, &shost->eh_cmd_q, eh_entry) { - if (cmd == cmd2) { - list_info = "on eh_cmd_q"; - goto unlock; - } - } -unlock: - spin_unlock_irq(shost->host_lock); + if (cmd->flags & SCMD_INITIALIZED) { + const char *list_info = scsi_cmd_list_info(cmd); - __scsi_format_command(buf, sizeof(buf), cmd->cmnd, cmd->cmd_len); - seq_printf(m, ", .cmd=%s, .retries=%d, .allowed=%d, .result = %#x, %s%s.flags=", - buf, cmd->retries, cmd->allowed, cmd->result, - list_info ? : "", list_info ? ", " : ""); + __scsi_format_command(buf, sizeof(buf), cmd->cmnd, cmd->cmd_len); + seq_printf(m, ", .cmd=%s, .retries=%d, .allowed=%d, .result = %#x%s%s", + buf, cmd->retries, cmd->allowed, cmd->result, + list_info ? ", " : "", list_info ? : ""); + seq_printf(m, ", .timeout=%d.%03d, allocated %d.%03d s ago", + timeout_ms / 1000, timeout_ms % 1000, + alloc_ms / 1000, alloc_ms % 1000); + } + seq_printf(m, ", .flags="); scsi_flags_show(m, cmd->flags, scsi_cmd_flags, ARRAY_SIZE(scsi_cmd_flags)); - seq_printf(m, ", .timeout=%d.%03d, allocated %d.%03d s ago", - timeout_ms / 1000, timeout_ms % 1000, - alloc_ms / 1000, alloc_ms % 1000); } diff --git a/drivers/scsi/scsi_devinfo.c b/drivers/scsi/scsi_devinfo.c index ba7237e838..a7071e7138 100644 --- a/drivers/scsi/scsi_devinfo.c +++ b/drivers/scsi/scsi_devinfo.c @@ -293,14 +293,16 @@ static void scsi_strcpy_devinfo(char *name, char *to, size_t to_length, size_t from_length; from_length = strlen(from); - /* This zero-pads the destination */ - strncpy(to, from, to_length); - if (from_length < to_length && !compatible) { - /* - * space pad the string if it is short. - */ - memset(&to[from_length], ' ', to_length - from_length); - } + + /* + * null pad and null terminate if compatible + * otherwise space pad + */ + if (compatible) + strscpy_pad(to, from, to_length); + else + memcpy_and_pad(to, to_length, from, from_length, ' '); + if (from_length > to_length) printk(KERN_WARNING "%s: %s string '%s' is too long\n", __func__, name, from); diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index 5b3230ef51..ec39acc986 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c @@ -32,7 +32,7 @@ #include #include #include -#include /* __scsi_init_queue() */ +#include /* scsi_init_limits() */ #include #include @@ -1869,7 +1869,6 @@ out_put_budget: case BLK_STS_OK: break; case BLK_STS_RESOURCE: - case BLK_STS_ZONE_RESOURCE: if (scsi_device_blocked(sdev)) ret = BLK_STS_DEV_RESOURCE; break; @@ -1964,42 +1963,36 @@ static void scsi_map_queues(struct blk_mq_tag_set *set) blk_mq_map_queues(&set->map[HCTX_TYPE_DEFAULT]); } -void __scsi_init_queue(struct Scsi_Host *shost, struct request_queue *q) +void scsi_init_limits(struct Scsi_Host *shost, struct queue_limits *lim) { struct device *dev = shost->dma_dev; - /* - * this limit is imposed by hardware restrictions - */ - blk_queue_max_segments(q, min_t(unsigned short, shost->sg_tablesize, - SG_MAX_SEGMENTS)); + memset(lim, 0, sizeof(*lim)); + lim->max_segments = + min_t(unsigned short, shost->sg_tablesize, SG_MAX_SEGMENTS); if (scsi_host_prot_dma(shost)) { shost->sg_prot_tablesize = min_not_zero(shost->sg_prot_tablesize, (unsigned short)SCSI_MAX_PROT_SG_SEGMENTS); BUG_ON(shost->sg_prot_tablesize < shost->sg_tablesize); - blk_queue_max_integrity_segments(q, shost->sg_prot_tablesize); + lim->max_integrity_segments = shost->sg_prot_tablesize; } - blk_queue_max_hw_sectors(q, shost->max_sectors); - blk_queue_segment_boundary(q, shost->dma_boundary); - dma_set_seg_boundary(dev, shost->dma_boundary); + lim->max_hw_sectors = shost->max_sectors; + lim->seg_boundary_mask = shost->dma_boundary; + lim->max_segment_size = shost->max_segment_size; + lim->virt_boundary_mask = shost->virt_boundary_mask; + lim->dma_alignment = max_t(unsigned int, + shost->dma_alignment, dma_get_cache_alignment() - 1); - blk_queue_max_segment_size(q, shost->max_segment_size); - blk_queue_virt_boundary(q, shost->virt_boundary_mask); - dma_set_max_seg_size(dev, queue_max_segment_size(q)); + if (shost->no_highmem) + lim->bounce = BLK_BOUNCE_HIGH; - /* - * Set a reasonable default alignment: The larger of 32-byte (dword), - * which is a common minimum for HBAs, and the minimum DMA alignment, - * which is set by the platform. - * - * Devices that require a bigger alignment can increase it later. - */ - blk_queue_dma_alignment(q, max(4, dma_get_cache_alignment()) - 1); + dma_set_seg_boundary(dev, shost->dma_boundary); + dma_set_max_seg_size(dev, shost->max_segment_size); } -EXPORT_SYMBOL_GPL(__scsi_init_queue); +EXPORT_SYMBOL_GPL(scsi_init_limits); static const struct blk_mq_ops scsi_mq_ops_no_commit = { .get_budget = scsi_mq_get_budget, diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c index ffd7e7e729..8300fc28cb 100644 --- a/drivers/scsi/scsi_scan.c +++ b/drivers/scsi/scsi_scan.c @@ -227,7 +227,7 @@ static int scsi_realloc_sdev_budget_map(struct scsi_device *sdev, /* * realloc if new shift is calculated, which is caused by setting - * up one new default queue depth after calling ->slave_configure + * up one new default queue depth after calling ->device_configure */ if (!need_alloc && new_shift != sdev->budget_map.shift) need_alloc = need_free = true; @@ -283,6 +283,7 @@ static struct scsi_device *scsi_alloc_sdev(struct scsi_target *starget, struct request_queue *q; int display_failure_msg = 1, ret; struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); + struct queue_limits lim; sdev = kzalloc(sizeof(*sdev) + shost->transportt->device_size, GFP_KERNEL); @@ -332,7 +333,8 @@ static struct scsi_device *scsi_alloc_sdev(struct scsi_target *starget, sdev->sg_reserved_size = INT_MAX; - q = blk_mq_alloc_queue(&sdev->host->tag_set, NULL, NULL); + scsi_init_limits(shost, &lim); + q = blk_mq_alloc_queue(&sdev->host->tag_set, &lim, NULL); if (IS_ERR(q)) { /* release fn is set up in scsi_sysfs_device_initialise, so * have to free and put manually here */ @@ -343,7 +345,6 @@ static struct scsi_device *scsi_alloc_sdev(struct scsi_target *starget, kref_get(&sdev->host->tagset_refcnt); sdev->request_queue = q; q->queuedata = sdev; - __scsi_init_queue(sdev->host, q); depth = sdev->host->cmd_per_lun ?: 1; @@ -873,6 +874,8 @@ static int scsi_probe_lun(struct scsi_device *sdev, unsigned char *inq_result, static int scsi_add_lun(struct scsi_device *sdev, unsigned char *inq_result, blist_flags_t *bflags, int async) { + const struct scsi_host_template *hostt = sdev->host->hostt; + struct queue_limits lim; int ret; /* @@ -1003,19 +1006,6 @@ static int scsi_add_lun(struct scsi_device *sdev, unsigned char *inq_result, if (*bflags & BLIST_SELECT_NO_ATN) sdev->select_no_atn = 1; - /* - * Maximum 512 sector transfer length - * broken RA4x00 Compaq Disk Array - */ - if (*bflags & BLIST_MAX_512) - blk_queue_max_hw_sectors(sdev->request_queue, 512); - /* - * Max 1024 sector transfer length for targets that report incorrect - * max/optimal lengths and relied on the old block layer safe default - */ - else if (*bflags & BLIST_MAX_1024) - blk_queue_max_hw_sectors(sdev->request_queue, 1024); - /* * Some devices may not want to have a start command automatically * issued when a device is added. @@ -1076,28 +1066,46 @@ static int scsi_add_lun(struct scsi_device *sdev, unsigned char *inq_result, transport_configure_device(&sdev->sdev_gendev); - if (sdev->host->hostt->slave_configure) { - ret = sdev->host->hostt->slave_configure(sdev); - if (ret) { - /* - * if LLDD reports slave not present, don't clutter - * console with alloc failure messages - */ - if (ret != -ENXIO) { - sdev_printk(KERN_ERR, sdev, - "failed to configure device\n"); - } - return SCSI_SCAN_NO_RESPONSE; - } + /* + * No need to freeze the queue as it isn't reachable to anyone else yet. + */ + lim = queue_limits_start_update(sdev->request_queue); + if (*bflags & BLIST_MAX_512) + lim.max_hw_sectors = 512; + else if (*bflags & BLIST_MAX_1024) + lim.max_hw_sectors = 1024; + if (hostt->device_configure) + ret = hostt->device_configure(sdev, &lim); + else if (hostt->slave_configure) + ret = hostt->slave_configure(sdev); + if (ret) { + queue_limits_cancel_update(sdev->request_queue); /* - * The queue_depth is often changed in ->slave_configure. - * Set up budget map again since memory consumption of - * the map depends on actual queue depth. + * If the LLDD reports device not present, don't clutter the + * console with failure messages. */ - scsi_realloc_sdev_budget_map(sdev, sdev->queue_depth); + if (ret != -ENXIO) + sdev_printk(KERN_ERR, sdev, + "failed to configure device\n"); + return SCSI_SCAN_NO_RESPONSE; } + ret = queue_limits_commit_update(sdev->request_queue, &lim); + if (ret) { + sdev_printk(KERN_ERR, sdev, "failed to apply queue limits.\n"); + return SCSI_SCAN_NO_RESPONSE; + } + + /* + * The queue_depth is often changed in ->device_configure. + * + * Set up budget map again since memory consumption of the map depends + * on actual queue depth. + */ + if (hostt->device_configure || hostt->slave_configure) + scsi_realloc_sdev_budget_map(sdev, sdev->queue_depth); + if (sdev->scsi_level >= SCSI_3) scsi_attach_vpd(sdev); diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c index 775df00021..b5aae4e8ae 100644 --- a/drivers/scsi/scsi_sysfs.c +++ b/drivers/scsi/scsi_sysfs.c @@ -1609,13 +1609,14 @@ restart: } EXPORT_SYMBOL(scsi_remove_target); -int scsi_register_driver(struct device_driver *drv) +int __scsi_register_driver(struct device_driver *drv, struct module *owner) { drv->bus = &scsi_bus_type; + drv->owner = owner; return driver_register(drv); } -EXPORT_SYMBOL(scsi_register_driver); +EXPORT_SYMBOL(__scsi_register_driver); int scsi_register_interface(struct class_interface *intf) { diff --git a/drivers/scsi/scsi_transport_fc.c b/drivers/scsi/scsi_transport_fc.c index b04075f194..7d088b8da0 100644 --- a/drivers/scsi/scsi_transport_fc.c +++ b/drivers/scsi/scsi_transport_fc.c @@ -4276,6 +4276,7 @@ fc_bsg_hostadd(struct Scsi_Host *shost, struct fc_host_attrs *fc_host) { struct device *dev = &shost->shost_gendev; struct fc_internal *i = to_fc_internal(shost->transportt); + struct queue_limits lim; struct request_queue *q; char bsg_name[20]; @@ -4286,16 +4287,16 @@ fc_bsg_hostadd(struct Scsi_Host *shost, struct fc_host_attrs *fc_host) snprintf(bsg_name, sizeof(bsg_name), "fc_host%d", shost->host_no); - - q = bsg_setup_queue(dev, bsg_name, fc_bsg_dispatch, fc_bsg_job_timeout, - i->f->dd_bsg_size); + scsi_init_limits(shost, &lim); + lim.max_segments = min_not_zero(lim.max_segments, i->f->max_bsg_segments); + q = bsg_setup_queue(dev, bsg_name, &lim, fc_bsg_dispatch, + fc_bsg_job_timeout, i->f->dd_bsg_size); if (IS_ERR(q)) { dev_err(dev, "fc_host%d: bsg interface failed to initialize - setup queue\n", shost->host_no); return PTR_ERR(q); } - __scsi_init_queue(shost, q); blk_queue_rq_timeout(q, FC_DEFAULT_BSG_TIMEOUT); fc_host->rqst_q = q; return 0; @@ -4311,6 +4312,7 @@ fc_bsg_rportadd(struct Scsi_Host *shost, struct fc_rport *rport) { struct device *dev = &rport->dev; struct fc_internal *i = to_fc_internal(shost->transportt); + struct queue_limits lim; struct request_queue *q; rport->rqst_q = NULL; @@ -4318,13 +4320,14 @@ fc_bsg_rportadd(struct Scsi_Host *shost, struct fc_rport *rport) if (!i->f->bsg_request) return -ENOTSUPP; - q = bsg_setup_queue(dev, dev_name(dev), fc_bsg_dispatch_prep, + scsi_init_limits(shost, &lim); + lim.max_segments = min_not_zero(lim.max_segments, i->f->max_bsg_segments); + q = bsg_setup_queue(dev, dev_name(dev), &lim, fc_bsg_dispatch_prep, fc_bsg_job_timeout, i->f->dd_bsg_size); if (IS_ERR(q)) { dev_err(dev, "failed to setup bsg queue\n"); return PTR_ERR(q); } - __scsi_init_queue(shost, q); blk_queue_rq_timeout(q, BLK_DEFAULT_SG_TIMEOUT); rport->rqst_q = q; return 0; diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c index af3ac63467..93e1978ad5 100644 --- a/drivers/scsi/scsi_transport_iscsi.c +++ b/drivers/scsi/scsi_transport_iscsi.c @@ -1535,6 +1535,7 @@ iscsi_bsg_host_add(struct Scsi_Host *shost, struct iscsi_cls_host *ihost) { struct device *dev = &shost->shost_gendev; struct iscsi_internal *i = to_iscsi_internal(shost->transportt); + struct queue_limits lim; struct request_queue *q; char bsg_name[20]; @@ -1542,13 +1543,14 @@ iscsi_bsg_host_add(struct Scsi_Host *shost, struct iscsi_cls_host *ihost) return -ENOTSUPP; snprintf(bsg_name, sizeof(bsg_name), "iscsi_host%d", shost->host_no); - q = bsg_setup_queue(dev, bsg_name, iscsi_bsg_host_dispatch, NULL, 0); + scsi_init_limits(shost, &lim); + q = bsg_setup_queue(dev, bsg_name, &lim, iscsi_bsg_host_dispatch, NULL, + 0); if (IS_ERR(q)) { shost_printk(KERN_ERR, shost, "bsg interface failed to " "initialize - no request queue\n"); return PTR_ERR(q); } - __scsi_init_queue(shost, q); ihost->bsg_q = q; return 0; @@ -1603,7 +1605,6 @@ static DEFINE_MUTEX(rx_queue_mutex); static LIST_HEAD(sesslist); static DEFINE_SPINLOCK(sesslock); static LIST_HEAD(connlist); -static LIST_HEAD(connlist_err); static DEFINE_SPINLOCK(connlock); static uint32_t iscsi_conn_get_sid(struct iscsi_cls_conn *conn) diff --git a/drivers/scsi/scsi_transport_sas.c b/drivers/scsi/scsi_transport_sas.c index 7fdd2b61fe..4e33f1661e 100644 --- a/drivers/scsi/scsi_transport_sas.c +++ b/drivers/scsi/scsi_transport_sas.c @@ -197,7 +197,7 @@ static int sas_bsg_initialize(struct Scsi_Host *shost, struct sas_rphy *rphy) } if (rphy) { - q = bsg_setup_queue(&rphy->dev, dev_name(&rphy->dev), + q = bsg_setup_queue(&rphy->dev, dev_name(&rphy->dev), NULL, sas_smp_dispatch, NULL, 0); if (IS_ERR(q)) return PTR_ERR(q); @@ -206,7 +206,7 @@ static int sas_bsg_initialize(struct Scsi_Host *shost, struct sas_rphy *rphy) char name[20]; snprintf(name, sizeof(name), "sas_host%d", shost->host_no); - q = bsg_setup_queue(&shost->shost_gendev, name, + q = bsg_setup_queue(&shost->shost_gendev, name, NULL, sas_smp_dispatch, NULL, 0); if (IS_ERR(q)) return PTR_ERR(q); diff --git a/drivers/scsi/scsicam.c b/drivers/scsi/scsicam.c index e2c7d8ef20..dd69342bbe 100644 --- a/drivers/scsi/scsicam.c +++ b/drivers/scsi/scsicam.c @@ -32,7 +32,7 @@ */ unsigned char *scsi_bios_ptable(struct block_device *dev) { - struct address_space *mapping = bdev_whole(dev)->bd_inode->i_mapping; + struct address_space *mapping = bdev_whole(dev)->bd_mapping; unsigned char *res = NULL; struct folio *folio; diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index a4638ea925..1b7561abe0 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -1261,12 +1261,6 @@ static blk_status_t sd_setup_read_write_cmnd(struct scsi_cmnd *cmd) } } - if (req_op(rq) == REQ_OP_ZONE_APPEND) { - ret = sd_zbc_prepare_zone_append(cmd, &lba, nr_blocks); - if (ret) - goto fail; - } - fua = rq->cmd_flags & REQ_FUA ? 0x8 : 0; dix = scsi_prot_sg_count(cmd); dif = scsi_host_dif_capable(cmd->device->host, sdkp->protection_type); @@ -1349,7 +1343,6 @@ static blk_status_t sd_init_command(struct scsi_cmnd *cmd) return sd_setup_flush_cmnd(cmd); case REQ_OP_READ: case REQ_OP_WRITE: - case REQ_OP_ZONE_APPEND: return sd_setup_read_write_cmnd(cmd); case REQ_OP_ZONE_RESET: return sd_zbc_setup_zone_mgmt_cmnd(cmd, ZO_RESET_WRITE_POINTER, @@ -3994,7 +3987,6 @@ static void scsi_disk_release(struct device *dev) struct scsi_disk *sdkp = to_scsi_disk(dev); ida_free(&sd_index_ida, sdkp->index); - sd_zbc_free_zone_info(sdkp); put_device(&sdkp->device->sdev_gendev); free_opal_dev(sdkp->opal_dev); @@ -4127,8 +4119,6 @@ static int sd_resume(struct device *dev) { struct scsi_disk *sdkp = dev_get_drvdata(dev); - sd_printk(KERN_NOTICE, sdkp, "Starting disk\n"); - if (opal_unlock_from_suspend(sdkp->opal_dev)) { sd_printk(KERN_NOTICE, sdkp, "OPAL unlock failed\n"); return -EIO; @@ -4145,12 +4135,13 @@ static int sd_resume_common(struct device *dev, bool runtime) if (!sdkp) /* E.g.: runtime resume at the start of sd_probe() */ return 0; + sd_printk(KERN_NOTICE, sdkp, "Starting disk\n"); + if (!sd_do_start_stop(sdkp->device, runtime)) { sdkp->suspended = false; return 0; } - sd_printk(KERN_NOTICE, sdkp, "Starting disk\n"); ret = sd_start_stop_device(sdkp, 1); if (!ret) { sd_resume(dev); @@ -4214,7 +4205,6 @@ static const struct dev_pm_ops sd_pm_ops = { static struct scsi_driver sd_template = { .gendrv = { .name = "sd", - .owner = THIS_MODULE, .probe = sd_probe, .probe_type = PROBE_PREFER_ASYNCHRONOUS, .remove = sd_remove, diff --git a/drivers/scsi/sd.h b/drivers/scsi/sd.h index 5c4285a582..49dd600bfa 100644 --- a/drivers/scsi/sd.h +++ b/drivers/scsi/sd.h @@ -104,12 +104,6 @@ struct scsi_disk { * between zone starting LBAs is constant. */ u32 zone_starting_lba_gran; - u32 *zones_wp_offset; - spinlock_t zones_wp_offset_lock; - u32 *rev_wp_offset; - struct mutex rev_mutex; - struct work_struct zone_wp_offset_work; - char *zone_wp_update_buf; #endif atomic_t openers; sector_t capacity; /* size in logical blocks */ @@ -245,7 +239,6 @@ static inline int sd_is_zoned(struct scsi_disk *sdkp) #ifdef CONFIG_BLK_DEV_ZONED -void sd_zbc_free_zone_info(struct scsi_disk *sdkp); int sd_zbc_read_zones(struct scsi_disk *sdkp, u8 buf[SD_BUF_SIZE]); int sd_zbc_revalidate_zones(struct scsi_disk *sdkp); blk_status_t sd_zbc_setup_zone_mgmt_cmnd(struct scsi_cmnd *cmd, @@ -255,13 +248,8 @@ unsigned int sd_zbc_complete(struct scsi_cmnd *cmd, unsigned int good_bytes, int sd_zbc_report_zones(struct gendisk *disk, sector_t sector, unsigned int nr_zones, report_zones_cb cb, void *data); -blk_status_t sd_zbc_prepare_zone_append(struct scsi_cmnd *cmd, sector_t *lba, - unsigned int nr_blocks); - #else /* CONFIG_BLK_DEV_ZONED */ -static inline void sd_zbc_free_zone_info(struct scsi_disk *sdkp) {} - static inline int sd_zbc_read_zones(struct scsi_disk *sdkp, u8 buf[SD_BUF_SIZE]) { return 0; @@ -285,13 +273,6 @@ static inline unsigned int sd_zbc_complete(struct scsi_cmnd *cmd, return good_bytes; } -static inline blk_status_t sd_zbc_prepare_zone_append(struct scsi_cmnd *cmd, - sector_t *lba, - unsigned int nr_blocks) -{ - return BLK_STS_TARGET; -} - #define sd_zbc_report_zones NULL #endif /* CONFIG_BLK_DEV_ZONED */ diff --git a/drivers/scsi/sd_zbc.c b/drivers/scsi/sd_zbc.c index 26af5ab7d7..806036e48a 100644 --- a/drivers/scsi/sd_zbc.c +++ b/drivers/scsi/sd_zbc.c @@ -23,36 +23,6 @@ #define CREATE_TRACE_POINTS #include "sd_trace.h" -/** - * sd_zbc_get_zone_wp_offset - Get zone write pointer offset. - * @zone: Zone for which to return the write pointer offset. - * - * Return: offset of the write pointer from the start of the zone. - */ -static unsigned int sd_zbc_get_zone_wp_offset(struct blk_zone *zone) -{ - if (zone->type == ZBC_ZONE_TYPE_CONV) - return 0; - - switch (zone->cond) { - case BLK_ZONE_COND_IMP_OPEN: - case BLK_ZONE_COND_EXP_OPEN: - case BLK_ZONE_COND_CLOSED: - return zone->wp - zone->start; - case BLK_ZONE_COND_FULL: - return zone->len; - case BLK_ZONE_COND_EMPTY: - case BLK_ZONE_COND_OFFLINE: - case BLK_ZONE_COND_READONLY: - default: - /* - * Offline and read-only zones do not have a valid - * write pointer. Use 0 as for an empty zone. - */ - return 0; - } -} - /* Whether or not a SCSI zone descriptor describes a gap zone. */ static bool sd_zbc_is_gap_zone(const u8 buf[64]) { @@ -121,9 +91,6 @@ static int sd_zbc_parse_report(struct scsi_disk *sdkp, const u8 buf[64], if (ret) return ret; - if (sdkp->rev_wp_offset) - sdkp->rev_wp_offset[idx] = sd_zbc_get_zone_wp_offset(&zone); - return 0; } @@ -347,123 +314,6 @@ static blk_status_t sd_zbc_cmnd_checks(struct scsi_cmnd *cmd) return BLK_STS_OK; } -#define SD_ZBC_INVALID_WP_OFST (~0u) -#define SD_ZBC_UPDATING_WP_OFST (SD_ZBC_INVALID_WP_OFST - 1) - -static int sd_zbc_update_wp_offset_cb(struct blk_zone *zone, unsigned int idx, - void *data) -{ - struct scsi_disk *sdkp = data; - - lockdep_assert_held(&sdkp->zones_wp_offset_lock); - - sdkp->zones_wp_offset[idx] = sd_zbc_get_zone_wp_offset(zone); - - return 0; -} - -/* - * An attempt to append a zone triggered an invalid write pointer error. - * Reread the write pointer of the zone(s) in which the append failed. - */ -static void sd_zbc_update_wp_offset_workfn(struct work_struct *work) -{ - struct scsi_disk *sdkp; - unsigned long flags; - sector_t zno; - int ret; - - sdkp = container_of(work, struct scsi_disk, zone_wp_offset_work); - - spin_lock_irqsave(&sdkp->zones_wp_offset_lock, flags); - for (zno = 0; zno < sdkp->zone_info.nr_zones; zno++) { - if (sdkp->zones_wp_offset[zno] != SD_ZBC_UPDATING_WP_OFST) - continue; - - spin_unlock_irqrestore(&sdkp->zones_wp_offset_lock, flags); - ret = sd_zbc_do_report_zones(sdkp, sdkp->zone_wp_update_buf, - SD_BUF_SIZE, - zno * sdkp->zone_info.zone_blocks, true); - spin_lock_irqsave(&sdkp->zones_wp_offset_lock, flags); - if (!ret) - sd_zbc_parse_report(sdkp, sdkp->zone_wp_update_buf + 64, - zno, sd_zbc_update_wp_offset_cb, - sdkp); - } - spin_unlock_irqrestore(&sdkp->zones_wp_offset_lock, flags); - - scsi_device_put(sdkp->device); -} - -/** - * sd_zbc_prepare_zone_append() - Prepare an emulated ZONE_APPEND command. - * @cmd: the command to setup - * @lba: the LBA to patch - * @nr_blocks: the number of LBAs to be written - * - * Called from sd_setup_read_write_cmnd() for REQ_OP_ZONE_APPEND. - * @sd_zbc_prepare_zone_append() handles the necessary zone wrote locking and - * patching of the lba for an emulated ZONE_APPEND command. - * - * In case the cached write pointer offset is %SD_ZBC_INVALID_WP_OFST it will - * schedule a REPORT ZONES command and return BLK_STS_IOERR. - */ -blk_status_t sd_zbc_prepare_zone_append(struct scsi_cmnd *cmd, sector_t *lba, - unsigned int nr_blocks) -{ - struct request *rq = scsi_cmd_to_rq(cmd); - struct scsi_disk *sdkp = scsi_disk(rq->q->disk); - unsigned int wp_offset, zno = blk_rq_zone_no(rq); - unsigned long flags; - blk_status_t ret; - - ret = sd_zbc_cmnd_checks(cmd); - if (ret != BLK_STS_OK) - return ret; - - if (!blk_rq_zone_is_seq(rq)) - return BLK_STS_IOERR; - - /* Unlock of the write lock will happen in sd_zbc_complete() */ - if (!blk_req_zone_write_trylock(rq)) - return BLK_STS_ZONE_RESOURCE; - - spin_lock_irqsave(&sdkp->zones_wp_offset_lock, flags); - wp_offset = sdkp->zones_wp_offset[zno]; - switch (wp_offset) { - case SD_ZBC_INVALID_WP_OFST: - /* - * We are about to schedule work to update a zone write pointer - * offset, which will cause the zone append command to be - * requeued. So make sure that the scsi device does not go away - * while the work is being processed. - */ - if (scsi_device_get(sdkp->device)) { - ret = BLK_STS_IOERR; - break; - } - sdkp->zones_wp_offset[zno] = SD_ZBC_UPDATING_WP_OFST; - schedule_work(&sdkp->zone_wp_offset_work); - fallthrough; - case SD_ZBC_UPDATING_WP_OFST: - ret = BLK_STS_DEV_RESOURCE; - break; - default: - wp_offset = sectors_to_logical(sdkp->device, wp_offset); - if (wp_offset + nr_blocks > sdkp->zone_info.zone_blocks) { - ret = BLK_STS_IOERR; - break; - } - - trace_scsi_prepare_zone_append(cmd, *lba, wp_offset); - *lba += wp_offset; - } - spin_unlock_irqrestore(&sdkp->zones_wp_offset_lock, flags); - if (ret) - blk_req_zone_write_unlock(rq); - return ret; -} - /** * sd_zbc_setup_zone_mgmt_cmnd - Prepare a zone ZBC_OUT command. The operations * can be RESET WRITE POINTER, OPEN, CLOSE or FINISH. @@ -504,96 +354,6 @@ blk_status_t sd_zbc_setup_zone_mgmt_cmnd(struct scsi_cmnd *cmd, return BLK_STS_OK; } -static bool sd_zbc_need_zone_wp_update(struct request *rq) -{ - switch (req_op(rq)) { - case REQ_OP_ZONE_APPEND: - case REQ_OP_ZONE_FINISH: - case REQ_OP_ZONE_RESET: - case REQ_OP_ZONE_RESET_ALL: - return true; - case REQ_OP_WRITE: - case REQ_OP_WRITE_ZEROES: - return blk_rq_zone_is_seq(rq); - default: - return false; - } -} - -/** - * sd_zbc_zone_wp_update - Update cached zone write pointer upon cmd completion - * @cmd: Completed command - * @good_bytes: Command reply bytes - * - * Called from sd_zbc_complete() to handle the update of the cached zone write - * pointer value in case an update is needed. - */ -static unsigned int sd_zbc_zone_wp_update(struct scsi_cmnd *cmd, - unsigned int good_bytes) -{ - int result = cmd->result; - struct request *rq = scsi_cmd_to_rq(cmd); - struct scsi_disk *sdkp = scsi_disk(rq->q->disk); - unsigned int zno = blk_rq_zone_no(rq); - enum req_op op = req_op(rq); - unsigned long flags; - - /* - * If we got an error for a command that needs updating the write - * pointer offset cache, we must mark the zone wp offset entry as - * invalid to force an update from disk the next time a zone append - * command is issued. - */ - spin_lock_irqsave(&sdkp->zones_wp_offset_lock, flags); - - if (result && op != REQ_OP_ZONE_RESET_ALL) { - if (op == REQ_OP_ZONE_APPEND) { - /* Force complete completion (no retry) */ - good_bytes = 0; - scsi_set_resid(cmd, blk_rq_bytes(rq)); - } - - /* - * Force an update of the zone write pointer offset on - * the next zone append access. - */ - if (sdkp->zones_wp_offset[zno] != SD_ZBC_UPDATING_WP_OFST) - sdkp->zones_wp_offset[zno] = SD_ZBC_INVALID_WP_OFST; - goto unlock_wp_offset; - } - - switch (op) { - case REQ_OP_ZONE_APPEND: - trace_scsi_zone_wp_update(cmd, rq->__sector, - sdkp->zones_wp_offset[zno], good_bytes); - rq->__sector += sdkp->zones_wp_offset[zno]; - fallthrough; - case REQ_OP_WRITE_ZEROES: - case REQ_OP_WRITE: - if (sdkp->zones_wp_offset[zno] < sd_zbc_zone_sectors(sdkp)) - sdkp->zones_wp_offset[zno] += - good_bytes >> SECTOR_SHIFT; - break; - case REQ_OP_ZONE_RESET: - sdkp->zones_wp_offset[zno] = 0; - break; - case REQ_OP_ZONE_FINISH: - sdkp->zones_wp_offset[zno] = sd_zbc_zone_sectors(sdkp); - break; - case REQ_OP_ZONE_RESET_ALL: - memset(sdkp->zones_wp_offset, 0, - sdkp->zone_info.nr_zones * sizeof(unsigned int)); - break; - default: - break; - } - -unlock_wp_offset: - spin_unlock_irqrestore(&sdkp->zones_wp_offset_lock, flags); - - return good_bytes; -} - /** * sd_zbc_complete - ZBC command post processing. * @cmd: Completed command @@ -619,11 +379,7 @@ unsigned int sd_zbc_complete(struct scsi_cmnd *cmd, unsigned int good_bytes, * so be quiet about the error. */ rq->rq_flags |= RQF_QUIET; - } else if (sd_zbc_need_zone_wp_update(rq)) - good_bytes = sd_zbc_zone_wp_update(cmd, good_bytes); - - if (req_op(rq) == REQ_OP_ZONE_APPEND) - blk_req_zone_write_unlock(rq); + } return good_bytes; } @@ -780,46 +536,6 @@ static void sd_zbc_print_zones(struct scsi_disk *sdkp) sdkp->zone_info.zone_blocks); } -static int sd_zbc_init_disk(struct scsi_disk *sdkp) -{ - sdkp->zones_wp_offset = NULL; - spin_lock_init(&sdkp->zones_wp_offset_lock); - sdkp->rev_wp_offset = NULL; - mutex_init(&sdkp->rev_mutex); - INIT_WORK(&sdkp->zone_wp_offset_work, sd_zbc_update_wp_offset_workfn); - sdkp->zone_wp_update_buf = kzalloc(SD_BUF_SIZE, GFP_KERNEL); - if (!sdkp->zone_wp_update_buf) - return -ENOMEM; - - return 0; -} - -void sd_zbc_free_zone_info(struct scsi_disk *sdkp) -{ - if (!sdkp->zone_wp_update_buf) - return; - - /* Serialize against revalidate zones */ - mutex_lock(&sdkp->rev_mutex); - - kvfree(sdkp->zones_wp_offset); - sdkp->zones_wp_offset = NULL; - kfree(sdkp->zone_wp_update_buf); - sdkp->zone_wp_update_buf = NULL; - - sdkp->early_zone_info = (struct zoned_disk_info){ }; - sdkp->zone_info = (struct zoned_disk_info){ }; - - mutex_unlock(&sdkp->rev_mutex); -} - -static void sd_zbc_revalidate_zones_cb(struct gendisk *disk) -{ - struct scsi_disk *sdkp = scsi_disk(disk); - - swap(sdkp->zones_wp_offset, sdkp->rev_wp_offset); -} - /* * Call blk_revalidate_disk_zones() if any of the zoned disk properties have * changed that make it necessary to call that function. Called by @@ -831,18 +547,8 @@ int sd_zbc_revalidate_zones(struct scsi_disk *sdkp) struct request_queue *q = disk->queue; u32 zone_blocks = sdkp->early_zone_info.zone_blocks; unsigned int nr_zones = sdkp->early_zone_info.nr_zones; - int ret = 0; unsigned int flags; - - /* - * For all zoned disks, initialize zone append emulation data if not - * already done. - */ - if (sd_is_zoned(sdkp) && !sdkp->zone_wp_update_buf) { - ret = sd_zbc_init_disk(sdkp); - if (ret) - return ret; - } + int ret; /* * There is nothing to do for regular disks, including host-aware disks @@ -851,50 +557,32 @@ int sd_zbc_revalidate_zones(struct scsi_disk *sdkp) if (!blk_queue_is_zoned(q)) return 0; - /* - * Make sure revalidate zones are serialized to ensure exclusive - * updates of the scsi disk data. - */ - mutex_lock(&sdkp->rev_mutex); - if (sdkp->zone_info.zone_blocks == zone_blocks && sdkp->zone_info.nr_zones == nr_zones && disk->nr_zones == nr_zones) - goto unlock; + return 0; - flags = memalloc_noio_save(); sdkp->zone_info.zone_blocks = zone_blocks; sdkp->zone_info.nr_zones = nr_zones; - sdkp->rev_wp_offset = kvcalloc(nr_zones, sizeof(u32), GFP_KERNEL); - if (!sdkp->rev_wp_offset) { - ret = -ENOMEM; - memalloc_noio_restore(flags); - goto unlock; - } blk_queue_chunk_sectors(q, logical_to_sectors(sdkp->device, zone_blocks)); - blk_queue_max_zone_append_sectors(q, - q->limits.max_segments << PAGE_SECTORS_SHIFT); - ret = blk_revalidate_disk_zones(disk, sd_zbc_revalidate_zones_cb); + /* Enable block layer zone append emulation */ + blk_queue_max_zone_append_sectors(q, 0); + flags = memalloc_noio_save(); + ret = blk_revalidate_disk_zones(disk); memalloc_noio_restore(flags); - kvfree(sdkp->rev_wp_offset); - sdkp->rev_wp_offset = NULL; - if (ret) { sdkp->zone_info = (struct zoned_disk_info){ }; sdkp->capacity = 0; - goto unlock; + return ret; } sd_zbc_print_zones(sdkp); -unlock: - mutex_unlock(&sdkp->rev_mutex); - - return ret; + return 0; } /** @@ -917,10 +605,8 @@ int sd_zbc_read_zones(struct scsi_disk *sdkp, u8 buf[SD_BUF_SIZE]) if (!sd_is_zoned(sdkp)) { /* * Device managed or normal SCSI disk, no special handling - * required. Nevertheless, free the disk zone information in - * case the device type changed. + * required. */ - sd_zbc_free_zone_info(sdkp); return 0; } @@ -941,7 +627,6 @@ int sd_zbc_read_zones(struct scsi_disk *sdkp, u8 buf[SD_BUF_SIZE]) /* The drive satisfies the kernel restrictions: set it up */ blk_queue_flag_set(QUEUE_FLAG_ZONE_RESETALL, q); - blk_queue_required_elevator_features(q, ELEVATOR_F_ZBD_SEQ_WRITE); if (sdkp->zones_max_open == U32_MAX) disk_set_max_open_zones(disk, 0); else diff --git a/drivers/scsi/ses.c b/drivers/scsi/ses.c index 0f2c87cc95..e22c7f5e65 100644 --- a/drivers/scsi/ses.c +++ b/drivers/scsi/ses.c @@ -908,7 +908,6 @@ static struct class_interface ses_interface = { static struct scsi_driver ses_template = { .gendrv = { .name = "ses", - .owner = THIS_MODULE, .probe = ses_probe, .remove = ses_remove, }, diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c index 385180c98b..24c7cb285d 100644 --- a/drivers/scsi/smartpqi/smartpqi_init.c +++ b/drivers/scsi/smartpqi/smartpqi_init.c @@ -1041,9 +1041,8 @@ static int pqi_write_driver_version_to_host_wellness( buffer->driver_version_tag[1] = 'V'; put_unaligned_le16(sizeof(buffer->driver_version), &buffer->driver_version_length); - strncpy(buffer->driver_version, "Linux " DRIVER_VERSION, - sizeof(buffer->driver_version) - 1); - buffer->driver_version[sizeof(buffer->driver_version) - 1] = '\0'; + strscpy(buffer->driver_version, "Linux " DRIVER_VERSION, + sizeof(buffer->driver_version)); buffer->dont_write_tag[0] = 'D'; buffer->dont_write_tag[1] = 'W'; buffer->end_tag[0] = 'Z'; @@ -6892,12 +6891,6 @@ static ssize_t pqi_firmware_version_show(struct device *dev, return scnprintf(buffer, PAGE_SIZE, "%s\n", ctrl_info->firmware_version); } -static ssize_t pqi_driver_version_show(struct device *dev, - struct device_attribute *attr, char *buffer) -{ - return scnprintf(buffer, PAGE_SIZE, "%s\n", DRIVER_VERSION BUILD_TIMESTAMP); -} - static ssize_t pqi_serial_number_show(struct device *dev, struct device_attribute *attr, char *buffer) { @@ -7066,7 +7059,8 @@ static ssize_t pqi_host_enable_r6_writes_store(struct device *dev, return count; } -static DEVICE_ATTR(driver_version, 0444, pqi_driver_version_show, NULL); +static DEVICE_STRING_ATTR_RO(driver_version, 0444, + DRIVER_VERSION BUILD_TIMESTAMP); static DEVICE_ATTR(firmware_version, 0444, pqi_firmware_version_show, NULL); static DEVICE_ATTR(model, 0444, pqi_model_show, NULL); static DEVICE_ATTR(serial_number, 0444, pqi_serial_number_show, NULL); @@ -7083,7 +7077,7 @@ static DEVICE_ATTR(enable_r6_writes, 0644, pqi_host_enable_r6_writes_show, pqi_host_enable_r6_writes_store); static struct attribute *pqi_shost_attrs[] = { - &dev_attr_driver_version.attr, + &dev_attr_driver_version.attr.attr, &dev_attr_firmware_version.attr, &dev_attr_model.attr, &dev_attr_serial_number.attr, diff --git a/drivers/scsi/snic/snic_attrs.c b/drivers/scsi/snic/snic_attrs.c index 3ddbdbc3de..48bf82d042 100644 --- a/drivers/scsi/snic/snic_attrs.c +++ b/drivers/scsi/snic/snic_attrs.c @@ -13,7 +13,7 @@ snic_show_sym_name(struct device *dev, { struct snic *snic = shost_priv(class_to_shost(dev)); - return snprintf(buf, PAGE_SIZE, "%s\n", snic->name); + return sysfs_emit(buf, "%s\n", snic->name); } static ssize_t @@ -23,8 +23,7 @@ snic_show_state(struct device *dev, { struct snic *snic = shost_priv(class_to_shost(dev)); - return snprintf(buf, PAGE_SIZE, "%s\n", - snic_state_str[snic_get_state(snic)]); + return sysfs_emit(buf, "%s\n", snic_state_str[snic_get_state(snic)]); } static ssize_t @@ -32,7 +31,7 @@ snic_show_drv_version(struct device *dev, struct device_attribute *attr, char *buf) { - return snprintf(buf, PAGE_SIZE, "%s\n", SNIC_DRV_VERSION); + return sysfs_emit(buf, "%s\n", SNIC_DRV_VERSION); } static ssize_t @@ -45,8 +44,8 @@ snic_show_link_state(struct device *dev, if (snic->config.xpt_type == SNIC_DAS) snic->link_status = svnic_dev_link_status(snic->vdev); - return snprintf(buf, PAGE_SIZE, "%s\n", - (snic->link_status) ? "Link Up" : "Link Down"); + return sysfs_emit(buf, "%s\n", + (snic->link_status) ? "Link Up" : "Link Down"); } static DEVICE_ATTR(snic_sym_name, S_IRUGO, snic_show_sym_name, NULL); diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c index 268b3a4089..7ab000942b 100644 --- a/drivers/scsi/sr.c +++ b/drivers/scsi/sr.c @@ -95,7 +95,6 @@ static const struct dev_pm_ops sr_pm_ops = { static struct scsi_driver sr_template = { .gendrv = { .name = "sr", - .owner = THIS_MODULE, .probe = sr_probe, .remove = sr_remove, .pm = &sr_pm_ops, diff --git a/drivers/scsi/sr_ioctl.c b/drivers/scsi/sr_ioctl.c index a0d2556a27..089653018d 100644 --- a/drivers/scsi/sr_ioctl.c +++ b/drivers/scsi/sr_ioctl.c @@ -431,7 +431,7 @@ int sr_select_speed(struct cdrom_device_info *cdi, unsigned long speed) struct packet_command cgc; /* avoid exceeding the max speed or overflowing integer bounds */ - speed = clamp(0, speed, 0xffff / 177); + speed = clamp(speed, 0, 0xffff / 177); if (speed == 0) speed = 0xffff; /* set to max */ diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c index 5a9bcf8e07..0d8ce1a921 100644 --- a/drivers/scsi/st.c +++ b/drivers/scsi/st.c @@ -206,7 +206,6 @@ static int st_remove(struct device *); static struct scsi_driver st_template = { .gendrv = { .name = "st", - .owner = THIS_MODULE, .probe = st_probe, .remove = st_remove, .groups = st_drv_groups, diff --git a/drivers/scsi/virtio_scsi.c b/drivers/scsi/virtio_scsi.c index 617eb892f4..89ca269457 100644 --- a/drivers/scsi/virtio_scsi.c +++ b/drivers/scsi/virtio_scsi.c @@ -1052,7 +1052,6 @@ static struct virtio_driver virtio_scsi_driver = { .feature_table = features, .feature_table_size = ARRAY_SIZE(features), .driver.name = KBUILD_MODNAME, - .driver.owner = THIS_MODULE, .id_table = id_table, .probe = virtscsi_probe, #ifdef CONFIG_PM_SLEEP diff --git a/drivers/scsi/vmw_pvscsi.c b/drivers/scsi/vmw_pvscsi.c index f88ecdb93a..c4fea07726 100644 --- a/drivers/scsi/vmw_pvscsi.c +++ b/drivers/scsi/vmw_pvscsi.c @@ -1346,7 +1346,7 @@ exit: static int pvscsi_probe(struct pci_dev *pdev, const struct pci_device_id *id) { - unsigned int irq_flag = PCI_IRQ_MSIX | PCI_IRQ_MSI | PCI_IRQ_LEGACY; + unsigned int irq_flag = PCI_IRQ_ALL_TYPES; struct pvscsi_adapter *adapter; struct pvscsi_adapter adapter_temp; struct Scsi_Host *host = NULL; diff --git a/drivers/scsi/wd33c93.c b/drivers/scsi/wd33c93.c index e4fafc77bd..a44b60c900 100644 --- a/drivers/scsi/wd33c93.c +++ b/drivers/scsi/wd33c93.c @@ -1721,9 +1721,7 @@ wd33c93_setup(char *str) p1 = setup_buffer; *p1 = '\0'; if (str) - strncpy(p1, str, SETUP_BUFFER_SIZE - strlen(setup_buffer)); - setup_buffer[SETUP_BUFFER_SIZE - 1] = '\0'; - p1 = setup_buffer; + strscpy(p1, str, SETUP_BUFFER_SIZE); i = 0; while (*p1 && (i < MAX_SETUP_ARGS)) { p2 = strchr(p1, ','); -- cgit v1.2.3