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