nexus.c revision 84541
118334Speter/* 250397Sobrien * Copyright 1998 Massachusetts Institute of Technology 318334Speter * 418334Speter * Permission to use, copy, modify, and distribute this software and 518334Speter * its documentation for any purpose and without fee is hereby 618334Speter * granted, provided that both the above copyright notice and this 718334Speter * permission notice appear in all copies, that both the above 818334Speter * copyright notice and this permission notice appear in all 918334Speter * supporting documentation, and that the name of M.I.T. not be used 1018334Speter * in advertising or publicity pertaining to distribution of the 1118334Speter * software without specific, written prior permission. M.I.T. makes 1218334Speter * no representations about the suitability of this software for any 1318334Speter * purpose. It is provided "as is" without express or implied 1418334Speter * warranty. 1518334Speter * 1618334Speter * THIS SOFTWARE IS PROVIDED BY M.I.T. ``AS IS''. M.I.T. DISCLAIMS 1718334Speter * ALL EXPRESS OR IMPLIED WARRANTIES WITH REGARD TO THIS SOFTWARE, 1818334Speter * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 1918334Speter * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT 2018334Speter * SHALL M.I.T. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 2118334Speter * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 2218334Speter * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF 2318334Speter * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 2418334Speter * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 2518334Speter * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 2618334Speter * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2718334Speter * SUCH DAMAGE. 2818334Speter * 2918334Speter * $FreeBSD: head/sys/ia64/ia64/nexus.c 84541 2001-10-05 10:30:09Z dfr $ 3018334Speter */ 3118334Speter 3218334Speter/* 3318334Speter * This code implements a `root nexus' for Intel Architecture 3418334Speter * machines. The function of the root nexus is to serve as an 3518334Speter * attachment point for both processors and buses, and to manage 3618334Speter * resources which are common to all of them. In particular, 3718334Speter * this code implements the core resource managers for interrupt 3818334Speter * requests, DMA requests (which rightfully should be a part of the 3918334Speter * ISA code but it's easier to do it here for now), I/O port addresses, 4018334Speter * and I/O memory address space. 4118334Speter */ 4250397Sobrien 4350397Sobrien#include <sys/param.h> 4450397Sobrien#include <sys/systm.h> 4550397Sobrien#include <sys/bus.h> 4650397Sobrien#include <sys/kernel.h> 4750397Sobrien#include <sys/malloc.h> 4850397Sobrien#include <sys/module.h> 4950397Sobrien#include <machine/bus.h> 5018334Speter#include <sys/rman.h> 5118334Speter#include <sys/interrupt.h> 5218334Speter 5350397Sobrien#include <machine/vmparam.h> 5450397Sobrien#include <vm/vm.h> 5518334Speter#include <vm/pmap.h> 5618334Speter#include <machine/pmap.h> 5718334Speter 5818334Speter#include <machine/nexusvar.h> 5918334Speter#include <machine/resource.h> 6018334Speter 6118334Speter#include <isa/isavar.h> 6218334Speter#include <isa/isareg.h> 6318334Speter#include <sys/rtprio.h> 6418334Speter 6518334Speterstatic MALLOC_DEFINE(M_NEXUSDEV, "nexusdev", "Nexus device"); 6618334Speterstruct nexus_device { 6718334Speter struct resource_list nx_resources; 6818334Speter int nx_pcibus; 6918334Speter}; 7018334Speter 7118334Speter#define DEVTONX(dev) ((struct nexus_device *)device_get_ivars(dev)) 7218334Speter 7318334Speterstatic struct rman irq_rman, drq_rman, port_rman, mem_rman; 7418334Speter 7518334Speterstatic int nexus_probe(device_t); 7618334Speterstatic int nexus_attach(device_t); 7718334Speterstatic int nexus_print_resources(struct resource_list *rl, const char *name, int type, 7818334Speter const char *format); 7950397Sobrienstatic int nexus_print_all_resources(device_t dev); 8050397Sobrienstatic int nexus_print_child(device_t, device_t); 8150397Sobrienstatic device_t nexus_add_child(device_t bus, int order, const char *name, 8250397Sobrien int unit); 8318334Speterstatic struct resource *nexus_alloc_resource(device_t, device_t, int, int *, 8418334Speter u_long, u_long, u_long, u_int); 8518334Speterstatic int nexus_read_ivar(device_t, device_t, int, uintptr_t *); 8618334Speterstatic int nexus_write_ivar(device_t, device_t, int, uintptr_t); 8718334Speterstatic int nexus_activate_resource(device_t, device_t, int, int, 8818334Speter struct resource *); 8918334Speterstatic int nexus_deactivate_resource(device_t, device_t, int, int, 9018334Speter struct resource *); 9118334Speterstatic int nexus_release_resource(device_t, device_t, int, int, 9218334Speter struct resource *); 9318334Speterstatic int nexus_setup_intr(device_t, device_t, struct resource *, int flags, 9418334Speter void (*)(void *), void *, void **); 9518334Speterstatic int nexus_teardown_intr(device_t, device_t, struct resource *, 9618334Speter void *); 9718334Speterstatic int nexus_set_resource(device_t, device_t, int, int, u_long, u_long); 9818334Speterstatic int nexus_get_resource(device_t, device_t, int, int, u_long *, u_long *); 9918334Speterstatic void nexus_delete_resource(device_t, device_t, int, int); 10018334Speter 10118334Speterstatic device_method_t nexus_methods[] = { 10218334Speter /* Device interface */ 10318334Speter DEVMETHOD(device_probe, nexus_probe), 10418334Speter DEVMETHOD(device_attach, nexus_attach), 10518334Speter DEVMETHOD(device_detach, bus_generic_detach), 10618334Speter DEVMETHOD(device_shutdown, bus_generic_shutdown), 10718334Speter DEVMETHOD(device_suspend, bus_generic_suspend), 10818334Speter DEVMETHOD(device_resume, bus_generic_resume), 10918334Speter 11018334Speter /* Bus interface */ 11118334Speter DEVMETHOD(bus_print_child, nexus_print_child), 11218334Speter DEVMETHOD(bus_add_child, nexus_add_child), 11318334Speter DEVMETHOD(bus_read_ivar, nexus_read_ivar), 11418334Speter DEVMETHOD(bus_write_ivar, nexus_write_ivar), 11518334Speter DEVMETHOD(bus_alloc_resource, nexus_alloc_resource), 11618334Speter DEVMETHOD(bus_release_resource, nexus_release_resource), 11718334Speter DEVMETHOD(bus_activate_resource, nexus_activate_resource), 11818334Speter DEVMETHOD(bus_deactivate_resource, nexus_deactivate_resource), 11918334Speter DEVMETHOD(bus_setup_intr, nexus_setup_intr), 12018334Speter DEVMETHOD(bus_teardown_intr, nexus_teardown_intr), 12118334Speter DEVMETHOD(bus_set_resource, nexus_set_resource), 12218334Speter DEVMETHOD(bus_get_resource, nexus_get_resource), 12318334Speter DEVMETHOD(bus_delete_resource, nexus_delete_resource), 12418334Speter 12518334Speter { 0, 0 } 12618334Speter}; 12718334Speter 12818334Speterstatic driver_t nexus_driver = { 12918334Speter "nexus", 13018334Speter nexus_methods, 13118334Speter 1, /* no softc */ 13218334Speter}; 13318334Speterstatic devclass_t nexus_devclass; 13418334Speter 13518334SpeterDRIVER_MODULE(nexus, root, nexus_driver, nexus_devclass, 0, 0); 13618334Speter 13718334Speterstatic int 13818334Speternexus_probe(device_t dev) 13918334Speter{ 14018334Speter 14118334Speter device_quiet(dev); /* suppress attach message for neatness */ 14218334Speter 14318334Speter /* 14418334Speter * XXX working notes: 14518334Speter * 14618334Speter * - IRQ resource creation should be moved to the PIC/APIC driver. 14718334Speter * - DRQ resource creation should be moved to the DMAC driver. 14818334Speter * - The above should be sorted to probe earlier than any child busses. 14918334Speter * 15018334Speter * - Leave I/O and memory creation here, as child probes may need them. 15118334Speter * (especially eg. ACPI) 15218334Speter */ 15318334Speter 15418334Speter /* 15518334Speter * IRQ's are on the mainboard on old systems, but on the ISA part 15618334Speter * of PCI->ISA bridges. There would be multiple sets of IRQs on 15718334Speter * multi-ISA-bus systems. PCI interrupts are routed to the ISA 15818334Speter * component, so in a way, PCI can be a partial child of an ISA bus(!). 15918334Speter * APIC interrupts are global though. 16018334Speter * 16118334Speter * XXX We depend on the AT PIC driver correctly claiming IRQ 2 16218334Speter * to prevent its reuse elsewhere in the !APIC_IO case. 16318334Speter */ 16418334Speter irq_rman.rm_start = 0; 16518334Speter irq_rman.rm_type = RMAN_ARRAY; 16618334Speter irq_rman.rm_descr = "Interrupt request lines"; 16718334Speter irq_rman.rm_end = 63; 16818334Speter if (rman_init(&irq_rman) 16918334Speter || rman_manage_region(&irq_rman, 17018334Speter irq_rman.rm_start, irq_rman.rm_end)) 17118334Speter panic("nexus_probe irq_rman"); 17218334Speter 17318334Speter /* 17418334Speter * ISA DMA on PCI systems is implemented in the ISA part of each 17518334Speter * PCI->ISA bridge and the channels can be duplicated if there are 17618334Speter * multiple bridges. (eg: laptops with docking stations) 17718334Speter */ 17818334Speter drq_rman.rm_start = 0; 17918334Speter drq_rman.rm_end = 7; 18018334Speter drq_rman.rm_type = RMAN_ARRAY; 18118334Speter drq_rman.rm_descr = "DMA request lines"; 18218334Speter /* XXX drq 0 not available on some machines */ 18350397Sobrien if (rman_init(&drq_rman) 18418334Speter || rman_manage_region(&drq_rman, 18518334Speter drq_rman.rm_start, drq_rman.rm_end)) 18618334Speter panic("nexus_probe drq_rman"); 18718334Speter 18818334Speter /* 18918334Speter * However, IO ports and Memory truely are global at this level, 19018334Speter * as are APIC interrupts (however many IO APICS there turn out 19118334Speter * to be on large systems..) 19218334Speter */ 19318334Speter port_rman.rm_start = 0; 19450397Sobrien port_rman.rm_end = 0xffff; 19518334Speter port_rman.rm_type = RMAN_ARRAY; 19618334Speter port_rman.rm_descr = "I/O ports"; 19718334Speter if (rman_init(&port_rman) 19818334Speter || rman_manage_region(&port_rman, 0, 0xffff)) 19918334Speter panic("nexus_probe port_rman"); 20018334Speter 20118334Speter mem_rman.rm_start = 0; 20218334Speter mem_rman.rm_end = ~0u; 20350397Sobrien mem_rman.rm_type = RMAN_ARRAY; 20418334Speter mem_rman.rm_descr = "I/O memory addresses"; 20518334Speter if (rman_init(&mem_rman) 20618334Speter || rman_manage_region(&mem_rman, 0, ~0)) 20718334Speter panic("nexus_probe mem_rman"); 20818334Speter 20918334Speter return bus_generic_probe(dev); 21018334Speter} 21118334Speter 21218334Speterstatic int 21318334Speternexus_attach(device_t dev) 21418334Speter{ 21518334Speter /* 21618334Speter * Mask the legacy PICs - we will use the I/O SAPIC for interrupt. 21718334Speter */ 21818334Speter outb(IO_ICU1+1, 0xff); 21918334Speter outb(IO_ICU2+1, 0xff); 22018334Speter 22118334Speter bus_generic_attach(dev); 22218334Speter return 0; 22318334Speter} 22418334Speter 22518334Speterstatic int 22618334Speternexus_print_resources(struct resource_list *rl, const char *name, int type, 22718334Speter const char *format) 22818334Speter{ 22918334Speter struct resource_list_entry *rle; 23018334Speter int printed, retval; 23118334Speter 23218334Speter printed = 0; 23318334Speter retval = 0; 23418334Speter /* Yes, this is kinda cheating */ 23518334Speter SLIST_FOREACH(rle, rl, link) { 23618334Speter if (rle->type == type) { 23718334Speter if (printed == 0) 23818334Speter retval += printf(" %s ", name); 23918334Speter else if (printed > 0) 24018334Speter retval += printf(","); 24118334Speter printed++; 24218334Speter retval += printf(format, rle->start); 24318334Speter if (rle->count > 1) { 24418334Speter retval += printf("-"); 24518334Speter retval += printf(format, rle->start + 24618334Speter rle->count - 1); 24718334Speter } 24818334Speter } 24918334Speter } 25018334Speter return retval; 25118334Speter} 25218334Speter 25318334Speterstatic int 25418334Speternexus_print_all_resources(device_t dev) 25518334Speter{ 25618334Speter struct nexus_device *ndev = DEVTONX(dev); 25718334Speter struct resource_list *rl = &ndev->nx_resources; 25818334Speter int retval = 0; 25918334Speter 26018334Speter if (SLIST_FIRST(rl) || ndev->nx_pcibus != -1) 26118334Speter retval += printf(" at"); 26218334Speter 26318334Speter retval += nexus_print_resources(rl, "port", SYS_RES_IOPORT, "%#lx"); 26450397Sobrien retval += nexus_print_resources(rl, "iomem", SYS_RES_MEMORY, "%#lx"); 26550397Sobrien retval += nexus_print_resources(rl, "irq", SYS_RES_IRQ, "%ld"); 26650397Sobrien 26750397Sobrien return retval; 26818334Speter} 26918334Speter 27050397Sobrienstatic int 27118334Speternexus_print_child(device_t bus, device_t child) 27250397Sobrien{ 27350397Sobrien struct nexus_device *ndev = DEVTONX(child); 27418334Speter int retval = 0; 27518334Speter 27618334Speter retval += bus_print_child_header(bus, child); 27718334Speter retval += nexus_print_all_resources(child); 27818334Speter if (ndev->nx_pcibus != -1) 27918334Speter retval += printf(" pcibus %d", ndev->nx_pcibus); 28018334Speter retval += printf(" on motherboard\n"); /* XXX "motherboard", ick */ 28118334Speter 28218334Speter return (retval); 28318334Speter} 28418334Speter 28518334Speterstatic device_t 28618334Speternexus_add_child(device_t bus, int order, const char *name, int unit) 28718334Speter{ 28818334Speter device_t child; 28918334Speter struct nexus_device *ndev; 29018334Speter 29118334Speter ndev = malloc(sizeof(struct nexus_device), M_NEXUSDEV, M_NOWAIT|M_ZERO); 29218334Speter if (!ndev) 29318334Speter return(0); 29418334Speter resource_list_init(&ndev->nx_resources); 29518334Speter ndev->nx_pcibus = -1; 29618334Speter 29718334Speter child = device_add_child_ordered(bus, order, name, unit); 29818334Speter 29918334Speter /* should we free this in nexus_child_detached? */ 30018334Speter device_set_ivars(child, ndev); 30118334Speter 30218334Speter return(child); 30318334Speter} 30418334Speter 30518334Speterstatic int 30618334Speternexus_read_ivar(device_t dev, device_t child, int which, uintptr_t *result) 30718334Speter{ 30818334Speter struct nexus_device *ndev = DEVTONX(child); 30918334Speter 31018334Speter switch (which) { 31118334Speter case NEXUS_IVAR_PCIBUS: 31218334Speter *result = ndev->nx_pcibus; 31318334Speter break; 31418334Speter default: 31518334Speter return ENOENT; 31618334Speter } 31718334Speter return 0; 31818334Speter} 31918334Speter 32018334Speter 32118334Speterstatic int 32218334Speternexus_write_ivar(device_t dev, device_t child, int which, uintptr_t value) 32318334Speter{ 32418334Speter struct nexus_device *ndev = DEVTONX(child); 32518334Speter 32618334Speter switch (which) { 32718334Speter case NEXUS_IVAR_PCIBUS: 32818334Speter ndev->nx_pcibus = value; 32918334Speter break; 33018334Speter default: 33118334Speter return ENOENT; 33218334Speter } 33318334Speter return 0; 33418334Speter} 33518334Speter 33618334Speter 33718334Speter/* 33818334Speter * Allocate a resource on behalf of child. NB: child is usually going to be a 33918334Speter * child of one of our descendants, not a direct child of nexus0. 34018334Speter * (Exceptions include npx.) 34150397Sobrien */ 34218334Speterstatic struct resource * 34318334Speternexus_alloc_resource(device_t bus, device_t child, int type, int *rid, 34418334Speter u_long start, u_long end, u_long count, u_int flags) 34518334Speter{ 34618334Speter struct nexus_device *ndev = DEVTONX(child); 34718334Speter struct resource *rv; 34818334Speter struct resource_list_entry *rle; 34918334Speter struct rman *rm; 35018334Speter int needactivate = flags & RF_ACTIVE; 35118334Speter 35218334Speter /* 35318334Speter * If this is an allocation of the "default" range for a given RID, and 35418334Speter * we know what the resources for this device are (ie. they aren't maintained 35518334Speter * by a child bus), then work out the start/end values. 35618334Speter */ 35718334Speter if ((start == 0UL) && (end == ~0UL) && (count == 1)) { 35818334Speter if (ndev == NULL) 35918334Speter return(NULL); 36018334Speter rle = resource_list_find(&ndev->nx_resources, type, *rid); 36118334Speter if (rle == NULL) 36218334Speter return(NULL); 36318334Speter start = rle->start; 36418334Speter end = rle->end; 36518334Speter count = rle->count; 36618334Speter } 36718334Speter 36818334Speter flags &= ~RF_ACTIVE; 36918334Speter 37018334Speter switch (type) { 37118334Speter case SYS_RES_IRQ: 37218334Speter rm = &irq_rman; 37350397Sobrien break; 37450397Sobrien 37550397Sobrien case SYS_RES_DRQ: 37650397Sobrien rm = &drq_rman; 37750397Sobrien break; 37850397Sobrien 37950397Sobrien case SYS_RES_IOPORT: 38050397Sobrien rm = &port_rman; 38150397Sobrien break; 38218334Speter 38350397Sobrien case SYS_RES_MEMORY: 38450397Sobrien rm = &mem_rman; 38550397Sobrien break; 38650397Sobrien 38750397Sobrien default: 38818334Speter return 0; 38918334Speter } 39018334Speter 39118334Speter rv = rman_reserve_resource(rm, start, end, count, flags, child); 39218334Speter if (rv == 0) 39318334Speter return 0; 39418334Speter 39518334Speter if (type == SYS_RES_MEMORY) { 39618334Speter rman_set_bustag(rv, IA64_BUS_SPACE_MEM); 39718334Speter } else if (type == SYS_RES_IOPORT) { 39818334Speter rman_set_bustag(rv, IA64_BUS_SPACE_IO); 39918334Speter /* IBM-PC: the type of bus_space_handle_t is u_int */ 40018334Speter rman_set_bushandle(rv, rv->r_start); 40118334Speter } 40218334Speter 40318334Speter if (needactivate) { 40450397Sobrien if (bus_activate_resource(child, type, *rid, rv)) { 40518334Speter rman_release_resource(rv); 40618334Speter return 0; 40718334Speter } 40818334Speter } 40918334Speter 41018334Speter return rv; 41118334Speter} 41218334Speter 41350397Sobrienstatic int 41418334Speternexus_activate_resource(device_t bus, device_t child, int type, int rid, 41550397Sobrien struct resource *r) 41618334Speter{ 41718334Speter /* 41818334Speter * If this is a memory resource, map it into the kernel. 41918334Speter */ 42018334Speter if (rman_get_bustag(r) == IA64_BUS_SPACE_MEM) { 42118334Speter vm_offset_t paddr = rman_get_start(r); 42218334Speter vm_offset_t psize = rman_get_size(r); 42318334Speter caddr_t vaddr = 0; 42418334Speter 42518334Speter vaddr = pmap_mapdev(paddr, psize); 42618334Speter rman_set_virtual(r, vaddr); 42718334Speter rman_set_bushandle(r, (bus_space_handle_t) paddr); 42818334Speter } 42918334Speter return (rman_activate_resource(r)); 43018334Speter} 43150397Sobrien 43250397Sobrienstatic int 43350397Sobriennexus_deactivate_resource(device_t bus, device_t child, int type, int rid, 43450397Sobrien struct resource *r) 43550397Sobrien{ 43650397Sobrien 43750397Sobrien return (rman_deactivate_resource(r)); 43850397Sobrien} 43950397Sobrien 44050397Sobrienstatic int 44150397Sobriennexus_release_resource(device_t bus, device_t child, int type, int rid, 44250397Sobrien struct resource *r) 44350397Sobrien{ 44450397Sobrien if (rman_get_flags(r) & RF_ACTIVE) { 44550397Sobrien int error = bus_deactivate_resource(child, type, rid, r); 44650397Sobrien if (error) 44750397Sobrien return error; 44850397Sobrien } 44950397Sobrien return (rman_release_resource(r)); 45050397Sobrien} 45150397Sobrien 45250397Sobrien/* 45350397Sobrien * Currently this uses the really grody interface from kern/kern_intr.c 45450397Sobrien * (which really doesn't belong in kern/anything.c). Eventually, all of 45550397Sobrien * the code in kern_intr.c and machdep_intr.c should get moved here, since 45650397Sobrien * this is going to be the official interface. 45718334Speter */ 45818334Speterstatic int 45918334Speternexus_setup_intr(device_t bus, device_t child, struct resource *irq, 46050397Sobrien int flags, void (*ihand)(void *), void *arg, void **cookiep) 46118334Speter{ 46218334Speter driver_t *driver; 46318334Speter int error; 46418334Speter 46518334Speter /* somebody tried to setup an irq that failed to allocate! */ 46618334Speter if (irq == NULL) 46718334Speter panic("nexus_setup_intr: NULL irq resource!"); 46818334Speter 46918334Speter *cookiep = 0; 47018334Speter if ((irq->r_flags & RF_SHAREABLE) == 0) 47118334Speter flags |= INTR_EXCL; 47218334Speter 47318334Speter driver = device_get_driver(child); 47418334Speter 47518334Speter /* 47618334Speter * We depend here on rman_activate_resource() being idempotent. 47718334Speter */ 47818334Speter error = rman_activate_resource(irq); 47918334Speter if (error) 48018334Speter return (error); 48118334Speter 48218334Speter error = ia64_setup_intr(device_get_nameunit(child), irq->r_start, 48318334Speter ihand, arg, flags, cookiep, 0); 48418334Speter 48518334Speter return (error); 48618334Speter} 48718334Speter 48818334Speterstatic int 48918334Speternexus_teardown_intr(device_t dev, device_t child, struct resource *r, void *ih) 49018334Speter{ 49118334Speter#if 0 49218334Speter return (inthand_remove(ih)); 49318334Speter#else 49418334Speter return 0; 49518334Speter#endif 49618334Speter} 49718334Speter 49818334Speterstatic int 49918334Speternexus_set_resource(device_t dev, device_t child, int type, int rid, u_long start, u_long count) 50018334Speter{ 50118334Speter struct nexus_device *ndev = DEVTONX(child); 50218334Speter struct resource_list *rl = &ndev->nx_resources; 50318334Speter 50418334Speter /* XXX this should return a success/failure indicator */ 50518334Speter resource_list_add(rl, type, rid, start, start + count - 1, count); 50618334Speter return(0); 50718334Speter} 50818334Speter 50918334Speterstatic int 51018334Speternexus_get_resource(device_t dev, device_t child, int type, int rid, u_long *startp, u_long *countp) 51118334Speter{ 51218334Speter struct nexus_device *ndev = DEVTONX(child); 51318334Speter struct resource_list *rl = &ndev->nx_resources; 51418334Speter struct resource_list_entry *rle; 51518334Speter 51618334Speter rle = resource_list_find(rl, type, rid); 51718334Speter device_printf(child, "type %d rid %d startp %p countp %p - got %p\n", 51818334Speter type, rid, startp, countp, rle); 51918334Speter if (!rle) 52018334Speter return(ENOENT); 52118334Speter if (startp) 52218334Speter *startp = rle->start; 52318334Speter if (countp) 52418334Speter *countp = rle->count; 52518334Speter return(0); 52618334Speter} 52718334Speter 52818334Speterstatic void 52918334Speternexus_delete_resource(device_t dev, device_t child, int type, int rid) 53018334Speter{ 53118334Speter struct nexus_device *ndev = DEVTONX(child); 53218334Speter struct resource_list *rl = &ndev->nx_resources; 53318334Speter 53418334Speter resource_list_delete(rl, type, rid); 53518334Speter} 53618334Speter 53718334Speter#if 0 53818334Speter 53918334Speter/* 54018334Speter * Placeholder which claims PnP 'devices' which describe system 54118334Speter * resources. 54218334Speter */ 54318334Speterstatic struct isa_pnp_id sysresource_ids[] = { 54418334Speter { 0x010cd041 /* PNP0c01 */, "System Memory" }, 54518334Speter { 0x020cd041 /* PNP0c02 */, "System Resource" }, 54618334Speter { 0 } 54718334Speter}; 54818334Speter 54918334Speterstatic int 55018334Spetersysresource_probe(device_t dev) 55118334Speter{ 55218334Speter int result; 55318334Speter 55418334Speter if ((result = ISA_PNP_PROBE(device_get_parent(dev), dev, sysresource_ids)) <= 0) { 55518334Speter device_quiet(dev); 55618334Speter } 55718334Speter return(result); 55818334Speter} 55918334Speter 56018334Speterstatic int 56118334Spetersysresource_attach(device_t dev) 56218334Speter{ 56318334Speter return(0); 56418334Speter} 56518334Speter 56618334Speterstatic device_method_t sysresource_methods[] = { 56718334Speter /* Device interface */ 56818334Speter DEVMETHOD(device_probe, sysresource_probe), 56918334Speter DEVMETHOD(device_attach, sysresource_attach), 57018334Speter DEVMETHOD(device_detach, bus_generic_detach), 57118334Speter DEVMETHOD(device_shutdown, bus_generic_shutdown), 57218334Speter DEVMETHOD(device_suspend, bus_generic_suspend), 57318334Speter DEVMETHOD(device_resume, bus_generic_resume), 57418334Speter { 0, 0 } 57518334Speter}; 57618334Speter 57718334Speterstatic driver_t sysresource_driver = { 57818334Speter "sysresource", 57918334Speter sysresource_methods, 58018334Speter 1, /* no softc */ 58118334Speter}; 58218334Speter 58318334Speterstatic devclass_t sysresource_devclass; 58418334Speter 58518334SpeterDRIVER_MODULE(sysresource, isa, sysresource_driver, sysresource_devclass, 0, 0); 58618334Speter 58718334Speter#endif 58818334Speter