1 /* $NetBSD: pcmcia_cis.c,v 1.17 2000/02/10 09:01:52 chopps Exp $ */
2 /* $FreeBSD: releng/5.3/sys/dev/pccard/pccard_cis.c 128169 2004-04-12 20:56:34Z imp $ */
3
4 /*
5 * Copyright (c) 1997 Marc Horowitz. All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software
16 * must display the following acknowledgement:
17 * This product includes software developed by Marc Horowitz.
18 * 4. The name of the author may not be used to endorse or promote products
19 * derived from this software without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
22 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
23 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
24 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
26 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
30 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 */
32
33 #include <sys/param.h>
34 #include <sys/systm.h>
35 #include <sys/malloc.h>
36 #include <sys/module.h>
37 #include <sys/kernel.h>
38 #include <sys/queue.h>
39 #include <sys/types.h>
40
41 #include <sys/bus.h>
42 #include <machine/bus.h>
43 #include <sys/rman.h>
44 #include <machine/resource.h>
45
46 #include <dev/pccard/pccardreg.h>
47 #include <dev/pccard/pccardvar.h>
48 #include <dev/pccard/pccard_cis.h>
49
50 #include "card_if.h"
51
52 extern int pccard_cis_debug;
53
54 #define PCCARDCISDEBUG
55 #ifdef PCCARDCISDEBUG
56 #define DPRINTF(arg) do { if (pccard_cis_debug) printf arg; } while (0)
57 #define DEVPRINTF(arg) do { if (pccard_cis_debug) device_printf arg; } while (0)
58 #else
59 #define DPRINTF(arg)
60 #define DEVPRINTF(arg)
61 #endif
62
63 #define PCCARD_CIS_SIZE 4096
64
65 struct cis_state {
66 int count;
67 int gotmfc;
68 struct pccard_config_entry temp_cfe;
69 struct pccard_config_entry *default_cfe;
70 struct pccard_card *card;
71 struct pccard_function *pf;
72 };
73
74 int pccard_parse_cis_tuple(struct pccard_tuple *, void *);
75 static int decode_funce(struct pccard_tuple *, struct pccard_function *);
76
77 void
78 pccard_read_cis(struct pccard_softc *sc)
79 {
80 struct cis_state state;
81
82 bzero(&state, sizeof state);
83
84 state.card = &sc->card;
85
86 state.card->error = 0;
87 state.card->cis1_major = -1;
88 state.card->cis1_minor = -1;
89 state.card->cis1_info[0] = NULL;
90 state.card->cis1_info[1] = NULL;
91 state.card->cis1_info[2] = NULL;
92 state.card->cis1_info[3] = NULL;
93 state.card->manufacturer = PCMCIA_VENDOR_INVALID;
94 state.card->product = PCMCIA_PRODUCT_INVALID;
95 STAILQ_INIT(&state.card->pf_head);
96
97 state.pf = NULL;
98
99 tsleep(&state, 0, "pccard", hz);
100 if (pccard_scan_cis(sc->dev, pccard_parse_cis_tuple,
101 &state) == -1)
102 state.card->error++;
103 }
104
105 int
106 pccard_scan_cis(device_t dev, int (*fct)(struct pccard_tuple *, void *),
107 void *arg)
108 {
109 struct resource *res;
110 int rid;
111 struct pccard_tuple tuple;
112 int longlink_present;
113 int longlink_common;
114 u_long longlink_addr; /* Type suspect */
115 int mfc_count;
116 int mfc_index;
117 #ifdef PCCARDCISDEBUG
118 int cis_none_cnt = 10; /* Only report 10 CIS_NONEs */
119 #endif
120 struct {
121 int common;
122 u_long addr;
123 } mfc[256 / 5];
124 int ret;
125
126 ret = 0;
127
128 /* allocate some memory */
129
130 /*
131 * Some reports from the field suggest that a 64k memory boundary
132 * helps card CIS being able to be read. Try it here and see what
133 * the results actually are. I'm not sure I understand why this
134 * would make cards work better, but it is easy enough to test.
135 */
136 rid = 0;
137 res = bus_alloc_resource(dev, SYS_RES_MEMORY, &rid, 0, ~0,
138 PCCARD_CIS_SIZE, RF_ACTIVE | rman_make_alignment_flags(64*1024));
139 if (res == NULL) {
140 device_printf(dev, "can't alloc memory to read attributes\n");
141 return -1;
142 }
143 CARD_SET_RES_FLAGS(device_get_parent(dev), dev, SYS_RES_MEMORY,
144 rid, PCCARD_A_MEM_ATTR);
145 tuple.memt = rman_get_bustag(res);
146 tuple.memh = rman_get_bushandle(res);
147 tuple.ptr = 0;
148
149 DPRINTF(("cis mem map 0x%x (resource: 0x%lx)\n",
150 (unsigned int) tuple.memh, rman_get_start(res)));
151
152 tuple.mult = 2;
153
154 longlink_present = 1;
155 longlink_common = 1;
156 longlink_addr = 0;
157
158 mfc_count = 0;
159 mfc_index = 0;
160
161 DEVPRINTF((dev, "CIS tuple chain:\n"));
162
163 while (1) {
164 while (1) {
165 /*
166 * Perform boundary check for insane cards.
167 * If CIS is too long, simulate CIS end.
168 * (This check may not be sufficient for
169 * malicious cards.)
170 */
171 if (tuple.mult * tuple.ptr >= PCCARD_CIS_SIZE - 1
172 - 32 /* ad hoc value */ ) {
173 printf("CIS is too long -- truncating\n");
174 tuple.code = CISTPL_END;
175 } else {
176 /* get the tuple code */
177 tuple.code = pccard_cis_read_1(&tuple, tuple.ptr);
178 }
179
180 /* two special-case tuples */
181
182 if (tuple.code == CISTPL_NULL) {
183 #ifdef PCCARDCISDEBUG
184 if (cis_none_cnt > 0)
185 DPRINTF(("CISTPL_NONE\n 00\n"));
186 else if (cis_none_cnt == 0)
187 DPRINTF(("TOO MANY CIS_NONE\n"));
188 cis_none_cnt--;
189 #endif
190 tuple.ptr++;
191 continue;
192 } else if (tuple.code == CISTPL_END) {
193 DPRINTF(("CISTPL_END\n ff\n"));
194 /* Call the function for the END tuple, since
195 the CIS semantics depend on it */
196 if ((*fct) (&tuple, arg)) {
197 ret = 1;
198 goto done;
199 }
200 tuple.ptr++;
201 break;
202 }
203 /* now all the normal tuples */
204
205 tuple.length = pccard_cis_read_1(&tuple, tuple.ptr + 1);
206 switch (tuple.code) {
207 case CISTPL_LONGLINK_A:
208 case CISTPL_LONGLINK_C:
209 if (tuple.length < 4) {
210 DPRINTF(("CISTPL_LONGLINK_%s too "
211 "short %d\n",
212 longlink_common ? "C" : "A",
213 tuple.length));
214 break;
215 }
216 longlink_present = 1;
217 longlink_common = (tuple.code ==
218 CISTPL_LONGLINK_C) ? 1 : 0;
219 longlink_addr = pccard_tuple_read_4(&tuple, 0);
220 DPRINTF(("CISTPL_LONGLINK_%s %lx\n",
221 longlink_common ? "C" : "A",
222 longlink_addr));
223 break;
224 case CISTPL_NO_LINK:
225 longlink_present = 0;
226 DPRINTF(("CISTPL_NO_LINK\n"));
227 break;
228 case CISTPL_CHECKSUM:
229 if (tuple.length < 5) {
230 DPRINTF(("CISTPL_CHECKSUM too "
231 "short %d\n", tuple.length));
232 break;
233 } {
234 int16_t offset;
235 u_long addr, length;
236 u_int cksum, sum;
237 int i;
238
239 offset = (uint16_t)
240 pccard_tuple_read_2(&tuple, 0);
241 length = pccard_tuple_read_2(&tuple, 2);
242 cksum = pccard_tuple_read_1(&tuple, 4);
243
244 addr = tuple.ptr + offset;
245
246 DPRINTF(("CISTPL_CHECKSUM addr=%lx "
247 "len=%lx cksum=%x",
248 addr, length, cksum));
249
250 /*
251 * XXX do more work to deal with
252 * distant regions
253 */
254 if ((addr >= PCCARD_CIS_SIZE) ||
255 ((addr + length) >=
256 PCCARD_CIS_SIZE)) {
257 DPRINTF((" skipped, "
258 "too distant\n"));
259 break;
260 }
261 sum = 0;
262 for (i = 0; i < length; i++)
263 sum +=
264 bus_space_read_1(tuple.memt,
265 tuple.memh,
266 addr + tuple.mult * i);
267 if (cksum != (sum & 0xff)) {
268 DPRINTF((" failed sum=%x\n",
269 sum));
270 device_printf(dev,
271 "CIS checksum failed\n");
272 #if 0
273 /*
274 * XXX Some working cards have
275 * XXX bad checksums!!
276 */
277 ret = -1;
278 #endif
279 } else {
280 DPRINTF((" ok\n"));
281 }
282 }
283 break;
284 case CISTPL_LONGLINK_MFC:
285 if (tuple.length < 1) {
286 DPRINTF(("CISTPL_LONGLINK_MFC too "
287 "short %d\n", tuple.length));
288 break;
289 }
290 if (((tuple.length - 1) % 5) != 0) {
291 DPRINTF(("CISTPL_LONGLINK_MFC bogus "
292 "length %d\n", tuple.length));
293 break;
294 }
295 /*
296 * this is kind of ad hoc, as I don't have
297 * any real documentation
298 */
299 {
300 int i, tmp_count;
301
302 /*
303 * put count into tmp var so that
304 * if we have to bail (because it's
305 * a bogus count) it won't be
306 * remembered for later use.
307 */
308 tmp_count =
309 pccard_tuple_read_1(&tuple, 0);
310
311 DPRINTF(("CISTPL_LONGLINK_MFC %d",
312 tmp_count));
313
314 /*
315 * make _sure_ it's the right size;
316 * if too short, it may be a weird
317 * (unknown/undefined) format
318 */
319 if (tuple.length != (tmp_count*5 + 1)) {
320 DPRINTF((" bogus length %d\n",
321 tuple.length));
322 break;
323 }
324 /*
325 * sanity check for a programming
326 * error which is difficult to find
327 * when debugging.
328 */
329 if (tmp_count >
330 howmany(sizeof mfc, sizeof mfc[0]))
331 panic("CISTPL_LONGLINK_MFC mfc "
332 "count would blow stack");
333 mfc_count = tmp_count;
334 for (i = 0; i < mfc_count; i++) {
335 mfc[i].common =
336 (pccard_tuple_read_1(&tuple,
337 1 + 5 * i) ==
338 PCCARD_MFC_MEM_COMMON) ?
339 1 : 0;
340 mfc[i].addr =
341 pccard_tuple_read_4(&tuple,
342 1 + 5 * i + 1);
343 DPRINTF((" %s:%lx",
344 mfc[i].common ? "common" :
345 "attr", mfc[i].addr));
346 }
347 DPRINTF(("\n"));
348 }
349 /*
350 * for LONGLINK_MFC, fall through to the
351 * function. This tuple has structural and
352 * semantic content.
353 */
354 default:
355 {
356 if ((*fct) (&tuple, arg)) {
357 ret = 1;
358 goto done;
359 }
360 }
361 break;
362 } /* switch */
363 #ifdef PCCARDCISDEBUG
364 /* print the tuple */
365 {
366 int i;
367
368 DPRINTF((" %02x %02x", tuple.code,
369 tuple.length));
370
371 for (i = 0; i < tuple.length; i++) {
372 DPRINTF((" %02x",
373 pccard_tuple_read_1(&tuple, i)));
374 if ((i % 16) == 13)
375 DPRINTF(("\n"));
376 }
377
378 if ((i % 16) != 14)
379 DPRINTF(("\n"));
380 }
381 #endif
382 /* skip to the next tuple */
383 tuple.ptr += 2 + tuple.length;
384 }
385
386 /*
387 * the chain is done. Clean up and move onto the next one,
388 * if any. The loop is here in the case that there is an MFC
389 * card with no longlink (which defaults to existing, == 0).
390 * In general, this means that if one pointer fails, it will
391 * try the next one, instead of just bailing.
392 */
393 while (1) {
394 if (longlink_present) {
395 CARD_SET_RES_FLAGS(device_get_parent(dev), dev,
396 SYS_RES_MEMORY, rid, longlink_common ?
397 PCCARD_A_MEM_COM : PCCARD_A_MEM_ATTR);
398 DPRINTF(("cis mem map %x\n",
399 (unsigned int) tuple.memh));
400 tuple.mult = longlink_common ? 1 : 2;
401 tuple.ptr = longlink_addr;
402 longlink_present = 0;
403 longlink_common = 1;
404 longlink_addr = 0;
405 } else if (mfc_count && (mfc_index < mfc_count)) {
406 CARD_SET_RES_FLAGS(device_get_parent(dev), dev,
407 SYS_RES_MEMORY, rid, mfc[mfc_index].common
408 ? PCCARD_A_MEM_COM : PCCARD_A_MEM_ATTR);
409 DPRINTF(("cis mem map %x\n",
410 (unsigned int) tuple.memh));
411 /* set parse state, and point at the next one */
412 tuple.mult = mfc[mfc_index].common ? 1 : 2;
413 tuple.ptr = mfc[mfc_index].addr;
414 mfc_index++;
415 } else {
416 goto done;
417 }
418
419 /* make sure that the link is valid */
420 tuple.code = pccard_cis_read_1(&tuple, tuple.ptr);
421 if (tuple.code != CISTPL_LINKTARGET) {
422 DPRINTF(("CISTPL_LINKTARGET expected, "
423 "code %02x observed\n", tuple.code));
424 continue;
425 }
426 tuple.length = pccard_cis_read_1(&tuple, tuple.ptr + 1);
427 if (tuple.length < 3) {
428 DPRINTF(("CISTPL_LINKTARGET too short %d\n",
429 tuple.length));
430 continue;
431 }
432 if ((pccard_tuple_read_1(&tuple, 0) != 'C') ||
433 (pccard_tuple_read_1(&tuple, 1) != 'I') ||
434 (pccard_tuple_read_1(&tuple, 2) != 'S')) {
435 DPRINTF(("CISTPL_LINKTARGET magic "
436 "%02x%02x%02x incorrect\n",
437 pccard_tuple_read_1(&tuple, 0),
438 pccard_tuple_read_1(&tuple, 1),
439 pccard_tuple_read_1(&tuple, 2)));
440 continue;
441 }
442 tuple.ptr += 2 + tuple.length;
443 break;
444 }
445 }
446
447 done:
448 bus_release_resource(dev, SYS_RES_MEMORY, rid, res);
449
450 return (ret);
451 }
452
453 /* XXX this is incredibly verbose. Not sure what trt is */
454
455 void
456 pccard_print_cis(device_t dev)
457 {
458 struct pccard_softc *sc = PCCARD_SOFTC(dev);
459 struct pccard_card *card = &sc->card;
460 struct pccard_function *pf;
461 struct pccard_config_entry *cfe;
462 int i;
463
464 device_printf(dev, "CIS version ");
465 if (card->cis1_major == 4) {
466 if (card->cis1_minor == 0)
467 printf("PCCARD 1.0\n");
468 else if (card->cis1_minor == 1)
469 printf("PCCARD 2.0 or 2.1\n");
470 } else if (card->cis1_major >= 5)
471 printf("PC Card Standard %d.%d\n", card->cis1_major, card->cis1_minor);
472 else
473 printf("unknown (major=%d, minor=%d)\n",
474 card->cis1_major, card->cis1_minor);
475
476 device_printf(dev, "CIS info: ");
477 for (i = 0; i < 4; i++) {
478 if (card->cis1_info[i] == NULL)
479 break;
480 if (i)
481 printf(", ");
482 printf("%s", card->cis1_info[i]);
483 }
484 printf("\n");
485
486 device_printf(dev, "Manufacturer code 0x%x, product 0x%x\n",
487 card->manufacturer, card->product);
488
489 STAILQ_FOREACH(pf, &card->pf_head, pf_list) {
490 device_printf(dev, "function %d: ", pf->number);
491
492 switch (pf->function) {
493 case PCCARD_FUNCTION_UNSPEC:
494 printf("unspecified");
495 break;
496 case PCCARD_FUNCTION_MULTIFUNCTION:
497 printf("multi-function");
498 break;
499 case PCCARD_FUNCTION_MEMORY:
500 printf("memory");
501 break;
502 case PCCARD_FUNCTION_SERIAL:
503 printf("serial port");
504 break;
505 case PCCARD_FUNCTION_PARALLEL:
506 printf("parallel port");
507 break;
508 case PCCARD_FUNCTION_DISK:
509 printf("fixed disk");
510 break;
511 case PCCARD_FUNCTION_VIDEO:
512 printf("video adapter");
513 break;
514 case PCCARD_FUNCTION_NETWORK:
515 printf("network adapter");
516 break;
517 case PCCARD_FUNCTION_AIMS:
518 printf("auto incrementing mass storage");
519 break;
520 case PCCARD_FUNCTION_SCSI:
521 printf("SCSI bridge");
522 break;
523 case PCCARD_FUNCTION_SECURITY:
524 printf("Security services");
525 break;
526 case PCCARD_FUNCTION_INSTRUMENT:
527 printf("Instrument");
528 break;
529 default:
530 printf("unknown (%d)", pf->function);
531 break;
532 }
533
534 printf(", ccr addr %x mask %x\n", pf->ccr_base, pf->ccr_mask);
535
536 STAILQ_FOREACH(cfe, &pf->cfe_head, cfe_list) {
537 device_printf(dev, "function %d, config table entry "
538 "%d: ", pf->number, cfe->number);
539
540 switch (cfe->iftype) {
541 case PCCARD_IFTYPE_MEMORY:
542 printf("memory card");
543 break;
544 case PCCARD_IFTYPE_IO:
545 printf("I/O card");
546 break;
547 default:
548 printf("card type unknown");
549 break;
550 }
551
552 printf("; irq mask %x", cfe->irqmask);
553
554 if (cfe->num_iospace) {
555 printf("; iomask %lx, iospace", cfe->iomask);
556
557 for (i = 0; i < cfe->num_iospace; i++) {
558 printf(" %lx", cfe->iospace[i].start);
559 if (cfe->iospace[i].length)
560 printf("-%lx",
561 cfe->iospace[i].start +
562 cfe->iospace[i].length - 1);
563 }
564 }
565 if (cfe->num_memspace) {
566 printf("; memspace");
567
568 for (i = 0; i < cfe->num_memspace; i++) {
569 printf(" %lx",
570 cfe->memspace[i].cardaddr);
571 if (cfe->memspace[i].length)
572 printf("-%lx",
573 cfe->memspace[i].cardaddr +
574 cfe->memspace[i].length - 1);
575 if (cfe->memspace[i].hostaddr)
576 printf("@%lx",
577 cfe->memspace[i].hostaddr);
578 }
579 }
580 if (cfe->maxtwins)
581 printf("; maxtwins %d", cfe->maxtwins);
582
583 printf(";");
584
585 if (cfe->flags & PCCARD_CFE_MWAIT_REQUIRED)
586 printf(" mwait_required");
587 if (cfe->flags & PCCARD_CFE_RDYBSY_ACTIVE)
588 printf(" rdybsy_active");
589 if (cfe->flags & PCCARD_CFE_WP_ACTIVE)
590 printf(" wp_active");
591 if (cfe->flags & PCCARD_CFE_BVD_ACTIVE)
592 printf(" bvd_active");
593 if (cfe->flags & PCCARD_CFE_IO8)
594 printf(" io8");
595 if (cfe->flags & PCCARD_CFE_IO16)
596 printf(" io16");
597 if (cfe->flags & PCCARD_CFE_IRQSHARE)
598 printf(" irqshare");
599 if (cfe->flags & PCCARD_CFE_IRQPULSE)
600 printf(" irqpulse");
601 if (cfe->flags & PCCARD_CFE_IRQLEVEL)
602 printf(" irqlevel");
603 if (cfe->flags & PCCARD_CFE_POWERDOWN)
604 printf(" powerdown");
605 if (cfe->flags & PCCARD_CFE_READONLY)
606 printf(" readonly");
607 if (cfe->flags & PCCARD_CFE_AUDIO)
608 printf(" audio");
609
610 printf("\n");
611 }
612 }
613
614 if (card->error)
615 device_printf(dev, "%d errors found while parsing CIS\n",
616 card->error);
617 }
618
619 int
620 pccard_parse_cis_tuple(struct pccard_tuple *tuple, void *arg)
621 {
622 /* most of these are educated guesses */
623 static struct pccard_config_entry init_cfe = {
624 -1, PCCARD_CFE_RDYBSY_ACTIVE | PCCARD_CFE_WP_ACTIVE |
625 PCCARD_CFE_BVD_ACTIVE, PCCARD_IFTYPE_MEMORY,
626 };
627
628 struct cis_state *state = arg;
629
630 switch (tuple->code) {
631 case CISTPL_END:
632 /* if we've seen a LONGLINK_MFC, and this is the first
633 * END after it, reset the function list.
634 *
635 * XXX This might also be the right place to start a
636 * new function, but that assumes that a function
637 * definition never crosses any longlink, and I'm not
638 * sure about that. This is probably safe for MFC
639 * cards, but what we have now isn't broken, so I'd
640 * rather not change it.
641 */
642 if (state->gotmfc == 1) {
643 struct pccard_function *pf, *pfnext;
644
645 for (pf = STAILQ_FIRST(&state->card->pf_head);
646 pf != NULL; pf = pfnext) {
647 pfnext = STAILQ_NEXT(pf, pf_list);
648 free(pf, M_DEVBUF);
649 }
650
651 STAILQ_INIT(&state->card->pf_head);
652
653 state->count = 0;
654 state->gotmfc = 2;
655 state->pf = NULL;
656 }
657 break;
658 case CISTPL_LONGLINK_MFC:
659 /*
660 * this tuple's structure was dealt with in scan_cis. here,
661 * record the fact that the MFC tuple was seen, so that
662 * functions declared before the MFC link can be cleaned
663 * up.
664 */
665 state->gotmfc = 1;
666 break;
667 #ifdef PCCARDCISDEBUG
668 case CISTPL_DEVICE:
669 case CISTPL_DEVICE_A:
670 {
671 u_int reg, dtype, dspeed;
672
673 reg = pccard_tuple_read_1(tuple, 0);
674 dtype = reg & PCCARD_DTYPE_MASK;
675 dspeed = reg & PCCARD_DSPEED_MASK;
676
677 DPRINTF(("CISTPL_DEVICE%s type=",
678 (tuple->code == CISTPL_DEVICE) ? "" : "_A"));
679 switch (dtype) {
680 case PCCARD_DTYPE_NULL:
681 DPRINTF(("null"));
682 break;
683 case PCCARD_DTYPE_ROM:
684 DPRINTF(("rom"));
685 break;
686 case PCCARD_DTYPE_OTPROM:
687 DPRINTF(("otprom"));
688 break;
689 case PCCARD_DTYPE_EPROM:
690 DPRINTF(("eprom"));
691 break;
692 case PCCARD_DTYPE_EEPROM:
693 DPRINTF(("eeprom"));
694 break;
695 case PCCARD_DTYPE_FLASH:
696 DPRINTF(("flash"));
697 break;
698 case PCCARD_DTYPE_SRAM:
699 DPRINTF(("sram"));
700 break;
701 case PCCARD_DTYPE_DRAM:
702 DPRINTF(("dram"));
703 break;
704 case PCCARD_DTYPE_FUNCSPEC:
705 DPRINTF(("funcspec"));
706 break;
707 case PCCARD_DTYPE_EXTEND:
708 DPRINTF(("extend"));
709 break;
710 default:
711 DPRINTF(("reserved"));
712 break;
713 }
714 DPRINTF((" speed="));
715 switch (dspeed) {
716 case PCCARD_DSPEED_NULL:
717 DPRINTF(("null"));
718 break;
719 case PCCARD_DSPEED_250NS:
720 DPRINTF(("250ns"));
721 break;
722 case PCCARD_DSPEED_200NS:
723 DPRINTF(("200ns"));
724 break;
725 case PCCARD_DSPEED_150NS:
726 DPRINTF(("150ns"));
727 break;
728 case PCCARD_DSPEED_100NS:
729 DPRINTF(("100ns"));
730 break;
731 case PCCARD_DSPEED_EXT:
732 DPRINTF(("ext"));
733 break;
734 default:
735 DPRINTF(("reserved"));
736 break;
737 }
738 }
739 DPRINTF(("\n"));
740 break;
741 #endif
742 case CISTPL_VERS_1:
743 if (tuple->length < 6) {
744 DPRINTF(("CISTPL_VERS_1 too short %d\n",
745 tuple->length));
746 break;
747 } {
748 int start, i, ch, count;
749
750 state->card->cis1_major = pccard_tuple_read_1(tuple, 0);
751 state->card->cis1_minor = pccard_tuple_read_1(tuple, 1);
752
753 for (count = 0, start = 0, i = 0;
754 (count < 4) && ((i + 4) < 256); i++) {
755 ch = pccard_tuple_read_1(tuple, 2 + i);
756 if (ch == 0xff)
757 break;
758 state->card->cis1_info_buf[i] = ch;
759 if (ch == 0) {
760 state->card->cis1_info[count] =
761 state->card->cis1_info_buf + start;
762 start = i + 1;
763 count++;
764 }
765 }
766 DPRINTF(("CISTPL_VERS_1\n"));
767 }
768 break;
769 case CISTPL_MANFID:
770 if (tuple->length < 4) {
771 DPRINTF(("CISTPL_MANFID too short %d\n",
772 tuple->length));
773 break;
774 }
775 state->card->manufacturer = pccard_tuple_read_2(tuple, 0);
776 state->card->product = pccard_tuple_read_2(tuple, 2);
777 /*
778 * This is for xe driver. But not limited to that driver.
779 * In PC Card Standard,
780 * Manufacturer ID: 2byte.
781 * Product ID: typically 2bytes, but there's no limit on its
782 * size. prodext is a two byte field, so maybe we should
783 * also handle the '6' case. So far no cards have surfaced
784 * with a length of '6'.
785 */
786 if (tuple->length == 5 ) {
787 state->card->prodext = pccard_tuple_read_1(tuple, 4);
788 }
789 DPRINTF(("CISTPL_MANFID\n"));
790 break;
791 case CISTPL_FUNCID:
792 if (tuple->length < 1) {
793 DPRINTF(("CISTPL_FUNCID too short %d\n",
794 tuple->length));
795 break;
796 }
797 if ((state->pf == NULL) || (state->gotmfc == 2)) {
798 state->pf = malloc(sizeof(*state->pf), M_DEVBUF,
799 M_NOWAIT | M_ZERO);
800 state->pf->number = state->count++;
801 state->pf->last_config_index = -1;
802 STAILQ_INIT(&state->pf->cfe_head);
803
804 STAILQ_INSERT_TAIL(&state->card->pf_head, state->pf,
805 pf_list);
806 }
807 state->pf->function = pccard_tuple_read_1(tuple, 0);
808
809 DPRINTF(("CISTPL_FUNCID\n"));
810 break;
811 case CISTPL_FUNCE:
812 if (state->pf == NULL || state->pf->function <= 0) {
813 DPRINTF(("CISTPL_FUNCE is not followed by "
814 "valid CISTPL_FUNCID\n"));
815 break;
816 }
817 if (tuple->length >= 2) {
818 decode_funce(tuple, state->pf);
819 }
820 DPRINTF(("CISTPL_FUNCE\n"));
821 break;
822 case CISTPL_CONFIG:
823 if (tuple->length < 3) {
824 DPRINTF(("CISTPL_CONFIG too short %d\n",
825 tuple->length));
826 break;
827 } {
828 u_int reg, rasz, rmsz, rfsz;
829 int i;
830
831 reg = pccard_tuple_read_1(tuple, 0);
832 rasz = 1 + ((reg & PCCARD_TPCC_RASZ_MASK) >>
833 PCCARD_TPCC_RASZ_SHIFT);
834 rmsz = 1 + ((reg & PCCARD_TPCC_RMSZ_MASK) >>
835 PCCARD_TPCC_RMSZ_SHIFT);
836 rfsz = ((reg & PCCARD_TPCC_RFSZ_MASK) >>
837 PCCARD_TPCC_RFSZ_SHIFT);
838
839 if (tuple->length < (rasz + rmsz + rfsz)) {
840 DPRINTF(("CISTPL_CONFIG (%d,%d,%d) too "
841 "short %d\n", rasz, rmsz, rfsz,
842 tuple->length));
843 break;
844 }
845 if (state->pf == NULL) {
846 state->pf = malloc(sizeof(*state->pf),
847 M_DEVBUF, M_NOWAIT | M_ZERO);
848 state->pf->number = state->count++;
849 state->pf->last_config_index = -1;
850 STAILQ_INIT(&state->pf->cfe_head);
851
852 STAILQ_INSERT_TAIL(&state->card->pf_head,
853 state->pf, pf_list);
854
855 state->pf->function = PCCARD_FUNCTION_UNSPEC;
856 }
857 state->pf->last_config_index =
858 pccard_tuple_read_1(tuple, 1);
859
860 state->pf->ccr_base = 0;
861 for (i = 0; i < rasz; i++)
862 state->pf->ccr_base |=
863 ((pccard_tuple_read_1(tuple, 2 + i)) <<
864 (i * 8));
865
866 state->pf->ccr_mask = 0;
867 for (i = 0; i < rmsz; i++)
868 state->pf->ccr_mask |=
869 ((pccard_tuple_read_1(tuple,
870 2 + rasz + i)) << (i * 8));
871
872 /* skip the reserved area and subtuples */
873
874 /* reset the default cfe for each cfe list */
875 state->temp_cfe = init_cfe;
876 state->default_cfe = &state->temp_cfe;
877 }
878 DPRINTF(("CISTPL_CONFIG\n"));
879 break;
880 case CISTPL_CFTABLE_ENTRY:
881 {
882 int idx, i, j;
883 u_int reg, reg2;
884 u_int intface, def, num;
885 u_int power, timing, iospace, irq, memspace, misc;
886 struct pccard_config_entry *cfe;
887
888 idx = 0;
889
890 reg = pccard_tuple_read_1(tuple, idx);
891 idx++;
892 intface = reg & PCCARD_TPCE_INDX_INTFACE;
893 def = reg & PCCARD_TPCE_INDX_DEFAULT;
894 num = reg & PCCARD_TPCE_INDX_NUM_MASK;
895
896 /*
897 * this is a little messy. Some cards have only a
898 * cfentry with the default bit set. So, as we go
899 * through the list, we add new indexes to the queue,
900 * and keep a pointer to the last one with the
901 * default bit set. if we see a record with the same
902 * index, as the default, we stash the default and
903 * replace the queue entry. otherwise, we just add
904 * new entries to the queue, pointing the default ptr
905 * at them if the default bit is set. if we get to
906 * the end with the default pointer pointing at a
907 * record which hasn't had a matching index, that's
908 * ok; it just becomes a cfentry like any other.
909 */
910
911 /*
912 * if the index in the cis differs from the default
913 * cis, create new entry in the queue and start it
914 * with the current default
915 */
916 if (num != state->default_cfe->number) {
917 cfe = (struct pccard_config_entry *)
918 malloc(sizeof(*cfe), M_DEVBUF, M_NOWAIT);
919
920 *cfe = *state->default_cfe;
921
922 STAILQ_INSERT_TAIL(&state->pf->cfe_head,
923 cfe, cfe_list);
924
925 cfe->number = num;
926
927 /*
928 * if the default bit is set in the cis, then
929 * point the new default at whatever is being
930 * filled in
931 */
932 if (def)
933 state->default_cfe = cfe;
934 } else {
935 /*
936 * the cis index matches the default index,
937 * fill in the default cfentry. It is
938 * assumed that the cfdefault index is in the
939 * queue. For it to be otherwise, the cis
940 * index would have to be -1 (initial
941 * condition) which is not possible, or there
942 * would have to be a preceding cis entry
943 * which had the same cis index and had the
944 * default bit unset. Neither condition
945 * should happen. If it does, this cfentry
946 * is lost (written into temp space), which
947 * is an acceptable failure mode.
948 */
949
950 cfe = state->default_cfe;
951
952 /*
953 * if the cis entry does not have the default
954 * bit set, copy the default out of the way
955 * first.
956 */
957 if (!def) {
958 state->temp_cfe = *state->default_cfe;
959 state->default_cfe = &state->temp_cfe;
960 }
961 }
962
963 if (intface) {
964 reg = pccard_tuple_read_1(tuple, idx);
965 idx++;
966 cfe->flags &= ~(PCCARD_CFE_MWAIT_REQUIRED
967 | PCCARD_CFE_RDYBSY_ACTIVE
968 | PCCARD_CFE_WP_ACTIVE
969 | PCCARD_CFE_BVD_ACTIVE);
970 if (reg & PCCARD_TPCE_IF_MWAIT)
971 cfe->flags |= PCCARD_CFE_MWAIT_REQUIRED;
972 if (reg & PCCARD_TPCE_IF_RDYBSY)
973 cfe->flags |= PCCARD_CFE_RDYBSY_ACTIVE;
974 if (reg & PCCARD_TPCE_IF_WP)
975 cfe->flags |= PCCARD_CFE_WP_ACTIVE;
976 if (reg & PCCARD_TPCE_IF_BVD)
977 cfe->flags |= PCCARD_CFE_BVD_ACTIVE;
978 cfe->iftype = reg & PCCARD_TPCE_IF_IFTYPE;
979 }
980 reg = pccard_tuple_read_1(tuple, idx);
981 idx++;
982
983 power = reg & PCCARD_TPCE_FS_POWER_MASK;
984 timing = reg & PCCARD_TPCE_FS_TIMING;
985 iospace = reg & PCCARD_TPCE_FS_IOSPACE;
986 irq = reg & PCCARD_TPCE_FS_IRQ;
987 memspace = reg & PCCARD_TPCE_FS_MEMSPACE_MASK;
988 misc = reg & PCCARD_TPCE_FS_MISC;
989
990 if (power) {
991 /* skip over power, don't save */
992 /* for each parameter selection byte */
993 for (i = 0; i < power; i++) {
994 reg = pccard_tuple_read_1(tuple, idx);
995 idx++;
996 /* for each bit */
997 for (j = 0; j < 7; j++) {
998 /* if the bit is set */
999 if ((reg >> j) & 0x01) {
1000 /* skip over bytes */
1001 do {
1002 reg2 = pccard_tuple_read_1(tuple, idx);
1003 idx++;
1004 /*
1005 * until
1006 * non-extensi
1007 * on byte
1008 */
1009 } while (reg2 & 0x80);
1010 }
1011 }
1012 }
1013 }
1014 if (timing) {
1015 /* skip over timing, don't save */
1016 reg = pccard_tuple_read_1(tuple, idx);
1017 idx++;
1018
1019 if ((reg & PCCARD_TPCE_TD_RESERVED_MASK) !=
1020 PCCARD_TPCE_TD_RESERVED_MASK)
1021 idx++;
1022 if ((reg & PCCARD_TPCE_TD_RDYBSY_MASK) !=
1023 PCCARD_TPCE_TD_RDYBSY_MASK)
1024 idx++;
1025 if ((reg & PCCARD_TPCE_TD_WAIT_MASK) !=
1026 PCCARD_TPCE_TD_WAIT_MASK)
1027 idx++;
1028 }
1029 if (iospace) {
1030 if (tuple->length <= idx) {
1031 DPRINTF(("ran out of space before TCPE_IO\n"));
1032 goto abort_cfe;
1033 }
1034
1035 reg = pccard_tuple_read_1(tuple, idx);
1036 idx++;
1037 cfe->flags &=
1038 ~(PCCARD_CFE_IO8 | PCCARD_CFE_IO16);
1039 if (reg & PCCARD_TPCE_IO_BUSWIDTH_8BIT)
1040 cfe->flags |= PCCARD_CFE_IO8;
1041 if (reg & PCCARD_TPCE_IO_BUSWIDTH_16BIT)
1042 cfe->flags |= PCCARD_CFE_IO16;
1043 cfe->iomask =
1044 reg & PCCARD_TPCE_IO_IOADDRLINES_MASK;
1045
1046 if (reg & PCCARD_TPCE_IO_HASRANGE) {
1047 reg = pccard_tuple_read_1(tuple, idx);
1048 idx++;
1049
1050 cfe->num_iospace = 1 + (reg &
1051 PCCARD_TPCE_IO_RANGE_COUNT);
1052
1053 if (cfe->num_iospace >
1054 (sizeof(cfe->iospace) /
1055 sizeof(cfe->iospace[0]))) {
1056 DPRINTF(("too many io "
1057 "spaces %d",
1058 cfe->num_iospace));
1059 state->card->error++;
1060 break;
1061 }
1062 for (i = 0; i < cfe->num_iospace; i++) {
1063 switch (reg & PCCARD_TPCE_IO_RANGE_ADDRSIZE_MASK) {
1064 case PCCARD_TPCE_IO_RANGE_ADDRSIZE_ONE:
1065 cfe->iospace[i].start =
1066 pccard_tuple_read_1(tuple, idx);
1067 idx++;
1068 break;
1069 case PCCARD_TPCE_IO_RANGE_ADDRSIZE_TWO:
1070 cfe->iospace[i].start =
1071 pccard_tuple_read_2(tuple, idx);
1072 idx += 2;
1073 break;
1074 case PCCARD_TPCE_IO_RANGE_ADDRSIZE_FOUR:
1075 cfe->iospace[i].start =
1076 pccard_tuple_read_4(tuple, idx);
1077 idx += 4;
1078 break;
1079 }
1080 switch (reg &
1081 PCCARD_TPCE_IO_RANGE_LENGTHSIZE_MASK) {
1082 case PCCARD_TPCE_IO_RANGE_LENGTHSIZE_ONE:
1083 cfe->iospace[i].length =
1084 pccard_tuple_read_1(tuple, idx);
1085 idx++;
1086 break;
1087 case PCCARD_TPCE_IO_RANGE_LENGTHSIZE_TWO:
1088 cfe->iospace[i].length =
1089 pccard_tuple_read_2(tuple, idx);
1090 idx += 2;
1091 break;
1092 case PCCARD_TPCE_IO_RANGE_LENGTHSIZE_FOUR:
1093 cfe->iospace[i].length =
1094 pccard_tuple_read_4(tuple, idx);
1095 idx += 4;
1096 break;
1097 }
1098 cfe->iospace[i].length++;
1099 }
1100 } else {
1101 cfe->num_iospace = 1;
1102 cfe->iospace[0].start = 0;
1103 cfe->iospace[0].length =
1104 (1 << cfe->iomask);
1105 }
1106 }
1107 if (irq) {
1108 if (tuple->length <= idx) {
1109 DPRINTF(("ran out of space before TCPE_IR\n"));
1110 goto abort_cfe;
1111 }
1112
1113 reg = pccard_tuple_read_1(tuple, idx);
1114 idx++;
1115 cfe->flags &= ~(PCCARD_CFE_IRQSHARE
1116 | PCCARD_CFE_IRQPULSE
1117 | PCCARD_CFE_IRQLEVEL);
1118 if (reg & PCCARD_TPCE_IR_SHARE)
1119 cfe->flags |= PCCARD_CFE_IRQSHARE;
1120 if (reg & PCCARD_TPCE_IR_PULSE)
1121 cfe->flags |= PCCARD_CFE_IRQPULSE;
1122 if (reg & PCCARD_TPCE_IR_LEVEL)
1123 cfe->flags |= PCCARD_CFE_IRQLEVEL;
1124
1125 if (reg & PCCARD_TPCE_IR_HASMASK) {
1126 /*
1127 * it's legal to ignore the
1128 * special-interrupt bits, so I will
1129 */
1130
1131 cfe->irqmask =
1132 pccard_tuple_read_2(tuple, idx);
1133 idx += 2;
1134 } else {
1135 cfe->irqmask =
1136 (1 << (reg & PCCARD_TPCE_IR_IRQ));
1137 }
1138 }
1139 if (memspace) {
1140 if (tuple->length <= idx) {
1141 DPRINTF(("ran out of space before TCPE_MS\n"));
1142 goto abort_cfe;
1143 }
1144
1145 if (memspace == PCCARD_TPCE_FS_MEMSPACE_NONE) {
1146 cfe->num_memspace = 0;
1147 } else if (memspace == PCCARD_TPCE_FS_MEMSPACE_LENGTH) {
1148 cfe->num_memspace = 1;
1149 cfe->memspace[0].length = 256 *
1150 pccard_tuple_read_2(tuple, idx);
1151 idx += 2;
1152 cfe->memspace[0].cardaddr = 0;
1153 cfe->memspace[0].hostaddr = 0;
1154 } else if (memspace ==
1155 PCCARD_TPCE_FS_MEMSPACE_LENGTHADDR) {
1156 cfe->num_memspace = 1;
1157 cfe->memspace[0].length = 256 *
1158 pccard_tuple_read_2(tuple, idx);
1159 idx += 2;
1160 cfe->memspace[0].cardaddr = 256 *
1161 pccard_tuple_read_2(tuple, idx);
1162 idx += 2;
1163 cfe->memspace[0].hostaddr = cfe->memspace[0].cardaddr;
1164 } else {
1165 int lengthsize;
1166 int cardaddrsize;
1167 int hostaddrsize;
1168
1169 reg = pccard_tuple_read_1(tuple, idx);
1170 idx++;
1171
1172 cfe->num_memspace = (reg &
1173 PCCARD_TPCE_MS_COUNT) + 1;
1174
1175 if (cfe->num_memspace >
1176 (sizeof(cfe->memspace) /
1177 sizeof(cfe->memspace[0]))) {
1178 DPRINTF(("too many mem "
1179 "spaces %d",
1180 cfe->num_memspace));
1181 state->card->error++;
1182 break;
1183 }
1184 lengthsize =
1185 ((reg & PCCARD_TPCE_MS_LENGTH_SIZE_MASK) >>
1186 PCCARD_TPCE_MS_LENGTH_SIZE_SHIFT);
1187 cardaddrsize =
1188 ((reg & PCCARD_TPCE_MS_CARDADDR_SIZE_MASK) >>
1189 PCCARD_TPCE_MS_CARDADDR_SIZE_SHIFT);
1190 hostaddrsize =
1191 (reg & PCCARD_TPCE_MS_HOSTADDR) ? cardaddrsize : 0;
1192
1193 if (lengthsize == 0) {
1194 DPRINTF(("cfe memspace "
1195 "lengthsize == 0"));
1196 state->card->error++;
1197 }
1198 for (i = 0; i < cfe->num_memspace; i++) {
1199 if (lengthsize) {
1200 cfe->memspace[i].length =
1201 256 * pccard_tuple_read_n(tuple, lengthsize,
1202 idx);
1203 idx += lengthsize;
1204 } else {
1205 cfe->memspace[i].length = 0;
1206 }
1207 if (cfe->memspace[i].length == 0) {
1208 DPRINTF(("cfe->memspace[%d].length == 0",
1209 i));
1210 state->card->error++;
1211 }
1212 if (cardaddrsize) {
1213 cfe->memspace[i].cardaddr =
1214 256 * pccard_tuple_read_n(tuple, cardaddrsize,
1215 idx);
1216 idx += cardaddrsize;
1217 } else {
1218 cfe->memspace[i].cardaddr = 0;
1219 }
1220 if (hostaddrsize) {
1221 cfe->memspace[i].hostaddr =
1222 256 * pccard_tuple_read_n(tuple, hostaddrsize,
1223 idx);
1224 idx += hostaddrsize;
1225 } else {
1226 cfe->memspace[i].hostaddr = 0;
1227 }
1228 }
1229 }
1230 }
1231 if (misc) {
1232 if (tuple->length <= idx) {
1233 DPRINTF(("ran out of space before TCPE_MI\n"));
1234 goto abort_cfe;
1235 }
1236
1237 reg = pccard_tuple_read_1(tuple, idx);
1238 idx++;
1239 cfe->flags &= ~(PCCARD_CFE_POWERDOWN
1240 | PCCARD_CFE_READONLY
1241 | PCCARD_CFE_AUDIO);
1242 if (reg & PCCARD_TPCE_MI_PWRDOWN)
1243 cfe->flags |= PCCARD_CFE_POWERDOWN;
1244 if (reg & PCCARD_TPCE_MI_READONLY)
1245 cfe->flags |= PCCARD_CFE_READONLY;
1246 if (reg & PCCARD_TPCE_MI_AUDIO)
1247 cfe->flags |= PCCARD_CFE_AUDIO;
1248 cfe->maxtwins = reg & PCCARD_TPCE_MI_MAXTWINS;
1249
1250 while (reg & PCCARD_TPCE_MI_EXT) {
1251 reg = pccard_tuple_read_1(tuple, idx);
1252 idx++;
1253 }
1254 }
1255 /* skip all the subtuples */
1256 }
1257
1258 abort_cfe:
1259 DPRINTF(("CISTPL_CFTABLE_ENTRY\n"));
1260 break;
1261 default:
1262 DPRINTF(("unhandled CISTPL %x\n", tuple->code));
1263 break;
1264 }
1265
1266 return (0);
1267 }
1268
1269 static int
1270 decode_funce(struct pccard_tuple *tuple, struct pccard_function *pf)
1271 {
1272 int type = pccard_tuple_read_1(tuple, 0);
1273
1274 switch (pf->function) {
1275 case PCCARD_FUNCTION_DISK:
1276 if (type == PCCARD_TPLFE_TYPE_DISK_DEVICE_INTERFACE) {
1277 pf->pf_funce_disk_interface
1278 = pccard_tuple_read_1(tuple, 1);
1279 }
1280 break;
1281 case PCCARD_FUNCTION_NETWORK:
1282 if (type == PCCARD_TPLFE_TYPE_LAN_NID) {
1283 int i;
1284 int len = pccard_tuple_read_1(tuple, 1);
1285 if (tuple->length < 2 + len || len > 8) {
1286 /* tuple length not enough or nid too long */
1287 break;
1288 }
1289 for (i = 0; i < len; i++) {
1290 pf->pf_funce_lan_nid[i]
1291 = pccard_tuple_read_1(tuple, i + 2);
1292 }
1293 pf->pf_funce_lan_nidlen = len;
1294 }
1295 break;
1296 default:
1297 break;
1298 }
1299 return 0;
1300 }
Cache object: 9f75a56995876f490640da7697564d1a
|