From: Thierry Reding Date: Thu, 24 Oct 2013 12:59:32 +0000 (+0200) Subject: Merge remote-tracking branch 'scsi/for-next' X-Git-Tag: next-20131024~27 X-Git-Url: https://git.karo-electronics.de/?p=karo-tx-linux.git;a=commitdiff_plain;h=56d34ec4f2b4a4c47b48c67f74e4fcbe0e662af4;hp=-c Merge remote-tracking branch 'scsi/for-next' --- 56d34ec4f2b4a4c47b48c67f74e4fcbe0e662af4 diff --combined MAINTAINERS index 40cf7cd5fa0e,407d5f3febfd..13a631bb788f --- a/MAINTAINERS +++ b/MAINTAINERS @@@ -237,11 -237,11 +237,11 @@@ F: drivers/platform/x86/acer-wmi. ACPI M: Len Brown -M: Rafael J. Wysocki +M: Rafael J. Wysocki L: linux-acpi@vger.kernel.org -W: http://www.lesswatts.org/projects/acpi/ -Q: http://patchwork.kernel.org/project/linux-acpi/list/ -T: git git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux +W: https://01.org/linux-acpi +Q: https://patchwork.kernel.org/project/linux-acpi/list/ +T: git git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm S: Supported F: drivers/acpi/ F: drivers/pnp/pnpacpi/ @@@ -253,38 -253,24 +253,38 @@@ F: drivers/pci/*acpi F: drivers/pci/*/*acpi* F: drivers/pci/*/*/*acpi* +ACPI COMPONENT ARCHITECTURE (ACPICA) +M: Robert Moore +M: Lv Zheng +M: Rafael J. Wysocki +L: linux-acpi@vger.kernel.org +L: devel@acpica.org +W: https://acpica.org/ +W: https://github.com/acpica/acpica/ +Q: https://patchwork.kernel.org/project/linux-acpi/list/ +T: git git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm +S: Supported +F: drivers/acpi/acpica/ +F: include/acpi/ + ACPI FAN DRIVER M: Zhang Rui L: linux-acpi@vger.kernel.org -W: http://www.lesswatts.org/projects/acpi/ +W: https://01.org/linux-acpi S: Supported F: drivers/acpi/fan.c ACPI THERMAL DRIVER M: Zhang Rui L: linux-acpi@vger.kernel.org -W: http://www.lesswatts.org/projects/acpi/ +W: https://01.org/linux-acpi S: Supported F: drivers/acpi/*thermal* ACPI VIDEO DRIVER M: Zhang Rui L: linux-acpi@vger.kernel.org -W: http://www.lesswatts.org/projects/acpi/ +W: https://01.org/linux-acpi S: Supported F: drivers/acpi/video.c @@@ -1416,7 -1402,7 +1416,7 @@@ M: Wolfram Sang @@@ -1672,9 -1658,9 +1672,9 @@@ F: drivers/video/backlight F: include/linux/backlight.h BATMAN ADVANCED -M: Marek Lindner -M: Simon Wunderlich -M: Antonio Quartulli +M: Marek Lindner +M: Simon Wunderlich +M: Antonio Quartulli L: b.a.t.m.a.n@lists.open-mesh.org W: http://www.open-mesh.org/ S: Maintained @@@ -1805,7 -1791,6 +1805,7 @@@ F: include/net/bluetooth BONDING DRIVER M: Jay Vosburgh +M: Veaceslav Falico M: Andy Gospodarek L: netdev@vger.kernel.org W: http://sourceforge.net/projects/bonding/ @@@ -1872,7 -1857,7 +1872,7 @@@ S: Supporte F: drivers/net/wireless/brcm80211/ BROADCOM BNX2FC 10 GIGABIT FCOE DRIVER - M: Bhanu Prakash Gollapudi + M: Eddie Wai L: linux-scsi@vger.kernel.org S: Supported F: drivers/scsi/bnx2fc/ @@@ -2315,7 -2300,7 +2315,7 @@@ S: Maintaine F: drivers/net/ethernet/ti/cpmac.c CPU FREQUENCY DRIVERS -M: Rafael J. Wysocki +M: Rafael J. Wysocki M: Viresh Kumar L: cpufreq@vger.kernel.org L: linux-pm@vger.kernel.org @@@ -2346,7 -2331,7 +2346,7 @@@ S: Maintaine F: drivers/cpuidle/cpuidle-big_little.c CPUIDLE DRIVERS -M: Rafael J. Wysocki +M: Rafael J. Wysocki M: Daniel Lezcano L: linux-pm@vger.kernel.org S: Maintained @@@ -2733,8 -2718,6 +2733,8 @@@ T: git git://git.linaro.org/people/sumi DMA GENERIC OFFLOAD ENGINE SUBSYSTEM M: Vinod Koul M: Dan Williams +L: dmaengine@vger.kernel.org +Q: https://patchwork.kernel.org/project/linux-dmaengine/list/ S: Supported F: drivers/dma/ F: include/linux/dma* @@@ -2839,9 -2822,7 +2839,9 @@@ L: dri-devel@lists.freedesktop.or L: linux-tegra@vger.kernel.org T: git git://anongit.freedesktop.org/tegra/linux.git S: Maintained +F: drivers/gpu/drm/tegra/ F: drivers/gpu/host1x/ +F: include/linux/host1x.h F: include/uapi/drm/tegra_drm.h F: Documentation/devicetree/bindings/gpu/nvidia,tegra20-host1x.txt @@@ -3572,7 -3553,7 +3572,7 @@@ F: fs/freevxfs FREEZER M: Pavel Machek -M: "Rafael J. Wysocki" +M: "Rafael J. Wysocki" L: linux-pm@vger.kernel.org S: Supported F: Documentation/power/freezing-of-tasks.txt @@@ -3643,12 -3624,6 +3643,12 @@@ L: linux-scsi@vger.kernel.or S: Odd Fixes (e.g., new signatures) F: drivers/scsi/fdomain.* +GCOV BASED KERNEL PROFILING +M: Peter Oberparleiter +S: Maintained +F: kernel/gcov/ +F: Documentation/gcov.txt + GDT SCSI DISK ARRAY CONTROLLER DRIVER M: Achim Leubner L: linux-scsi@vger.kernel.org @@@ -3698,14 -3673,6 +3698,14 @@@ S: Maintaine F: include/asm-generic/ F: include/uapi/asm-generic/ +GENERIC PHY FRAMEWORK +M: Kishon Vijay Abraham I +L: linux-kernel@vger.kernel.org +T: git git://git.kernel.org/pub/scm/linux/kernel/git/kishon/linux-phy.git +S: Supported +F: drivers/phy/ +F: include/linux/phy/ + GENERIC UIO DRIVER FOR PCI DEVICES M: "Michael S. Tsirkin" L: kvm@vger.kernel.org @@@ -3922,7 -3889,7 +3922,7 @@@ F: drivers/video/hgafb. HIBERNATION (aka Software Suspend, aka swsusp) M: Pavel Machek -M: "Rafael J. Wysocki" +M: "Rafael J. Wysocki" L: linux-pm@vger.kernel.org S: Supported F: arch/x86/power/ @@@ -4247,7 -4214,7 +4247,7 @@@ S: Maintaine F: drivers/media/rc/iguanair.c IIO SUBSYSTEM AND DRIVERS -M: Jonathan Cameron +M: Jonathan Cameron L: linux-iio@vger.kernel.org S: Maintained F: drivers/iio/ @@@ -4372,7 -4339,7 +4372,7 @@@ F: drivers/video/i810 INTEL MENLOW THERMAL DRIVER M: Sujith Thomas L: platform-driver-x86@vger.kernel.org -W: http://www.lesswatts.org/projects/acpi/ +W: https://01.org/linux-acpi S: Supported F: drivers/platform/x86/intel_menlow.c @@@ -4384,10 -4351,7 +4384,10 @@@ F: arch/x86/kernel/microcode_intel. INTEL I/OAT DMA DRIVER M: Dan Williams -S: Maintained +M: Dave Jiang +L: dmaengine@vger.kernel.org +Q: https://patchwork.kernel.org/project/linux-dmaengine/list/ +S: Supported F: drivers/dma/ioat* INTEL IOMMU (VT-d) @@@ -4784,13 -4748,6 +4784,13 @@@ S: Maintaine F: Documentation/hwmon/k8temp F: drivers/hwmon/k8temp.c +KTAP +M: Jovi Zhangwei +W: http://www.ktap.org +L: ktap@freelists.org +S: Maintained +F: drivers/staging/ktap/ + KCONFIG M: Michal Marek L: linux-kbuild@vger.kernel.org @@@ -6415,12 -6372,6 +6415,12 @@@ S: Supporte F: Documentation/devicetree/bindings/pci/nvidia,tegra20-pcie.txt F: drivers/pci/host/pci-tegra.c +PCI DRIVER FOR SAMSUNG EXYNOS +M: Jingoo Han +L: linux-pci@vger.kernel.org +S: Maintained +F: drivers/pci/host/pci-exynos.c + PCMCIA SUBSYSTEM P: Linux PCMCIA Team L: linux-pcmcia@lists.infradead.org @@@ -6891,14 -6842,6 +6891,14 @@@ L: linux-hexagon@vger.kernel.or S: Supported F: arch/hexagon/ +QUALCOMM WCN36XX WIRELESS DRIVER +M: Eugene Krasnikov +L: wcn36xx@lists.infradead.org +W: http://wireless.kernel.org/en/users/Drivers/wcn36xx +T: git git://github.com/KrasnikovEugene/wcn36xx.git +S: Supported +F: drivers/net/wireless/ath/wcn36xx/ + QUICKCAM PARALLEL PORT WEBCAMS M: Hans Verkuil L: linux-media@vger.kernel.org @@@ -6986,7 -6929,7 +6986,7 @@@ M: "Paul E. McKenney" @@@ -7013,9 -6956,8 +7013,9 @@@ T: git git://git.kernel.org/pub/scm/lin F: Documentation/RCU/ X: Documentation/RCU/torture.txt F: include/linux/rcu* -F: kernel/rcu* -X: kernel/rcutorture.c +X: include/linux/srcu.h +F: kernel/rcu/ +X: kernel/rcu/torture.c REAL TIME CLOCK (RTC) SUBSYSTEM M: Alessandro Zummo @@@ -7340,8 -7282,6 +7340,8 @@@ S: Maintaine F: kernel/sched/ F: include/linux/sched.h F: include/uapi/linux/sched.h +F: kernel/wait.c +F: include/linux/wait.h SCORE ARCHITECTURE M: Chen Liqin @@@ -7476,10 -7416,9 +7476,10 @@@ SELINUX SECURITY MODUL M: Stephen Smalley M: James Morris M: Eric Paris +M: Paul Moore L: selinux@tycho.nsa.gov (subscribers-only, general discussion) W: http://selinuxproject.org -T: git git://git.infradead.org/users/eparis/selinux.git +T: git git://git.infradead.org/users/pcmoore/selinux S: Supported F: include/linux/selinux* F: security/selinux/ @@@ -7705,8 -7644,8 +7705,8 @@@ M: "Paul E. McKenney" @@@ -7877,13 -7816,6 +7877,13 @@@ F: Documentation/sound/alsa/soc F: sound/soc/ F: include/sound/soc* +SOUND - DMAENGINE HELPERS +M: Lars-Peter Clausen +S: Supported +F: include/sound/dmaengine_pcm.h +F: sound/core/pcm_dmaengine.c +F: sound/soc/soc-generic-dmaengine-pcm.c + SPARC + UltraSPARC (sparc/sparc64) M: "David S. Miller" L: sparclinux@vger.kernel.org @@@ -8041,7 -7973,7 +8041,7 @@@ S: Maintaine F: drivers/staging/media/go7007/ STAGING - INDUSTRIAL IO -M: Jonathan Cameron +M: Jonathan Cameron L: linux-iio@vger.kernel.org S: Odd Fixes F: drivers/staging/iio/ @@@ -8163,7 -8095,7 +8163,7 @@@ F: drivers/sh SUSPEND TO RAM M: Len Brown M: Pavel Machek -M: "Rafael J. Wysocki" +M: "Rafael J. Wysocki" L: linux-pm@vger.kernel.org S: Supported F: Documentation/power/ @@@ -8568,7 -8500,6 +8568,7 @@@ F: drivers/media/usb/tm6000 TPM DEVICE DRIVER M: Leonidas Da Silva Barbosa M: Ashley Lai +M: Peter Huewe M: Rajiv Andrade W: http://tpmdd.sourceforge.net M: Marcel Selhorst @@@ -8665,6 -8596,14 +8665,6 @@@ S: Maintaine F: arch/m68k/*/*_no.* F: arch/m68k/include/asm/*_no.* -UCLINUX FOR RENESAS H8/300 (H8300) -M: Yoshinori Sato -W: http://uclinux-h8.sourceforge.jp/ -S: Supported -F: arch/h8300/ -F: drivers/ide/ide-h8300.c -F: drivers/net/ethernet/8390/ne-h8300.c - UDF FILESYSTEM M: Jan Kara S: Maintained diff --combined drivers/scsi/fnic/fnic_main.c index 889b594fe8b0,be09b101b4a1..33e4ec2bfe73 --- a/drivers/scsi/fnic/fnic_main.c +++ b/drivers/scsi/fnic/fnic_main.c @@@ -556,6 -556,13 +556,13 @@@ static int fnic_probe(struct pci_dev *p host->transportt = fnic_fc_transport; + err = fnic_stats_debugfs_init(fnic); + if (err) { + shost_printk(KERN_ERR, fnic->lport->host, + "Failed to initialize debugfs for stats\n"); + fnic_stats_debugfs_remove(fnic); + } + /* Setup PCI resources */ pci_set_drvdata(pdev, fnic); @@@ -917,6 -924,7 +924,7 @@@ err_out_release_regions err_out_disable_device: pci_disable_device(pdev); err_out_free_hba: + fnic_stats_debugfs_remove(fnic); scsi_host_put(lp->host); err_out: return err; @@@ -969,6 -977,7 +977,7 @@@ static void fnic_remove(struct pci_dev fcoe_ctlr_destroy(&fnic->ctlr); fc_lport_destroy(lp); + fnic_stats_debugfs_remove(fnic); /* * This stops the fnic device, masks all interrupts. Completed @@@ -996,6 -1005,7 +1005,6 @@@ fnic_iounmap(fnic); pci_release_regions(pdev); pci_disable_device(pdev); - pci_set_drvdata(pdev, NULL); scsi_host_put(lp->host); } @@@ -1013,6 -1023,14 +1022,14 @@@ static int __init fnic_init_module(void printk(KERN_INFO PFX "%s, ver %s\n", DRV_DESCRIPTION, DRV_VERSION); + /* Create debugfs entries for fnic */ + err = fnic_debugfs_init(); + if (err < 0) { + printk(KERN_ERR PFX "Failed to create fnic directory " + "for tracing and stats logging\n"); + fnic_debugfs_terminate(); + } + /* Allocate memory for trace buffer */ err = fnic_trace_buf_init(); if (err < 0) { @@@ -1101,6 -1119,7 +1118,7 @@@ err_create_fnic_sgl_slab_max kmem_cache_destroy(fnic_sgl_cache[FNIC_SGL_CACHE_DFLT]); err_create_fnic_sgl_slab_dflt: fnic_trace_free(); + fnic_debugfs_terminate(); return err; } @@@ -1117,6 -1136,7 +1135,7 @@@ static void __exit fnic_cleanup_module( kmem_cache_destroy(fnic_io_req_cache); fc_release_transport(fnic_fc_transport); fnic_trace_free(); + fnic_debugfs_terminate(); } module_init(fnic_init_module); diff --combined drivers/scsi/hpsa.c index df72d4a58385,fb5a89815150..22f6432eb475 --- a/drivers/scsi/hpsa.c +++ b/drivers/scsi/hpsa.c @@@ -100,7 -100,6 +100,6 @@@ static const struct pci_device_id hpsa_ {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSF, 0x103C, 0x3354}, {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSF, 0x103C, 0x3355}, {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSF, 0x103C, 0x3356}, - {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSH, 0x103C, 0x1920}, {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSH, 0x103C, 0x1921}, {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSH, 0x103C, 0x1922}, {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSH, 0x103C, 0x1923}, @@@ -5018,6 -5017,7 +5017,6 @@@ static void hpsa_remove_one(struct pci_ kfree(h->hba_inquiry_data); pci_disable_device(pdev); pci_release_regions(pdev); - pci_set_drvdata(pdev, NULL); kfree(h); } diff --combined drivers/scsi/lpfc/lpfc_init.c index 3dfd38ce806c,ca6bf2af7ce8..68c94cc85c35 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c @@@ -4545,7 -4545,7 +4545,7 @@@ lpfc_enable_pci_dev(struct lpfc_hba *ph pci_save_state(pdev); /* PCIe EEH recovery on powerpc platforms needs fundamental reset */ - if (pci_find_capability(pdev, PCI_CAP_ID_EXP)) + if (pci_is_pcie(pdev)) pdev->needs_freset = 1; return 0; @@@ -4581,6 -4581,8 +4581,6 @@@ lpfc_disable_pci_dev(struct lpfc_hba *p /* Release PCI resource and disable PCI device */ pci_release_selected_regions(pdev, bars); pci_disable_device(pdev); - /* Null out PCI private reference to driver */ - pci_set_drvdata(pdev, NULL); return; } @@@ -9427,6 -9429,7 +9427,6 @@@ lpfc_pci_remove_one_s3(struct pci_dev * /* Disable interrupt */ lpfc_sli_disable_intr(phba); - pci_set_drvdata(pdev, NULL); scsi_host_put(shost); /* diff --combined drivers/scsi/megaraid/megaraid_sas_base.c index a6efc1e088ec,e62ff020c253..84cfe0f62b25 --- a/drivers/scsi/megaraid/megaraid_sas_base.c +++ b/drivers/scsi/megaraid/megaraid_sas_base.c @@@ -3199,11 -3199,11 +3199,11 @@@ megasas_get_pd_list(struct megasas_inst for (pd_index = 0; pd_index < le32_to_cpu(ci->count); pd_index++) { - instance->pd_list[pd_addr->deviceId].tid = + instance->pd_list[le16_to_cpu(pd_addr->deviceId)].tid = le16_to_cpu(pd_addr->deviceId); - instance->pd_list[pd_addr->deviceId].driveType = + instance->pd_list[le16_to_cpu(pd_addr->deviceId)].driveType = pd_addr->scsiDevType; - instance->pd_list[pd_addr->deviceId].driveState = + instance->pd_list[le16_to_cpu(pd_addr->deviceId)].driveState = MR_PD_STATE_SYSTEM; pd_addr++; } @@@ -3998,7 -3998,7 +3998,7 @@@ megasas_register_aen(struct megasas_ins * values */ if ((prev_aen.members.class <= curr_aen.members.class) && - !((le16_to_cpu(prev_aen.members.locale) & curr_aen.members.locale) ^ + !((prev_aen.members.locale & curr_aen.members.locale) ^ curr_aen.members.locale)) { /* * Previously issued event registration includes @@@ -4006,7 -4006,7 +4006,7 @@@ */ return 0; } else { - curr_aen.members.locale |= le16_to_cpu(prev_aen.members.locale); + curr_aen.members.locale |= prev_aen.members.locale; if (prev_aen.members.class < curr_aen.members.class) curr_aen.members.class = prev_aen.members.class; @@@ -4097,7 -4097,7 +4097,7 @@@ static int megasas_start_aen(struct meg class_locale.members.class = MR_EVT_CLASS_DEBUG; return megasas_register_aen(instance, - le32_to_cpu(eli.newest_seq_num) + 1, + eli.newest_seq_num + 1, class_locale.word); } @@@ -4449,6 -4449,7 +4449,6 @@@ retry_irq_register megasas_mgmt_info.instance[megasas_mgmt_info.max_index] = NULL; megasas_mgmt_info.max_index--; - pci_set_drvdata(pdev, NULL); instance->instancet->disable_intr(instance); if (instance->msix_vectors) for (i = 0 ; i < instance->msix_vectors; i++) @@@ -4804,6 -4805,8 +4804,6 @@@ static void megasas_detach_one(struct p } } - pci_set_drvdata(instance->pdev, NULL); - instance->instancet->disable_intr(instance); if (instance->msix_vectors) @@@ -4845,6 -4848,8 +4845,6 @@@ instance->evt_detail, instance->evt_detail_h); scsi_host_put(host); - pci_set_drvdata(pdev, NULL); - pci_disable_device(pdev); return; diff --combined drivers/scsi/pm8001/pm8001_init.c index 0dba7c7856ab,662bf13c42f0..34f5f5ffef05 --- a/drivers/scsi/pm8001/pm8001_init.c +++ b/drivers/scsi/pm8001/pm8001_init.c @@@ -54,6 -54,9 +54,9 @@@ static const struct pm8001_chip_info pm [chip_8009] = {1, 8, &pm8001_80xx_dispatch,}, [chip_8018] = {0, 16, &pm8001_80xx_dispatch,}, [chip_8019] = {1, 16, &pm8001_80xx_dispatch,}, + [chip_8074] = {0, 8, &pm8001_80xx_dispatch,}, + [chip_8076] = {0, 16, &pm8001_80xx_dispatch,}, + [chip_8077] = {0, 16, &pm8001_80xx_dispatch,}, }; static int pm8001_id; @@@ -344,6 -347,10 +347,10 @@@ static int pm8001_alloc(struct pm8001_h /* Memory region for fw flash */ pm8001_ha->memoryMap.region[FW_FLASH].total_len = 4096; + pm8001_ha->memoryMap.region[FORENSIC_MEM].num_elements = 1; + pm8001_ha->memoryMap.region[FORENSIC_MEM].total_len = 0x10000; + pm8001_ha->memoryMap.region[FORENSIC_MEM].element_size = 0x10000; + pm8001_ha->memoryMap.region[FORENSIC_MEM].alignment = 0x10000; for (i = 0; i < USI_MAX_MEMCNT; i++) { if (pm8001_mem_alloc(pm8001_ha->pdev, &pm8001_ha->memoryMap.region[i].virt_ptr, @@@ -664,6 -671,31 +671,31 @@@ static void pm8001_init_sas_add(struct #endif } + /* + * pm8001_get_phy_settings_info : Read phy setting values. + * @pm8001_ha : our hba. + */ + void pm8001_get_phy_settings_info(struct pm8001_hba_info *pm8001_ha) + { + + #ifdef PM8001_READ_VPD + /*OPTION ROM FLASH read for the SPC cards */ + DECLARE_COMPLETION_ONSTACK(completion); + struct pm8001_ioctl_payload payload; + + pm8001_ha->nvmd_completion = &completion; + /* SAS ADDRESS read from flash / EEPROM */ + payload.minor_function = 6; + payload.offset = 0; + payload.length = 4096; + payload.func_specific = kzalloc(4096, GFP_KERNEL); + /* Read phy setting values from flash */ + PM8001_CHIP_DISP->get_nvmd_req(pm8001_ha, &payload); + wait_for_completion(&completion); + pm8001_set_phy_profile(pm8001_ha, sizeof(u8), payload.func_specific); + #endif + } + #ifdef PM8001_USE_MSIX /** * pm8001_setup_msix - enable MSI-X interrupt @@@ -844,6 -876,10 +876,10 @@@ static int pm8001_pci_probe(struct pci_ } pm8001_init_sas_add(pm8001_ha); + /* phy setting support for motherboard controller */ + if (pdev->subsystem_vendor != PCI_VENDOR_ID_ADAPTEC2 && + pdev->subsystem_vendor != 0) + pm8001_get_phy_settings_info(pm8001_ha); pm8001_post_sas_ha_init(shost, chip); rc = sas_register_ha(SHOST_TO_SAS_HA(shost)); if (rc) @@@ -873,6 -909,7 +909,6 @@@ static void pm8001_pci_remove(struct pc struct pm8001_hba_info *pm8001_ha; int i; pm8001_ha = sha->lldd_ha; - pci_set_drvdata(pdev, NULL); sas_unregister_ha(sha); sas_remove_host(pm8001_ha->shost); list_del(&pm8001_ha->list); @@@ -1036,6 -1073,12 +1072,12 @@@ static struct pci_device_id pm8001_pci_ { PCI_VDEVICE(ADAPTEC2, 0x8009), chip_8009 }, { PCI_VDEVICE(PMC_Sierra, 0x8019), chip_8019 }, { PCI_VDEVICE(ADAPTEC2, 0x8019), chip_8019 }, + { PCI_VDEVICE(PMC_Sierra, 0x8074), chip_8074 }, + { PCI_VDEVICE(ADAPTEC2, 0x8074), chip_8074 }, + { PCI_VDEVICE(PMC_Sierra, 0x8076), chip_8076 }, + { PCI_VDEVICE(ADAPTEC2, 0x8076), chip_8076 }, + { PCI_VDEVICE(PMC_Sierra, 0x8077), chip_8077 }, + { PCI_VDEVICE(ADAPTEC2, 0x8077), chip_8077 }, { PCI_VENDOR_ID_ADAPTEC2, 0x8081, PCI_VENDOR_ID_ADAPTEC2, 0x0400, 0, 0, chip_8001 }, { PCI_VENDOR_ID_ADAPTEC2, 0x8081, @@@ -1056,6 -1099,24 +1098,24 @@@ PCI_VENDOR_ID_ADAPTEC2, 0x0016, 0, 0, chip_8019 }, { PCI_VENDOR_ID_ADAPTEC2, 0x8089, PCI_VENDOR_ID_ADAPTEC2, 0x1600, 0, 0, chip_8019 }, + { PCI_VENDOR_ID_ADAPTEC2, 0x8074, + PCI_VENDOR_ID_ADAPTEC2, 0x0800, 0, 0, chip_8074 }, + { PCI_VENDOR_ID_ADAPTEC2, 0x8076, + PCI_VENDOR_ID_ADAPTEC2, 0x1600, 0, 0, chip_8076 }, + { PCI_VENDOR_ID_ADAPTEC2, 0x8077, + PCI_VENDOR_ID_ADAPTEC2, 0x1600, 0, 0, chip_8077 }, + { PCI_VENDOR_ID_ADAPTEC2, 0x8074, + PCI_VENDOR_ID_ADAPTEC2, 0x0008, 0, 0, chip_8074 }, + { PCI_VENDOR_ID_ADAPTEC2, 0x8076, + PCI_VENDOR_ID_ADAPTEC2, 0x0016, 0, 0, chip_8076 }, + { PCI_VENDOR_ID_ADAPTEC2, 0x8077, + PCI_VENDOR_ID_ADAPTEC2, 0x0016, 0, 0, chip_8077 }, + { PCI_VENDOR_ID_ADAPTEC2, 0x8076, + PCI_VENDOR_ID_ADAPTEC2, 0x0808, 0, 0, chip_8076 }, + { PCI_VENDOR_ID_ADAPTEC2, 0x8077, + PCI_VENDOR_ID_ADAPTEC2, 0x0808, 0, 0, chip_8077 }, + { PCI_VENDOR_ID_ADAPTEC2, 0x8074, + PCI_VENDOR_ID_ADAPTEC2, 0x0404, 0, 0, chip_8074 }, {} /* terminate list */ }; @@@ -1107,8 -1168,11 +1167,11 @@@ module_init(pm8001_init) module_exit(pm8001_exit); MODULE_AUTHOR("Jack Wang "); + MODULE_AUTHOR("Anand Kumar Santhanam "); + MODULE_AUTHOR("Sangeetha Gnanasekaran "); MODULE_DESCRIPTION( - "PMC-Sierra PM8001/8081/8088/8089 SAS/SATA controller driver"); + "PMC-Sierra PM8001/8081/8088/8089/8074/8076/8077 " + "SAS/SATA controller driver"); MODULE_VERSION(DRV_VERSION); MODULE_LICENSE("GPL"); MODULE_DEVICE_TABLE(pci, pm8001_pci_table); diff --combined drivers/scsi/qla4xxx/ql4_os.c index 1be6cefc390b,6dc3e99b7f9c..a28d5e624aab --- a/drivers/scsi/qla4xxx/ql4_os.c +++ b/drivers/scsi/qla4xxx/ql4_os.c @@@ -149,6 -149,8 +149,8 @@@ static int qla4xxx_send_ping(struct Scs static int qla4xxx_get_chap_list(struct Scsi_Host *shost, uint16_t chap_tbl_idx, uint32_t *num_entries, char *buf); static int qla4xxx_delete_chap(struct Scsi_Host *shost, uint16_t chap_tbl_idx); + static int qla4xxx_set_chap_entry(struct Scsi_Host *shost, void *data, + int len); /* * SCSI host template entry points @@@ -252,6 -254,7 +254,7 @@@ static struct iscsi_transport qla4xxx_i .send_ping = qla4xxx_send_ping, .get_chap = qla4xxx_get_chap_list, .delete_chap = qla4xxx_delete_chap, + .set_chap = qla4xxx_set_chap_entry, .get_flashnode_param = qla4xxx_sysfs_ddb_get_param, .set_flashnode_param = qla4xxx_sysfs_ddb_set_param, .new_flashnode = qla4xxx_sysfs_ddb_add, @@@ -508,6 -511,95 +511,95 @@@ static umode_t qla4_attr_is_visible(in return 0; } + static int qla4xxx_get_chap_by_index(struct scsi_qla_host *ha, + int16_t chap_index, + struct ql4_chap_table **chap_entry) + { + int rval = QLA_ERROR; + int max_chap_entries; + + if (!ha->chap_list) { + ql4_printk(KERN_ERR, ha, "CHAP table cache is empty!\n"); + rval = QLA_ERROR; + goto exit_get_chap; + } + + if (is_qla80XX(ha)) + max_chap_entries = (ha->hw.flt_chap_size / 2) / + sizeof(struct ql4_chap_table); + else + max_chap_entries = MAX_CHAP_ENTRIES_40XX; + + if (chap_index > max_chap_entries) { + ql4_printk(KERN_ERR, ha, "Invalid Chap index\n"); + rval = QLA_ERROR; + goto exit_get_chap; + } + + *chap_entry = (struct ql4_chap_table *)ha->chap_list + chap_index; + if ((*chap_entry)->cookie != + __constant_cpu_to_le16(CHAP_VALID_COOKIE)) { + rval = QLA_ERROR; + *chap_entry = NULL; + } else { + rval = QLA_SUCCESS; + } + + exit_get_chap: + return rval; + } + + /** + * qla4xxx_find_free_chap_index - Find the first free chap index + * @ha: pointer to adapter structure + * @chap_index: CHAP index to be returned + * + * Find the first free chap index available in the chap table + * + * Note: Caller should acquire the chap lock before getting here. + **/ + static int qla4xxx_find_free_chap_index(struct scsi_qla_host *ha, + uint16_t *chap_index) + { + int i, rval; + int free_index = -1; + int max_chap_entries = 0; + struct ql4_chap_table *chap_table; + + if (is_qla80XX(ha)) + max_chap_entries = (ha->hw.flt_chap_size / 2) / + sizeof(struct ql4_chap_table); + else + max_chap_entries = MAX_CHAP_ENTRIES_40XX; + + if (!ha->chap_list) { + ql4_printk(KERN_ERR, ha, "CHAP table cache is empty!\n"); + rval = QLA_ERROR; + goto exit_find_chap; + } + + for (i = 0; i < max_chap_entries; i++) { + chap_table = (struct ql4_chap_table *)ha->chap_list + i; + + if ((chap_table->cookie != + __constant_cpu_to_le16(CHAP_VALID_COOKIE)) && + (i > MAX_RESRV_CHAP_IDX)) { + free_index = i; + break; + } + } + + if (free_index != -1) { + *chap_index = free_index; + rval = QLA_SUCCESS; + } else { + rval = QLA_ERROR; + } + + exit_find_chap: + return rval; + } + static int qla4xxx_get_chap_list(struct Scsi_Host *shost, uint16_t chap_tbl_idx, uint32_t *num_entries, char *buf) { @@@ -691,6 -783,111 +783,111 @@@ exit_delete_chap return ret; } + /** + * qla4xxx_set_chap_entry - Make chap entry with given information + * @shost: pointer to host + * @data: chap info - credentials, index and type to make chap entry + * @len: length of data + * + * Add or update chap entry with the given information + **/ + static int qla4xxx_set_chap_entry(struct Scsi_Host *shost, void *data, int len) + { + struct scsi_qla_host *ha = to_qla_host(shost); + struct iscsi_chap_rec chap_rec; + struct ql4_chap_table *chap_entry = NULL; + struct iscsi_param_info *param_info; + struct nlattr *attr; + int max_chap_entries = 0; + int type; + int rem = len; + int rc = 0; + + memset(&chap_rec, 0, sizeof(chap_rec)); + + nla_for_each_attr(attr, data, len, rem) { + param_info = nla_data(attr); + + switch (param_info->param) { + case ISCSI_CHAP_PARAM_INDEX: + chap_rec.chap_tbl_idx = *(uint16_t *)param_info->value; + break; + case ISCSI_CHAP_PARAM_CHAP_TYPE: + chap_rec.chap_type = param_info->value[0]; + break; + case ISCSI_CHAP_PARAM_USERNAME: + memcpy(chap_rec.username, param_info->value, + param_info->len); + break; + case ISCSI_CHAP_PARAM_PASSWORD: + memcpy(chap_rec.password, param_info->value, + param_info->len); + break; + case ISCSI_CHAP_PARAM_PASSWORD_LEN: + chap_rec.password_length = param_info->value[0]; + break; + default: + ql4_printk(KERN_ERR, ha, + "%s: No such sysfs attribute\n", __func__); + rc = -ENOSYS; + goto exit_set_chap; + }; + } + + if (chap_rec.chap_type == CHAP_TYPE_IN) + type = BIDI_CHAP; + else + type = LOCAL_CHAP; + + if (is_qla80XX(ha)) + max_chap_entries = (ha->hw.flt_chap_size / 2) / + sizeof(struct ql4_chap_table); + else + max_chap_entries = MAX_CHAP_ENTRIES_40XX; + + mutex_lock(&ha->chap_sem); + if (chap_rec.chap_tbl_idx < max_chap_entries) { + rc = qla4xxx_get_chap_by_index(ha, chap_rec.chap_tbl_idx, + &chap_entry); + if (!rc) { + if (!(type == qla4xxx_get_chap_type(chap_entry))) { + ql4_printk(KERN_INFO, ha, + "Type mismatch for CHAP entry %d\n", + chap_rec.chap_tbl_idx); + rc = -EINVAL; + goto exit_unlock_chap; + } + + /* If chap index is in use then don't modify it */ + rc = qla4xxx_is_chap_active(shost, + chap_rec.chap_tbl_idx); + if (rc) { + ql4_printk(KERN_INFO, ha, + "CHAP entry %d is in use\n", + chap_rec.chap_tbl_idx); + rc = -EBUSY; + goto exit_unlock_chap; + } + } + } else { + rc = qla4xxx_find_free_chap_index(ha, &chap_rec.chap_tbl_idx); + if (rc) { + ql4_printk(KERN_INFO, ha, "CHAP entry not available\n"); + rc = -EBUSY; + goto exit_unlock_chap; + } + } + + rc = qla4xxx_set_chap(ha, chap_rec.username, chap_rec.password, + chap_rec.chap_tbl_idx, type); + + exit_unlock_chap: + mutex_unlock(&ha->chap_sem); + + exit_set_chap: + return rc; + } + static int qla4xxx_get_iface_param(struct iscsi_iface *iface, enum iscsi_param_type param_type, int param, char *buf) @@@ -1455,9 -1652,12 +1652,12 @@@ static int qla4xxx_session_get_param(st struct iscsi_session *sess = cls_sess->dd_data; struct ddb_entry *ddb_entry = sess->dd_data; struct scsi_qla_host *ha = ddb_entry->ha; + struct iscsi_cls_conn *cls_conn = ddb_entry->conn; + struct ql4_chap_table chap_tbl; int rval, len; uint16_t idx; + memset(&chap_tbl, 0, sizeof(chap_tbl)); switch (param) { case ISCSI_PARAM_CHAP_IN_IDX: rval = qla4xxx_get_chap_index(ha, sess->username_in, @@@ -1469,14 -1669,46 +1669,46 @@@ len = sprintf(buf, "%hu\n", idx); break; case ISCSI_PARAM_CHAP_OUT_IDX: - rval = qla4xxx_get_chap_index(ha, sess->username, - sess->password, LOCAL_CHAP, - &idx); + if (ddb_entry->ddb_type == FLASH_DDB) { + if (ddb_entry->chap_tbl_idx != INVALID_ENTRY) { + idx = ddb_entry->chap_tbl_idx; + rval = QLA_SUCCESS; + } else { + rval = QLA_ERROR; + } + } else { + rval = qla4xxx_get_chap_index(ha, sess->username, + sess->password, + LOCAL_CHAP, &idx); + } if (rval) len = sprintf(buf, "\n"); else len = sprintf(buf, "%hu\n", idx); break; + case ISCSI_PARAM_USERNAME: + case ISCSI_PARAM_PASSWORD: + /* First, populate session username and password for FLASH DDB, + * if not already done. This happens when session login fails + * for a FLASH DDB. + */ + if (ddb_entry->ddb_type == FLASH_DDB && + ddb_entry->chap_tbl_idx != INVALID_ENTRY && + !sess->username && !sess->password) { + idx = ddb_entry->chap_tbl_idx; + rval = qla4xxx_get_uni_chap_at_index(ha, chap_tbl.name, + chap_tbl.secret, + idx); + if (!rval) { + iscsi_set_param(cls_conn, ISCSI_PARAM_USERNAME, + (char *)chap_tbl.name, + strlen((char *)chap_tbl.name)); + iscsi_set_param(cls_conn, ISCSI_PARAM_PASSWORD, + (char *)chap_tbl.secret, + chap_tbl.secret_len); + } + } + /* allow fall-through */ default: return iscsi_session_get_param(cls_sess, param, buf); } @@@ -2373,11 -2605,6 +2605,6 @@@ static void qla4xxx_copy_to_sess_conn_p COPY_ISID(sess->isid, fw_ddb_entry->isid); ddb_link = le16_to_cpu(fw_ddb_entry->ddb_link); - if (ddb_link < MAX_DDB_ENTRIES) - sess->discovery_parent_idx = ddb_link; - else - sess->discovery_parent_idx = DDB_NO_LINK; - if (ddb_link == DDB_ISNS) disc_parent = ISCSI_DISC_PARENT_ISNS; else if (ddb_link == DDB_NO_LINK) @@@ -2402,6 -2629,7 +2629,7 @@@ static void qla4xxx_copy_fwddb_param(st int buflen = 0; struct iscsi_session *sess; struct ddb_entry *ddb_entry; + struct ql4_chap_table chap_tbl; struct iscsi_conn *conn; char ip_addr[DDB_IPADDR_LEN]; uint16_t options = 0; @@@ -2409,6 -2637,7 +2637,7 @@@ sess = cls_sess->dd_data; ddb_entry = sess->dd_data; conn = cls_conn->dd_data; + memset(&chap_tbl, 0, sizeof(chap_tbl)); ddb_entry->chap_tbl_idx = le16_to_cpu(fw_ddb_entry->chap_tbl_idx); @@@ -2435,6 -2664,19 +2664,19 @@@ (char *)fw_ddb_entry->iscsi_name, buflen); iscsi_set_param(cls_conn, ISCSI_PARAM_INITIATOR_NAME, (char *)ha->name_string, buflen); + + if (ddb_entry->chap_tbl_idx != INVALID_ENTRY) { + if (!qla4xxx_get_uni_chap_at_index(ha, chap_tbl.name, + chap_tbl.secret, + ddb_entry->chap_tbl_idx)) { + iscsi_set_param(cls_conn, ISCSI_PARAM_USERNAME, + (char *)chap_tbl.name, + strlen((char *)chap_tbl.name)); + iscsi_set_param(cls_conn, ISCSI_PARAM_PASSWORD, + (char *)chap_tbl.secret, + chap_tbl.secret_len); + } + } } void qla4xxx_update_session_conn_fwddb_param(struct scsi_qla_host *ha, @@@ -4937,7 -5179,8 +5179,8 @@@ static int qla4xxx_compare_tuple_ddb(st } static int qla4xxx_is_session_exists(struct scsi_qla_host *ha, - struct dev_db_entry *fw_ddb_entry) + struct dev_db_entry *fw_ddb_entry, + uint32_t *index) { struct ddb_entry *ddb_entry; struct ql4_tuple_ddb *fw_tddb = NULL; @@@ -4971,6 -5214,8 +5214,8 @@@ qla4xxx_get_param_ddb(ddb_entry, tmp_tddb); if (!qla4xxx_compare_tuple_ddb(ha, fw_tddb, tmp_tddb, false)) { ret = QLA_SUCCESS; /* found */ + if (index != NULL) + *index = idx; goto exit_check; } } @@@ -5206,6 -5451,7 +5451,7 @@@ static void qla4xxx_setup_flash_ddb_ent ddb_entry->ha = ha; ddb_entry->unblock_sess = qla4xxx_unblock_flash_ddb; ddb_entry->ddb_change = qla4xxx_flash_ddb_change; + ddb_entry->chap_tbl_idx = INVALID_ENTRY; atomic_set(&ddb_entry->retry_relogin_timer, INVALID_ENTRY); atomic_set(&ddb_entry->relogin_timer, 0); @@@ -5267,6 -5513,87 +5513,87 @@@ static void qla4xxx_wait_for_ip_configu } while (time_after(wtime, jiffies)); } + static int qla4xxx_cmp_fw_stentry(struct dev_db_entry *fw_ddb_entry, + struct dev_db_entry *flash_ddb_entry) + { + uint16_t options = 0; + size_t ip_len = IP_ADDR_LEN; + + options = le16_to_cpu(fw_ddb_entry->options); + if (options & DDB_OPT_IPV6_DEVICE) + ip_len = IPv6_ADDR_LEN; + + if (memcmp(fw_ddb_entry->ip_addr, flash_ddb_entry->ip_addr, ip_len)) + return QLA_ERROR; + + if (memcmp(&fw_ddb_entry->isid[0], &flash_ddb_entry->isid[0], + sizeof(fw_ddb_entry->isid))) + return QLA_ERROR; + + if (memcmp(&fw_ddb_entry->port, &flash_ddb_entry->port, + sizeof(fw_ddb_entry->port))) + return QLA_ERROR; + + return QLA_SUCCESS; + } + + static int qla4xxx_find_flash_st_idx(struct scsi_qla_host *ha, + struct dev_db_entry *fw_ddb_entry, + uint32_t fw_idx, uint32_t *flash_index) + { + struct dev_db_entry *flash_ddb_entry; + dma_addr_t flash_ddb_entry_dma; + uint32_t idx = 0; + int max_ddbs; + int ret = QLA_ERROR, status; + + max_ddbs = is_qla40XX(ha) ? MAX_DEV_DB_ENTRIES_40XX : + MAX_DEV_DB_ENTRIES; + + flash_ddb_entry = dma_pool_alloc(ha->fw_ddb_dma_pool, GFP_KERNEL, + &flash_ddb_entry_dma); + if (flash_ddb_entry == NULL || fw_ddb_entry == NULL) { + ql4_printk(KERN_ERR, ha, "Out of memory\n"); + goto exit_find_st_idx; + } + + status = qla4xxx_flashdb_by_index(ha, flash_ddb_entry, + flash_ddb_entry_dma, fw_idx); + if (status == QLA_SUCCESS) { + status = qla4xxx_cmp_fw_stentry(fw_ddb_entry, flash_ddb_entry); + if (status == QLA_SUCCESS) { + *flash_index = fw_idx; + ret = QLA_SUCCESS; + goto exit_find_st_idx; + } + } + + for (idx = 0; idx < max_ddbs; idx++) { + status = qla4xxx_flashdb_by_index(ha, flash_ddb_entry, + flash_ddb_entry_dma, idx); + if (status == QLA_ERROR) + continue; + + status = qla4xxx_cmp_fw_stentry(fw_ddb_entry, flash_ddb_entry); + if (status == QLA_SUCCESS) { + *flash_index = idx; + ret = QLA_SUCCESS; + goto exit_find_st_idx; + } + } + + if (idx == max_ddbs) + ql4_printk(KERN_ERR, ha, "Failed to find ST [%d] in flash\n", + fw_idx); + + exit_find_st_idx: + if (flash_ddb_entry) + dma_pool_free(ha->fw_ddb_dma_pool, flash_ddb_entry, + flash_ddb_entry_dma); + + return ret; + } + static void qla4xxx_build_st_list(struct scsi_qla_host *ha, struct list_head *list_st) { @@@ -5278,6 -5605,7 +5605,7 @@@ int ret; uint32_t idx = 0, next_idx = 0; uint32_t state = 0, conn_err = 0; + uint32_t flash_index = -1; uint16_t conn_id = 0; fw_ddb_entry = dma_pool_alloc(ha->fw_ddb_dma_pool, GFP_KERNEL, @@@ -5310,6 -5638,19 +5638,19 @@@ if (!st_ddb_idx) break; + ret = qla4xxx_find_flash_st_idx(ha, fw_ddb_entry, idx, + &flash_index); + if (ret == QLA_ERROR) { + ql4_printk(KERN_ERR, ha, + "No flash entry for ST at idx [%d]\n", idx); + st_ddb_idx->flash_ddb_idx = idx; + } else { + ql4_printk(KERN_INFO, ha, + "ST at idx [%d] is stored at flash [%d]\n", + idx, flash_index); + st_ddb_idx->flash_ddb_idx = flash_index; + } + st_ddb_idx->fw_ddb_idx = idx; list_add_tail(&st_ddb_idx->list, list_st); @@@ -5354,6 -5695,28 +5695,28 @@@ static void qla4xxx_remove_failed_ddb(s } } + static void qla4xxx_update_sess_disc_idx(struct scsi_qla_host *ha, + struct ddb_entry *ddb_entry, + struct dev_db_entry *fw_ddb_entry) + { + struct iscsi_cls_session *cls_sess; + struct iscsi_session *sess; + uint32_t max_ddbs = 0; + uint16_t ddb_link = -1; + + max_ddbs = is_qla40XX(ha) ? MAX_DEV_DB_ENTRIES_40XX : + MAX_DEV_DB_ENTRIES; + + cls_sess = ddb_entry->sess; + sess = cls_sess->dd_data; + + ddb_link = le16_to_cpu(fw_ddb_entry->ddb_link); + if (ddb_link < max_ddbs) + sess->discovery_parent_idx = ddb_link; + else + sess->discovery_parent_idx = DDB_NO_LINK; + } + static int qla4xxx_sess_conn_setup(struct scsi_qla_host *ha, struct dev_db_entry *fw_ddb_entry, int is_reset, uint16_t idx) @@@ -5418,6 -5781,7 +5781,7 @@@ /* Update sess/conn params */ qla4xxx_copy_fwddb_param(ha, fw_ddb_entry, cls_sess, cls_conn); + qla4xxx_update_sess_disc_idx(ha, ddb_entry, fw_ddb_entry); if (is_reset == RESET_ADAPTER) { iscsi_block_session(cls_sess); @@@ -5434,17 -5798,43 +5798,43 @@@ exit_setup return ret; } + static void qla4xxx_update_fw_ddb_link(struct scsi_qla_host *ha, + struct list_head *list_ddb, + struct dev_db_entry *fw_ddb_entry) + { + struct qla_ddb_index *ddb_idx, *ddb_idx_tmp; + uint16_t ddb_link; + + ddb_link = le16_to_cpu(fw_ddb_entry->ddb_link); + + list_for_each_entry_safe(ddb_idx, ddb_idx_tmp, list_ddb, list) { + if (ddb_idx->fw_ddb_idx == ddb_link) { + DEBUG2(ql4_printk(KERN_INFO, ha, + "Updating NT parent idx from [%d] to [%d]\n", + ddb_link, ddb_idx->flash_ddb_idx)); + fw_ddb_entry->ddb_link = + cpu_to_le16(ddb_idx->flash_ddb_idx); + return; + } + } + } + static void qla4xxx_build_nt_list(struct scsi_qla_host *ha, - struct list_head *list_nt, int is_reset) + struct list_head *list_nt, + struct list_head *list_st, + int is_reset) { struct dev_db_entry *fw_ddb_entry; + struct ddb_entry *ddb_entry = NULL; dma_addr_t fw_ddb_dma; int max_ddbs; int fw_idx_size; int ret; uint32_t idx = 0, next_idx = 0; uint32_t state = 0, conn_err = 0; + uint32_t ddb_idx = -1; uint16_t conn_id = 0; + uint16_t ddb_link = -1; struct qla_ddb_index *nt_ddb_idx; fw_ddb_entry = dma_pool_alloc(ha->fw_ddb_dma_pool, GFP_KERNEL, @@@ -5471,12 -5861,18 +5861,18 @@@ if (strlen((char *) fw_ddb_entry->iscsi_name) == 0) goto continue_next_nt; + ddb_link = le16_to_cpu(fw_ddb_entry->ddb_link); + if (ddb_link < max_ddbs) + qla4xxx_update_fw_ddb_link(ha, list_st, fw_ddb_entry); + if (!(state == DDB_DS_NO_CONNECTION_ACTIVE || - state == DDB_DS_SESSION_FAILED)) + state == DDB_DS_SESSION_FAILED) && + (is_reset == INIT_ADAPTER)) goto continue_next_nt; DEBUG2(ql4_printk(KERN_INFO, ha, "Adding DDB to session = 0x%x\n", idx)); + if (is_reset == INIT_ADAPTER) { nt_ddb_idx = vmalloc(fw_idx_size); if (!nt_ddb_idx) @@@ -5506,9 -5902,17 +5902,17 @@@ list_add_tail(&nt_ddb_idx->list, list_nt); } else if (is_reset == RESET_ADAPTER) { - if (qla4xxx_is_session_exists(ha, fw_ddb_entry) == - QLA_SUCCESS) + ret = qla4xxx_is_session_exists(ha, fw_ddb_entry, + &ddb_idx); + if (ret == QLA_SUCCESS) { + ddb_entry = qla4xxx_lookup_ddb_by_fw_index(ha, + ddb_idx); + if (ddb_entry != NULL) + qla4xxx_update_sess_disc_idx(ha, + ddb_entry, + fw_ddb_entry); goto continue_next_nt; + } } ret = qla4xxx_sess_conn_setup(ha, fw_ddb_entry, is_reset, idx); @@@ -5526,7 -5930,8 +5930,8 @@@ exit_nt_list } static void qla4xxx_build_new_nt_list(struct scsi_qla_host *ha, - struct list_head *list_nt) + struct list_head *list_nt, + uint16_t target_id) { struct dev_db_entry *fw_ddb_entry; dma_addr_t fw_ddb_dma; @@@ -5571,13 -5976,16 +5976,16 @@@ nt_ddb_idx->fw_ddb_idx = idx; - ret = qla4xxx_is_session_exists(ha, fw_ddb_entry); + ret = qla4xxx_is_session_exists(ha, fw_ddb_entry, NULL); if (ret == QLA_SUCCESS) { /* free nt_ddb_idx and do not add to list_nt */ vfree(nt_ddb_idx); goto continue_next_new_nt; } + if (target_id < max_ddbs) + fw_ddb_entry->ddb_link = cpu_to_le16(target_id); + list_add_tail(&nt_ddb_idx->list, list_nt); ret = qla4xxx_sess_conn_setup(ha, fw_ddb_entry, RESET_ADAPTER, @@@ -5894,7 -6302,8 +6302,8 @@@ exit_ddb_conn_open } static int qla4xxx_ddb_login_st(struct scsi_qla_host *ha, - struct dev_db_entry *fw_ddb_entry) + struct dev_db_entry *fw_ddb_entry, + uint16_t target_id) { struct qla_ddb_index *ddb_idx, *ddb_idx_tmp; struct list_head list_nt; @@@ -5919,7 -6328,7 +6328,7 @@@ if (ret == QLA_ERROR) goto exit_login_st; - qla4xxx_build_new_nt_list(ha, &list_nt); + qla4xxx_build_new_nt_list(ha, &list_nt, target_id); list_for_each_entry_safe(ddb_idx, ddb_idx_tmp, &list_nt, list) { list_del_init(&ddb_idx->list); @@@ -5946,7 -6355,7 +6355,7 @@@ static int qla4xxx_ddb_login_nt(struct { int ret = QLA_ERROR; - ret = qla4xxx_is_session_exists(ha, fw_ddb_entry); + ret = qla4xxx_is_session_exists(ha, fw_ddb_entry, NULL); if (ret != QLA_SUCCESS) ret = qla4xxx_sess_conn_setup(ha, fw_ddb_entry, RESET_ADAPTER, idx); @@@ -6001,7 -6410,8 +6410,8 @@@ static int qla4xxx_sysfs_ddb_login(stru fw_ddb_entry->cookie = DDB_VALID_COOKIE; if (strlen((char *)fw_ddb_entry->iscsi_name) == 0) - ret = qla4xxx_ddb_login_st(ha, fw_ddb_entry); + ret = qla4xxx_ddb_login_st(ha, fw_ddb_entry, + fnode_sess->target_id); else ret = qla4xxx_ddb_login_nt(ha, fw_ddb_entry, fnode_sess->target_id); @@@ -6522,10 -6932,13 +6932,13 @@@ qla4xxx_sysfs_ddb_set_param(struct iscs struct Scsi_Host *shost = iscsi_flash_session_to_shost(fnode_sess); struct scsi_qla_host *ha = to_qla_host(shost); struct iscsi_flashnode_param_info *fnode_param; + struct ql4_chap_table chap_tbl; struct nlattr *attr; + uint16_t chap_out_idx = INVALID_ENTRY; int rc = QLA_ERROR; uint32_t rem = len; + memset((void *)&chap_tbl, 0, sizeof(chap_tbl)); nla_for_each_attr(attr, data, len, rem) { fnode_param = nla_data(attr); @@@ -6567,6 -6980,10 +6980,10 @@@ break; case ISCSI_FLASHNODE_CHAP_AUTH_EN: fnode_sess->chap_auth_en = fnode_param->value[0]; + /* Invalidate chap index if chap auth is disabled */ + if (!fnode_sess->chap_auth_en) + fnode_sess->chap_out_idx = INVALID_ENTRY; + break; case ISCSI_FLASHNODE_SNACK_REQ_EN: fnode_conn->snack_req_en = fnode_param->value[0]; @@@ -6705,6 -7122,17 +7122,17 @@@ fnode_conn->exp_statsn = *(uint32_t *)fnode_param->value; break; + case ISCSI_FLASHNODE_CHAP_OUT_IDX: + chap_out_idx = *(uint16_t *)fnode_param->value; + if (!qla4xxx_get_uni_chap_at_index(ha, + chap_tbl.name, + chap_tbl.secret, + chap_out_idx)) { + fnode_sess->chap_out_idx = chap_out_idx; + /* Enable chap auth if chap index is valid */ + fnode_sess->chap_auth_en = QL4_PARAM_ENABLE; + } + break; default: ql4_printk(KERN_ERR, ha, "%s: No such sysfs attribute\n", __func__); @@@ -6926,11 -7354,10 +7354,10 @@@ void qla4xxx_build_ddb_list(struct scsi schedule_timeout_uninterruptible(HZ / 10); } while (time_after(wtime, jiffies)); - /* Free up the sendtargets list */ - qla4xxx_free_ddb_list(&list_st); - qla4xxx_build_nt_list(ha, &list_nt, is_reset); + qla4xxx_build_nt_list(ha, &list_nt, &list_st, is_reset); + qla4xxx_free_ddb_list(&list_st); qla4xxx_free_ddb_list(&list_nt); qla4xxx_free_ddb_index(ha); @@@ -7400,6 -7827,7 +7827,6 @@@ static void qla4xxx_remove_adapter(stru pci_disable_pcie_error_reporting(pdev); pci_disable_device(pdev); - pci_set_drvdata(pdev, NULL); } /**