git: 1fac2cb4d6e5 - main - LinuxKPI: enhance PCI bits for DRM

Bjoern A. Zeeb bz at FreeBSD.org
Thu Jan 28 16:46:00 UTC 2021


The branch main has been updated by bz:

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

commit 1fac2cb4d6e5cfa1b8ff689213011b0fe077ffa7
Author:     Bjoern A. Zeeb <bz at FreeBSD.org>
AuthorDate: 2021-01-28 16:23:19 +0000
Commit:     Bjoern A. Zeeb <bz at FreeBSD.org>
CommitDate: 2021-01-28 16:23:19 +0000

    LinuxKPI: enhance PCI bits for DRM
    
    In pci_domain_nr() directly return the domain which got set in
    lkpifill_pci_dev() in all cases.  This was missed between D27550
    and 105a37cac76b971f7a94409fbdc4f508a7e97fa0 .
    
    In order to implement pci_dev_put() harmonize further code
    (which was started in the aforementioned commit) and add kobj
    related bits (through the now common lkpifill_pci_dev() code)
    to the DRM specific calls without adding the DRM allocated
    pci devices to the pci_devices list.
    Add a release for the lkpinew_pci_dev() (DRM) case so freeing
    will work.
    This allows the DRM created devices to use the normal kobj/refcount
    logic and work with, e.g., pci_dev_put().
    (For a slightly more detailed code walk see the review).
    
    Sponsored-by:   The FreeBSD Foundation
    Obtained-from:  bz_iwlwifi (partially)
    MFC after:      3 days
    Differential Revision:  https://reviews.freebsd.org/D28188
---
 sys/compat/linuxkpi/common/include/linux/pci.h | 10 +++++-
 sys/compat/linuxkpi/common/src/linux_pci.c     | 42 +++++++++++++++-----------
 2 files changed, 33 insertions(+), 19 deletions(-)

diff --git a/sys/compat/linuxkpi/common/include/linux/pci.h b/sys/compat/linuxkpi/common/include/linux/pci.h
index 6338f5795f0a..ddb3f0b222a5 100644
--- a/sys/compat/linuxkpi/common/include/linux/pci.h
+++ b/sys/compat/linuxkpi/common/include/linux/pci.h
@@ -338,6 +338,14 @@ pci_set_drvdata(struct pci_dev *pdev, void *data)
 	dev_set_drvdata(&pdev->dev, data);
 }
 
+static __inline void
+pci_dev_put(struct pci_dev *pdev)
+{
+
+	if (pdev != NULL)
+		put_device(&pdev->dev);
+}
+
 static inline int
 pci_enable_device(struct pci_dev *pdev)
 {
@@ -1094,7 +1102,7 @@ static inline int
 pci_domain_nr(struct pci_bus *pbus)
 {
 
-	return (pci_get_domain(pbus->self->dev.bsddev));
+	return (pbus->domain);
 }
 
 static inline int
diff --git a/sys/compat/linuxkpi/common/src/linux_pci.c b/sys/compat/linuxkpi/common/src/linux_pci.c
index 0e184b64884b..075df3c2adf7 100644
--- a/sys/compat/linuxkpi/common/src/linux_pci.c
+++ b/sys/compat/linuxkpi/common/src/linux_pci.c
@@ -220,24 +220,42 @@ lkpifill_pci_dev(device_t dev, struct pci_dev *pdev)
 	pdev->devfn = PCI_DEVFN(pci_get_slot(dev), pci_get_function(dev));
 	pdev->vendor = pci_get_vendor(dev);
 	pdev->device = pci_get_device(dev);
+	pdev->subsystem_vendor = pci_get_subvendor(dev);
+	pdev->subsystem_device = pci_get_subdevice(dev);
 	pdev->class = pci_get_class(dev);
 	pdev->revision = pci_get_revid(dev);
-	pdev->dev.bsddev = dev;
+	pdev->bus = malloc(sizeof(*pdev->bus), M_DEVBUF, M_WAITOK | M_ZERO);
 	pdev->bus->self = pdev;
 	pdev->bus->number = pci_get_bus(dev);
 	pdev->bus->domain = pci_get_domain(dev);
+	pdev->dev.bsddev = dev;
+	pdev->dev.parent = &linux_root_device;
+	INIT_LIST_HEAD(&pdev->dev.irqents);
+	kobject_init(&pdev->dev.kobj, &linux_dev_ktype);
+	kobject_set_name(&pdev->dev.kobj, device_get_nameunit(dev));
+	kobject_add(&pdev->dev.kobj, &linux_root_device.kobj,
+	    kobject_name(&pdev->dev.kobj));
+}
+
+static void
+lkpinew_pci_dev_release(struct device *dev)
+{
+	struct pci_dev *pdev;
+
+	pdev = to_pci_dev(dev);
+	free(pdev->bus, M_DEVBUF);
+	free(pdev, M_DEVBUF);
 }
 
 static struct pci_dev *
 lkpinew_pci_dev(device_t dev)
 {
 	struct pci_dev *pdev;
-	struct pci_bus *pbus;
 
 	pdev = malloc(sizeof(*pdev), M_DEVBUF, M_WAITOK|M_ZERO);
-	pbus = malloc(sizeof(*pbus), M_DEVBUF, M_WAITOK|M_ZERO);
-	pdev->bus = pbus;
 	lkpifill_pci_dev(dev, pdev);
+	pdev->dev.release = lkpinew_pci_dev_release;
+
 	return (pdev);
 }
 
@@ -309,7 +327,6 @@ linux_pci_attach_device(device_t dev, struct pci_driver *pdrv,
     const struct pci_device_id *id, struct pci_dev *pdev)
 {
 	struct resource_list_entry *rle;
-	struct pci_devinfo *dinfo;
 	device_t parent;
 	uintptr_t rid;
 	int error;
@@ -321,30 +338,19 @@ linux_pci_attach_device(device_t dev, struct pci_driver *pdrv,
 	isdrm = pdrv != NULL && pdrv->isdrm;
 
 	if (isdrm) {
+		struct pci_devinfo *dinfo;
+
 		dinfo = device_get_ivars(parent);
 		device_set_ivars(dev, dinfo);
-	} else {
-		dinfo = device_get_ivars(dev);
 	}
 
-	pdev->bus = malloc(sizeof(*pdev->bus), M_DEVBUF, M_WAITOK | M_ZERO);
 	lkpifill_pci_dev(dev, pdev);
-	pdev->dev.parent = &linux_root_device;
-	INIT_LIST_HEAD(&pdev->dev.irqents);
 	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;
-	pdev->subsystem_device = dinfo->cfg.subdevice;
 	pdev->pdrv = pdrv;
-	kobject_init(&pdev->dev.kobj, &linux_dev_ktype);
-	kobject_set_name(&pdev->dev.kobj, device_get_nameunit(dev));
-	kobject_add(&pdev->dev.kobj, &linux_root_device.kobj,
-	    kobject_name(&pdev->dev.kobj));
 	rle = linux_pci_get_rle(pdev, SYS_RES_IRQ, 0);
 	if (rle != NULL)
 		pdev->dev.irq = rle->start;


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