Index: sys/compat/linuxkpi/common/include/linux/device.h =================================================================== --- sys/compat/linuxkpi/common/include/linux/device.h +++ sys/compat/linuxkpi/common/include/linux/device.h @@ -110,6 +110,7 @@ void *driver_data; unsigned int irq; #define LINUX_IRQ_INVALID 65535 + bool msi; unsigned int msix; unsigned int msix_max; const struct attribute_group **groups; Index: sys/compat/linuxkpi/common/include/linux/interrupt.h =================================================================== --- sys/compat/linuxkpi/common/include/linux/interrupt.h +++ sys/compat/linuxkpi/common/include/linux/interrupt.h @@ -55,6 +55,8 @@ static inline int linux_irq_rid(struct device *dev, unsigned int irq) { + if (dev->msi) + return (1); if (irq == dev->irq) return (0); return irq - dev->msix + 1; Index: sys/compat/linuxkpi/common/include/linux/pci.h =================================================================== --- sys/compat/linuxkpi/common/include/linux/pci.h +++ sys/compat/linuxkpi/common/include/linux/pci.h @@ -447,6 +447,18 @@ pdev->dev.msix_max = 0; } +#define pci_disable_msi(pdev) \ + linux_pci_disable_msi(pdev) + +static inline void +linux_pci_disable_msi(struct pci_dev *pdev) +{ + + pci_release_msi(pdev->dev.bsddev); + pdev->dev.msi = false; +} + + static inline bus_addr_t pci_bus_address(struct pci_dev *pdev, int bar) { @@ -611,6 +623,31 @@ return (nvec); } +#define pci_enable_msi(pdev) \ + linux_pci_enable_msi(pdev) + +static inline int +pci_enable_msi(struct pci_dev *pdev) +{ + struct resource_list_entry *rle; + int error; + int avail; + + avail = pci_msi_count(pdev->dev.bsddev); + if (avail < 1) { + return -EINVAL; + } + avail = 1; + if ((error = -pci_alloc_msi(pdev->dev.bsddev, &avail)) != 0) { + return error; + } + rle = linux_pci_get_rle(pdev, SYS_RES_IRQ, 1); + pdev->dev.msi = true; + pdev->dev.irq = rle->start; + pdev->irq = rle->start; + return (0); +} + static inline int pci_channel_offline(struct pci_dev *pdev) {