Changeset View
Changeset View
Standalone View
Standalone View
sys/compat/linuxkpi/common/include/linux/pci.h
Show First 20 Lines • Show All 222 Lines • ▼ Show 20 Lines | struct pci_dev { | ||||
uint16_t device; | uint16_t device; | ||||
uint16_t vendor; | uint16_t vendor; | ||||
uint16_t subsystem_vendor; | uint16_t subsystem_vendor; | ||||
uint16_t subsystem_device; | uint16_t subsystem_device; | ||||
unsigned int irq; | unsigned int irq; | ||||
unsigned int devfn; | unsigned int devfn; | ||||
uint32_t class; | uint32_t class; | ||||
uint8_t revision; | uint8_t revision; | ||||
bool msi_enabled; | |||||
}; | }; | ||||
static inline struct resource_list_entry * | static inline struct resource_list_entry * | ||||
linux_pci_get_rle(struct pci_dev *pdev, int type, int rid) | linux_pci_get_rle(struct pci_dev *pdev, int type, int rid) | ||||
{ | { | ||||
struct pci_devinfo *dinfo; | struct pci_devinfo *dinfo; | ||||
struct resource_list *rl; | struct resource_list *rl; | ||||
Show All 18 Lines | |||||
{ | { | ||||
struct pci_dev *pdev; | struct pci_dev *pdev; | ||||
struct device *found; | struct device *found; | ||||
found = NULL; | found = NULL; | ||||
spin_lock(&pci_lock); | spin_lock(&pci_lock); | ||||
list_for_each_entry(pdev, &pci_devices, links) { | list_for_each_entry(pdev, &pci_devices, links) { | ||||
if (irq == pdev->dev.irq || | if (irq == pdev->dev.irq || | ||||
(irq >= pdev->dev.msix && irq < pdev->dev.msix_max)) { | (irq >= pdev->dev.irq_start && irq < pdev->dev.irq_end)) { | ||||
found = &pdev->dev; | found = &pdev->dev; | ||||
break; | break; | ||||
} | } | ||||
} | } | ||||
spin_unlock(&pci_lock); | spin_unlock(&pci_lock); | ||||
return (found); | return (found); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 145 Lines • ▼ Show 20 Lines | pci_disable_msix(struct pci_dev *pdev) | ||||
pci_release_msi(pdev->dev.bsddev); | pci_release_msi(pdev->dev.bsddev); | ||||
/* | /* | ||||
* The MSIX IRQ numbers associated with this PCI device are no | * The MSIX IRQ numbers associated with this PCI device are no | ||||
* longer valid and might be re-assigned. Make sure | * longer valid and might be re-assigned. Make sure | ||||
* linux_pci_find_irq_dev() does no longer see them by | * linux_pci_find_irq_dev() does no longer see them by | ||||
* resetting their references to zero: | * resetting their references to zero: | ||||
*/ | */ | ||||
pdev->dev.msix = 0; | pdev->dev.irq_start = 0; | ||||
pdev->dev.msix_max = 0; | pdev->dev.irq_end = 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.irq_start = 0; | |||||
pdev->dev.irq_end = 0; | |||||
pdev->irq = pdev->dev.irq; | |||||
pdev->msi_enabled = false; | |||||
} | |||||
unsigned long pci_resource_start(struct pci_dev *pdev, int bar); | unsigned long pci_resource_start(struct pci_dev *pdev, int bar); | ||||
unsigned long pci_resource_len(struct pci_dev *pdev, int bar); | unsigned long pci_resource_len(struct pci_dev *pdev, int bar); | ||||
static inline bus_addr_t | static inline bus_addr_t | ||||
pci_bus_address(struct pci_dev *pdev, int bar) | pci_bus_address(struct pci_dev *pdev, int bar) | ||||
{ | { | ||||
return (pci_resource_start(pdev, bar)); | return (pci_resource_start(pdev, bar)); | ||||
▲ Show 20 Lines • Show All 118 Lines • ▼ Show 20 Lines | pci_enable_msix(struct pci_dev *pdev, struct msix_entry *entries, int nreq) | ||||
* Handle case where "pci_alloc_msix()" may allocate less | * Handle case where "pci_alloc_msix()" may allocate less | ||||
* interrupts than available and return with no error: | * interrupts than available and return with no error: | ||||
*/ | */ | ||||
if (avail < nreq) { | if (avail < nreq) { | ||||
pci_release_msi(pdev->dev.bsddev); | pci_release_msi(pdev->dev.bsddev); | ||||
return avail; | return avail; | ||||
} | } | ||||
rle = linux_pci_get_rle(pdev, SYS_RES_IRQ, 1); | rle = linux_pci_get_rle(pdev, SYS_RES_IRQ, 1); | ||||
pdev->dev.msix = rle->start; | pdev->dev.irq_start = rle->start; | ||||
pdev->dev.msix_max = rle->start + avail; | pdev->dev.irq_end = rle->start + avail; | ||||
for (i = 0; i < nreq; i++) | for (i = 0; i < nreq; i++) | ||||
entries[i].vector = pdev->dev.msix + i; | entries[i].vector = pdev->dev.irq_start + i; | ||||
return (0); | return (0); | ||||
} | } | ||||
#define pci_enable_msix_range(...) \ | #define pci_enable_msix_range(...) \ | ||||
linux_pci_enable_msix_range(__VA_ARGS__) | linux_pci_enable_msix_range(__VA_ARGS__) | ||||
static inline int | static inline int | ||||
pci_enable_msix_range(struct pci_dev *dev, struct msix_entry *entries, | pci_enable_msix_range(struct pci_dev *dev, struct msix_entry *entries, | ||||
Show All 11 Lines | if (rc < 0) { | ||||
return (rc); | return (rc); | ||||
} else if (rc > 0) { | } else if (rc > 0) { | ||||
if (rc < minvec) | if (rc < minvec) | ||||
return (-ENOSPC); | return (-ENOSPC); | ||||
nvec = rc; | nvec = rc; | ||||
} | } | ||||
} while (rc); | } while (rc); | ||||
return (nvec); | 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; /* this function only enable one MSI IRQ */ | |||||
hselasky: Can there be more than one msi IRQ and should we support that?
Maybe rename msix_max ->… | |||||
Done Inline ActionsThis (deprecated) function (that GPU drivers use) can only enable one. Otherwise, pretty much only pci_alloc_irq_vectors_affinity could allocate multiple MSI IRQs. val_packett.cool: This (deprecated) function (that GPU drivers use) can only enable one.
Otherwise, pretty much… | |||||
if ((error = -pci_alloc_msi(pdev->dev.bsddev, &avail)) != 0) | |||||
return error; | |||||
rle = linux_pci_get_rle(pdev, SYS_RES_IRQ, 1); | |||||
pdev->dev.irq_start = rle->start; | |||||
pdev->dev.irq_end = rle->start + avail; | |||||
pdev->irq = rle->start; | |||||
pdev->msi_enabled = true; | |||||
return (0); | |||||
} | } | ||||
static inline int | static inline int | ||||
pci_channel_offline(struct pci_dev *pdev) | pci_channel_offline(struct pci_dev *pdev) | ||||
{ | { | ||||
return (pci_get_vendor(pdev->dev.bsddev) == PCIV_INVALID); | return (pci_get_vendor(pdev->dev.bsddev) == PCIV_INVALID); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 305 Lines • Show Last 20 Lines |
Can there be more than one msi IRQ and should we support that?
Maybe rename msix_max -> num_interrupts for use with both MSI and MSIX ?