1 /*
2 * Copyright (c) 2000,2001 Jonathan Chen.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions, and the following disclaimer,
10 * without modification, immediately at the beginning of the file.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in
13 * the documentation and/or other materials provided with the
14 * distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
20 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE.
27 *
28 * $FreeBSD: releng/5.0/sys/dev/cardbus/cardbus_cis.c 107301 2002-11-27 06:56:29Z imp $
29 */
30
31 /*
32 * CIS Handling for the Cardbus Bus
33 */
34
35 #include <sys/param.h>
36 #include <sys/systm.h>
37 #include <sys/kernel.h>
38 #include <sys/malloc.h>
39
40 #include <sys/bus.h>
41 #include <machine/bus.h>
42 #include <machine/resource.h>
43 #include <sys/rman.h>
44
45 #include <sys/pciio.h>
46 #include <dev/pci/pcivar.h>
47 #include <dev/pci/pcireg.h>
48
49 #include <dev/cardbus/cardbusreg.h>
50 #include <dev/cardbus/cardbusvar.h>
51 #include <dev/cardbus/cardbus_cis.h>
52
53 #include <dev/pccard/pccardvar.h>
54
55 extern int cardbus_cis_debug;
56
57 #define DPRINTF(a) if (cardbus_cis_debug) printf a
58 #define DEVPRINTF(x) if (cardbus_cis_debug) device_printf x
59
60 #define DECODE_PARAMS \
61 (device_t cbdev, device_t child, int id, int len, \
62 u_int8_t *tupledata, u_int32_t start, u_int32_t *off, \
63 struct tuple_callbacks *info)
64
65 struct tuple_callbacks {
66 int id;
67 char *name;
68 int (*func) DECODE_PARAMS;
69 };
70
71 #define DECODE_PROTOTYPE(NAME) static int decode_tuple_ ## NAME DECODE_PARAMS
72 DECODE_PROTOTYPE(generic);
73 DECODE_PROTOTYPE(nothing);
74 DECODE_PROTOTYPE(copy);
75 DECODE_PROTOTYPE(linktarget);
76 DECODE_PROTOTYPE(vers_1);
77 DECODE_PROTOTYPE(funcid);
78 DECODE_PROTOTYPE(manfid);
79 DECODE_PROTOTYPE(funce);
80 DECODE_PROTOTYPE(bar);
81 DECODE_PROTOTYPE(unhandled);
82 DECODE_PROTOTYPE(end);
83 static int cardbus_read_tuple_conf(device_t cbdev, device_t child,
84 u_int32_t start, u_int32_t *off, int *tupleid, int *len,
85 u_int8_t *tupledata);
86 static int cardbus_read_tuple_mem(device_t cbdev, struct resource *res,
87 u_int32_t start, u_int32_t *off, int *tupleid, int *len,
88 u_int8_t *tupledata);
89 static int cardbus_read_tuple(device_t cbdev, device_t child,
90 struct resource *res, u_int32_t start, u_int32_t *off,
91 int *tupleid, int *len, u_int8_t *tupledata);
92 static void cardbus_read_tuple_finish(device_t cbdev, device_t child,
93 int rid, struct resource *res);
94 static struct resource *cardbus_read_tuple_init(device_t cbdev, device_t child,
95 u_int32_t *start, int *rid);
96 static int decode_tuple(device_t cbdev, device_t child, int tupleid,
97 int len, u_int8_t *tupledata, u_int32_t start,
98 u_int32_t *off, struct tuple_callbacks *callbacks);
99 static int cardbus_parse_cis(device_t cbdev, device_t child,
100 struct tuple_callbacks *callbacks);
101 static int barsort(const void *a, const void *b);
102 static int cardbus_alloc_resources(device_t cbdev, device_t child);
103 static void cardbus_add_map(device_t cbdev, device_t child, int reg);
104 static void cardbus_pickup_maps(device_t cbdev, device_t child);
105
106
107 #define MAKETUPLE(NAME,FUNC) { CISTPL_ ## NAME, #NAME, decode_tuple_ ## FUNC }
108
109 static char *funcnames[] = {
110 "Multi-Functioned",
111 "Memory",
112 "Serial Port",
113 "Parallel Port",
114 "Fixed Disk",
115 "Video Adaptor",
116 "Network Adaptor",
117 "AIMS",
118 "SCSI",
119 "Security"
120 };
121
122 struct cardbus_quirk {
123 u_int32_t devid; /* Vendor/device of the card */
124 int type;
125 #define CARDBUS_QUIRK_MAP_REG 1 /* PCI map register in weird place */
126 int arg1;
127 int arg2;
128 };
129
130 struct cardbus_quirk cardbus_quirks[] = {
131 { 0 }
132 };
133
134 static struct cis_tupleinfo *cisread_buf;
135 static int ncisread_buf;
136
137 /*
138 * Handler functions for various CIS tuples
139 */
140
141 DECODE_PROTOTYPE(generic)
142 {
143 #ifdef CARDBUS_DEBUG
144 int i;
145
146 if (info)
147 printf("TUPLE: %s [%d]:", info->name, len);
148 else
149 printf("TUPLE: Unknown(0x%02x) [%d]:", id, len);
150
151 for (i = 0; i < len; i++) {
152 if (i % 0x10 == 0 && len > 0x10)
153 printf("\n 0x%02x:", i);
154 printf(" %02x", tupledata[i]);
155 }
156 printf("\n");
157 #endif
158 return (0);
159 }
160
161 DECODE_PROTOTYPE(nothing)
162 {
163 return (0);
164 }
165
166 DECODE_PROTOTYPE(copy)
167 {
168 struct cis_tupleinfo *tmpbuf;
169
170 tmpbuf = malloc(sizeof(struct cis_tupleinfo) * (ncisread_buf+1),
171 M_DEVBUF, M_WAITOK);
172 if (ncisread_buf > 0) {
173 memcpy(tmpbuf, cisread_buf,
174 sizeof(struct cis_tupleinfo) * ncisread_buf);
175 free(cisread_buf, M_DEVBUF);
176 }
177 cisread_buf = tmpbuf;
178
179 cisread_buf[ncisread_buf].id = id;
180 cisread_buf[ncisread_buf].len = len;
181 cisread_buf[ncisread_buf].data = malloc(len, M_DEVBUF, M_WAITOK);
182 memcpy(cisread_buf[ncisread_buf].data, tupledata, len);
183 ncisread_buf++;
184 return (0);
185 }
186
187 DECODE_PROTOTYPE(linktarget)
188 {
189 #ifdef CARDBUS_DEBUG
190 int i;
191
192 printf("TUPLE: %s [%d]:", info->name, len);
193
194 for (i = 0; i < len; i++) {
195 if (i % 0x10 == 0 && len > 0x10)
196 printf("\n 0x%02x:", i);
197 printf(" %02x", tupledata[i]);
198 }
199 printf("\n");
200 #endif
201 if (len != 3 || tupledata[0] != 'C' || tupledata[1] != 'I' ||
202 tupledata[2] != 'S') {
203 printf("Invalid data for CIS Link Target!\n");
204 decode_tuple_generic(cbdev, child, id, len, tupledata,
205 start, off, info);
206 return (EINVAL);
207 }
208 return (0);
209 }
210
211 DECODE_PROTOTYPE(vers_1)
212 {
213 int i;
214
215 printf("Product version: %d.%d\n", tupledata[0], tupledata[1]);
216 printf("Product name: ");
217 for (i = 2; i < len; i++) {
218 if (tupledata[i] == '\0')
219 printf(" | ");
220 else if (tupledata[i] == 0xff)
221 break;
222 else
223 printf("%c", tupledata[i]);
224 }
225 printf("\n");
226 return (0);
227 }
228
229 DECODE_PROTOTYPE(funcid)
230 {
231 struct cardbus_devinfo *dinfo = device_get_ivars(child);
232 int numnames = sizeof(funcnames) / sizeof(funcnames[0]);
233 int i;
234
235 printf("Functions: ");
236 for (i = 0; i < len; i++) {
237 if (tupledata[i] < numnames)
238 printf("%s", funcnames[tupledata[i]]);
239 else
240 printf("Unknown(%d)", tupledata[i]);
241 if (i < len-1)
242 printf(", ");
243 }
244
245 if (len > 0)
246 dinfo->funcid = tupledata[0]; /* use first in list */
247 printf("\n");
248 return (0);
249 }
250
251 DECODE_PROTOTYPE(manfid)
252 {
253 struct cardbus_devinfo *dinfo = device_get_ivars(child);
254 int i;
255
256 printf("Manufacturer ID: ");
257 for (i = 0; i < len; i++)
258 printf("%02x", tupledata[i]);
259 printf("\n");
260
261 if (len == 5) {
262 dinfo->mfrid = tupledata[1] | (tupledata[2]<<8);
263 dinfo->prodid = tupledata[3] | (tupledata[4]<<8);
264 }
265 return (0);
266 }
267
268 DECODE_PROTOTYPE(funce)
269 {
270 struct cardbus_devinfo *dinfo = device_get_ivars(child);
271 int type, i;
272
273 printf("Function Extension: ");
274 for (i = 0; i < len; i++)
275 printf("%02x", tupledata[i]);
276 printf("\n");
277 if (len < 2) /* too short */
278 return (0);
279 type = tupledata[0]; /* XXX <32 always? */
280 switch (dinfo->funcid) {
281 case TPL_FUNC_SERIAL:
282 if (type == TPL_FUNCE_SER_UART) { /* NB: len known > 1 */
283 dinfo->funce.sio.type = tupledata[1] & 0x1f;
284 }
285 dinfo->fepresent |= 1<<type;
286 break;
287 case TPL_FUNC_LAN:
288 switch (type) {
289 case TPL_FUNCE_LAN_TECH:
290 dinfo->funce.lan.tech = tupledata[1]; /* XXX mask? */
291 break;
292 #if 0
293 case TPL_FUNCE_LAN_SPEED:
294 for (i = 0; i < 3; i++) {
295 if (dinfo->funce.lan.speed[i] == 0) {
296 if (len > 4) {
297 dinfo->funce.lan.speed[i] =
298 ...;
299 }
300 break;
301 }
302 }
303 break;
304 #endif
305 case TPL_FUNCE_LAN_MEDIA:
306 for (i = 0; i < 4 && dinfo->funce.lan.media[i]; i++) {
307 if (dinfo->funce.lan.media[i] == 0) {
308 /* NB: len known > 1 */
309 dinfo->funce.lan.media[i] =
310 tupledata[1]; /*XXX? mask */
311 break;
312 }
313 }
314 break;
315 case TPL_FUNCE_LAN_NID:
316 if (len > 6)
317 bcopy(&tupledata[1], dinfo->funce.lan.nid, 6);
318 break;
319 case TPL_FUNCE_LAN_CONN:
320 dinfo->funce.lan.contype = tupledata[1];/*XXX mask? */
321 break;
322 }
323 dinfo->fepresent |= 1<<type;
324 break;
325 }
326 return (0);
327 }
328
329 DECODE_PROTOTYPE(bar)
330 {
331 struct cardbus_devinfo *dinfo = device_get_ivars(child);
332 int type;
333 int reg;
334 u_int32_t bar;
335
336 if (len != 6) {
337 printf("*** ERROR *** BAR length not 6 (%d)\n", len);
338 return (EINVAL);
339 }
340 reg = *(u_int16_t*)tupledata;
341 len = *(u_int32_t*)(tupledata + 2);
342 if (reg & TPL_BAR_REG_AS) {
343 type = SYS_RES_IOPORT;
344 } else {
345 type = SYS_RES_MEMORY;
346 }
347 bar = (reg & TPL_BAR_REG_ASI_MASK) - 1;
348 if (bar < 0 || bar > 5 ||
349 (type == SYS_RES_IOPORT && bar == 5)) {
350 device_printf(cbdev, "Invalid BAR number: %02x(%02x)\n",
351 reg, bar);
352 return (0);
353 }
354 bar = CARDBUS_BASE0_REG + bar * 4;
355 if (type == SYS_RES_MEMORY) {
356 if (bar & TPL_BAR_REG_PREFETCHABLE)
357 dinfo->mprefetchable |= BARBIT(bar);
358 if (bar & TPL_BAR_REG_BELOW1MB)
359 dinfo->mbelow1mb |= BARBIT(bar);
360 } else if (type == SYS_RES_IOPORT) {
361 if (bar & TPL_BAR_REG_BELOW1MB)
362 dinfo->ibelow1mb |= BARBIT(bar);
363 }
364 DEVPRINTF((cbdev, "Opening BAR: type=%s, bar=%02x, len=%04x%s%s\n",
365 (type == SYS_RES_MEMORY) ? "MEM" : "IO", bar, len,
366 (type == SYS_RES_MEMORY && dinfo->mprefetchable & BARBIT(bar)) ?
367 " (Prefetchable)" : "", type == SYS_RES_MEMORY ?
368 ((dinfo->mbelow1mb & BARBIT(bar)) ? " (Below 1Mb)" : "") :
369 (dinfo->ibelow1mb & BARBIT(bar)) ? " (Below 1Mb)" : "" ));
370
371 resource_list_add(&dinfo->pci.resources, type, bar, 0UL, ~0UL, len);
372
373 /*
374 * Mark the appropriate bit in the PCI command register so that
375 * device drivers will know which type of BARs can be used.
376 */
377 pci_enable_io(child, type);
378 return (0);
379 }
380
381 DECODE_PROTOTYPE(unhandled)
382 {
383 printf("TUPLE: %s [%d] is unhandled! Bailing...", info->name, len);
384 return (-1);
385 }
386
387 DECODE_PROTOTYPE(end)
388 {
389 printf("CIS reading done\n");
390 return (0);
391 }
392
393 /*
394 * Functions to read the a tuple from the card
395 */
396
397 static int
398 cardbus_read_tuple_conf(device_t cbdev, device_t child, u_int32_t start,
399 u_int32_t *off, int *tupleid, int *len, u_int8_t *tupledata)
400 {
401 int i, j;
402 u_int32_t e;
403 u_int32_t loc;
404
405 loc = start + *off;
406
407 e = pci_read_config(child, loc - loc % 4, 4);
408 for (j = loc % 4; j > 0; j--)
409 e >>= 8;
410 *len = 0;
411 for (i = loc, j = -2; j < *len; j++, i++) {
412 if (i % 4 == 0)
413 e = pci_read_config(child, i, 4);
414 if (j == -2)
415 *tupleid = 0xff & e;
416 else if (j == -1)
417 *len = 0xff & e;
418 else
419 tupledata[j] = 0xff & e;
420 e >>= 8;
421 }
422 *off += *len + 2;
423 return (0);
424 }
425
426 static int
427 cardbus_read_tuple_mem(device_t cbdev, struct resource *res, u_int32_t start,
428 u_int32_t *off, int *tupleid, int *len, u_int8_t *tupledata)
429 {
430 bus_space_tag_t bt;
431 bus_space_handle_t bh;
432 int ret;
433
434 bt = rman_get_bustag(res);
435 bh = rman_get_bushandle(res);
436
437 *tupleid = bus_space_read_1(bt, bh, start + *off);
438 *len = bus_space_read_1(bt, bh, start + *off + 1);
439 bus_space_read_region_1(bt, bh, *off + start + 2, tupledata, *len);
440 ret = 0;
441 *off += *len + 2;
442 return (ret);
443 }
444
445 static int
446 cardbus_read_tuple(device_t cbdev, device_t child, struct resource *res,
447 u_int32_t start, u_int32_t *off, int *tupleid, int *len,
448 u_int8_t *tupledata)
449 {
450 if (res == (struct resource*)~0UL) {
451 return (cardbus_read_tuple_conf(cbdev, child, start, off,
452 tupleid, len, tupledata));
453 } else {
454 return (cardbus_read_tuple_mem(cbdev, res, start, off,
455 tupleid, len, tupledata));
456 }
457 }
458
459 static void
460 cardbus_read_tuple_finish(device_t cbdev, device_t child, int rid,
461 struct resource *res)
462 {
463 if (res != (struct resource*)~0UL) {
464 bus_release_resource(cbdev, SYS_RES_MEMORY, rid, res);
465 pci_write_config(child, rid, 0, 4);
466 PCI_DISABLE_IO(cbdev, child, SYS_RES_MEMORY);
467 }
468 }
469
470 static struct resource *
471 cardbus_read_tuple_init(device_t cbdev, device_t child, u_int32_t *start,
472 int *rid)
473 {
474 u_int32_t testval;
475 u_int32_t size;
476 struct resource *res;
477
478 switch (CARDBUS_CIS_SPACE(*start)) {
479 case CARDBUS_CIS_ASI_TUPLE:
480 /* CIS in PCI config space need no initialization */
481 return ((struct resource*)~0UL);
482 case CARDBUS_CIS_ASI_BAR0:
483 case CARDBUS_CIS_ASI_BAR1:
484 case CARDBUS_CIS_ASI_BAR2:
485 case CARDBUS_CIS_ASI_BAR3:
486 case CARDBUS_CIS_ASI_BAR4:
487 case CARDBUS_CIS_ASI_BAR5:
488 *rid = CARDBUS_BASE0_REG + (CARDBUS_CIS_SPACE(*start) - 1) * 4;
489 break;
490 case CARDBUS_CIS_ASI_ROM:
491 *rid = CARDBUS_ROM_REG;
492 #if 0
493 /*
494 * This mask doesn't contain the bit that actually enables
495 * the Option ROM.
496 */
497 pci_write_config(child, *rid, CARDBUS_ROM_ADDRMASK, 4);
498 #endif
499 break;
500 default:
501 device_printf(cbdev, "Unable to read CIS: Unknown space: %d\n",
502 CARDBUS_CIS_SPACE(*start));
503 return (NULL);
504 }
505
506 /* figure out how much space we need */
507 pci_write_config(child, *rid, 0xffffffff, 4);
508 testval = pci_read_config(child, *rid, 4);
509
510 /*
511 * This bit has a different meaning depending if we are dealing
512 * with a normal BAR or an Option ROM BAR.
513 */
514 if (((testval & 0x1) == 0x1) && (*rid != CARDBUS_ROM_REG)) {
515 device_printf(cbdev, "CIS Space is IO, expecting memory.\n");
516 return (NULL);
517 }
518
519 size = CARDBUS_MAPREG_MEM_SIZE(testval);
520 /* XXX Is this some kind of hack? */
521 if (size < 4096)
522 size = 4096;
523 /* allocate the memory space to read CIS */
524 res = bus_alloc_resource(cbdev, SYS_RES_MEMORY, rid, 0, ~0, size,
525 rman_make_alignment_flags(size) | RF_ACTIVE);
526 if (res == NULL) {
527 device_printf(cbdev, "Unable to allocate resource "
528 "to read CIS.\n");
529 return (NULL);
530 }
531 pci_write_config(child, *rid,
532 rman_get_start(res) | ((*rid == CARDBUS_ROM_REG)?
533 CARDBUS_ROM_ENABLE : 0),
534 4);
535 PCI_ENABLE_IO(cbdev, child, SYS_RES_MEMORY);
536
537 /* Flip to the right ROM image if CIS is in ROM */
538 if (CARDBUS_CIS_SPACE(*start) == CARDBUS_CIS_ASI_ROM) {
539 bus_space_tag_t bt;
540 bus_space_handle_t bh;
541 u_int32_t imagesize;
542 u_int32_t imagebase = 0;
543 u_int32_t pcidata;
544 u_int16_t romsig;
545 int romnum = 0;
546 int imagenum;
547
548 bt = rman_get_bustag(res);
549 bh = rman_get_bushandle(res);
550
551 imagenum = CARDBUS_CIS_ASI_ROM_IMAGE(*start);
552 for (romnum = 0;; romnum++) {
553 romsig = bus_space_read_2(bt, bh,
554 imagebase + CARDBUS_EXROM_SIGNATURE);
555 if (romsig != 0xaa55) {
556 device_printf(cbdev, "Bad header in rom %d: "
557 "[%x] %04x\n", romnum, imagebase +
558 CARDBUS_EXROM_SIGNATURE, romsig);
559 bus_release_resource(cbdev, SYS_RES_MEMORY,
560 *rid, res);
561 *rid = 0;
562 return (NULL);
563 }
564
565 /*
566 * If this was the Option ROM image that we were
567 * looking for, then we are done.
568 */
569 if (romnum == imagenum)
570 break;
571
572 /* Find out where the next Option ROM image is */
573 pcidata = imagebase + bus_space_read_2(bt, bh,
574 imagebase + CARDBUS_EXROM_DATA_PTR);
575 imagesize = bus_space_read_2(bt, bh,
576 pcidata + CARDBUS_EXROM_DATA_IMAGE_LENGTH);
577
578 if (imagesize == 0) {
579 /*
580 * XXX some ROMs seem to have this as zero,
581 * can we assume this means 1 block?
582 */
583 device_printf(cbdev, "Warning, size of Option "
584 "ROM image %d is 0 bytes, assuming 512 "
585 "bytes.\n", romnum);
586 imagesize = 1;
587 }
588
589 /* Image size is in 512 byte units */
590 imagesize <<= 9;
591
592 if ((bus_space_read_1(bt, bh, pcidata +
593 CARDBUS_EXROM_DATA_INDICATOR) & 0x80) != 0) {
594 device_printf(cbdev, "Cannot find CIS in "
595 "Option ROM\n");
596 bus_release_resource(cbdev, SYS_RES_MEMORY,
597 *rid, res);
598 *rid = 0;
599 return (NULL);
600 }
601 imagebase += imagesize;
602 }
603 *start = imagebase + CARDBUS_CIS_ADDR(*start);
604 } else {
605 *start = CARDBUS_CIS_ADDR(*start);
606 }
607
608 return (res);
609 }
610
611 /*
612 * Dispatch the right handler function per tuple
613 */
614
615 static int
616 decode_tuple(device_t cbdev, device_t child, int tupleid, int len,
617 u_int8_t *tupledata, u_int32_t start, u_int32_t *off,
618 struct tuple_callbacks *callbacks)
619 {
620 int i;
621 for (i = 0; callbacks[i].id != CISTPL_GENERIC; i++) {
622 if (tupleid == callbacks[i].id)
623 return (callbacks[i].func(cbdev, child, tupleid, len,
624 tupledata, start, off, &callbacks[i]));
625 }
626
627 if (tupleid < CISTPL_CUSTOMSTART) {
628 device_printf(cbdev, "Undefined tuple encountered, "
629 "CIS parsing terminated\n");
630 return (EINVAL);
631 }
632 return (callbacks[i].func(cbdev, child, tupleid, len,
633 tupledata, start, off, NULL));
634 }
635
636 static int
637 cardbus_parse_cis(device_t cbdev, device_t child,
638 struct tuple_callbacks *callbacks)
639 {
640 u_int8_t tupledata[MAXTUPLESIZE];
641 int tupleid;
642 int len;
643 int expect_linktarget;
644 u_int32_t start, off;
645 struct resource *res;
646 int rid;
647
648 bzero(tupledata, MAXTUPLESIZE);
649 expect_linktarget = TRUE;
650 if ((start = pci_read_config(child, CARDBUS_CIS_REG, 4)) == 0)
651 return (ENXIO);
652 off = 0;
653 res = cardbus_read_tuple_init(cbdev, child, &start, &rid);
654 if (res == NULL)
655 return (ENXIO);
656 do {
657 if (0 != cardbus_read_tuple(cbdev, child, res, start, &off,
658 &tupleid, &len, tupledata)) {
659 device_printf(cbdev, "Failed to read CIS.\n");
660 cardbus_read_tuple_finish(cbdev, child, rid, res);
661 return (ENXIO);
662 }
663
664 if (expect_linktarget && tupleid != CISTPL_LINKTARGET) {
665 device_printf(cbdev, "Expecting link target, got 0x%x\n",
666 tupleid);
667 cardbus_read_tuple_finish(cbdev, child, rid, res);
668 return (EINVAL);
669 }
670 expect_linktarget = decode_tuple(cbdev, child, tupleid, len,
671 tupledata, start, &off, callbacks);
672 if (expect_linktarget != 0) {
673 cardbus_read_tuple_finish(cbdev, child, rid, res);
674 return (expect_linktarget);
675 }
676 } while (tupleid != CISTPL_END);
677 cardbus_read_tuple_finish(cbdev, child, rid, res);
678 return (0);
679 }
680
681 static int
682 barsort(const void *a, const void *b)
683 {
684 return ((*(const struct resource_list_entry * const *)b)->count -
685 (*(const struct resource_list_entry * const *)a)->count);
686 }
687
688 static int
689 cardbus_alloc_resources(device_t cbdev, device_t child)
690 {
691 struct cardbus_devinfo *dinfo = device_get_ivars(child);
692 int count;
693 struct resource_list_entry *rle;
694 struct resource_list_entry **barlist;
695 int tmp;
696 u_int32_t mem_psize = 0, mem_nsize = 0, io_size = 0;
697 struct resource *res;
698 u_int32_t start,end;
699 int rid, flags;
700
701 count = 0;
702 SLIST_FOREACH(rle, &dinfo->pci.resources, link) {
703 count++;
704 }
705 if (count == 0)
706 return (0);
707 barlist = malloc(sizeof(struct resource_list_entry*) * count, M_DEVBUF,
708 M_WAITOK);
709 count = 0;
710 SLIST_FOREACH(rle, &dinfo->pci.resources, link) {
711 barlist[count] = rle;
712 if (rle->type == SYS_RES_IOPORT) {
713 io_size += rle->count;
714 } else if (rle->type == SYS_RES_MEMORY) {
715 if (dinfo->mprefetchable & BARBIT(rle->rid))
716 mem_psize += rle->count;
717 else
718 mem_nsize += rle->count;
719 }
720 count++;
721 }
722
723 /*
724 * We want to allocate the largest resource first, so that our
725 * allocated memory is packed.
726 */
727 qsort(barlist, count, sizeof(struct resource_list_entry*), barsort);
728
729 /* Allocate prefetchable memory */
730 flags = 0;
731 for (tmp = 0; tmp < count; tmp++) {
732 if (barlist[tmp]->res == NULL &&
733 barlist[tmp]->type == SYS_RES_MEMORY &&
734 dinfo->mprefetchable & BARBIT(barlist[tmp]->rid)) {
735 flags = rman_make_alignment_flags(barlist[tmp]->count);
736 break;
737 }
738 }
739 if (flags > 0) { /* If any prefetchable memory is requested... */
740 /*
741 * First we allocate one big space for all resources of this
742 * type. We do this because our parent, pccbb, needs to open
743 * a window to forward all addresses within the window, and
744 * it would be best if nobody else has resources allocated
745 * within the window.
746 * (XXX: Perhaps there might be a better way to do this?)
747 */
748 rid = 0;
749 res = bus_alloc_resource(cbdev, SYS_RES_MEMORY, &rid, 0,
750 (dinfo->mprefetchable & dinfo->mbelow1mb)?0xFFFFF:~0UL,
751 mem_psize, flags);
752 start = rman_get_start(res);
753 end = rman_get_end(res);
754 DEVPRINTF((cbdev, "Prefetchable memory at %x-%x\n", start, end));
755 /*
756 * Now that we know the region is free, release it and hand it
757 * out piece by piece.
758 */
759 bus_release_resource(cbdev, SYS_RES_MEMORY, rid, res);
760 for (tmp = 0; tmp < count; tmp++) {
761 if (barlist[tmp]->res == NULL &&
762 barlist[tmp]->type == SYS_RES_MEMORY &&
763 dinfo->mprefetchable & BARBIT(barlist[tmp]->rid)) {
764 barlist[tmp]->res = bus_alloc_resource(cbdev,
765 barlist[tmp]->type,
766 &barlist[tmp]->rid, start, end,
767 barlist[tmp]->count,
768 rman_make_alignment_flags(
769 barlist[tmp]->count));
770 if (barlist[tmp]->res == NULL) {
771 mem_nsize += barlist[tmp]->count;
772 dinfo->mprefetchable &=
773 ~BARBIT(barlist[tmp]->rid);
774 DEVPRINTF((cbdev, "Cannot pre-allocate "
775 "prefetchable memory, will try as "
776 "non-prefetchable.\n"));
777 } else {
778 barlist[tmp]->start =
779 rman_get_start(barlist[tmp]->res);
780 barlist[tmp]->end =
781 rman_get_end(barlist[tmp]->res);
782 pci_write_config(child,
783 barlist[tmp]->rid,
784 barlist[tmp]->start, 4);
785 DEVPRINTF((cbdev, "Prefetchable memory "
786 "rid=%x at %lx-%lx\n",
787 barlist[tmp]->rid,
788 barlist[tmp]->start,
789 barlist[tmp]->end));
790 }
791 }
792 }
793 }
794
795 /* Allocate non-prefetchable memory */
796 flags = 0;
797 for (tmp = 0; tmp < count; tmp++) {
798 if (barlist[tmp]->res == NULL &&
799 barlist[tmp]->type == SYS_RES_MEMORY) {
800 flags = rman_make_alignment_flags(barlist[tmp]->count);
801 break;
802 }
803 }
804 if (flags > 0) { /* If any non-prefetchable memory is requested... */
805 /*
806 * First we allocate one big space for all resources of this
807 * type. We do this because our parent, pccbb, needs to open
808 * a window to forward all addresses within the window, and
809 * it would be best if nobody else has resources allocated
810 * within the window.
811 * (XXX: Perhaps there might be a better way to do this?)
812 */
813 rid = 0;
814 res = bus_alloc_resource(cbdev, SYS_RES_MEMORY, &rid, 0,
815 ((~dinfo->mprefetchable) & dinfo->mbelow1mb)?0xFFFFF:~0UL,
816 mem_nsize, flags);
817 start = rman_get_start(res);
818 end = rman_get_end(res);
819 DEVPRINTF((cbdev, "Non-prefetchable memory at %x-%x\n",
820 start, end));
821 /*
822 * Now that we know the region is free, release it and hand it
823 * out piece by piece.
824 */
825 bus_release_resource(cbdev, SYS_RES_MEMORY, rid, res);
826 for (tmp = 0; tmp < count; tmp++) {
827 if (barlist[tmp]->res == NULL &&
828 barlist[tmp]->type == SYS_RES_MEMORY) {
829 barlist[tmp]->res = bus_alloc_resource(cbdev,
830 barlist[tmp]->type, &barlist[tmp]->rid,
831 start, end, barlist[tmp]->count,
832 rman_make_alignment_flags(
833 barlist[tmp]->count));
834 if (barlist[tmp]->res == NULL) {
835 DEVPRINTF((cbdev, "Cannot pre-allocate "
836 "memory for cardbus device\n"));
837 free(barlist, M_DEVBUF);
838 return (ENOMEM);
839 }
840 barlist[tmp]->start =
841 rman_get_start(barlist[tmp]->res);
842 barlist[tmp]->end = rman_get_end(
843 barlist[tmp]->res);
844 pci_write_config(child, barlist[tmp]->rid,
845 barlist[tmp]->start, 4);
846 DEVPRINTF((cbdev, "Non-prefetchable memory "
847 "rid=%x at %lx-%lx (%lx)\n",
848 barlist[tmp]->rid, barlist[tmp]->start,
849 barlist[tmp]->end, barlist[tmp]->count));
850 }
851 }
852 }
853
854 /* Allocate IO ports */
855 flags = 0;
856 for (tmp = 0; tmp < count; tmp++) {
857 if (barlist[tmp]->res == NULL &&
858 barlist[tmp]->type == SYS_RES_IOPORT) {
859 flags = rman_make_alignment_flags(barlist[tmp]->count);
860 break;
861 }
862 }
863 if (flags > 0) { /* If any IO port is requested... */
864 /*
865 * First we allocate one big space for all resources of this
866 * type. We do this because our parent, pccbb, needs to open
867 * a window to forward all addresses within the window, and
868 * it would be best if nobody else has resources allocated
869 * within the window.
870 * (XXX: Perhaps there might be a better way to do this?)
871 */
872 rid = 0;
873 res = bus_alloc_resource(cbdev, SYS_RES_IOPORT, &rid, 0,
874 (dinfo->ibelow1mb)?0xFFFFF:~0UL, io_size, flags);
875 start = rman_get_start(res);
876 end = rman_get_end(res);
877 DEVPRINTF((cbdev, "IO port at %x-%x\n", start, end));
878 /*
879 * Now that we know the region is free, release it and hand it
880 * out piece by piece.
881 */
882 bus_release_resource(cbdev, SYS_RES_IOPORT, rid, res);
883 for (tmp = 0; tmp < count; tmp++) {
884 if (barlist[tmp]->res == NULL &&
885 barlist[tmp]->type == SYS_RES_IOPORT) {
886 barlist[tmp]->res = bus_alloc_resource(cbdev,
887 barlist[tmp]->type, &barlist[tmp]->rid,
888 start, end, barlist[tmp]->count,
889 rman_make_alignment_flags(
890 barlist[tmp]->count));
891 if (barlist[tmp]->res == NULL) {
892 DEVPRINTF((cbdev, "Cannot pre-allocate "
893 "IO port for cardbus device\n"));
894 free(barlist, M_DEVBUF);
895 return (ENOMEM);
896 }
897 barlist[tmp]->start =
898 rman_get_start(barlist[tmp]->res);
899 barlist[tmp]->end =
900 rman_get_end(barlist[tmp]->res);
901 pci_write_config(child, barlist[tmp]->rid,
902 barlist[tmp]->start, 4);
903 DEVPRINTF((cbdev, "IO port rid=%x at %lx-%lx\n",
904 barlist[tmp]->rid, barlist[tmp]->start,
905 barlist[tmp]->end));
906 }
907 }
908 }
909
910 /* Allocate IRQ */
911 rid = 0;
912 res = bus_alloc_resource(cbdev, SYS_RES_IRQ, &rid, 0, ~0UL, 1,
913 RF_SHAREABLE);
914 resource_list_add(&dinfo->pci.resources, SYS_RES_IRQ, rid,
915 rman_get_start(res), rman_get_end(res), 1);
916 rle = resource_list_find(&dinfo->pci.resources, SYS_RES_IRQ, rid);
917 rle->res = res;
918 dinfo->pci.cfg.intline = rman_get_start(res);
919 pci_write_config(child, PCIR_INTLINE, rman_get_start(res), 1);
920
921 free(barlist, M_DEVBUF);
922 return (0);
923 }
924
925 /*
926 * Adding a memory/io resource (sans CIS)
927 */
928
929 static void
930 cardbus_add_map(device_t cbdev, device_t child, int reg)
931 {
932 struct cardbus_devinfo *dinfo = device_get_ivars(child);
933 struct resource_list_entry *rle;
934 u_int32_t size;
935 u_int32_t testval;
936 int type;
937
938 SLIST_FOREACH(rle, &dinfo->pci.resources, link) {
939 if (rle->rid == reg)
940 return;
941 }
942
943 if (reg == CARDBUS_ROM_REG)
944 testval = CARDBUS_ROM_ADDRMASK;
945 else
946 testval = ~0;
947
948 pci_write_config(child, reg, testval, 4);
949 testval = pci_read_config(child, reg, 4);
950
951 if (testval == ~0 || testval == 0)
952 return;
953
954 if ((testval & 1) == 0)
955 type = SYS_RES_MEMORY;
956 else
957 type = SYS_RES_IOPORT;
958
959 size = CARDBUS_MAPREG_MEM_SIZE(testval);
960 device_printf(cbdev, "Resource not specified in CIS: id=%x, size=%x\n",
961 reg, size);
962 resource_list_add(&dinfo->pci.resources, type, reg, 0UL, ~0UL, size);
963 }
964
965 static void
966 cardbus_pickup_maps(device_t cbdev, device_t child)
967 {
968 struct cardbus_devinfo *dinfo = device_get_ivars(child);
969 struct cardbus_quirk *q;
970 int reg;
971
972 /*
973 * Try to pick up any resources that was not specified in CIS.
974 * Some devices (eg, 3c656) does not list all resources required by
975 * the driver in its CIS.
976 * XXX: should we do this or use quirks?
977 */
978 for (reg = 0; reg < dinfo->pci.cfg.nummaps; reg++) {
979 cardbus_add_map(cbdev, child, PCIR_MAPS + reg * 4);
980 }
981
982 for (q = &cardbus_quirks[0]; q->devid; q++) {
983 if (q->devid == ((dinfo->pci.cfg.device << 16) | dinfo->pci.cfg.vendor)
984 && q->type == CARDBUS_QUIRK_MAP_REG) {
985 cardbus_add_map(cbdev, child, q->arg1);
986 }
987 }
988 }
989
990 int
991 cardbus_cis_read(device_t cbdev, device_t child, u_int8_t id,
992 struct cis_tupleinfo **buff, int *nret)
993 {
994 struct tuple_callbacks cisread_callbacks[] = {
995 MAKETUPLE(NULL, nothing),
996 /* first entry will be overwritten */
997 MAKETUPLE(NULL, nothing),
998 MAKETUPLE(DEVICE, nothing),
999 MAKETUPLE(LONG_LINK_CB, unhandled),
1000 MAKETUPLE(INDIRECT, unhandled),
1001 MAKETUPLE(CONFIG_CB, nothing),
1002 MAKETUPLE(CFTABLE_ENTRY_CB, nothing),
1003 MAKETUPLE(LONGLINK_MFC, unhandled),
1004 MAKETUPLE(BAR, nothing),
1005 MAKETUPLE(PWR_MGMNT, nothing),
1006 MAKETUPLE(EXTDEVICE, nothing),
1007 MAKETUPLE(CHECKSUM, nothing),
1008 MAKETUPLE(LONGLINK_A, unhandled),
1009 MAKETUPLE(LONGLINK_C, unhandled),
1010 MAKETUPLE(LINKTARGET, nothing),
1011 MAKETUPLE(NO_LINK, nothing),
1012 MAKETUPLE(VERS_1, nothing),
1013 MAKETUPLE(ALTSTR, nothing),
1014 MAKETUPLE(DEVICE_A, nothing),
1015 MAKETUPLE(JEDEC_C, nothing),
1016 MAKETUPLE(JEDEC_A, nothing),
1017 MAKETUPLE(CONFIG, nothing),
1018 MAKETUPLE(CFTABLE_ENTRY, nothing),
1019 MAKETUPLE(DEVICE_OC, nothing),
1020 MAKETUPLE(DEVICE_OA, nothing),
1021 MAKETUPLE(DEVICE_GEO, nothing),
1022 MAKETUPLE(DEVICE_GEO_A, nothing),
1023 MAKETUPLE(MANFID, nothing),
1024 MAKETUPLE(FUNCID, nothing),
1025 MAKETUPLE(FUNCE, nothing),
1026 MAKETUPLE(SWIL, nothing),
1027 MAKETUPLE(VERS_2, nothing),
1028 MAKETUPLE(FORMAT, nothing),
1029 MAKETUPLE(GEOMETRY, nothing),
1030 MAKETUPLE(BYTEORDER, nothing),
1031 MAKETUPLE(DATE, nothing),
1032 MAKETUPLE(BATTERY, nothing),
1033 MAKETUPLE(ORG, nothing),
1034 MAKETUPLE(END, end),
1035 MAKETUPLE(GENERIC, nothing),
1036 };
1037 int ret;
1038
1039 cisread_callbacks[0].id = id;
1040 cisread_callbacks[0].name = "COPY";
1041 cisread_callbacks[0].func = decode_tuple_copy;
1042 ncisread_buf = 0;
1043 cisread_buf = NULL;
1044 ret = cardbus_parse_cis(cbdev, child, cisread_callbacks);
1045
1046 *buff = cisread_buf;
1047 *nret = ncisread_buf;
1048 return (ret);
1049 }
1050
1051 void
1052 cardbus_cis_free(device_t cbdev, struct cis_tupleinfo *buff, int *nret)
1053 {
1054 int i;
1055 for (i = 0; i < *nret; i++)
1056 free(buff[i].data, M_DEVBUF);
1057 if (*nret > 0)
1058 free(buff, M_DEVBUF);
1059 }
1060
1061 int
1062 cardbus_do_cis(device_t cbdev, device_t child)
1063 {
1064 int ret;
1065 struct tuple_callbacks init_callbacks[] = {
1066 MAKETUPLE(NULL, generic),
1067 MAKETUPLE(DEVICE, generic),
1068 MAKETUPLE(LONG_LINK_CB, unhandled),
1069 MAKETUPLE(INDIRECT, unhandled),
1070 MAKETUPLE(CONFIG_CB, generic),
1071 MAKETUPLE(CFTABLE_ENTRY_CB, generic),
1072 MAKETUPLE(LONGLINK_MFC, unhandled),
1073 MAKETUPLE(BAR, bar),
1074 MAKETUPLE(PWR_MGMNT, generic),
1075 MAKETUPLE(EXTDEVICE, generic),
1076 MAKETUPLE(CHECKSUM, generic),
1077 MAKETUPLE(LONGLINK_A, unhandled),
1078 MAKETUPLE(LONGLINK_C, unhandled),
1079 MAKETUPLE(LINKTARGET, linktarget),
1080 MAKETUPLE(NO_LINK, generic),
1081 MAKETUPLE(VERS_1, vers_1),
1082 MAKETUPLE(ALTSTR, generic),
1083 MAKETUPLE(DEVICE_A, generic),
1084 MAKETUPLE(JEDEC_C, generic),
1085 MAKETUPLE(JEDEC_A, generic),
1086 MAKETUPLE(CONFIG, generic),
1087 MAKETUPLE(CFTABLE_ENTRY, generic),
1088 MAKETUPLE(DEVICE_OC, generic),
1089 MAKETUPLE(DEVICE_OA, generic),
1090 MAKETUPLE(DEVICE_GEO, generic),
1091 MAKETUPLE(DEVICE_GEO_A, generic),
1092 MAKETUPLE(MANFID, manfid),
1093 MAKETUPLE(FUNCID, funcid),
1094 MAKETUPLE(FUNCE, funce),
1095 MAKETUPLE(SWIL, generic),
1096 MAKETUPLE(VERS_2, generic),
1097 MAKETUPLE(FORMAT, generic),
1098 MAKETUPLE(GEOMETRY, generic),
1099 MAKETUPLE(BYTEORDER, generic),
1100 MAKETUPLE(DATE, generic),
1101 MAKETUPLE(BATTERY, generic),
1102 MAKETUPLE(ORG, generic),
1103 MAKETUPLE(END, end),
1104 MAKETUPLE(GENERIC, generic),
1105 };
1106
1107 ret = cardbus_parse_cis(cbdev, child, init_callbacks);
1108 if (ret < 0)
1109 return (ret);
1110 cardbus_pickup_maps(cbdev, child);
1111 return (cardbus_alloc_resources(cbdev, child));
1112 }
Cache object: 0b30a8e4840bdce628af1735a7b5bca8
|