Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Christoph Hellwig and committed by
Martin K. Petersen
2e48e349 223e4b93

+38 -71
+38 -66
drivers/scsi/vmw_pvscsi.c
··· 68 68 69 69 struct pvscsi_adapter { 70 70 char *mmioBase; 71 - unsigned int irq; 72 71 u8 rev; 73 - bool use_msi; 74 - bool use_msix; 75 72 bool use_msg; 76 73 bool use_req_threshold; 77 74 ··· 1158 1161 static irqreturn_t pvscsi_isr(int irq, void *devp) 1159 1162 { 1160 1163 struct pvscsi_adapter *adapter = devp; 1161 - int handled; 1164 + unsigned long flags; 1162 1165 1163 - if (adapter->use_msi || adapter->use_msix) 1164 - handled = true; 1165 - else { 1166 - u32 val = pvscsi_read_intr_status(adapter); 1167 - handled = (val & PVSCSI_INTR_ALL_SUPPORTED) != 0; 1168 - if (handled) 1169 - pvscsi_write_intr_status(devp, val); 1170 - } 1166 + spin_lock_irqsave(&adapter->hw_lock, flags); 1167 + pvscsi_process_completion_ring(adapter); 1168 + if (adapter->use_msg && pvscsi_msg_pending(adapter)) 1169 + queue_work(adapter->workqueue, &adapter->work); 1170 + spin_unlock_irqrestore(&adapter->hw_lock, flags); 1171 1171 1172 - if (handled) { 1173 - unsigned long flags; 1172 + return IRQ_HANDLED; 1173 + } 1174 1174 1175 - spin_lock_irqsave(&adapter->hw_lock, flags); 1175 + static irqreturn_t pvscsi_shared_isr(int irq, void *devp) 1176 + { 1177 + struct pvscsi_adapter *adapter = devp; 1178 + u32 val = pvscsi_read_intr_status(adapter); 1176 1179 1177 - pvscsi_process_completion_ring(adapter); 1178 - if (adapter->use_msg && pvscsi_msg_pending(adapter)) 1179 - queue_work(adapter->workqueue, &adapter->work); 1180 - 1181 - spin_unlock_irqrestore(&adapter->hw_lock, flags); 1182 - } 1183 - 1184 - return IRQ_RETVAL(handled); 1180 + if (!(val & PVSCSI_INTR_ALL_SUPPORTED)) 1181 + return IRQ_NONE; 1182 + pvscsi_write_intr_status(devp, val); 1183 + return pvscsi_isr(irq, devp); 1185 1184 } 1186 1185 1187 1186 static void pvscsi_free_sgls(const struct pvscsi_adapter *adapter) ··· 1189 1196 free_pages((unsigned long)ctx->sgl, get_order(SGL_SIZE)); 1190 1197 } 1191 1198 1192 - static int pvscsi_setup_msix(const struct pvscsi_adapter *adapter, 1193 - unsigned int *irq) 1194 - { 1195 - struct msix_entry entry = { 0, PVSCSI_VECTOR_COMPLETION }; 1196 - int ret; 1197 - 1198 - ret = pci_enable_msix_exact(adapter->dev, &entry, 1); 1199 - if (ret) 1200 - return ret; 1201 - 1202 - *irq = entry.vector; 1203 - 1204 - return 0; 1205 - } 1206 - 1207 1199 static void pvscsi_shutdown_intr(struct pvscsi_adapter *adapter) 1208 1200 { 1209 - if (adapter->irq) { 1210 - free_irq(adapter->irq, adapter); 1211 - adapter->irq = 0; 1212 - } 1213 - if (adapter->use_msi) { 1214 - pci_disable_msi(adapter->dev); 1215 - adapter->use_msi = 0; 1216 - } else if (adapter->use_msix) { 1217 - pci_disable_msix(adapter->dev); 1218 - adapter->use_msix = 0; 1219 - } 1201 + free_irq(pci_irq_vector(adapter->dev, 0), adapter); 1202 + pci_free_irq_vectors(adapter->dev); 1220 1203 } 1221 1204 1222 1205 static void pvscsi_release_resources(struct pvscsi_adapter *adapter) ··· 1328 1359 1329 1360 static int pvscsi_probe(struct pci_dev *pdev, const struct pci_device_id *id) 1330 1361 { 1362 + unsigned int irq_flag = PCI_IRQ_MSIX | PCI_IRQ_MSI | PCI_IRQ_LEGACY; 1331 1363 struct pvscsi_adapter *adapter; 1332 1364 struct pvscsi_adapter adapter_temp; 1333 1365 struct Scsi_Host *host = NULL; 1334 1366 unsigned int i; 1335 - unsigned long flags = 0; 1336 1367 int error; 1337 1368 u32 max_id; 1338 1369 ··· 1481 1512 goto out_reset_adapter; 1482 1513 } 1483 1514 1484 - if (!pvscsi_disable_msix && 1485 - pvscsi_setup_msix(adapter, &adapter->irq) == 0) { 1486 - printk(KERN_INFO "vmw_pvscsi: using MSI-X\n"); 1487 - adapter->use_msix = 1; 1488 - } else if (!pvscsi_disable_msi && pci_enable_msi(pdev) == 0) { 1489 - printk(KERN_INFO "vmw_pvscsi: using MSI\n"); 1490 - adapter->use_msi = 1; 1491 - adapter->irq = pdev->irq; 1492 - } else { 1493 - printk(KERN_INFO "vmw_pvscsi: using INTx\n"); 1494 - adapter->irq = pdev->irq; 1495 - flags = IRQF_SHARED; 1496 - } 1515 + if (pvscsi_disable_msix) 1516 + irq_flag &= ~PCI_IRQ_MSIX; 1517 + if (pvscsi_disable_msi) 1518 + irq_flag &= ~PCI_IRQ_MSI; 1519 + 1520 + error = pci_alloc_irq_vectors(adapter->dev, 1, 1, irq_flag); 1521 + if (error) 1522 + goto out_reset_adapter; 1497 1523 1498 1524 adapter->use_req_threshold = pvscsi_setup_req_threshold(adapter, true); 1499 1525 printk(KERN_DEBUG "vmw_pvscsi: driver-based request coalescing %sabled\n", 1500 1526 adapter->use_req_threshold ? "en" : "dis"); 1501 1527 1502 - error = request_irq(adapter->irq, pvscsi_isr, flags, 1503 - "vmw_pvscsi", adapter); 1528 + if (adapter->dev->msix_enabled || adapter->dev->msi_enabled) { 1529 + printk(KERN_INFO "vmw_pvscsi: using MSI%s\n", 1530 + adapter->dev->msix_enabled ? "-X" : ""); 1531 + error = request_irq(pci_irq_vector(pdev, 0), pvscsi_isr, 1532 + 0, "vmw_pvscsi", adapter); 1533 + } else { 1534 + printk(KERN_INFO "vmw_pvscsi: using INTx\n"); 1535 + error = request_irq(pci_irq_vector(pdev, 0), pvscsi_shared_isr, 1536 + IRQF_SHARED, "vmw_pvscsi", adapter); 1537 + } 1538 + 1504 1539 if (error) { 1505 1540 printk(KERN_ERR 1506 1541 "vmw_pvscsi: unable to request IRQ: %d\n", error); 1507 - adapter->irq = 0; 1508 1542 goto out_reset_adapter; 1509 1543 } 1510 1544
-5
drivers/scsi/vmw_pvscsi.h
··· 423 423 #define PVSCSI_MAX_INTRS 24 424 424 425 425 /* 426 - * Enumeration of supported MSI-X vectors 427 - */ 428 - #define PVSCSI_VECTOR_COMPLETION 0 429 - 430 - /* 431 426 * Misc constants for the rings. 432 427 */ 433 428