git: de27805fee0b - main - linuxkpi: handle ARI

Konstantin Belousov kib at FreeBSD.org
Fri Jan 8 21:18:52 UTC 2021


The branch main has been updated by kib:

URL: https://cgit.FreeBSD.org/src/commit/?id=de27805fee0bbe3b714615b1df4cf0b8ebbc39b9

commit de27805fee0bbe3b714615b1df4cf0b8ebbc39b9
Author:     Konstantin Belousov <kib at FreeBSD.org>
AuthorDate: 2021-01-04 21:41:12 +0000
Commit:     Konstantin Belousov <kib at FreeBSD.org>
CommitDate: 2021-01-08 21:17:21 +0000

    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
---
 sys/compat/linuxkpi/common/src/linux_pci.c | 20 ++++++++++++++------
 sys/conf/kmod.mk                           |  1 +
 2 files changed, 15 insertions(+), 6 deletions(-)

diff --git a/sys/compat/linuxkpi/common/src/linux_pci.c b/sys/compat/linuxkpi/common/src/linux_pci.c
index 3fbe296a0f62..be61c2dba3d2 100644
--- a/sys/compat/linuxkpi/common/src/linux_pci.c
+++ b/sys/compat/linuxkpi/common/src/linux_pci.c
@@ -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);
diff --git a/sys/conf/kmod.mk b/sys/conf/kmod.mk
index dcc00829b831..b7ba121925ea 100644
--- a/sys/conf/kmod.mk
+++ b/sys/conf/kmod.mk
@@ -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 \


More information about the dev-commits-src-all mailing list