From owner-svn-src-all@freebsd.org Fri Aug 11 03:59:50 2017 Return-Path: Delivered-To: svn-src-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 3EA10D928F6; Fri, 11 Aug 2017 03:59:50 +0000 (UTC) (envelope-from markj@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 18D6B8316C; Fri, 11 Aug 2017 03:59:50 +0000 (UTC) (envelope-from markj@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id v7B3xnsq064491; Fri, 11 Aug 2017 03:59:49 GMT (envelope-from markj@FreeBSD.org) Received: (from markj@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id v7B3xnl4064488; Fri, 11 Aug 2017 03:59:49 GMT (envelope-from markj@FreeBSD.org) Message-Id: <201708110359.v7B3xnl4064488@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: markj set sender to markj@FreeBSD.org using -f From: Mark Johnston Date: Fri, 11 Aug 2017 03:59:48 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r322392 - in head/sys/compat/linuxkpi/common: include/linux src X-SVN-Group: head X-SVN-Commit-Author: markj X-SVN-Commit-Paths: in head/sys/compat/linuxkpi/common: include/linux src X-SVN-Commit-Revision: 322392 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 11 Aug 2017 03:59:50 -0000 Author: markj Date: Fri Aug 11 03:59:48 2017 New Revision: 322392 URL: https://svnweb.freebsd.org/changeset/base/322392 Log: Add a specialized function for DRM drivers to register themselves. Such drivers attach to a vgapci bus rather than directly to a pci bus. For the rest of the LinuxKPI to work correctly in this case, we override the vgapci bus' ivars with those of the grandparent. Reviewed by: hselasky MFC after: 1 week Differential Revision: https://reviews.freebsd.org/D11932 Modified: head/sys/compat/linuxkpi/common/include/linux/pci.h head/sys/compat/linuxkpi/common/src/linux_pci.c Modified: head/sys/compat/linuxkpi/common/include/linux/pci.h ============================================================================== --- head/sys/compat/linuxkpi/common/include/linux/pci.h Fri Aug 11 03:09:11 2017 (r322391) +++ head/sys/compat/linuxkpi/common/include/linux/pci.h Fri Aug 11 03:59:48 2017 (r322392) @@ -187,8 +187,14 @@ struct pci_driver { devclass_t bsdclass; struct device_driver driver; const struct pci_error_handlers *err_handler; + bool isdrm; }; +struct pci_bus { + struct pci_dev *self; + int number; +}; + extern struct list_head pci_drivers; extern struct list_head pci_devices; extern spinlock_t pci_lock; @@ -199,6 +205,7 @@ struct pci_dev { struct device dev; struct list_head links; struct pci_driver *pdrv; + struct pci_bus *bus; uint64_t dma_mask; uint16_t device; uint16_t vendor; @@ -502,8 +509,12 @@ pci_write_config_dword(struct pci_dev *pdev, int where return (0); } -extern int pci_register_driver(struct pci_driver *pdrv); -extern void pci_unregister_driver(struct pci_driver *pdrv); +int linux_pci_register_driver(struct pci_driver *pdrv); +int linux_pci_register_drm_driver(struct pci_driver *pdrv); +void linux_pci_unregister_driver(struct pci_driver *pdrv); + +#define pci_register_driver(pdrv) linux_pci_register_driver(pdrv) +#define pci_unregister_driver(pdrv) linux_pci_unregister_driver(pdrv) struct msix_entry { int entry; Modified: head/sys/compat/linuxkpi/common/src/linux_pci.c ============================================================================== --- head/sys/compat/linuxkpi/common/src/linux_pci.c Fri Aug 11 03:09:11 2017 (r322391) +++ head/sys/compat/linuxkpi/common/src/linux_pci.c Fri Aug 11 03:59:48 2017 (r322392) @@ -118,17 +118,29 @@ static int linux_pci_attach(device_t dev) { struct resource_list_entry *rle; + struct pci_bus *pbus; struct pci_dev *pdev; struct pci_devinfo *dinfo; struct pci_driver *pdrv; const struct pci_device_id *id; + device_t parent; + devclass_t devclass; int error; - dinfo = device_get_ivars(dev); - linux_set_current(curthread); + pdrv = linux_pci_find(dev, &id); pdev = device_get_softc(dev); + + parent = device_get_parent(dev); + devclass = device_get_devclass(parent); + if (pdrv->isdrm) { + dinfo = device_get_ivars(parent); + device_set_ivars(dev, dinfo); + } else { + dinfo = device_get_ivars(dev); + } + pdev->dev.parent = &linux_root_device; pdev->dev.bsddev = dev; INIT_LIST_HEAD(&pdev->dev.irqents); @@ -151,6 +163,13 @@ linux_pci_attach(device_t dev) else pdev->dev.irq = LINUX_IRQ_INVALID; pdev->irq = pdev->dev.irq; + + if (pdev->bus == NULL) { + pbus = malloc(sizeof(*pbus), M_DEVBUF, M_WAITOK | M_ZERO); + pbus->self = pdev; + pdev->bus = pbus; + } + DROP_GIANT(); spin_lock(&pci_lock); list_add(&pdev->links, &pci_devices); @@ -246,14 +265,11 @@ linux_pci_shutdown(device_t dev) return (0); } -int -pci_register_driver(struct pci_driver *pdrv) +static int +_linux_pci_register_driver(struct pci_driver *pdrv, devclass_t dc) { - devclass_t bus; - int error = 0; + int error; - bus = devclass_find("pci"); - linux_set_current(curthread); spin_lock(&pci_lock); list_add(&pdrv->links, &pci_drivers); @@ -263,16 +279,39 @@ pci_register_driver(struct pci_driver *pdrv) pdrv->bsddriver.size = sizeof(struct pci_dev); mtx_lock(&Giant); - if (bus != NULL) { - error = devclass_add_driver(bus, &pdrv->bsddriver, - BUS_PASS_DEFAULT, &pdrv->bsdclass); - } + error = devclass_add_driver(dc, &pdrv->bsddriver, + BUS_PASS_DEFAULT, &pdrv->bsdclass); mtx_unlock(&Giant); return (-error); } +int +linux_pci_register_driver(struct pci_driver *pdrv) +{ + devclass_t dc; + + dc = devclass_find("pci"); + if (dc == NULL) + return (-ENXIO); + pdrv->isdrm = false; + return (_linux_pci_register_driver(pdrv, dc)); +} + +int +linux_pci_register_drm_driver(struct pci_driver *pdrv) +{ + devclass_t dc; + + dc = devclass_create("vgapci"); + if (dc == NULL) + return (-ENXIO); + pdrv->isdrm = true; + pdrv->name = "drmn"; + return (_linux_pci_register_driver(pdrv, dc)); +} + void -pci_unregister_driver(struct pci_driver *pdrv) +linux_pci_unregister_driver(struct pci_driver *pdrv) { devclass_t bus;