Module Name: src
Committed By: riastradh
Date: Sun Jun 23 00:53:48 UTC 2024
Modified Files:
src/sys/external/bsd/drm2/linux: linux_pci.c
Log Message:
linux_pci: Nix pci enumeration kludges.
Now that we can pass a cookie through, this stuff will be a little
less fragile.
To generate a diff of this commit:
cvs rdiff -u -r1.28 -r1.29 src/sys/external/bsd/drm2/linux/linux_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/linux/linux_pci.c
diff -u src/sys/external/bsd/drm2/linux/linux_pci.c:1.28 src/sys/external/bsd/drm2/linux/linux_pci.c:1.29
--- src/sys/external/bsd/drm2/linux/linux_pci.c:1.28 Sun May 19 17:36:08 2024
+++ src/sys/external/bsd/drm2/linux/linux_pci.c Sun Jun 23 00:53:48 2024
@@ -1,4 +1,4 @@
-/* $NetBSD: linux_pci.c,v 1.28 2024/05/19 17:36:08 riastradh Exp $ */
+/* $NetBSD: linux_pci.c,v 1.29 2024/06/23 00:53:48 riastradh Exp $ */
/*-
* Copyright (c) 2013 The NetBSD Foundation, Inc.
@@ -35,7 +35,7 @@
#endif
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: linux_pci.c,v 1.28 2024/05/19 17:36:08 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: linux_pci.c,v 1.29 2024/06/23 00:53:48 riastradh Exp $");
#if NACPICA > 0
#include <dev/acpi/acpivar.h>
@@ -573,24 +573,20 @@ pci_bus_alloc_resource(struct pci_bus *b
return 0;
}
-/*
- * 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.
- */
+struct pci_domain_bus_and_slot {
+ int domain, bus, slot;
+};
static int
-pci_kludgey_match_bus0_dev0_func0(const struct pci_attach_args *pa)
+pci_match_domain_bus_and_slot(void *cookie, const struct pci_attach_args *pa)
{
+ const struct pci_domain_bus_and_slot *C = cookie;
- /* XXX domain */
- if (pa->pa_bus != 0)
+ if (pci_get_segment(pa->pa_pc) != C->domain)
return 0;
- if (pa->pa_device != 0)
+ if (pa->pa_bus != C->bus)
return 0;
- if (pa->pa_function != 0)
+ if (PCI_DEVFN(pa->pa_device, pa->pa_function) != C->slot)
return 0;
return 1;
@@ -600,12 +596,10 @@ struct pci_dev *
pci_get_domain_bus_and_slot(int domain, int bus, int slot)
{
struct pci_attach_args pa;
+ struct pci_domain_bus_and_slot context = {domain, bus, slot},
+ *C = &context;
- KASSERT(domain == 0);
- KASSERT(bus == 0);
- KASSERT(slot == PCI_DEVFN(0, 0));
-
- if (!pci_find_device(&pa, &pci_kludgey_match_bus0_dev0_func0))
+ if (!pci_find_device1(&pa, &pci_match_domain_bus_and_slot, C))
return NULL;
struct pci_dev *const pdev = kmem_zalloc(sizeof(*pdev), KM_SLEEP);
@@ -614,101 +608,59 @@ pci_get_domain_bus_and_slot(int domain,
return pdev;
}
-static int
-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 int
-pci_kludgey_match_other_display(const struct pci_attach_args *pa)
+void
+pci_dev_put(struct pci_dev *pdev)
{
- if (PCI_CLASS(pa->pa_class) != PCI_CLASS_DISPLAY)
- return 0;
- if (PCI_SUBCLASS(pa->pa_class) != PCI_SUBCLASS_DISPLAY_MISC)
- return 0;
+ if (pdev == NULL)
+ return;
- return 1;
+ KASSERT(ISSET(pdev->pd_kludges, NBPCI_KLUDGE_GET_MUMBLE));
+ kmem_free(pdev->bus, sizeof(*pdev->bus));
+ kmem_free(pdev, sizeof(*pdev));
}
-static int
-pci_kludgey_match_vga_display(const struct pci_attach_args *pa)
-{
-
- if (PCI_CLASS(pa->pa_class) != PCI_CLASS_DISPLAY)
- return 0;
- if (PCI_SUBCLASS(pa->pa_class) != PCI_SUBCLASS_DISPLAY_VGA)
- return 0;
-
- return 1;
-}
+struct pci_get_class_state {
+ uint32_t class_subclass_shifted;
+ const struct pci_dev *from;
+};
static int
-pci_kludgey_match_3d_display(const struct pci_attach_args *pa)
+pci_get_class_match(void *cookie, const struct pci_attach_args *pa)
{
+ struct pci_get_class_state *C = cookie;
- if (PCI_CLASS(pa->pa_class) != PCI_CLASS_DISPLAY)
+ if (C->from) {
+ if ((pci_get_segment(C->from->pd_pa.pa_pc) ==
+ pci_get_segment(pa->pa_pc)) &&
+ C->from->pd_pa.pa_bus == pa->pa_bus &&
+ C->from->pd_pa.pa_device == pa->pa_device &&
+ C->from->pd_pa.pa_function == pa->pa_function)
+ C->from = NULL;
return 0;
- if (PCI_SUBCLASS(pa->pa_class) != PCI_SUBCLASS_DISPLAY_3D)
+ }
+ if (C->class_subclass_shifted !=
+ (PCI_CLASS(pa->pa_class) << 8 | PCI_SUBCLASS(pa->pa_class)))
return 0;
return 1;
}
-void
-pci_dev_put(struct pci_dev *pdev)
-{
-
- if (pdev == NULL)
- return;
-
- KASSERT(ISSET(pdev->pd_kludges, NBPCI_KLUDGE_GET_MUMBLE));
- kmem_free(pdev->bus, sizeof(*pdev->bus));
- kmem_free(pdev, sizeof(*pdev));
-}
-
-struct pci_dev * /* XXX i915/amdgpu kludge */
+struct pci_dev *
pci_get_class(uint32_t class_subclass_shifted, struct pci_dev *from)
{
+ struct pci_get_class_state context = {class_subclass_shifted, from},
+ *C = &context;
struct pci_attach_args pa;
+ struct pci_dev *pdev = NULL;
- if (from != NULL) {
- pci_dev_put(from);
- return NULL;
- }
-
- switch (class_subclass_shifted) {
- case PCI_CLASS_BRIDGE_ISA << 8:
- if (!pci_find_device(&pa, &pci_kludgey_match_isa_bridge))
- return NULL;
- break;
- case PCI_CLASS_DISPLAY_OTHER << 8:
- if (!pci_find_device(&pa, &pci_kludgey_match_other_display))
- return NULL;
- break;
- case PCI_CLASS_DISPLAY_VGA << 8:
- if (!pci_find_device(&pa, &pci_kludgey_match_vga_display))
- return NULL;
- break;
- case PCI_CLASS_DISPLAY_3D << 8:
- if (!pci_find_device(&pa, &pci_kludgey_match_3d_display))
- return NULL;
- break;
- default:
- panic("unknown pci_get_class: %"PRIx32,
- class_subclass_shifted);
- }
-
- struct pci_dev *const pdev = kmem_zalloc(sizeof(*pdev), KM_SLEEP);
+ if (!pci_find_device1(&pa, &pci_get_class_match, C))
+ goto out;
+ pdev = kmem_zalloc(sizeof(*pdev), KM_SLEEP);
linux_pci_dev_init(pdev, NULL, NULL, &pa, NBPCI_KLUDGE_GET_MUMBLE);
+out: if (from)
+ pci_dev_put(from);
return pdev;
}