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