isa.c revision 47178
14Srgrimes/*- 245720Speter * Copyright (c) 1998 Doug Rabson 34Srgrimes * All rights reserved. 44Srgrimes * 54Srgrimes * Redistribution and use in source and binary forms, with or without 64Srgrimes * modification, are permitted provided that the following conditions 74Srgrimes * are met: 84Srgrimes * 1. Redistributions of source code must retain the above copyright 94Srgrimes * notice, this list of conditions and the following disclaimer. 104Srgrimes * 2. Redistributions in binary form must reproduce the above copyright 114Srgrimes * notice, this list of conditions and the following disclaimer in the 124Srgrimes * documentation and/or other materials provided with the distribution. 134Srgrimes * 1445720Speter * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 154Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 164Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1745720Speter * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 184Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 194Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 204Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 214Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 224Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 234Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 244Srgrimes * SUCH DAMAGE. 254Srgrimes * 2647178Sdfr * $Id: isa.c,v 1.125 1999/05/08 21:59:25 dfr Exp $ 274Srgrimes */ 284Srgrimes 294Srgrimes/* 3045720Speter * Modifications for Intel architecture by Garrett A. Wollman. 3145720Speter * Copyright 1998 Massachusetts Institute of Technology 324Srgrimes * 3345720Speter * Permission to use, copy, modify, and distribute this software and 3445720Speter * its documentation for any purpose and without fee is hereby 3545720Speter * granted, provided that both the above copyright notice and this 3645720Speter * permission notice appear in all copies, that both the above 3745720Speter * copyright notice and this permission notice appear in all 3845720Speter * supporting documentation, and that the name of M.I.T. not be used 3945720Speter * in advertising or publicity pertaining to distribution of the 4045720Speter * software without specific, written prior permission. M.I.T. makes 4145720Speter * no representations about the suitability of this software for any 4245720Speter * purpose. It is provided "as is" without express or implied 4345720Speter * warranty. 4445720Speter * 4545720Speter * THIS SOFTWARE IS PROVIDED BY M.I.T. ``AS IS''. M.I.T. DISCLAIMS 4645720Speter * ALL EXPRESS OR IMPLIED WARRANTIES WITH REGARD TO THIS SOFTWARE, 4745720Speter * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 4845720Speter * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT 4945720Speter * SHALL M.I.T. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 5045720Speter * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 5145720Speter * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF 5245720Speter * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 5345720Speter * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 5445720Speter * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 5545720Speter * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 5645720Speter * SUCH DAMAGE. 574Srgrimes */ 584Srgrimes 592056Swollman#include <sys/param.h> 6013644Sbde#include <sys/systm.h> 6145720Speter#include <sys/kernel.h> 6245720Speter#include <sys/bus.h> 632056Swollman#include <sys/malloc.h> 6445720Speter#include <sys/module.h> 6545720Speter#include <machine/bus.h> 6645720Speter#include <sys/rman.h> 674Srgrimes 6845720Speter#include <machine/resource.h> 6926157Sse 7045720Speter#include <isa/isavar.h> 7129613Sjmg 7245720SpeterMALLOC_DEFINE(M_ISADEV, "isadev", "ISA device"); 734Srgrimes 744Srgrimes/* 7545720Speter * The structure used to attach devices to the isa bus. 7645720Speter */ 7745720Speterstruct isa_device { 7846015Skato int id_port[ISA_NPORT_IVARS]; 7945720Speter u_short id_portsize[ISA_NPORT_IVARS]; 8045720Speter vm_offset_t id_maddr[ISA_NMEM_IVARS]; 8145720Speter vm_size_t id_msize[ISA_NMEM_IVARS]; 8245720Speter int id_irq[ISA_NIRQ_IVARS]; 8345720Speter int id_drq[ISA_NDRQ_IVARS]; 8445720Speter int id_flags; 8545720Speter struct resource *id_portres[ISA_NPORT_IVARS]; 8645720Speter struct resource *id_memres[ISA_NMEM_IVARS]; 8745720Speter struct resource *id_irqres[ISA_NIRQ_IVARS]; 8845720Speter struct resource *id_drqres[ISA_NDRQ_IVARS]; 8945720Speter}; 904Srgrimes 9145720Speter#define DEVTOISA(dev) ((struct isa_device *) device_get_ivars(dev)) 922103Sdg 9345720Speterstatic devclass_t isa_devclass; 9445720Speter 954Srgrimes/* 9645720Speter * At 'probe' time, we add all the devices which we know about to the 9745720Speter * bus. The generic attach routine will probe and attach them if they 9845720Speter * are alive. 994Srgrimes */ 10045720Speterstatic int 10145720Speterisa_probe(device_t dev) 10231457Sjmg{ 10345720Speter isa_wrap_old_drivers(); 10447178Sdfr return bus_generic_probe(dev); 1053258Sdg} 1068876Srgrimes 10745720Speterextern device_t isa_bus_device; 10845720Speter 10945720Speterstatic int 11045720Speterisa_attach(device_t dev) 1114Srgrimes{ 11245720Speter /* 11345720Speter * Arrange for bus_generic_attach(dev) to be called later. 11445720Speter */ 11545720Speter isa_bus_device = dev; 11645720Speter return 0; 1173258Sdg} 1183258Sdg 11947178Sdfr/* 12047178Sdfr * Add a new child with default ivars. 12147178Sdfr */ 12247178Sdfrstatic device_t 12347178Sdfrisa_add_child(device_t dev, device_t place, const char *name, int unit) 12447178Sdfr{ 12547178Sdfr struct isa_device *idev; 12647178Sdfr 12747178Sdfr idev = malloc(sizeof(struct isa_device), M_ISADEV, M_NOWAIT); 12847178Sdfr if (!idev) 12947178Sdfr return 0; 13047178Sdfr bzero(idev, sizeof *idev); 13147178Sdfr 13247178Sdfr idev->id_port[0] = -1; 13347178Sdfr idev->id_port[1] = -1; 13447178Sdfr idev->id_portsize[0] = 0; 13547178Sdfr idev->id_portsize[1] = 0; 13647178Sdfr idev->id_maddr[0] = 0; 13747178Sdfr idev->id_maddr[1] = 0; 13847178Sdfr idev->id_msize[0] = 0; 13947178Sdfr idev->id_msize[1] = 0; 14047178Sdfr idev->id_irq[0] = -1; 14147178Sdfr idev->id_irq[1] = -1; 14247178Sdfr idev->id_drq[0] = -1; 14347178Sdfr idev->id_drq[1] = -1; 14447178Sdfr idev->id_flags = 0; 14547178Sdfr 14647178Sdfr if (place) 14747178Sdfr return device_add_child_after(dev, place, name, unit, idev); 14847178Sdfr else 14947178Sdfr return device_add_child(dev, name, unit, idev); 15047178Sdfr} 15147178Sdfr 1523258Sdgstatic void 15345720Speterisa_print_child(device_t bus, device_t dev) 1543258Sdg{ 15545720Speter struct isa_device *id = DEVTOISA(dev); 1568876Srgrimes 15745720Speter if (id->id_port[0] > 0 || id->id_port[1] > 0 15845720Speter || id->id_maddr[0] > 0 || id->id_maddr[1] > 0 15945720Speter || id->id_irq[0] >= 0 || id->id_irq[1] >= 0 16045720Speter || id->id_drq[0] >= 0 || id->id_drq[1] >= 0) 16145720Speter printf(" at"); 16245720Speter if (id->id_port[0] > 0 && id->id_port[1] > 0) { 16345720Speter printf(" ports %#x", (u_int)id->id_port[0]); 16445720Speter if (id->id_portsize[0] > 1) 16545720Speter printf("-%#x", (u_int)(id->id_port[0] 16645720Speter + id->id_portsize[0] - 1)); 16745720Speter printf(" and %#x", (u_int)id->id_port[1]); 16845720Speter if (id->id_portsize[1] > 1) 16945720Speter printf("-%#x", (u_int)(id->id_port[1] 17045720Speter + id->id_portsize[1] - 1)); 17145720Speter } else if (id->id_port[0] > 0) { 17245720Speter printf(" port %#x", (u_int)id->id_port[0]); 17345720Speter if (id->id_portsize[0] > 1) 17445720Speter printf("-%#x", (u_int)(id->id_port[0] 17545720Speter + id->id_portsize[0] - 1)); 17645720Speter } else if (id->id_port[1] > 0) { 17745720Speter printf(" port %#x", (u_int)id->id_port[1]); 17845720Speter if (id->id_portsize[1] > 1) 17945720Speter printf("-%#x", (u_int)(id->id_port[1] 18045720Speter + id->id_portsize[1] - 1)); 1814109Sjkh } 18245720Speter if (id->id_maddr[0] && id->id_maddr[1]) { 18345720Speter printf(" iomem %#x", (u_int)id->id_maddr[0]); 18445720Speter if (id->id_msize[0]) 18545720Speter printf("-%#x", (u_int)(id->id_maddr[0] 18645720Speter + id->id_msize[0] - 1)); 18745720Speter printf(" and %#x", (u_int)id->id_maddr[1]); 18845720Speter if (id->id_msize[1]) 18945720Speter printf("-%#x", (u_int)(id->id_maddr[1] 19045720Speter + id->id_msize[1] - 1)); 19145720Speter } else if (id->id_maddr[0]) { 19245720Speter printf(" iomem %#x", (u_int)id->id_maddr[0]); 19345720Speter if (id->id_msize[0]) 19445720Speter printf("-%#x", (u_int)(id->id_maddr[0] 19545720Speter + id->id_msize[0] - 1)); 19645720Speter } else if (id->id_maddr[1]) { 19745720Speter printf(" iomem %#x", (u_int)id->id_maddr[1]); 19845720Speter if (id->id_msize[1]) 19945720Speter printf("-%#x", (u_int)(id->id_maddr[1] 20045720Speter + id->id_msize[1] - 1)); 201593Srgrimes } 20245720Speter if (id->id_irq[0] >= 0 && id->id_irq[1] >= 0) 20345720Speter printf(" irqs %d and %d", id->id_irq[0], id->id_irq[1]); 20445720Speter else if (id->id_irq[0] >= 0) 20545720Speter printf(" irq %d", id->id_irq[0]); 20645720Speter else if (id->id_irq[1] >= 0) 20745720Speter printf(" irq %d", id->id_irq[1]); 20845720Speter if (id->id_drq[0] >= 0 && id->id_drq[1] >= 0) 20945720Speter printf(" drqs %d and %d", id->id_drq[0], id->id_drq[1]); 21045720Speter else if (id->id_drq[0] >= 0) 21145720Speter printf(" drq %d", id->id_drq[0]); 21245720Speter else if (id->id_drq[1] >= 0) 21345720Speter printf(" drq %d", id->id_drq[1]); 21425498Sfsmp 21545720Speter if (id->id_flags) 21645720Speter printf(" flags %#x", id->id_flags); 21745720Speter 21845720Speter printf(" on %s%d", 21945720Speter device_get_name(bus), device_get_unit(bus)); 2204Srgrimes} 2214Srgrimes 22245720Speterstatic int 22345720Speterisa_read_ivar(device_t bus, device_t dev, int index, uintptr_t * result) 22413646Sbde{ 22545720Speter struct isa_device* idev = DEVTOISA(dev); 22613646Sbde 22745720Speter switch (index) { 22845720Speter case ISA_IVAR_PORT_0: 22945720Speter *result = idev->id_port[0]; 23045720Speter break; 23145720Speter case ISA_IVAR_PORT_1: 23245720Speter *result = idev->id_port[1]; 23345720Speter break; 23445720Speter case ISA_IVAR_PORTSIZE_0: 23545720Speter *result = idev->id_portsize[0]; 23645720Speter break; 23745720Speter case ISA_IVAR_PORTSIZE_1: 23845720Speter *result = idev->id_portsize[1]; 23945720Speter break; 24045720Speter case ISA_IVAR_MADDR_0: 24145720Speter *result = idev->id_maddr[0]; 24245720Speter break; 24345720Speter case ISA_IVAR_MADDR_1: 24445720Speter *result = idev->id_maddr[1]; 24545720Speter break; 24645720Speter case ISA_IVAR_MSIZE_0: 24745720Speter *result = idev->id_msize[0]; 24845720Speter break; 24945720Speter case ISA_IVAR_MSIZE_1: 25045720Speter *result = idev->id_msize[1]; 25145720Speter break; 25245720Speter case ISA_IVAR_IRQ_0: 25345720Speter *result = idev->id_irq[0]; 25445720Speter break; 25545720Speter case ISA_IVAR_IRQ_1: 25645720Speter *result = idev->id_irq[1]; 25745720Speter break; 25845720Speter case ISA_IVAR_DRQ_0: 25945720Speter *result = idev->id_drq[0]; 26045720Speter break; 26145720Speter case ISA_IVAR_DRQ_1: 26245720Speter *result = idev->id_drq[1]; 26345720Speter break; 26445720Speter case ISA_IVAR_FLAGS: 26545720Speter *result = idev->id_flags; 26645720Speter break; 26713646Sbde } 26845720Speter return ENOENT; 26913646Sbde} 27013646Sbde 27113646Sbde/* 27245720Speter * XXX -- this interface is pretty much irrelevant in the presence of 27345720Speter * BUS_ALLOC_RESOURCE / BUS_RELEASE_RESOURCE (at least for the ivars which 27445720Speter * are defined at this point). 27515147Ssmpatel */ 27645720Speterstatic int 27745720Speterisa_write_ivar(device_t bus, device_t dev, 27845720Speter int index, uintptr_t value) 27915147Ssmpatel{ 28045720Speter struct isa_device* idev = DEVTOISA(dev); 28115147Ssmpatel 28245720Speter switch (index) { 28345720Speter case ISA_IVAR_PORT_0: 28445720Speter idev->id_port[0] = value; 28545720Speter break; 28645720Speter case ISA_IVAR_PORT_1: 28745720Speter idev->id_port[1] = value; 28845720Speter break; 28945720Speter case ISA_IVAR_PORTSIZE_0: 29045720Speter idev->id_portsize[0] = value; 29145720Speter break; 29245720Speter case ISA_IVAR_PORTSIZE_1: 29345720Speter idev->id_portsize[1] = value; 29445720Speter break; 29545720Speter case ISA_IVAR_MADDR_0: 29645720Speter idev->id_maddr[0] = value; 29745720Speter break; 29845720Speter case ISA_IVAR_MADDR_1: 29945720Speter idev->id_maddr[1] = value; 30045720Speter break; 30145720Speter case ISA_IVAR_MSIZE_0: 30245720Speter idev->id_msize[0] = value; 30345720Speter break; 30445720Speter case ISA_IVAR_MSIZE_1: 30545720Speter idev->id_msize[1] = value; 30645720Speter break; 30745720Speter case ISA_IVAR_IRQ_0: 30845720Speter idev->id_irq[0] = value; 30945720Speter break; 31045720Speter case ISA_IVAR_IRQ_1: 31145720Speter idev->id_irq[1] = value; 31245720Speter break; 31345720Speter case ISA_IVAR_DRQ_0: 31445720Speter idev->id_drq[0] = value; 31545720Speter break; 31645720Speter case ISA_IVAR_DRQ_1: 31745720Speter idev->id_drq[1] = value; 31845720Speter break; 31945720Speter case ISA_IVAR_FLAGS: 32045720Speter idev->id_flags = value; 32145720Speter break; 32245720Speter default: 32345720Speter return (ENOENT); 32415147Ssmpatel } 32515147Ssmpatel return (0); 32615147Ssmpatel} 32715147Ssmpatel 32815147Ssmpatel/* 32945720Speter * This implementation simply passes the request up to the parent 33045720Speter * bus, which in our case is the special i386 nexus, substituting any 33145720Speter * configured values if the caller defaulted. We can get away with 33245720Speter * this because there is no special mapping for ISA resources on an Intel 33345720Speter * platform. When porting this code to another architecture, it may be 33445720Speter * necessary to interpose a mapping layer here. 33515147Ssmpatel */ 33645720Speterstatic struct resource * 33745720Speterisa_alloc_resource(device_t bus, device_t child, int type, int *rid, 33845720Speter u_long start, u_long end, u_long count, u_int flags) 33915147Ssmpatel{ 34045720Speter int isdefault; 34145720Speter struct resource *rv, **rvp = 0; 34245720Speter struct isa_device *id = DEVTOISA(child); 34315147Ssmpatel 34445720Speter if (child) { 34545720Speter /* 34645720Speter * If this is our child, then use the isa_device to find 34745720Speter * defaults and to record results. 34815147Ssmpatel */ 34945720Speter if (device_get_devclass(device_get_parent(child)) == isa_devclass) 35045720Speter id = DEVTOISA(child); 35145720Speter else 35245720Speter id = NULL; 35345720Speter } else 35445720Speter id = NULL; 35545720Speter isdefault = (id != NULL && start == 0UL && end == ~0UL && *rid == 0); 35645720Speter if (*rid > 1) 35745720Speter return 0; 35815147Ssmpatel 35945720Speter switch (type) { 36045720Speter case SYS_RES_IRQ: 36145720Speter if (isdefault && id->id_irq[0] >= 0) { 36245720Speter start = id->id_irq[0]; 36345720Speter end = id->id_irq[0]; 36445720Speter count = 1; 36545720Speter } 36645720Speter if (id) 36745720Speter rvp = &id->id_irqres[*rid]; 36845720Speter break; 36915147Ssmpatel 37045720Speter case SYS_RES_DRQ: 37145720Speter if (isdefault && id->id_drq[0] >= 0) { 37245720Speter start = id->id_drq[0]; 37345720Speter end = id->id_drq[0]; 37445720Speter count = 1; 37545720Speter } 37645720Speter if (id) 37745720Speter rvp = &id->id_drqres[*rid]; 37845720Speter break; 3794Srgrimes 38045720Speter case SYS_RES_MEMORY: 38145720Speter if (isdefault && id->id_maddr[0]) { 38245720Speter start = id->id_maddr[0]; 38345720Speter count = max(count, (u_long)id->id_msize[0]); 38445720Speter end = id->id_maddr[0] + count; 38545720Speter } 38645720Speter if (id) 38745720Speter rvp = &id->id_memres[*rid]; 38845720Speter break; 3894Srgrimes 39045720Speter case SYS_RES_IOPORT: 39145720Speter if (isdefault && id->id_port[0]) { 39245720Speter start = id->id_port[0]; 39345720Speter count = max(count, (u_long)id->id_portsize[0]); 39445720Speter end = id->id_port[0] + count; 39545720Speter } 39645720Speter if (id) 39745720Speter rvp = &id->id_portres[*rid]; 39845720Speter break; 3994Srgrimes 40045720Speter default: 40145720Speter return 0; 40245720Speter } 40315147Ssmpatel 40445720Speter /* 40545720Speter * If the client attempts to reallocate a resource without 40645720Speter * releasing what was there previously, die horribly so that 40745720Speter * he knows how he !@#$ed up. 40845720Speter */ 40945720Speter if (rvp && *rvp != 0) 41045720Speter panic("%s%d: (%d, %d) not free for %s%d\n", 41145720Speter device_get_name(bus), device_get_unit(bus), 41245720Speter type, *rid, 41345720Speter device_get_name(child), device_get_unit(child)); 4144Srgrimes 41525498Sfsmp /* 41645720Speter * nexus_alloc_resource had better not change *rid... 41725498Sfsmp */ 41845720Speter rv = BUS_ALLOC_RESOURCE(device_get_parent(bus), child, type, rid, 41945720Speter start, end, count, flags); 42045720Speter if (rvp && (*rvp = rv) != 0) { 42145720Speter switch (type) { 42245720Speter case SYS_RES_MEMORY: 42345720Speter id->id_maddr[*rid] = rv->r_start; 42445720Speter id->id_msize[*rid] = count; 42545720Speter break; 42645720Speter case SYS_RES_IOPORT: 42745720Speter id->id_port[*rid] = rv->r_start; 42845720Speter id->id_portsize[*rid] = count; 42945720Speter break; 43045720Speter case SYS_RES_IRQ: 43145720Speter id->id_irq[*rid] = rv->r_start; 43245720Speter break; 43345720Speter case SYS_RES_DRQ: 43445720Speter id->id_drq[*rid] = rv->r_start; 43545720Speter break; 43645720Speter } 43745720Speter } 43845720Speter return rv; 43945720Speter} 44015147Ssmpatel 44145720Speterstatic int 44245720Speterisa_release_resource(device_t bus, device_t child, int type, int rid, 44345720Speter struct resource *r) 44445720Speter{ 44545720Speter int rv; 44645720Speter struct isa_device *id = DEVTOISA(child); 44715147Ssmpatel 44845720Speter if (rid > 1) 44945720Speter return EINVAL; 4504Srgrimes 45145720Speter switch (type) { 45245720Speter case SYS_RES_IRQ: 45345720Speter case SYS_RES_DRQ: 45445720Speter case SYS_RES_IOPORT: 45545720Speter case SYS_RES_MEMORY: 45645720Speter break; 45745720Speter default: 45845720Speter return (ENOENT); 4594Srgrimes } 4604Srgrimes 46145720Speter rv = BUS_RELEASE_RESOURCE(device_get_parent(bus), child, type, rid, r); 4624Srgrimes 46345720Speter if (rv == 0) { 46445720Speter switch (type) { 46545720Speter case SYS_RES_IRQ: 46645720Speter id->id_irqres[rid] = 0; 46745720Speter break; 4684051Sache 46945720Speter case SYS_RES_DRQ: 47045720Speter id->id_drqres[rid] = 0; 47145720Speter break; 4724Srgrimes 47345720Speter case SYS_RES_MEMORY: 47445720Speter id->id_memres[rid] = 0; 47545720Speter break; 4764Srgrimes 47745720Speter case SYS_RES_IOPORT: 47845720Speter id->id_portres[rid] = 0; 47945720Speter break; 4804Srgrimes 48145720Speter default: 48245720Speter return ENOENT; 4834051Sache } 4844Srgrimes } 4854Srgrimes 48645720Speter return rv; 4874Srgrimes} 4884Srgrimes 4894Srgrimes/* 49045720Speter * We can't use the bus_generic_* versions of these methods because those 49145720Speter * methods always pass the bus param as the requesting device, and we need 49245720Speter * to pass the child (the i386 nexus knows about this and is prepared to 49345720Speter * deal). 4944Srgrimes */ 4952103Sdgstatic int 49646743Sdfrisa_setup_intr(device_t bus, device_t child, struct resource *r, int flags, 49745720Speter void (*ihand)(void *), void *arg, void **cookiep) 49831457Sjmg{ 49946743Sdfr return (BUS_SETUP_INTR(device_get_parent(bus), child, r, flags, 50046743Sdfr ihand, arg, cookiep)); 5014Srgrimes} 5024Srgrimes 50345720Speterstatic int 50445720Speterisa_teardown_intr(device_t bus, device_t child, struct resource *r, 50545720Speter void *cookie) 50627639Smsmith{ 50745720Speter return (BUS_TEARDOWN_INTR(device_get_parent(bus), child, r, cookie)); 50827639Smsmith} 50927639Smsmith 51045720Speterstatic device_method_t isa_methods[] = { 51145720Speter /* Device interface */ 51245720Speter DEVMETHOD(device_probe, isa_probe), 51345720Speter DEVMETHOD(device_attach, isa_attach), 51445720Speter DEVMETHOD(device_detach, bus_generic_detach), 51545720Speter DEVMETHOD(device_shutdown, bus_generic_shutdown), 51645720Speter DEVMETHOD(device_suspend, bus_generic_suspend), 51745720Speter DEVMETHOD(device_resume, bus_generic_resume), 51828847Smsmith 51945720Speter /* Bus interface */ 52047178Sdfr DEVMETHOD(bus_add_child, isa_add_child), 52145720Speter DEVMETHOD(bus_print_child, isa_print_child), 52245720Speter DEVMETHOD(bus_read_ivar, isa_read_ivar), 52345720Speter DEVMETHOD(bus_write_ivar, isa_write_ivar), 52445720Speter DEVMETHOD(bus_alloc_resource, isa_alloc_resource), 52545720Speter DEVMETHOD(bus_release_resource, isa_release_resource), 52645720Speter DEVMETHOD(bus_activate_resource, bus_generic_activate_resource), 52745720Speter DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource), 52845720Speter DEVMETHOD(bus_setup_intr, isa_setup_intr), 52945720Speter DEVMETHOD(bus_teardown_intr, isa_teardown_intr), 53028847Smsmith 53145720Speter { 0, 0 } 53245720Speter}; 53310666Sbde 53445720Speterstatic driver_t isa_driver = { 53545720Speter "isa", 53645720Speter isa_methods, 53745720Speter 1, /* no softc */ 53845720Speter}; 53910666Sbde 54010666Sbde/* 54145720Speter * ISA can be attached to a PCI-ISA bridge or directly to the nexus. 5424Srgrimes */ 54345720SpeterDRIVER_MODULE(isa, isab, isa_driver, isa_devclass, 0, 0); 54445720SpeterDRIVER_MODULE(isa, nexus, isa_driver, isa_devclass, 0, 0); 545