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