mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 10:40:15 +02:00 
			
		
		
		
	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
					
				
					 2 changed files with 38 additions and 71 deletions
				
			
		| 
						 | 
					@ -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 @@ static u32 pvscsi_get_max_targets(struct pvscsi_adapter *adapter)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
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 a new issue