diff options
Diffstat (limited to 'drivers/scsi/hpsa.c')
-rw-r--r-- | drivers/scsi/hpsa.c | 70 |
1 files changed, 40 insertions, 30 deletions
diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c index 6b35d0dfe64c..cef5d49b59cd 100644 --- a/drivers/scsi/hpsa.c +++ b/drivers/scsi/hpsa.c | |||
@@ -5971,10 +5971,6 @@ static int hpsa_kdump_hard_reset_controller(struct pci_dev *pdev) | |||
5971 | 5971 | ||
5972 | /* Save the PCI command register */ | 5972 | /* Save the PCI command register */ |
5973 | pci_read_config_word(pdev, 4, &command_register); | 5973 | pci_read_config_word(pdev, 4, &command_register); |
5974 | /* Turn the board off. This is so that later pci_restore_state() | ||
5975 | * won't turn the board on before the rest of config space is ready. | ||
5976 | */ | ||
5977 | pci_disable_device(pdev); | ||
5978 | pci_save_state(pdev); | 5974 | pci_save_state(pdev); |
5979 | 5975 | ||
5980 | /* find the first memory BAR, so we can find the cfg table */ | 5976 | /* find the first memory BAR, so we can find the cfg table */ |
@@ -6022,11 +6018,6 @@ static int hpsa_kdump_hard_reset_controller(struct pci_dev *pdev) | |||
6022 | goto unmap_cfgtable; | 6018 | goto unmap_cfgtable; |
6023 | 6019 | ||
6024 | pci_restore_state(pdev); | 6020 | pci_restore_state(pdev); |
6025 | rc = pci_enable_device(pdev); | ||
6026 | if (rc) { | ||
6027 | dev_warn(&pdev->dev, "failed to enable device.\n"); | ||
6028 | goto unmap_cfgtable; | ||
6029 | } | ||
6030 | pci_write_config_word(pdev, 4, command_register); | 6021 | pci_write_config_word(pdev, 4, command_register); |
6031 | 6022 | ||
6032 | /* Some devices (notably the HP Smart Array 5i Controller) | 6023 | /* Some devices (notably the HP Smart Array 5i Controller) |
@@ -6159,26 +6150,22 @@ static void hpsa_interrupt_mode(struct ctlr_info *h) | |||
6159 | h->msix_vector = MAX_REPLY_QUEUES; | 6150 | h->msix_vector = MAX_REPLY_QUEUES; |
6160 | if (h->msix_vector > num_online_cpus()) | 6151 | if (h->msix_vector > num_online_cpus()) |
6161 | h->msix_vector = num_online_cpus(); | 6152 | h->msix_vector = num_online_cpus(); |
6162 | err = pci_enable_msix(h->pdev, hpsa_msix_entries, | 6153 | err = pci_enable_msix_range(h->pdev, hpsa_msix_entries, |
6163 | h->msix_vector); | 6154 | 1, h->msix_vector); |
6164 | if (err > 0) { | 6155 | if (err < 0) { |
6156 | dev_warn(&h->pdev->dev, "MSI-X init failed %d\n", err); | ||
6157 | h->msix_vector = 0; | ||
6158 | goto single_msi_mode; | ||
6159 | } else if (err < h->msix_vector) { | ||
6165 | dev_warn(&h->pdev->dev, "only %d MSI-X vectors " | 6160 | dev_warn(&h->pdev->dev, "only %d MSI-X vectors " |
6166 | "available\n", err); | 6161 | "available\n", err); |
6167 | h->msix_vector = err; | ||
6168 | err = pci_enable_msix(h->pdev, hpsa_msix_entries, | ||
6169 | h->msix_vector); | ||
6170 | } | ||
6171 | if (!err) { | ||
6172 | for (i = 0; i < h->msix_vector; i++) | ||
6173 | h->intr[i] = hpsa_msix_entries[i].vector; | ||
6174 | return; | ||
6175 | } else { | ||
6176 | dev_warn(&h->pdev->dev, "MSI-X init failed %d\n", | ||
6177 | err); | ||
6178 | h->msix_vector = 0; | ||
6179 | goto default_int_mode; | ||
6180 | } | 6162 | } |
6163 | h->msix_vector = err; | ||
6164 | for (i = 0; i < h->msix_vector; i++) | ||
6165 | h->intr[i] = hpsa_msix_entries[i].vector; | ||
6166 | return; | ||
6181 | } | 6167 | } |
6168 | single_msi_mode: | ||
6182 | if (pci_find_capability(h->pdev, PCI_CAP_ID_MSI)) { | 6169 | if (pci_find_capability(h->pdev, PCI_CAP_ID_MSI)) { |
6183 | dev_info(&h->pdev->dev, "MSI\n"); | 6170 | dev_info(&h->pdev->dev, "MSI\n"); |
6184 | if (!pci_enable_msi(h->pdev)) | 6171 | if (!pci_enable_msi(h->pdev)) |
@@ -6541,6 +6528,23 @@ static int hpsa_init_reset_devices(struct pci_dev *pdev) | |||
6541 | if (!reset_devices) | 6528 | if (!reset_devices) |
6542 | return 0; | 6529 | return 0; |
6543 | 6530 | ||
6531 | /* kdump kernel is loading, we don't know in which state is | ||
6532 | * the pci interface. The dev->enable_cnt is equal zero | ||
6533 | * so we call enable+disable, wait a while and switch it on. | ||
6534 | */ | ||
6535 | rc = pci_enable_device(pdev); | ||
6536 | if (rc) { | ||
6537 | dev_warn(&pdev->dev, "Failed to enable PCI device\n"); | ||
6538 | return -ENODEV; | ||
6539 | } | ||
6540 | pci_disable_device(pdev); | ||
6541 | msleep(260); /* a randomly chosen number */ | ||
6542 | rc = pci_enable_device(pdev); | ||
6543 | if (rc) { | ||
6544 | dev_warn(&pdev->dev, "failed to enable device.\n"); | ||
6545 | return -ENODEV; | ||
6546 | } | ||
6547 | pci_set_master(pdev); | ||
6544 | /* Reset the controller with a PCI power-cycle or via doorbell */ | 6548 | /* Reset the controller with a PCI power-cycle or via doorbell */ |
6545 | rc = hpsa_kdump_hard_reset_controller(pdev); | 6549 | rc = hpsa_kdump_hard_reset_controller(pdev); |
6546 | 6550 | ||
@@ -6549,10 +6553,11 @@ static int hpsa_init_reset_devices(struct pci_dev *pdev) | |||
6549 | * "performant mode". Or, it might be 640x, which can't reset | 6553 | * "performant mode". Or, it might be 640x, which can't reset |
6550 | * due to concerns about shared bbwc between 6402/6404 pair. | 6554 | * due to concerns about shared bbwc between 6402/6404 pair. |
6551 | */ | 6555 | */ |
6552 | if (rc == -ENOTSUPP) | 6556 | if (rc) { |
6553 | return rc; /* just try to do the kdump anyhow. */ | 6557 | if (rc != -ENOTSUPP) /* just try to do the kdump anyhow. */ |
6554 | if (rc) | 6558 | rc = -ENODEV; |
6555 | return -ENODEV; | 6559 | goto out_disable; |
6560 | } | ||
6556 | 6561 | ||
6557 | /* Now try to get the controller to respond to a no-op */ | 6562 | /* Now try to get the controller to respond to a no-op */ |
6558 | dev_warn(&pdev->dev, "Waiting for controller to respond to no-op\n"); | 6563 | dev_warn(&pdev->dev, "Waiting for controller to respond to no-op\n"); |
@@ -6563,7 +6568,11 @@ static int hpsa_init_reset_devices(struct pci_dev *pdev) | |||
6563 | dev_warn(&pdev->dev, "no-op failed%s\n", | 6568 | dev_warn(&pdev->dev, "no-op failed%s\n", |
6564 | (i < 11 ? "; re-trying" : "")); | 6569 | (i < 11 ? "; re-trying" : "")); |
6565 | } | 6570 | } |
6566 | return 0; | 6571 | |
6572 | out_disable: | ||
6573 | |||
6574 | pci_disable_device(pdev); | ||
6575 | return rc; | ||
6567 | } | 6576 | } |
6568 | 6577 | ||
6569 | static int hpsa_allocate_cmd_pool(struct ctlr_info *h) | 6578 | static int hpsa_allocate_cmd_pool(struct ctlr_info *h) |
@@ -6743,6 +6752,7 @@ static void hpsa_undo_allocations_after_kdump_soft_reset(struct ctlr_info *h) | |||
6743 | iounmap(h->transtable); | 6752 | iounmap(h->transtable); |
6744 | if (h->cfgtable) | 6753 | if (h->cfgtable) |
6745 | iounmap(h->cfgtable); | 6754 | iounmap(h->cfgtable); |
6755 | pci_disable_device(h->pdev); | ||
6746 | pci_release_regions(h->pdev); | 6756 | pci_release_regions(h->pdev); |
6747 | kfree(h); | 6757 | kfree(h); |
6748 | } | 6758 | } |