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

MSI: Add an arch_msi_check_device()

Add an arch_check_device(), which gives archs a chance to check the input
to pci_enable_msi/x. The arch might be interested in the value of nvec so
pass it in. Propagate the error value returned from the arch routine out
to the caller.

Signed-off-by: Michael Ellerman <michael@ellerman.id.au>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>

authored by

Michael Ellerman and committed by
Greg Kroah-Hartman
c9953a73 17bbc12a

+26 -4
+25 -4
drivers/pci/msi.c
··· 459 459 /** 460 460 * pci_msi_check_device - check whether MSI may be enabled on a device 461 461 * @dev: pointer to the pci_dev data structure of MSI device function 462 + * @nvec: how many MSIs have been requested ? 462 463 * @type: are we checking for MSI or MSI-X ? 463 464 * 464 465 * Look at global flags, the device itself, and its parent busses 465 466 * to determine if MSI/-X are supported for the device. If MSI/-X is 466 467 * supported return 0, else return an error code. 467 468 **/ 468 - static int pci_msi_check_device(struct pci_dev * dev, int type) 469 + static int pci_msi_check_device(struct pci_dev* dev, int nvec, int type) 469 470 { 470 471 struct pci_bus *bus; 472 + int ret; 471 473 472 474 /* MSI must be globally enabled and supported by the device */ 473 475 if (!pci_msi_enable || !dev || dev->no_msi) ··· 484 482 for (bus = dev->bus; bus; bus = bus->parent) 485 483 if (bus->bus_flags & PCI_BUS_FLAGS_NO_MSI) 486 484 return -EINVAL; 485 + 486 + ret = arch_msi_check_device(dev, nvec, type); 487 + if (ret) 488 + return ret; 487 489 488 490 if (!pci_find_capability(dev, type)) 489 491 return -EINVAL; ··· 509 503 { 510 504 int status; 511 505 512 - if (pci_msi_check_device(dev, PCI_CAP_ID_MSI)) 513 - return -EINVAL; 506 + status = pci_msi_check_device(dev, 1, PCI_CAP_ID_MSI); 507 + if (status) 508 + return status; 514 509 515 510 WARN_ON(!!dev->msi_enabled); 516 511 ··· 608 601 int i, j; 609 602 u16 control; 610 603 611 - if (!entries || pci_msi_check_device(dev, PCI_CAP_ID_MSIX)) 604 + if (!entries) 612 605 return -EINVAL; 606 + 607 + status = pci_msi_check_device(dev, nvec, PCI_CAP_ID_MSIX); 608 + if (status) 609 + return status; 613 610 614 611 pos = pci_find_capability(dev, PCI_CAP_ID_MSIX); 615 612 pci_read_config_word(dev, msi_control_reg(pos), &control); ··· 698 687 { 699 688 pci_msi_enable = 0; 700 689 } 690 + 691 + 692 + /* Arch hooks */ 693 + 694 + int __attribute__ ((weak)) 695 + arch_msi_check_device(struct pci_dev* dev, int nvec, int type) 696 + { 697 + return 0; 698 + } 699 +
+1
include/linux/msi.h
··· 41 41 */ 42 42 int arch_setup_msi_irq(struct pci_dev *dev, struct msi_desc *desc); 43 43 void arch_teardown_msi_irq(unsigned int irq); 44 + extern int arch_msi_check_device(struct pci_dev* dev, int nvec, int type); 44 45 45 46 46 47 #endif /* LINUX_MSI_H */