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