mirror of
https://github.com/SCST-project/scst.git
synced 2026-08-18 05:06:31 +00:00
Synchronize with Feral CVS repository:
Clean up MSI-X implementation and make sure we snag at least *3* vectors so that the ATIO-Q vector is snagged. git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@284 d57e44dd-8a1f-0410-8b47-8ef2f437770f
This commit is contained in:
+42
-13
@@ -1,4 +1,4 @@
|
||||
/* $Id: isp_pci.c,v 1.158 2008/01/26 00:14:12 mjacob Exp $ */
|
||||
/* $Id: isp_pci.c,v 1.159 2008/01/27 01:10:42 mjacob Exp $ */
|
||||
/*
|
||||
* Copyright (c) 1997-2007 by Matthew Jacob
|
||||
* All rights reserved.
|
||||
@@ -349,8 +349,8 @@ struct isp_pcisoftc {
|
||||
void * vaddr; /* Mapped Memory Address */
|
||||
vm_offset_t voff;
|
||||
vm_offset_t poff[_NREG_BLKS];
|
||||
u32 msix_vector : 16,
|
||||
: 13,
|
||||
u16 msix_vector[3];
|
||||
u8 : 5,
|
||||
msix_enabled : 2,
|
||||
msi_enabled : 1;
|
||||
};
|
||||
@@ -427,7 +427,9 @@ isplinux_pci_release(struct Scsi_Host *host)
|
||||
}
|
||||
if (isp_pci->msix_enabled) {
|
||||
if (isp_pci->msix_enabled > 1) {
|
||||
free_irq(isp_pci->msix_vector, isp_pci);
|
||||
free_irq(isp_pci->msix_vector[0], isp_pci);
|
||||
free_irq(isp_pci->msix_vector[1], isp_pci);
|
||||
free_irq(isp_pci->msix_vector[2], isp_pci);
|
||||
}
|
||||
pci_disable_msix(isp_pci->pci_dev);
|
||||
isp_pci->msix_enabled = 0;
|
||||
@@ -528,7 +530,6 @@ isplinux_pci_init_one(struct Scsi_Host *host)
|
||||
struct pci_dev *pdev;
|
||||
ispsoftc_t *isp;
|
||||
const char *fwname = NULL;
|
||||
struct msix_entry isp_msix;
|
||||
|
||||
isp_pci = (struct isp_pcisoftc *) ISP_HOST2ISP(host);
|
||||
pdev = isp_pci->pci_dev;
|
||||
@@ -613,19 +614,27 @@ isplinux_pci_init_one(struct Scsi_Host *host)
|
||||
pci_intx(pdev, 1);
|
||||
}
|
||||
|
||||
isp_msix.vector = 0;
|
||||
isp_msix.entry = 0;
|
||||
|
||||
if (pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2422 || pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2432) {
|
||||
struct msix_entry isp_msix[3];
|
||||
int reg;
|
||||
|
||||
isp_msix[0].vector = 0;
|
||||
isp_msix[0].entry = 0;
|
||||
isp_msix[1].vector = 1;
|
||||
isp_msix[1].entry = 1;
|
||||
isp_msix[2].vector = 2;
|
||||
isp_msix[2].entry = 2;
|
||||
|
||||
/* enable PCI-INTX */
|
||||
pci_intx(pdev, 1);
|
||||
|
||||
/* enable MSI-X or MSI-X */
|
||||
if (pci_enable_msix(pdev, &isp_msix, 1) == 0) {
|
||||
if (pci_enable_msix(pdev, isp_msix, 3) == 0) {
|
||||
isp_pci->msix_enabled = 1;
|
||||
isp_pci->msix_vector = isp_msix.vector;
|
||||
isp_pci->msix_vector[0] = isp_msix[0].vector;
|
||||
isp_pci->msix_vector[1] = isp_msix[1].vector;
|
||||
isp_pci->msix_vector[2] = isp_msix[2].vector;
|
||||
} else if (pci_enable_msi(pdev) == 0) {
|
||||
isp_pci->msi_enabled = 1;
|
||||
}
|
||||
@@ -800,8 +809,19 @@ isplinux_pci_init_one(struct Scsi_Host *host)
|
||||
}
|
||||
#endif
|
||||
if (isp_pci->msix_enabled) {
|
||||
if (request_irq(isp_pci->msix_vector, isplinux_intr, 0, isp->isp_name, isp_pci)) {
|
||||
isp_prt(isp, ISP_LOGWARN, "unable to request MSI-X vector %u", isp_pci->msix_vector);
|
||||
if (request_irq(isp_pci->msix_vector[0], isplinux_intr, 0, "isp_general", isp_pci)) {
|
||||
isp_prt(isp, ISP_LOGWARN, "unable to request MSI-X vector 0");
|
||||
pci_disable_msix(pdev);
|
||||
isp_pci->msix_enabled = 0;
|
||||
} else if (request_irq(isp_pci->msix_vector[1], isplinux_intr, 0, "isp_resp_q", isp_pci)) {
|
||||
isp_prt(isp, ISP_LOGWARN, "unable to request MSI-X vector 1");
|
||||
free_irq(isp_pci->msix_vector[0], isp_pci);
|
||||
pci_disable_msix(pdev);
|
||||
isp_pci->msix_enabled = 0;
|
||||
} else if (request_irq(isp_pci->msix_vector[2], isplinux_intr, 0, "isp_atio_q", isp_pci)) {
|
||||
isp_prt(isp, ISP_LOGWARN, "unable to request MSI-X vector 2");
|
||||
free_irq(isp_pci->msix_vector[0], isp_pci);
|
||||
free_irq(isp_pci->msix_vector[1], isp_pci);
|
||||
pci_disable_msix(pdev);
|
||||
isp_pci->msix_enabled = 0;
|
||||
} else {
|
||||
@@ -809,6 +829,11 @@ isplinux_pci_init_one(struct Scsi_Host *host)
|
||||
}
|
||||
}
|
||||
if (isp_pci->msix_enabled == 0) {
|
||||
if (isp_pci->msi_enabled == 0) {
|
||||
if (pci_enable_msi(pdev) == 0) {
|
||||
isp_pci->msi_enabled = 1;
|
||||
}
|
||||
}
|
||||
if (request_irq(pdev->irq, isplinux_intr, ISP_IRQ_FLAGS, isp->isp_name, isp_pci)) {
|
||||
isp_prt(isp, ISP_LOGERR, "could not snag irq %u (0x%x)", pdev->irq, pdev->irq);
|
||||
goto bad;
|
||||
@@ -921,7 +946,9 @@ bad:
|
||||
}
|
||||
if (isp_pci->msix_enabled) {
|
||||
if (isp_pci->msix_enabled > 1) {
|
||||
free_irq(isp_pci->msix_vector, isp_pci);
|
||||
free_irq(isp_pci->msix_vector[0], isp_pci);
|
||||
free_irq(isp_pci->msix_vector[1], isp_pci);
|
||||
free_irq(isp_pci->msix_vector[2], isp_pci);
|
||||
}
|
||||
pci_disable_msix(isp_pci->pci_dev);
|
||||
isp_pci->msix_enabled = 0;
|
||||
@@ -3355,7 +3382,9 @@ isplinux_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
|
||||
scsi_host_put(host);
|
||||
if (pci_isp->msix_enabled) {
|
||||
if (pci_isp->msix_enabled > 1) {
|
||||
free_irq(pci_isp->msix_vector, pci_isp);
|
||||
free_irq(pci_isp->msix_vector[0], pci_isp);
|
||||
free_irq(pci_isp->msix_vector[1], pci_isp);
|
||||
free_irq(pci_isp->msix_vector[2], pci_isp);
|
||||
}
|
||||
pci_disable_msix(pci_isp->pci_dev);
|
||||
pci_isp->msix_enabled = 0;
|
||||
|
||||
Reference in New Issue
Block a user