PERFORCE change 230855 for review

John Baldwin jhb at FreeBSD.org
Mon Jul 8 02:20:04 UTC 2013


http://p4web.freebsd.org/@@230855?ac=10

Change 230855 by jhb at jhb_fiver on 2013/07/08 02:19:27

	Merge pci_domain.c into pci_subr.c.

Affected files ...

.. //depot/projects/pci/sys/conf/files#12 edit
.. //depot/projects/pci/sys/dev/pci/pci_domain.c#14 delete
.. //depot/projects/pci/sys/dev/pci/pci_subr.c#6 edit

Differences ...

==== //depot/projects/pci/sys/conf/files#12 (text+ko) ====

@@ -1899,7 +1899,6 @@
 dev/pci/ignore_pci.c		optional pci
 dev/pci/isa_pci.c		optional pci isa
 dev/pci/pci.c			optional pci
-dev/pci/pci_domain.c		optional pci new_pcib
 dev/pci/pci_if.m		standard
 dev/pci/pci_pci.c		optional pci
 dev/pci/pci_subr.c		optional pci

==== //depot/projects/pci/sys/dev/pci/pci_subr.c#6 (text+ko) ====

@@ -151,7 +151,7 @@
 /*
  * Some Host-PCI bridge drivers know which resource ranges they can
  * decode and should only allocate subranges to child PCI devices.
- * This API provides a way to manage this.  The bridge drive should
+ * This API provides a way to manage this.  The bridge driver should
  * initialize this structure during attach and call
  * pcib_host_res_decodes() on each resource range it decodes.  It can
  * then use pcib_host_res_alloc() and pcib_host_res_adjust() as helper
@@ -282,4 +282,100 @@
 	}
 	return (ERANGE);
 }
+
+#ifdef PCI_RES_BUS
+struct pci_domain {
+	int	pd_domain;
+	struct rman pd_bus_rman;
+	TAILQ_ENTRY(pci_domain) pd_link;
+};
+
+static TAILQ_HEAD(, pci_domain) domains = TAILQ_HEAD_INITIALIZER(domains);
+
+/*
+ * Each PCI domain maintains its own resource manager for PCI bus
+ * numbers in that domain.  Domain objects are created on first use.
+ * Host to PCI bridge drivers and PCI-PCI bridge drivers should
+ * allocate their bus ranges from their domain.
+ */
+static struct pci_domain *
+pci_find_domain(int domain)
+{
+	struct pci_domain *d;
+	char buf[64];
+	int error;
+
+	TAILQ_FOREACH(d, &domains, pd_link) {
+		if (d->pd_domain == domain)
+			return (d);
+	}
+
+	snprintf(buf, sizeof(buf), "PCI domain %d", domain);
+	d = malloc(sizeof(*d) + strlen(buf) + 1, M_DEVBUF, M_WAITOK | M_ZERO);
+	d->pd_domain = domain;
+	d->pd_bus_rman.rm_start = 0;
+	d->pd_bus_rman.rm_end = PCI_BUSMAX;
+	d->pd_bus_rman.rm_type = RMAN_ARRAY;
+	strcpy((char *)(d + 1), buf);
+	d->pd_bus_rman.rm_descr = (char *)(d + 1);
+	error = rman_init(&d->pd_bus_rman);
+	if (error)
+		panic("Failed to initialize PCI domain %d rman", domain);
+	TAILQ_INSERT_TAIL(&domains, d, pd_link);
+	return (d);
+}
+
+struct resource *
+pci_domain_alloc_bus(int domain, device_t dev, int *rid, u_long start,
+    u_long end, u_long count, u_int flags)
+{
+	struct pci_domain *d;
+	struct resource *res;
+
+	if (domain < 0 || domain > PCI_DOMAINMAX)
+		return (NULL);
+	d = pci_find_domain(domain);
+	res = rman_reserve_resource(&d->pd_bus_rman, start, end, count, flags,
+	    dev);
+	if (res == NULL)
+		return (NULL);
+
+	rman_set_rid(res, *rid);
+	return (res);
+}
+
+int
+pci_domain_adjust_bus(int domain, device_t dev, struct resource *r,
+    u_long start, u_long end)
+{
+#ifdef INVARIANTS
+	struct pci_domain *d;
+#endif
+
+	if (domain < 0 || domain > PCI_DOMAINMAX)
+		return (EINVAL);
+#ifdef INVARIANTS
+	d = pci_find_domain(domain);
+	KASSERT(rman_is_region_manager(r, &d->pd_bus_rman), ("bad resource"));
+#endif
+	return (rman_adjust_resource(r, start, end));
+}
+
+int
+pci_domain_release_bus(int domain, device_t dev, int rid, struct resource *r)
+{
+#ifdef INVARIANTS
+	struct pci_domain *d;
+#endif
+
+	if (domain < 0 || domain > PCI_DOMAINMAX)
+		return (EINVAL);
+#ifdef INVARIANTS
+	d = pci_find_domain(domain);
+	KASSERT(rman_is_region_manager(r, &d->pd_bus_rman), ("bad resource"));
+#endif
+	return (rman_release_resource(r));
+}
+#endif /* PCI_RES_BUS */
+
 #endif /* NEW_PCIB */


More information about the p4-projects mailing list