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