This source file includes following definitions.
- pcmcia_read_cis
- pcmcia_scan_cis
- pcmcia_print_cis
- pcmcia_parse_cis_tuple
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 #include <sys/types.h>
34 #include <sys/param.h>
35 #include <sys/systm.h>
36 #include <sys/device.h>
37 #include <sys/malloc.h>
38
39 #include <dev/pcmcia/pcmciareg.h>
40 #include <dev/pcmcia/pcmciachip.h>
41 #include <dev/pcmcia/pcmciavar.h>
42
43 #ifdef PCMCIACISDEBUG
44 #define DPRINTF(arg) printf arg
45 #else
46 #define DPRINTF(arg)
47 #endif
48
49 #define PCMCIA_CIS_SIZE 1024
50
51 struct cis_state {
52 int count;
53 int gotmfc;
54 struct pcmcia_config_entry temp_cfe;
55 struct pcmcia_config_entry *default_cfe;
56 struct pcmcia_card *card;
57 struct pcmcia_function *pf;
58 };
59
60 int pcmcia_parse_cis_tuple(struct pcmcia_tuple *, void *);
61
62 void
63 pcmcia_read_cis(sc)
64 struct pcmcia_softc *sc;
65 {
66 struct cis_state state;
67
68 memset(&state, 0, sizeof state);
69
70 state.card = &sc->card;
71
72 state.card->error = 0;
73 state.card->cis1_major = -1;
74 state.card->cis1_minor = -1;
75 state.card->cis1_info[0] = NULL;
76 state.card->cis1_info[1] = NULL;
77 state.card->cis1_info[2] = NULL;
78 state.card->cis1_info[3] = NULL;
79 state.card->manufacturer = PCMCIA_VENDOR_INVALID;
80 state.card->product = PCMCIA_PRODUCT_INVALID;
81 SIMPLEQ_INIT(&state.card->pf_head);
82
83 state.pf = NULL;
84
85 if (pcmcia_scan_cis((struct device *)sc, pcmcia_parse_cis_tuple,
86 &state) == -1)
87 state.card->error++;
88 }
89
90 int
91 pcmcia_scan_cis(dev, fct, arg)
92 struct device *dev;
93 int (*fct)(struct pcmcia_tuple *, void *);
94 void *arg;
95 {
96 struct pcmcia_softc *sc = (struct pcmcia_softc *) dev;
97 pcmcia_chipset_tag_t pct;
98 pcmcia_chipset_handle_t pch;
99 int window;
100 struct pcmcia_mem_handle pcmh;
101 struct pcmcia_tuple tuple;
102 int longlink_present;
103 int longlink_common;
104 u_long longlink_addr;
105 int mfc_count;
106 int mfc_index;
107 struct {
108 int common;
109 u_long addr;
110 } mfc[256 / 5];
111 int ret;
112
113 ret = 0;
114
115 pct = sc->pct;
116 pch = sc->pch;
117
118
119
120 if (pcmcia_chip_mem_alloc(pct, pch, PCMCIA_CIS_SIZE, &pcmh)) {
121 #ifdef DIAGNOSTIC
122 printf("%s: can't alloc memory to read attributes\n",
123 sc->dev.dv_xname);
124 #endif
125 return -1;
126 }
127
128
129 if (pcmcia_chip_mem_map(pct, pch, PCMCIA_MEM_ATTR, 0,
130 PCMCIA_CIS_SIZE, &pcmh, &tuple.ptr, &window)) {
131 pcmcia_chip_mem_free(pct, pch, &pcmh);
132 #ifdef DIAGNOSTIC
133 printf("%s: can't map memory to read attributes\n",
134 sc->dev.dv_xname);
135 #endif
136 return -1;
137 }
138 tuple.memt = pcmh.memt;
139 tuple.memh = pcmh.memh;
140
141 DPRINTF(("cis mem map %x\n", (unsigned int) tuple.memh));
142
143 tuple.mult = 2;
144
145 longlink_present = 1;
146 longlink_common = 1;
147 longlink_addr = 0;
148
149 mfc_count = 0;
150 mfc_index = 0;
151
152 DPRINTF(("%s: CIS tuple chain:\n", sc->dev.dv_xname));
153
154 while (1) {
155 while (1) {
156
157
158
159
160
161
162 if (tuple.mult * tuple.ptr >= PCMCIA_CIS_SIZE - 1
163 - 32 ) {
164 DPRINTF(("CISTPL_END (too long CIS)\n"));
165 tuple.code = PCMCIA_CISTPL_END;
166 goto cis_end;
167 }
168
169
170
171 tuple.code = pcmcia_cis_read_1(&tuple, tuple.ptr);
172
173
174
175 if (tuple.code == PCMCIA_CISTPL_NULL) {
176 DPRINTF(("CISTPL_NONE\n 00\n"));
177 tuple.ptr++;
178 continue;
179 } else if (tuple.code == PCMCIA_CISTPL_END) {
180 DPRINTF(("CISTPL_END\n ff\n"));
181 cis_end:
182
183
184 if ((*fct) (&tuple, arg)) {
185 pcmcia_chip_mem_unmap(pct, pch,
186 window);
187 ret = 1;
188 goto done;
189 }
190 tuple.ptr++;
191 break;
192 }
193
194
195 tuple.length = pcmcia_cis_read_1(&tuple, tuple.ptr + 1);
196 switch (tuple.code) {
197 case PCMCIA_CISTPL_LONGLINK_A:
198 case PCMCIA_CISTPL_LONGLINK_C:
199 if (tuple.length < 4) {
200 DPRINTF(("CISTPL_LONGLINK_%s too "
201 "short %d\n",
202 longlink_common ? "C" : "A",
203 tuple.length));
204 break;
205 }
206 longlink_present = 1;
207 longlink_common = (tuple.code ==
208 PCMCIA_CISTPL_LONGLINK_C) ? 1 : 0;
209 longlink_addr = pcmcia_tuple_read_4(&tuple, 0);
210 DPRINTF(("CISTPL_LONGLINK_%s %lx\n",
211 longlink_common ? "C" : "A",
212 longlink_addr));
213 break;
214 case PCMCIA_CISTPL_NO_LINK:
215 longlink_present = 0;
216 DPRINTF(("CISTPL_NO_LINK\n"));
217 break;
218 case PCMCIA_CISTPL_CHECKSUM:
219 if (tuple.length < 5) {
220 DPRINTF(("CISTPL_CHECKSUM too "
221 "short %d\n", tuple.length));
222 break;
223 } {
224 int16_t offset;
225 u_long addr, length;
226 u_int cksum, sum;
227 int i;
228
229 *((u_int16_t *) & offset) =
230 pcmcia_tuple_read_2(&tuple, 0);
231 length = pcmcia_tuple_read_2(&tuple, 2);
232 cksum = pcmcia_tuple_read_1(&tuple, 4);
233
234 addr = tuple.ptr + offset;
235
236 DPRINTF(("CISTPL_CHECKSUM addr=%lx "
237 "len=%lx cksum=%x",
238 addr, length, cksum));
239
240
241
242
243
244 if ((addr >= PCMCIA_CIS_SIZE) ||
245 ((addr + length) < 0) ||
246 ((addr + length) >=
247 PCMCIA_CIS_SIZE)) {
248 DPRINTF((" skipped, "
249 "too distant\n"));
250 break;
251 }
252 sum = 0;
253 for (i = 0; i < length; i++)
254 sum +=
255 bus_space_read_1(tuple.memt,
256 tuple.memh,
257 addr + tuple.mult * i);
258 if (cksum != (sum & 0xff)) {
259 DPRINTF((" failed sum=%x\n",
260 sum));
261 printf("%s: CIS checksum "
262 "failed\n",
263 sc->dev.dv_xname);
264 #if 0
265
266
267
268
269 ret = -1;
270 #endif
271 } else {
272 DPRINTF((" ok\n"));
273 }
274 }
275 break;
276 case PCMCIA_CISTPL_LONGLINK_MFC:
277 if (tuple.length < 6) {
278 DPRINTF(("CISTPL_LONGLINK_MFC too "
279 "short %d\n", tuple.length));
280 break;
281 }
282 if (((tuple.length - 1) % 5) != 0) {
283 DPRINTF(("CISTPL_LONGLINK_MFC bogus "
284 "length %d\n", tuple.length));
285 break;
286 }
287 {
288 int i, tmp_count;
289
290
291
292
293
294
295
296 tmp_count =
297 pcmcia_tuple_read_1(&tuple, 0);
298 DPRINTF(("CISTPL_LONGLINK_MFC %d",
299 tmp_count));
300
301
302
303
304
305
306 if (tuple.length != (tmp_count*5 + 1)) {
307 DPRINTF((" bogus length %d\n",
308 tuple.length));
309 break;
310 }
311
312 #ifdef PCMCIACISDEBUG
313
314
315
316
317
318 if (tmp_count >
319 howmany(sizeof mfc, sizeof mfc[0]))
320 panic("CISTPL_LONGLINK_MFC mfc "
321 "count would blow stack");
322 #endif
323
324 mfc_count = tmp_count;
325 for (i = 0; i < mfc_count; i++) {
326 mfc[i].common =
327 (pcmcia_tuple_read_1(&tuple,
328 1 + 5 * i) ==
329 PCMCIA_MFC_MEM_COMMON) ?
330 1 : 0;
331 mfc[i].addr =
332 pcmcia_tuple_read_4(&tuple,
333 1 + 5 * i + 1);
334 DPRINTF((" %s:%lx",
335 mfc[i].common ? "common" :
336 "attr", mfc[i].addr));
337 }
338 DPRINTF(("\n"));
339 }
340
341
342
343
344
345 default:
346 {
347 if ((*fct) (&tuple, arg)) {
348 pcmcia_chip_mem_unmap(pct,
349 pch, window);
350 ret = 1;
351 goto done;
352 }
353 }
354 break;
355 }
356 #ifdef PCMCIACISDEBUG
357
358 {
359 int i;
360
361 DPRINTF((" %02x %02x", tuple.code,
362 tuple.length));
363
364 for (i = 0; i < tuple.length; i++) {
365 DPRINTF((" %02x",
366 pcmcia_tuple_read_1(&tuple, i)));
367 if ((i % 16) == 13)
368 DPRINTF(("\n"));
369 }
370 if ((i % 16) != 14)
371 DPRINTF(("\n"));
372 }
373 #endif
374
375 tuple.ptr += 2 + tuple.length;
376 }
377
378
379
380
381
382
383
384
385
386 while (1) {
387 pcmcia_chip_mem_unmap(pct, pch, window);
388
389 if (longlink_present) {
390
391
392
393
394
395
396
397
398
399
400 if (!longlink_common)
401 longlink_addr *= 2;
402
403 pcmcia_chip_mem_map(pct, pch, longlink_common ?
404 PCMCIA_MEM_COMMON : PCMCIA_MEM_ATTR,
405 longlink_addr, PCMCIA_CIS_SIZE,
406 &pcmh, &tuple.ptr, &window);
407
408 if (!longlink_common)
409 tuple.ptr /= 2;
410
411 DPRINTF(("cis mem map %x\n",
412 (unsigned int) tuple.memh));
413
414 tuple.mult = longlink_common ? 1 : 2;
415 longlink_present = 0;
416 longlink_common = 1;
417 longlink_addr = 0;
418 } else if (mfc_count && (mfc_index < mfc_count)) {
419 if (!mfc[mfc_index].common)
420 mfc[mfc_index].addr *= 2;
421
422 pcmcia_chip_mem_map(pct, pch,
423 mfc[mfc_index].common ?
424 PCMCIA_MEM_COMMON : PCMCIA_MEM_ATTR,
425 mfc[mfc_index].addr, PCMCIA_CIS_SIZE,
426 &pcmh, &tuple.ptr, &window);
427
428 if (!mfc[mfc_index].common)
429 tuple.ptr /= 2;
430
431 DPRINTF(("cis mem map %x\n",
432 (unsigned int) tuple.memh));
433
434
435
436 tuple.mult = mfc[mfc_index].common ? 1 : 2;
437
438 mfc_index++;
439 } else {
440 goto done;
441 }
442
443
444 tuple.code = pcmcia_cis_read_1(&tuple, tuple.ptr);
445 if (tuple.code != PCMCIA_CISTPL_LINKTARGET) {
446 DPRINTF(("CISTPL_LINKTARGET expected, "
447 "code %02x observed\n", tuple.code));
448 continue;
449 }
450 tuple.length = pcmcia_cis_read_1(&tuple, tuple.ptr + 1);
451 if (tuple.length < 3) {
452 DPRINTF(("CISTPL_LINKTARGET too short %d\n",
453 tuple.length));
454 continue;
455 }
456 if ((pcmcia_tuple_read_1(&tuple, 0) != 'C') ||
457 (pcmcia_tuple_read_1(&tuple, 1) != 'I') ||
458 (pcmcia_tuple_read_1(&tuple, 2) != 'S')) {
459 DPRINTF(("CISTPL_LINKTARGET magic "
460 "%02x%02x%02x incorrect\n",
461 pcmcia_tuple_read_1(&tuple, 0),
462 pcmcia_tuple_read_1(&tuple, 1),
463 pcmcia_tuple_read_1(&tuple, 2)));
464 continue;
465 }
466 tuple.ptr += 2 + tuple.length;
467
468 break;
469 }
470 }
471
472 pcmcia_chip_mem_unmap(pct, pch, window);
473
474 done:
475
476 pcmcia_chip_mem_free(pct, pch, &pcmh);
477
478 return (ret);
479 }
480
481
482
483 void
484 pcmcia_print_cis(sc)
485 struct pcmcia_softc *sc;
486 {
487 struct pcmcia_card *card = &sc->card;
488 struct pcmcia_function *pf;
489 struct pcmcia_config_entry *cfe;
490 int i;
491
492 printf("%s: CIS version ", sc->dev.dv_xname);
493 if (card->cis1_major == 4) {
494 if (card->cis1_minor == 0)
495 printf("PCMCIA 1.0\n");
496 else if (card->cis1_minor == 1)
497 printf("PCMCIA 2.0 or 2.1\n");
498 } else if (card->cis1_major >= 5)
499 printf("PC Card Standard %d.%d\n", card->cis1_major,
500 card->cis1_minor);
501 else
502 printf("unknown (major=%d, minor=%d)\n",
503 card->cis1_major, card->cis1_minor);
504
505 printf("%s: CIS info: ", sc->dev.dv_xname);
506 for (i = 0; i < 4; i++) {
507 if (card->cis1_info[i] == NULL)
508 break;
509 if (i)
510 printf(", ");
511 printf("%s", card->cis1_info[i]);
512 }
513 printf("\n");
514
515 printf("%s: Manufacturer code 0x%x, product 0x%x\n",
516 sc->dev.dv_xname, card->manufacturer, card->product);
517
518 SIMPLEQ_FOREACH(pf, &card->pf_head, pf_list) {
519 printf("%s: function %d: ", sc->dev.dv_xname, pf->number);
520
521 switch (pf->function) {
522 case PCMCIA_FUNCTION_UNSPEC:
523 printf("unspecified");
524 break;
525 case PCMCIA_FUNCTION_MULTIFUNCTION:
526 printf("multi-function");
527 break;
528 case PCMCIA_FUNCTION_MEMORY:
529 printf("memory");
530 break;
531 case PCMCIA_FUNCTION_SERIAL:
532 printf("serial port");
533 break;
534 case PCMCIA_FUNCTION_PARALLEL:
535 printf("parallel port");
536 break;
537 case PCMCIA_FUNCTION_DISK:
538 printf("fixed disk");
539 break;
540 case PCMCIA_FUNCTION_VIDEO:
541 printf("video adapter");
542 break;
543 case PCMCIA_FUNCTION_NETWORK:
544 printf("network adapter");
545 break;
546 case PCMCIA_FUNCTION_AIMS:
547 printf("auto incrementing mass storage");
548 break;
549 case PCMCIA_FUNCTION_SCSI:
550 printf("SCSI bridge");
551 break;
552 case PCMCIA_FUNCTION_SECURITY:
553 printf("Security services");
554 break;
555 case PCMCIA_FUNCTION_INSTRUMENT:
556 printf("Instrument");
557 break;
558 case PCMCIA_FUNCTION_IOBUS:
559 printf("Serial I/O Bus Adapter");
560 break;
561 default:
562 printf("unknown (%d)", pf->function);
563 break;
564 }
565
566 printf(", ccr addr %lx mask %lx\n", pf->ccr_base, pf->ccr_mask);
567
568 SIMPLEQ_FOREACH(cfe, &pf->cfe_head, cfe_list) {
569 printf("%s: function %d, config table entry %d: ",
570 sc->dev.dv_xname, pf->number, cfe->number);
571
572 switch (cfe->iftype) {
573 case PCMCIA_IFTYPE_MEMORY:
574 printf("memory card");
575 break;
576 case PCMCIA_IFTYPE_IO:
577 printf("I/O card");
578 break;
579 default:
580 printf("card type unknown");
581 break;
582 }
583
584 printf("; irq mask %x", cfe->irqmask);
585
586 if (cfe->num_iospace) {
587 printf("; iomask %lx, iospace", cfe->iomask);
588
589 for (i = 0; i < cfe->num_iospace; i++)
590 printf(" %lx%s%lx",
591 cfe->iospace[i].start,
592 cfe->iospace[i].length ? "-" : "",
593 cfe->iospace[i].start +
594 cfe->iospace[i].length - 1);
595 }
596 if (cfe->num_memspace) {
597 printf("; memspace");
598
599 for (i = 0; i < cfe->num_memspace; i++)
600 printf(" %lx%s%lx%s%lx",
601 cfe->memspace[i].cardaddr,
602 cfe->memspace[i].length ? "-" : "",
603 cfe->memspace[i].cardaddr +
604 cfe->memspace[i].length - 1,
605 cfe->memspace[i].hostaddr ?
606 "@" : "",
607 cfe->memspace[i].hostaddr);
608 }
609 if (cfe->maxtwins)
610 printf("; maxtwins %d", cfe->maxtwins);
611
612 printf(";");
613
614 if (cfe->flags & PCMCIA_CFE_MWAIT_REQUIRED)
615 printf(" mwait_required");
616 if (cfe->flags & PCMCIA_CFE_RDYBSY_ACTIVE)
617 printf(" rdybsy_active");
618 if (cfe->flags & PCMCIA_CFE_WP_ACTIVE)
619 printf(" wp_active");
620 if (cfe->flags & PCMCIA_CFE_BVD_ACTIVE)
621 printf(" bvd_active");
622 if (cfe->flags & PCMCIA_CFE_IO8)
623 printf(" io8");
624 if (cfe->flags & PCMCIA_CFE_IO16)
625 printf(" io16");
626 if (cfe->flags & PCMCIA_CFE_IRQSHARE)
627 printf(" irqshare");
628 if (cfe->flags & PCMCIA_CFE_IRQPULSE)
629 printf(" irqpulse");
630 if (cfe->flags & PCMCIA_CFE_IRQLEVEL)
631 printf(" irqlevel");
632 if (cfe->flags & PCMCIA_CFE_POWERDOWN)
633 printf(" powerdown");
634 if (cfe->flags & PCMCIA_CFE_READONLY)
635 printf(" readonly");
636 if (cfe->flags & PCMCIA_CFE_AUDIO)
637 printf(" audio");
638
639 printf("\n");
640 }
641 }
642
643 if (card->error)
644 printf("%s: %d errors found while parsing CIS\n",
645 sc->dev.dv_xname, card->error);
646 }
647
648 int
649 pcmcia_parse_cis_tuple(tuple, arg)
650 struct pcmcia_tuple *tuple;
651 void *arg;
652 {
653
654 static struct pcmcia_config_entry init_cfe = {
655 -1, PCMCIA_CFE_RDYBSY_ACTIVE | PCMCIA_CFE_WP_ACTIVE |
656 PCMCIA_CFE_BVD_ACTIVE, PCMCIA_IFTYPE_MEMORY,
657 };
658
659 struct cis_state *state = arg;
660
661 switch (tuple->code) {
662 case PCMCIA_CISTPL_END:
663
664
665
666
667
668
669
670
671
672
673
674 if (state->gotmfc == 1) {
675 struct pcmcia_function *pf, *pfnext;
676
677 for (pf = SIMPLEQ_FIRST(&state->card->pf_head);
678 pf != NULL; pf = pfnext) {
679 pfnext = SIMPLEQ_NEXT(pf, pf_list);
680 free(pf, M_DEVBUF);
681 }
682
683 SIMPLEQ_INIT(&state->card->pf_head);
684
685 state->count = 0;
686 state->gotmfc = 2;
687 state->pf = NULL;
688 }
689 break;
690
691 case PCMCIA_CISTPL_LONGLINK_MFC:
692
693
694
695
696
697
698 state->gotmfc = 1;
699 break;
700
701 #ifdef PCMCIACISDEBUG
702 case PCMCIA_CISTPL_DEVICE:
703 case PCMCIA_CISTPL_DEVICE_A:
704 {
705 u_int reg, dtype, dspeed;
706
707 reg = pcmcia_tuple_read_1(tuple, 0);
708 dtype = reg & PCMCIA_DTYPE_MASK;
709 dspeed = reg & PCMCIA_DSPEED_MASK;
710
711 DPRINTF(("CISTPL_DEVICE%s type=",
712 (tuple->code == PCMCIA_CISTPL_DEVICE) ? "" : "_A"));
713 switch (dtype) {
714 case PCMCIA_DTYPE_NULL:
715 DPRINTF(("null"));
716 break;
717 case PCMCIA_DTYPE_ROM:
718 DPRINTF(("rom"));
719 break;
720 case PCMCIA_DTYPE_OTPROM:
721 DPRINTF(("otprom"));
722 break;
723 case PCMCIA_DTYPE_EPROM:
724 DPRINTF(("eprom"));
725 break;
726 case PCMCIA_DTYPE_EEPROM:
727 DPRINTF(("eeprom"));
728 break;
729 case PCMCIA_DTYPE_FLASH:
730 DPRINTF(("flash"));
731 break;
732 case PCMCIA_DTYPE_SRAM:
733 DPRINTF(("sram"));
734 break;
735 case PCMCIA_DTYPE_DRAM:
736 DPRINTF(("dram"));
737 break;
738 case PCMCIA_DTYPE_FUNCSPEC:
739 DPRINTF(("funcspec"));
740 break;
741 case PCMCIA_DTYPE_EXTEND:
742 DPRINTF(("extend"));
743 break;
744 default:
745 DPRINTF(("reserved"));
746 break;
747 }
748 DPRINTF((" speed="));
749 switch (dspeed) {
750 case PCMCIA_DSPEED_NULL:
751 DPRINTF(("null"));
752 break;
753 case PCMCIA_DSPEED_250NS:
754 DPRINTF(("250ns"));
755 break;
756 case PCMCIA_DSPEED_200NS:
757 DPRINTF(("200ns"));
758 break;
759 case PCMCIA_DSPEED_150NS:
760 DPRINTF(("150ns"));
761 break;
762 case PCMCIA_DSPEED_100NS:
763 DPRINTF(("100ns"));
764 break;
765 case PCMCIA_DSPEED_EXT:
766 DPRINTF(("ext"));
767 break;
768 default:
769 DPRINTF(("reserved"));
770 break;
771 }
772 }
773 DPRINTF(("\n"));
774 break;
775 #endif
776
777 case PCMCIA_CISTPL_VERS_1:
778 if (tuple->length < 6) {
779 DPRINTF(("CISTPL_VERS_1 too short %d\n",
780 tuple->length));
781 break;
782 } {
783 int start, i, ch, count;
784
785 state->card->cis1_major = pcmcia_tuple_read_1(tuple, 0);
786 state->card->cis1_minor = pcmcia_tuple_read_1(tuple, 1);
787
788 for (count = 0, start = 0, i = 0;
789 (count < 4) && ((i + 4) < 256); i++) {
790 ch = pcmcia_tuple_read_1(tuple, 2 + i);
791 if (ch == 0xff)
792 break;
793 state->card->cis1_info_buf[i] = ch;
794 if (ch == 0) {
795 state->card->cis1_info[count] =
796 state->card->cis1_info_buf + start;
797 start = i + 1;
798 count++;
799 }
800 }
801 DPRINTF(("CISTPL_VERS_1\n"));
802 }
803 break;
804
805 case PCMCIA_CISTPL_MANFID:
806 if (tuple->length < 4) {
807 DPRINTF(("CISTPL_MANFID too short %d\n",
808 tuple->length));
809 break;
810 }
811 state->card->manufacturer = pcmcia_tuple_read_2(tuple, 0);
812 state->card->product = pcmcia_tuple_read_2(tuple, 2);
813 DPRINTF(("CISTPL_MANFID\n"));
814 break;
815
816 case PCMCIA_CISTPL_FUNCID:
817 if (tuple->length < 2) {
818 DPRINTF(("CISTPL_FUNCID too short %d\n",
819 tuple->length));
820 break;
821 }
822
823
824
825
826
827
828
829
830
831
832
833 if (state->pf) {
834 if (state->pf->function == PCMCIA_FUNCTION_UNSPEC) {
835
836
837
838
839 } else {
840
841
842
843 state->pf = NULL;
844 }
845 }
846 if (state->pf == NULL) {
847 state->pf = malloc(sizeof(*state->pf), M_DEVBUF,
848 M_NOWAIT);
849 if (state->pf == NULL)
850 panic("pcmcia_parse_cis_tuple");
851 bzero(state->pf, sizeof(*state->pf));
852 state->pf->number = state->count++;
853 state->pf->last_config_index = -1;
854 SIMPLEQ_INIT(&state->pf->cfe_head);
855
856 SIMPLEQ_INSERT_TAIL(&state->card->pf_head, state->pf,
857 pf_list);
858 }
859 state->pf->function = pcmcia_tuple_read_1(tuple, 0);
860
861 DPRINTF(("CISTPL_FUNCID\n"));
862 break;
863
864 case PCMCIA_CISTPL_CONFIG:
865 if (tuple->length < 3) {
866 DPRINTF(("CISTPL_CONFIG too short %d\n",
867 tuple->length));
868 break;
869 } {
870 u_int reg, rasz, rmsz, rfsz;
871 int i;
872
873 reg = pcmcia_tuple_read_1(tuple, 0);
874 rasz = 1 + ((reg & PCMCIA_TPCC_RASZ_MASK) >>
875 PCMCIA_TPCC_RASZ_SHIFT);
876 rmsz = 1 + ((reg & PCMCIA_TPCC_RMSZ_MASK) >>
877 PCMCIA_TPCC_RMSZ_SHIFT);
878 rfsz = ((reg & PCMCIA_TPCC_RFSZ_MASK) >>
879 PCMCIA_TPCC_RFSZ_SHIFT);
880
881 if (tuple->length < (rasz + rmsz + rfsz)) {
882 DPRINTF(("CISTPL_CONFIG (%d,%d,%d) too "
883 "short %d\n", rasz, rmsz, rfsz,
884 tuple->length));
885 break;
886 }
887 if (state->pf == NULL) {
888 state->pf = malloc(sizeof(*state->pf),
889 M_DEVBUF, M_NOWAIT);
890 if (state->pf == NULL)
891 panic("pcmcia_parse_cis_tuple");
892 bzero(state->pf, sizeof(*state->pf));
893 state->pf->number = state->count++;
894 state->pf->last_config_index = -1;
895 SIMPLEQ_INIT(&state->pf->cfe_head);
896
897 SIMPLEQ_INSERT_TAIL(&state->card->pf_head,
898 state->pf, pf_list);
899
900 state->pf->function = PCMCIA_FUNCTION_UNSPEC;
901 }
902 state->pf->last_config_index =
903 pcmcia_tuple_read_1(tuple, 1);
904
905 state->pf->ccr_base = 0;
906 for (i = 0; i < rasz; i++)
907 state->pf->ccr_base |=
908 ((pcmcia_tuple_read_1(tuple, 2 + i)) <<
909 (i * 8));
910
911 state->pf->ccr_mask = 0;
912 for (i = 0; i < rmsz; i++)
913 state->pf->ccr_mask |=
914 ((pcmcia_tuple_read_1(tuple,
915 2 + rasz + i)) << (i * 8));
916
917
918
919
920 state->temp_cfe = init_cfe;
921 state->default_cfe = &state->temp_cfe;
922 }
923 DPRINTF(("CISTPL_CONFIG\n"));
924 break;
925
926 case PCMCIA_CISTPL_CFTABLE_ENTRY:
927 if (tuple->length < 2) {
928 DPRINTF(("CISTPL_CFTABLE_ENTRY too short %d\n",
929 tuple->length));
930 break;
931 } {
932 int idx, i, j;
933 u_int reg, reg2;
934 u_int intface, def, num;
935 u_int power, timing, iospace, irq, memspace, misc;
936 struct pcmcia_config_entry *cfe;
937
938 idx = 0;
939
940 reg = pcmcia_tuple_read_1(tuple, idx);
941 idx++;
942 intface = reg & PCMCIA_TPCE_INDX_INTFACE;
943 def = reg & PCMCIA_TPCE_INDX_DEFAULT;
944 num = reg & PCMCIA_TPCE_INDX_NUM_MASK;
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966 if (state->default_cfe == NULL) {
967 DPRINTF(("CISTPL_CFTABLE_ENTRY with no "
968 "default\n"));
969 break;
970 }
971 if (num != state->default_cfe->number) {
972 cfe = (struct pcmcia_config_entry *)
973 malloc(sizeof(*cfe), M_DEVBUF, M_NOWAIT);
974 if (cfe == NULL)
975 panic("pcmcia_parse_cis_tuple");
976
977 *cfe = *state->default_cfe;
978
979 SIMPLEQ_INSERT_TAIL(&state->pf->cfe_head,
980 cfe, cfe_list);
981
982 cfe->number = num;
983
984
985
986
987
988
989 if (def)
990 state->default_cfe = cfe;
991 } else {
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007 cfe = state->default_cfe;
1008
1009
1010
1011
1012
1013
1014 if (!def) {
1015 state->temp_cfe = *state->default_cfe;
1016 state->default_cfe = &state->temp_cfe;
1017 }
1018 }
1019
1020 if (intface) {
1021 reg = pcmcia_tuple_read_1(tuple, idx);
1022 idx++;
1023 cfe->flags &= ~(PCMCIA_CFE_MWAIT_REQUIRED
1024 | PCMCIA_CFE_RDYBSY_ACTIVE
1025 | PCMCIA_CFE_WP_ACTIVE
1026 | PCMCIA_CFE_BVD_ACTIVE);
1027 if (reg & PCMCIA_TPCE_IF_MWAIT)
1028 cfe->flags |= PCMCIA_CFE_MWAIT_REQUIRED;
1029 if (reg & PCMCIA_TPCE_IF_RDYBSY)
1030 cfe->flags |= PCMCIA_CFE_RDYBSY_ACTIVE;
1031 if (reg & PCMCIA_TPCE_IF_WP)
1032 cfe->flags |= PCMCIA_CFE_WP_ACTIVE;
1033 if (reg & PCMCIA_TPCE_IF_BVD)
1034 cfe->flags |= PCMCIA_CFE_BVD_ACTIVE;
1035 cfe->iftype = reg & PCMCIA_TPCE_IF_IFTYPE;
1036 }
1037 reg = pcmcia_tuple_read_1(tuple, idx);
1038 idx++;
1039
1040 power = reg & PCMCIA_TPCE_FS_POWER_MASK;
1041 timing = reg & PCMCIA_TPCE_FS_TIMING;
1042 iospace = reg & PCMCIA_TPCE_FS_IOSPACE;
1043 irq = reg & PCMCIA_TPCE_FS_IRQ;
1044 memspace = reg & PCMCIA_TPCE_FS_MEMSPACE_MASK;
1045 misc = reg & PCMCIA_TPCE_FS_MISC;
1046
1047 if (power) {
1048
1049
1050 for (i = 0; i < power; i++) {
1051 reg = pcmcia_tuple_read_1(tuple, idx);
1052 idx++;
1053
1054 for (j = 0; j < 7; j++) {
1055
1056 if ((reg >> j) & 0x01) {
1057
1058 do {
1059 reg2 = pcmcia_tuple_read_1(tuple, idx);
1060 idx++;
1061
1062
1063
1064
1065
1066
1067 } while (reg2 & 0x80);
1068 }
1069 }
1070 }
1071 }
1072 if (timing) {
1073
1074 reg = pcmcia_tuple_read_1(tuple, idx);
1075 idx++;
1076
1077 if ((reg & PCMCIA_TPCE_TD_RESERVED_MASK) !=
1078 PCMCIA_TPCE_TD_RESERVED_MASK)
1079 idx++;
1080 if ((reg & PCMCIA_TPCE_TD_RDYBSY_MASK) !=
1081 PCMCIA_TPCE_TD_RDYBSY_MASK)
1082 idx++;
1083 if ((reg & PCMCIA_TPCE_TD_WAIT_MASK) !=
1084 PCMCIA_TPCE_TD_WAIT_MASK)
1085 idx++;
1086 }
1087 if (iospace) {
1088 if (tuple->length <= idx) {
1089 DPRINTF(("ran out of space before TPCE_IO\n"));
1090
1091 goto abort_cfe;
1092 }
1093
1094 reg = pcmcia_tuple_read_1(tuple, idx);
1095 idx++;
1096
1097 cfe->flags &=
1098 ~(PCMCIA_CFE_IO8 | PCMCIA_CFE_IO16);
1099 if (reg & PCMCIA_TPCE_IO_BUSWIDTH_8BIT)
1100 cfe->flags |= PCMCIA_CFE_IO8;
1101 if (reg & PCMCIA_TPCE_IO_BUSWIDTH_16BIT)
1102 cfe->flags |= PCMCIA_CFE_IO16;
1103 cfe->iomask =
1104 reg & PCMCIA_TPCE_IO_IOADDRLINES_MASK;
1105
1106 if (reg & PCMCIA_TPCE_IO_HASRANGE) {
1107 reg = pcmcia_tuple_read_1(tuple, idx);
1108 idx++;
1109
1110 cfe->num_iospace = 1 + (reg &
1111 PCMCIA_TPCE_IO_RANGE_COUNT);
1112
1113 if (cfe->num_iospace >
1114 (sizeof(cfe->iospace) /
1115 sizeof(cfe->iospace[0]))) {
1116 DPRINTF(("too many io "
1117 "spaces %d",
1118 cfe->num_iospace));
1119 state->card->error++;
1120 break;
1121 }
1122 for (i = 0; i < cfe->num_iospace; i++) {
1123 switch (reg & PCMCIA_TPCE_IO_RANGE_ADDRSIZE_MASK) {
1124 case PCMCIA_TPCE_IO_RANGE_ADDRSIZE_ONE:
1125 cfe->iospace[i].start =
1126 pcmcia_tuple_read_1(tuple, idx);
1127 idx++;
1128 break;
1129 case PCMCIA_TPCE_IO_RANGE_ADDRSIZE_TWO:
1130 cfe->iospace[i].start =
1131 pcmcia_tuple_read_2(tuple, idx);
1132 idx += 2;
1133 break;
1134 case PCMCIA_TPCE_IO_RANGE_ADDRSIZE_FOUR:
1135 cfe->iospace[i].start =
1136 pcmcia_tuple_read_4(tuple, idx);
1137 idx += 4;
1138 break;
1139 }
1140 switch (reg &
1141 PCMCIA_TPCE_IO_RANGE_LENGTHSIZE_MASK) {
1142 case PCMCIA_TPCE_IO_RANGE_LENGTHSIZE_ONE:
1143 cfe->iospace[i].length =
1144 pcmcia_tuple_read_1(tuple, idx);
1145 idx++;
1146 break;
1147 case PCMCIA_TPCE_IO_RANGE_LENGTHSIZE_TWO:
1148 cfe->iospace[i].length =
1149 pcmcia_tuple_read_2(tuple, idx);
1150 idx += 2;
1151 break;
1152 case PCMCIA_TPCE_IO_RANGE_LENGTHSIZE_FOUR:
1153 cfe->iospace[i].length =
1154 pcmcia_tuple_read_4(tuple, idx);
1155 idx += 4;
1156 break;
1157 }
1158 cfe->iospace[i].length++;
1159 }
1160 } else {
1161 cfe->num_iospace = 1;
1162 cfe->iospace[0].start = 0;
1163 cfe->iospace[0].length =
1164 (1 << cfe->iomask);
1165 }
1166 }
1167
1168 if (irq) {
1169 if (tuple->length <= idx) {
1170 DPRINTF(("ran out of space before TPCE_IR\n"));
1171
1172 goto abort_cfe;
1173 }
1174
1175 reg = pcmcia_tuple_read_1(tuple, idx);
1176 idx++;
1177
1178 cfe->flags &= ~(PCMCIA_CFE_IRQSHARE
1179 | PCMCIA_CFE_IRQPULSE
1180 | PCMCIA_CFE_IRQLEVEL);
1181 if (reg & PCMCIA_TPCE_IR_SHARE)
1182 cfe->flags |= PCMCIA_CFE_IRQSHARE;
1183 if (reg & PCMCIA_TPCE_IR_PULSE)
1184 cfe->flags |= PCMCIA_CFE_IRQPULSE;
1185 if (reg & PCMCIA_TPCE_IR_LEVEL)
1186 cfe->flags |= PCMCIA_CFE_IRQLEVEL;
1187
1188 if (reg & PCMCIA_TPCE_IR_HASMASK) {
1189
1190
1191
1192
1193
1194 cfe->irqmask =
1195 pcmcia_tuple_read_2(tuple, idx);
1196 idx += 2;
1197 } else {
1198 cfe->irqmask =
1199 (1 << (reg & PCMCIA_TPCE_IR_IRQ));
1200 }
1201 }
1202 if (memspace) {
1203 if (tuple->length <= idx) {
1204 DPRINTF(("ran out of space before TPCE_MS\n"));
1205 goto abort_cfe;
1206 }
1207
1208 if (memspace == PCMCIA_TPCE_FS_MEMSPACE_NONE) {
1209 cfe->num_memspace = 0;
1210 } else if (memspace == PCMCIA_TPCE_FS_MEMSPACE_LENGTH) {
1211 cfe->num_memspace = 1;
1212 cfe->memspace[0].length = 256 *
1213 pcmcia_tuple_read_2(tuple, idx);
1214 idx += 2;
1215 cfe->memspace[0].cardaddr = 0;
1216 cfe->memspace[0].hostaddr = 0;
1217 } else if (memspace ==
1218 PCMCIA_TPCE_FS_MEMSPACE_LENGTHADDR) {
1219 cfe->num_memspace = 1;
1220 cfe->memspace[0].length = 256 *
1221 pcmcia_tuple_read_2(tuple, idx);
1222 idx += 2;
1223 cfe->memspace[0].cardaddr = 256 *
1224 pcmcia_tuple_read_2(tuple, idx);
1225 idx += 2;
1226 cfe->memspace[0].hostaddr = cfe->memspace[0].cardaddr;
1227 } else {
1228 int lengthsize;
1229 int cardaddrsize;
1230 int hostaddrsize;
1231
1232 reg = pcmcia_tuple_read_1(tuple, idx);
1233 idx++;
1234
1235 cfe->num_memspace = (reg &
1236 PCMCIA_TPCE_MS_COUNT) + 1;
1237
1238 if (cfe->num_memspace >
1239 (sizeof(cfe->memspace) /
1240 sizeof(cfe->memspace[0]))) {
1241 DPRINTF(("too many mem "
1242 "spaces %d",
1243 cfe->num_memspace));
1244 state->card->error++;
1245 break;
1246 }
1247 lengthsize =
1248 ((reg & PCMCIA_TPCE_MS_LENGTH_SIZE_MASK) >>
1249 PCMCIA_TPCE_MS_LENGTH_SIZE_SHIFT);
1250 cardaddrsize =
1251 ((reg & PCMCIA_TPCE_MS_CARDADDR_SIZE_MASK) >>
1252 PCMCIA_TPCE_MS_CARDADDR_SIZE_SHIFT);
1253 hostaddrsize =
1254 (reg & PCMCIA_TPCE_MS_HOSTADDR) ? cardaddrsize : 0;
1255
1256 if (lengthsize == 0) {
1257 DPRINTF(("cfe memspace "
1258 "lengthsize == 0"));
1259 state->card->error++;
1260 }
1261 for (i = 0; i < cfe->num_memspace; i++) {
1262 if (lengthsize) {
1263 cfe->memspace[i].length =
1264 256 * pcmcia_tuple_read_n(tuple, lengthsize,
1265 idx);
1266 idx += lengthsize;
1267 } else {
1268 cfe->memspace[i].length = 0;
1269 }
1270 if (cfe->memspace[i].length == 0) {
1271 DPRINTF(("cfe->memspace[%d].length == 0",
1272 i));
1273 state->card->error++;
1274 }
1275 if (cardaddrsize) {
1276 cfe->memspace[i].cardaddr =
1277 256 * pcmcia_tuple_read_n(tuple, cardaddrsize,
1278 idx);
1279 idx += cardaddrsize;
1280 } else {
1281 cfe->memspace[i].cardaddr = 0;
1282 }
1283 if (hostaddrsize) {
1284 cfe->memspace[i].hostaddr =
1285 256 * pcmcia_tuple_read_n(tuple, hostaddrsize,
1286 idx);
1287 idx += hostaddrsize;
1288 } else {
1289 cfe->memspace[i].hostaddr = 0;
1290 }
1291 }
1292 }
1293 }
1294 if (misc) {
1295 if (tuple->length <= idx) {
1296 DPRINTF(("ran out of space before TPCE_MI\n"));
1297
1298 goto abort_cfe;
1299 }
1300
1301 reg = pcmcia_tuple_read_1(tuple, idx);
1302 idx++;
1303
1304 cfe->flags &= ~(PCMCIA_CFE_POWERDOWN
1305 | PCMCIA_CFE_READONLY
1306 | PCMCIA_CFE_AUDIO);
1307 if (reg & PCMCIA_TPCE_MI_PWRDOWN)
1308 cfe->flags |= PCMCIA_CFE_POWERDOWN;
1309 if (reg & PCMCIA_TPCE_MI_READONLY)
1310 cfe->flags |= PCMCIA_CFE_READONLY;
1311 if (reg & PCMCIA_TPCE_MI_AUDIO)
1312 cfe->flags |= PCMCIA_CFE_AUDIO;
1313 cfe->maxtwins = reg & PCMCIA_TPCE_MI_MAXTWINS;
1314
1315 while (reg & PCMCIA_TPCE_MI_EXT) {
1316 reg = pcmcia_tuple_read_1(tuple, idx);
1317 idx++;
1318 }
1319 }
1320
1321 }
1322
1323 abort_cfe:
1324 DPRINTF(("CISTPL_CFTABLE_ENTRY\n"));
1325 break;
1326
1327 default:
1328 DPRINTF(("unhandled CISTPL %x\n", tuple->code));
1329 break;
1330 }
1331
1332 return (0);
1333 }