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