linuxkpi: handle ARI
Stop trying to manually calculate RID, which cannot be done correctly by PCI_DEVFN(). Use PCI_GET_RID() method instead. Do not use pci_find_dbsf() to go from the linux pci_dev to freebsd device_t. First, device is readily available as dev.bsddev. Second, using pci_find_dbsf() fails for ARI-enabled functions with large function numbers, because PCI_SLOT()/PCI_FUNC() are for non-ARI. Reviewed by: bz, hselasky, manu Tested by: manu (drm) Sponsored by: Mellanox Technologies/NVidia Networking MFC after: 1 week Differential Revision: https://reviews.freebsd.org/D27960
This commit is contained in:
parent
04a3ba363d
commit
de27805fee
@ -68,6 +68,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <linux/backlight.h>
|
||||
|
||||
#include "backlight_if.h"
|
||||
#include "pcib_if.h"
|
||||
|
||||
static device_probe_t linux_pci_probe;
|
||||
static device_attach_t linux_pci_attach;
|
||||
@ -247,12 +248,16 @@ linux_pci_attach_device(device_t dev, struct pci_driver *pdrv,
|
||||
struct pci_bus *pbus;
|
||||
struct pci_devinfo *dinfo;
|
||||
device_t parent;
|
||||
uintptr_t rid;
|
||||
int error;
|
||||
bool isdrm;
|
||||
|
||||
linux_set_current(curthread);
|
||||
|
||||
if (pdrv != NULL && pdrv->isdrm) {
|
||||
parent = device_get_parent(dev);
|
||||
parent = device_get_parent(dev);
|
||||
isdrm = pdrv != NULL && pdrv->isdrm;
|
||||
|
||||
if (isdrm) {
|
||||
dinfo = device_get_ivars(parent);
|
||||
device_set_ivars(dev, dinfo);
|
||||
} else {
|
||||
@ -262,7 +267,11 @@ linux_pci_attach_device(device_t dev, struct pci_driver *pdrv,
|
||||
pdev->dev.parent = &linux_root_device;
|
||||
pdev->dev.bsddev = dev;
|
||||
INIT_LIST_HEAD(&pdev->dev.irqents);
|
||||
pdev->devfn = PCI_DEVFN(pci_get_slot(dev), pci_get_function(dev));
|
||||
if (isdrm)
|
||||
PCI_GET_ID(device_get_parent(parent), parent, PCI_ID_RID, &rid);
|
||||
else
|
||||
PCI_GET_ID(parent, dev, PCI_ID_RID, &rid);
|
||||
pdev->devfn = rid;
|
||||
pdev->device = dinfo->cfg.device;
|
||||
pdev->vendor = dinfo->cfg.vendor;
|
||||
pdev->subsystem_vendor = dinfo->cfg.subvendor;
|
||||
@ -487,9 +496,8 @@ pci_resource_start(struct pci_dev *pdev, int bar)
|
||||
|
||||
if ((rle = linux_pci_get_bar(pdev, bar)) == NULL)
|
||||
return (0);
|
||||
dev = pci_find_dbsf(pdev->bus->domain, pdev->bus->number,
|
||||
PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn));
|
||||
MPASS(dev != NULL);
|
||||
dev = pdev->pdrv != NULL && pdev->pdrv->isdrm ?
|
||||
device_get_parent(pdev->dev.bsddev) : pdev->dev.bsddev;
|
||||
if (BUS_TRANSLATE_RESOURCE(dev, rle->type, rle->start, &newstart)) {
|
||||
device_printf(pdev->dev.bsddev, "translate of %#jx failed\n",
|
||||
(uintmax_t)rle->start);
|
||||
|
@ -96,6 +96,7 @@ LINUXKPI_GENSRCS+= \
|
||||
device_if.h \
|
||||
pci_if.h \
|
||||
pci_iov_if.h \
|
||||
pcib_if.h \
|
||||
vnode_if.h \
|
||||
usb_if.h \
|
||||
opt_usb.h \
|
||||
|
Loading…
Reference in New Issue
Block a user