1 /* $NetBSD: isapnpdebug.c,v 1.5 1998/09/05 14:15:25 christos Exp $ */ 2 3 /*- 4 * Copyright (c) 1996 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Christos Zoulas. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 3. All advertising materials mentioning features or use of this software 19 * must display the following acknowledgement: 20 * This product includes software developed by the NetBSD 21 * Foundation, Inc. and its contributors. 22 * 4. Neither the name of The NetBSD Foundation nor the names of its 23 * contributors may be used to endorse or promote products derived 24 * from this software without specific prior written permission. 25 * 26 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 27 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 28 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 29 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 30 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 31 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 32 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 33 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 34 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 35 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 36 * POSSIBILITY OF SUCH DAMAGE. 37 */ 38 39 #ifdef DEBUG_ISAPNP 40 41 #include <sys/param.h> 42 #include <sys/systm.h> 43 #include <sys/device.h> 44 45 #include <machine/bus.h> 46 47 #include <dev/isa/isavar.h> 48 49 #include <dev/isapnp/isapnpreg.h> 50 #include <dev/isapnp/isapnpvar.h> 51 52 /* isapnp_print_mem(): 53 * Print a memory tag 54 */ 55 void 56 isapnp_print_mem(str, mem) 57 const char *str; 58 const struct isapnp_region *mem; 59 { 60 printf("%sMemory: %s,%sshadowable,decode-%s,%scacheable,%s", str, 61 (mem->flags & ISAPNP_MEMATTR_ROM) ? "ROM," : "RAM,", 62 (mem->flags & ISAPNP_MEMATTR_SHADOWABLE) ? "" : "non-", 63 (mem->flags & ISAPNP_MEMATTR_HIGH_ADDR) ? 64 "high-addr," : "range-len,", 65 (mem->flags & ISAPNP_MEMATTR_CACHEABLE) ? "" : "non-", 66 (mem->flags & ISAPNP_MEMATTR_WRITEABLE) ? 67 "writeable," : "read-only,"); 68 69 switch (mem->flags & ISAPNP_MEMWIDTH_MASK) { 70 case ISAPNP_MEMWIDTH_8: 71 printf("8-bit "); 72 break; 73 case ISAPNP_MEMWIDTH_16: 74 printf("16-bit "); 75 break; 76 case ISAPNP_MEMWIDTH_8_16: 77 printf("8/16-bit "); 78 break; 79 case ISAPNP_MEMWIDTH_32: 80 printf("32-bit "); 81 break; 82 } 83 84 printf("min 0x%x, max 0x%x, ", mem->minbase, mem->maxbase); 85 printf("align 0x%x, length 0x%x\n", mem->align, mem->length); 86 } 87 88 89 /* isapnp_print_io(): 90 * Print an io tag 91 */ 92 void 93 isapnp_print_io(str, io) 94 const char *str; 95 const struct isapnp_region *io; 96 { 97 printf("%d %sIO Ports: %d address bits, alignment %d ", 98 io->length, str, (io->flags & ISAPNP_IOFLAGS_16) ? 16 : 10, 99 io->align); 100 101 printf("min 0x%x, max 0x%x\n", io->minbase, io->maxbase); 102 } 103 104 105 /* isapnp_print_irq(): 106 * Print an irq tag 107 */ 108 void 109 isapnp_print_irq(str, irq) 110 const char *str; 111 const struct isapnp_pin *irq; 112 { 113 int i; 114 115 printf("%sIRQ's supported: ", str); 116 for (i = 0; i < 16; i++) 117 if (irq->bits & (1 << i)) 118 printf("%d ", i); 119 120 if (irq->flags & ISAPNP_IRQTYPE_EDGE_PLUS) 121 printf("E+"); 122 if (irq->flags & ISAPNP_IRQTYPE_EDGE_MINUS) 123 printf("E-"); 124 if (irq->flags & ISAPNP_IRQTYPE_LEVEL_PLUS) 125 printf("L+"); 126 if (irq->flags & ISAPNP_IRQTYPE_LEVEL_MINUS) 127 printf("L-"); 128 printf("\n"); 129 } 130 131 /* isapnp_print_drq(): 132 * Print a drq tag 133 */ 134 void 135 isapnp_print_drq(str, drq) 136 const char *str; 137 const struct isapnp_pin *drq; 138 { 139 int i; 140 u_char flags = drq->flags; 141 142 printf("%sDRQ's supported: ", str); 143 for (i = 0; i < 8; i++) 144 if (drq->bits & (1 << i)) 145 printf("%d ", i); 146 147 printf("Width: "); 148 switch (flags & ISAPNP_DMAWIDTH_MASK) { 149 case ISAPNP_DMAWIDTH_8: 150 printf("8-bit "); 151 break; 152 case ISAPNP_DMAWIDTH_8_16: 153 printf("8/16-bit "); 154 break; 155 case ISAPNP_DMAWIDTH_16: 156 printf("16-bit "); 157 break; 158 case ISAPNP_DMAWIDTH_RESERVED: 159 printf("Reserved "); 160 break; 161 } 162 163 printf("Speed: "); 164 switch (flags & ISAPNP_DMASPEED_MASK) { 165 case ISAPNP_DMASPEED_COMPAT: 166 printf("compat "); 167 break; 168 case ISAPNP_DMASPEED_A: 169 printf("A "); 170 break; 171 case ISAPNP_DMASPEED_B: 172 printf("B "); 173 break; 174 case ISAPNP_DMASPEED_F: 175 printf("F "); 176 break; 177 } 178 179 if (flags & ISAPNP_DMAATTR_MASK) 180 printf("Attributes: %s%s%s", 181 (flags & ISAPNP_DMAATTR_BUS_MASTER) ? "bus master " : "", 182 (flags & ISAPNP_DMAATTR_INCR_8) ? "incr 8 " : "", 183 (flags & ISAPNP_DMAATTR_INCR_16) ? "incr 16 " : ""); 184 printf("\n"); 185 } 186 187 188 /* isapnp_print_dep_start(): 189 * Print a start dependencies tag 190 */ 191 void 192 isapnp_print_dep_start(str, pref) 193 const char *str; 194 const u_char pref; 195 { 196 197 printf("%sconfig: ", str); 198 switch (pref) { 199 case ISAPNP_DEP_PREFERRED: 200 printf("preferred\n"); 201 break; 202 203 case ISAPNP_DEP_ACCEPTABLE: 204 printf("acceptable\n"); 205 break; 206 207 case ISAPNP_DEP_FUNCTIONAL: 208 printf("functional\n"); 209 break; 210 211 case ISAPNP_DEP_UNSET: /* Used internally */ 212 printf("unset\n"); 213 break; 214 215 case ISAPNP_DEP_CONFLICTING: /* Used internally */ 216 printf("conflicting\n"); 217 break; 218 219 default: 220 printf("invalid\n"); 221 break; 222 } 223 } 224 225 void 226 isapnp_print_attach(pa) 227 const struct isapnp_attach_args *pa; 228 { 229 int i; 230 231 printf("Found <%s, %s, %s, %s> ", pa->ipa_devident, 232 pa->ipa_devlogic, pa->ipa_devcompat, pa->ipa_devclass); 233 isapnp_print_dep_start("", pa->ipa_pref); 234 235 for (i = 0; i < pa->ipa_nio; i++) 236 isapnp_print_io("", &pa->ipa_io[i]); 237 238 for (i = 0; i < pa->ipa_nmem; i++) 239 isapnp_print_mem("", &pa->ipa_mem[i]); 240 241 for (i = 0; i < pa->ipa_nirq; i++) 242 isapnp_print_irq("", &pa->ipa_irq[i]); 243 244 for (i = 0; i < pa->ipa_ndrq; i++) 245 isapnp_print_drq("", &pa->ipa_drq[i]); 246 247 for (i = 0; i < pa->ipa_nmem32; i++) 248 isapnp_print_mem("", &pa->ipa_mem32[i]); 249 } 250 251 252 /* isapnp_get_config(): 253 * Get the current configuration of the card 254 */ 255 void 256 isapnp_get_config(sc, pa) 257 struct isapnp_softc *sc; 258 struct isapnp_attach_args *pa; 259 { 260 int i; 261 u_char v0, v1, v2, v3; 262 static u_char isapnp_mem_range[] = ISAPNP_MEM_DESC; 263 static u_char isapnp_io_range[] = ISAPNP_IO_DESC; 264 static u_char isapnp_irq_range[] = ISAPNP_IRQ_DESC; 265 static u_char isapnp_drq_range[] = ISAPNP_DRQ_DESC; 266 static u_char isapnp_mem32_range[] = ISAPNP_MEM32_DESC; 267 struct isapnp_region *r; 268 struct isapnp_pin *p; 269 270 memset(pa, 0, sizeof(*pa)); 271 272 for (i = 0; i < sizeof(isapnp_io_range); i++) { 273 r = &pa->ipa_io[i]; 274 v0 = isapnp_read_reg(sc, 275 isapnp_io_range[i] + ISAPNP_IO_BASE_15_8); 276 v1 = isapnp_read_reg(sc, 277 isapnp_io_range[i] + ISAPNP_IO_BASE_7_0); 278 r->base = (v0 << 8) | v1; 279 if (r->base == 0) 280 break; 281 } 282 pa->ipa_nio = i; 283 284 for (i = 0; i < sizeof(isapnp_mem_range); i++) { 285 r = &pa->ipa_mem[i]; 286 v0 = isapnp_read_reg(sc, 287 isapnp_mem_range[i] + ISAPNP_MEM_BASE_23_16); 288 v1 = isapnp_read_reg(sc, 289 isapnp_mem_range[i] + ISAPNP_MEM_BASE_15_8); 290 r->base = (v0 << 16) | (v1 << 8); 291 if (r->base == 0) 292 break; 293 294 v0 = isapnp_read_reg(sc, 295 isapnp_mem_range[i] + ISAPNP_MEM_LRANGE_23_16); 296 v1 = isapnp_read_reg(sc, 297 isapnp_mem_range[i] + ISAPNP_MEM_LRANGE_15_8); 298 r->length = (v0 << 16) | (v1 << 8); 299 v0 = isapnp_read_reg(sc, 300 isapnp_mem_range[i] + ISAPNP_MEM_CONTROL); 301 r->flags = 0; 302 if (v0 & ISAPNP_MEM_CONTROL_LIMIT) 303 r->flags |= ISAPNP_MEMATTR_HIGH_ADDR; 304 if (v0 & ISAPNP_MEM_CONTROL_16) 305 r->flags |= ISAPNP_MEMWIDTH_16; 306 } 307 pa->ipa_nmem = i; 308 309 for (i = 0; i < sizeof(isapnp_irq_range); i++) { 310 v0 = isapnp_read_reg(sc, 311 isapnp_irq_range[i] + ISAPNP_IRQ_NUMBER); 312 p = &pa->ipa_irq[i]; 313 p->num = v0 & 0xf; 314 if (p->num == 0) 315 break; 316 317 switch (v0 & (ISAPNP_IRQ_LEVEL|ISAPNP_IRQ_HIGH)) { 318 case ISAPNP_IRQ_LEVEL|ISAPNP_IRQ_HIGH: 319 p->flags = ISAPNP_IRQTYPE_LEVEL_PLUS; 320 break; 321 case ISAPNP_IRQ_HIGH: 322 p->flags = ISAPNP_IRQTYPE_EDGE_PLUS; 323 break; 324 case ISAPNP_IRQ_LEVEL: 325 p->flags = ISAPNP_IRQTYPE_LEVEL_MINUS; 326 break; 327 default: 328 p->flags = ISAPNP_IRQTYPE_EDGE_MINUS; 329 break; 330 } 331 } 332 pa->ipa_nirq = i; 333 334 for (i = 0; i < sizeof(isapnp_drq_range); i++) { 335 v0 = isapnp_read_reg(sc, isapnp_drq_range[i]); 336 p = &pa->ipa_drq[i]; 337 p->num = v0 & 0xf; 338 if (p->num == 4) 339 break; 340 } 341 pa->ipa_ndrq = i; 342 343 for (i = 0; i < sizeof(isapnp_mem32_range); i++) { 344 r = &pa->ipa_mem32[i]; 345 v0 = isapnp_read_reg(sc, 346 isapnp_mem32_range[i] + ISAPNP_MEM32_BASE_31_24); 347 v1 = isapnp_read_reg(sc, 348 isapnp_mem32_range[i] + ISAPNP_MEM32_BASE_23_16); 349 v2 = isapnp_read_reg(sc, 350 isapnp_mem32_range[i] + ISAPNP_MEM32_BASE_15_8); 351 v3 = isapnp_read_reg(sc, 352 isapnp_mem32_range[i] + ISAPNP_MEM32_BASE_7_0); 353 r->base = (v0 << 24) | (v1 << 16) | (v2 << 8) | v3; 354 if (r->base == 0) 355 break; 356 357 v0 = isapnp_read_reg(sc, 358 isapnp_mem32_range[i] + ISAPNP_MEM32_LRANGE_31_24); 359 v1 = isapnp_read_reg(sc, 360 isapnp_mem32_range[i] + ISAPNP_MEM32_LRANGE_23_16); 361 v2 = isapnp_read_reg(sc, 362 isapnp_mem32_range[i] + ISAPNP_MEM32_LRANGE_15_8); 363 v3 = isapnp_read_reg(sc, 364 isapnp_mem32_range[i] + ISAPNP_MEM32_LRANGE_7_0); 365 r->length = (v0 << 24) | (v1 << 16) | (v2 << 8) | v3; 366 v0 = isapnp_read_reg(sc, 367 isapnp_mem_range[i] + ISAPNP_MEM_CONTROL); 368 r->flags = v0; 369 } 370 pa->ipa_nmem32 = i; 371 } 372 373 374 /* isapnp_print_config(): 375 * Print the current configuration of the card 376 */ 377 void 378 isapnp_print_config(pa) 379 const struct isapnp_attach_args *pa; 380 { 381 int i; 382 const struct isapnp_region *r; 383 const struct isapnp_pin *p; 384 385 printf("Register configuration:\n"); 386 if (pa->ipa_nio) 387 for (i = 0; i < pa->ipa_nio; i++) { 388 r = &pa->ipa_io[i]; 389 printf("io[%d]: 0x%x/%d\n", i, r->base, r->length); 390 } 391 392 if (pa->ipa_nmem) 393 for (i = 0; i < pa->ipa_nmem; i++) { 394 r = &pa->ipa_mem[i]; 395 printf("mem[%d]: 0x%x/%d\n", i, r->base, r->length); 396 } 397 398 if (pa->ipa_nirq) 399 for (i = 0; i < pa->ipa_nirq; i++) { 400 p = &pa->ipa_irq[i]; 401 printf("irq[%d]: %d\n", i, p->num); 402 } 403 404 if (pa->ipa_ndrq) 405 for (i = 0; i < pa->ipa_ndrq; i++) { 406 p = &pa->ipa_drq[i]; 407 printf("drq[%d]: %d\n", i, p->num); 408 } 409 410 if (pa->ipa_nmem32) 411 for (i = 0; i < pa->ipa_nmem32; i++) { 412 r = &pa->ipa_mem32[i]; 413 printf("mem32[%d]: 0x%x/%d\n", i, r->base, r->length); 414 } 415 } 416 417 #endif 418