1 /* $NetBSD: isa.c,v 1.94 1997/01/26 03:49:28 cgd Exp $ */ 2 3 /*- 4 * Copyright (c) 1993, 1994 Charles Hannum. All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 3. All advertising materials mentioning features or use of this software 15 * must display the following acknowledgement: 16 * This product includes software developed by Charles Hannum. 17 * 4. The name of the author may not be used to endorse or promote products 18 * derived from this software without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 21 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 22 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 23 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 24 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 25 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 29 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32 #include <sys/param.h> 33 #include <sys/systm.h> 34 #include <sys/kernel.h> 35 #include <sys/conf.h> 36 #include <sys/malloc.h> 37 #include <sys/device.h> 38 39 #include <machine/intr.h> 40 41 #include <dev/isa/isareg.h> 42 #include <dev/isa/isavar.h> 43 44 #ifdef __BROKEN_INDIRECT_CONFIG 45 int isamatch __P((struct device *, void *, void *)); 46 #else 47 int isamatch __P((struct device *, struct cfdata *, void *)); 48 #endif 49 void isaattach __P((struct device *, struct device *, void *)); 50 int isaprint __P((void *, const char *)); 51 52 struct cfattach isa_ca = { 53 sizeof(struct isa_softc), isamatch, isaattach 54 }; 55 56 struct cfdriver isa_cd = { 57 #ifdef __BROKEN_INDIRECT_CONFIG 58 NULL, "isa", DV_DULL, 1 59 #else 60 NULL, "isa", DV_DULL 61 #endif 62 }; 63 64 #ifdef __BROKEN_INDIRECT_CONFIG 65 void isascan __P((struct device *, void *)); 66 #else 67 int isasearch __P((struct device *, struct cfdata *, void *)); 68 #endif 69 70 int 71 #ifdef __BROKEN_INDIRECT_CONFIG 72 isamatch(parent, match, aux) 73 #else 74 isamatch(parent, cf, aux) 75 #endif 76 struct device *parent; 77 #ifdef __BROKEN_INDIRECT_CONFIG 78 void *match; 79 #else 80 struct cfdata *cf; 81 #endif 82 void *aux; 83 { 84 #ifdef __BROKEN_INDIRECT_CONFIG 85 struct cfdata *cf = match; 86 #endif 87 struct isabus_attach_args *iba = aux; 88 89 if (strcmp(iba->iba_busname, cf->cf_driver->cd_name)) 90 return (0); 91 92 /* XXX check other indicators */ 93 94 return (1); 95 } 96 97 void 98 isaattach(parent, self, aux) 99 struct device *parent, *self; 100 void *aux; 101 { 102 struct isa_softc *sc = (struct isa_softc *)self; 103 struct isabus_attach_args *iba = aux; 104 105 isa_attach_hook(parent, self, iba); 106 printf("\n"); 107 108 sc->sc_iot = iba->iba_iot; 109 sc->sc_memt = iba->iba_memt; 110 sc->sc_ic = iba->iba_ic; 111 112 /* 113 * Map port 0x84, which causes a 1.25us delay when read. 114 * We do this now, since several drivers need it. 115 */ 116 if (bus_space_map(sc->sc_iot, 0x84, 1, 0, &sc->sc_delaybah)) 117 panic("isaattach: can't map `delay port'"); /* XXX */ 118 119 TAILQ_INIT(&sc->sc_subdevs); 120 #ifdef __BROKEN_INDIRECT_CONFIG 121 config_scan(isascan, self); 122 #else 123 config_search(isasearch, self, NULL); 124 #endif 125 } 126 127 int 128 isaprint(aux, isa) 129 void *aux; 130 const char *isa; 131 { 132 struct isa_attach_args *ia = aux; 133 134 if (ia->ia_iosize) 135 printf(" port 0x%x", ia->ia_iobase); 136 if (ia->ia_iosize > 1) 137 printf("-0x%x", ia->ia_iobase + ia->ia_iosize - 1); 138 if (ia->ia_msize) 139 printf(" iomem 0x%x", ia->ia_maddr); 140 if (ia->ia_msize > 1) 141 printf("-0x%x", ia->ia_maddr + ia->ia_msize - 1); 142 if (ia->ia_irq != IRQUNK) 143 printf(" irq %d", ia->ia_irq); 144 if (ia->ia_drq != DRQUNK) 145 printf(" drq %d", ia->ia_drq); 146 return (UNCONF); 147 } 148 149 #ifdef __BROKEN_INDIRECT_CONFIG 150 void 151 isascan(parent, match) 152 struct device *parent; 153 void *match; 154 { 155 struct isa_softc *sc = (struct isa_softc *)parent; 156 struct device *dev = match; 157 struct cfdata *cf = dev->dv_cfdata; 158 struct isa_attach_args ia; 159 160 #if defined(__i386__) 161 if (cf->cf_fstate == FSTATE_STAR) 162 panic("clone devices not supported on ISA bus"); 163 #endif 164 165 ia.ia_iot = sc->sc_iot; 166 ia.ia_memt = sc->sc_memt; 167 ia.ia_ic = sc->sc_ic; 168 ia.ia_iobase = cf->cf_loc[0]; 169 ia.ia_iosize = 0x666; 170 ia.ia_maddr = cf->cf_loc[2]; 171 ia.ia_msize = cf->cf_loc[3]; 172 ia.ia_irq = cf->cf_loc[4] == 2 ? 9 : cf->cf_loc[4]; 173 ia.ia_drq = cf->cf_loc[5]; 174 ia.ia_delaybah = sc->sc_delaybah; 175 176 if ((*cf->cf_attach->ca_match)(parent, match, &ia) > 0) 177 config_attach(parent, match, &ia, isaprint); 178 else 179 free(dev, M_DEVBUF); 180 } 181 #else /* !__BROKEN_INDIRECT_CONFIG */ 182 int 183 isasearch(parent, cf, aux) 184 struct device *parent; 185 struct cfdata *cf; 186 void *aux; 187 { 188 struct isa_softc *sc = (struct isa_softc *)parent; 189 struct isa_attach_args ia; 190 int tryagain; 191 192 do { 193 ia.ia_iot = sc->sc_iot; 194 ia.ia_memt = sc->sc_memt; 195 ia.ia_ic = sc->sc_ic; 196 ia.ia_iobase = cf->cf_loc[0]; 197 ia.ia_iosize = 0x666; 198 ia.ia_maddr = cf->cf_loc[2]; 199 ia.ia_msize = cf->cf_loc[3]; 200 ia.ia_irq = cf->cf_loc[4] == 2 ? 9 : cf->cf_loc[4]; 201 ia.ia_drq = cf->cf_loc[5]; 202 ia.ia_delaybah = sc->sc_delaybah; 203 204 tryagain = 0; 205 if ((*cf->cf_attach->ca_match)(parent, cf, &ia) > 0) { 206 config_attach(parent, cf, &ia, isaprint); 207 tryagain = (cf->cf_fstate == FSTATE_STAR); 208 } 209 } while (tryagain); 210 211 return (0); 212 } 213 #endif /* __BROKEN_INDIRECT_CONFIG */ 214 215 char * 216 isa_intr_typename(type) 217 int type; 218 { 219 220 switch (type) { 221 case IST_NONE : 222 return ("none"); 223 case IST_PULSE: 224 return ("pulsed"); 225 case IST_EDGE: 226 return ("edge-triggered"); 227 case IST_LEVEL: 228 return ("level-triggered"); 229 default: 230 panic("isa_intr_typename: invalid type %d", type); 231 } 232 } 233