struct hw_interrupt_type;
struct msi_desc;
/* Helper functions */
-extern int pci_enable_msi(struct msi_info *msi, struct msi_desc **desc);
+extern int pci_enable_msi(struct pci_dev *pdev, struct msi_info *msi,
+ struct msi_desc **desc);
extern void pci_disable_msi(struct msi_desc *msi_desc);
extern int pci_prepare_msix(u16 seg, u8 bus, u8 devfn, bool off);
extern void pci_cleanup_msi(struct pci_dev *pdev);
* irq or non-zero for otherwise.
**/
-static int __pci_enable_msi(struct msi_info *msi, struct msi_desc **desc)
+static int __pci_enable_msi(struct pci_dev *pdev, struct msi_info *msi,
+ struct msi_desc **desc)
{
- struct pci_dev *pdev;
struct msi_desc *old_desc;
ASSERT(pcidevs_locked());
- pdev = pci_get_pdev(NULL, msi->sbdf);
+
if ( !pdev )
return -ENODEV;
* of irqs available. Driver should use the returned value to re-send
* its request.
**/
-static int __pci_enable_msix(struct msi_info *msi, struct msi_desc **desc)
+static int __pci_enable_msix(struct pci_dev *pdev, struct msi_info *msi,
+ struct msi_desc **desc)
{
- struct pci_dev *pdev;
struct msi_desc *old_desc;
ASSERT(pcidevs_locked());
- pdev = pci_get_pdev(NULL, msi->sbdf);
+
if ( !pdev || !pdev->msix )
return -ENODEV;
* Notice: only construct the msi_desc
* no change to irq_desc here, and the interrupt is masked
*/
-int pci_enable_msi(struct msi_info *msi, struct msi_desc **desc)
+int pci_enable_msi(struct pci_dev *pdev, struct msi_info *msi,
+ struct msi_desc **desc)
{
ASSERT(pcidevs_locked());
if ( !use_msi )
return -EPERM;
- return msi->table_base ? __pci_enable_msix(msi, desc) :
- __pci_enable_msi(msi, desc);
+ return msi->table_base ? __pci_enable_msix(pdev, msi, desc) :
+ __pci_enable_msi(pdev, msi, desc);
}
/*
if ( rc > 0 )
{
struct msi_desc *msi_desc = NULL;
+ struct pci_dev *pdev;
pcidevs_lock();
- rc = pci_enable_msi(&msi, &msi_desc);
+ pdev = pci_get_pdev(NULL, msi.sbdf);
+ rc = pdev ? pci_enable_msi(pdev, &msi, &msi_desc) : -ENODEV;
+
if ( !rc )
{
struct irq_desc *desc = irq_to_desc(msi.irq);