isa.c revision 46015
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 * 2646015Skato * $Id: isa.c,v 1.121 1999/04/24 06:47:24 peter 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 952103Sdgstatic void 9645720Speterisa_add_device(device_t dev, const char *name, int unit) 97593Srgrimes{ 9845720Speter struct isa_device *idev; 9945720Speter device_t child; 10045720Speter int sensitive, t; 10145720Speter static device_t last_sensitive; 1024Srgrimes 10345720Speter if (resource_int_value(name, unit, "sensitive", &sensitive) != 0) 10445720Speter sensitive = 0; 1052103Sdg 10645720Speter idev = malloc(sizeof(struct isa_device), M_ISADEV, M_NOWAIT); 10745720Speter if (!idev) 10845720Speter return; 10945720Speter bzero(idev, sizeof *idev); 11032922Seivind 11145720Speter if (resource_int_value(name, unit, "port", &t) == 0) 11245720Speter idev->id_port[0] = t; 11345720Speter else 11445720Speter idev->id_port[0] = -1; 11545720Speter idev->id_port[1] = 0; 1164Srgrimes 11745720Speter if (resource_int_value(name, unit, "portsize", &t) == 0) 11845720Speter idev->id_portsize[0] = t; 11945720Speter else 12045720Speter idev->id_portsize[0] = 0; 12145720Speter idev->id_portsize[1] = 0; 12226157Sse 12345720Speter if (resource_int_value(name, unit, "maddr", &t) == 0) 12445720Speter idev->id_maddr[0] = t; 12545720Speter else 12645720Speter idev->id_maddr[0] = 0; 12745720Speter idev->id_maddr[1] = 0; 12826157Sse 12945720Speter if (resource_int_value(name, unit, "msize", &t) == 0) 13045720Speter idev->id_msize[0] = t; 13145720Speter else 13245720Speter idev->id_msize[0] = 0; 13345720Speter idev->id_msize[1] = 0; 13426157Sse 13545720Speter if (resource_int_value(name, unit, "flags", &t) == 0) 13645720Speter idev->id_flags = t; 13745720Speter else 13845720Speter idev->id_flags = 0; 13926157Sse 14045720Speter if (resource_int_value(name, unit, "irq", &t) == 0) 14145720Speter idev->id_irq[0] = t; 14245720Speter else 14345720Speter idev->id_irq[0] = -1; 14445720Speter idev->id_irq[1] = -1; 14526157Sse 14645720Speter if (resource_int_value(name, unit, "drq", &t) == 0) 14745720Speter idev->id_drq[0] = t; 14845720Speter else 14945720Speter idev->id_drq[0] = -1; 15045720Speter idev->id_drq[1] = -1; 1514Srgrimes 15245720Speter if (sensitive) 15345720Speter child = device_add_child_after(dev, last_sensitive, name, 15445720Speter unit, idev); 15545720Speter else 15645720Speter child = device_add_child(dev, name, unit, idev); 15745720Speter if (child == 0) 15845720Speter return; 15945720Speter else if (sensitive) 16045720Speter last_sensitive = child; 16145720Speter 16245720Speter if (resource_int_value(name, unit, "disabled", &t) == 0 && t != 0) 16345720Speter device_disable(child); 1644Srgrimes} 165593Srgrimes 1664Srgrimes/* 16745720Speter * At 'probe' time, we add all the devices which we know about to the 16845720Speter * bus. The generic attach routine will probe and attach them if they 16945720Speter * are alive. 1704Srgrimes */ 17145720Speterstatic int 17245720Speterisa_probe(device_t dev) 17331457Sjmg{ 17445720Speter int i; 17545720Speter static char buf[] = "isaXXX"; 1764Srgrimes 17745720Speter device_set_desc(dev, "ISA bus"); 1783670Sphk 17945720Speter /* 18045720Speter * Add all devices configured to be attached to isa0. 18145720Speter */ 18245720Speter sprintf(buf, "isa%d", device_get_unit(dev)); 18345720Speter for (i = resource_query_string(-1, "at", buf); 18445720Speter i != -1; 18545720Speter i = resource_query_string(i, "at", buf)) { 18645723Speter if (strcmp(resource_query_name(i), "atkbd") == 0) 18745723Speter continue; /* old GENERIC kludge */ 18845720Speter isa_add_device(dev, resource_query_name(i), 18945720Speter resource_query_unit(i)); 19045720Speter } 1913670Sphk 1922103Sdg /* 19345720Speter * and isa? 1942103Sdg */ 19545720Speter for (i = resource_query_string(-1, "at", "isa"); 19645720Speter i != -1; 19745720Speter i = resource_query_string(i, "at", "isa")) { 19845723Speter if (strcmp(resource_query_name(i), "atkbd") == 0) 19945723Speter continue; /* old GENERIC kludge */ 20045720Speter isa_add_device(dev, resource_query_name(i), 20145720Speter resource_query_unit(i)); 20245720Speter } 2034Srgrimes 20445720Speter isa_wrap_old_drivers(); 20545720Speter 20645720Speter return 0; 2073258Sdg} 2088876Srgrimes 20945720Speterextern device_t isa_bus_device; 21045720Speter 21145720Speterstatic int 21245720Speterisa_attach(device_t dev) 2134Srgrimes{ 21445720Speter /* 21545720Speter * Arrange for bus_generic_attach(dev) to be called later. 21645720Speter */ 21745720Speter isa_bus_device = dev; 21845720Speter return 0; 2193258Sdg} 2203258Sdg 2213258Sdgstatic void 22245720Speterisa_print_child(device_t bus, device_t dev) 2233258Sdg{ 22445720Speter struct isa_device *id = DEVTOISA(dev); 2258876Srgrimes 22645720Speter if (id->id_port[0] > 0 || id->id_port[1] > 0 22745720Speter || id->id_maddr[0] > 0 || id->id_maddr[1] > 0 22845720Speter || id->id_irq[0] >= 0 || id->id_irq[1] >= 0 22945720Speter || id->id_drq[0] >= 0 || id->id_drq[1] >= 0) 23045720Speter printf(" at"); 23145720Speter if (id->id_port[0] > 0 && id->id_port[1] > 0) { 23245720Speter printf(" ports %#x", (u_int)id->id_port[0]); 23345720Speter if (id->id_portsize[0] > 1) 23445720Speter printf("-%#x", (u_int)(id->id_port[0] 23545720Speter + id->id_portsize[0] - 1)); 23645720Speter printf(" and %#x", (u_int)id->id_port[1]); 23745720Speter if (id->id_portsize[1] > 1) 23845720Speter printf("-%#x", (u_int)(id->id_port[1] 23945720Speter + id->id_portsize[1] - 1)); 24045720Speter } else if (id->id_port[0] > 0) { 24145720Speter printf(" port %#x", (u_int)id->id_port[0]); 24245720Speter if (id->id_portsize[0] > 1) 24345720Speter printf("-%#x", (u_int)(id->id_port[0] 24445720Speter + id->id_portsize[0] - 1)); 24545720Speter } else if (id->id_port[1] > 0) { 24645720Speter printf(" port %#x", (u_int)id->id_port[1]); 24745720Speter if (id->id_portsize[1] > 1) 24845720Speter printf("-%#x", (u_int)(id->id_port[1] 24945720Speter + id->id_portsize[1] - 1)); 2504109Sjkh } 25145720Speter if (id->id_maddr[0] && id->id_maddr[1]) { 25245720Speter printf(" iomem %#x", (u_int)id->id_maddr[0]); 25345720Speter if (id->id_msize[0]) 25445720Speter printf("-%#x", (u_int)(id->id_maddr[0] 25545720Speter + id->id_msize[0] - 1)); 25645720Speter printf(" and %#x", (u_int)id->id_maddr[1]); 25745720Speter if (id->id_msize[1]) 25845720Speter printf("-%#x", (u_int)(id->id_maddr[1] 25945720Speter + id->id_msize[1] - 1)); 26045720Speter } else if (id->id_maddr[0]) { 26145720Speter printf(" iomem %#x", (u_int)id->id_maddr[0]); 26245720Speter if (id->id_msize[0]) 26345720Speter printf("-%#x", (u_int)(id->id_maddr[0] 26445720Speter + id->id_msize[0] - 1)); 26545720Speter } else if (id->id_maddr[1]) { 26645720Speter printf(" iomem %#x", (u_int)id->id_maddr[1]); 26745720Speter if (id->id_msize[1]) 26845720Speter printf("-%#x", (u_int)(id->id_maddr[1] 26945720Speter + id->id_msize[1] - 1)); 270593Srgrimes } 27145720Speter if (id->id_irq[0] >= 0 && id->id_irq[1] >= 0) 27245720Speter printf(" irqs %d and %d", id->id_irq[0], id->id_irq[1]); 27345720Speter else if (id->id_irq[0] >= 0) 27445720Speter printf(" irq %d", id->id_irq[0]); 27545720Speter else if (id->id_irq[1] >= 0) 27645720Speter printf(" irq %d", id->id_irq[1]); 27745720Speter if (id->id_drq[0] >= 0 && id->id_drq[1] >= 0) 27845720Speter printf(" drqs %d and %d", id->id_drq[0], id->id_drq[1]); 27945720Speter else if (id->id_drq[0] >= 0) 28045720Speter printf(" drq %d", id->id_drq[0]); 28145720Speter else if (id->id_drq[1] >= 0) 28245720Speter printf(" drq %d", id->id_drq[1]); 28325498Sfsmp 28445720Speter if (id->id_flags) 28545720Speter printf(" flags %#x", id->id_flags); 28645720Speter 28745720Speter printf(" on %s%d", 28845720Speter device_get_name(bus), device_get_unit(bus)); 2894Srgrimes} 2904Srgrimes 29145720Speterstatic int 29245720Speterisa_read_ivar(device_t bus, device_t dev, int index, uintptr_t * result) 29313646Sbde{ 29445720Speter struct isa_device* idev = DEVTOISA(dev); 29513646Sbde 29645720Speter switch (index) { 29745720Speter case ISA_IVAR_PORT_0: 29845720Speter *result = idev->id_port[0]; 29945720Speter break; 30045720Speter case ISA_IVAR_PORT_1: 30145720Speter *result = idev->id_port[1]; 30245720Speter break; 30345720Speter case ISA_IVAR_PORTSIZE_0: 30445720Speter *result = idev->id_portsize[0]; 30545720Speter break; 30645720Speter case ISA_IVAR_PORTSIZE_1: 30745720Speter *result = idev->id_portsize[1]; 30845720Speter break; 30945720Speter case ISA_IVAR_MADDR_0: 31045720Speter *result = idev->id_maddr[0]; 31145720Speter break; 31245720Speter case ISA_IVAR_MADDR_1: 31345720Speter *result = idev->id_maddr[1]; 31445720Speter break; 31545720Speter case ISA_IVAR_MSIZE_0: 31645720Speter *result = idev->id_msize[0]; 31745720Speter break; 31845720Speter case ISA_IVAR_MSIZE_1: 31945720Speter *result = idev->id_msize[1]; 32045720Speter break; 32145720Speter case ISA_IVAR_IRQ_0: 32245720Speter *result = idev->id_irq[0]; 32345720Speter break; 32445720Speter case ISA_IVAR_IRQ_1: 32545720Speter *result = idev->id_irq[1]; 32645720Speter break; 32745720Speter case ISA_IVAR_DRQ_0: 32845720Speter *result = idev->id_drq[0]; 32945720Speter break; 33045720Speter case ISA_IVAR_DRQ_1: 33145720Speter *result = idev->id_drq[1]; 33245720Speter break; 33345720Speter case ISA_IVAR_FLAGS: 33445720Speter *result = idev->id_flags; 33545720Speter break; 33613646Sbde } 33745720Speter return ENOENT; 33813646Sbde} 33913646Sbde 34013646Sbde/* 34145720Speter * XXX -- this interface is pretty much irrelevant in the presence of 34245720Speter * BUS_ALLOC_RESOURCE / BUS_RELEASE_RESOURCE (at least for the ivars which 34345720Speter * are defined at this point). 34415147Ssmpatel */ 34545720Speterstatic int 34645720Speterisa_write_ivar(device_t bus, device_t dev, 34745720Speter int index, uintptr_t value) 34815147Ssmpatel{ 34945720Speter struct isa_device* idev = DEVTOISA(dev); 35015147Ssmpatel 35145720Speter switch (index) { 35245720Speter case ISA_IVAR_PORT_0: 35345720Speter idev->id_port[0] = value; 35445720Speter break; 35545720Speter case ISA_IVAR_PORT_1: 35645720Speter idev->id_port[1] = value; 35745720Speter break; 35845720Speter case ISA_IVAR_PORTSIZE_0: 35945720Speter idev->id_portsize[0] = value; 36045720Speter break; 36145720Speter case ISA_IVAR_PORTSIZE_1: 36245720Speter idev->id_portsize[1] = value; 36345720Speter break; 36445720Speter case ISA_IVAR_MADDR_0: 36545720Speter idev->id_maddr[0] = value; 36645720Speter break; 36745720Speter case ISA_IVAR_MADDR_1: 36845720Speter idev->id_maddr[1] = value; 36945720Speter break; 37045720Speter case ISA_IVAR_MSIZE_0: 37145720Speter idev->id_msize[0] = value; 37245720Speter break; 37345720Speter case ISA_IVAR_MSIZE_1: 37445720Speter idev->id_msize[1] = value; 37545720Speter break; 37645720Speter case ISA_IVAR_IRQ_0: 37745720Speter idev->id_irq[0] = value; 37845720Speter break; 37945720Speter case ISA_IVAR_IRQ_1: 38045720Speter idev->id_irq[1] = value; 38145720Speter break; 38245720Speter case ISA_IVAR_DRQ_0: 38345720Speter idev->id_drq[0] = value; 38445720Speter break; 38545720Speter case ISA_IVAR_DRQ_1: 38645720Speter idev->id_drq[1] = value; 38745720Speter break; 38845720Speter case ISA_IVAR_FLAGS: 38945720Speter idev->id_flags = value; 39045720Speter break; 39145720Speter default: 39245720Speter return (ENOENT); 39315147Ssmpatel } 39415147Ssmpatel return (0); 39515147Ssmpatel} 39615147Ssmpatel 39715147Ssmpatel/* 39845720Speter * This implementation simply passes the request up to the parent 39945720Speter * bus, which in our case is the special i386 nexus, substituting any 40045720Speter * configured values if the caller defaulted. We can get away with 40145720Speter * this because there is no special mapping for ISA resources on an Intel 40245720Speter * platform. When porting this code to another architecture, it may be 40345720Speter * necessary to interpose a mapping layer here. 40415147Ssmpatel */ 40545720Speterstatic struct resource * 40645720Speterisa_alloc_resource(device_t bus, device_t child, int type, int *rid, 40745720Speter u_long start, u_long end, u_long count, u_int flags) 40815147Ssmpatel{ 40945720Speter int isdefault; 41045720Speter struct resource *rv, **rvp = 0; 41145720Speter struct isa_device *id = DEVTOISA(child); 41215147Ssmpatel 41345720Speter if (child) { 41445720Speter /* 41545720Speter * If this is our child, then use the isa_device to find 41645720Speter * defaults and to record results. 41715147Ssmpatel */ 41845720Speter if (device_get_devclass(device_get_parent(child)) == isa_devclass) 41945720Speter id = DEVTOISA(child); 42045720Speter else 42145720Speter id = NULL; 42245720Speter } else 42345720Speter id = NULL; 42445720Speter isdefault = (id != NULL && start == 0UL && end == ~0UL && *rid == 0); 42545720Speter if (*rid > 1) 42645720Speter return 0; 42715147Ssmpatel 42845720Speter switch (type) { 42945720Speter case SYS_RES_IRQ: 43045720Speter if (isdefault && id->id_irq[0] >= 0) { 43145720Speter start = id->id_irq[0]; 43245720Speter end = id->id_irq[0]; 43345720Speter count = 1; 43445720Speter } 43545720Speter if (id) 43645720Speter rvp = &id->id_irqres[*rid]; 43745720Speter break; 43815147Ssmpatel 43945720Speter case SYS_RES_DRQ: 44045720Speter if (isdefault && id->id_drq[0] >= 0) { 44145720Speter start = id->id_drq[0]; 44245720Speter end = id->id_drq[0]; 44345720Speter count = 1; 44445720Speter } 44545720Speter if (id) 44645720Speter rvp = &id->id_drqres[*rid]; 44745720Speter break; 4484Srgrimes 44945720Speter case SYS_RES_MEMORY: 45045720Speter if (isdefault && id->id_maddr[0]) { 45145720Speter start = id->id_maddr[0]; 45245720Speter count = max(count, (u_long)id->id_msize[0]); 45345720Speter end = id->id_maddr[0] + count; 45445720Speter } 45545720Speter if (id) 45645720Speter rvp = &id->id_memres[*rid]; 45745720Speter break; 4584Srgrimes 45945720Speter case SYS_RES_IOPORT: 46045720Speter if (isdefault && id->id_port[0]) { 46145720Speter start = id->id_port[0]; 46245720Speter count = max(count, (u_long)id->id_portsize[0]); 46345720Speter end = id->id_port[0] + count; 46445720Speter } 46545720Speter if (id) 46645720Speter rvp = &id->id_portres[*rid]; 46745720Speter break; 4684Srgrimes 46945720Speter default: 47045720Speter return 0; 47145720Speter } 47215147Ssmpatel 47345720Speter /* 47445720Speter * If the client attempts to reallocate a resource without 47545720Speter * releasing what was there previously, die horribly so that 47645720Speter * he knows how he !@#$ed up. 47745720Speter */ 47845720Speter if (rvp && *rvp != 0) 47945720Speter panic("%s%d: (%d, %d) not free for %s%d\n", 48045720Speter device_get_name(bus), device_get_unit(bus), 48145720Speter type, *rid, 48245720Speter device_get_name(child), device_get_unit(child)); 4834Srgrimes 48425498Sfsmp /* 48545720Speter * nexus_alloc_resource had better not change *rid... 48625498Sfsmp */ 48745720Speter rv = BUS_ALLOC_RESOURCE(device_get_parent(bus), child, type, rid, 48845720Speter start, end, count, flags); 48945720Speter if (rvp && (*rvp = rv) != 0) { 49045720Speter switch (type) { 49145720Speter case SYS_RES_MEMORY: 49245720Speter id->id_maddr[*rid] = rv->r_start; 49345720Speter id->id_msize[*rid] = count; 49445720Speter break; 49545720Speter case SYS_RES_IOPORT: 49645720Speter id->id_port[*rid] = rv->r_start; 49745720Speter id->id_portsize[*rid] = count; 49845720Speter break; 49945720Speter case SYS_RES_IRQ: 50045720Speter id->id_irq[*rid] = rv->r_start; 50145720Speter break; 50245720Speter case SYS_RES_DRQ: 50345720Speter id->id_drq[*rid] = rv->r_start; 50445720Speter break; 50545720Speter } 50645720Speter } 50745720Speter return rv; 50845720Speter} 50915147Ssmpatel 51045720Speterstatic int 51145720Speterisa_release_resource(device_t bus, device_t child, int type, int rid, 51245720Speter struct resource *r) 51345720Speter{ 51445720Speter int rv; 51545720Speter struct isa_device *id = DEVTOISA(child); 51615147Ssmpatel 51745720Speter if (rid > 1) 51845720Speter return EINVAL; 5194Srgrimes 52045720Speter switch (type) { 52145720Speter case SYS_RES_IRQ: 52245720Speter case SYS_RES_DRQ: 52345720Speter case SYS_RES_IOPORT: 52445720Speter case SYS_RES_MEMORY: 52545720Speter break; 52645720Speter default: 52745720Speter return (ENOENT); 5284Srgrimes } 5294Srgrimes 53045720Speter rv = BUS_RELEASE_RESOURCE(device_get_parent(bus), child, type, rid, r); 5314Srgrimes 53245720Speter#if 0 53345720Speter if (rv) { 53445720Speter /* Kludge, isa as a child of pci doesn't have mapping regs */ 53545720Speter printf("WARNING: isa_release_resource: BUS_RELEASE_RESOURCE() failed: %d\n", rv); 53645720Speter rv = 0; 53728847Smsmith } 53845720Speter#endif 53928847Smsmith 54045720Speter if (rv == 0) { 54145720Speter switch (type) { 54245720Speter case SYS_RES_IRQ: 54345720Speter id->id_irqres[rid] = 0; 54445720Speter break; 5454051Sache 54645720Speter case SYS_RES_DRQ: 54745720Speter id->id_drqres[rid] = 0; 54845720Speter break; 5494Srgrimes 55045720Speter case SYS_RES_MEMORY: 55145720Speter id->id_memres[rid] = 0; 55245720Speter break; 5534Srgrimes 55445720Speter case SYS_RES_IOPORT: 55545720Speter id->id_portres[rid] = 0; 55645720Speter break; 5574Srgrimes 55845720Speter default: 55945720Speter return ENOENT; 5604051Sache } 5614Srgrimes } 5624Srgrimes 56345720Speter return rv; 5644Srgrimes} 5654Srgrimes 5664Srgrimes/* 56745720Speter * We can't use the bus_generic_* versions of these methods because those 56845720Speter * methods always pass the bus param as the requesting device, and we need 56945720Speter * to pass the child (the i386 nexus knows about this and is prepared to 57045720Speter * deal). 5714Srgrimes */ 5722103Sdgstatic int 57345720Speterisa_setup_intr(device_t bus, device_t child, struct resource *r, 57445720Speter void (*ihand)(void *), void *arg, void **cookiep) 57531457Sjmg{ 57645720Speter return (BUS_SETUP_INTR(device_get_parent(bus), child, r, ihand, arg, 57745720Speter cookiep)); 5784Srgrimes} 5794Srgrimes 58045720Speterstatic int 58145720Speterisa_teardown_intr(device_t bus, device_t child, struct resource *r, 58245720Speter void *cookie) 58327639Smsmith{ 58445720Speter return (BUS_TEARDOWN_INTR(device_get_parent(bus), child, r, cookie)); 58527639Smsmith} 58627639Smsmith 58745720Speterstatic device_method_t isa_methods[] = { 58845720Speter /* Device interface */ 58945720Speter DEVMETHOD(device_probe, isa_probe), 59045720Speter DEVMETHOD(device_attach, isa_attach), 59145720Speter DEVMETHOD(device_detach, bus_generic_detach), 59245720Speter DEVMETHOD(device_shutdown, bus_generic_shutdown), 59345720Speter DEVMETHOD(device_suspend, bus_generic_suspend), 59445720Speter DEVMETHOD(device_resume, bus_generic_resume), 59528847Smsmith 59645720Speter /* Bus interface */ 59745720Speter DEVMETHOD(bus_print_child, isa_print_child), 59845720Speter DEVMETHOD(bus_read_ivar, isa_read_ivar), 59945720Speter DEVMETHOD(bus_write_ivar, isa_write_ivar), 60045720Speter DEVMETHOD(bus_alloc_resource, isa_alloc_resource), 60145720Speter DEVMETHOD(bus_release_resource, isa_release_resource), 60245720Speter DEVMETHOD(bus_activate_resource, bus_generic_activate_resource), 60345720Speter DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource), 60445720Speter DEVMETHOD(bus_setup_intr, isa_setup_intr), 60545720Speter DEVMETHOD(bus_teardown_intr, isa_teardown_intr), 60628847Smsmith 60745720Speter { 0, 0 } 60845720Speter}; 60910666Sbde 61045720Speterstatic driver_t isa_driver = { 61145720Speter "isa", 61245720Speter isa_methods, 61345720Speter DRIVER_TYPE_MISC, 61445720Speter 1, /* no softc */ 61545720Speter}; 61610666Sbde 61710666Sbde/* 61845720Speter * ISA can be attached to a PCI-ISA bridge or directly to the nexus. 6194Srgrimes */ 62045720SpeterDRIVER_MODULE(isa, isab, isa_driver, isa_devclass, 0, 0); 62145720SpeterDRIVER_MODULE(isa, nexus, isa_driver, isa_devclass, 0, 0); 622