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 */
29
30 #include <sys/cdefs.h>
31 __FBSDID("$FreeBSD: releng/5.3/sys/dev/cardbus/cardbus_cis.c 128131 2004-04-11 19:22:25Z imp $");
32
33 /*
34 * CIS Handling for the Cardbus Bus
35 */
36
37 #include <sys/param.h>
38 #include <sys/systm.h>
39 #include <sys/kernel.h>
40 #include <sys/malloc.h>
41
42 #include <sys/bus.h>
43 #include <machine/bus.h>
44 #include <machine/resource.h>
45 #include <sys/rman.h>
46 #include <sys/endian.h>
47
48 #include <sys/pciio.h>
49 #include <dev/pci/pcivar.h>
50 #include <dev/pci/pcireg.h>
51
52 #include <dev/pccard/pccardvar.h>
53 #include <dev/pccard/pccard_cis.h>
54
55 #include <dev/cardbus/cardbusreg.h>
56 #include <dev/cardbus/cardbusvar.h>
57 #include <dev/cardbus/cardbus_cis.h>
58
59 extern int cardbus_cis_debug;
60
61 #define DPRINTF(a) if (cardbus_cis_debug) printf a
62 #define DEVPRINTF(x) if (cardbus_cis_debug) device_printf x
63
64 struct tuple_callbacks;
65
66 typedef int (tuple_cb) (device_t cbdev, device_t child, int id, int len,
67 uint8_t *tupledata, uint32_t start, uint32_t *off,
68 struct tuple_callbacks *info);
69
70 struct tuple_callbacks {
71 int id;
72 char *name;
73 tuple_cb *func;
74 };
75
76 static int decode_tuple_generic(device_t cbdev, device_t child, int id,
77 int len, uint8_t *tupledata, uint32_t start, uint32_t *off,
78 struct tuple_callbacks *info);
79 static int decode_tuple_linktarget(device_t cbdev, device_t child, int id,
80 int len, uint8_t *tupledata, uint32_t start, uint32_t *off,
81 struct tuple_callbacks *info);
82 static int decode_tuple_vers_1(device_t cbdev, device_t child, int id,
83 int len, uint8_t *tupledata, uint32_t start, uint32_t *off,
84 struct tuple_callbacks *info);
85 static int decode_tuple_funcid(device_t cbdev, device_t child, int id,
86 int len, uint8_t *tupledata, uint32_t start, uint32_t *off,
87 struct tuple_callbacks *info);
88 static int decode_tuple_manfid(device_t cbdev, device_t child, int id,
89 int len, uint8_t *tupledata, uint32_t start, uint32_t *off,
90 struct tuple_callbacks *info);
91 static int decode_tuple_funce(device_t cbdev, device_t child, int id,
92 int len, uint8_t *tupledata, uint32_t start, uint32_t *off,
93 struct tuple_callbacks *info);
94 static int decode_tuple_bar(device_t cbdev, device_t child, int id,
95 int len, uint8_t *tupledata, uint32_t start, uint32_t *off,
96 struct tuple_callbacks *info);
97 static int decode_tuple_unhandled(device_t cbdev, device_t child, int id,
98 int len, uint8_t *tupledata, uint32_t start, uint32_t *off,
99 struct tuple_callbacks *info);
100 static int decode_tuple_end(device_t cbdev, device_t child, int id,
101 int len, uint8_t *tupledata, uint32_t start, uint32_t *off,
102 struct tuple_callbacks *info);
103
104 static int cardbus_read_tuple_conf(device_t cbdev, device_t child,
105 uint32_t start, uint32_t *off, int *tupleid, int *len,
106 uint8_t *tupledata);
107 static int cardbus_read_tuple_mem(device_t cbdev, struct resource *res,
108 uint32_t start, uint32_t *off, int *tupleid, int *len,
109 uint8_t *tupledata);
110 static int cardbus_read_tuple(device_t cbdev, device_t child,
111 struct resource *res, uint32_t start, uint32_t *off,
112 int *tupleid, int *len, uint8_t *tupledata);
113 static void cardbus_read_tuple_finish(device_t cbdev, device_t child,
114 int rid, struct resource *res);
115 static struct resource *cardbus_read_tuple_init(device_t cbdev, device_t child,
116 uint32_t *start, int *rid);
117 static int decode_tuple(device_t cbdev, device_t child, int tupleid,
118 int len, uint8_t *tupledata, uint32_t start,
119 uint32_t *off, struct tuple_callbacks *callbacks);
120 static int cardbus_parse_cis(device_t cbdev, device_t child,
121 struct tuple_callbacks *callbacks);
122 static int barsort(const void *a, const void *b);
123 static int cardbus_alloc_resources(device_t cbdev, device_t child);
124 static void cardbus_add_map(device_t cbdev, device_t child, int reg);
125 static void cardbus_pickup_maps(device_t cbdev, device_t child);
126
127
128 #define MAKETUPLE(NAME,FUNC) { CISTPL_ ## NAME, #NAME, decode_tuple_ ## FUNC }
129
130 static char *funcnames[] = {
131 "Multi-Functioned",
132 "Memory",
133 "Serial Port",
134 "Parallel Port",
135 "Fixed Disk",
136 "Video Adaptor",
137 "Network Adaptor",
138 "AIMS",
139 "SCSI",
140 "Security"
141 };
142
143 /*
144 * Handler functions for various CIS tuples
145 */
146
147 static int
148 decode_tuple_generic(device_t cbdev, device_t child, int id,
149 int len, uint8_t *tupledata, uint32_t start, uint32_t *off,
150 struct tuple_callbacks *info)
151 {
152 int i;
153
154 if (cardbus_cis_debug) {
155 if (info)
156 printf("TUPLE: %s [%d]:", info->name, len);
157 else
158 printf("TUPLE: Unknown(0x%02x) [%d]:", id, len);
159
160 for (i = 0; i < len; i++) {
161 if (i % 0x10 == 0 && len > 0x10)
162 printf("\n 0x%02x:", i);
163 printf(" %02x", tupledata[i]);
164 }
165 printf("\n");
166 }
167 return (0);
168 }
169
170 static int
171 decode_tuple_linktarget(device_t cbdev, device_t child, int id,
172 int len, uint8_t *tupledata, uint32_t start, uint32_t *off,
173 struct tuple_callbacks *info)
174 {
175 int i;
176
177 if (cardbus_cis_debug) {
178 printf("TUPLE: %s [%d]:", info->name, len);
179
180 for (i = 0; i < len; i++) {
181 if (i % 0x10 == 0 && len > 0x10)
182 printf("\n 0x%02x:", i);
183 printf(" %02x", tupledata[i]);
184 }
185 printf("\n");
186 }
187 if (len != 3 || tupledata[0] != 'C' || tupledata[1] != 'I' ||
188 tupledata[2] != 'S') {
189 printf("Invalid data for CIS Link Target!\n");
190 decode_tuple_generic(cbdev, child, id, len, tupledata,
191 start, off, info);
192 return (EINVAL);
193 }
194 return (0);
195 }
196
197 static int
198 decode_tuple_vers_1(device_t cbdev, device_t child, int id,
199 int len, uint8_t *tupledata, uint32_t start, uint32_t *off,
200 struct tuple_callbacks *info)
201 {
202 int i;
203
204 if (cardbus_cis_debug) {
205 printf("Product version: %d.%d\n", tupledata[0], tupledata[1]);
206 printf("Product name: ");
207 for (i = 2; i < len; i++) {
208 if (tupledata[i] == '\0')
209 printf(" | ");
210 else if (tupledata[i] == 0xff)
211 break;
212 else
213 printf("%c", tupledata[i]);
214 }
215 printf("\n");
216 }
217 return (0);
218 }
219
220 static int
221 decode_tuple_funcid(device_t cbdev, device_t child, int id,
222 int len, uint8_t *tupledata, uint32_t start, uint32_t *off,
223 struct tuple_callbacks *info)
224 {
225 struct cardbus_devinfo *dinfo = device_get_ivars(child);
226 int numnames = sizeof(funcnames) / sizeof(funcnames[0]);
227 int i;
228
229 if (cardbus_cis_debug) {
230 printf("Functions: ");
231 for (i = 0; i < len; i++) {
232 if (tupledata[i] < numnames)
233 printf("%s", funcnames[tupledata[i]]);
234 else
235 printf("Unknown(%d)", tupledata[i]);
236 if (i < len-1)
237 printf(", ");
238 }
239 printf("\n");
240 }
241 if (len > 0)
242 dinfo->funcid = tupledata[0]; /* use first in list */
243 return (0);
244 }
245
246 static int
247 decode_tuple_manfid(device_t cbdev, device_t child, int id,
248 int len, uint8_t *tupledata, uint32_t start, uint32_t *off,
249 struct tuple_callbacks *info)
250 {
251 struct cardbus_devinfo *dinfo = device_get_ivars(child);
252 int i;
253
254 if (cardbus_cis_debug) {
255 printf("Manufacturer ID: ");
256 for (i = 0; i < len; i++)
257 printf("%02x", tupledata[i]);
258 printf("\n");
259 }
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 static int
269 decode_tuple_funce(device_t cbdev, device_t child, int id,
270 int len, uint8_t *tupledata, uint32_t start, uint32_t *off,
271 struct tuple_callbacks *info)
272 {
273 struct cardbus_devinfo *dinfo = device_get_ivars(child);
274 int type, i;
275
276 if (cardbus_cis_debug) {
277 printf("Function Extension: ");
278 for (i = 0; i < len; i++)
279 printf("%02x", tupledata[i]);
280 printf("\n");
281 }
282 if (len < 2) /* too short */
283 return (0);
284 type = tupledata[0]; /* XXX <32 always? */
285 switch (dinfo->funcid) {
286 case TPL_FUNC_SERIAL:
287 if (type == TPL_FUNCE_SER_UART) { /* NB: len known > 1 */
288 dinfo->funce.sio.type = tupledata[1] & 0x1f;
289 }
290 dinfo->fepresent |= 1<<type;
291 break;
292 case TPL_FUNC_LAN:
293 switch (type) {
294 case TPL_FUNCE_LAN_TECH:
295 dinfo->funce.lan.tech = tupledata[1]; /* XXX mask? */
296 break;
297 #if 0
298 case TPL_FUNCE_LAN_SPEED:
299 for (i = 0; i < 3; i++) {
300 if (dinfo->funce.lan.speed[i] == 0) {
301 if (len > 4) {
302 dinfo->funce.lan.speed[i] =
303 ...;
304 }
305 break;
306 }
307 }
308 break;
309 #endif
310 case TPL_FUNCE_LAN_MEDIA:
311 for (i = 0; i < 4 && dinfo->funce.lan.media[i]; i++) {
312 if (dinfo->funce.lan.media[i] == 0) {
313 /* NB: len known > 1 */
314 dinfo->funce.lan.media[i] =
315 tupledata[1]; /*XXX? mask */
316 break;
317 }
318 }
319 break;
320 case TPL_FUNCE_LAN_NID:
321 if (tupledata[1] > sizeof(dinfo->funce.lan.nid)) {
322 /* ignore, warning? */
323 return (0);
324 }
325 bcopy(tupledata + 2, dinfo->funce.lan.nid,
326 tupledata[1]);
327 break;
328 case TPL_FUNCE_LAN_CONN:
329 dinfo->funce.lan.contype = tupledata[1];/*XXX mask? */
330 break;
331 }
332 dinfo->fepresent |= 1<<type;
333 break;
334 }
335 return (0);
336 }
337
338 static int
339 decode_tuple_bar(device_t cbdev, device_t child, int id,
340 int len, uint8_t *tupledata, uint32_t start, uint32_t *off,
341 struct tuple_callbacks *info)
342 {
343 struct cardbus_devinfo *dinfo = device_get_ivars(child);
344 int type;
345 uint8_t reg;
346 uint32_t bar, pci_bar;
347
348 if (len != 6) {
349 device_printf(cbdev, "CIS BAR length not 6 (%d)\n", len);
350 return (EINVAL);
351 }
352
353 reg = *tupledata;
354 len = le32toh(*(uint32_t*)(tupledata + 2));
355 if (reg & TPL_BAR_REG_AS) {
356 type = SYS_RES_IOPORT;
357 } else {
358 type = SYS_RES_MEMORY;
359 }
360
361 bar = reg & TPL_BAR_REG_ASI_MASK;
362 if (bar == 0) {
363 device_printf(cbdev, "Invalid BAR type 0 in CIS\n");
364 return (EINVAL); /* XXX Return an error? */
365 } else if (bar == 7) {
366 /* XXX Should we try to map in Option ROMs? */
367 return (0);
368 }
369
370 /* Convert from BAR type to BAR offset */
371 bar = CARDBUS_BASE0_REG + (bar - 1) * 4;
372
373 if (type == SYS_RES_MEMORY) {
374 if (reg & TPL_BAR_REG_PREFETCHABLE)
375 dinfo->mprefetchable |= BARBIT(bar);
376 #if 0
377 /*
378 * XXX: It appears from a careful reading of the spec
379 * that we're not supposed to honor this when the bridge
380 * is not on the main system bus. PCI spec doesn't appear
381 * to allow for memory ranges not listed in the bridge's
382 * decode range to be decoded. The PC Card spec seems to
383 * indicate that this should only be done on x86 based
384 * machines, which seems to imply that on non-x86 machines
385 * the adddresses can be anywhere. This further implies that
386 * since the hardware can do it on non-x86 machines, it should
387 * be able to do it on x86 machines. Therefore, we can and
388 * should ignore this hint. Furthermore, the PC Card spec
389 * recommends always allocating memory above 1MB, contradicting
390 * the other part of the PC Card spec.
391 *
392 * NetBSD ignores this bit, but it also ignores the
393 * prefetchable bit too, so that's not an indication of
394 * correctness.
395 */
396 if (reg & TPL_BAR_REG_BELOW1MB)
397 dinfo->mbelow1mb |= BARBIT(bar);
398 #endif
399 }
400
401 /*
402 * Sanity check the BAR length reported in the CIS with the length
403 * encoded in the PCI BAR. The latter seems to be more reliable.
404 * XXX - This probably belongs elsewhere.
405 */
406 pci_write_config(child, bar, 0xffffffff, 4);
407 pci_bar = pci_read_config(child, bar, 4);
408 if ((pci_bar != 0x0) && (pci_bar != 0xffffffff)) {
409 if (type == SYS_RES_MEMORY) {
410 pci_bar &= ~0xf;
411 } else {
412 pci_bar &= ~0x3;
413 }
414 len = 1 << (ffs(pci_bar) - 1);
415 }
416
417 DEVPRINTF((cbdev, "Opening BAR: type=%s, bar=%02x, len=%04x%s%s\n",
418 (type == SYS_RES_MEMORY) ? "MEM" : "IO", bar, len,
419 (type == SYS_RES_MEMORY && dinfo->mprefetchable & BARBIT(bar)) ?
420 " (Prefetchable)" : "", type == SYS_RES_MEMORY ?
421 ((dinfo->mbelow1mb & BARBIT(bar)) ? " (Below 1Mb)" : "") : ""));
422
423 resource_list_add(&dinfo->pci.resources, type, bar, 0UL, ~0UL, len);
424
425 /*
426 * Mark the appropriate bit in the PCI command register so that
427 * device drivers will know which type of BARs can be used.
428 */
429 pci_enable_io(child, type);
430 return (0);
431 }
432
433 static int
434 decode_tuple_unhandled(device_t cbdev, device_t child, int id,
435 int len, uint8_t *tupledata, uint32_t start, uint32_t *off,
436 struct tuple_callbacks *info)
437 {
438 /* Make this message suck less XXX */
439 printf("TUPLE: %s [%d] is unhandled! Bailing...", info->name, len);
440 return (-1);
441 }
442
443 static int
444 decode_tuple_end(device_t cbdev, device_t child, int id,
445 int len, uint8_t *tupledata, uint32_t start, uint32_t *off,
446 struct tuple_callbacks *info)
447 {
448 if (cardbus_cis_debug) {
449 printf("CIS reading done\n");
450 }
451 return (0);
452 }
453
454 /*
455 * Functions to read the a tuple from the card
456 */
457
458 static int
459 cardbus_read_tuple_conf(device_t cbdev, device_t child, uint32_t start,
460 uint32_t *off, int *tupleid, int *len, uint8_t *tupledata)
461 {
462 int i, j;
463 uint32_t e;
464 uint32_t loc;
465
466 loc = start + *off;
467
468 e = pci_read_config(child, loc - loc % 4, 4);
469 for (j = loc % 4; j > 0; j--)
470 e >>= 8;
471 *len = 0;
472 for (i = loc, j = -2; j < *len; j++, i++) {
473 if (i % 4 == 0)
474 e = pci_read_config(child, i, 4);
475 if (j == -2)
476 *tupleid = 0xff & e;
477 else if (j == -1)
478 *len = 0xff & e;
479 else
480 tupledata[j] = 0xff & e;
481 e >>= 8;
482 }
483 *off += *len + 2;
484 return (0);
485 }
486
487 static int
488 cardbus_read_tuple_mem(device_t cbdev, struct resource *res, uint32_t start,
489 uint32_t *off, int *tupleid, int *len, uint8_t *tupledata)
490 {
491 bus_space_tag_t bt;
492 bus_space_handle_t bh;
493 int ret;
494
495 bt = rman_get_bustag(res);
496 bh = rman_get_bushandle(res);
497
498 *tupleid = bus_space_read_1(bt, bh, start + *off);
499 *len = bus_space_read_1(bt, bh, start + *off + 1);
500 bus_space_read_region_1(bt, bh, *off + start + 2, tupledata, *len);
501 ret = 0;
502 *off += *len + 2;
503 return (ret);
504 }
505
506 static int
507 cardbus_read_tuple(device_t cbdev, device_t child, struct resource *res,
508 uint32_t start, uint32_t *off, int *tupleid, int *len,
509 uint8_t *tupledata)
510 {
511 if (res == (struct resource*)~0UL) {
512 return (cardbus_read_tuple_conf(cbdev, child, start, off,
513 tupleid, len, tupledata));
514 } else {
515 return (cardbus_read_tuple_mem(cbdev, res, start, off,
516 tupleid, len, tupledata));
517 }
518 }
519
520 static void
521 cardbus_read_tuple_finish(device_t cbdev, device_t child, int rid,
522 struct resource *res)
523 {
524 if (res != (struct resource*)~0UL) {
525 bus_release_resource(cbdev, SYS_RES_MEMORY, rid, res);
526 pci_write_config(child, rid, 0, 4);
527 PCI_DISABLE_IO(cbdev, child, SYS_RES_MEMORY);
528 }
529 }
530
531 static struct resource *
532 cardbus_read_tuple_init(device_t cbdev, device_t child, uint32_t *start,
533 int *rid)
534 {
535 uint32_t testval;
536 uint32_t size;
537 struct resource *res;
538
539 switch (CARDBUS_CIS_SPACE(*start)) {
540 case CARDBUS_CIS_ASI_TUPLE:
541 /* CIS in PCI config space need no initialization */
542 return ((struct resource*)~0UL);
543 case CARDBUS_CIS_ASI_BAR0:
544 case CARDBUS_CIS_ASI_BAR1:
545 case CARDBUS_CIS_ASI_BAR2:
546 case CARDBUS_CIS_ASI_BAR3:
547 case CARDBUS_CIS_ASI_BAR4:
548 case CARDBUS_CIS_ASI_BAR5:
549 *rid = CARDBUS_BASE0_REG + (CARDBUS_CIS_SPACE(*start) - 1) * 4;
550 break;
551 case CARDBUS_CIS_ASI_ROM:
552 *rid = CARDBUS_ROM_REG;
553 #if 0
554 /*
555 * This mask doesn't contain the bit that actually enables
556 * the Option ROM.
557 */
558 pci_write_config(child, *rid, CARDBUS_ROM_ADDRMASK, 4);
559 #endif
560 break;
561 default:
562 device_printf(cbdev, "Unable to read CIS: Unknown space: %d\n",
563 CARDBUS_CIS_SPACE(*start));
564 return (NULL);
565 }
566
567 /* figure out how much space we need */
568 pci_write_config(child, *rid, 0xffffffff, 4);
569 testval = pci_read_config(child, *rid, 4);
570
571 /*
572 * This bit has a different meaning depending if we are dealing
573 * with a normal BAR or an Option ROM BAR.
574 */
575 if (((testval & 0x1) == 0x1) && (*rid != CARDBUS_ROM_REG)) {
576 device_printf(cbdev, "CIS Space is IO, expecting memory.\n");
577 return (NULL);
578 }
579
580 size = CARDBUS_MAPREG_MEM_SIZE(testval);
581 /* XXX Is this some kind of hack? */
582 if (size < 4096)
583 size = 4096;
584 /* allocate the memory space to read CIS */
585 res = bus_alloc_resource(cbdev, SYS_RES_MEMORY, rid, 0, ~0, size,
586 rman_make_alignment_flags(size) | RF_ACTIVE);
587 if (res == NULL) {
588 device_printf(cbdev, "Unable to allocate resource "
589 "to read CIS.\n");
590 return (NULL);
591 }
592 pci_write_config(child, *rid,
593 rman_get_start(res) | ((*rid == CARDBUS_ROM_REG)?
594 CARDBUS_ROM_ENABLE : 0),
595 4);
596 PCI_ENABLE_IO(cbdev, child, SYS_RES_MEMORY);
597
598 /* Flip to the right ROM image if CIS is in ROM */
599 if (CARDBUS_CIS_SPACE(*start) == CARDBUS_CIS_ASI_ROM) {
600 bus_space_tag_t bt;
601 bus_space_handle_t bh;
602 uint32_t imagesize;
603 uint32_t imagebase = 0;
604 uint32_t pcidata;
605 uint16_t romsig;
606 int romnum = 0;
607 int imagenum;
608
609 bt = rman_get_bustag(res);
610 bh = rman_get_bushandle(res);
611
612 imagenum = CARDBUS_CIS_ASI_ROM_IMAGE(*start);
613 for (romnum = 0;; romnum++) {
614 romsig = bus_space_read_2(bt, bh,
615 imagebase + CARDBUS_EXROM_SIGNATURE);
616 if (romsig != 0xaa55) {
617 device_printf(cbdev, "Bad header in rom %d: "
618 "[%x] %04x\n", romnum, imagebase +
619 CARDBUS_EXROM_SIGNATURE, romsig);
620 bus_release_resource(cbdev, SYS_RES_MEMORY,
621 *rid, res);
622 *rid = 0;
623 return (NULL);
624 }
625
626 /*
627 * If this was the Option ROM image that we were
628 * looking for, then we are done.
629 */
630 if (romnum == imagenum)
631 break;
632
633 /* Find out where the next Option ROM image is */
634 pcidata = imagebase + bus_space_read_2(bt, bh,
635 imagebase + CARDBUS_EXROM_DATA_PTR);
636 imagesize = bus_space_read_2(bt, bh,
637 pcidata + CARDBUS_EXROM_DATA_IMAGE_LENGTH);
638
639 if (imagesize == 0) {
640 /*
641 * XXX some ROMs seem to have this as zero,
642 * can we assume this means 1 block?
643 */
644 device_printf(cbdev, "Warning, size of Option "
645 "ROM image %d is 0 bytes, assuming 512 "
646 "bytes.\n", romnum);
647 imagesize = 1;
648 }
649
650 /* Image size is in 512 byte units */
651 imagesize <<= 9;
652
653 if ((bus_space_read_1(bt, bh, pcidata +
654 CARDBUS_EXROM_DATA_INDICATOR) & 0x80) != 0) {
655 device_printf(cbdev, "Cannot find CIS in "
656 "Option ROM\n");
657 bus_release_resource(cbdev, SYS_RES_MEMORY,
658 *rid, res);
659 *rid = 0;
660 return (NULL);
661 }
662 imagebase += imagesize;
663 }
664 *start = imagebase + CARDBUS_CIS_ADDR(*start);
665 } else {
666 *start = CARDBUS_CIS_ADDR(*start);
667 }
668
669 return (res);
670 }
671
672 /*
673 * Dispatch the right handler function per tuple
674 */
675
676 static int
677 decode_tuple(device_t cbdev, device_t child, int tupleid, int len,
678 uint8_t *tupledata, uint32_t start, uint32_t *off,
679 struct tuple_callbacks *callbacks)
680 {
681 int i;
682 for (i = 0; callbacks[i].id != CISTPL_GENERIC; i++) {
683 if (tupleid == callbacks[i].id)
684 return (callbacks[i].func(cbdev, child, tupleid, len,
685 tupledata, start, off, &callbacks[i]));
686 }
687 return (callbacks[i].func(cbdev, child, tupleid, len,
688 tupledata, start, off, NULL));
689 }
690
691 static int
692 cardbus_parse_cis(device_t cbdev, device_t child,
693 struct tuple_callbacks *callbacks)
694 {
695 uint8_t tupledata[MAXTUPLESIZE];
696 int tupleid;
697 int len;
698 int expect_linktarget;
699 uint32_t start, off;
700 struct resource *res;
701 int rid;
702
703 bzero(tupledata, MAXTUPLESIZE);
704 expect_linktarget = TRUE;
705 if ((start = pci_read_config(child, CARDBUS_CIS_REG, 4)) == 0)
706 return (ENXIO);
707 off = 0;
708 res = cardbus_read_tuple_init(cbdev, child, &start, &rid);
709 if (res == NULL)
710 return (ENXIO);
711
712 do {
713 if (0 != cardbus_read_tuple(cbdev, child, res, start, &off,
714 &tupleid, &len, tupledata)) {
715 device_printf(cbdev, "Failed to read CIS.\n");
716 cardbus_read_tuple_finish(cbdev, child, rid, res);
717 return (ENXIO);
718 }
719
720 if (expect_linktarget && tupleid != CISTPL_LINKTARGET) {
721 device_printf(cbdev, "Expecting link target, got 0x%x\n",
722 tupleid);
723 cardbus_read_tuple_finish(cbdev, child, rid, res);
724 return (EINVAL);
725 }
726 expect_linktarget = decode_tuple(cbdev, child, tupleid, len,
727 tupledata, start, &off, callbacks);
728 if (expect_linktarget != 0) {
729 cardbus_read_tuple_finish(cbdev, child, rid, res);
730 return (expect_linktarget);
731 }
732 } while (tupleid != CISTPL_END);
733 cardbus_read_tuple_finish(cbdev, child, rid, res);
734 return (0);
735 }
736
737 static void
738 cardbus_do_res(struct resource_list_entry *rle, device_t child, uint32_t start)
739 {
740 rle->start = start;
741 rle->end = start + rle->count - 1;
742 pci_write_config(child, rle->rid, rle->start, 4);
743 }
744
745 static int
746 barsort(const void *a, const void *b)
747 {
748 return ((*(const struct resource_list_entry * const *)b)->count -
749 (*(const struct resource_list_entry * const *)a)->count);
750 }
751
752 static int
753 cardbus_alloc_resources(device_t cbdev, device_t child)
754 {
755 struct cardbus_devinfo *dinfo = device_get_ivars(child);
756 int count;
757 struct resource_list_entry *rle;
758 struct resource_list_entry **barlist;
759 int tmp;
760 uint32_t mem_psize = 0, mem_nsize = 0, io_size = 0;
761 struct resource *res;
762 uint32_t start,end;
763 int rid, flags;
764
765 count = 0;
766 SLIST_FOREACH(rle, &dinfo->pci.resources, link) {
767 count++;
768 }
769 if (count == 0)
770 return (0);
771 barlist = malloc(sizeof(struct resource_list_entry*) * count, M_DEVBUF,
772 M_WAITOK);
773 count = 0;
774 SLIST_FOREACH(rle, &dinfo->pci.resources, link) {
775 barlist[count] = rle;
776 if (rle->type == SYS_RES_IOPORT) {
777 io_size += rle->count;
778 } else if (rle->type == SYS_RES_MEMORY) {
779 if (dinfo->mprefetchable & BARBIT(rle->rid))
780 mem_psize += rle->count;
781 else
782 mem_nsize += rle->count;
783 }
784 count++;
785 }
786
787 /*
788 * We want to allocate the largest resource first, so that our
789 * allocated memory is packed.
790 */
791 qsort(barlist, count, sizeof(struct resource_list_entry*), barsort);
792
793 /* Allocate prefetchable memory */
794 flags = 0;
795 for (tmp = 0; tmp < count; tmp++) {
796 rle = barlist[tmp];
797 if (rle->res == NULL &&
798 rle->type == SYS_RES_MEMORY &&
799 dinfo->mprefetchable & BARBIT(rle->rid)) {
800 flags = rman_make_alignment_flags(rle->count);
801 break;
802 }
803 }
804 if (flags > 0) { /* If any 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_psize, flags);
817 if (res == NULL) {
818 device_printf(cbdev,
819 "Can't get memory for prefetch mem\n");
820 free(barlist, M_DEVBUF);
821 return (EIO);
822 }
823 start = rman_get_start(res);
824 end = rman_get_end(res);
825 DEVPRINTF((cbdev, "Prefetchable memory at %x-%x\n", start, end));
826 /*
827 * Now that we know the region is free, release it and hand it
828 * out piece by piece.
829 */
830 bus_release_resource(cbdev, SYS_RES_MEMORY, rid, res);
831 for (tmp = 0; tmp < count; tmp++) {
832 rle = barlist[tmp];
833 if (rle->type == SYS_RES_MEMORY &&
834 dinfo->mprefetchable & BARBIT(rle->rid)) {
835 cardbus_do_res(rle, child, start);
836 start += rle->count;
837 }
838 }
839 }
840
841 /* Allocate non-prefetchable memory */
842 flags = 0;
843 for (tmp = 0; tmp < count; tmp++) {
844 rle = barlist[tmp];
845 if (rle->type == SYS_RES_MEMORY &&
846 (dinfo->mprefetchable & BARBIT(rle->rid)) == 0) {
847 flags = rman_make_alignment_flags(rle->count);
848 break;
849 }
850 }
851 if (flags > 0) { /* If any non-prefetchable memory is requested... */
852 /*
853 * First we allocate one big space for all resources of this
854 * type. We do this because our parent, pccbb, needs to open
855 * a window to forward all addresses within the window, and
856 * it would be best if nobody else has resources allocated
857 * within the window.
858 * (XXX: Perhaps there might be a better way to do this?)
859 */
860 rid = 0;
861 res = bus_alloc_resource(cbdev, SYS_RES_MEMORY, &rid, 0,
862 ((~dinfo->mprefetchable) & dinfo->mbelow1mb)?0xFFFFF:~0UL,
863 mem_nsize, flags);
864 if (res == NULL) {
865 device_printf(cbdev,
866 "Can't get memory for non-prefetch mem\n");
867 free(barlist, M_DEVBUF);
868 return (EIO);
869 }
870 start = rman_get_start(res);
871 end = rman_get_end(res);
872 DEVPRINTF((cbdev, "Non-prefetchable memory at %x-%x\n",
873 start, end));
874 /*
875 * Now that we know the region is free, release it and hand it
876 * out piece by piece.
877 */
878 bus_release_resource(cbdev, SYS_RES_MEMORY, rid, res);
879 for (tmp = 0; tmp < count; tmp++) {
880 rle = barlist[tmp];
881 if (rle->type == SYS_RES_MEMORY &&
882 (dinfo->mprefetchable & BARBIT(rle->rid)) == 0) {
883 cardbus_do_res(rle, child, start);
884 start += rle->count;
885 }
886 }
887 }
888
889 /* Allocate IO ports */
890 flags = 0;
891 for (tmp = 0; tmp < count; tmp++) {
892 rle = barlist[tmp];
893 if (rle->type == SYS_RES_IOPORT) {
894 flags = rman_make_alignment_flags(rle->count);
895 break;
896 }
897 }
898 if (flags > 0) { /* If any IO port is requested... */
899 /*
900 * First we allocate one big space for all resources of this
901 * type. We do this because our parent, pccbb, needs to open
902 * a window to forward all addresses within the window, and
903 * it would be best if nobody else has resources allocated
904 * within the window.
905 * (XXX: Perhaps there might be a better way to do this?)
906 */
907 rid = 0;
908 res = bus_alloc_resource(cbdev, SYS_RES_IOPORT, &rid, 0,
909 (dinfo->ibelow1mb)?0xFFFFF:~0UL, io_size, flags);
910 if (res == NULL) {
911 device_printf(cbdev,
912 "Can't get memory for IO ports\n");
913 free(barlist, M_DEVBUF);
914 return (EIO);
915 }
916 start = rman_get_start(res);
917 end = rman_get_end(res);
918 DEVPRINTF((cbdev, "IO port at %x-%x\n", start, end));
919 /*
920 * Now that we know the region is free, release it and hand it
921 * out piece by piece.
922 */
923 bus_release_resource(cbdev, SYS_RES_IOPORT, rid, res);
924 for (tmp = 0; tmp < count; tmp++) {
925 rle = barlist[tmp];
926 if (rle->type == SYS_RES_IOPORT) {
927 cardbus_do_res(rle, child, start);
928 start += rle->count;
929 }
930 }
931 }
932
933 /* Allocate IRQ */
934 rid = 0;
935 res = bus_alloc_resource_any(cbdev, SYS_RES_IRQ, &rid, RF_SHAREABLE);
936 if (res == NULL) {
937 device_printf(cbdev, "Can't get memory for irq\n");
938 free(barlist, M_DEVBUF);
939 return (EIO);
940 }
941 start = rman_get_start(res);
942 end = rman_get_end(res);
943 bus_release_resource(cbdev, SYS_RES_IRQ, rid, res);
944 resource_list_add(&dinfo->pci.resources, SYS_RES_IRQ, rid, start, end,
945 1);
946 dinfo->pci.cfg.intline = rman_get_start(res);
947 pci_write_config(child, PCIR_INTLINE, rman_get_start(res), 1);
948
949 free(barlist, M_DEVBUF);
950 return (0);
951 }
952
953 /*
954 * Adding a memory/io resource (sans CIS)
955 */
956
957 static void
958 cardbus_add_map(device_t cbdev, device_t child, int reg)
959 {
960 struct cardbus_devinfo *dinfo = device_get_ivars(child);
961 struct resource_list_entry *rle;
962 uint32_t size;
963 uint32_t testval;
964 int type;
965
966 SLIST_FOREACH(rle, &dinfo->pci.resources, link) {
967 if (rle->rid == reg)
968 return;
969 }
970
971 if (reg == CARDBUS_ROM_REG)
972 testval = CARDBUS_ROM_ADDRMASK;
973 else
974 testval = ~0;
975
976 pci_write_config(child, reg, testval, 4);
977 testval = pci_read_config(child, reg, 4);
978
979 if (testval == ~0 || testval == 0)
980 return;
981
982 if ((testval & 1) == 0)
983 type = SYS_RES_MEMORY;
984 else
985 type = SYS_RES_IOPORT;
986
987 size = CARDBUS_MAPREG_MEM_SIZE(testval);
988 device_printf(cbdev, "Resource not specified in CIS: id=%x, size=%x\n",
989 reg, size);
990 resource_list_add(&dinfo->pci.resources, type, reg, 0UL, ~0UL, size);
991 }
992
993 static void
994 cardbus_pickup_maps(device_t cbdev, device_t child)
995 {
996 struct cardbus_devinfo *dinfo = device_get_ivars(child);
997 int reg;
998
999 /*
1000 * Try to pick up any resources that was not specified in CIS.
1001 * Maybe this isn't any longer necessary now that we have fixed
1002 * CIS parsing and we should filter things here? XXX
1003 */
1004 for (reg = 0; reg < dinfo->pci.cfg.nummaps; reg++)
1005 cardbus_add_map(cbdev, child, PCIR_BAR(reg));
1006 }
1007
1008 int
1009 cardbus_do_cis(device_t cbdev, device_t child)
1010 {
1011 int ret;
1012 struct tuple_callbacks init_callbacks[] = {
1013 MAKETUPLE(LONGLINK_CB, unhandled),
1014 MAKETUPLE(INDIRECT, unhandled),
1015 MAKETUPLE(LONGLINK_MFC, unhandled),
1016 MAKETUPLE(BAR, bar),
1017 MAKETUPLE(LONGLINK_A, unhandled),
1018 MAKETUPLE(LONGLINK_C, unhandled),
1019 MAKETUPLE(LINKTARGET, linktarget),
1020 MAKETUPLE(VERS_1, vers_1),
1021 MAKETUPLE(MANFID, manfid),
1022 MAKETUPLE(FUNCID, funcid),
1023 MAKETUPLE(FUNCE, funce),
1024 MAKETUPLE(END, end),
1025 MAKETUPLE(GENERIC, generic),
1026 };
1027
1028 ret = cardbus_parse_cis(cbdev, child, init_callbacks);
1029 if (ret < 0)
1030 return (ret);
1031 cardbus_pickup_maps(cbdev, child);
1032 return (cardbus_alloc_resources(cbdev, child));
1033 }
Cache object: 66489b1af72dfcf90f2ac56f3b3f802c
|