Date: Thu, 28 Jan 2021 16:46:00 GMT From: "Bjoern A. Zeeb" <bz@FreeBSD.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org Subject: git: 1fac2cb4d6e5 - main - LinuxKPI: enhance PCI bits for DRM Message-ID: <202101281646.10SGk0aL088837@gitrepo.freebsd.org>
next in thread | raw e-mail | index | archive | help
The branch main has been updated by bz: URL: https://cgit.FreeBSD.org/src/commit/?id=1fac2cb4d6e5cfa1b8ff689213011b0fe077ffa7 commit 1fac2cb4d6e5cfa1b8ff689213011b0fe077ffa7 Author: Bjoern A. Zeeb <bz@FreeBSD.org> AuthorDate: 2021-01-28 16:23:19 +0000 Commit: Bjoern A. Zeeb <bz@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;
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202101281646.10SGk0aL088837>