diff options
author | Bjoern A. Zeeb <bz@FreeBSD.org> | 2021-07-01 13:33:01 +0000 |
---|---|---|
committer | Bjoern A. Zeeb <bz@FreeBSD.org> | 2021-07-27 14:57:23 +0000 |
commit | 366d68f283793df22392f9fb992c5029dfc293bb (patch) | |
tree | 933af669ab05bc584e92aa9ff45aaf193127c23e /sys/compat/linuxkpi/common/include | |
parent | 30c6d982190482857883fc96eefafcc6fd769fa0 (diff) | |
download | src-366d68f283793df22392f9fb992c5029dfc293bb.tar.gz src-366d68f283793df22392f9fb992c5029dfc293bb.zip |
LinuxKPI: add module_pci_driver() and pci_alloc_irq_vectors()
Add the two new functions needed by rtw88 to register the driver and
handle the module bits as well as a version of pci_alloc_irq_vectors()
for what is needed.
Reviewed by: hselasky
MFC after: 10 days
Differential Revision: https://reviews.freebsd.org/D30981
Diffstat (limited to 'sys/compat/linuxkpi/common/include')
-rw-r--r-- | sys/compat/linuxkpi/common/include/linux/pci.h | 59 |
1 files changed, 59 insertions, 0 deletions
diff --git a/sys/compat/linuxkpi/common/include/linux/pci.h b/sys/compat/linuxkpi/common/include/linux/pci.h index 4784799d82b5..a80e6965915d 100644 --- a/sys/compat/linuxkpi/common/include/linux/pci.h +++ b/sys/compat/linuxkpi/common/include/linux/pci.h @@ -186,6 +186,10 @@ typedef int pci_power_t; #define PCI_EXT_CAP_ID_ERR PCIZ_AER +#define PCI_IRQ_LEGACY 0x01 +#define PCI_IRQ_MSI 0x02 +#define PCI_IRQ_MSIX 0x04 + struct pci_dev; struct pci_driver { @@ -221,6 +225,25 @@ extern spinlock_t pci_lock; #define __devexit_p(x) x +#define module_pci_driver(_driver) \ + \ +static inline int \ +_pci_init(void) \ +{ \ + \ + return (linux_pci_register_driver(&_driver)); \ +} \ + \ +static inline void \ +_pci_exit(void) \ +{ \ + \ + linux_pci_unregister_driver(&_driver); \ +} \ + \ +module_init(_pci_init); \ +module_exit(_pci_exit) + /* * If we find drivers accessing this from multiple KPIs we may have to * refcount objects of this structure. @@ -818,6 +841,42 @@ pci_enable_msi(struct pci_dev *pdev) } static inline int +pci_alloc_irq_vectors(struct pci_dev *pdev, int minv, int maxv, + unsigned int flags) +{ + int error; + + if (flags & PCI_IRQ_MSIX) { + struct msix_entry *entries; + int i; + + entries = kcalloc(maxv, sizeof(*entries), GFP_KERNEL); + if (entries == NULL) { + error = -ENOMEM; + goto out; + } + for (i = 0; i < maxv; ++i) + entries[i].entry = i; + error = pci_enable_msix(pdev, entries, maxv); +out: + kfree(entries); + if (error == 0 && pdev->msix_enabled) + return (pdev->dev.irq_end - pdev->dev.irq_start); + } + if (flags & PCI_IRQ_MSI) { + error = pci_enable_msi(pdev); + if (error == 0 && pdev->msi_enabled) + return (pdev->dev.irq_end - pdev->dev.irq_start); + } + if (flags & PCI_IRQ_LEGACY) { + if (pdev->irq) + return (1); + } + + return (-EINVAL); +} + +static inline int pci_channel_offline(struct pci_dev *pdev) { |