The branch main has been updated by bz:

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

commit 1fac2cb4d6e5cfa1b8ff689213011b0fe077ffa7
Author:     Bjoern A. Zeeb <[email protected]>
AuthorDate: 2021-01-28 16:23:19 +0000
Commit:     Bjoern A. Zeeb <[email protected]>
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;
_______________________________________________
[email protected] mailing list
https://lists.freebsd.org/mailman/listinfo/dev-commits-src-main
To unsubscribe, send any mail to "[email protected]"

Reply via email to