scsi: arcmsr: Use pci_alloc_irq_vectors

Switch the arcmsr driver to use pci_alloc_irq_vectors.  We need to two
calls to pci_alloc_irq_vectors as arcmsr 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: Ching Huang <ching2048@areca.com.tw>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
This commit is contained in:
Christoph Hellwig 2016-09-11 15:31:23 +02:00 committed by Martin K. Petersen
parent e3a00f68e4
commit 68130c9948
2 changed files with 32 additions and 53 deletions

View File

@ -629,7 +629,6 @@ struct AdapterControlBlock
struct pci_dev * pdev; struct pci_dev * pdev;
struct Scsi_Host * host; struct Scsi_Host * host;
unsigned long vir2phy_offset; unsigned long vir2phy_offset;
struct msix_entry entries[ARCMST_NUM_MSIX_VECTORS];
/* Offset is used in making arc cdb physical to virtual calculations */ /* Offset is used in making arc cdb physical to virtual calculations */
uint32_t outbound_int_enable; uint32_t outbound_int_enable;
uint32_t cdb_phyaddr_hi32; uint32_t cdb_phyaddr_hi32;
@ -671,8 +670,6 @@ struct AdapterControlBlock
/* iop init */ /* iop init */
#define ACB_F_ABORT 0x0200 #define ACB_F_ABORT 0x0200
#define ACB_F_FIRMWARE_TRAP 0x0400 #define ACB_F_FIRMWARE_TRAP 0x0400
#define ACB_F_MSI_ENABLED 0x1000
#define ACB_F_MSIX_ENABLED 0x2000
struct CommandControlBlock * pccb_pool[ARCMSR_MAX_FREECCB_NUM]; struct CommandControlBlock * pccb_pool[ARCMSR_MAX_FREECCB_NUM];
/* used for memory free */ /* used for memory free */
struct list_head ccb_free_list; struct list_head ccb_free_list;
@ -725,7 +722,7 @@ struct AdapterControlBlock
atomic_t rq_map_token; atomic_t rq_map_token;
atomic_t ante_token_value; atomic_t ante_token_value;
uint32_t maxOutstanding; uint32_t maxOutstanding;
int msix_vector_count; int vector_count;
};/* HW_DEVICE_EXTENSION */ };/* HW_DEVICE_EXTENSION */
/* /*
******************************************************************************* *******************************************************************************

View File

@ -720,51 +720,39 @@ static void arcmsr_message_isr_bh_fn(struct work_struct *work)
static int static int
arcmsr_request_irq(struct pci_dev *pdev, struct AdapterControlBlock *acb) arcmsr_request_irq(struct pci_dev *pdev, struct AdapterControlBlock *acb)
{ {
int i, j, r; unsigned long flags;
struct msix_entry entries[ARCMST_NUM_MSIX_VECTORS]; int nvec, i;
for (i = 0; i < ARCMST_NUM_MSIX_VECTORS; i++) nvec = pci_alloc_irq_vectors(pdev, 1, ARCMST_NUM_MSIX_VECTORS,
entries[i].entry = i; PCI_IRQ_MSIX);
r = pci_enable_msix_range(pdev, entries, 1, ARCMST_NUM_MSIX_VECTORS); if (nvec > 0) {
if (r < 0) pr_info("arcmsr%d: msi-x enabled\n", acb->host->host_no);
goto msi_int; flags = 0;
acb->msix_vector_count = r; } else {
for (i = 0; i < r; i++) { nvec = pci_alloc_irq_vectors(pdev, 1, 1,
if (request_irq(entries[i].vector, PCI_IRQ_MSI | PCI_IRQ_LEGACY);
arcmsr_do_interrupt, 0, "arcmsr", acb)) { if (nvec < 1)
return FAILED;
flags = IRQF_SHARED;
}
acb->vector_count = nvec;
for (i = 0; i < nvec; i++) {
if (request_irq(pci_irq_vector(pdev, i), arcmsr_do_interrupt,
flags, "arcmsr", acb)) {
pr_warn("arcmsr%d: request_irq =%d failed!\n", pr_warn("arcmsr%d: request_irq =%d failed!\n",
acb->host->host_no, entries[i].vector); acb->host->host_no, pci_irq_vector(pdev, i));
for (j = 0 ; j < i ; j++) goto out_free_irq;
free_irq(entries[j].vector, acb);
pci_disable_msix(pdev);
goto msi_int;
} }
acb->entries[i] = entries[i];
}
acb->acb_flags |= ACB_F_MSIX_ENABLED;
pr_info("arcmsr%d: msi-x enabled\n", acb->host->host_no);
return SUCCESS;
msi_int:
if (pci_enable_msi_exact(pdev, 1) < 0)
goto legacy_int;
if (request_irq(pdev->irq, arcmsr_do_interrupt,
IRQF_SHARED, "arcmsr", acb)) {
pr_warn("arcmsr%d: request_irq =%d failed!\n",
acb->host->host_no, pdev->irq);
pci_disable_msi(pdev);
goto legacy_int;
}
acb->acb_flags |= ACB_F_MSI_ENABLED;
pr_info("arcmsr%d: msi enabled\n", acb->host->host_no);
return SUCCESS;
legacy_int:
if (request_irq(pdev->irq, arcmsr_do_interrupt,
IRQF_SHARED, "arcmsr", acb)) {
pr_warn("arcmsr%d: request_irq = %d failed!\n",
acb->host->host_no, pdev->irq);
return FAILED;
} }
return SUCCESS; return SUCCESS;
out_free_irq:
while (--i >= 0)
free_irq(pci_irq_vector(pdev, i), acb);
pci_free_irq_vectors(pdev);
return FAILED;
} }
static int arcmsr_probe(struct pci_dev *pdev, const struct pci_device_id *id) static int arcmsr_probe(struct pci_dev *pdev, const struct pci_device_id *id)
@ -886,15 +874,9 @@ static void arcmsr_free_irq(struct pci_dev *pdev,
{ {
int i; int i;
if (acb->acb_flags & ACB_F_MSI_ENABLED) { for (i = 0; i < acb->vector_count; i++)
free_irq(pdev->irq, acb); free_irq(pci_irq_vector(pdev, i), acb);
pci_disable_msi(pdev); pci_free_irq_vectors(pdev);
} else if (acb->acb_flags & ACB_F_MSIX_ENABLED) {
for (i = 0; i < acb->msix_vector_count; i++)
free_irq(acb->entries[i].vector, acb);
pci_disable_msix(pdev);
} else
free_irq(pdev->irq, acb);
} }
static int arcmsr_suspend(struct pci_dev *pdev, pm_message_t state) static int arcmsr_suspend(struct pci_dev *pdev, pm_message_t state)