diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-08-07 07:10:32 +0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-08-07 07:10:32 +0400 |
commit | 6b22df74f7af62137772c280791c932855f7635b (patch) | |
tree | 1ae52bc548b48eb9d243c41363b5c39fb93a5ca6 /drivers/scsi/pm8001/pm8001_init.c | |
parent | 930e0312bcdc96d15f02ed6812d4a6c947855a2d (diff) | |
parent | a93cb871cdeace7de7d865555ed492e8bc8075b5 (diff) | |
download | linux-6b22df74f7af62137772c280791c932855f7635b.tar.xz |
Merge tag 'scsi-misc' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi
Pull SCSI updates from James Bottomley:
"This patch set consists of the usual driver updates (ufs, storvsc,
pm8001 hpsa). It also has removal of the user space target driver
code (everyone is using LIO now), a partial PCI MSI-X update, more
multi-queue updates, conversion to 64 bit LUNs (so we could
theoretically cope with any LUN returned by a device) and placeholder
support for the ZBC device type (Shingle drives), plus an assortment
of minor updates and bug fixes"
* tag 'scsi-misc' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi: (143 commits)
scsi: do not issue SCSI RSOC command to Promise Vtrak E610f
vmw_pvscsi: Use pci_enable_msix_exact() instead of pci_enable_msix()
pm8001: Fix invalid return when request_irq() failed
lpfc: Remove superfluous call to pci_disable_msix()
isci: Use pci_enable_msix_exact() instead of pci_enable_msix()
bfa: Use pci_enable_msix_exact() instead of pci_enable_msix()
bfa: Cleanup bfad_setup_intr() function
bfa: Do not call pci_enable_msix() after it failed once
fnic: Use pci_enable_msix_exact() instead of pci_enable_msix()
scsi: use short driver name for per-driver cmd slab caches
scsi_debug: support scsi-mq, queues and locks
Drivers: add blist flags
scsi: ufs: fix endianness sparse warnings
scsi: ufs: make undeclared functions static
bnx2i: Update driver version to 2.7.10.1
pm8001: fix a memory leak in nvmd_resp
pm8001: fix update_flash
pm8001: fix a memory leak in flash_update
pm8001: Cleaning up uninitialized variables
pm8001: Fix to remove null pointer checks that could never happen
...
Diffstat (limited to 'drivers/scsi/pm8001/pm8001_init.c')
-rw-r--r-- | drivers/scsi/pm8001/pm8001_init.c | 40 |
1 files changed, 34 insertions, 6 deletions
diff --git a/drivers/scsi/pm8001/pm8001_init.c b/drivers/scsi/pm8001/pm8001_init.c index e90c89f1d480..e49623a897a7 100644 --- a/drivers/scsi/pm8001/pm8001_init.c +++ b/drivers/scsi/pm8001/pm8001_init.c @@ -246,6 +246,7 @@ static int pm8001_alloc(struct pm8001_hba_info *pm8001_ha, { int i; spin_lock_init(&pm8001_ha->lock); + spin_lock_init(&pm8001_ha->bitmap_lock); PM8001_INIT_DBG(pm8001_ha, pm8001_printk("pm8001_alloc: PHY:%x\n", pm8001_ha->chip->n_phy)); @@ -621,6 +622,8 @@ static void pm8001_init_sas_add(struct pm8001_hba_info *pm8001_ha) DECLARE_COMPLETION_ONSTACK(completion); struct pm8001_ioctl_payload payload; u16 deviceid; + int rc; + pci_read_config_word(pm8001_ha->pdev, PCI_DEVICE_ID, &deviceid); pm8001_ha->nvmd_completion = &completion; @@ -638,7 +641,16 @@ static void pm8001_init_sas_add(struct pm8001_hba_info *pm8001_ha) } payload.offset = 0; payload.func_specific = kzalloc(payload.length, GFP_KERNEL); - PM8001_CHIP_DISP->get_nvmd_req(pm8001_ha, &payload); + if (!payload.func_specific) { + PM8001_INIT_DBG(pm8001_ha, pm8001_printk("mem alloc fail\n")); + return; + } + rc = PM8001_CHIP_DISP->get_nvmd_req(pm8001_ha, &payload); + if (rc) { + kfree(payload.func_specific); + PM8001_INIT_DBG(pm8001_ha, pm8001_printk("nvmd failed\n")); + return; + } wait_for_completion(&completion); for (i = 0, j = 0; i <= 7; i++, j++) { @@ -661,6 +673,7 @@ static void pm8001_init_sas_add(struct pm8001_hba_info *pm8001_ha) pm8001_printk("phy %d sas_addr = %016llx\n", i, pm8001_ha->phy[i].dev_sas_addr)); } + kfree(payload.func_specific); #else for (i = 0; i < pm8001_ha->chip->n_phy; i++) { pm8001_ha->phy[i].dev_sas_addr = 0x50010c600047f9d0ULL; @@ -684,6 +697,7 @@ static int pm8001_get_phy_settings_info(struct pm8001_hba_info *pm8001_ha) /*OPTION ROM FLASH read for the SPC cards */ DECLARE_COMPLETION_ONSTACK(completion); struct pm8001_ioctl_payload payload; + int rc; pm8001_ha->nvmd_completion = &completion; /* SAS ADDRESS read from flash / EEPROM */ @@ -694,7 +708,12 @@ static int pm8001_get_phy_settings_info(struct pm8001_hba_info *pm8001_ha) if (!payload.func_specific) return -ENOMEM; /* Read phy setting values from flash */ - PM8001_CHIP_DISP->get_nvmd_req(pm8001_ha, &payload); + rc = PM8001_CHIP_DISP->get_nvmd_req(pm8001_ha, &payload); + if (rc) { + kfree(payload.func_specific); + PM8001_INIT_DBG(pm8001_ha, pm8001_printk("nvmd failed\n")); + return -ENOMEM; + } wait_for_completion(&completion); pm8001_set_phy_profile(pm8001_ha, sizeof(u8), payload.func_specific); kfree(payload.func_specific); @@ -744,9 +763,10 @@ static u32 pm8001_setup_msix(struct pm8001_hba_info *pm8001_ha) pm8001_ha->irq_vector[i].irq_id = i; pm8001_ha->irq_vector[i].drv_inst = pm8001_ha; - if (request_irq(pm8001_ha->msix_entries[i].vector, + rc = request_irq(pm8001_ha->msix_entries[i].vector, pm8001_interrupt_handler_msix, flag, - intr_drvname[i], &(pm8001_ha->irq_vector[i]))) { + intr_drvname[i], &(pm8001_ha->irq_vector[i])); + if (rc) { for (j = 0; j < i; j++) free_irq( pm8001_ha->msix_entries[j].vector, @@ -964,6 +984,7 @@ static int pm8001_pci_suspend(struct pci_dev *pdev, pm_message_t state) int i, j; u32 device_state; pm8001_ha = sha->lldd_ha; + sas_suspend_ha(sha); flush_workqueue(pm8001_wq); scsi_block_requests(pm8001_ha->shost); if (!pdev->pm_cap) { @@ -1013,6 +1034,7 @@ static int pm8001_pci_resume(struct pci_dev *pdev) int rc; u8 i = 0, j; u32 device_state; + DECLARE_COMPLETION_ONSTACK(completion); pm8001_ha = sha->lldd_ha; device_state = pdev->current_state; @@ -1033,7 +1055,7 @@ static int pm8001_pci_resume(struct pci_dev *pdev) rc = pci_go_44(pdev); if (rc) goto err_out_disable; - + sas_prep_resume_ha(sha); /* chip soft rst only for spc */ if (pm8001_ha->chip_id == chip_8001) { PM8001_CHIP_DISP->chip_soft_rst(pm8001_ha); @@ -1065,7 +1087,13 @@ static int pm8001_pci_resume(struct pci_dev *pdev) for (i = 1; i < pm8001_ha->number_of_intr; i++) PM8001_CHIP_DISP->interrupt_enable(pm8001_ha, i); } - scsi_unblock_requests(pm8001_ha->shost); + pm8001_ha->flags = PM8001F_RUN_TIME; + for (i = 0; i < pm8001_ha->chip->n_phy; i++) { + pm8001_ha->phy[i].enable_completion = &completion; + PM8001_CHIP_DISP->phy_start_req(pm8001_ha, i); + wait_for_completion(&completion); + } + sas_resume_ha(sha); return 0; err_out_disable: |