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.1 2004/02/10 07:55:45 joerg 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 1024
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,
105 pccard_scan_cis(device_t dev, int (*fct)(struct pccard_tuple *, void *),
108 struct resource *res;
110 struct pccard_tuple tuple;
111 int longlink_present;
113 u_long longlink_addr;
124 /* allocate some memory */
127 res = bus_alloc_resource(dev, SYS_RES_MEMORY, &rid, 0, ~0,
128 PCCARD_CIS_SIZE, RF_ACTIVE);
130 device_printf(dev, "can't alloc memory to read attributes\n");
133 CARD_SET_RES_FLAGS(device_get_parent(dev), dev, SYS_RES_MEMORY,
134 rid, PCCARD_A_MEM_ATTR);
135 tuple.memt = rman_get_bustag(res);
136 tuple.memh = rman_get_bushandle(res);
139 DPRINTF(("cis mem map %x\n", (unsigned int) tuple.memh));
143 longlink_present = 1;
150 DEVPRINTF((dev, "CIS tuple chain:\n"));
154 /* get the tuple code */
156 tuple.code = pccard_cis_read_1(&tuple, tuple.ptr);
158 /* two special-case tuples */
160 if (tuple.code == PCCARD_CISTPL_NULL) {
161 DPRINTF(("CISTPL_NONE\n 00\n"));
164 } else if (tuple.code == PCCARD_CISTPL_END) {
165 DPRINTF(("CISTPL_END\n ff\n"));
166 /* Call the function for the END tuple, since
167 the CIS semantics depend on it */
168 if ((*fct) (&tuple, arg)) {
175 /* now all the normal tuples */
177 tuple.length = pccard_cis_read_1(&tuple, tuple.ptr + 1);
178 switch (tuple.code) {
179 case PCCARD_CISTPL_LONGLINK_A:
180 case PCCARD_CISTPL_LONGLINK_C:
181 if (tuple.length < 4) {
182 DPRINTF(("CISTPL_LONGLINK_%s too "
184 longlink_common ? "C" : "A",
188 longlink_present = 1;
189 longlink_common = (tuple.code ==
190 PCCARD_CISTPL_LONGLINK_C) ? 1 : 0;
191 longlink_addr = pccard_tuple_read_4(&tuple, 0);
192 DPRINTF(("CISTPL_LONGLINK_%s %lx\n",
193 longlink_common ? "C" : "A",
196 case PCCARD_CISTPL_NO_LINK:
197 longlink_present = 0;
198 DPRINTF(("CISTPL_NO_LINK\n"));
200 case PCCARD_CISTPL_CHECKSUM:
201 if (tuple.length < 5) {
202 DPRINTF(("CISTPL_CHECKSUM too "
203 "short %d\n", tuple.length));
212 pccard_tuple_read_2(&tuple, 0);
213 length = pccard_tuple_read_2(&tuple, 2);
214 cksum = pccard_tuple_read_1(&tuple, 4);
216 addr = tuple.ptr + offset;
218 DPRINTF(("CISTPL_CHECKSUM addr=%lx "
220 addr, length, cksum));
223 * XXX do more work to deal with
226 if ((addr >= PCCARD_CIS_SIZE) ||
229 DPRINTF((" skipped, "
234 for (i = 0; i < length; i++)
236 bus_space_read_1(tuple.memt,
238 addr + tuple.mult * i);
239 if (cksum != (sum & 0xff)) {
240 DPRINTF((" failed sum=%x\n",
243 "CIS checksum failed\n");
246 * XXX Some working cards have
247 * XXX bad checksums!!
256 case PCCARD_CISTPL_LONGLINK_MFC:
257 if (tuple.length < 1) {
258 DPRINTF(("CISTPL_LONGLINK_MFC too "
259 "short %d\n", tuple.length));
262 if (((tuple.length - 1) % 5) != 0) {
263 DPRINTF(("CISTPL_LONGLINK_MFC bogus "
264 "length %d\n", tuple.length));
268 * this is kind of ad hoc, as I don't have
269 * any real documentation
275 * put count into tmp var so that
276 * if we have to bail (because it's
277 * a bogus count) it won't be
278 * remembered for later use.
281 pccard_tuple_read_1(&tuple, 0);
283 DPRINTF(("CISTPL_LONGLINK_MFC %d",
287 * make _sure_ it's the right size;
288 * if too short, it may be a weird
289 * (unknown/undefined) format
291 if (tuple.length != (tmp_count*5 + 1)) {
292 DPRINTF((" bogus length %d\n",
297 * sanity check for a programming
298 * error which is difficult to find
302 howmany(sizeof mfc, sizeof mfc[0]))
303 panic("CISTPL_LONGLINK_MFC mfc "
304 "count would blow stack");
305 mfc_count = tmp_count;
306 for (i = 0; i < mfc_count; i++) {
308 (pccard_tuple_read_1(&tuple,
310 PCCARD_MFC_MEM_COMMON) ?
313 pccard_tuple_read_4(&tuple,
316 mfc[i].common ? "common" :
317 "attr", mfc[i].addr));
322 * for LONGLINK_MFC, fall through to the
323 * function. This tuple has structural and
328 if ((*fct) (&tuple, arg)) {
335 #ifdef PCCARDCISDEBUG
336 /* print the tuple */
340 DPRINTF((" %02x %02x", tuple.code,
343 for (i = 0; i < tuple.length; i++) {
345 pccard_tuple_read_1(&tuple, i)));
354 /* skip to the next tuple */
355 tuple.ptr += 2 + tuple.length;
359 * the chain is done. Clean up and move onto the next one,
360 * if any. The loop is here in the case that there is an MFC
361 * card with no longlink (which defaults to existing, == 0).
362 * In general, this means that if one pointer fails, it will
363 * try the next one, instead of just bailing.
367 if (longlink_present) {
368 CARD_SET_RES_FLAGS(device_get_parent(dev), dev,
369 SYS_RES_MEMORY, rid, longlink_common ?
370 PCCARD_A_MEM_COM : PCCARD_A_MEM_ATTR);
371 DPRINTF(("cis mem map %x\n",
372 (unsigned int) tuple.memh));
373 tuple.mult = longlink_common ? 1 : 2;
374 tuple.ptr = longlink_addr;
375 longlink_present = 0;
378 } else if (mfc_count && (mfc_index < mfc_count)) {
379 CARD_SET_RES_FLAGS(device_get_parent(dev), dev,
380 SYS_RES_MEMORY, rid, mfc[mfc_index].common
381 ? PCCARD_A_MEM_COM : PCCARD_A_MEM_ATTR);
382 DPRINTF(("cis mem map %x\n",
383 (unsigned int) tuple.memh));
384 /* set parse state, and point at the next one */
385 tuple.mult = mfc[mfc_index].common ? 1 : 2;
386 tuple.ptr = mfc[mfc_index].addr;
392 /* make sure that the link is valid */
393 tuple.code = pccard_cis_read_1(&tuple, tuple.ptr);
394 if (tuple.code != PCCARD_CISTPL_LINKTARGET) {
395 DPRINTF(("CISTPL_LINKTARGET expected, "
396 "code %02x observed\n", tuple.code));
399 tuple.length = pccard_cis_read_1(&tuple, tuple.ptr + 1);
400 if (tuple.length < 3) {
401 DPRINTF(("CISTPL_LINKTARGET too short %d\n",
405 if ((pccard_tuple_read_1(&tuple, 0) != 'C') ||
406 (pccard_tuple_read_1(&tuple, 1) != 'I') ||
407 (pccard_tuple_read_1(&tuple, 2) != 'S')) {
408 DPRINTF(("CISTPL_LINKTARGET magic "
409 "%02x%02x%02x incorrect\n",
410 pccard_tuple_read_1(&tuple, 0),
411 pccard_tuple_read_1(&tuple, 1),
412 pccard_tuple_read_1(&tuple, 2)));
415 tuple.ptr += 2 + tuple.length;
421 bus_release_resource(dev, SYS_RES_MEMORY, rid, res);
426 /* XXX this is incredibly verbose. Not sure what trt is */
429 pccard_print_cis(device_t dev)
431 struct pccard_softc *sc = PCCARD_SOFTC(dev);
432 struct pccard_card *card = &sc->card;
433 struct pccard_function *pf;
434 struct pccard_config_entry *cfe;
437 device_printf(dev, "CIS version ");
438 if (card->cis1_major == 4) {
439 if (card->cis1_minor == 0)
440 printf("PCCARD 1.0\n");
441 else if (card->cis1_minor == 1)
442 printf("PCCARD 2.0 or 2.1\n");
443 } else if (card->cis1_major >= 5)
444 printf("PC Card Standard %d.%d\n", card->cis1_major, card->cis1_minor);
446 printf("unknown (major=%d, minor=%d)\n",
447 card->cis1_major, card->cis1_minor);
449 device_printf(dev, "CIS info: ");
450 for (i = 0; i < 4; i++) {
451 if (card->cis1_info[i] == NULL)
455 printf("%s", card->cis1_info[i]);
459 device_printf(dev, "Manufacturer code 0x%x, product 0x%x\n",
460 card->manufacturer, card->product);
462 STAILQ_FOREACH(pf, &card->pf_head, pf_list) {
463 device_printf(dev, "function %d: ", pf->number);
465 switch (pf->function) {
466 case PCCARD_FUNCTION_UNSPEC:
467 printf("unspecified");
469 case PCCARD_FUNCTION_MULTIFUNCTION:
470 printf("multi-function");
472 case PCCARD_FUNCTION_MEMORY:
475 case PCCARD_FUNCTION_SERIAL:
476 printf("serial port");
478 case PCCARD_FUNCTION_PARALLEL:
479 printf("parallel port");
481 case PCCARD_FUNCTION_DISK:
482 printf("fixed disk");
484 case PCCARD_FUNCTION_VIDEO:
485 printf("video adapter");
487 case PCCARD_FUNCTION_NETWORK:
488 printf("network adapter");
490 case PCCARD_FUNCTION_AIMS:
491 printf("auto incrementing mass storage");
493 case PCCARD_FUNCTION_SCSI:
494 printf("SCSI bridge");
496 case PCCARD_FUNCTION_SECURITY:
497 printf("Security services");
499 case PCCARD_FUNCTION_INSTRUMENT:
500 printf("Instrument");
503 printf("unknown (%d)", pf->function);
507 printf(", ccr addr %x mask %x\n", pf->ccr_base, pf->ccr_mask);
509 STAILQ_FOREACH(cfe, &pf->cfe_head, cfe_list) {
510 device_printf(dev, "function %d, config table entry "
511 "%d: ", pf->number, cfe->number);
513 switch (cfe->iftype) {
514 case PCCARD_IFTYPE_MEMORY:
515 printf("memory card");
517 case PCCARD_IFTYPE_IO:
521 printf("card type unknown");
525 printf("; irq mask %x", cfe->irqmask);
527 if (cfe->num_iospace) {
528 printf("; iomask %lx, iospace", cfe->iomask);
530 for (i = 0; i < cfe->num_iospace; i++) {
531 printf(" %lx", cfe->iospace[i].start);
532 if (cfe->iospace[i].length)
534 cfe->iospace[i].start +
535 cfe->iospace[i].length - 1);
538 if (cfe->num_memspace) {
539 printf("; memspace");
541 for (i = 0; i < cfe->num_memspace; i++) {
543 cfe->memspace[i].cardaddr);
544 if (cfe->memspace[i].length)
546 cfe->memspace[i].cardaddr +
547 cfe->memspace[i].length - 1);
548 if (cfe->memspace[i].hostaddr)
550 cfe->memspace[i].hostaddr);
554 printf("; maxtwins %d", cfe->maxtwins);
558 if (cfe->flags & PCCARD_CFE_MWAIT_REQUIRED)
559 printf(" mwait_required");
560 if (cfe->flags & PCCARD_CFE_RDYBSY_ACTIVE)
561 printf(" rdybsy_active");
562 if (cfe->flags & PCCARD_CFE_WP_ACTIVE)
563 printf(" wp_active");
564 if (cfe->flags & PCCARD_CFE_BVD_ACTIVE)
565 printf(" bvd_active");
566 if (cfe->flags & PCCARD_CFE_IO8)
568 if (cfe->flags & PCCARD_CFE_IO16)
570 if (cfe->flags & PCCARD_CFE_IRQSHARE)
572 if (cfe->flags & PCCARD_CFE_IRQPULSE)
574 if (cfe->flags & PCCARD_CFE_IRQLEVEL)
576 if (cfe->flags & PCCARD_CFE_POWERDOWN)
577 printf(" powerdown");
578 if (cfe->flags & PCCARD_CFE_READONLY)
580 if (cfe->flags & PCCARD_CFE_AUDIO)
588 device_printf(dev, "%d errors found while parsing CIS\n",
593 pccard_parse_cis_tuple(struct pccard_tuple *tuple, void *arg)
595 /* most of these are educated guesses */
596 static struct pccard_config_entry init_cfe = {
597 -1, PCCARD_CFE_RDYBSY_ACTIVE | PCCARD_CFE_WP_ACTIVE |
598 PCCARD_CFE_BVD_ACTIVE, PCCARD_IFTYPE_MEMORY,
601 struct cis_state *state = arg;
603 switch (tuple->code) {
604 case PCCARD_CISTPL_END:
605 /* if we've seen a LONGLINK_MFC, and this is the first
606 * END after it, reset the function list.
608 * XXX This might also be the right place to start a
609 * new function, but that assumes that a function
610 * definition never crosses any longlink, and I'm not
611 * sure about that. This is probably safe for MFC
612 * cards, but what we have now isn't broken, so I'd
613 * rather not change it.
615 if (state->gotmfc == 1) {
616 struct pccard_function *pf, *pfnext;
618 for (pf = STAILQ_FIRST(&state->card->pf_head);
619 pf != NULL; pf = pfnext) {
620 pfnext = STAILQ_NEXT(pf, pf_list);
624 STAILQ_INIT(&state->card->pf_head);
631 case PCCARD_CISTPL_LONGLINK_MFC:
633 * this tuple's structure was dealt with in scan_cis. here,
634 * record the fact that the MFC tuple was seen, so that
635 * functions declared before the MFC link can be cleaned
640 #ifdef PCCARDCISDEBUG
641 case PCCARD_CISTPL_DEVICE:
642 case PCCARD_CISTPL_DEVICE_A:
644 u_int reg, dtype, dspeed;
646 reg = pccard_tuple_read_1(tuple, 0);
647 dtype = reg & PCCARD_DTYPE_MASK;
648 dspeed = reg & PCCARD_DSPEED_MASK;
650 DPRINTF(("CISTPL_DEVICE%s type=",
651 (tuple->code == PCCARD_CISTPL_DEVICE) ? "" : "_A"));
653 case PCCARD_DTYPE_NULL:
656 case PCCARD_DTYPE_ROM:
659 case PCCARD_DTYPE_OTPROM:
662 case PCCARD_DTYPE_EPROM:
665 case PCCARD_DTYPE_EEPROM:
668 case PCCARD_DTYPE_FLASH:
671 case PCCARD_DTYPE_SRAM:
674 case PCCARD_DTYPE_DRAM:
677 case PCCARD_DTYPE_FUNCSPEC:
678 DPRINTF(("funcspec"));
680 case PCCARD_DTYPE_EXTEND:
684 DPRINTF(("reserved"));
687 DPRINTF((" speed="));
689 case PCCARD_DSPEED_NULL:
692 case PCCARD_DSPEED_250NS:
695 case PCCARD_DSPEED_200NS:
698 case PCCARD_DSPEED_150NS:
701 case PCCARD_DSPEED_100NS:
704 case PCCARD_DSPEED_EXT:
708 DPRINTF(("reserved"));
715 case PCCARD_CISTPL_VERS_1:
716 if (tuple->length < 6) {
717 DPRINTF(("CISTPL_VERS_1 too short %d\n",
721 int start, i, ch, count;
723 state->card->cis1_major = pccard_tuple_read_1(tuple, 0);
724 state->card->cis1_minor = pccard_tuple_read_1(tuple, 1);
726 for (count = 0, start = 0, i = 0;
727 (count < 4) && ((i + 4) < 256); i++) {
728 ch = pccard_tuple_read_1(tuple, 2 + i);
731 state->card->cis1_info_buf[i] = ch;
733 state->card->cis1_info[count] =
734 state->card->cis1_info_buf + start;
739 DPRINTF(("CISTPL_VERS_1\n"));
742 case PCCARD_CISTPL_MANFID:
743 if (tuple->length < 4) {
744 DPRINTF(("CISTPL_MANFID too short %d\n",
748 state->card->manufacturer = pccard_tuple_read_2(tuple, 0);
749 state->card->product = pccard_tuple_read_2(tuple, 2);
751 * This is for xe driver. But not limited to that driver.
752 * In PC Card Standard,
753 * Manufacturer ID: 2byte.
754 * Product ID: typically 2bytes, but there's no limit on its
755 * size. prodext is a two byte field, so maybe we should
756 * also handle the '6' case. So far no cards have surfaced
757 * with a length of '6'.
759 if (tuple->length == 5 ) {
760 state->card->prodext = pccard_tuple_read_1(tuple, 4);
762 DPRINTF(("CISTPL_MANFID\n"));
764 case PCCARD_CISTPL_FUNCID:
765 if (tuple->length < 1) {
766 DPRINTF(("CISTPL_FUNCID too short %d\n",
770 if ((state->pf == NULL) || (state->gotmfc == 2)) {
771 state->pf = malloc(sizeof(*state->pf), M_DEVBUF,
773 state->pf->number = state->count++;
774 state->pf->last_config_index = -1;
775 STAILQ_INIT(&state->pf->cfe_head);
777 STAILQ_INSERT_TAIL(&state->card->pf_head, state->pf,
780 state->pf->function = pccard_tuple_read_1(tuple, 0);
782 DPRINTF(("CISTPL_FUNCID\n"));
784 case PCCARD_CISTPL_FUNCE:
785 if (state->pf == NULL || state->pf->function <= 0) {
786 DPRINTF(("CISTPL_FUNCE is not followed by "
787 "valid CISTPL_FUNCID\n"));
790 if (tuple->length >= 2) {
791 decode_funce(tuple, state->pf);
793 DPRINTF(("CISTPL_FUNCE\n"));
795 case PCCARD_CISTPL_CONFIG:
796 if (tuple->length < 3) {
797 DPRINTF(("CISTPL_CONFIG too short %d\n",
801 u_int reg, rasz, rmsz, rfsz;
804 reg = pccard_tuple_read_1(tuple, 0);
805 rasz = 1 + ((reg & PCCARD_TPCC_RASZ_MASK) >>
806 PCCARD_TPCC_RASZ_SHIFT);
807 rmsz = 1 + ((reg & PCCARD_TPCC_RMSZ_MASK) >>
808 PCCARD_TPCC_RMSZ_SHIFT);
809 rfsz = ((reg & PCCARD_TPCC_RFSZ_MASK) >>
810 PCCARD_TPCC_RFSZ_SHIFT);
812 if (tuple->length < (rasz + rmsz + rfsz)) {
813 DPRINTF(("CISTPL_CONFIG (%d,%d,%d) too "
814 "short %d\n", rasz, rmsz, rfsz,
818 if (state->pf == NULL) {
819 state->pf = malloc(sizeof(*state->pf),
820 M_DEVBUF, M_NOWAIT | M_ZERO);
821 state->pf->number = state->count++;
822 state->pf->last_config_index = -1;
823 STAILQ_INIT(&state->pf->cfe_head);
825 STAILQ_INSERT_TAIL(&state->card->pf_head,
828 state->pf->function = PCCARD_FUNCTION_UNSPEC;
830 state->pf->last_config_index =
831 pccard_tuple_read_1(tuple, 1);
833 state->pf->ccr_base = 0;
834 for (i = 0; i < rasz; i++)
835 state->pf->ccr_base |=
836 ((pccard_tuple_read_1(tuple, 2 + i)) <<
839 state->pf->ccr_mask = 0;
840 for (i = 0; i < rmsz; i++)
841 state->pf->ccr_mask |=
842 ((pccard_tuple_read_1(tuple,
843 2 + rasz + i)) << (i * 8));
845 /* skip the reserved area and subtuples */
847 /* reset the default cfe for each cfe list */
848 state->temp_cfe = init_cfe;
849 state->default_cfe = &state->temp_cfe;
851 DPRINTF(("CISTPL_CONFIG\n"));
853 case PCCARD_CISTPL_CFTABLE_ENTRY:
857 u_int intface, def, num;
858 u_int power, timing, iospace, irq, memspace, misc;
859 struct pccard_config_entry *cfe;
863 reg = pccard_tuple_read_1(tuple, idx);
865 intface = reg & PCCARD_TPCE_INDX_INTFACE;
866 def = reg & PCCARD_TPCE_INDX_DEFAULT;
867 num = reg & PCCARD_TPCE_INDX_NUM_MASK;
870 * this is a little messy. Some cards have only a
871 * cfentry with the default bit set. So, as we go
872 * through the list, we add new indexes to the queue,
873 * and keep a pointer to the last one with the
874 * default bit set. if we see a record with the same
875 * index, as the default, we stash the default and
876 * replace the queue entry. otherwise, we just add
877 * new entries to the queue, pointing the default ptr
878 * at them if the default bit is set. if we get to
879 * the end with the default pointer pointing at a
880 * record which hasn't had a matching index, that's
881 * ok; it just becomes a cfentry like any other.
885 * if the index in the cis differs from the default
886 * cis, create new entry in the queue and start it
887 * with the current default
889 if (num != state->default_cfe->number) {
890 cfe = (struct pccard_config_entry *)
891 malloc(sizeof(*cfe), M_DEVBUF, M_NOWAIT);
893 *cfe = *state->default_cfe;
895 STAILQ_INSERT_TAIL(&state->pf->cfe_head,
901 * if the default bit is set in the cis, then
902 * point the new default at whatever is being
906 state->default_cfe = cfe;
909 * the cis index matches the default index,
910 * fill in the default cfentry. It is
911 * assumed that the cfdefault index is in the
912 * queue. For it to be otherwise, the cis
913 * index would have to be -1 (initial
914 * condition) which is not possible, or there
915 * would have to be a preceding cis entry
916 * which had the same cis index and had the
917 * default bit unset. Neither condition
918 * should happen. If it does, this cfentry
919 * is lost (written into temp space), which
920 * is an acceptable failure mode.
923 cfe = state->default_cfe;
926 * if the cis entry does not have the default
927 * bit set, copy the default out of the way
931 state->temp_cfe = *state->default_cfe;
932 state->default_cfe = &state->temp_cfe;
937 reg = pccard_tuple_read_1(tuple, idx);
939 cfe->flags &= ~(PCCARD_CFE_MWAIT_REQUIRED
940 | PCCARD_CFE_RDYBSY_ACTIVE
941 | PCCARD_CFE_WP_ACTIVE
942 | PCCARD_CFE_BVD_ACTIVE);
943 if (reg & PCCARD_TPCE_IF_MWAIT)
944 cfe->flags |= PCCARD_CFE_MWAIT_REQUIRED;
945 if (reg & PCCARD_TPCE_IF_RDYBSY)
946 cfe->flags |= PCCARD_CFE_RDYBSY_ACTIVE;
947 if (reg & PCCARD_TPCE_IF_WP)
948 cfe->flags |= PCCARD_CFE_WP_ACTIVE;
949 if (reg & PCCARD_TPCE_IF_BVD)
950 cfe->flags |= PCCARD_CFE_BVD_ACTIVE;
951 cfe->iftype = reg & PCCARD_TPCE_IF_IFTYPE;
953 reg = pccard_tuple_read_1(tuple, idx);
956 power = reg & PCCARD_TPCE_FS_POWER_MASK;
957 timing = reg & PCCARD_TPCE_FS_TIMING;
958 iospace = reg & PCCARD_TPCE_FS_IOSPACE;
959 irq = reg & PCCARD_TPCE_FS_IRQ;
960 memspace = reg & PCCARD_TPCE_FS_MEMSPACE_MASK;
961 misc = reg & PCCARD_TPCE_FS_MISC;
964 /* skip over power, don't save */
965 /* for each parameter selection byte */
966 for (i = 0; i < power; i++) {
967 reg = pccard_tuple_read_1(tuple, idx);
970 for (j = 0; j < 7; j++) {
971 /* if the bit is set */
972 if ((reg >> j) & 0x01) {
973 /* skip over bytes */
975 reg2 = pccard_tuple_read_1(tuple, idx);
982 } while (reg2 & 0x80);
988 /* skip over timing, don't save */
989 reg = pccard_tuple_read_1(tuple, idx);
992 if ((reg & PCCARD_TPCE_TD_RESERVED_MASK) !=
993 PCCARD_TPCE_TD_RESERVED_MASK)
995 if ((reg & PCCARD_TPCE_TD_RDYBSY_MASK) !=
996 PCCARD_TPCE_TD_RDYBSY_MASK)
998 if ((reg & PCCARD_TPCE_TD_WAIT_MASK) !=
999 PCCARD_TPCE_TD_WAIT_MASK)
1003 if (tuple->length <= idx) {
1004 DPRINTF(("ran out of space before TCPE_IO\n"));
1008 reg = pccard_tuple_read_1(tuple, idx);
1011 ~(PCCARD_CFE_IO8 | PCCARD_CFE_IO16);
1012 if (reg & PCCARD_TPCE_IO_BUSWIDTH_8BIT)
1013 cfe->flags |= PCCARD_CFE_IO8;
1014 if (reg & PCCARD_TPCE_IO_BUSWIDTH_16BIT)
1015 cfe->flags |= PCCARD_CFE_IO16;
1017 reg & PCCARD_TPCE_IO_IOADDRLINES_MASK;
1019 if (reg & PCCARD_TPCE_IO_HASRANGE) {
1020 reg = pccard_tuple_read_1(tuple, idx);
1023 cfe->num_iospace = 1 + (reg &
1024 PCCARD_TPCE_IO_RANGE_COUNT);
1026 if (cfe->num_iospace >
1027 (sizeof(cfe->iospace) /
1028 sizeof(cfe->iospace[0]))) {
1029 DPRINTF(("too many io "
1032 state->card->error++;
1035 for (i = 0; i < cfe->num_iospace; i++) {
1036 switch (reg & PCCARD_TPCE_IO_RANGE_ADDRSIZE_MASK) {
1037 case PCCARD_TPCE_IO_RANGE_ADDRSIZE_ONE:
1038 cfe->iospace[i].start =
1039 pccard_tuple_read_1(tuple, idx);
1042 case PCCARD_TPCE_IO_RANGE_ADDRSIZE_TWO:
1043 cfe->iospace[i].start =
1044 pccard_tuple_read_2(tuple, idx);
1047 case PCCARD_TPCE_IO_RANGE_ADDRSIZE_FOUR:
1048 cfe->iospace[i].start =
1049 pccard_tuple_read_4(tuple, idx);
1054 PCCARD_TPCE_IO_RANGE_LENGTHSIZE_MASK) {
1055 case PCCARD_TPCE_IO_RANGE_LENGTHSIZE_ONE:
1056 cfe->iospace[i].length =
1057 pccard_tuple_read_1(tuple, idx);
1060 case PCCARD_TPCE_IO_RANGE_LENGTHSIZE_TWO:
1061 cfe->iospace[i].length =
1062 pccard_tuple_read_2(tuple, idx);
1065 case PCCARD_TPCE_IO_RANGE_LENGTHSIZE_FOUR:
1066 cfe->iospace[i].length =
1067 pccard_tuple_read_4(tuple, idx);
1071 cfe->iospace[i].length++;
1074 cfe->num_iospace = 1;
1075 cfe->iospace[0].start = 0;
1076 cfe->iospace[0].length =
1081 if (tuple->length <= idx) {
1082 DPRINTF(("ran out of space before TCPE_IR\n"));
1086 reg = pccard_tuple_read_1(tuple, idx);
1088 cfe->flags &= ~(PCCARD_CFE_IRQSHARE
1089 | PCCARD_CFE_IRQPULSE
1090 | PCCARD_CFE_IRQLEVEL);
1091 if (reg & PCCARD_TPCE_IR_SHARE)
1092 cfe->flags |= PCCARD_CFE_IRQSHARE;
1093 if (reg & PCCARD_TPCE_IR_PULSE)
1094 cfe->flags |= PCCARD_CFE_IRQPULSE;
1095 if (reg & PCCARD_TPCE_IR_LEVEL)
1096 cfe->flags |= PCCARD_CFE_IRQLEVEL;
1098 if (reg & PCCARD_TPCE_IR_HASMASK) {
1100 * it's legal to ignore the
1101 * special-interrupt bits, so I will
1105 pccard_tuple_read_2(tuple, idx);
1109 (1 << (reg & PCCARD_TPCE_IR_IRQ));
1113 if (tuple->length <= idx) {
1114 DPRINTF(("ran out of space before TCPE_MS\n"));
1118 if (memspace == PCCARD_TPCE_FS_MEMSPACE_NONE) {
1119 cfe->num_memspace = 0;
1120 } else if (memspace == PCCARD_TPCE_FS_MEMSPACE_LENGTH) {
1121 cfe->num_memspace = 1;
1122 cfe->memspace[0].length = 256 *
1123 pccard_tuple_read_2(tuple, idx);
1125 cfe->memspace[0].cardaddr = 0;
1126 cfe->memspace[0].hostaddr = 0;
1127 } else if (memspace ==
1128 PCCARD_TPCE_FS_MEMSPACE_LENGTHADDR) {
1129 cfe->num_memspace = 1;
1130 cfe->memspace[0].length = 256 *
1131 pccard_tuple_read_2(tuple, idx);
1133 cfe->memspace[0].cardaddr = 256 *
1134 pccard_tuple_read_2(tuple, idx);
1136 cfe->memspace[0].hostaddr = cfe->memspace[0].cardaddr;
1142 reg = pccard_tuple_read_1(tuple, idx);
1145 cfe->num_memspace = (reg &
1146 PCCARD_TPCE_MS_COUNT) + 1;
1148 if (cfe->num_memspace >
1149 (sizeof(cfe->memspace) /
1150 sizeof(cfe->memspace[0]))) {
1151 DPRINTF(("too many mem "
1153 cfe->num_memspace));
1154 state->card->error++;
1158 ((reg & PCCARD_TPCE_MS_LENGTH_SIZE_MASK) >>
1159 PCCARD_TPCE_MS_LENGTH_SIZE_SHIFT);
1161 ((reg & PCCARD_TPCE_MS_CARDADDR_SIZE_MASK) >>
1162 PCCARD_TPCE_MS_CARDADDR_SIZE_SHIFT);
1164 (reg & PCCARD_TPCE_MS_HOSTADDR) ? cardaddrsize : 0;
1166 if (lengthsize == 0) {
1167 DPRINTF(("cfe memspace "
1168 "lengthsize == 0"));
1169 state->card->error++;
1171 for (i = 0; i < cfe->num_memspace; i++) {
1173 cfe->memspace[i].length =
1174 256 * pccard_tuple_read_n(tuple, lengthsize,
1178 cfe->memspace[i].length = 0;
1180 if (cfe->memspace[i].length == 0) {
1181 DPRINTF(("cfe->memspace[%d].length == 0",
1183 state->card->error++;
1186 cfe->memspace[i].cardaddr =
1187 256 * pccard_tuple_read_n(tuple, cardaddrsize,
1189 idx += cardaddrsize;
1191 cfe->memspace[i].cardaddr = 0;
1194 cfe->memspace[i].hostaddr =
1195 256 * pccard_tuple_read_n(tuple, hostaddrsize,
1197 idx += hostaddrsize;
1199 cfe->memspace[i].hostaddr = 0;
1205 if (tuple->length <= idx) {
1206 DPRINTF(("ran out of space before TCPE_MI\n"));
1210 reg = pccard_tuple_read_1(tuple, idx);
1212 cfe->flags &= ~(PCCARD_CFE_POWERDOWN
1213 | PCCARD_CFE_READONLY
1214 | PCCARD_CFE_AUDIO);
1215 if (reg & PCCARD_TPCE_MI_PWRDOWN)
1216 cfe->flags |= PCCARD_CFE_POWERDOWN;
1217 if (reg & PCCARD_TPCE_MI_READONLY)
1218 cfe->flags |= PCCARD_CFE_READONLY;
1219 if (reg & PCCARD_TPCE_MI_AUDIO)
1220 cfe->flags |= PCCARD_CFE_AUDIO;
1221 cfe->maxtwins = reg & PCCARD_TPCE_MI_MAXTWINS;
1223 while (reg & PCCARD_TPCE_MI_EXT) {
1224 reg = pccard_tuple_read_1(tuple, idx);
1228 /* skip all the subtuples */
1232 DPRINTF(("CISTPL_CFTABLE_ENTRY\n"));
1235 DPRINTF(("unhandled CISTPL %x\n", tuple->code));
1243 decode_funce(struct pccard_tuple *tuple, struct pccard_function *pf)
1245 int type = pccard_tuple_read_1(tuple, 0);
1247 switch (pf->function) {
1248 case PCCARD_FUNCTION_DISK:
1249 if (type == PCCARD_TPLFE_TYPE_DISK_DEVICE_INTERFACE) {
1250 pf->pf_funce_disk_interface
1251 = pccard_tuple_read_1(tuple, 1);
1254 case PCCARD_FUNCTION_NETWORK:
1255 if (type == PCCARD_TPLFE_TYPE_LAN_NID) {
1257 int len = pccard_tuple_read_1(tuple, 1);
1258 if (tuple->length < 2 + len || len > 8) {
1259 /* tuple length not enough or nid too long */
1262 for (i = 0; i < len; i++) {
1263 pf->pf_funce_lan_nid[i]
1264 = pccard_tuple_read_1(tuple, i + 2);
1266 pf->pf_funce_lan_nidlen = len;