scsi: vmw_pvscsi: switch to pci_alloc_irq_vectors
And simplify the interrupt handler by splitting the INTx case that needs to deal with shared interrupts into a separate helper. [mkp: typo fixage] Signed-off-by: Christoph Hellwig <hch@lst.de> Acked-by: Jim Gill <jgill@vmware.com> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
This commit is contained in:
parent
223e4b93e6
commit
2e48e34911
|
@ -68,10 +68,7 @@ struct pvscsi_ctx {
|
||||||
|
|
||||||
struct pvscsi_adapter {
|
struct pvscsi_adapter {
|
||||||
char *mmioBase;
|
char *mmioBase;
|
||||||
unsigned int irq;
|
|
||||||
u8 rev;
|
u8 rev;
|
||||||
bool use_msi;
|
|
||||||
bool use_msix;
|
|
||||||
bool use_msg;
|
bool use_msg;
|
||||||
bool use_req_threshold;
|
bool use_req_threshold;
|
||||||
|
|
||||||
|
@ -1161,30 +1158,26 @@ static bool pvscsi_setup_req_threshold(struct pvscsi_adapter *adapter,
|
||||||
static irqreturn_t pvscsi_isr(int irq, void *devp)
|
static irqreturn_t pvscsi_isr(int irq, void *devp)
|
||||||
{
|
{
|
||||||
struct pvscsi_adapter *adapter = devp;
|
struct pvscsi_adapter *adapter = devp;
|
||||||
int handled;
|
unsigned long flags;
|
||||||
|
|
||||||
if (adapter->use_msi || adapter->use_msix)
|
spin_lock_irqsave(&adapter->hw_lock, flags);
|
||||||
handled = true;
|
pvscsi_process_completion_ring(adapter);
|
||||||
else {
|
if (adapter->use_msg && pvscsi_msg_pending(adapter))
|
||||||
u32 val = pvscsi_read_intr_status(adapter);
|
queue_work(adapter->workqueue, &adapter->work);
|
||||||
handled = (val & PVSCSI_INTR_ALL_SUPPORTED) != 0;
|
spin_unlock_irqrestore(&adapter->hw_lock, flags);
|
||||||
if (handled)
|
|
||||||
pvscsi_write_intr_status(devp, val);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (handled) {
|
return IRQ_HANDLED;
|
||||||
unsigned long flags;
|
}
|
||||||
|
|
||||||
spin_lock_irqsave(&adapter->hw_lock, flags);
|
static irqreturn_t pvscsi_shared_isr(int irq, void *devp)
|
||||||
|
{
|
||||||
|
struct pvscsi_adapter *adapter = devp;
|
||||||
|
u32 val = pvscsi_read_intr_status(adapter);
|
||||||
|
|
||||||
pvscsi_process_completion_ring(adapter);
|
if (!(val & PVSCSI_INTR_ALL_SUPPORTED))
|
||||||
if (adapter->use_msg && pvscsi_msg_pending(adapter))
|
return IRQ_NONE;
|
||||||
queue_work(adapter->workqueue, &adapter->work);
|
pvscsi_write_intr_status(devp, val);
|
||||||
|
return pvscsi_isr(irq, devp);
|
||||||
spin_unlock_irqrestore(&adapter->hw_lock, flags);
|
|
||||||
}
|
|
||||||
|
|
||||||
return IRQ_RETVAL(handled);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void pvscsi_free_sgls(const struct pvscsi_adapter *adapter)
|
static void pvscsi_free_sgls(const struct pvscsi_adapter *adapter)
|
||||||
|
@ -1196,34 +1189,10 @@ static void pvscsi_free_sgls(const struct pvscsi_adapter *adapter)
|
||||||
free_pages((unsigned long)ctx->sgl, get_order(SGL_SIZE));
|
free_pages((unsigned long)ctx->sgl, get_order(SGL_SIZE));
|
||||||
}
|
}
|
||||||
|
|
||||||
static int pvscsi_setup_msix(const struct pvscsi_adapter *adapter,
|
|
||||||
unsigned int *irq)
|
|
||||||
{
|
|
||||||
struct msix_entry entry = { 0, PVSCSI_VECTOR_COMPLETION };
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
ret = pci_enable_msix_exact(adapter->dev, &entry, 1);
|
|
||||||
if (ret)
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
*irq = entry.vector;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void pvscsi_shutdown_intr(struct pvscsi_adapter *adapter)
|
static void pvscsi_shutdown_intr(struct pvscsi_adapter *adapter)
|
||||||
{
|
{
|
||||||
if (adapter->irq) {
|
free_irq(pci_irq_vector(adapter->dev, 0), adapter);
|
||||||
free_irq(adapter->irq, adapter);
|
pci_free_irq_vectors(adapter->dev);
|
||||||
adapter->irq = 0;
|
|
||||||
}
|
|
||||||
if (adapter->use_msi) {
|
|
||||||
pci_disable_msi(adapter->dev);
|
|
||||||
adapter->use_msi = 0;
|
|
||||||
} else if (adapter->use_msix) {
|
|
||||||
pci_disable_msix(adapter->dev);
|
|
||||||
adapter->use_msix = 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void pvscsi_release_resources(struct pvscsi_adapter *adapter)
|
static void pvscsi_release_resources(struct pvscsi_adapter *adapter)
|
||||||
|
@ -1359,11 +1328,11 @@ exit:
|
||||||
|
|
||||||
static int pvscsi_probe(struct pci_dev *pdev, const struct pci_device_id *id)
|
static int pvscsi_probe(struct pci_dev *pdev, const struct pci_device_id *id)
|
||||||
{
|
{
|
||||||
|
unsigned int irq_flag = PCI_IRQ_MSIX | PCI_IRQ_MSI | PCI_IRQ_LEGACY;
|
||||||
struct pvscsi_adapter *adapter;
|
struct pvscsi_adapter *adapter;
|
||||||
struct pvscsi_adapter adapter_temp;
|
struct pvscsi_adapter adapter_temp;
|
||||||
struct Scsi_Host *host = NULL;
|
struct Scsi_Host *host = NULL;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
unsigned long flags = 0;
|
|
||||||
int error;
|
int error;
|
||||||
u32 max_id;
|
u32 max_id;
|
||||||
|
|
||||||
|
@ -1512,30 +1481,33 @@ static int pvscsi_probe(struct pci_dev *pdev, const struct pci_device_id *id)
|
||||||
goto out_reset_adapter;
|
goto out_reset_adapter;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!pvscsi_disable_msix &&
|
if (pvscsi_disable_msix)
|
||||||
pvscsi_setup_msix(adapter, &adapter->irq) == 0) {
|
irq_flag &= ~PCI_IRQ_MSIX;
|
||||||
printk(KERN_INFO "vmw_pvscsi: using MSI-X\n");
|
if (pvscsi_disable_msi)
|
||||||
adapter->use_msix = 1;
|
irq_flag &= ~PCI_IRQ_MSI;
|
||||||
} else if (!pvscsi_disable_msi && pci_enable_msi(pdev) == 0) {
|
|
||||||
printk(KERN_INFO "vmw_pvscsi: using MSI\n");
|
error = pci_alloc_irq_vectors(adapter->dev, 1, 1, irq_flag);
|
||||||
adapter->use_msi = 1;
|
if (error)
|
||||||
adapter->irq = pdev->irq;
|
goto out_reset_adapter;
|
||||||
} else {
|
|
||||||
printk(KERN_INFO "vmw_pvscsi: using INTx\n");
|
|
||||||
adapter->irq = pdev->irq;
|
|
||||||
flags = IRQF_SHARED;
|
|
||||||
}
|
|
||||||
|
|
||||||
adapter->use_req_threshold = pvscsi_setup_req_threshold(adapter, true);
|
adapter->use_req_threshold = pvscsi_setup_req_threshold(adapter, true);
|
||||||
printk(KERN_DEBUG "vmw_pvscsi: driver-based request coalescing %sabled\n",
|
printk(KERN_DEBUG "vmw_pvscsi: driver-based request coalescing %sabled\n",
|
||||||
adapter->use_req_threshold ? "en" : "dis");
|
adapter->use_req_threshold ? "en" : "dis");
|
||||||
|
|
||||||
error = request_irq(adapter->irq, pvscsi_isr, flags,
|
if (adapter->dev->msix_enabled || adapter->dev->msi_enabled) {
|
||||||
"vmw_pvscsi", adapter);
|
printk(KERN_INFO "vmw_pvscsi: using MSI%s\n",
|
||||||
|
adapter->dev->msix_enabled ? "-X" : "");
|
||||||
|
error = request_irq(pci_irq_vector(pdev, 0), pvscsi_isr,
|
||||||
|
0, "vmw_pvscsi", adapter);
|
||||||
|
} else {
|
||||||
|
printk(KERN_INFO "vmw_pvscsi: using INTx\n");
|
||||||
|
error = request_irq(pci_irq_vector(pdev, 0), pvscsi_shared_isr,
|
||||||
|
IRQF_SHARED, "vmw_pvscsi", adapter);
|
||||||
|
}
|
||||||
|
|
||||||
if (error) {
|
if (error) {
|
||||||
printk(KERN_ERR
|
printk(KERN_ERR
|
||||||
"vmw_pvscsi: unable to request IRQ: %d\n", error);
|
"vmw_pvscsi: unable to request IRQ: %d\n", error);
|
||||||
adapter->irq = 0;
|
|
||||||
goto out_reset_adapter;
|
goto out_reset_adapter;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -422,11 +422,6 @@ struct PVSCSIConfigPageController {
|
||||||
*/
|
*/
|
||||||
#define PVSCSI_MAX_INTRS 24
|
#define PVSCSI_MAX_INTRS 24
|
||||||
|
|
||||||
/*
|
|
||||||
* Enumeration of supported MSI-X vectors
|
|
||||||
*/
|
|
||||||
#define PVSCSI_VECTOR_COMPLETION 0
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Misc constants for the rings.
|
* Misc constants for the rings.
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Reference in New Issue