summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@lst.de>2016-09-11 09:31:24 -0400
committerMartin K. Petersen <martin.petersen@oracle.com>2016-11-08 17:29:46 -0500
commita299ee62cf40d6d80a9f11d57220f0a28077fe2d (patch)
treef5a357809478024aa5af521a8754e62446d93abe
parent68130c99480919c2088df530fc25b5e314ad806a (diff)
scsi: ipr: Use pci_irq_allocate_vectors
Switch the ipr driver to use pci_alloc_irq_vectors. We need to two calls to pci_alloc_irq_vectors as ipr only supports multiple MSI-X vectors, but not multiple MSI vectors. Otherwise this cleans up a lot of cruft and allows to use a common request_irq loop for irq types, which happens to only iterate over a single line in the non MSI-X case. Signed-off-by: Christoph Hellwig <hch@lst.de> Acked-by: Brian King <brking@linux.vnet.ibm.com> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
-rw-r--r--drivers/scsi/ipr.c173
-rw-r--r--drivers/scsi/ipr.h7
2 files changed, 52 insertions, 128 deletions
diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c
index 532474109624..534dc3c877da 100644
--- a/drivers/scsi/ipr.c
+++ b/drivers/scsi/ipr.c
@@ -186,16 +186,16 @@ static const struct ipr_chip_cfg_t ipr_chip_cfg[] = {
186}; 186};
187 187
188static const struct ipr_chip_t ipr_chip[] = { 188static const struct ipr_chip_t ipr_chip[] = {
189 { PCI_VENDOR_ID_MYLEX, PCI_DEVICE_ID_IBM_GEMSTONE, IPR_USE_LSI, IPR_SIS32, IPR_PCI_CFG, &ipr_chip_cfg[0] }, 189 { PCI_VENDOR_ID_MYLEX, PCI_DEVICE_ID_IBM_GEMSTONE, false, IPR_SIS32, IPR_PCI_CFG, &ipr_chip_cfg[0] },
190 { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_CITRINE, IPR_USE_LSI, IPR_SIS32, IPR_PCI_CFG, &ipr_chip_cfg[0] }, 190 { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_CITRINE, false, IPR_SIS32, IPR_PCI_CFG, &ipr_chip_cfg[0] },
191 { PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_OBSIDIAN, IPR_USE_LSI, IPR_SIS32, IPR_PCI_CFG, &ipr_chip_cfg[0] }, 191 { PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_OBSIDIAN, false, IPR_SIS32, IPR_PCI_CFG, &ipr_chip_cfg[0] },
192 { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_OBSIDIAN, IPR_USE_LSI, IPR_SIS32, IPR_PCI_CFG, &ipr_chip_cfg[0] }, 192 { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_OBSIDIAN, false, IPR_SIS32, IPR_PCI_CFG, &ipr_chip_cfg[0] },
193 { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_OBSIDIAN_E, IPR_USE_MSI, IPR_SIS32, IPR_PCI_CFG, &ipr_chip_cfg[0] }, 193 { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_OBSIDIAN_E, true, IPR_SIS32, IPR_PCI_CFG, &ipr_chip_cfg[0] },
194 { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_SNIPE, IPR_USE_LSI, IPR_SIS32, IPR_PCI_CFG, &ipr_chip_cfg[1] }, 194 { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_SNIPE, false, IPR_SIS32, IPR_PCI_CFG, &ipr_chip_cfg[1] },
195 { PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_SCAMP, IPR_USE_LSI, IPR_SIS32, IPR_PCI_CFG, &ipr_chip_cfg[1] }, 195 { PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_SCAMP, false, IPR_SIS32, IPR_PCI_CFG, &ipr_chip_cfg[1] },
196 { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_CROC_FPGA_E2, IPR_USE_MSI, IPR_SIS64, IPR_MMIO, &ipr_chip_cfg[2] }, 196 { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_CROC_FPGA_E2, true, IPR_SIS64, IPR_MMIO, &ipr_chip_cfg[2] },
197 { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_CROCODILE, IPR_USE_MSI, IPR_SIS64, IPR_MMIO, &ipr_chip_cfg[2] }, 197 { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_CROCODILE, true, IPR_SIS64, IPR_MMIO, &ipr_chip_cfg[2] },
198 { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_RATTLESNAKE, IPR_USE_MSI, IPR_SIS64, IPR_MMIO, &ipr_chip_cfg[2] } 198 { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_RATTLESNAKE, true, IPR_SIS64, IPR_MMIO, &ipr_chip_cfg[2] }
199}; 199};
200 200
201static int ipr_max_bus_speeds[] = { 201static int ipr_max_bus_speeds[] = {
@@ -9439,23 +9439,11 @@ static void ipr_free_mem(struct ipr_ioa_cfg *ioa_cfg)
9439static void ipr_free_irqs(struct ipr_ioa_cfg *ioa_cfg) 9439static void ipr_free_irqs(struct ipr_ioa_cfg *ioa_cfg)
9440{ 9440{
9441 struct pci_dev *pdev = ioa_cfg->pdev; 9441 struct pci_dev *pdev = ioa_cfg->pdev;
9442 int i;
9442 9443
9443 if (ioa_cfg->intr_flag == IPR_USE_MSI || 9444 for (i = 0; i < ioa_cfg->nvectors; i++)
9444 ioa_cfg->intr_flag == IPR_USE_MSIX) { 9445 free_irq(pci_irq_vector(pdev, i), &ioa_cfg->hrrq[i]);
9445 int i; 9446 pci_free_irq_vectors(pdev);
9446 for (i = 0; i < ioa_cfg->nvectors; i++)
9447 free_irq(ioa_cfg->vectors_info[i].vec,
9448 &ioa_cfg->hrrq[i]);
9449 } else
9450 free_irq(pdev->irq, &ioa_cfg->hrrq[0]);
9451
9452 if (ioa_cfg->intr_flag == IPR_USE_MSI) {
9453 pci_disable_msi(pdev);
9454 ioa_cfg->intr_flag &= ~IPR_USE_MSI;
9455 } else if (ioa_cfg->intr_flag == IPR_USE_MSIX) {
9456 pci_disable_msix(pdev);
9457 ioa_cfg->intr_flag &= ~IPR_USE_MSIX;
9458 }
9459} 9447}
9460 9448
9461/** 9449/**
@@ -9883,45 +9871,6 @@ static void ipr_wait_for_pci_err_recovery(struct ipr_ioa_cfg *ioa_cfg)
9883 } 9871 }
9884} 9872}
9885 9873
9886static int ipr_enable_msix(struct ipr_ioa_cfg *ioa_cfg)
9887{
9888 struct msix_entry entries[IPR_MAX_MSIX_VECTORS];
9889 int i, vectors;
9890
9891 for (i = 0; i < ARRAY_SIZE(entries); ++i)
9892 entries[i].entry = i;
9893
9894 vectors = pci_enable_msix_range(ioa_cfg->pdev,
9895 entries, 1, ipr_number_of_msix);
9896 if (vectors < 0) {
9897 ipr_wait_for_pci_err_recovery(ioa_cfg);
9898 return vectors;
9899 }
9900
9901 for (i = 0; i < vectors; i++)
9902 ioa_cfg->vectors_info[i].vec = entries[i].vector;
9903 ioa_cfg->nvectors = vectors;
9904
9905 return 0;
9906}
9907
9908static int ipr_enable_msi(struct ipr_ioa_cfg *ioa_cfg)
9909{
9910 int i, vectors;
9911
9912 vectors = pci_enable_msi_range(ioa_cfg->pdev, 1, ipr_number_of_msix);
9913 if (vectors < 0) {
9914 ipr_wait_for_pci_err_recovery(ioa_cfg);
9915 return vectors;
9916 }
9917
9918 for (i = 0; i < vectors; i++)
9919 ioa_cfg->vectors_info[i].vec = ioa_cfg->pdev->irq + i;
9920 ioa_cfg->nvectors = vectors;
9921
9922 return 0;
9923}
9924
9925static void name_msi_vectors(struct ipr_ioa_cfg *ioa_cfg) 9874static void name_msi_vectors(struct ipr_ioa_cfg *ioa_cfg)
9926{ 9875{
9927 int vec_idx, n = sizeof(ioa_cfg->vectors_info[0].desc) - 1; 9876 int vec_idx, n = sizeof(ioa_cfg->vectors_info[0].desc) - 1;
@@ -9934,19 +9883,20 @@ static void name_msi_vectors(struct ipr_ioa_cfg *ioa_cfg)
9934 } 9883 }
9935} 9884}
9936 9885
9937static int ipr_request_other_msi_irqs(struct ipr_ioa_cfg *ioa_cfg) 9886static int ipr_request_other_msi_irqs(struct ipr_ioa_cfg *ioa_cfg,
9887 struct pci_dev *pdev)
9938{ 9888{
9939 int i, rc; 9889 int i, rc;
9940 9890
9941 for (i = 1; i < ioa_cfg->nvectors; i++) { 9891 for (i = 1; i < ioa_cfg->nvectors; i++) {
9942 rc = request_irq(ioa_cfg->vectors_info[i].vec, 9892 rc = request_irq(pci_irq_vector(pdev, i),
9943 ipr_isr_mhrrq, 9893 ipr_isr_mhrrq,
9944 0, 9894 0,
9945 ioa_cfg->vectors_info[i].desc, 9895 ioa_cfg->vectors_info[i].desc,
9946 &ioa_cfg->hrrq[i]); 9896 &ioa_cfg->hrrq[i]);
9947 if (rc) { 9897 if (rc) {
9948 while (--i >= 0) 9898 while (--i >= 0)
9949 free_irq(ioa_cfg->vectors_info[i].vec, 9899 free_irq(pci_irq_vector(pdev, i),
9950 &ioa_cfg->hrrq[i]); 9900 &ioa_cfg->hrrq[i]);
9951 return rc; 9901 return rc;
9952 } 9902 }
@@ -9984,8 +9934,7 @@ static irqreturn_t ipr_test_intr(int irq, void *devp)
9984 * ipr_test_msi - Test for Message Signaled Interrupt (MSI) support. 9934 * ipr_test_msi - Test for Message Signaled Interrupt (MSI) support.
9985 * @pdev: PCI device struct 9935 * @pdev: PCI device struct
9986 * 9936 *
9987 * Description: The return value from pci_enable_msi_range() can not always be 9937 * Description: This routine sets up and initiates a test interrupt to determine
9988 * trusted. This routine sets up and initiates a test interrupt to determine
9989 * if the interrupt is received via the ipr_test_intr() service routine. 9938 * if the interrupt is received via the ipr_test_intr() service routine.
9990 * If the tests fails, the driver will fall back to LSI. 9939 * If the tests fails, the driver will fall back to LSI.
9991 * 9940 *
@@ -9997,6 +9946,7 @@ static int ipr_test_msi(struct ipr_ioa_cfg *ioa_cfg, struct pci_dev *pdev)
9997 int rc; 9946 int rc;
9998 volatile u32 int_reg; 9947 volatile u32 int_reg;
9999 unsigned long lock_flags = 0; 9948 unsigned long lock_flags = 0;
9949 int irq = pci_irq_vector(pdev, 0);
10000 9950
10001 ENTER; 9951 ENTER;
10002 9952
@@ -10008,15 +9958,12 @@ static int ipr_test_msi(struct ipr_ioa_cfg *ioa_cfg, struct pci_dev *pdev)
10008 int_reg = readl(ioa_cfg->regs.sense_interrupt_mask_reg); 9958 int_reg = readl(ioa_cfg->regs.sense_interrupt_mask_reg);
10009 spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); 9959 spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
10010 9960
10011 if (ioa_cfg->intr_flag == IPR_USE_MSIX) 9961 rc = request_irq(irq, ipr_test_intr, 0, IPR_NAME, ioa_cfg);
10012 rc = request_irq(ioa_cfg->vectors_info[0].vec, ipr_test_intr, 0, IPR_NAME, ioa_cfg);
10013 else
10014 rc = request_irq(pdev->irq, ipr_test_intr, 0, IPR_NAME, ioa_cfg);
10015 if (rc) { 9962 if (rc) {
10016 dev_err(&pdev->dev, "Can not assign irq %d\n", pdev->irq); 9963 dev_err(&pdev->dev, "Can not assign irq %d\n", irq);
10017 return rc; 9964 return rc;
10018 } else if (ipr_debug) 9965 } else if (ipr_debug)
10019 dev_info(&pdev->dev, "IRQ assigned: %d\n", pdev->irq); 9966 dev_info(&pdev->dev, "IRQ assigned: %d\n", irq);
10020 9967
10021 writel(IPR_PCII_IO_DEBUG_ACKNOWLEDGE, ioa_cfg->regs.sense_interrupt_reg32); 9968 writel(IPR_PCII_IO_DEBUG_ACKNOWLEDGE, ioa_cfg->regs.sense_interrupt_reg32);
10022 int_reg = readl(ioa_cfg->regs.sense_interrupt_reg); 9969 int_reg = readl(ioa_cfg->regs.sense_interrupt_reg);
@@ -10033,10 +9980,7 @@ static int ipr_test_msi(struct ipr_ioa_cfg *ioa_cfg, struct pci_dev *pdev)
10033 9980
10034 spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); 9981 spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
10035 9982
10036 if (ioa_cfg->intr_flag == IPR_USE_MSIX) 9983 free_irq(irq, ioa_cfg);
10037 free_irq(ioa_cfg->vectors_info[0].vec, ioa_cfg);
10038 else
10039 free_irq(pdev->irq, ioa_cfg);
10040 9984
10041 LEAVE; 9985 LEAVE;
10042 9986
@@ -10060,6 +10004,7 @@ static int ipr_probe_ioa(struct pci_dev *pdev,
10060 int rc = PCIBIOS_SUCCESSFUL; 10004 int rc = PCIBIOS_SUCCESSFUL;
10061 volatile u32 mask, uproc, interrupts; 10005 volatile u32 mask, uproc, interrupts;
10062 unsigned long lock_flags, driver_lock_flags; 10006 unsigned long lock_flags, driver_lock_flags;
10007 unsigned int irq_flag;
10063 10008
10064 ENTER; 10009 ENTER;
10065 10010
@@ -10175,18 +10120,18 @@ static int ipr_probe_ioa(struct pci_dev *pdev,
10175 ipr_number_of_msix = IPR_MAX_MSIX_VECTORS; 10120 ipr_number_of_msix = IPR_MAX_MSIX_VECTORS;
10176 } 10121 }
10177 10122
10178 if (ioa_cfg->ipr_chip->intr_type == IPR_USE_MSI && 10123 irq_flag = PCI_IRQ_LEGACY;
10179 ipr_enable_msix(ioa_cfg) == 0) 10124 if (ioa_cfg->ipr_chip->has_msi)
10180 ioa_cfg->intr_flag = IPR_USE_MSIX; 10125 irq_flag |= PCI_IRQ_MSI | PCI_IRQ_MSIX;
10181 else if (ioa_cfg->ipr_chip->intr_type == IPR_USE_MSI && 10126 rc = pci_alloc_irq_vectors(pdev, 1, ipr_number_of_msix, irq_flag);
10182 ipr_enable_msi(ioa_cfg) == 0) 10127 if (rc < 0) {
10183 ioa_cfg->intr_flag = IPR_USE_MSI; 10128 ipr_wait_for_pci_err_recovery(ioa_cfg);
10184 else { 10129 goto cleanup_nomem;
10185 ioa_cfg->intr_flag = IPR_USE_LSI;
10186 ioa_cfg->clear_isr = 1;
10187 ioa_cfg->nvectors = 1;
10188 dev_info(&pdev->dev, "Cannot enable MSI.\n");
10189 } 10130 }
10131 ioa_cfg->nvectors = rc;
10132
10133 if (!pdev->msi_enabled && !pdev->msix_enabled)
10134 ioa_cfg->clear_isr = 1;
10190 10135
10191 pci_set_master(pdev); 10136 pci_set_master(pdev);
10192 10137
@@ -10199,33 +10144,22 @@ static int ipr_probe_ioa(struct pci_dev *pdev,
10199 } 10144 }
10200 } 10145 }
10201 10146
10202 if (ioa_cfg->intr_flag == IPR_USE_MSI || 10147 if (pdev->msi_enabled || pdev->msix_enabled) {
10203 ioa_cfg->intr_flag == IPR_USE_MSIX) {
10204 rc = ipr_test_msi(ioa_cfg, pdev); 10148 rc = ipr_test_msi(ioa_cfg, pdev);
10205 if (rc == -EOPNOTSUPP) { 10149 switch (rc) {
10150 case 0:
10151 dev_info(&pdev->dev,
10152 "Request for %d MSI%ss succeeded.", ioa_cfg->nvectors,
10153 pdev->msix_enabled ? "-X" : "");
10154 break;
10155 case -EOPNOTSUPP:
10206 ipr_wait_for_pci_err_recovery(ioa_cfg); 10156 ipr_wait_for_pci_err_recovery(ioa_cfg);
10207 if (ioa_cfg->intr_flag == IPR_USE_MSI) { 10157 pci_free_irq_vectors(pdev);
10208 ioa_cfg->intr_flag &= ~IPR_USE_MSI;
10209 pci_disable_msi(pdev);
10210 } else if (ioa_cfg->intr_flag == IPR_USE_MSIX) {
10211 ioa_cfg->intr_flag &= ~IPR_USE_MSIX;
10212 pci_disable_msix(pdev);
10213 }
10214 10158
10215 ioa_cfg->intr_flag = IPR_USE_LSI;
10216 ioa_cfg->nvectors = 1; 10159 ioa_cfg->nvectors = 1;
10217 } 10160 break;
10218 else if (rc) 10161 default:
10219 goto out_msi_disable; 10162 goto out_msi_disable;
10220 else {
10221 if (ioa_cfg->intr_flag == IPR_USE_MSI)
10222 dev_info(&pdev->dev,
10223 "Request for %d MSIs succeeded with starting IRQ: %d\n",
10224 ioa_cfg->nvectors, pdev->irq);
10225 else if (ioa_cfg->intr_flag == IPR_USE_MSIX)
10226 dev_info(&pdev->dev,
10227 "Request for %d MSIXs succeeded.",
10228 ioa_cfg->nvectors);
10229 } 10163 }
10230 } 10164 }
10231 10165
@@ -10273,15 +10207,13 @@ static int ipr_probe_ioa(struct pci_dev *pdev,
10273 ipr_mask_and_clear_interrupts(ioa_cfg, ~IPR_PCII_IOA_TRANS_TO_OPER); 10207 ipr_mask_and_clear_interrupts(ioa_cfg, ~IPR_PCII_IOA_TRANS_TO_OPER);
10274 spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); 10208 spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
10275 10209
10276 if (ioa_cfg->intr_flag == IPR_USE_MSI 10210 if (pdev->msi_enabled || pdev->msix_enabled) {
10277 || ioa_cfg->intr_flag == IPR_USE_MSIX) {
10278 name_msi_vectors(ioa_cfg); 10211 name_msi_vectors(ioa_cfg);
10279 rc = request_irq(ioa_cfg->vectors_info[0].vec, ipr_isr, 10212 rc = request_irq(pci_irq_vector(pdev, 0), ipr_isr, 0,
10280 0,
10281 ioa_cfg->vectors_info[0].desc, 10213 ioa_cfg->vectors_info[0].desc,
10282 &ioa_cfg->hrrq[0]); 10214 &ioa_cfg->hrrq[0]);
10283 if (!rc) 10215 if (!rc)
10284 rc = ipr_request_other_msi_irqs(ioa_cfg); 10216 rc = ipr_request_other_msi_irqs(ioa_cfg, pdev);
10285 } else { 10217 } else {
10286 rc = request_irq(pdev->irq, ipr_isr, 10218 rc = request_irq(pdev->irq, ipr_isr,
10287 IRQF_SHARED, 10219 IRQF_SHARED,
@@ -10323,10 +10255,7 @@ cleanup_nolog:
10323 ipr_free_mem(ioa_cfg); 10255 ipr_free_mem(ioa_cfg);
10324out_msi_disable: 10256out_msi_disable:
10325 ipr_wait_for_pci_err_recovery(ioa_cfg); 10257 ipr_wait_for_pci_err_recovery(ioa_cfg);
10326 if (ioa_cfg->intr_flag == IPR_USE_MSI) 10258 pci_free_irq_vectors(pdev);
10327 pci_disable_msi(pdev);
10328 else if (ioa_cfg->intr_flag == IPR_USE_MSIX)
10329 pci_disable_msix(pdev);
10330cleanup_nomem: 10259cleanup_nomem:
10331 iounmap(ipr_regs); 10260 iounmap(ipr_regs);
10332out_disable: 10261out_disable:
diff --git a/drivers/scsi/ipr.h b/drivers/scsi/ipr.h
index 8995053d01b3..b7d2e98eb45b 100644
--- a/drivers/scsi/ipr.h
+++ b/drivers/scsi/ipr.h
@@ -1413,10 +1413,7 @@ struct ipr_chip_cfg_t {
1413struct ipr_chip_t { 1413struct ipr_chip_t {
1414 u16 vendor; 1414 u16 vendor;
1415 u16 device; 1415 u16 device;
1416 u16 intr_type; 1416 bool has_msi;
1417#define IPR_USE_LSI 0x00
1418#define IPR_USE_MSI 0x01
1419#define IPR_USE_MSIX 0x02
1420 u16 sis_type; 1417 u16 sis_type;
1421#define IPR_SIS32 0x00 1418#define IPR_SIS32 0x00
1422#define IPR_SIS64 0x01 1419#define IPR_SIS64 0x01
@@ -1593,11 +1590,9 @@ struct ipr_ioa_cfg {
1593 struct ipr_cmnd **ipr_cmnd_list; 1590 struct ipr_cmnd **ipr_cmnd_list;
1594 dma_addr_t *ipr_cmnd_list_dma; 1591 dma_addr_t *ipr_cmnd_list_dma;
1595 1592
1596 u16 intr_flag;
1597 unsigned int nvectors; 1593 unsigned int nvectors;
1598 1594
1599 struct { 1595 struct {
1600 unsigned short vec;
1601 char desc[22]; 1596 char desc[22];
1602 } vectors_info[IPR_MAX_MSIX_VECTORS]; 1597 } vectors_info[IPR_MAX_MSIX_VECTORS];
1603 1598