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