Date: Mon, 8 Jul 2013 02:20:03 GMT From: John Baldwin <jhb@FreeBSD.org> To: Perforce Change Reviews <perforce@FreeBSD.org> Subject: PERFORCE change 230855 for review Message-ID: <201307080220.r682K3mb025996@skunkworks.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://p4web.freebsd.org/@@230855?ac=10 Change 230855 by jhb@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 */
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201307080220.r682K3mb025996>
