10dbe859dSJohn Baldwin /*- 2179fa75eSJohn Baldwin * Copyright (c) 2011 Hudson River Trading LLC 30dbe859dSJohn Baldwin * Written by: John H. Baldwin <jhb@FreeBSD.org> 40dbe859dSJohn Baldwin * All rights reserved. 50dbe859dSJohn Baldwin * 60dbe859dSJohn Baldwin * Redistribution and use in source and binary forms, with or without 70dbe859dSJohn Baldwin * modification, are permitted provided that the following conditions 80dbe859dSJohn Baldwin * are met: 90dbe859dSJohn Baldwin * 1. Redistributions of source code must retain the above copyright 100dbe859dSJohn Baldwin * notice, this list of conditions and the following disclaimer. 110dbe859dSJohn Baldwin * 2. Redistributions in binary form must reproduce the above copyright 120dbe859dSJohn Baldwin * notice, this list of conditions and the following disclaimer in the 130dbe859dSJohn Baldwin * documentation and/or other materials provided with the distribution. 140dbe859dSJohn Baldwin * 150dbe859dSJohn Baldwin * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 160dbe859dSJohn Baldwin * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 170dbe859dSJohn Baldwin * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 180dbe859dSJohn Baldwin * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 190dbe859dSJohn Baldwin * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 200dbe859dSJohn Baldwin * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 210dbe859dSJohn Baldwin * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 220dbe859dSJohn Baldwin * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 230dbe859dSJohn Baldwin * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 240dbe859dSJohn Baldwin * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 250dbe859dSJohn Baldwin * SUCH DAMAGE. 260dbe859dSJohn Baldwin */ 270dbe859dSJohn Baldwin 280dbe859dSJohn Baldwin #include <sys/cdefs.h> 290dbe859dSJohn Baldwin __FBSDID("$FreeBSD$"); 300dbe859dSJohn Baldwin 310dbe859dSJohn Baldwin /* 320dbe859dSJohn Baldwin * Support APIs for Host to PCI bridge drivers and drivers that 330dbe859dSJohn Baldwin * provide PCI domains. 340dbe859dSJohn Baldwin */ 350dbe859dSJohn Baldwin 3634ff71eeSJohn Baldwin #include <sys/param.h> 370dbe859dSJohn Baldwin #include <sys/bus.h> 384edef187SJohn Baldwin #include <sys/malloc.h> 390dbe859dSJohn Baldwin #include <sys/rman.h> 4034ff71eeSJohn Baldwin #include <sys/systm.h> 410dbe859dSJohn Baldwin 420dbe859dSJohn Baldwin #include <dev/pci/pcireg.h> 430dbe859dSJohn Baldwin #include <dev/pci/pcivar.h> 440dbe859dSJohn Baldwin #include <dev/pci/pcib_private.h> 450dbe859dSJohn Baldwin 460dbe859dSJohn Baldwin /* 470dbe859dSJohn Baldwin * Try to read the bus number of a host-PCI bridge using appropriate config 480dbe859dSJohn Baldwin * registers. 490dbe859dSJohn Baldwin */ 500dbe859dSJohn Baldwin int 510dbe859dSJohn Baldwin host_pcib_get_busno(pci_read_config_fn read_config, int bus, int slot, int func, 520dbe859dSJohn Baldwin uint8_t *busnum) 530dbe859dSJohn Baldwin { 540dbe859dSJohn Baldwin uint32_t id; 550dbe859dSJohn Baldwin 560dbe859dSJohn Baldwin id = read_config(bus, slot, func, PCIR_DEVVENDOR, 4); 570dbe859dSJohn Baldwin if (id == 0xffffffff) 580dbe859dSJohn Baldwin return (0); 590dbe859dSJohn Baldwin 600dbe859dSJohn Baldwin switch (id) { 610dbe859dSJohn Baldwin case 0x12258086: 620dbe859dSJohn Baldwin /* Intel 824?? */ 630dbe859dSJohn Baldwin /* XXX This is a guess */ 640dbe859dSJohn Baldwin /* *busnum = read_config(bus, slot, func, 0x41, 1); */ 650dbe859dSJohn Baldwin *busnum = bus; 660dbe859dSJohn Baldwin break; 670dbe859dSJohn Baldwin case 0x84c48086: 680dbe859dSJohn Baldwin /* Intel 82454KX/GX (Orion) */ 690dbe859dSJohn Baldwin *busnum = read_config(bus, slot, func, 0x4a, 1); 700dbe859dSJohn Baldwin break; 710dbe859dSJohn Baldwin case 0x84ca8086: 720dbe859dSJohn Baldwin /* 730dbe859dSJohn Baldwin * For the 450nx chipset, there is a whole bundle of 740dbe859dSJohn Baldwin * things pretending to be host bridges. The MIOC will 750dbe859dSJohn Baldwin * be seen first and isn't really a pci bridge (the 76*db4fcadfSConrad Meyer * actual buses are attached to the PXB's). We need to 770dbe859dSJohn Baldwin * read the registers of the MIOC to figure out the 780dbe859dSJohn Baldwin * bus numbers for the PXB channels. 790dbe859dSJohn Baldwin * 800dbe859dSJohn Baldwin * Since the MIOC doesn't have a pci bus attached, we 810dbe859dSJohn Baldwin * pretend it wasn't there. 820dbe859dSJohn Baldwin */ 830dbe859dSJohn Baldwin return (0); 840dbe859dSJohn Baldwin case 0x84cb8086: 850dbe859dSJohn Baldwin switch (slot) { 860dbe859dSJohn Baldwin case 0x12: 870dbe859dSJohn Baldwin /* Intel 82454NX PXB#0, Bus#A */ 880dbe859dSJohn Baldwin *busnum = read_config(bus, 0x10, func, 0xd0, 1); 890dbe859dSJohn Baldwin break; 900dbe859dSJohn Baldwin case 0x13: 910dbe859dSJohn Baldwin /* Intel 82454NX PXB#0, Bus#B */ 920dbe859dSJohn Baldwin *busnum = read_config(bus, 0x10, func, 0xd1, 1) + 1; 930dbe859dSJohn Baldwin break; 940dbe859dSJohn Baldwin case 0x14: 950dbe859dSJohn Baldwin /* Intel 82454NX PXB#1, Bus#A */ 960dbe859dSJohn Baldwin *busnum = read_config(bus, 0x10, func, 0xd3, 1); 970dbe859dSJohn Baldwin break; 980dbe859dSJohn Baldwin case 0x15: 990dbe859dSJohn Baldwin /* Intel 82454NX PXB#1, Bus#B */ 1000dbe859dSJohn Baldwin *busnum = read_config(bus, 0x10, func, 0xd4, 1) + 1; 1010dbe859dSJohn Baldwin break; 1020dbe859dSJohn Baldwin } 1030dbe859dSJohn Baldwin break; 1040dbe859dSJohn Baldwin 1050dbe859dSJohn Baldwin /* ServerWorks -- vendor 0x1166 */ 1060dbe859dSJohn Baldwin case 0x00051166: 1070dbe859dSJohn Baldwin case 0x00061166: 1080dbe859dSJohn Baldwin case 0x00081166: 1090dbe859dSJohn Baldwin case 0x00091166: 1100dbe859dSJohn Baldwin case 0x00101166: 1110dbe859dSJohn Baldwin case 0x00111166: 1120dbe859dSJohn Baldwin case 0x00171166: 1130dbe859dSJohn Baldwin case 0x01011166: 1140dbe859dSJohn Baldwin case 0x010f1014: 1150dbe859dSJohn Baldwin case 0x01101166: 1160dbe859dSJohn Baldwin case 0x02011166: 1170dbe859dSJohn Baldwin case 0x02251166: 1180dbe859dSJohn Baldwin case 0x03021014: 1190dbe859dSJohn Baldwin *busnum = read_config(bus, slot, func, 0x44, 1); 1200dbe859dSJohn Baldwin break; 1210dbe859dSJohn Baldwin 1220dbe859dSJohn Baldwin /* Compaq/HP -- vendor 0x0e11 */ 1230dbe859dSJohn Baldwin case 0x60100e11: 1240dbe859dSJohn Baldwin *busnum = read_config(bus, slot, func, 0xc8, 1); 1250dbe859dSJohn Baldwin break; 1260dbe859dSJohn Baldwin default: 1270dbe859dSJohn Baldwin /* Don't know how to read bus number. */ 1280dbe859dSJohn Baldwin return 0; 1290dbe859dSJohn Baldwin } 1300dbe859dSJohn Baldwin 1310dbe859dSJohn Baldwin return 1; 1320dbe859dSJohn Baldwin } 13334ff71eeSJohn Baldwin 13434ff71eeSJohn Baldwin #ifdef NEW_PCIB 13534ff71eeSJohn Baldwin /* 13634ff71eeSJohn Baldwin * Return a pointer to a pretty name for a PCI device. If the device 13734ff71eeSJohn Baldwin * has a driver attached, the device's name is used, otherwise a name 13834ff71eeSJohn Baldwin * is generated from the device's PCI address. 13934ff71eeSJohn Baldwin */ 14034ff71eeSJohn Baldwin const char * 14134ff71eeSJohn Baldwin pcib_child_name(device_t child) 14234ff71eeSJohn Baldwin { 14334ff71eeSJohn Baldwin static char buf[64]; 14434ff71eeSJohn Baldwin 14534ff71eeSJohn Baldwin if (device_get_nameunit(child) != NULL) 14634ff71eeSJohn Baldwin return (device_get_nameunit(child)); 14734ff71eeSJohn Baldwin snprintf(buf, sizeof(buf), "pci%d:%d:%d:%d", pci_get_domain(child), 14834ff71eeSJohn Baldwin pci_get_bus(child), pci_get_slot(child), pci_get_function(child)); 14934ff71eeSJohn Baldwin return (buf); 15034ff71eeSJohn Baldwin } 15134ff71eeSJohn Baldwin 15234ff71eeSJohn Baldwin /* 15334ff71eeSJohn Baldwin * Some Host-PCI bridge drivers know which resource ranges they can 15434ff71eeSJohn Baldwin * decode and should only allocate subranges to child PCI devices. 155e0c34b57SJohn Baldwin * This API provides a way to manage this. The bridge driver should 15634ff71eeSJohn Baldwin * initialize this structure during attach and call 15734ff71eeSJohn Baldwin * pcib_host_res_decodes() on each resource range it decodes. It can 15834ff71eeSJohn Baldwin * then use pcib_host_res_alloc() and pcib_host_res_adjust() as helper 15934ff71eeSJohn Baldwin * routines for BUS_ALLOC_RESOURCE() and BUS_ADJUST_RESOURCE(). This 16034ff71eeSJohn Baldwin * API assumes that resources for any decoded ranges can be safely 16134ff71eeSJohn Baldwin * allocated from the parent via bus_generic_alloc_resource(). 16234ff71eeSJohn Baldwin */ 16334ff71eeSJohn Baldwin int 16434ff71eeSJohn Baldwin pcib_host_res_init(device_t pcib, struct pcib_host_resources *hr) 16534ff71eeSJohn Baldwin { 16634ff71eeSJohn Baldwin 16734ff71eeSJohn Baldwin hr->hr_pcib = pcib; 16834ff71eeSJohn Baldwin resource_list_init(&hr->hr_rl); 16934ff71eeSJohn Baldwin return (0); 17034ff71eeSJohn Baldwin } 17134ff71eeSJohn Baldwin 17234ff71eeSJohn Baldwin int 17334ff71eeSJohn Baldwin pcib_host_res_free(device_t pcib, struct pcib_host_resources *hr) 17434ff71eeSJohn Baldwin { 17534ff71eeSJohn Baldwin 17634ff71eeSJohn Baldwin resource_list_free(&hr->hr_rl); 17734ff71eeSJohn Baldwin return (0); 17834ff71eeSJohn Baldwin } 17934ff71eeSJohn Baldwin 18034ff71eeSJohn Baldwin int 1812dd1bdf1SJustin Hibbits pcib_host_res_decodes(struct pcib_host_resources *hr, int type, rman_res_t start, 1822dd1bdf1SJustin Hibbits rman_res_t end, u_int flags) 18334ff71eeSJohn Baldwin { 18434ff71eeSJohn Baldwin struct resource_list_entry *rle; 18534ff71eeSJohn Baldwin int rid; 18634ff71eeSJohn Baldwin 18734ff71eeSJohn Baldwin if (bootverbose) 188da1b038aSJustin Hibbits device_printf(hr->hr_pcib, "decoding %d %srange %#jx-%#jx\n", 18934ff71eeSJohn Baldwin type, flags & RF_PREFETCHABLE ? "prefetchable ": "", start, 19034ff71eeSJohn Baldwin end); 19134ff71eeSJohn Baldwin rid = resource_list_add_next(&hr->hr_rl, type, start, end, 19234ff71eeSJohn Baldwin end - start + 1); 19334ff71eeSJohn Baldwin if (flags & RF_PREFETCHABLE) { 19434ff71eeSJohn Baldwin KASSERT(type == SYS_RES_MEMORY, 19534ff71eeSJohn Baldwin ("only memory is prefetchable")); 19634ff71eeSJohn Baldwin rle = resource_list_find(&hr->hr_rl, type, rid); 19734ff71eeSJohn Baldwin rle->flags = RLE_PREFETCH; 19834ff71eeSJohn Baldwin } 19934ff71eeSJohn Baldwin return (0); 20034ff71eeSJohn Baldwin } 20134ff71eeSJohn Baldwin 20234ff71eeSJohn Baldwin struct resource * 20334ff71eeSJohn Baldwin pcib_host_res_alloc(struct pcib_host_resources *hr, device_t dev, int type, 2042dd1bdf1SJustin Hibbits int *rid, rman_res_t start, rman_res_t end, rman_res_t count, u_int flags) 20534ff71eeSJohn Baldwin { 20634ff71eeSJohn Baldwin struct resource_list_entry *rle; 20734ff71eeSJohn Baldwin struct resource *r; 2082dd1bdf1SJustin Hibbits rman_res_t new_start, new_end; 20934ff71eeSJohn Baldwin 21034ff71eeSJohn Baldwin if (flags & RF_PREFETCHABLE) 21134ff71eeSJohn Baldwin KASSERT(type == SYS_RES_MEMORY, 21234ff71eeSJohn Baldwin ("only memory is prefetchable")); 21334ff71eeSJohn Baldwin 21434ff71eeSJohn Baldwin rle = resource_list_find(&hr->hr_rl, type, 0); 21534ff71eeSJohn Baldwin if (rle == NULL) { 21634ff71eeSJohn Baldwin /* 21734ff71eeSJohn Baldwin * No decoding ranges for this resource type, just pass 21834ff71eeSJohn Baldwin * the request up to the parent. 21934ff71eeSJohn Baldwin */ 22034ff71eeSJohn Baldwin return (bus_generic_alloc_resource(hr->hr_pcib, dev, type, rid, 22134ff71eeSJohn Baldwin start, end, count, flags)); 22234ff71eeSJohn Baldwin } 22334ff71eeSJohn Baldwin 22434ff71eeSJohn Baldwin restart: 22534ff71eeSJohn Baldwin /* Try to allocate from each decoded range. */ 22634ff71eeSJohn Baldwin for (; rle != NULL; rle = STAILQ_NEXT(rle, link)) { 22734ff71eeSJohn Baldwin if (rle->type != type) 22834ff71eeSJohn Baldwin continue; 22934ff71eeSJohn Baldwin if (((flags & RF_PREFETCHABLE) != 0) != 23034ff71eeSJohn Baldwin ((rle->flags & RLE_PREFETCH) != 0)) 23134ff71eeSJohn Baldwin continue; 232da1b038aSJustin Hibbits new_start = ummax(start, rle->start); 233da1b038aSJustin Hibbits new_end = ummin(end, rle->end); 23434ff71eeSJohn Baldwin if (new_start > new_end || 23534ff71eeSJohn Baldwin new_start + count - 1 > new_end || 23634ff71eeSJohn Baldwin new_start + count < new_start) 23734ff71eeSJohn Baldwin continue; 23834ff71eeSJohn Baldwin r = bus_generic_alloc_resource(hr->hr_pcib, dev, type, rid, 23934ff71eeSJohn Baldwin new_start, new_end, count, flags); 24034ff71eeSJohn Baldwin if (r != NULL) { 24134ff71eeSJohn Baldwin if (bootverbose) 24234ff71eeSJohn Baldwin device_printf(hr->hr_pcib, 243da1b038aSJustin Hibbits "allocated type %d (%#jx-%#jx) for rid %x of %s\n", 24434ff71eeSJohn Baldwin type, rman_get_start(r), rman_get_end(r), 24534ff71eeSJohn Baldwin *rid, pcib_child_name(dev)); 24634ff71eeSJohn Baldwin return (r); 24734ff71eeSJohn Baldwin } 24834ff71eeSJohn Baldwin } 24934ff71eeSJohn Baldwin 25034ff71eeSJohn Baldwin /* 25134ff71eeSJohn Baldwin * If we failed to find a prefetch range for a memory 25234ff71eeSJohn Baldwin * resource, try again without prefetch. 25334ff71eeSJohn Baldwin */ 25434ff71eeSJohn Baldwin if (flags & RF_PREFETCHABLE) { 25534ff71eeSJohn Baldwin flags &= ~RF_PREFETCHABLE; 25634ff71eeSJohn Baldwin rle = resource_list_find(&hr->hr_rl, type, 0); 25734ff71eeSJohn Baldwin goto restart; 25834ff71eeSJohn Baldwin } 25934ff71eeSJohn Baldwin return (NULL); 26034ff71eeSJohn Baldwin } 26134ff71eeSJohn Baldwin 26234ff71eeSJohn Baldwin int 26334ff71eeSJohn Baldwin pcib_host_res_adjust(struct pcib_host_resources *hr, device_t dev, int type, 2642dd1bdf1SJustin Hibbits struct resource *r, rman_res_t start, rman_res_t end) 26534ff71eeSJohn Baldwin { 26634ff71eeSJohn Baldwin struct resource_list_entry *rle; 26734ff71eeSJohn Baldwin 26834ff71eeSJohn Baldwin rle = resource_list_find(&hr->hr_rl, type, 0); 26934ff71eeSJohn Baldwin if (rle == NULL) { 27034ff71eeSJohn Baldwin /* 27134ff71eeSJohn Baldwin * No decoding ranges for this resource type, just pass 27234ff71eeSJohn Baldwin * the request up to the parent. 27334ff71eeSJohn Baldwin */ 27434ff71eeSJohn Baldwin return (bus_generic_adjust_resource(hr->hr_pcib, dev, type, r, 27534ff71eeSJohn Baldwin start, end)); 27634ff71eeSJohn Baldwin } 27734ff71eeSJohn Baldwin 27834ff71eeSJohn Baldwin /* Only allow adjustments that stay within a decoded range. */ 27934ff71eeSJohn Baldwin for (; rle != NULL; rle = STAILQ_NEXT(rle, link)) { 28034ff71eeSJohn Baldwin if (rle->start <= start && rle->end >= end) 28134ff71eeSJohn Baldwin return (bus_generic_adjust_resource(hr->hr_pcib, dev, 28234ff71eeSJohn Baldwin type, r, start, end)); 28334ff71eeSJohn Baldwin } 28434ff71eeSJohn Baldwin return (ERANGE); 28534ff71eeSJohn Baldwin } 2864edef187SJohn Baldwin 2874edef187SJohn Baldwin #ifdef PCI_RES_BUS 2884edef187SJohn Baldwin struct pci_domain { 2894edef187SJohn Baldwin int pd_domain; 2904edef187SJohn Baldwin struct rman pd_bus_rman; 2914edef187SJohn Baldwin TAILQ_ENTRY(pci_domain) pd_link; 2924edef187SJohn Baldwin }; 2934edef187SJohn Baldwin 2944edef187SJohn Baldwin static TAILQ_HEAD(, pci_domain) domains = TAILQ_HEAD_INITIALIZER(domains); 2954edef187SJohn Baldwin 2964edef187SJohn Baldwin /* 2974edef187SJohn Baldwin * Each PCI domain maintains its own resource manager for PCI bus 2984edef187SJohn Baldwin * numbers in that domain. Domain objects are created on first use. 2994edef187SJohn Baldwin * Host to PCI bridge drivers and PCI-PCI bridge drivers should 3004edef187SJohn Baldwin * allocate their bus ranges from their domain. 3014edef187SJohn Baldwin */ 3024edef187SJohn Baldwin static struct pci_domain * 3034edef187SJohn Baldwin pci_find_domain(int domain) 3044edef187SJohn Baldwin { 3054edef187SJohn Baldwin struct pci_domain *d; 3064edef187SJohn Baldwin char buf[64]; 3074edef187SJohn Baldwin int error; 3084edef187SJohn Baldwin 3094edef187SJohn Baldwin TAILQ_FOREACH(d, &domains, pd_link) { 3104edef187SJohn Baldwin if (d->pd_domain == domain) 3114edef187SJohn Baldwin return (d); 3124edef187SJohn Baldwin } 3134edef187SJohn Baldwin 3144edef187SJohn Baldwin snprintf(buf, sizeof(buf), "PCI domain %d bus numbers", domain); 3154edef187SJohn Baldwin d = malloc(sizeof(*d) + strlen(buf) + 1, M_DEVBUF, M_WAITOK | M_ZERO); 3164edef187SJohn Baldwin d->pd_domain = domain; 3174edef187SJohn Baldwin d->pd_bus_rman.rm_start = 0; 3184edef187SJohn Baldwin d->pd_bus_rman.rm_end = PCI_BUSMAX; 3194edef187SJohn Baldwin d->pd_bus_rman.rm_type = RMAN_ARRAY; 3204edef187SJohn Baldwin strcpy((char *)(d + 1), buf); 3214edef187SJohn Baldwin d->pd_bus_rman.rm_descr = (char *)(d + 1); 3224edef187SJohn Baldwin error = rman_init(&d->pd_bus_rman); 3234edef187SJohn Baldwin if (error == 0) 3244edef187SJohn Baldwin error = rman_manage_region(&d->pd_bus_rman, 0, PCI_BUSMAX); 3254edef187SJohn Baldwin if (error) 3264edef187SJohn Baldwin panic("Failed to initialize PCI domain %d rman", domain); 3274edef187SJohn Baldwin TAILQ_INSERT_TAIL(&domains, d, pd_link); 3284edef187SJohn Baldwin return (d); 3294edef187SJohn Baldwin } 3304edef187SJohn Baldwin 3314edef187SJohn Baldwin struct resource * 3322dd1bdf1SJustin Hibbits pci_domain_alloc_bus(int domain, device_t dev, int *rid, rman_res_t start, 3332dd1bdf1SJustin Hibbits rman_res_t end, rman_res_t count, u_int flags) 3344edef187SJohn Baldwin { 3354edef187SJohn Baldwin struct pci_domain *d; 3364edef187SJohn Baldwin struct resource *res; 3374edef187SJohn Baldwin 3384edef187SJohn Baldwin if (domain < 0 || domain > PCI_DOMAINMAX) 3394edef187SJohn Baldwin return (NULL); 3404edef187SJohn Baldwin d = pci_find_domain(domain); 3414edef187SJohn Baldwin res = rman_reserve_resource(&d->pd_bus_rman, start, end, count, flags, 3424edef187SJohn Baldwin dev); 3434edef187SJohn Baldwin if (res == NULL) 3444edef187SJohn Baldwin return (NULL); 3454edef187SJohn Baldwin 3464edef187SJohn Baldwin rman_set_rid(res, *rid); 3474edef187SJohn Baldwin return (res); 3484edef187SJohn Baldwin } 3494edef187SJohn Baldwin 3504edef187SJohn Baldwin int 3514edef187SJohn Baldwin pci_domain_adjust_bus(int domain, device_t dev, struct resource *r, 3522dd1bdf1SJustin Hibbits rman_res_t start, rman_res_t end) 3534edef187SJohn Baldwin { 3544edef187SJohn Baldwin #ifdef INVARIANTS 3554edef187SJohn Baldwin struct pci_domain *d; 3564edef187SJohn Baldwin #endif 3574edef187SJohn Baldwin 3584edef187SJohn Baldwin if (domain < 0 || domain > PCI_DOMAINMAX) 3594edef187SJohn Baldwin return (EINVAL); 3604edef187SJohn Baldwin #ifdef INVARIANTS 3614edef187SJohn Baldwin d = pci_find_domain(domain); 3624edef187SJohn Baldwin KASSERT(rman_is_region_manager(r, &d->pd_bus_rman), ("bad resource")); 3634edef187SJohn Baldwin #endif 3644edef187SJohn Baldwin return (rman_adjust_resource(r, start, end)); 3654edef187SJohn Baldwin } 3664edef187SJohn Baldwin 3674edef187SJohn Baldwin int 3684edef187SJohn Baldwin pci_domain_release_bus(int domain, device_t dev, int rid, struct resource *r) 3694edef187SJohn Baldwin { 3704edef187SJohn Baldwin #ifdef INVARIANTS 3714edef187SJohn Baldwin struct pci_domain *d; 3724edef187SJohn Baldwin #endif 3734edef187SJohn Baldwin 3744edef187SJohn Baldwin if (domain < 0 || domain > PCI_DOMAINMAX) 3754edef187SJohn Baldwin return (EINVAL); 3764edef187SJohn Baldwin #ifdef INVARIANTS 3774edef187SJohn Baldwin d = pci_find_domain(domain); 3784edef187SJohn Baldwin KASSERT(rman_is_region_manager(r, &d->pd_bus_rman), ("bad resource")); 3794edef187SJohn Baldwin #endif 3804edef187SJohn Baldwin return (rman_release_resource(r)); 3814edef187SJohn Baldwin } 3824edef187SJohn Baldwin #endif /* PCI_RES_BUS */ 3834edef187SJohn Baldwin 38434ff71eeSJohn Baldwin #endif /* NEW_PCIB */ 385