0d6e2d783d
This patch fixes build failing with undefined symbol _PAGE_IOMAP with kernel 3.18. The Xen-specific _PAGE_IOMAP PTE flag was removed in kernel 3.18 and could be used for other purpose in future. This patch ensures that _PAGE_IOMAP flag is only used for kernels before 3.18. Signed-off-by: Shu Shen <shu.shen@radisys.com> Acked-by: Jincheng Miao <jmiao@redhat.com>
117 lines
2.8 KiB
C
117 lines
2.8 KiB
C
/*
|
|
* Minimal wrappers to allow compiling igb_uio on older kernels.
|
|
*/
|
|
|
|
#ifndef RHEL_RELEASE_VERSION
|
|
#define RHEL_RELEASE_VERSION(a, b) (((a) << 8) + (b))
|
|
#endif
|
|
|
|
#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 3, 0)
|
|
#define pci_cfg_access_lock pci_block_user_cfg_access
|
|
#define pci_cfg_access_unlock pci_unblock_user_cfg_access
|
|
#endif
|
|
|
|
#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 18, 0)
|
|
#define HAVE_PTE_MASK_PAGE_IOMAP
|
|
#endif
|
|
|
|
#ifndef PCI_MSIX_ENTRY_SIZE
|
|
#define PCI_MSIX_ENTRY_SIZE 16
|
|
#define PCI_MSIX_ENTRY_LOWER_ADDR 0
|
|
#define PCI_MSIX_ENTRY_UPPER_ADDR 4
|
|
#define PCI_MSIX_ENTRY_DATA 8
|
|
#define PCI_MSIX_ENTRY_VECTOR_CTRL 12
|
|
#define PCI_MSIX_ENTRY_CTRL_MASKBIT 1
|
|
#endif
|
|
|
|
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 34) && \
|
|
(!(defined(RHEL_RELEASE_CODE) && \
|
|
RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(5, 9)))
|
|
|
|
static int pci_num_vf(struct pci_dev *dev)
|
|
{
|
|
struct iov {
|
|
int pos;
|
|
int nres;
|
|
u32 cap;
|
|
u16 ctrl;
|
|
u16 total;
|
|
u16 initial;
|
|
u16 nr_virtfn;
|
|
} *iov = (struct iov *)dev->sriov;
|
|
|
|
if (!dev->is_physfn)
|
|
return 0;
|
|
|
|
return iov->nr_virtfn;
|
|
}
|
|
|
|
#endif /* < 2.6.34 */
|
|
|
|
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 39) && \
|
|
(!(defined(RHEL_RELEASE_CODE) && \
|
|
RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(6, 4)))
|
|
|
|
#define kstrtoul strict_strtoul
|
|
|
|
#endif /* < 2.6.39 */
|
|
|
|
#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 3, 0) && \
|
|
(!(defined(RHEL_RELEASE_CODE) && \
|
|
RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(6, 3)))
|
|
|
|
/* Check if INTX works to control irq's.
|
|
* Set's INTX_DISABLE flag and reads it back
|
|
*/
|
|
static bool pci_intx_mask_supported(struct pci_dev *pdev)
|
|
{
|
|
bool mask_supported = false;
|
|
uint16_t orig, new;
|
|
|
|
pci_block_user_cfg_access(pdev);
|
|
pci_read_config_word(pdev, PCI_COMMAND, &orig);
|
|
pci_write_config_word(pdev, PCI_COMMAND,
|
|
orig ^ PCI_COMMAND_INTX_DISABLE);
|
|
pci_read_config_word(pdev, PCI_COMMAND, &new);
|
|
|
|
if ((new ^ orig) & ~PCI_COMMAND_INTX_DISABLE) {
|
|
dev_err(&pdev->dev, "Command register changed from "
|
|
"0x%x to 0x%x: driver or hardware bug?\n", orig, new);
|
|
} else if ((new ^ orig) & PCI_COMMAND_INTX_DISABLE) {
|
|
mask_supported = true;
|
|
pci_write_config_word(pdev, PCI_COMMAND, orig);
|
|
}
|
|
pci_unblock_user_cfg_access(pdev);
|
|
|
|
return mask_supported;
|
|
}
|
|
|
|
static bool pci_check_and_mask_intx(struct pci_dev *pdev)
|
|
{
|
|
bool pending;
|
|
uint32_t status;
|
|
|
|
pci_block_user_cfg_access(pdev);
|
|
pci_read_config_dword(pdev, PCI_COMMAND, &status);
|
|
|
|
/* interrupt is not ours, goes to out */
|
|
pending = (((status >> 16) & PCI_STATUS_INTERRUPT) != 0);
|
|
if (pending) {
|
|
uint16_t old, new;
|
|
|
|
old = status;
|
|
if (status != 0)
|
|
new = old & (~PCI_COMMAND_INTX_DISABLE);
|
|
else
|
|
new = old | PCI_COMMAND_INTX_DISABLE;
|
|
|
|
if (old != new)
|
|
pci_write_config_word(pdev, PCI_COMMAND, new);
|
|
}
|
|
pci_unblock_user_cfg_access(pdev);
|
|
|
|
return pending;
|
|
}
|
|
|
|
#endif /* < 3.3.0 */
|