1 /* $NetBSD: isapnp.c,v 1.57 2008/03/30 15:31:07 ad Exp $ */ 2 3 /*- 4 * Copyright (c) 1996, 2008 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 /* 40 * ISA PnP bus autoconfiguration. 41 */ 42 43 #include <sys/cdefs.h> 44 __KERNEL_RCSID(0, "$NetBSD: isapnp.c,v 1.57 2008/03/30 15:31:07 ad Exp $"); 45 46 #include "isadma.h" 47 48 #include <sys/param.h> 49 #include <sys/systm.h> 50 #include <sys/device.h> 51 #include <sys/malloc.h> 52 53 #include <sys/bus.h> 54 55 #include <dev/isa/isavar.h> 56 57 #include <dev/isapnp/isapnpreg.h> 58 #include <dev/isapnp/isapnpvar.h> 59 #include <dev/isapnp/isapnpdevs.h> 60 61 #include "wss_isapnp.h" /* XXX part of disgusting CS chip hack */ 62 63 #ifndef ISAPNP_ALLOC_INTR_MASK 64 #define ISAPNP_ALLOC_INTR_MASK (~0) 65 #endif 66 67 static void isapnp_init(struct isapnp_softc *); 68 static inline u_char isapnp_shift_bit(struct isapnp_softc *); 69 static int isapnp_findcard(struct isapnp_softc *); 70 static void isapnp_free_region(bus_space_tag_t, struct isapnp_region *); 71 static int isapnp_alloc_region(bus_space_tag_t, struct isapnp_region *); 72 static int isapnp_alloc_irq(isa_chipset_tag_t, struct isapnp_pin *); 73 static int isapnp_alloc_drq(isa_chipset_tag_t, struct isapnp_pin *); 74 static int isapnp_testconfig(bus_space_tag_t, bus_space_tag_t, 75 struct isapnp_attach_args *, int); 76 static struct isapnp_attach_args *isapnp_bestconfig(struct isapnp_softc *, 77 struct isapnp_attach_args **); 78 static void isapnp_print_region(const char *, struct isapnp_region *, size_t); 79 static void isapnp_configure(struct isapnp_softc *, 80 const struct isapnp_attach_args *); 81 static void isapnp_print_pin(const char *, struct isapnp_pin *, size_t); 82 static int isapnp_print(void *, const char *); 83 #ifdef _KERNEL 84 static int isapnp_submatch(device_t, cfdata_t, const int *, void *); 85 #endif 86 static int isapnp_find(struct isapnp_softc *, int); 87 static int isapnp_match(device_t, cfdata_t, void *); 88 static void isapnp_attach(device_t, device_t, void *); 89 static void isapnp_callback(device_t); 90 91 CFATTACH_DECL_NEW(isapnp, sizeof(struct isapnp_softc), 92 isapnp_match, isapnp_attach, NULL, NULL); 93 94 /* 95 * This keeps track if which ISA's we have been probed on. 96 */ 97 struct isapnp_probe_cookie { 98 LIST_ENTRY(isapnp_probe_cookie) ipc_link; 99 device_t ipc_parent; 100 }; 101 LIST_HEAD(, isapnp_probe_cookie) isapnp_probes = 102 LIST_HEAD_INITIALIZER(isapnp_probes); 103 104 /* isapnp_init(): 105 * Write the PNP initiation key to wake up the cards... 106 */ 107 static void 108 isapnp_init(struct isapnp_softc *sc) 109 { 110 int i; 111 u_char v = ISAPNP_LFSR_INIT; 112 113 /* First write 0's twice to enter the Wait for Key state */ 114 ISAPNP_WRITE_ADDR(sc, 0); 115 ISAPNP_WRITE_ADDR(sc, 0); 116 117 /* Send the 32 byte sequence to awake the logic */ 118 for (i = 0; i < ISAPNP_LFSR_LENGTH; i++) { 119 ISAPNP_WRITE_ADDR(sc, v); 120 v = ISAPNP_LFSR_NEXT(v); 121 } 122 } 123 124 125 /* isapnp_shift_bit(): 126 * Read a bit at a time from the config card. 127 */ 128 static inline u_char 129 isapnp_shift_bit(struct isapnp_softc *sc) 130 { 131 u_char c1, c2; 132 133 DELAY(250); 134 c1 = ISAPNP_READ_DATA(sc); 135 DELAY(250); 136 c2 = ISAPNP_READ_DATA(sc); 137 138 if (c1 == 0x55 && c2 == 0xAA) 139 return 0x80; 140 else 141 return 0; 142 } 143 144 145 /* isapnp_findcard(): 146 * Attempt to read the vendor/serial/checksum for a card 147 * If a card is found [the checksum matches], assign the 148 * next card number to it and return 1 149 */ 150 static int 151 isapnp_findcard(struct isapnp_softc *sc) 152 { 153 u_char v = ISAPNP_LFSR_INIT, csum, w; 154 int i, b; 155 156 if (sc->sc_ncards == ISAPNP_MAX_CARDS) { 157 aprint_error_dev(sc->sc_dev, "Too many pnp cards\n"); 158 return 0; 159 } 160 161 /* Set the read port */ 162 isapnp_write_reg(sc, ISAPNP_WAKE, 0); 163 isapnp_write_reg(sc, ISAPNP_SET_RD_PORT, sc->sc_read_port >> 2); 164 sc->sc_read_port |= 3; 165 DELAY(1000); 166 167 ISAPNP_WRITE_ADDR(sc, ISAPNP_SERIAL_ISOLATION); 168 DELAY(1000); 169 170 /* Read the 8 bytes of the Vendor ID and Serial Number */ 171 for(i = 0; i < 8; i++) { 172 /* Read each bit separately */ 173 for (w = 0, b = 0; b < 8; b++) { 174 u_char neg = isapnp_shift_bit(sc); 175 176 w >>= 1; 177 w |= neg; 178 v = ISAPNP_LFSR_NEXT(v) ^ neg; 179 } 180 sc->sc_id[sc->sc_ncards][i] = w; 181 } 182 183 /* Read the remaining checksum byte */ 184 for (csum = 0, b = 0; b < 8; b++) { 185 u_char neg = isapnp_shift_bit(sc); 186 187 csum >>= 1; 188 csum |= neg; 189 } 190 sc->sc_id[sc->sc_ncards][8] = csum; 191 192 if (csum == v) { 193 sc->sc_ncards++; 194 isapnp_write_reg(sc, ISAPNP_CARD_SELECT_NUM, sc->sc_ncards); 195 return 1; 196 } 197 return 0; 198 } 199 200 201 /* isapnp_free_region(): 202 * Free a region 203 */ 204 static void 205 isapnp_free_region(bus_space_tag_t t, struct isapnp_region *r) 206 { 207 if (r->length == 0) 208 return; 209 210 #ifdef _KERNEL 211 bus_space_unmap(t, r->h, r->length); 212 #endif 213 } 214 215 216 /* isapnp_alloc_region(): 217 * Allocate a single region if possible 218 */ 219 static int 220 isapnp_alloc_region(bus_space_tag_t t, struct isapnp_region *r) 221 { 222 int error = 0; 223 224 if (r->length == 0) { 225 r->base = 0; 226 return 0; 227 } 228 229 for (r->base = r->minbase; r->base <= r->maxbase; 230 r->base += r->align) { 231 #ifdef _KERNEL 232 error = bus_space_map(t, r->base, r->length, 0, &r->h); 233 #endif 234 if (error == 0) 235 return 0; 236 if (r->align == 0) 237 break; 238 } 239 return error; 240 } 241 242 243 /* isapnp_alloc_irq(): 244 * Allocate an irq 245 */ 246 static int 247 isapnp_alloc_irq(isa_chipset_tag_t ic, struct isapnp_pin *i) 248 { 249 int irq; 250 #define LEVEL_IRQ (ISAPNP_IRQTYPE_LEVEL_PLUS|ISAPNP_IRQTYPE_LEVEL_MINUS) 251 i->type = (i->flags & LEVEL_IRQ) ? IST_LEVEL : IST_EDGE; 252 253 if (i->bits == 0) { 254 i->num = 0; 255 return 0; 256 } 257 258 if (isa_intr_alloc(ic, ISAPNP_ALLOC_INTR_MASK & i->bits, 259 i->type, &irq) == 0) { 260 i->num = irq; 261 return 0; 262 } 263 264 return EINVAL; 265 } 266 267 /* isapnp_alloc_drq(): 268 * Allocate a drq 269 */ 270 static int 271 isapnp_alloc_drq(isa_chipset_tag_t ic, struct isapnp_pin *i) 272 { 273 #if NISADMA > 0 274 int b; 275 276 if (i->bits == 0) { 277 i->num = 0; 278 return 0; 279 } 280 281 for (b = 0; b < 8; b++) 282 if ((i->bits & (1 << b)) && isa_drq_isfree(ic, b)) { 283 i->num = b; 284 return 0; 285 } 286 #endif /* NISADMA > 0 */ 287 288 return EINVAL; 289 } 290 291 /* isapnp_testconfig(): 292 * Test/Allocate the regions used 293 */ 294 static int 295 isapnp_testconfig(bus_space_tag_t iot, bus_space_tag_t memt, 296 struct isapnp_attach_args *ipa, int alloc) 297 { 298 int nio = 0, nmem = 0, nmem32 = 0, nirq = 0, ndrq = 0; 299 int error = 0; 300 301 #ifdef DEBUG_ISAPNP 302 isapnp_print_attach(ipa); 303 #endif 304 305 for (; nio < ipa->ipa_nio; nio++) { 306 error = isapnp_alloc_region(iot, &ipa->ipa_io[nio]); 307 if (error) 308 goto bad; 309 } 310 311 for (; nmem < ipa->ipa_nmem; nmem++) { 312 error = isapnp_alloc_region(memt, &ipa->ipa_mem[nmem]); 313 if (error) 314 goto bad; 315 } 316 317 for (; nmem32 < ipa->ipa_nmem32; nmem32++) { 318 error = isapnp_alloc_region(memt, &ipa->ipa_mem32[nmem32]); 319 if (error) 320 goto bad; 321 } 322 323 for (; nirq < ipa->ipa_nirq; nirq++) { 324 error = isapnp_alloc_irq(ipa->ipa_ic, &ipa->ipa_irq[nirq]); 325 if (error) 326 goto bad; 327 } 328 329 for (; ndrq < ipa->ipa_ndrq; ndrq++) { 330 error = isapnp_alloc_drq(ipa->ipa_ic, &ipa->ipa_drq[ndrq]); 331 if (error) 332 goto bad; 333 } 334 335 if (alloc) 336 return error; 337 338 bad: 339 #ifdef notyet 340 for (ndrq--; ndrq >= 0; ndrq--) 341 isapnp_free_pin(&ipa->ipa_drq[ndrq]); 342 343 for (nirq--; nirq >= 0; nirq--) 344 isapnp_free_pin(&ipa->ipa_irq[nirq]); 345 #endif 346 347 for (nmem32--; nmem32 >= 0; nmem32--) 348 isapnp_free_region(memt, &ipa->ipa_mem32[nmem32]); 349 350 for (nmem--; nmem >= 0; nmem--) 351 isapnp_free_region(memt, &ipa->ipa_mem[nmem]); 352 353 for (nio--; nio >= 0; nio--) 354 isapnp_free_region(iot, &ipa->ipa_io[nio]); 355 356 return error; 357 } 358 359 360 /* isapnp_config(): 361 * Test/Allocate the regions used 362 */ 363 int 364 isapnp_config(bus_space_tag_t iot, bus_space_tag_t memt, 365 struct isapnp_attach_args *ipa) 366 { 367 return isapnp_testconfig(iot, memt, ipa, 1); 368 } 369 370 371 /* isapnp_unconfig(): 372 * Free the regions used 373 */ 374 void 375 isapnp_unconfig(bus_space_tag_t iot, bus_space_tag_t memt, 376 struct isapnp_attach_args *ipa) 377 { 378 int i; 379 380 #ifdef notyet 381 for (i = 0; i < ipa->ipa_ndrq; i++) 382 isapnp_free_pin(&ipa->ipa_drq[i]); 383 384 for (i = 0; i < ipa->ipa_nirq; i++) 385 isapnp_free_pin(&ipa->ipa_irq[i]); 386 #endif 387 388 for (i = 0; i < ipa->ipa_nmem32; i++) 389 isapnp_free_region(memt, &ipa->ipa_mem32[i]); 390 391 for (i = 0; i < ipa->ipa_nmem; i++) 392 isapnp_free_region(memt, &ipa->ipa_mem[i]); 393 394 for (i = 0; i < ipa->ipa_nio; i++) 395 isapnp_free_region(iot, &ipa->ipa_io[i]); 396 } 397 398 399 /* isapnp_bestconfig(): 400 * Return the best configuration for each logical device, remove and 401 * free all other configurations. 402 */ 403 static struct isapnp_attach_args * 404 isapnp_bestconfig(struct isapnp_softc *sc, struct isapnp_attach_args **ipa) 405 { 406 struct isapnp_attach_args *c, *best, *f = *ipa; 407 int error; 408 409 for (;;) { 410 if (f == NULL) 411 return NULL; 412 413 #define SAMEDEV(a, b) (strcmp((a)->ipa_devlogic, (b)->ipa_devlogic) == 0) 414 415 /* Find the best config */ 416 for (best = c = f; c != NULL; c = c->ipa_sibling) { 417 if (!SAMEDEV(c, f)) 418 continue; 419 if (c->ipa_pref < best->ipa_pref) 420 best = c; 421 } 422 423 /* 424 * Make sure the ISA chipset is initialized! We need 425 * it to test the best config! 426 */ 427 best->ipa_ic = sc->sc_ic; 428 429 /* Test the best config */ 430 error = isapnp_testconfig(sc->sc_iot, sc->sc_memt, best, 0); 431 432 /* Remove this config from the list */ 433 if (best == f) 434 f = f->ipa_sibling; 435 else { 436 for (c = f; c->ipa_sibling != best; c = c->ipa_sibling) 437 continue; 438 c->ipa_sibling = best->ipa_sibling; 439 } 440 441 if (error) { 442 best->ipa_pref = ISAPNP_DEP_CONFLICTING; 443 444 for (c = f; c != NULL; c = c->ipa_sibling) 445 if (c != best && SAMEDEV(c, best)) 446 break; 447 /* Last config for this logical device is conflicting */ 448 if (c == NULL) { 449 *ipa = f; 450 return best; 451 } 452 453 ISAPNP_FREE(best); 454 continue; 455 } 456 else { 457 /* Remove all other configs for this device */ 458 struct isapnp_attach_args *l = NULL, *n = NULL, *d; 459 460 for (c = f; c; ) { 461 if (c == best) 462 continue; 463 d = c->ipa_sibling; 464 if (SAMEDEV(c, best)) 465 ISAPNP_FREE(c); 466 else { 467 if (n) 468 n->ipa_sibling = c; 469 470 else 471 l = c; 472 n = c; 473 c->ipa_sibling = NULL; 474 } 475 c = d; 476 } 477 f = l; 478 } 479 *ipa = f; 480 return best; 481 } 482 } 483 484 485 /* isapnp_id_to_vendor(): 486 * Convert a pnp ``compressed ascii'' vendor id to a string 487 */ 488 char * 489 isapnp_id_to_vendor(char *v, const u_char *id) 490 { 491 char *p = v; 492 493 *p++ = 'A' + (id[0] >> 2) - 1; 494 *p++ = 'A' + ((id[0] & 3) << 3) + (id[1] >> 5) - 1; 495 *p++ = 'A' + (id[1] & 0x1f) - 1; 496 *p++ = HEXDIGITS[id[2] >> 4]; 497 *p++ = HEXDIGITS[id[2] & 0x0f]; 498 *p++ = HEXDIGITS[id[3] >> 4]; 499 *p++ = HEXDIGITS[id[3] & 0x0f]; 500 *p = '\0'; 501 502 return v; 503 } 504 505 506 /* isapnp_print_region(): 507 * Print a region allocation 508 */ 509 static void 510 isapnp_print_region(const char *str, struct isapnp_region *r, size_t n) 511 { 512 size_t i; 513 514 if (n == 0) 515 return; 516 517 aprint_normal(" %s ", str); 518 for (i = 0; i < n; i++, r++) { 519 aprint_normal("0x%x", r->base); 520 if (r->length) 521 aprint_normal("/%d", r->length); 522 if (i != n - 1) 523 aprint_normal(","); 524 } 525 } 526 527 528 /* isapnp_print_pin(): 529 * Print an irq/drq assignment 530 */ 531 static void 532 isapnp_print_pin(const char *str, struct isapnp_pin *p, size_t n) 533 { 534 size_t i; 535 536 if (n == 0) 537 return; 538 539 printf(" %s ", str); 540 for (i = 0; i < n; i++, p++) { 541 printf("%d", p->num); 542 if (i != n - 1) 543 printf(","); 544 } 545 } 546 547 548 /* isapnp_print(): 549 * Print the configuration line for an ISA PnP card. 550 */ 551 static int 552 isapnp_print(void *aux, const char *str) 553 { 554 struct isapnp_attach_args *ipa = aux; 555 556 if (str != NULL) 557 aprint_normal("%s: <%s, %s, %s, %s>", 558 str, ipa->ipa_devident, ipa->ipa_devlogic, 559 ipa->ipa_devcompat, ipa->ipa_devclass); 560 561 isapnp_print_region("port", ipa->ipa_io, ipa->ipa_nio); 562 isapnp_print_region("mem", ipa->ipa_mem, ipa->ipa_nmem); 563 isapnp_print_region("mem32", ipa->ipa_mem32, ipa->ipa_nmem32); 564 isapnp_print_pin("irq", ipa->ipa_irq, ipa->ipa_nirq); 565 isapnp_print_pin("drq", ipa->ipa_drq, ipa->ipa_ndrq); 566 567 return UNCONF; 568 } 569 570 571 #ifdef _KERNEL 572 /* isapnp_submatch(): 573 * Probe the logical device... 574 */ 575 static int 576 isapnp_submatch(device_t parent, cfdata_t match, const int *ldesc, void *aux) 577 { 578 579 return (config_match(parent, match, aux)); 580 } 581 582 583 /* isapnp_devmatch(): 584 * Match a probed device with the information from the driver 585 */ 586 int 587 isapnp_devmatch(const struct isapnp_attach_args *ipa, 588 const struct isapnp_devinfo *dinfo, int *variant) 589 { 590 const struct isapnp_matchinfo *match; 591 int n; 592 593 for (match = dinfo->devlogic, n = dinfo->nlogic; n--; match++) 594 if (strcmp(match->name, ipa->ipa_devlogic) == 0) { 595 *variant = match->variant; 596 return (1); 597 } 598 599 for (match = dinfo->devcompat, n = dinfo->ncompat; n--; match++) 600 if (strcmp(match->name, ipa->ipa_devcompat) == 0) { 601 *variant = match->variant; 602 return (1); 603 } 604 605 return (0); 606 } 607 608 609 /* isapnp_isa_attach_hook(): 610 * This routine is called from the isa attach code and 611 * is a kludge; we are resetting all the cards here in order 612 * to undo any card configuration that the bios did for us, in order 613 * to avoid having the PnP devices match an isa probe. The correct 614 * way of doing this is to read the PnP BIOS and find the card settings 615 * from there. Unfortunately it is not as easy as it sounds. 616 */ 617 void 618 isapnp_isa_attach_hook(struct isa_softc *isa_sc) 619 { 620 struct isapnp_softc sc; 621 622 sc.sc_iot = isa_sc->sc_iot; 623 sc.sc_ncards = 0; 624 625 if (isapnp_map(&sc)) 626 return; 627 628 #if NWSS_ISAPNP > 0 629 /* 630 * XXX XXX 631 * This a totally disgusting hack, but I can't figure out another way. 632 * It seems that many CS audio chips have a bug (as far as I can 633 * understand). The reset below does not really reset the chip, it 634 * remains in a catatonic state and will not respond when probed. 635 * The chip can be used both as a WSS and as a SB device, and a 636 * single read at the WSS address (0x534) takes it out of this 637 * non-responsive state. 638 * The read has to happen at this point in time (or earlier) so 639 * it cannot be moved to the wss_isapnp.c driver. 640 * (BTW, We're not alone in having problems with these chips: 641 * Windoze 98 couldn't detect the sound chip on a Dell when I tried.) 642 * 643 * Lennart Augustsson <augustss@NetBSD.org> 644 * 645 * (Implementation from John Kohl <jtk@kolvir.arlington.ma.us>) 646 */ 647 { 648 bus_space_handle_t ioh; 649 int rv; 650 if ((rv = bus_space_map(sc.sc_iot, 0x534, 1, 0, &ioh)) == 0) { 651 DPRINTF(("wss probe kludge\n")); 652 (void)bus_space_read_1(sc.sc_iot, ioh, 0); 653 bus_space_unmap(sc.sc_iot, ioh, 1); 654 } else { 655 DPRINTF(("wss probe kludge failed to map: %d\n", rv)); 656 } 657 } 658 #endif 659 660 isapnp_init(&sc); 661 662 isapnp_write_reg(&sc, ISAPNP_CONFIG_CONTROL, ISAPNP_CC_RESET_DRV); 663 DELAY(2000); 664 665 isapnp_unmap(&sc); 666 } 667 #endif 668 669 670 /* isapnp_find(): 671 * Probe and add cards 672 */ 673 static int 674 isapnp_find(struct isapnp_softc *sc, int all) 675 { 676 int p; 677 678 isapnp_init(sc); 679 680 isapnp_write_reg(sc, ISAPNP_CONFIG_CONTROL, ISAPNP_CC_RESET_DRV); 681 DELAY(2000); 682 683 isapnp_init(sc); 684 DELAY(2000); 685 686 for (p = ISAPNP_RDDATA_MIN; p <= ISAPNP_RDDATA_MAX; p += 4) { 687 sc->sc_read_port = p; 688 if (isapnp_map_readport(sc)) 689 continue; 690 DPRINTF(("%s: Trying port %x\r", device_xname(sc->sc_dev), p)); 691 if (isapnp_findcard(sc)) 692 break; 693 isapnp_unmap_readport(sc); 694 } 695 696 if (p > ISAPNP_RDDATA_MAX) { 697 sc->sc_read_port = 0; 698 return 0; 699 } 700 701 if (all) 702 while (isapnp_findcard(sc)) 703 continue; 704 705 return 1; 706 } 707 708 709 /* isapnp_configure(): 710 * Configure a PnP card 711 * XXX: The memory configuration code is wrong. We need to check the 712 * range/length bit an do appropriate sets. 713 */ 714 static void 715 isapnp_configure(struct isapnp_softc *sc, const struct isapnp_attach_args *ipa) 716 { 717 int i; 718 static u_char isapnp_mem_range[] = ISAPNP_MEM_DESC; 719 static u_char isapnp_io_range[] = ISAPNP_IO_DESC; 720 static u_char isapnp_irq_range[] = ISAPNP_IRQ_DESC; 721 static u_char isapnp_drq_range[] = ISAPNP_DRQ_DESC; 722 static u_char isapnp_mem32_range[] = ISAPNP_MEM32_DESC; 723 const struct isapnp_region *r; 724 const struct isapnp_pin *p; 725 struct isapnp_region rz; 726 struct isapnp_pin pz; 727 728 memset(&pz, 0, sizeof(pz)); 729 memset(&rz, 0, sizeof(rz)); 730 731 #define B0(a) ((a) & 0xff) 732 #define B1(a) (((a) >> 8) & 0xff) 733 #define B2(a) (((a) >> 16) & 0xff) 734 #define B3(a) (((a) >> 24) & 0xff) 735 736 for (i = 0; i < sizeof(isapnp_io_range); i++) { 737 if (i < ipa->ipa_nio) 738 r = &ipa->ipa_io[i]; 739 else 740 r = &rz; 741 742 isapnp_write_reg(sc, 743 isapnp_io_range[i] + ISAPNP_IO_BASE_15_8, B1(r->base)); 744 isapnp_write_reg(sc, 745 isapnp_io_range[i] + ISAPNP_IO_BASE_7_0, B0(r->base)); 746 } 747 748 for (i = 0; i < sizeof(isapnp_mem_range); i++) { 749 if (i < ipa->ipa_nmem) 750 r = &ipa->ipa_mem[i]; 751 else 752 r = &rz; 753 754 isapnp_write_reg(sc, 755 isapnp_mem_range[i] + ISAPNP_MEM_BASE_23_16, B2(r->base)); 756 isapnp_write_reg(sc, 757 isapnp_mem_range[i] + ISAPNP_MEM_BASE_15_8, B1(r->base)); 758 759 isapnp_write_reg(sc, 760 isapnp_mem_range[i] + ISAPNP_MEM_LRANGE_23_16, 761 B2(r->length)); 762 isapnp_write_reg(sc, 763 isapnp_mem_range[i] + ISAPNP_MEM_LRANGE_15_8, 764 B1(r->length)); 765 } 766 767 for (i = 0; i < sizeof(isapnp_irq_range); i++) { 768 u_char v; 769 770 if (i < ipa->ipa_nirq) 771 p = &ipa->ipa_irq[i]; 772 else 773 p = &pz; 774 775 isapnp_write_reg(sc, 776 isapnp_irq_range[i] + ISAPNP_IRQ_NUMBER, p->num); 777 778 switch (p->flags) { 779 case ISAPNP_IRQTYPE_LEVEL_PLUS: 780 v = ISAPNP_IRQ_LEVEL|ISAPNP_IRQ_HIGH; 781 break; 782 783 case ISAPNP_IRQTYPE_EDGE_PLUS: 784 v = ISAPNP_IRQ_HIGH; 785 break; 786 787 case ISAPNP_IRQTYPE_LEVEL_MINUS: 788 v = ISAPNP_IRQ_LEVEL; 789 break; 790 791 default: 792 case ISAPNP_IRQTYPE_EDGE_MINUS: 793 v = 0; 794 break; 795 } 796 isapnp_write_reg(sc, 797 isapnp_irq_range[i] + ISAPNP_IRQ_CONTROL, v); 798 } 799 800 for (i = 0; i < sizeof(isapnp_drq_range); i++) { 801 u_char v; 802 803 if (i < ipa->ipa_ndrq) 804 v = ipa->ipa_drq[i].num; 805 else 806 v = 4; 807 808 isapnp_write_reg(sc, isapnp_drq_range[i], v); 809 } 810 811 for (i = 0; i < sizeof(isapnp_mem32_range); i++) { 812 if (i < ipa->ipa_nmem32) 813 r = &ipa->ipa_mem32[i]; 814 else 815 r = &rz; 816 817 isapnp_write_reg(sc, 818 isapnp_mem32_range[i] + ISAPNP_MEM32_BASE_31_24, 819 B3(r->base)); 820 isapnp_write_reg(sc, 821 isapnp_mem32_range[i] + ISAPNP_MEM32_BASE_23_16, 822 B2(r->base)); 823 isapnp_write_reg(sc, 824 isapnp_mem32_range[i] + ISAPNP_MEM32_BASE_15_8, 825 B1(r->base)); 826 isapnp_write_reg(sc, 827 isapnp_mem32_range[i] + ISAPNP_MEM32_BASE_7_0, 828 B0(r->base)); 829 830 isapnp_write_reg(sc, 831 isapnp_mem32_range[i] + ISAPNP_MEM32_LRANGE_31_24, 832 B3(r->length)); 833 isapnp_write_reg(sc, 834 isapnp_mem32_range[i] + ISAPNP_MEM32_LRANGE_23_16, 835 B2(r->length)); 836 isapnp_write_reg(sc, 837 isapnp_mem32_range[i] + ISAPNP_MEM32_LRANGE_15_8, 838 B1(r->length)); 839 isapnp_write_reg(sc, 840 isapnp_mem32_range[i] + ISAPNP_MEM32_LRANGE_7_0, 841 B0(r->length)); 842 } 843 } 844 845 846 /* isapnp_match(): 847 * Probe routine 848 */ 849 static int 850 isapnp_match(device_t parent, cfdata_t match, void *aux) 851 { 852 struct isapnp_softc sc; 853 struct isa_attach_args *ia = aux; 854 struct isapnp_probe_cookie *ipc; 855 856 /* 857 * If the system has no ISA expansion slots, skip the probe 858 * because it's very slow. 859 */ 860 if (isa_get_slotcount() == 0) 861 return (0); 862 863 /* 864 * Ensure we only probe ISA PnP once; we don't actually consume 865 * bus resources, so we have to prevent being cloned forever. 866 */ 867 for (ipc = LIST_FIRST(&isapnp_probes); ipc != NULL; 868 ipc = LIST_NEXT(ipc, ipc_link)) 869 if (ipc->ipc_parent == parent) 870 return (0); 871 872 ipc = malloc(sizeof(*ipc), M_DEVBUF, M_NOWAIT); 873 if (ipc == NULL) 874 panic("isapnp_match: can't allocate probe cookie"); 875 876 ipc->ipc_parent = parent; 877 LIST_INSERT_HEAD(&isapnp_probes, ipc, ipc_link); 878 879 sc.sc_iot = ia->ia_iot; 880 881 if (isapnp_map(&sc)) 882 return 0; 883 884 isapnp_unmap(&sc); 885 886 /* 887 * We always match. We must let all legacy ISA devices map 888 * their address spaces before we look for a read port. 889 */ 890 ia->ia_io[0].ir_addr = ISAPNP_ADDR; 891 ia->ia_io[0].ir_size = 1; 892 893 ia->ia_niomem = 0; 894 ia->ia_nirq = 0; 895 ia->ia_ndrq = 0; 896 897 return (1); 898 } 899 900 901 /* isapnp_attach 902 * Attach the PnP `bus'. 903 */ 904 static void 905 isapnp_attach(device_t parent, device_t self, void *aux) 906 { 907 struct isapnp_softc *sc = device_private(self); 908 struct isa_attach_args *ia = aux; 909 910 sc->sc_dev = self; 911 sc->sc_iot = ia->ia_iot; 912 sc->sc_memt = ia->ia_memt; 913 sc->sc_ic = ia->ia_ic; 914 sc->sc_dmat = ia->ia_dmat; 915 sc->sc_ncards = 0; 916 917 aprint_normal(": ISA Plug 'n Play device support\n"); 918 919 if (isapnp_map(sc)) { 920 aprint_error_dev(self, "unable to map PnP register\n"); 921 return; 922 } 923 924 #ifdef _KERNEL 925 /* 926 * Defer configuration until the rest of the ISA devices have 927 * attached themselves. 928 */ 929 config_defer(self, isapnp_callback); 930 #else 931 isapnp_callback(self); 932 #endif 933 934 if (!pmf_device_register(self, NULL, NULL)) 935 aprint_error_dev(self, "couldn't establish power handler\n"); 936 } 937 938 /* isapnp_callback 939 * Find and attach PnP cards. 940 */ 941 void 942 isapnp_callback(device_t self) 943 { 944 struct isapnp_softc *sc = device_private(self); 945 struct isapnp_attach_args *ipa, *lpa; 946 int c, d; 947 948 /* 949 * Look for cards. If none are found, we say so and just return. 950 */ 951 if (isapnp_find(sc, 1) == 0) { 952 aprint_verbose_dev(sc->sc_dev, 953 "no ISA Plug 'n Play devices found\n"); 954 return; 955 } 956 957 aprint_verbose_dev(sc->sc_dev, "read port 0x%x\n", sc->sc_read_port); 958 959 /* 960 * Now configure all of the cards. 961 */ 962 for (c = 0; c < sc->sc_ncards; c++) { 963 /* Good morning card c */ 964 isapnp_write_reg(sc, ISAPNP_WAKE, c + 1); 965 966 if ((ipa = isapnp_get_resource(sc, c)) == NULL) 967 continue; 968 969 DPRINTF(("Selecting attachments\n")); 970 for (d = 0; 971 (lpa = isapnp_bestconfig(sc, &ipa)) != NULL; d++) { 972 isapnp_write_reg(sc, ISAPNP_LOGICAL_DEV_NUM, d); 973 isapnp_configure(sc, lpa); 974 #ifdef DEBUG_ISAPNP 975 { 976 struct isapnp_attach_args pa; 977 978 isapnp_get_config(sc, &pa); 979 isapnp_print_config(&pa); 980 } 981 #endif 982 983 DPRINTF(("%s: configuring <%s, %s, %s, %s>\n", 984 device_xname(sc->sc_dev), 985 lpa->ipa_devident, lpa->ipa_devlogic, 986 lpa->ipa_devcompat, lpa->ipa_devclass)); 987 if (lpa->ipa_pref == ISAPNP_DEP_CONFLICTING) { 988 aprint_verbose_dev(sc->sc_dev, 989 "<%s, %s, %s, %s> ignored; %s\n", 990 lpa->ipa_devident, lpa->ipa_devlogic, 991 lpa->ipa_devcompat, lpa->ipa_devclass, 992 "resource conflict"); 993 ISAPNP_FREE(lpa); 994 continue; 995 } 996 997 lpa->ipa_ic = sc->sc_ic; 998 lpa->ipa_iot = sc->sc_iot; 999 lpa->ipa_memt = sc->sc_memt; 1000 lpa->ipa_dmat = sc->sc_dmat; 1001 1002 isapnp_write_reg(sc, ISAPNP_ACTIVATE, 1); 1003 #ifdef _KERNEL 1004 if (config_found_sm_loc(self, "isapnp", NULL, lpa, 1005 isapnp_print, isapnp_submatch) == NULL) 1006 isapnp_write_reg(sc, ISAPNP_ACTIVATE, 0); 1007 #else 1008 isapnp_print(lpa, NULL); 1009 aprint_verbose("\n"); 1010 #endif 1011 ISAPNP_FREE(lpa); 1012 } 1013 isapnp_write_reg(sc, ISAPNP_WAKE, 0); /* Good night cards */ 1014 } 1015 } 1016