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