Module Name: src Committed By: riastradh Date: Wed Jul 24 03:24:03 UTC 2013
Modified Files: src/sys/external/bsd/drm2/dist/include/drm [riastradh-drm2]: drmP.h src/sys/external/bsd/drm2/include/linux [riastradh-drm2]: pci.h src/sys/external/bsd/drm2/pci [riastradh-drm2]: drm_pci.c Log Message: Kludge up Linux PCI device shims. . New drm_pci_attach/drm_pci_detach simplify initialization of autoconf-derived struct pci_dev. . New linux_pci_dev_init initializes struct pci_dev so that there's one place where all its fields are listed. The kludge parameter is, well, kludgey. Sorry. . Replace pci_kludgey_find_dev by pci_get_bus_and_slot with the same interface as Linux's, but some kasserts requiring it to look for the one bus/device/function tuple that i915drm is interested in. . Add pci_get_class which does similarly, for intel_detect_pch. Later pci_get_bus_and_slot and pci_get_class should be fixed once we can pass a cookie through PCI bus enumeration and pci_find_device. To generate a diff of this commit: cvs rdiff -u -r1.1.1.1.2.48 -r1.1.1.1.2.49 \ src/sys/external/bsd/drm2/dist/include/drm/drmP.h cvs rdiff -u -r1.1.2.12 -r1.1.2.13 \ src/sys/external/bsd/drm2/include/linux/pci.h cvs rdiff -u -r1.1.2.1 -r1.1.2.2 src/sys/external/bsd/drm2/pci/drm_pci.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/external/bsd/drm2/dist/include/drm/drmP.h diff -u src/sys/external/bsd/drm2/dist/include/drm/drmP.h:1.1.1.1.2.48 src/sys/external/bsd/drm2/dist/include/drm/drmP.h:1.1.1.1.2.49 --- src/sys/external/bsd/drm2/dist/include/drm/drmP.h:1.1.1.1.2.48 Wed Jul 24 03:23:31 2013 +++ src/sys/external/bsd/drm2/dist/include/drm/drmP.h Wed Jul 24 03:24:03 2013 @@ -1830,6 +1830,11 @@ extern drm_dma_handle_t *drm_pci_alloc(s size_t align); extern void __drm_pci_free(struct drm_device *dev, drm_dma_handle_t * dmah); extern void drm_pci_free(struct drm_device *dev, drm_dma_handle_t * dmah); +#ifdef __NetBSD__ +extern void drm_pci_attach(device_t, const struct pci_attach_args *, + struct pci_dev *, struct drm_device *); +extern int drm_pci_detach(struct drm_device *, int); +#endif /* sysfs support (drm_sysfs.c) */ struct drm_sysfs_class; Index: src/sys/external/bsd/drm2/include/linux/pci.h diff -u src/sys/external/bsd/drm2/include/linux/pci.h:1.1.2.12 src/sys/external/bsd/drm2/include/linux/pci.h:1.1.2.13 --- src/sys/external/bsd/drm2/include/linux/pci.h:1.1.2.12 Wed Jul 24 03:20:05 2013 +++ src/sys/external/bsd/drm2/include/linux/pci.h Wed Jul 24 03:24:03 2013 @@ -1,4 +1,4 @@ -/* $NetBSD: pci.h,v 1.1.2.12 2013/07/24 03:20:05 riastradh Exp $ */ +/* $NetBSD: pci.h,v 1.1.2.13 2013/07/24 03:24:03 riastradh Exp $ */ /*- * Copyright (c) 2013 The NetBSD Foundation, Inc. @@ -59,10 +59,19 @@ struct pci_device_id { #define PCI_BASE_CLASS_DISPLAY PCI_CLASS_DISPLAY -#define PCI_CLASS_BRIDGE_ISA PCI_SUBCLASS_BRIDGE_ISA +#define PCI_CLASS_BRIDGE_ISA \ + ((PCI_CLASS_BRIDGE << 8) | PCI_SUBCLASS_BRIDGE_ISA) +CTASSERT(PCI_CLASS_BRIDGE_ISA == 0x0601); #define PCI_VENDOR_ID_INTEL PCI_VENDOR_INTEL +#define PCI_DEVFN(DEV, FN) \ + (__SHIFTIN((DEV), __BITS(3, 7)) | __SHIFTIN((FN), __BITS(0, 2))) +#define PCI_SLOT(DEVFN) __SHIFTOUT((DEVFN), __BITS(3, 7)) +#define PCI_FUNC(DEVFN) __SHIFTOUT((DEVFN), __BITS(0, 2)) + +#define PCI_CAP_ID_AGP PCI_CAP_AGP + struct pci_dev { struct pci_attach_args pd_pa; bool pd_kludged; /* XXX pci_kludgey_find_dev */ @@ -84,12 +93,26 @@ pci_dev_dev(struct pci_dev *pdev) return pdev->pd_dev; } -#define PCI_DEVFN(DEV, FN) \ - (__SHIFTIN((DEV), __BITS(3, 7)) | __SHIFTIN((FN), __BITS(0, 2))) -#define PCI_SLOT(DEVFN) __SHIFTOUT((DEVFN), __BITS(3, 7)) -#define PCI_FUNC(DEVFN) __SHIFTOUT((DEVFN), __BITS(0, 2)) +static inline void +linux_pci_dev_init(struct pci_dev *pdev, device_t dev, + const struct pci_attach_args *pa, bool kludged) +{ + const uint32_t subsystem_id = pci_conf_read(pa->pa_pc, pa->pa_tag, + PCI_SUBSYS_ID_REG); -#define PCI_CAP_ID_AGP PCI_CAP_AGP + pdev->pd_pa = *pa; + pdev->pd_kludged = kludged; + pdev->pd_dev = dev; + pdev->bus = NULL; /* XXX struct pci_dev::bus */ + pdev->devfn = PCI_DEVFN(pa->pa_device, pa->pa_function); + pdev->vendor = PCI_VENDOR(pa->pa_id); + pdev->device = PCI_PRODUCT(pa->pa_id); + pdev->subsystem_vendor = PCI_SUBSYS_VENDOR(subsystem_id); + pdev->subsystem_device = PCI_SUBSYS_ID(subsystem_id); + pdev->revision = PCI_REVISION(pa->pa_class); + pdev->class = __SHIFTOUT(pa->pa_class, 0xffffff00UL); /* ? */ + pdev->msi_enabled = false; +} static inline int pci_find_capability(struct pci_dev *pdev, int cap) @@ -230,35 +253,72 @@ pci_bus_alloc_resource(struct pci_bus *b } /* - * XXX Mega-kludgerific! - * - * XXX Doesn't check whether any such device actually exists. + * XXX Mega-kludgerific! pci_get_bus_and_slot and pci_get_class are + * defined only for their single purposes in i915drm, in + * i915_get_bridge_dev and intel_detect_pch. We can't define them more + * generally without adapting pci_find_device (and pci_enumerate_bus + * internally) to pass a cookie through. */ +static inline int /* XXX inline? */ +pci_kludgey_match_bus0_dev0_func0(const struct pci_attach_args *pa) +{ + + if (pa->pa_bus != 0) + return 0; + if (pa->pa_device != 0) + return 0; + if (pa->pa_function != 0) + return 0; + + return 1; +} + static inline struct pci_dev * -pci_kludgey_find_dev(struct pci_dev *pdev, int bus, int dev, int func) +pci_get_bus_and_slot(int bus, int slot) { - struct pci_dev *const otherdev = kmem_zalloc(sizeof(*otherdev), - KM_SLEEP); + struct pci_attach_args pa; -#ifdef DIAGNOSTIC - { - int obus, odev, ofunc; - - pci_decompose_tag(pdev->pd_pa.pa_pc, pdev->pd_pa.pa_tag, &obus, - &odev, &ofunc); - KASSERT(obus == bus); - } -#endif + KASSERT(bus == 0); + KASSERT(slot == PCI_DEVFN(0, 0)); + + if (!pci_find_device(&pa, &pci_kludgey_match_bus0_dev0_func0)) + return NULL; + + struct pci_dev *const pdev = kmem_zalloc(sizeof(*pdev), KM_SLEEP); + linux_pci_dev_init(pdev, NULL, &pa, true); + + return pdev; +} + +static inline int /* XXX inline? */ +pci_kludgey_match_isa_bridge(const struct pci_attach_args *pa) +{ + + if (PCI_CLASS(pa->pa_class) != PCI_CLASS_BRIDGE) + return 0; + if (PCI_SUBCLASS(pa->pa_class) != PCI_SUBCLASS_BRIDGE_ISA) + return 0; + + return 1; +} + +static inline struct pci_dev * +pci_get_class(uint32_t class_subclass_shifted __unused, + struct pci_dev *from __unused) +{ + struct pci_attach_args pa; + + KASSERT(class_subclass_shifted == (PCI_CLASS_BRIDGE_ISA << 8)); + KASSERT(from == NULL); + + if (!pci_find_device(&pa, &pci_kludgey_match_isa_bridge)) + return NULL; - otherdev->bus = NULL; /* XXX struct pci_dev::bus */ - otherdev->device = dev; - otherdev->pd_pa = pdev->pd_pa; - otherdev->pd_pa.pa_tag = pci_make_tag(otherdev->pd_pa.pa_pc, - bus, dev, func); - otherdev->pd_kludged = true; + struct pci_dev *const pdev = kmem_zalloc(sizeof(*pdev), KM_SLEEP); + linux_pci_dev_init(pdev, NULL, &pa, true); - return otherdev; + return pdev; } static inline void Index: src/sys/external/bsd/drm2/pci/drm_pci.c diff -u src/sys/external/bsd/drm2/pci/drm_pci.c:1.1.2.1 src/sys/external/bsd/drm2/pci/drm_pci.c:1.1.2.2 --- src/sys/external/bsd/drm2/pci/drm_pci.c:1.1.2.1 Wed Jul 24 02:35:07 2013 +++ src/sys/external/bsd/drm2/pci/drm_pci.c Wed Jul 24 03:24:03 2013 @@ -1,4 +1,4 @@ -/* $NetBSD: drm_pci.c,v 1.1.2.1 2013/07/24 02:35:07 riastradh Exp $ */ +/* $NetBSD: drm_pci.c,v 1.1.2.2 2013/07/24 03:24:03 riastradh Exp $ */ /*- * Copyright (c) 2013 The NetBSD Foundation, Inc. @@ -30,7 +30,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: drm_pci.c,v 1.1.2.1 2013/07/24 02:35:07 riastradh Exp $"); +__KERNEL_RCSID(0, "$NetBSD: drm_pci.c,v 1.1.2.2 2013/07/24 03:24:03 riastradh Exp $"); #include <sys/types.h> #include <sys/errno.h> @@ -73,6 +73,28 @@ drm_pci_attach_args(struct drm_device *d return &dev->pdev->pd_pa; } +void +drm_pci_attach(device_t self, const struct pci_attach_args *pa, + struct pci_dev *pdev, struct drm_device *dev) +{ + + linux_pci_dev_init(pdev, self, pa, false); + + dev->pdev = pdev; + dev->pci_vendor = pdev->vendor; + dev->pci_device = pdev->device; + + /* XXX Set the power state to D0? */ +} + +int +drm_pci_detach(struct drm_device *dev __unused, int flags __unused) +{ + + /* XXX Disestablish irqs or anything? */ + return 0; +} + static int drm_pci_get_irq(struct drm_device *dev) {