This source file includes following definitions.
- isapnp_init
- isapnp_shift_bit
- isapnp_findcard
- isapnp_free_region
- isapnp_alloc_region
- isapnp_alloc_irq
- isapnp_alloc_drq
- isapnp_testconfig
- isapnp_config
- isapnp_unconfig
- isapnp_bestconfig
- isapnp_id_to_vendor
- isapnp_print_region
- isapnp_print_pin
- isapnp_print
- isapnp_com_submatch
- isapnp_submatch
- isapnp_find
- isapnp_configure
- isapnp_isa_attach_hook
- isapnp_match
- isapnp_attach
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37 #include <sys/param.h>
38 #include <sys/systm.h>
39 #include <sys/device.h>
40 #include <sys/malloc.h>
41
42 #include <machine/bus.h>
43
44 #include <dev/isa/isapnpreg.h>
45
46 #include <dev/isa/isavar.h>
47 #include <dev/isa/isadmavar.h>
48
49 #include <dev/isa/pnpdevs.h>
50
51 #include "isadma.h"
52
53 void isapnp_init(struct isapnp_softc *);
54 static __inline u_char isapnp_shift_bit(struct isapnp_softc *);
55 int isapnp_findcard(struct isapnp_softc *);
56 void isapnp_free_region(bus_space_tag_t, struct isapnp_region *);
57 int isapnp_alloc_region(bus_space_tag_t, struct isapnp_region *);
58 int isapnp_alloc_irq(isa_chipset_tag_t, struct isapnp_pin *);
59 int isapnp_alloc_drq(struct device *, struct isapnp_pin *);
60 int isapnp_testconfig(bus_space_tag_t, bus_space_tag_t,
61 struct isa_attach_args *, int);
62 struct isa_attach_args *isapnp_bestconfig(struct device *,
63 struct isapnp_softc *, struct isa_attach_args **);
64 void isapnp_print_region(const char *, struct isapnp_region *,
65 size_t);
66 void isapnp_configure(struct isapnp_softc *,
67 const struct isa_attach_args *);
68 void isapnp_print_pin(const char *, struct isapnp_pin *, size_t);
69 int isapnp_print(void *, const char *);
70 int isapnp_submatch(struct device *, void *, void *);
71 int isapnp_com_submatch(struct device *, void *, void *);
72 int isapnp_find(struct isapnp_softc *, int);
73 int isapnp_match(struct device *, void *, void *);
74 void isapnp_attach(struct device *, struct device *, void *);
75
76 #ifdef DEBUG_ISAPNP
77 # define DPRINTF(a) printf a
78 #else
79 # define DPRINTF(a)
80 #endif
81
82 struct cfattach isapnp_ca = {
83 sizeof(struct isapnp_softc), isapnp_match, isapnp_attach
84 };
85
86 struct cfdriver isapnp_cd = {
87 NULL, "isapnp", DV_DULL
88 };
89
90
91
92
93
94 void
95 isapnp_init(sc)
96 struct isapnp_softc *sc;
97 {
98 int i;
99 u_char v = ISAPNP_LFSR_INIT;
100
101
102 ISAPNP_WRITE_ADDR(sc, 0);
103 ISAPNP_WRITE_ADDR(sc, 0);
104
105
106 for (i = 0; i < ISAPNP_LFSR_LENGTH; i++) {
107 ISAPNP_WRITE_ADDR(sc, v);
108 v = ISAPNP_LFSR_NEXT(v);
109 }
110 }
111
112
113
114
115
116 static __inline u_char
117 isapnp_shift_bit(sc)
118 struct isapnp_softc *sc;
119 {
120 u_char c1, c2;
121
122 DELAY(250);
123 c1 = ISAPNP_READ_DATA(sc);
124 DELAY(250);
125 c2 = ISAPNP_READ_DATA(sc);
126
127 if (c1 == 0x55 && c2 == 0xAA)
128 return 0x80;
129 else
130 return 0;
131 }
132
133
134
135
136
137
138
139 int
140 isapnp_findcard(sc)
141 struct isapnp_softc *sc;
142 {
143 u_char v = ISAPNP_LFSR_INIT, csum, w;
144 int i, b;
145
146 if (sc->sc_ncards == ISAPNP_MAX_CARDS) {
147 printf("%s: Too many pnp cards\n", sc->sc_dev.dv_xname);
148 return 0;
149 }
150
151
152 isapnp_write_reg(sc, ISAPNP_WAKE, 0);
153 isapnp_write_reg(sc, ISAPNP_SET_RD_PORT, sc->sc_read_port >> 2);
154 sc->sc_read_port |= 3;
155 DELAY(1000);
156
157 ISAPNP_WRITE_ADDR(sc, ISAPNP_SERIAL_ISOLATION);
158 DELAY(1000);
159
160
161 for(i = 0; i < 8; i++) {
162
163 for (w = 0, b = 0; b < 8; b++) {
164 u_char neg = isapnp_shift_bit(sc);
165
166 w >>= 1;
167 w |= neg;
168 v = ISAPNP_LFSR_NEXT(v) ^ neg;
169 }
170 sc->sc_id[sc->sc_ncards][i] = w;
171 }
172
173
174 for (csum = 0, b = 0; b < 8; b++) {
175 u_char neg = isapnp_shift_bit(sc);
176
177 csum >>= 1;
178 csum |= neg;
179 }
180 sc->sc_id[sc->sc_ncards][8] = csum;
181
182 if (csum == v) {
183 sc->sc_ncards++;
184 isapnp_write_reg(sc, ISAPNP_CARD_SELECT_NUM, sc->sc_ncards);
185 return 1;
186 }
187 return 0;
188 }
189
190
191
192
193
194 void
195 isapnp_free_region(t, r)
196 bus_space_tag_t t;
197 struct isapnp_region *r;
198 {
199 if (r->length == 0)
200 return;
201
202 bus_space_unmap(t, r->h, r->length);
203 r->h = NULL;
204 }
205
206
207
208
209
210 int
211 isapnp_alloc_region(t, r)
212 bus_space_tag_t t;
213 struct isapnp_region *r;
214 {
215 int error = 0;
216
217 if (r->length == 0)
218 return 0;
219
220 r->h = NULL;
221 for (r->base = r->minbase; r->base <= r->maxbase;
222 r->base += r->align) {
223 error = bus_space_map(t, r->base, r->length, 0, &r->h);
224 if (error == 0)
225 return 0;
226 }
227 return error;
228 }
229
230
231
232
233
234 int
235 isapnp_alloc_irq(ic, i)
236 isa_chipset_tag_t ic;
237 struct isapnp_pin *i;
238 {
239 int irq;
240 #define LEVEL_IRQ (ISAPNP_IRQTYPE_LEVEL_PLUS|ISAPNP_IRQTYPE_LEVEL_MINUS)
241 i->type = (i->flags & LEVEL_IRQ) ? IST_LEVEL : IST_EDGE;
242
243 if (i->bits == 0) {
244 i->num = 0;
245 return 0;
246 }
247
248 if (isa_intr_alloc(ic, i->bits, i->type, &irq) == 0) {
249 i->num = irq;
250 return 0;
251 }
252
253 return EINVAL;
254 }
255
256
257
258
259 int
260 isapnp_alloc_drq(isa, i)
261 struct device *isa;
262 struct isapnp_pin *i;
263 {
264 #if NISADMA > 0
265 int b;
266
267 if (i->bits == 0) {
268 i->num = 0;
269 return 0;
270 }
271
272 for (b = 0; b < 16; b++)
273 if ((i->bits & (1 << b)) && isa_drq_isfree(isa, b)) {
274 i->num = b;
275 return 0;
276 }
277 #endif
278
279 return EINVAL;
280 }
281
282
283
284
285 int
286 isapnp_testconfig(iot, memt, ipa, alloc)
287 bus_space_tag_t iot, memt;
288 struct isa_attach_args *ipa;
289 int alloc;
290 {
291 int nio = 0, nmem = 0, nmem32 = 0, nirq = 0, ndrq = 0;
292 int error = 0;
293
294 #ifdef DEBUG_ISAPNP
295 isapnp_print_attach(ipa);
296 #endif
297
298 for (; nio < ipa->ipa_nio; nio++) {
299 error = isapnp_alloc_region(iot, &ipa->ipa_io[nio]);
300 if (error)
301 goto bad;
302 }
303
304 for (; nmem < ipa->ipa_nmem; nmem++) {
305 error = isapnp_alloc_region(memt, &ipa->ipa_mem[nmem]);
306 if (error)
307 goto bad;
308 }
309
310 for (; nmem32 < ipa->ipa_nmem32; nmem32++) {
311 error = isapnp_alloc_region(memt, &ipa->ipa_mem32[nmem32]);
312 if (error)
313 goto bad;
314 }
315
316 for (; nirq < ipa->ipa_nirq; nirq++) {
317 error = isapnp_alloc_irq(ipa->ia_ic, &ipa->ipa_irq[nirq]);
318 if (error)
319 goto bad;
320 }
321
322 for (; ndrq < ipa->ipa_ndrq; ndrq++) {
323 error = isapnp_alloc_drq(ipa->ia_isa, &ipa->ipa_drq[ndrq]);
324 if (error)
325 goto bad;
326 }
327
328 if (alloc)
329 return error;
330
331 bad:
332 #ifdef notyet
333 for (ndrq--; ndrq >= 0; ndrq--)
334 isapnp_free_pin(&ipa->ipa_drq[ndrq]);
335
336 for (nirq--; nirq >= 0; nirq--)
337 isapnp_free_pin(&ipa->ipa_irq[nirq]);
338 #endif
339
340 for (nmem32--; nmem32 >= 0; nmem32--)
341 isapnp_free_region(memt, &ipa->ipa_mem32[nmem32]);
342
343 for (nmem--; nmem >= 0; nmem--)
344 isapnp_free_region(memt, &ipa->ipa_mem[nmem]);
345
346 for (nio--; nio >= 0; nio--)
347 isapnp_free_region(iot, &ipa->ipa_io[nio]);
348
349 return error;
350 }
351
352
353
354
355
356 int
357 isapnp_config(iot, memt, ipa)
358 bus_space_tag_t iot, memt;
359 struct isa_attach_args *ipa;
360 {
361 return isapnp_testconfig(iot, memt, ipa, 1);
362 }
363
364
365
366
367
368 void
369 isapnp_unconfig(iot, memt, ipa)
370 bus_space_tag_t iot, memt;
371 struct isa_attach_args *ipa;
372 {
373 int i;
374
375 #ifdef notyet
376 for (i = 0; i < ipa->ipa_ndrq; i++)
377 isapnp_free_pin(&ipa->ipa_drq[i]);
378
379 for (i = 0; i < ipa->ipa_nirq; i++)
380 isapnp_free_pin(&ipa->ipa_irq[i]);
381 #endif
382
383 for (i = 0; i < ipa->ipa_nmem32; i++)
384 isapnp_free_region(memt, &ipa->ipa_mem32[i]);
385
386 for (i = 0; i < ipa->ipa_nmem; i++)
387 isapnp_free_region(memt, &ipa->ipa_mem[i]);
388
389 for (i = 0; i < ipa->ipa_nio; i++)
390 isapnp_free_region(iot, &ipa->ipa_io[i]);
391 }
392
393
394
395
396
397
398 struct isa_attach_args *
399 isapnp_bestconfig(isa, sc, ipa)
400 struct device *isa;
401 struct isapnp_softc *sc;
402 struct isa_attach_args **ipa;
403 {
404 struct isa_attach_args *c, *best, *f = *ipa;
405 int error;
406
407 for (;;) {
408 if (f == NULL)
409 return NULL;
410
411 #define SAMEDEV(a, b) (strcmp((a)->ipa_devlogic, (b)->ipa_devlogic) == 0)
412
413
414 for (best = c = f; c != NULL; c = c->ipa_sibling) {
415 if (!SAMEDEV(c, f))
416 continue;
417 if (c->ipa_pref < best->ipa_pref)
418 best = c;
419 }
420
421 best->ia_isa = isa;
422
423 error = isapnp_testconfig(sc->sc_iot, sc->sc_memt, best, 0);
424
425
426 if (best == f)
427 f = f->ipa_sibling;
428 else {
429 for (c = f; c->ipa_sibling != best; c = c->ipa_sibling)
430 continue;
431 c->ipa_sibling = best->ipa_sibling;
432 }
433
434 if (error) {
435 best->ipa_pref = ISAPNP_DEP_CONFLICTING;
436
437 for (c = f; c != NULL; c = c->ipa_sibling)
438 if (c != best && SAMEDEV(c, best))
439 break;
440
441 if (c == NULL) {
442 *ipa = f;
443 return best;
444 }
445
446 ISAPNP_FREE(best);
447 continue;
448 }
449 else {
450
451 struct isa_attach_args *l = NULL, *n = NULL, *d;
452
453 for (c = f; c; ) {
454 if (c == best)
455 continue;
456 d = c->ipa_sibling;
457 if (SAMEDEV(c, best))
458 ISAPNP_FREE(c);
459 else {
460 if (n)
461 n->ipa_sibling = c;
462
463 else
464 l = c;
465 n = c;
466 c->ipa_sibling = NULL;
467 }
468 c = d;
469 }
470 f = l;
471 }
472 *ipa = f;
473 return best;
474 }
475 }
476
477
478
479
480
481 char *
482 isapnp_id_to_vendor(v, id)
483 char *v;
484 const u_char *id;
485 {
486 static const char hex[] = "0123456789ABCDEF";
487 char *p = v;
488
489 *p++ = 'A' + (id[0] >> 2) - 1;
490 *p++ = 'A' + ((id[0] & 3) << 3) + (id[1] >> 5) - 1;
491 *p++ = 'A' + (id[1] & 0x1f) - 1;
492 *p++ = hex[id[2] >> 4];
493 *p++ = hex[id[2] & 0x0f];
494 *p++ = hex[id[3] >> 4];
495 *p++ = hex[id[3] & 0x0f];
496 *p = '\0';
497
498 return v;
499 }
500
501
502
503
504
505 void
506 isapnp_print_region(str, r, n)
507 const char *str;
508 struct isapnp_region *r;
509 size_t n;
510 {
511 size_t i;
512
513 if (n == 0)
514 return;
515
516 printf(" %s ", str);
517 for (i = 0; i < n; i++, r++) {
518 printf("0x%x", r->base);
519 if (r->length)
520 printf("/%d", r->length);
521 if (i != n - 1)
522 printf(",");
523 }
524 }
525
526
527
528
529
530 void
531 isapnp_print_pin(str, p, n)
532 const char *str;
533 struct isapnp_pin *p;
534 size_t n;
535 {
536 size_t i;
537
538 if (n == 0)
539 return;
540
541 printf(" %s ", str);
542 for (i = 0; i < n; i++, p++) {
543 printf("%d", p->num);
544 if (i != n - 1)
545 printf(",");
546 }
547 }
548
549
550
551
552 int
553 isapnp_print(aux, str)
554 void *aux;
555 const char *str;
556 {
557 struct isa_attach_args *ipa = aux;
558
559 if (!str)
560 printf(" ");
561 printf("\"%s, %s, %s, %s\"", ipa->ipa_devident,
562 ipa->ipa_devlogic, ipa->ipa_devcompat, ipa->ipa_devclass);
563
564 if (str)
565 printf(" at %s", str);
566
567 isapnp_print_region("port", ipa->ipa_io, ipa->ipa_nio);
568 isapnp_print_region("mem", ipa->ipa_mem, ipa->ipa_nmem);
569 isapnp_print_region("mem32", ipa->ipa_mem32, ipa->ipa_nmem32);
570 isapnp_print_pin("irq", ipa->ipa_irq, ipa->ipa_nirq);
571 isapnp_print_pin("drq", ipa->ipa_drq, ipa->ipa_ndrq);
572 return UNCONF;
573 }
574
575
576
577
578
579
580
581 int
582 isapnp_com_submatch(parent, match, aux)
583 struct device *parent;
584 void *match, *aux;
585 {
586 struct cfdata *cf = match;
587 struct isa_attach_args *ipa = aux;
588
589 if ((strcmp("com", cf->cf_driver->cd_name) == 0 ||
590 strcmp("pccom", cf->cf_driver->cd_name) == 0) &&
591 ipa->ipa_nio == 1 && ipa->ipa_nirq == 1 &&
592 ipa->ipa_ndrq == 0 && ipa->ipa_nmem == 0 &&
593 ipa->ipa_io[0].length == 8) {
594 if (isapnp_config(ipa->ia_iot, ipa->ia_memt, ipa)) {
595 printf("%s: error in region allocation\n",
596 cf->cf_driver->cd_name);
597 return (0);
598 }
599 return ((*cf->cf_attach->ca_match)(parent, match, ipa));
600 }
601 return (0);
602 }
603
604
605
606
607 int
608 isapnp_submatch(parent, match, aux)
609 struct device *parent;
610 void *match, *aux;
611 {
612 struct cfdata *cf = match;
613 struct isa_attach_args *ipa = aux;
614 const char *dname;
615 int i;
616
617 for (i = 0; i < sizeof(isapnp_knowndevs)/sizeof(isapnp_knowndevs[0]); i++) {
618 dname = NULL;
619
620 if (strcmp(isapnp_knowndevs[i].pnpid, ipa->ipa_devlogic) == 0)
621 dname = isapnp_knowndevs[i].driver;
622 else if (strcmp(isapnp_knowndevs[i].pnpid, ipa->ipa_devcompat) == 0)
623 dname = isapnp_knowndevs[i].driver;
624
625 if (dname && strcmp(dname, cf->cf_driver->cd_name) == 0) {
626
627
628
629
630 if (isapnp_config(ipa->ia_iot, ipa->ia_memt, ipa)) {
631 printf("%s: error in region allocation\n",
632 cf->cf_driver->cd_name);
633 return (0);
634 }
635
636 return ((*cf->cf_attach->ca_match)(parent, match, ipa));
637 }
638 }
639
640 return (0);
641 }
642
643
644
645
646 int
647 isapnp_find(sc, all)
648 struct isapnp_softc *sc;
649 int all;
650 {
651 int p;
652
653 isapnp_init(sc);
654
655 isapnp_write_reg(sc, ISAPNP_CONFIG_CONTROL, ISAPNP_CC_RESET_DRV);
656 DELAY(2000);
657
658 isapnp_init(sc);
659 DELAY(2000);
660
661 for (p = ISAPNP_RDDATA_MIN; p <= ISAPNP_RDDATA_MAX; p += 4) {
662 sc->sc_read_port = p;
663 if (isapnp_map_readport(sc))
664 continue;
665 DPRINTF(("%s: Trying port %x\n", sc->sc_dev.dv_xname, p));
666 if (isapnp_findcard(sc))
667 break;
668 isapnp_unmap_readport(sc);
669 }
670
671 if (p > ISAPNP_RDDATA_MAX) {
672 sc->sc_read_port = 0;
673 return 0;
674 }
675
676 if (all)
677 while (isapnp_findcard(sc))
678 continue;
679
680 return 1;
681 }
682
683
684
685
686
687
688
689 void
690 isapnp_configure(sc, ipa)
691 struct isapnp_softc *sc;
692 const struct isa_attach_args *ipa;
693 {
694 int i;
695 static u_char isapnp_mem_range[] = ISAPNP_MEM_DESC;
696 static u_char isapnp_io_range[] = ISAPNP_IO_DESC;
697 static u_char isapnp_irq_range[] = ISAPNP_IRQ_DESC;
698 static u_char isapnp_drq_range[] = ISAPNP_DRQ_DESC;
699 static u_char isapnp_mem32_range[] = ISAPNP_MEM32_DESC;
700 const struct isapnp_region *r;
701 const struct isapnp_pin *p;
702 struct isapnp_region rz;
703 struct isapnp_pin pz;
704
705 bzero(&pz, sizeof(pz));
706 bzero(&rz, sizeof(rz));
707
708 #define B0(a) ((a) & 0xff)
709 #define B1(a) (((a) >> 8) & 0xff)
710 #define B2(a) (((a) >> 16) & 0xff)
711 #define B3(a) (((a) >> 24) & 0xff)
712
713 for (i = 0; i < sizeof(isapnp_io_range); i++) {
714 if (i < ipa->ipa_nio)
715 r = &ipa->ipa_io[i];
716 else
717 r = &rz;
718
719 isapnp_write_reg(sc,
720 isapnp_io_range[i] + ISAPNP_IO_BASE_15_8, B1(r->base));
721 isapnp_write_reg(sc,
722 isapnp_io_range[i] + ISAPNP_IO_BASE_7_0, B0(r->base));
723 }
724
725 for (i = 0; i < sizeof(isapnp_mem_range); i++) {
726 if (i < ipa->ipa_nmem)
727 r = &ipa->ipa_mem[i];
728 else
729 r = &rz;
730
731 isapnp_write_reg(sc,
732 isapnp_mem_range[i] + ISAPNP_MEM_BASE_23_16, B2(r->base));
733 isapnp_write_reg(sc,
734 isapnp_mem_range[i] + ISAPNP_MEM_BASE_15_8, B1(r->base));
735
736 isapnp_write_reg(sc,
737 isapnp_mem_range[i] + ISAPNP_MEM_LRANGE_23_16,
738 B2(r->length));
739 isapnp_write_reg(sc,
740 isapnp_mem_range[i] + ISAPNP_MEM_LRANGE_15_8,
741 B1(r->length));
742 }
743
744 for (i = 0; i < sizeof(isapnp_irq_range); i++) {
745 u_char v;
746
747 if (i < ipa->ipa_nirq)
748 p = &ipa->ipa_irq[i];
749 else
750 p = &pz;
751
752 isapnp_write_reg(sc,
753 isapnp_irq_range[i] + ISAPNP_IRQ_NUMBER, p->num);
754
755 switch (p->flags) {
756 case ISAPNP_IRQTYPE_LEVEL_PLUS:
757 v = ISAPNP_IRQ_LEVEL|ISAPNP_IRQ_HIGH;
758 break;
759
760 case ISAPNP_IRQTYPE_EDGE_PLUS:
761 v = ISAPNP_IRQ_HIGH;
762 break;
763
764 case ISAPNP_IRQTYPE_LEVEL_MINUS:
765 v = ISAPNP_IRQ_LEVEL;
766 break;
767
768 default:
769 case ISAPNP_IRQTYPE_EDGE_MINUS:
770 v = 0;
771 break;
772 }
773 isapnp_write_reg(sc,
774 isapnp_irq_range[i] + ISAPNP_IRQ_CONTROL, v);
775 }
776
777 for (i = 0; i < sizeof(isapnp_drq_range); i++) {
778 u_char v;
779
780 if (i < ipa->ipa_ndrq)
781 v = ipa->ipa_drq[i].num;
782 else
783 v = 4;
784
785 isapnp_write_reg(sc, isapnp_drq_range[i], v);
786 }
787
788 for (i = 0; i < sizeof(isapnp_mem32_range); i++) {
789 if (i < ipa->ipa_nmem32)
790 r = &ipa->ipa_mem32[i];
791 else
792 r = &rz;
793
794 isapnp_write_reg(sc,
795 isapnp_mem32_range[i] + ISAPNP_MEM32_BASE_31_24,
796 B3(r->base));
797 isapnp_write_reg(sc,
798 isapnp_mem32_range[i] + ISAPNP_MEM32_BASE_23_16,
799 B2(r->base));
800 isapnp_write_reg(sc,
801 isapnp_mem32_range[i] + ISAPNP_MEM32_BASE_15_8,
802 B1(r->base));
803 isapnp_write_reg(sc,
804 isapnp_mem32_range[i] + ISAPNP_MEM32_BASE_7_0,
805 B0(r->base));
806
807 isapnp_write_reg(sc,
808 isapnp_mem32_range[i] + ISAPNP_MEM32_LRANGE_31_24,
809 B3(r->length));
810 isapnp_write_reg(sc,
811 isapnp_mem32_range[i] + ISAPNP_MEM32_LRANGE_23_16,
812 B2(r->length));
813 isapnp_write_reg(sc,
814 isapnp_mem32_range[i] + ISAPNP_MEM32_LRANGE_15_8,
815 B1(r->length));
816 isapnp_write_reg(sc,
817 isapnp_mem32_range[i] + ISAPNP_MEM32_LRANGE_7_0,
818 B0(r->length));
819 }
820 }
821
822
823
824
825
826
827
828 void
829 isapnp_isa_attach_hook(isa_sc)
830 struct isa_softc *isa_sc;
831
832 {
833 struct isapnp_softc sc;
834
835 bzero(&sc, sizeof sc);
836 sc.sc_iot = isa_sc->sc_iot;
837 sc.sc_ncards = 0;
838
839 if (isapnp_map(&sc))
840 return;
841
842 isapnp_init(&sc);
843
844 isapnp_write_reg(&sc, ISAPNP_CONFIG_CONTROL, ISAPNP_CC_RESET_DRV);
845 DELAY(2000);
846
847 isapnp_unmap(&sc);
848 }
849
850
851
852
853 int
854 isapnp_match(parent, match, aux)
855 struct device *parent;
856 void *match;
857 void *aux;
858 {
859 int rv;
860 struct isapnp_softc sc;
861 struct isa_attach_args *ia = aux;
862
863 sc.sc_iot = ia->ia_iot;
864 sc.sc_ncards = 0;
865 (void) strlcpy(sc.sc_dev.dv_xname, "(isapnp probe)",
866 sizeof sc.sc_dev.dv_xname);
867
868 if (isapnp_map(&sc))
869 return 0;
870
871 rv = isapnp_find(&sc, 0);
872 ia->ia_iobase = ISAPNP_ADDR;
873 ia->ia_iosize = 1;
874
875 isapnp_unmap(&sc);
876 if (rv)
877 isapnp_unmap_readport(&sc);
878
879 return (rv);
880 }
881
882
883
884
885
886 void
887 isapnp_attach(parent, self, aux)
888 struct device *parent, *self;
889 void *aux;
890 {
891 struct isapnp_softc *sc = (struct isapnp_softc *) self;
892 struct isa_attach_args *ia = aux;
893 void *match;
894 int c, d;
895
896 sc->sc_iot = ia->ia_iot;
897 sc->sc_memt = ia->ia_memt;
898 #if NISADMA > 0
899 sc->sc_dmat = ia->ia_dmat;
900 #endif
901 sc->sc_ncards = 0;
902
903 if (isapnp_map(sc))
904 panic("%s: bus map failed", sc->sc_dev.dv_xname);
905
906 if (!isapnp_find(sc, 1)) {
907 printf(": no cards found\n");
908 return;
909 }
910
911 printf(": read port 0x%x\n", sc->sc_read_port);
912
913 for (c = 0; c < sc->sc_ncards; c++) {
914 struct isa_attach_args *ipa, *lpa;
915
916
917 isapnp_write_reg(sc, ISAPNP_WAKE, c + 1);
918
919 if ((ipa = isapnp_get_resource(sc, c, ia)) == NULL)
920 continue;
921
922 DPRINTF(("Selecting attachments\n"));
923 for (d = 0;
924 (lpa = isapnp_bestconfig(parent, sc, &ipa)) != NULL; d++) {
925 isapnp_write_reg(sc, ISAPNP_LOGICAL_DEV_NUM, d);
926 isapnp_configure(sc, lpa);
927 #ifdef DEBUG_ISAPNP
928 {
929 struct isa_attach_args pa;
930
931 isapnp_get_config(sc, &pa);
932 isapnp_print_config(&pa);
933 }
934 #endif
935
936 DPRINTF(("%s: configuring <%s, %s, %s, %s>\n",
937 sc->sc_dev.dv_xname,
938 lpa->ipa_devident, lpa->ipa_devlogic,
939 lpa->ipa_devcompat, lpa->ipa_devclass));
940 if (lpa->ipa_pref == ISAPNP_DEP_CONFLICTING) {
941 isapnp_print(lpa, self->dv_xname);
942 printf(" resource conflict\n");
943 ISAPNP_FREE(lpa);
944 continue;
945 }
946
947 lpa->ia_ic = ia->ia_ic;
948 lpa->ia_iot = ia->ia_iot;
949 lpa->ia_memt = ia->ia_memt;
950 #if NISADMA > 0
951 lpa->ia_dmat = ia->ia_dmat;
952 #endif
953 lpa->ia_delaybah = ia->ia_delaybah;
954
955 isapnp_write_reg(sc, ISAPNP_ACTIVATE, 1);
956
957 if ((match = config_search(isapnp_submatch,
958 self, lpa)))
959 config_attach(self, match, lpa, isapnp_print);
960 else if ((match = config_search(isapnp_com_submatch,
961 self, lpa)))
962 config_attach(self, match, lpa, isapnp_print);
963 else {
964 isapnp_print(lpa, self->dv_xname);
965 printf(" not configured\n");
966 isapnp_write_reg(sc, ISAPNP_ACTIVATE, 0);
967 }
968 ISAPNP_FREE(lpa);
969 }
970 isapnp_write_reg(sc, ISAPNP_WAKE, 0);
971 }
972 }