1 /* $NetBSD: isapnpdebug.c,v 1.6 2001/11/13 07:56:41 lukem 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 #include <sys/cdefs.h> 40 __KERNEL_RCSID(0, "$NetBSD: isapnpdebug.c,v 1.6 2001/11/13 07:56:41 lukem Exp $"); 41 42 #ifdef DEBUG_ISAPNP 43 44 #include <sys/param.h> 45 #include <sys/systm.h> 46 #include <sys/device.h> 47 48 #include <machine/bus.h> 49 50 #include <dev/isa/isavar.h> 51 52 #include <dev/isapnp/isapnpreg.h> 53 #include <dev/isapnp/isapnpvar.h> 54 55 /* isapnp_print_mem(): 56 * Print a memory tag 57 */ 58 void 59 isapnp_print_mem(str, mem) 60 const char *str; 61 const struct isapnp_region *mem; 62 { 63 printf("%sMemory: %s,%sshadowable,decode-%s,%scacheable,%s", str, 64 (mem->flags & ISAPNP_MEMATTR_ROM) ? "ROM," : "RAM,", 65 (mem->flags & ISAPNP_MEMATTR_SHADOWABLE) ? "" : "non-", 66 (mem->flags & ISAPNP_MEMATTR_HIGH_ADDR) ? 67 "high-addr," : "range-len,", 68 (mem->flags & ISAPNP_MEMATTR_CACHEABLE) ? "" : "non-", 69 (mem->flags & ISAPNP_MEMATTR_WRITEABLE) ? 70 "writeable," : "read-only,"); 71 72 switch (mem->flags & ISAPNP_MEMWIDTH_MASK) { 73 case ISAPNP_MEMWIDTH_8: 74 printf("8-bit "); 75 break; 76 case ISAPNP_MEMWIDTH_16: 77 printf("16-bit "); 78 break; 79 case ISAPNP_MEMWIDTH_8_16: 80 printf("8/16-bit "); 81 break; 82 case ISAPNP_MEMWIDTH_32: 83 printf("32-bit "); 84 break; 85 } 86 87 printf("min 0x%x, max 0x%x, ", mem->minbase, mem->maxbase); 88 printf("align 0x%x, length 0x%x\n", mem->align, mem->length); 89 } 90 91 92 /* isapnp_print_io(): 93 * Print an io tag 94 */ 95 void 96 isapnp_print_io(str, io) 97 const char *str; 98 const struct isapnp_region *io; 99 { 100 printf("%d %sIO Ports: %d address bits, alignment %d ", 101 io->length, str, (io->flags & ISAPNP_IOFLAGS_16) ? 16 : 10, 102 io->align); 103 104 printf("min 0x%x, max 0x%x\n", io->minbase, io->maxbase); 105 } 106 107 108 /* isapnp_print_irq(): 109 * Print an irq tag 110 */ 111 void 112 isapnp_print_irq(str, irq) 113 const char *str; 114 const struct isapnp_pin *irq; 115 { 116 int i; 117 118 printf("%sIRQ's supported: ", str); 119 for (i = 0; i < 16; i++) 120 if (irq->bits & (1 << i)) 121 printf("%d ", i); 122 123 if (irq->flags & ISAPNP_IRQTYPE_EDGE_PLUS) 124 printf("E+"); 125 if (irq->flags & ISAPNP_IRQTYPE_EDGE_MINUS) 126 printf("E-"); 127 if (irq->flags & ISAPNP_IRQTYPE_LEVEL_PLUS) 128 printf("L+"); 129 if (irq->flags & ISAPNP_IRQTYPE_LEVEL_MINUS) 130 printf("L-"); 131 printf("\n"); 132 } 133 134 /* isapnp_print_drq(): 135 * Print a drq tag 136 */ 137 void 138 isapnp_print_drq(str, drq) 139 const char *str; 140 const struct isapnp_pin *drq; 141 { 142 int i; 143 u_char flags = drq->flags; 144 145 printf("%sDRQ's supported: ", str); 146 for (i = 0; i < 8; i++) 147 if (drq->bits & (1 << i)) 148 printf("%d ", i); 149 150 printf("Width: "); 151 switch (flags & ISAPNP_DMAWIDTH_MASK) { 152 case ISAPNP_DMAWIDTH_8: 153 printf("8-bit "); 154 break; 155 case ISAPNP_DMAWIDTH_8_16: 156 printf("8/16-bit "); 157 break; 158 case ISAPNP_DMAWIDTH_16: 159 printf("16-bit "); 160 break; 161 case ISAPNP_DMAWIDTH_RESERVED: 162 printf("Reserved "); 163 break; 164 } 165 166 printf("Speed: "); 167 switch (flags & ISAPNP_DMASPEED_MASK) { 168 case ISAPNP_DMASPEED_COMPAT: 169 printf("compat "); 170 break; 171 case ISAPNP_DMASPEED_A: 172 printf("A "); 173 break; 174 case ISAPNP_DMASPEED_B: 175 printf("B "); 176 break; 177 case ISAPNP_DMASPEED_F: 178 printf("F "); 179 break; 180 } 181 182 if (flags & ISAPNP_DMAATTR_MASK) 183 printf("Attributes: %s%s%s", 184 (flags & ISAPNP_DMAATTR_BUS_MASTER) ? "bus master " : "", 185 (flags & ISAPNP_DMAATTR_INCR_8) ? "incr 8 " : "", 186 (flags & ISAPNP_DMAATTR_INCR_16) ? "incr 16 " : ""); 187 printf("\n"); 188 } 189 190 191 /* isapnp_print_dep_start(): 192 * Print a start dependencies tag 193 */ 194 void 195 isapnp_print_dep_start(str, pref) 196 const char *str; 197 const u_char pref; 198 { 199 200 printf("%sconfig: ", str); 201 switch (pref) { 202 case ISAPNP_DEP_PREFERRED: 203 printf("preferred\n"); 204 break; 205 206 case ISAPNP_DEP_ACCEPTABLE: 207 printf("acceptable\n"); 208 break; 209 210 case ISAPNP_DEP_FUNCTIONAL: 211 printf("functional\n"); 212 break; 213 214 case ISAPNP_DEP_UNSET: /* Used internally */ 215 printf("unset\n"); 216 break; 217 218 case ISAPNP_DEP_CONFLICTING: /* Used internally */ 219 printf("conflicting\n"); 220 break; 221 222 default: 223 printf("invalid\n"); 224 break; 225 } 226 } 227 228 void 229 isapnp_print_attach(pa) 230 const struct isapnp_attach_args *pa; 231 { 232 int i; 233 234 printf("Found <%s, %s, %s, %s> ", pa->ipa_devident, 235 pa->ipa_devlogic, pa->ipa_devcompat, pa->ipa_devclass); 236 isapnp_print_dep_start("", pa->ipa_pref); 237 238 for (i = 0; i < pa->ipa_nio; i++) 239 isapnp_print_io("", &pa->ipa_io[i]); 240 241 for (i = 0; i < pa->ipa_nmem; i++) 242 isapnp_print_mem("", &pa->ipa_mem[i]); 243 244 for (i = 0; i < pa->ipa_nirq; i++) 245 isapnp_print_irq("", &pa->ipa_irq[i]); 246 247 for (i = 0; i < pa->ipa_ndrq; i++) 248 isapnp_print_drq("", &pa->ipa_drq[i]); 249 250 for (i = 0; i < pa->ipa_nmem32; i++) 251 isapnp_print_mem("", &pa->ipa_mem32[i]); 252 } 253 254 255 /* isapnp_get_config(): 256 * Get the current configuration of the card 257 */ 258 void 259 isapnp_get_config(sc, pa) 260 struct isapnp_softc *sc; 261 struct isapnp_attach_args *pa; 262 { 263 int i; 264 u_char v0, v1, v2, v3; 265 static u_char isapnp_mem_range[] = ISAPNP_MEM_DESC; 266 static u_char isapnp_io_range[] = ISAPNP_IO_DESC; 267 static u_char isapnp_irq_range[] = ISAPNP_IRQ_DESC; 268 static u_char isapnp_drq_range[] = ISAPNP_DRQ_DESC; 269 static u_char isapnp_mem32_range[] = ISAPNP_MEM32_DESC; 270 struct isapnp_region *r; 271 struct isapnp_pin *p; 272 273 memset(pa, 0, sizeof(*pa)); 274 275 for (i = 0; i < sizeof(isapnp_io_range); i++) { 276 r = &pa->ipa_io[i]; 277 v0 = isapnp_read_reg(sc, 278 isapnp_io_range[i] + ISAPNP_IO_BASE_15_8); 279 v1 = isapnp_read_reg(sc, 280 isapnp_io_range[i] + ISAPNP_IO_BASE_7_0); 281 r->base = (v0 << 8) | v1; 282 if (r->base == 0) 283 break; 284 } 285 pa->ipa_nio = i; 286 287 for (i = 0; i < sizeof(isapnp_mem_range); i++) { 288 r = &pa->ipa_mem[i]; 289 v0 = isapnp_read_reg(sc, 290 isapnp_mem_range[i] + ISAPNP_MEM_BASE_23_16); 291 v1 = isapnp_read_reg(sc, 292 isapnp_mem_range[i] + ISAPNP_MEM_BASE_15_8); 293 r->base = (v0 << 16) | (v1 << 8); 294 if (r->base == 0) 295 break; 296 297 v0 = isapnp_read_reg(sc, 298 isapnp_mem_range[i] + ISAPNP_MEM_LRANGE_23_16); 299 v1 = isapnp_read_reg(sc, 300 isapnp_mem_range[i] + ISAPNP_MEM_LRANGE_15_8); 301 r->length = (v0 << 16) | (v1 << 8); 302 v0 = isapnp_read_reg(sc, 303 isapnp_mem_range[i] + ISAPNP_MEM_CONTROL); 304 r->flags = 0; 305 if (v0 & ISAPNP_MEM_CONTROL_LIMIT) 306 r->flags |= ISAPNP_MEMATTR_HIGH_ADDR; 307 if (v0 & ISAPNP_MEM_CONTROL_16) 308 r->flags |= ISAPNP_MEMWIDTH_16; 309 } 310 pa->ipa_nmem = i; 311 312 for (i = 0; i < sizeof(isapnp_irq_range); i++) { 313 v0 = isapnp_read_reg(sc, 314 isapnp_irq_range[i] + ISAPNP_IRQ_NUMBER); 315 p = &pa->ipa_irq[i]; 316 p->num = v0 & 0xf; 317 if (p->num == 0) 318 break; 319 320 switch (v0 & (ISAPNP_IRQ_LEVEL|ISAPNP_IRQ_HIGH)) { 321 case ISAPNP_IRQ_LEVEL|ISAPNP_IRQ_HIGH: 322 p->flags = ISAPNP_IRQTYPE_LEVEL_PLUS; 323 break; 324 case ISAPNP_IRQ_HIGH: 325 p->flags = ISAPNP_IRQTYPE_EDGE_PLUS; 326 break; 327 case ISAPNP_IRQ_LEVEL: 328 p->flags = ISAPNP_IRQTYPE_LEVEL_MINUS; 329 break; 330 default: 331 p->flags = ISAPNP_IRQTYPE_EDGE_MINUS; 332 break; 333 } 334 } 335 pa->ipa_nirq = i; 336 337 for (i = 0; i < sizeof(isapnp_drq_range); i++) { 338 v0 = isapnp_read_reg(sc, isapnp_drq_range[i]); 339 p = &pa->ipa_drq[i]; 340 p->num = v0 & 0xf; 341 if (p->num == 4) 342 break; 343 } 344 pa->ipa_ndrq = i; 345 346 for (i = 0; i < sizeof(isapnp_mem32_range); i++) { 347 r = &pa->ipa_mem32[i]; 348 v0 = isapnp_read_reg(sc, 349 isapnp_mem32_range[i] + ISAPNP_MEM32_BASE_31_24); 350 v1 = isapnp_read_reg(sc, 351 isapnp_mem32_range[i] + ISAPNP_MEM32_BASE_23_16); 352 v2 = isapnp_read_reg(sc, 353 isapnp_mem32_range[i] + ISAPNP_MEM32_BASE_15_8); 354 v3 = isapnp_read_reg(sc, 355 isapnp_mem32_range[i] + ISAPNP_MEM32_BASE_7_0); 356 r->base = (v0 << 24) | (v1 << 16) | (v2 << 8) | v3; 357 if (r->base == 0) 358 break; 359 360 v0 = isapnp_read_reg(sc, 361 isapnp_mem32_range[i] + ISAPNP_MEM32_LRANGE_31_24); 362 v1 = isapnp_read_reg(sc, 363 isapnp_mem32_range[i] + ISAPNP_MEM32_LRANGE_23_16); 364 v2 = isapnp_read_reg(sc, 365 isapnp_mem32_range[i] + ISAPNP_MEM32_LRANGE_15_8); 366 v3 = isapnp_read_reg(sc, 367 isapnp_mem32_range[i] + ISAPNP_MEM32_LRANGE_7_0); 368 r->length = (v0 << 24) | (v1 << 16) | (v2 << 8) | v3; 369 v0 = isapnp_read_reg(sc, 370 isapnp_mem_range[i] + ISAPNP_MEM_CONTROL); 371 r->flags = v0; 372 } 373 pa->ipa_nmem32 = i; 374 } 375 376 377 /* isapnp_print_config(): 378 * Print the current configuration of the card 379 */ 380 void 381 isapnp_print_config(pa) 382 const struct isapnp_attach_args *pa; 383 { 384 int i; 385 const struct isapnp_region *r; 386 const struct isapnp_pin *p; 387 388 printf("Register configuration:\n"); 389 if (pa->ipa_nio) 390 for (i = 0; i < pa->ipa_nio; i++) { 391 r = &pa->ipa_io[i]; 392 printf("io[%d]: 0x%x/%d\n", i, r->base, r->length); 393 } 394 395 if (pa->ipa_nmem) 396 for (i = 0; i < pa->ipa_nmem; i++) { 397 r = &pa->ipa_mem[i]; 398 printf("mem[%d]: 0x%x/%d\n", i, r->base, r->length); 399 } 400 401 if (pa->ipa_nirq) 402 for (i = 0; i < pa->ipa_nirq; i++) { 403 p = &pa->ipa_irq[i]; 404 printf("irq[%d]: %d\n", i, p->num); 405 } 406 407 if (pa->ipa_ndrq) 408 for (i = 0; i < pa->ipa_ndrq; i++) { 409 p = &pa->ipa_drq[i]; 410 printf("drq[%d]: %d\n", i, p->num); 411 } 412 413 if (pa->ipa_nmem32) 414 for (i = 0; i < pa->ipa_nmem32; i++) { 415 r = &pa->ipa_mem32[i]; 416 printf("mem32[%d]: 0x%x/%d\n", i, r->base, r->length); 417 } 418 } 419 420 #endif 421