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;
 }
 

Reply via email to