1 /* $NetBSD: pcmcia_cis.c,v 1.17 2000/02/10 09:01:52 chopps Exp $ */
2 /* $FreeBSD: src/sys/dev/pccard/pccard_cis.c,v 1.23 2002/11/14 14:02:32 mux Exp $ */
3 /* $DragonFly: src/sys/bus/pccard/pccard_cis.c,v 1.3 2004/06/28 02:34:44 dillon Exp $ */
6 * Copyright (c) 1997 Marc Horowitz. All rights reserved.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software
17 * must display the following acknowledgement:
18 * This product includes software developed by Marc Horowitz.
19 * 4. The name of the author may not be used to endorse or promote products
20 * derived from this software without specific prior written permission.
22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
23 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
24 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
25 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
27 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
31 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 #include <sys/param.h>
35 #include <sys/systm.h>
36 #include <sys/malloc.h>
37 #include <sys/module.h>
38 #include <sys/kernel.h>
39 #include <sys/queue.h>
40 #include <sys/types.h>
43 #include <machine/bus.h>
45 #include <machine/resource.h>
47 #include <bus/pccard/pccardreg.h>
48 #include <bus/pccard/pccardvar.h>
52 extern int pccard_cis_debug;
54 #define PCCARDCISDEBUG
56 #define DPRINTF(arg) if (pccard_cis_debug) printf arg
57 #define DEVPRINTF(arg) if (pccard_cis_debug) device_printf arg
60 #define DEVPRINTF(arg)
63 #define PCCARD_CIS_SIZE 4096
68 struct pccard_config_entry temp_cfe;
69 struct pccard_config_entry *default_cfe;
70 struct pccard_card *card;
71 struct pccard_function *pf;
74 int pccard_parse_cis_tuple(struct pccard_tuple *, void *);
75 static int decode_funce(struct pccard_tuple *, struct pccard_function *);
78 pccard_read_cis(struct pccard_softc *sc)
80 struct cis_state state;
82 bzero(&state, sizeof state);
84 state.card = &sc->card;
86 state.card->error = 0;
87 state.card->cis1_major = -1;
88 state.card->cis1_minor = -1;
89 state.card->cis1_info[0] = NULL;
90 state.card->cis1_info[1] = NULL;
91 state.card->cis1_info[2] = NULL;
92 state.card->cis1_info[3] = NULL;
93 state.card->manufacturer = PCMCIA_VENDOR_INVALID;
94 state.card->product = PCMCIA_PRODUCT_INVALID;
95 STAILQ_INIT(&state.card->pf_head);
99 if (pccard_scan_cis(sc->dev, pccard_parse_cis_tuple,
104 #define EARLY_TERM "pccard_scan_cis: early termination, " \
105 "array exceeds allocation\n"
108 pccard_scan_cis(device_t dev, int (*fct)(struct pccard_tuple *, void *),
111 struct resource *res;
113 struct pccard_tuple tuple;
114 int longlink_present;
116 u_long longlink_addr;
127 /* allocate some memory */
130 res = bus_alloc_resource(dev, SYS_RES_MEMORY, &rid, 0, ~0,
131 PCCARD_CIS_SIZE, RF_ACTIVE);
133 device_printf(dev, "can't alloc memory to read attributes\n");
136 CARD_SET_RES_FLAGS(device_get_parent(dev), dev, SYS_RES_MEMORY,
137 rid, PCCARD_A_MEM_ATTR);
138 tuple.memt = rman_get_bustag(res);
139 tuple.memh = rman_get_bushandle(res);
142 DPRINTF(("cis mem map %x\n", (unsigned int) tuple.memh));
146 longlink_present = 1;
153 DEVPRINTF((dev, "CIS tuple chain:\n"));
157 /* get the tuple code */
159 if (tuple.ptr * tuple.mult >= PCCARD_CIS_SIZE) {
160 device_printf(dev, EARLY_TERM);
164 tuple.code = pccard_cis_read_1(&tuple, tuple.ptr);
166 /* two special-case tuples */
168 if (tuple.code == PCCARD_CISTPL_NULL) {
169 DPRINTF(("CISTPL_NONE\n 00\n"));
172 } else if (tuple.code == PCCARD_CISTPL_END) {
173 DPRINTF(("CISTPL_END\n ff\n"));
174 /* Call the function for the END tuple, since
175 the CIS semantics depend on it */
176 if ((*fct) (&tuple, arg)) {
183 /* now all the normal tuples */
185 if ((tuple.ptr + 1) * tuple.mult >= PCCARD_CIS_SIZE) {
186 device_printf(dev, EARLY_TERM);
189 tuple.length = pccard_cis_read_1(&tuple, tuple.ptr + 1);
194 if ((tuple.ptr + 1 + tuple.length) * tuple.mult >=
196 device_printf(dev, EARLY_TERM);
200 switch (tuple.code) {
201 case PCCARD_CISTPL_LONGLINK_A:
202 case PCCARD_CISTPL_LONGLINK_C:
203 if (tuple.length < 4) {
204 DPRINTF(("CISTPL_LONGLINK_%s too "
206 longlink_common ? "C" : "A",
210 longlink_present = 1;
211 longlink_common = (tuple.code ==
212 PCCARD_CISTPL_LONGLINK_C) ? 1 : 0;
213 longlink_addr = pccard_tuple_read_4(&tuple, 0);
214 DPRINTF(("CISTPL_LONGLINK_%s %lx\n",
215 longlink_common ? "C" : "A",
218 case PCCARD_CISTPL_NO_LINK:
219 longlink_present = 0;
220 DPRINTF(("CISTPL_NO_LINK\n"));
222 case PCCARD_CISTPL_CHECKSUM:
223 if (tuple.length < 5) {
224 DPRINTF(("CISTPL_CHECKSUM too "
225 "short %d\n", tuple.length));
234 pccard_tuple_read_2(&tuple, 0);
235 length = pccard_tuple_read_2(&tuple, 2);
236 cksum = pccard_tuple_read_1(&tuple, 4);
238 addr = tuple.ptr + offset;
240 DPRINTF(("CISTPL_CHECKSUM addr=%lx "
242 addr, length, cksum));
245 * XXX do more work to deal with
248 if ((addr >= PCCARD_CIS_SIZE) ||
249 ((addr + length * tuple.mult) >
251 DPRINTF((" skipped, "
256 for (i = 0; i < length; i++) {
258 bus_space_read_1(tuple.memt,
260 addr + tuple.mult * i);
262 if (cksum != (sum & 0xff)) {
263 DPRINTF((" failed sum=%x\n",
266 "CIS checksum failed\n");
269 * XXX Some working cards have
270 * XXX bad checksums!!
279 case PCCARD_CISTPL_LONGLINK_MFC:
280 if (tuple.length < 1) {
281 DPRINTF(("CISTPL_LONGLINK_MFC too "
282 "short %d\n", tuple.length));
285 if (((tuple.length - 1) % 5) != 0) {
286 DPRINTF(("CISTPL_LONGLINK_MFC bogus "
287 "length %d\n", tuple.length));
291 * this is kind of ad hoc, as I don't have
292 * any real documentation
298 * put count into tmp var so that
299 * if we have to bail (because it's
300 * a bogus count) it won't be
301 * remembered for later use.
304 pccard_tuple_read_1(&tuple, 0);
306 DPRINTF(("CISTPL_LONGLINK_MFC %d",
310 * make _sure_ it's the right size;
311 * if too short, it may be a weird
312 * (unknown/undefined) format
314 if (tuple.length != (tmp_count*5 + 1)) {
315 DPRINTF((" bogus length %d\n",
320 * sanity check for a programming
321 * error which is difficult to find
325 howmany(sizeof mfc, sizeof mfc[0]))
326 panic("CISTPL_LONGLINK_MFC mfc "
327 "count would blow stack");
328 mfc_count = tmp_count;
329 for (i = 0; i < mfc_count; i++) {
331 (pccard_tuple_read_1(&tuple,
333 PCCARD_MFC_MEM_COMMON) ?
336 pccard_tuple_read_4(&tuple,
339 mfc[i].common ? "common" :
340 "attr", mfc[i].addr));
345 * for LONGLINK_MFC, fall through to the
346 * function. This tuple has structural and
351 if ((*fct) (&tuple, arg)) {
358 #ifdef PCCARDCISDEBUG
359 /* print the tuple */
363 DPRINTF((" %02x %02x", tuple.code,
366 for (i = 0; i < tuple.length; i++) {
368 pccard_tuple_read_1(&tuple, i)));
377 /* skip to the next tuple */
378 tuple.ptr += 2 + tuple.length;
382 * the chain is done. Clean up and move onto the next one,
383 * if any. The loop is here in the case that there is an MFC
384 * card with no longlink (which defaults to existing, == 0).
385 * In general, this means that if one pointer fails, it will
386 * try the next one, instead of just bailing.
390 if (longlink_present) {
391 CARD_SET_RES_FLAGS(device_get_parent(dev), dev,
392 SYS_RES_MEMORY, rid, longlink_common ?
393 PCCARD_A_MEM_COM : PCCARD_A_MEM_ATTR);
394 DPRINTF(("cis mem map %x\n",
395 (unsigned int) tuple.memh));
396 tuple.mult = longlink_common ? 1 : 2;
397 tuple.ptr = longlink_addr;
398 longlink_present = 0;
401 } else if (mfc_count && (mfc_index < mfc_count)) {
402 CARD_SET_RES_FLAGS(device_get_parent(dev), dev,
403 SYS_RES_MEMORY, rid, mfc[mfc_index].common
404 ? PCCARD_A_MEM_COM : PCCARD_A_MEM_ATTR);
405 DPRINTF(("cis mem map %x\n",
406 (unsigned int) tuple.memh));
407 /* set parse state, and point at the next one */
408 tuple.mult = mfc[mfc_index].common ? 1 : 2;
409 tuple.ptr = mfc[mfc_index].addr;
415 /* make sure that the link is valid */
416 tuple.code = pccard_cis_read_1(&tuple, tuple.ptr);
417 if (tuple.code != PCCARD_CISTPL_LINKTARGET) {
418 DPRINTF(("CISTPL_LINKTARGET expected, "
419 "code %02x observed\n", tuple.code));
422 tuple.length = pccard_cis_read_1(&tuple, tuple.ptr + 1);
423 if (tuple.length < 3) {
424 DPRINTF(("CISTPL_LINKTARGET too short %d\n",
428 if ((pccard_tuple_read_1(&tuple, 0) != 'C') ||
429 (pccard_tuple_read_1(&tuple, 1) != 'I') ||
430 (pccard_tuple_read_1(&tuple, 2) != 'S')) {
431 DPRINTF(("CISTPL_LINKTARGET magic "
432 "%02x%02x%02x incorrect\n",
433 pccard_tuple_read_1(&tuple, 0),
434 pccard_tuple_read_1(&tuple, 1),
435 pccard_tuple_read_1(&tuple, 2)));
438 tuple.ptr += 2 + tuple.length;
444 bus_release_resource(dev, SYS_RES_MEMORY, rid, res);
449 /* XXX this is incredibly verbose. Not sure what trt is */
452 pccard_print_cis(device_t dev)
454 struct pccard_softc *sc = PCCARD_SOFTC(dev);
455 struct pccard_card *card = &sc->card;
456 struct pccard_function *pf;
457 struct pccard_config_entry *cfe;
460 device_printf(dev, "CIS version ");
461 if (card->cis1_major == 4) {
462 if (card->cis1_minor == 0)
463 printf("PCCARD 1.0\n");
464 else if (card->cis1_minor == 1)
465 printf("PCCARD 2.0 or 2.1\n");
466 } else if (card->cis1_major >= 5)
467 printf("PC Card Standard %d.%d\n", card->cis1_major, card->cis1_minor);
469 printf("unknown (major=%d, minor=%d)\n",
470 card->cis1_major, card->cis1_minor);
472 device_printf(dev, "CIS info: ");
473 for (i = 0; i < 4; i++) {
474 if (card->cis1_info[i] == NULL)
478 printf("%s", card->cis1_info[i]);
482 device_printf(dev, "Manufacturer code 0x%x, product 0x%x\n",
483 card->manufacturer, card->product);
485 STAILQ_FOREACH(pf, &card->pf_head, pf_list) {
486 device_printf(dev, "function %d: ", pf->number);
488 switch (pf->function) {
489 case PCCARD_FUNCTION_UNSPEC:
490 printf("unspecified");
492 case PCCARD_FUNCTION_MULTIFUNCTION:
493 printf("multi-function");
495 case PCCARD_FUNCTION_MEMORY:
498 case PCCARD_FUNCTION_SERIAL:
499 printf("serial port");
501 case PCCARD_FUNCTION_PARALLEL:
502 printf("parallel port");
504 case PCCARD_FUNCTION_DISK:
505 printf("fixed disk");
507 case PCCARD_FUNCTION_VIDEO:
508 printf("video adapter");
510 case PCCARD_FUNCTION_NETWORK:
511 printf("network adapter");
513 case PCCARD_FUNCTION_AIMS:
514 printf("auto incrementing mass storage");
516 case PCCARD_FUNCTION_SCSI:
517 printf("SCSI bridge");
519 case PCCARD_FUNCTION_SECURITY:
520 printf("Security services");
522 case PCCARD_FUNCTION_INSTRUMENT:
523 printf("Instrument");
526 printf("unknown (%d)", pf->function);
530 printf(", ccr addr %x mask %x\n", pf->ccr_base, pf->ccr_mask);
532 STAILQ_FOREACH(cfe, &pf->cfe_head, cfe_list) {
533 device_printf(dev, "function %d, config table entry "
534 "%d: ", pf->number, cfe->number);
536 switch (cfe->iftype) {
537 case PCCARD_IFTYPE_MEMORY:
538 printf("memory card");
540 case PCCARD_IFTYPE_IO:
544 printf("card type unknown");
548 printf("; irq mask %x", cfe->irqmask);
550 if (cfe->num_iospace) {
551 printf("; iomask %lx, iospace", cfe->iomask);
553 for (i = 0; i < cfe->num_iospace; i++) {
554 printf(" %lx", cfe->iospace[i].start);
555 if (cfe->iospace[i].length)
557 cfe->iospace[i].start +
558 cfe->iospace[i].length - 1);
561 if (cfe->num_memspace) {
562 printf("; memspace");
564 for (i = 0; i < cfe->num_memspace; i++) {
566 cfe->memspace[i].cardaddr);
567 if (cfe->memspace[i].length)
569 cfe->memspace[i].cardaddr +
570 cfe->memspace[i].length - 1);
571 if (cfe->memspace[i].hostaddr)
573 cfe->memspace[i].hostaddr);
577 printf("; maxtwins %d", cfe->maxtwins);
581 if (cfe->flags & PCCARD_CFE_MWAIT_REQUIRED)
582 printf(" mwait_required");
583 if (cfe->flags & PCCARD_CFE_RDYBSY_ACTIVE)
584 printf(" rdybsy_active");
585 if (cfe->flags & PCCARD_CFE_WP_ACTIVE)
586 printf(" wp_active");
587 if (cfe->flags & PCCARD_CFE_BVD_ACTIVE)
588 printf(" bvd_active");
589 if (cfe->flags & PCCARD_CFE_IO8)
591 if (cfe->flags & PCCARD_CFE_IO16)
593 if (cfe->flags & PCCARD_CFE_IRQSHARE)
595 if (cfe->flags & PCCARD_CFE_IRQPULSE)
597 if (cfe->flags & PCCARD_CFE_IRQLEVEL)
599 if (cfe->flags & PCCARD_CFE_POWERDOWN)
600 printf(" powerdown");
601 if (cfe->flags & PCCARD_CFE_READONLY)
603 if (cfe->flags & PCCARD_CFE_AUDIO)
611 device_printf(dev, "%d errors found while parsing CIS\n",
616 pccard_parse_cis_tuple(struct pccard_tuple *tuple, void *arg)
618 /* most of these are educated guesses */
619 static struct pccard_config_entry init_cfe = {
620 -1, PCCARD_CFE_RDYBSY_ACTIVE | PCCARD_CFE_WP_ACTIVE |
621 PCCARD_CFE_BVD_ACTIVE, PCCARD_IFTYPE_MEMORY,
624 struct cis_state *state = arg;
626 switch (tuple->code) {
627 case PCCARD_CISTPL_END:
628 /* if we've seen a LONGLINK_MFC, and this is the first
629 * END after it, reset the function list.
631 * XXX This might also be the right place to start a
632 * new function, but that assumes that a function
633 * definition never crosses any longlink, and I'm not
634 * sure about that. This is probably safe for MFC
635 * cards, but what we have now isn't broken, so I'd
636 * rather not change it.
638 if (state->gotmfc == 1) {
639 struct pccard_function *pf, *pfnext;
641 for (pf = STAILQ_FIRST(&state->card->pf_head);
642 pf != NULL; pf = pfnext) {
643 pfnext = STAILQ_NEXT(pf, pf_list);
647 STAILQ_INIT(&state->card->pf_head);
654 case PCCARD_CISTPL_LONGLINK_MFC:
656 * this tuple's structure was dealt with in scan_cis. here,
657 * record the fact that the MFC tuple was seen, so that
658 * functions declared before the MFC link can be cleaned
663 #ifdef PCCARDCISDEBUG
664 case PCCARD_CISTPL_DEVICE:
665 case PCCARD_CISTPL_DEVICE_A:
667 u_int reg, dtype, dspeed;
669 reg = pccard_tuple_read_1(tuple, 0);
670 dtype = reg & PCCARD_DTYPE_MASK;
671 dspeed = reg & PCCARD_DSPEED_MASK;
673 DPRINTF(("CISTPL_DEVICE%s type=",
674 (tuple->code == PCCARD_CISTPL_DEVICE) ? "" : "_A"));
676 case PCCARD_DTYPE_NULL:
679 case PCCARD_DTYPE_ROM:
682 case PCCARD_DTYPE_OTPROM:
685 case PCCARD_DTYPE_EPROM:
688 case PCCARD_DTYPE_EEPROM:
691 case PCCARD_DTYPE_FLASH:
694 case PCCARD_DTYPE_SRAM:
697 case PCCARD_DTYPE_DRAM:
700 case PCCARD_DTYPE_FUNCSPEC:
701 DPRINTF(("funcspec"));
703 case PCCARD_DTYPE_EXTEND:
707 DPRINTF(("reserved"));
710 DPRINTF((" speed="));
712 case PCCARD_DSPEED_NULL:
715 case PCCARD_DSPEED_250NS:
718 case PCCARD_DSPEED_200NS:
721 case PCCARD_DSPEED_150NS:
724 case PCCARD_DSPEED_100NS:
727 case PCCARD_DSPEED_EXT:
731 DPRINTF(("reserved"));
738 case PCCARD_CISTPL_VERS_1:
739 if (tuple->length < 6) {
740 DPRINTF(("CISTPL_VERS_1 too short %d\n",
744 int start, i, ch, count;
746 state->card->cis1_major = pccard_tuple_read_1(tuple, 0);
747 state->card->cis1_minor = pccard_tuple_read_1(tuple, 1);
749 for (count = 0, start = 0, i = 0;
750 (count < 4) && ((i + 4) < 256); i++) {
751 ch = pccard_tuple_read_1(tuple, 2 + i);
754 state->card->cis1_info_buf[i] = ch;
756 state->card->cis1_info[count] =
757 state->card->cis1_info_buf + start;
762 DPRINTF(("CISTPL_VERS_1\n"));
765 case PCCARD_CISTPL_MANFID:
766 if (tuple->length < 4) {
767 DPRINTF(("CISTPL_MANFID too short %d\n",
771 state->card->manufacturer = pccard_tuple_read_2(tuple, 0);
772 state->card->product = pccard_tuple_read_2(tuple, 2);
774 * This is for xe driver. But not limited to that driver.
775 * In PC Card Standard,
776 * Manufacturer ID: 2byte.
777 * Product ID: typically 2bytes, but there's no limit on its
778 * size. prodext is a two byte field, so maybe we should
779 * also handle the '6' case. So far no cards have surfaced
780 * with a length of '6'.
782 if (tuple->length == 5 ) {
783 state->card->prodext = pccard_tuple_read_1(tuple, 4);
785 DPRINTF(("CISTPL_MANFID\n"));
787 case PCCARD_CISTPL_FUNCID:
788 if (tuple->length < 1) {
789 DPRINTF(("CISTPL_FUNCID too short %d\n",
793 if ((state->pf == NULL) || (state->gotmfc == 2)) {
794 state->pf = malloc(sizeof(*state->pf), M_DEVBUF,
796 state->pf->number = state->count++;
797 state->pf->last_config_index = -1;
798 STAILQ_INIT(&state->pf->cfe_head);
800 STAILQ_INSERT_TAIL(&state->card->pf_head, state->pf,
803 state->pf->function = pccard_tuple_read_1(tuple, 0);
805 DPRINTF(("CISTPL_FUNCID\n"));
807 case PCCARD_CISTPL_FUNCE:
808 if (state->pf == NULL || state->pf->function <= 0) {
809 DPRINTF(("CISTPL_FUNCE is not followed by "
810 "valid CISTPL_FUNCID\n"));
813 if (tuple->length >= 2) {
814 decode_funce(tuple, state->pf);
816 DPRINTF(("CISTPL_FUNCE\n"));
818 case PCCARD_CISTPL_CONFIG:
819 if (tuple->length < 3) {
820 DPRINTF(("CISTPL_CONFIG too short %d\n",
824 u_int reg, rasz, rmsz, rfsz;
827 reg = pccard_tuple_read_1(tuple, 0);
828 rasz = 1 + ((reg & PCCARD_TPCC_RASZ_MASK) >>
829 PCCARD_TPCC_RASZ_SHIFT);
830 rmsz = 1 + ((reg & PCCARD_TPCC_RMSZ_MASK) >>
831 PCCARD_TPCC_RMSZ_SHIFT);
832 rfsz = ((reg & PCCARD_TPCC_RFSZ_MASK) >>
833 PCCARD_TPCC_RFSZ_SHIFT);
835 if (tuple->length < (rasz + rmsz + rfsz)) {
836 DPRINTF(("CISTPL_CONFIG (%d,%d,%d) too "
837 "short %d\n", rasz, rmsz, rfsz,
841 if (state->pf == NULL) {
842 state->pf = malloc(sizeof(*state->pf),
843 M_DEVBUF, M_INTWAIT | M_ZERO);
844 state->pf->number = state->count++;
845 state->pf->last_config_index = -1;
846 STAILQ_INIT(&state->pf->cfe_head);
848 STAILQ_INSERT_TAIL(&state->card->pf_head,
851 state->pf->function = PCCARD_FUNCTION_UNSPEC;
853 state->pf->last_config_index =
854 pccard_tuple_read_1(tuple, 1);
856 state->pf->ccr_base = 0;
857 for (i = 0; i < rasz; i++)
858 state->pf->ccr_base |=
859 ((pccard_tuple_read_1(tuple, 2 + i)) <<
862 state->pf->ccr_mask = 0;
863 for (i = 0; i < rmsz; i++)
864 state->pf->ccr_mask |=
865 ((pccard_tuple_read_1(tuple,
866 2 + rasz + i)) << (i * 8));
868 /* skip the reserved area and subtuples */
870 /* reset the default cfe for each cfe list */
871 state->temp_cfe = init_cfe;
872 state->default_cfe = &state->temp_cfe;
874 DPRINTF(("CISTPL_CONFIG\n"));
876 case PCCARD_CISTPL_CFTABLE_ENTRY:
880 u_int intface, def, num;
881 u_int power, timing, iospace, irq, memspace, misc;
882 struct pccard_config_entry *cfe;
886 reg = pccard_tuple_read_1(tuple, idx);
888 intface = reg & PCCARD_TPCE_INDX_INTFACE;
889 def = reg & PCCARD_TPCE_INDX_DEFAULT;
890 num = reg & PCCARD_TPCE_INDX_NUM_MASK;
893 * this is a little messy. Some cards have only a
894 * cfentry with the default bit set. So, as we go
895 * through the list, we add new indexes to the queue,
896 * and keep a pointer to the last one with the
897 * default bit set. if we see a record with the same
898 * index, as the default, we stash the default and
899 * replace the queue entry. otherwise, we just add
900 * new entries to the queue, pointing the default ptr
901 * at them if the default bit is set. if we get to
902 * the end with the default pointer pointing at a
903 * record which hasn't had a matching index, that's
904 * ok; it just becomes a cfentry like any other.
908 * if the index in the cis differs from the default
909 * cis, create new entry in the queue and start it
910 * with the current default
912 if (num != state->default_cfe->number) {
913 cfe = malloc(sizeof(*cfe), M_DEVBUF, M_INTWAIT);
915 *cfe = *state->default_cfe;
917 STAILQ_INSERT_TAIL(&state->pf->cfe_head,
923 * if the default bit is set in the cis, then
924 * point the new default at whatever is being
928 state->default_cfe = cfe;
931 * the cis index matches the default index,
932 * fill in the default cfentry. It is
933 * assumed that the cfdefault index is in the
934 * queue. For it to be otherwise, the cis
935 * index would have to be -1 (initial
936 * condition) which is not possible, or there
937 * would have to be a preceding cis entry
938 * which had the same cis index and had the
939 * default bit unset. Neither condition
940 * should happen. If it does, this cfentry
941 * is lost (written into temp space), which
942 * is an acceptable failure mode.
945 cfe = state->default_cfe;
948 * if the cis entry does not have the default
949 * bit set, copy the default out of the way
953 state->temp_cfe = *state->default_cfe;
954 state->default_cfe = &state->temp_cfe;
959 reg = pccard_tuple_read_1(tuple, idx);
961 cfe->flags &= ~(PCCARD_CFE_MWAIT_REQUIRED
962 | PCCARD_CFE_RDYBSY_ACTIVE
963 | PCCARD_CFE_WP_ACTIVE
964 | PCCARD_CFE_BVD_ACTIVE);
965 if (reg & PCCARD_TPCE_IF_MWAIT)
966 cfe->flags |= PCCARD_CFE_MWAIT_REQUIRED;
967 if (reg & PCCARD_TPCE_IF_RDYBSY)
968 cfe->flags |= PCCARD_CFE_RDYBSY_ACTIVE;
969 if (reg & PCCARD_TPCE_IF_WP)
970 cfe->flags |= PCCARD_CFE_WP_ACTIVE;
971 if (reg & PCCARD_TPCE_IF_BVD)
972 cfe->flags |= PCCARD_CFE_BVD_ACTIVE;
973 cfe->iftype = reg & PCCARD_TPCE_IF_IFTYPE;
975 reg = pccard_tuple_read_1(tuple, idx);
978 power = reg & PCCARD_TPCE_FS_POWER_MASK;
979 timing = reg & PCCARD_TPCE_FS_TIMING;
980 iospace = reg & PCCARD_TPCE_FS_IOSPACE;
981 irq = reg & PCCARD_TPCE_FS_IRQ;
982 memspace = reg & PCCARD_TPCE_FS_MEMSPACE_MASK;
983 misc = reg & PCCARD_TPCE_FS_MISC;
986 /* skip over power, don't save */
987 /* for each parameter selection byte */
988 for (i = 0; i < power; i++) {
989 reg = pccard_tuple_read_1(tuple, idx);
992 for (j = 0; j < 7; j++) {
993 /* if the bit is set */
994 if ((reg >> j) & 0x01) {
995 /* skip over bytes */
997 reg2 = pccard_tuple_read_1(tuple, idx);
1004 } while (reg2 & 0x80);
1010 /* skip over timing, don't save */
1011 reg = pccard_tuple_read_1(tuple, idx);
1014 if ((reg & PCCARD_TPCE_TD_RESERVED_MASK) !=
1015 PCCARD_TPCE_TD_RESERVED_MASK)
1017 if ((reg & PCCARD_TPCE_TD_RDYBSY_MASK) !=
1018 PCCARD_TPCE_TD_RDYBSY_MASK)
1020 if ((reg & PCCARD_TPCE_TD_WAIT_MASK) !=
1021 PCCARD_TPCE_TD_WAIT_MASK)
1025 if (tuple->length <= idx) {
1026 DPRINTF(("ran out of space before TCPE_IO\n"));
1030 reg = pccard_tuple_read_1(tuple, idx);
1033 ~(PCCARD_CFE_IO8 | PCCARD_CFE_IO16);
1034 if (reg & PCCARD_TPCE_IO_BUSWIDTH_8BIT)
1035 cfe->flags |= PCCARD_CFE_IO8;
1036 if (reg & PCCARD_TPCE_IO_BUSWIDTH_16BIT)
1037 cfe->flags |= PCCARD_CFE_IO16;
1039 reg & PCCARD_TPCE_IO_IOADDRLINES_MASK;
1041 if (reg & PCCARD_TPCE_IO_HASRANGE) {
1042 reg = pccard_tuple_read_1(tuple, idx);
1045 cfe->num_iospace = 1 + (reg &
1046 PCCARD_TPCE_IO_RANGE_COUNT);
1048 if (cfe->num_iospace >
1049 (sizeof(cfe->iospace) /
1050 sizeof(cfe->iospace[0]))) {
1051 DPRINTF(("too many io "
1054 state->card->error++;
1057 for (i = 0; i < cfe->num_iospace; i++) {
1058 switch (reg & PCCARD_TPCE_IO_RANGE_ADDRSIZE_MASK) {
1059 case PCCARD_TPCE_IO_RANGE_ADDRSIZE_ONE:
1060 cfe->iospace[i].start =
1061 pccard_tuple_read_1(tuple, idx);
1064 case PCCARD_TPCE_IO_RANGE_ADDRSIZE_TWO:
1065 cfe->iospace[i].start =
1066 pccard_tuple_read_2(tuple, idx);
1069 case PCCARD_TPCE_IO_RANGE_ADDRSIZE_FOUR:
1070 cfe->iospace[i].start =
1071 pccard_tuple_read_4(tuple, idx);
1076 PCCARD_TPCE_IO_RANGE_LENGTHSIZE_MASK) {
1077 case PCCARD_TPCE_IO_RANGE_LENGTHSIZE_ONE:
1078 cfe->iospace[i].length =
1079 pccard_tuple_read_1(tuple, idx);
1082 case PCCARD_TPCE_IO_RANGE_LENGTHSIZE_TWO:
1083 cfe->iospace[i].length =
1084 pccard_tuple_read_2(tuple, idx);
1087 case PCCARD_TPCE_IO_RANGE_LENGTHSIZE_FOUR:
1088 cfe->iospace[i].length =
1089 pccard_tuple_read_4(tuple, idx);
1093 cfe->iospace[i].length++;
1096 cfe->num_iospace = 1;
1097 cfe->iospace[0].start = 0;
1098 cfe->iospace[0].length =
1103 if (tuple->length <= idx) {
1104 DPRINTF(("ran out of space before TCPE_IR\n"));
1108 reg = pccard_tuple_read_1(tuple, idx);
1110 cfe->flags &= ~(PCCARD_CFE_IRQSHARE
1111 | PCCARD_CFE_IRQPULSE
1112 | PCCARD_CFE_IRQLEVEL);
1113 if (reg & PCCARD_TPCE_IR_SHARE)
1114 cfe->flags |= PCCARD_CFE_IRQSHARE;
1115 if (reg & PCCARD_TPCE_IR_PULSE)
1116 cfe->flags |= PCCARD_CFE_IRQPULSE;
1117 if (reg & PCCARD_TPCE_IR_LEVEL)
1118 cfe->flags |= PCCARD_CFE_IRQLEVEL;
1120 if (reg & PCCARD_TPCE_IR_HASMASK) {
1122 * it's legal to ignore the
1123 * special-interrupt bits, so I will
1127 pccard_tuple_read_2(tuple, idx);
1131 (1 << (reg & PCCARD_TPCE_IR_IRQ));
1135 if (tuple->length <= idx) {
1136 DPRINTF(("ran out of space before TCPE_MS\n"));
1140 if (memspace == PCCARD_TPCE_FS_MEMSPACE_NONE) {
1141 cfe->num_memspace = 0;
1142 } else if (memspace == PCCARD_TPCE_FS_MEMSPACE_LENGTH) {
1143 cfe->num_memspace = 1;
1144 cfe->memspace[0].length = 256 *
1145 pccard_tuple_read_2(tuple, idx);
1147 cfe->memspace[0].cardaddr = 0;
1148 cfe->memspace[0].hostaddr = 0;
1149 } else if (memspace ==
1150 PCCARD_TPCE_FS_MEMSPACE_LENGTHADDR) {
1151 cfe->num_memspace = 1;
1152 cfe->memspace[0].length = 256 *
1153 pccard_tuple_read_2(tuple, idx);
1155 cfe->memspace[0].cardaddr = 256 *
1156 pccard_tuple_read_2(tuple, idx);
1158 cfe->memspace[0].hostaddr = cfe->memspace[0].cardaddr;
1164 reg = pccard_tuple_read_1(tuple, idx);
1167 cfe->num_memspace = (reg &
1168 PCCARD_TPCE_MS_COUNT) + 1;
1170 if (cfe->num_memspace >
1171 (sizeof(cfe->memspace) /
1172 sizeof(cfe->memspace[0]))) {
1173 DPRINTF(("too many mem "
1175 cfe->num_memspace));
1176 state->card->error++;
1180 ((reg & PCCARD_TPCE_MS_LENGTH_SIZE_MASK) >>
1181 PCCARD_TPCE_MS_LENGTH_SIZE_SHIFT);
1183 ((reg & PCCARD_TPCE_MS_CARDADDR_SIZE_MASK) >>
1184 PCCARD_TPCE_MS_CARDADDR_SIZE_SHIFT);
1186 (reg & PCCARD_TPCE_MS_HOSTADDR) ? cardaddrsize : 0;
1188 if (lengthsize == 0) {
1189 DPRINTF(("cfe memspace "
1190 "lengthsize == 0"));
1191 state->card->error++;
1193 for (i = 0; i < cfe->num_memspace; i++) {
1195 cfe->memspace[i].length =
1196 256 * pccard_tuple_read_n(tuple, lengthsize,
1200 cfe->memspace[i].length = 0;
1202 if (cfe->memspace[i].length == 0) {
1203 DPRINTF(("cfe->memspace[%d].length == 0",
1205 state->card->error++;
1208 cfe->memspace[i].cardaddr =
1209 256 * pccard_tuple_read_n(tuple, cardaddrsize,
1211 idx += cardaddrsize;
1213 cfe->memspace[i].cardaddr = 0;
1216 cfe->memspace[i].hostaddr =
1217 256 * pccard_tuple_read_n(tuple, hostaddrsize,
1219 idx += hostaddrsize;
1221 cfe->memspace[i].hostaddr = 0;
1227 if (tuple->length <= idx) {
1228 DPRINTF(("ran out of space before TCPE_MI\n"));
1232 reg = pccard_tuple_read_1(tuple, idx);
1234 cfe->flags &= ~(PCCARD_CFE_POWERDOWN
1235 | PCCARD_CFE_READONLY
1236 | PCCARD_CFE_AUDIO);
1237 if (reg & PCCARD_TPCE_MI_PWRDOWN)
1238 cfe->flags |= PCCARD_CFE_POWERDOWN;
1239 if (reg & PCCARD_TPCE_MI_READONLY)
1240 cfe->flags |= PCCARD_CFE_READONLY;
1241 if (reg & PCCARD_TPCE_MI_AUDIO)
1242 cfe->flags |= PCCARD_CFE_AUDIO;
1243 cfe->maxtwins = reg & PCCARD_TPCE_MI_MAXTWINS;
1245 while (reg & PCCARD_TPCE_MI_EXT) {
1246 reg = pccard_tuple_read_1(tuple, idx);
1250 /* skip all the subtuples */
1254 DPRINTF(("CISTPL_CFTABLE_ENTRY\n"));
1257 DPRINTF(("unhandled CISTPL %x\n", tuple->code));
1265 decode_funce(struct pccard_tuple *tuple, struct pccard_function *pf)
1267 int type = pccard_tuple_read_1(tuple, 0);
1269 switch (pf->function) {
1270 case PCCARD_FUNCTION_DISK:
1271 if (type == PCCARD_TPLFE_TYPE_DISK_DEVICE_INTERFACE) {
1272 pf->pf_funce_disk_interface
1273 = pccard_tuple_read_1(tuple, 1);
1276 case PCCARD_FUNCTION_NETWORK:
1277 if (type == PCCARD_TPLFE_TYPE_LAN_NID) {
1279 int len = pccard_tuple_read_1(tuple, 1);
1280 if (tuple->length < 2 + len || len > 8) {
1281 /* tuple length not enough or nid too long */
1284 for (i = 0; i < len; i++) {
1285 pf->pf_funce_lan_nid[i]
1286 = pccard_tuple_read_1(tuple, i + 2);
1288 pf->pf_funce_lan_nidlen = len;