Merge from vendor branch FILE:
[dragonfly.git] / sys / dev / pccard / cardbus / cardbus.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.c,v 1.28 2002/11/27 17:30:41 imp Exp $
29  * $DragonFly: src/sys/dev/pccard/cardbus/cardbus.c,v 1.5 2005/05/24 20:59:03 dillon Exp $
30  */
31
32 /*
33  * Cardbus Bus Driver
34  *
35  * much of the bus code was stolen directly from sys/pci/pci.c
36  *   (Copyright (c) 1997, Stefan Esser <se@freebsd.org>)
37  *
38  * Written by Jonathan Chen <jon@freebsd.org>
39  */
40
41 #include <sys/param.h>
42 #include <sys/systm.h>
43 #include <sys/malloc.h>
44 #include <sys/kernel.h>
45 #include <sys/sysctl.h>
46
47 #include <sys/bus.h>
48 #include <machine/bus.h>
49 #include <sys/rman.h>
50 #include <machine/resource.h>
51
52 #include <sys/pciio.h>
53 #include <bus/pci/pcivar.h>
54 #include <bus/pci/pcireg.h>
55 #include <bus/pci/pci_private.h>
56
57 #include <dev/pccard/cardbus/cardbusreg.h>
58 #include <dev/pccard/cardbus/cardbusvar.h>
59 #include <dev/pccard/cardbus/cardbus_cis.h>
60 #include <bus/pccard/pccardvar.h>
61
62 #include "power_if.h"
63 #include "pcib_if.h"
64
65 /* sysctl vars */
66 SYSCTL_NODE(_hw, OID_AUTO, cardbus, CTLFLAG_RD, 0, "CardBus parameters");
67
68 int    cardbus_debug = 0;
69 TUNABLE_INT("hw.cardbus.debug", &cardbus_debug);
70 SYSCTL_INT(_hw_cardbus, OID_AUTO, debug, CTLFLAG_RW,
71     &cardbus_debug, 0,
72   "CardBus debug");
73
74 int    cardbus_cis_debug = 0;
75 TUNABLE_INT("hw.cardbus.cis_debug", &cardbus_cis_debug);
76 SYSCTL_INT(_hw_cardbus, OID_AUTO, cis_debug, CTLFLAG_RW,
77     &cardbus_cis_debug, 0,
78   "CardBus CIS debug");
79
80 #define DPRINTF(a) if (cardbus_debug) printf a
81 #define DEVPRINTF(x) if (cardbus_debug) device_printf x
82
83
84 static struct resource  *cardbus_alloc_resource(device_t cbdev, device_t child,
85                     int type, int *rid, u_long start, u_long end, u_long count,
86                     u_int flags);
87 static int      cardbus_attach(device_t cbdev);
88 static int      cardbus_attach_card(device_t cbdev);
89 static int      cardbus_child_location_str(device_t cbdev, device_t child,
90                     char *, size_t len);
91 static int      cardbus_child_pnpinfo_str(device_t cbdev, device_t child,
92                     char *, size_t len);
93 static __inline void cardbus_clear_command_bit(device_t cbdev, device_t child,
94                     u_int16_t bit);
95 static void     cardbus_delete_resource(device_t cbdev, device_t child,
96                     int type, int rid);
97 static void     cardbus_delete_resource_method(device_t cbdev, device_t child,
98                     int type, int rid);
99 static int      cardbus_detach(device_t cbdev);
100 static int      cardbus_detach_card(device_t cbdev);
101 static void     cardbus_device_setup_regs(device_t brdev, int b, int s, int f,
102                     pcicfgregs *cfg);
103 static void     cardbus_disable_busmaster_method(device_t cbdev, device_t child);
104 static void     cardbus_disable_io_method(device_t cbdev, device_t child,
105                     int space);
106 static void     cardbus_driver_added(device_t cbdev, driver_t *driver);
107 static void     cardbus_enable_busmaster_method(device_t cbdev, device_t child);
108 static void     cardbus_enable_io_method(device_t cbdev, device_t child,
109                     int space);
110 static int      cardbus_freecfg(struct cardbus_devinfo *dinfo);
111 static int      cardbus_get_powerstate_method(device_t cbdev, device_t child);
112 static int      cardbus_get_resource(device_t cbdev, device_t child, int type,
113                     int rid, u_long *startp, u_long *countp);
114 static int      cardbus_get_resource_method(device_t cbdev, device_t child,
115                     int type, int rid, u_long *startp, u_long *countp);
116 static void     cardbus_hdrtypedata(device_t brdev, int b, int s, int f,
117                     pcicfgregs *cfg);
118 static int      cardbus_print_child(device_t cbdev, device_t child);
119 static int      cardbus_print_resources(struct resource_list *rl,
120                     const char *name, int type, const char *format);
121 static void     cardbus_print_verbose(struct cardbus_devinfo *dinfo);
122 static int      cardbus_probe(device_t cbdev);
123 static void     cardbus_probe_nomatch(device_t cbdev, device_t child);
124 static struct cardbus_devinfo   *cardbus_read_device(device_t brdev, int b,
125                     int s, int f);
126 static void     cardbus_read_extcap(device_t cbdev, pcicfgregs *cfg);
127 static u_int32_t cardbus_read_config_method(device_t cbdev,
128                     device_t child, int reg, int width);
129 static int      cardbus_read_ivar(device_t cbdev, device_t child, int which,
130                     u_long *result);
131 static void     cardbus_release_all_resources(device_t cbdev,
132                     struct cardbus_devinfo *dinfo);
133 static int      cardbus_release_resource(device_t cbdev, device_t child,
134                     int type, int rid, struct resource *r);
135 static __inline void cardbus_set_command_bit(device_t cbdev, device_t child,
136                     u_int16_t bit);
137 static int      cardbus_set_powerstate_method(device_t cbdev, device_t child,
138                     int state);
139 static int      cardbus_set_resource(device_t cbdev, device_t child, int type,
140                     int rid, u_long start, u_long count, struct resource *res);
141 static int      cardbus_set_resource_method(device_t cbdev, device_t child,
142                     int type, int rid, u_long start, u_long count);
143 static int      cardbus_setup_intr(device_t cbdev, device_t child,
144                     struct resource *irq, int flags, driver_intr_t *intr,
145                     void *arg, void **cookiep, lwkt_serialize_t);
146 static int      cardbus_teardown_intr(device_t cbdev, device_t child,
147                     struct resource *irq, void *cookie);
148 static void     cardbus_write_config_method(device_t cbdev, device_t child,
149                     int reg, u_int32_t val, int width);
150 static int      cardbus_write_ivar(device_t cbdev, device_t child, int which,
151                     uintptr_t value);
152
153 /************************************************************************/
154 /* Probe/Attach                                                         */
155 /************************************************************************/
156
157 static int
158 cardbus_probe(device_t cbdev)
159 {
160         device_set_desc(cbdev, "CardBus bus");
161         return 0;
162 }
163
164 static int
165 cardbus_attach(device_t cbdev)
166 {
167         return 0;
168 }
169
170 static int
171 cardbus_detach(device_t cbdev)
172 {
173         cardbus_detach_card(cbdev);
174         return 0;
175 }
176
177 static int
178 cardbus_suspend(device_t self)
179 {
180         cardbus_detach_card(self);
181         return (0);
182 }
183
184 static int
185 cardbus_resume(device_t self)
186 {
187         return (0);
188 }
189
190 /************************************************************************/
191 /* Attach/Detach card                                                   */
192 /************************************************************************/
193
194 static void
195 cardbus_device_setup_regs(device_t brdev, int b, int s, int f, pcicfgregs *cfg)
196 {
197         PCIB_WRITE_CONFIG(brdev, b, s, f, PCIR_INTLINE,
198             pci_get_irq(device_get_parent(brdev)), 1);
199         cfg->intline = PCIB_READ_CONFIG(brdev, b, s, f, PCIR_INTLINE, 1);
200
201         PCIB_WRITE_CONFIG(brdev, b, s, f, PCIR_CACHELNSZ, 0x08, 1);
202         cfg->cachelnsz = PCIB_READ_CONFIG(brdev, b, s, f, PCIR_CACHELNSZ, 1);
203
204         PCIB_WRITE_CONFIG(brdev, b, s, f, PCIR_LATTIMER, 0xa8, 1);
205         cfg->lattimer = PCIB_READ_CONFIG(brdev, b, s, f, PCIR_LATTIMER, 1);
206
207         PCIB_WRITE_CONFIG(brdev, b, s, f, PCIR_MINGNT, 0x14, 1);
208         cfg->mingnt = PCIB_READ_CONFIG(brdev, b, s, f, PCIR_MINGNT, 1);
209
210         PCIB_WRITE_CONFIG(brdev, b, s, f, PCIR_MAXLAT, 0x14, 1);
211         cfg->maxlat = PCIB_READ_CONFIG(brdev, b, s, f, PCIR_MAXLAT, 1);
212 }
213
214 static int
215 cardbus_attach_card(device_t cbdev)
216 {
217         device_t brdev = device_get_parent(cbdev);
218         int cardattached = 0;
219         static int curr_bus_number = 2; /* XXX EVILE BAD (see below) */
220         int bus, slot, func;
221
222         cardbus_detach_card(cbdev); /* detach existing cards */
223
224         POWER_ENABLE_SOCKET(brdev, cbdev);
225         bus = pcib_get_bus(cbdev);
226         if (bus == 0) {
227                 /*
228                  * XXX EVILE BAD XXX
229                  * Not all BIOSes initialize the secondary bus number properly,
230                  * so if the default is bad, we just put one in and hope it
231                  * works.
232                  */
233                 bus = curr_bus_number;
234                 pci_write_config(brdev, PCIR_SECBUS_2, curr_bus_number, 1);
235                 pci_write_config(brdev, PCIR_SUBBUS_2, curr_bus_number + 2, 1);
236                 curr_bus_number += 3;
237         }
238         /* For each function, set it up and try to attach a driver to it */
239         for (slot = 0; slot <= CARDBUS_SLOTMAX; slot++) {
240                 int cardbusfunchigh = 0;
241                 for (func = 0; func <= cardbusfunchigh; func++) {
242                         struct cardbus_devinfo *dinfo =
243                             cardbus_read_device(brdev, bus, slot, func);
244
245                         if (dinfo == NULL)
246                                 continue;
247                         if (dinfo->pci.cfg.mfdev)
248                                 cardbusfunchigh = CARDBUS_FUNCMAX;
249
250                         cardbus_device_setup_regs(brdev, bus, slot, func,
251                             &dinfo->pci.cfg);
252                         cardbus_print_verbose(dinfo);
253                         dinfo->pci.cfg.dev = device_add_child(cbdev, NULL, -1);
254                         if (!dinfo->pci.cfg.dev) {
255                                 DEVPRINTF((cbdev, "Cannot add child!\n"));
256                                 cardbus_freecfg(dinfo);
257                                 continue;
258                         }
259                         resource_list_init(&dinfo->pci.resources);
260                         device_set_ivars(dinfo->pci.cfg.dev, dinfo);
261                         cardbus_do_cis(cbdev, dinfo->pci.cfg.dev);
262                         if (device_probe_and_attach(dinfo->pci.cfg.dev) != 0)
263                                 cardbus_release_all_resources(cbdev, dinfo);
264                         else
265                                 cardattached++;
266                 }
267         }
268
269         if (cardattached > 0)
270                 return (0);
271         POWER_DISABLE_SOCKET(brdev, cbdev);
272         return (ENOENT);
273 }
274
275 static int
276 cardbus_detach_card(device_t cbdev)
277 {
278         int numdevs;
279         device_t *devlist;
280         int tmp;
281         int err = 0;
282
283         device_get_children(cbdev, &devlist, &numdevs);
284
285         if (numdevs == 0) {
286                 free(devlist, M_TEMP);
287                 return (ENOENT);
288         }
289
290         for (tmp = 0; tmp < numdevs; tmp++) {
291                 struct cardbus_devinfo *dinfo = device_get_ivars(devlist[tmp]);
292                 int status = device_get_state(devlist[tmp]);
293
294                 if (dinfo->pci.cfg.dev != devlist[tmp])
295                         device_printf(cbdev, "devinfo dev mismatch\n");
296                 if (status == DS_ATTACHED || status == DS_BUSY)
297                         device_detach(devlist[tmp]);
298                 cardbus_release_all_resources(cbdev, dinfo);
299                 device_delete_child(cbdev, devlist[tmp]);
300                 cardbus_freecfg(dinfo);
301         }
302         POWER_DISABLE_SOCKET(device_get_parent(cbdev), cbdev);
303         free(devlist, M_TEMP);
304         return (err);
305 }
306
307 static void
308 cardbus_driver_added(device_t cbdev, driver_t *driver)
309 {
310         int numdevs;
311         device_t *devlist;
312         int tmp;
313         struct cardbus_devinfo *dinfo;
314
315         device_get_children(cbdev, &devlist, &numdevs);
316
317         DEVICE_IDENTIFY(driver, cbdev);
318         POWER_ENABLE_SOCKET(device_get_parent(cbdev), cbdev);
319         for (tmp = 0; tmp < numdevs; tmp++) {
320                 if (device_get_state(devlist[tmp]) == DS_NOTPRESENT) {
321                         dinfo = device_get_ivars(devlist[tmp]);
322 #ifdef notyet
323                         cardbus_device_setup_regs(brdev, bus, slot, func,
324                             &dinfo->pci.cfg);
325 #endif
326                         cardbus_print_verbose(dinfo);
327                         resource_list_init(&dinfo->pci.resources);
328                         cardbus_do_cis(cbdev, dinfo->pci.cfg.dev);
329                         if (device_probe_and_attach(dinfo->pci.cfg.dev) != 0) {
330                                 cardbus_release_all_resources(cbdev, dinfo);
331                         }
332                 }
333         }
334
335         free(devlist, M_TEMP);
336 }
337
338 /************************************************************************/
339 /* PCI-Like config reading (copied from pci.c                           */
340 /************************************************************************/
341
342 /* read configuration header into pcicfgrect structure */
343
344 static void
345 cardbus_read_extcap(device_t cbdev, pcicfgregs *cfg)
346 {
347 #define REG(n, w) PCIB_READ_CONFIG(cbdev, cfg->bus, cfg->slot, cfg->func, n, w)
348         int ptr, nextptr, ptrptr;
349
350         switch (cfg->hdrtype) {
351         case 0:
352                 ptrptr = 0x34;
353                 break;
354         case 2:
355                 ptrptr = 0x14;
356                 break;
357         default:
358                 return;         /* no extended capabilities support */
359         }
360         nextptr = REG(ptrptr, 1);       /* sanity check? */
361
362         /*
363          * Read capability entries.
364          */
365         while (nextptr != 0) {
366                 /* Sanity check */
367                 if (nextptr > 255) {
368                         printf("illegal PCI extended capability offset %d\n",
369                             nextptr);
370                         return;
371                 }
372                 /* Find the next entry */
373                 ptr = nextptr;
374                 nextptr = REG(ptr + 1, 1);
375
376                 /* Process this entry */
377                 switch (REG(ptr, 1)) {
378                 case 0x01:              /* PCI power management */
379                         if (cfg->pp_cap == 0) {
380                                 cfg->pp_cap = REG(ptr + PCIR_POWER_CAP, 2);
381                                 cfg->pp_status = ptr + PCIR_POWER_STATUS;
382                                 cfg->pp_pmcsr = ptr + PCIR_POWER_PMCSR;
383                                 if ((nextptr - ptr) > PCIR_POWER_DATA)
384                                         cfg->pp_data = ptr + PCIR_POWER_DATA;
385                         }
386                         break;
387                 default:
388                         break;
389                 }
390         }
391 #undef  REG
392 }
393
394 /* extract header type specific config data */
395
396 static void
397 cardbus_hdrtypedata(device_t brdev, int b, int s, int f, pcicfgregs *cfg)
398 {
399 #define REG(n, w)       PCIB_READ_CONFIG(brdev, b, s, f, n, w)
400         switch (cfg->hdrtype) {
401         case 0:
402                 cfg->subvendor  = REG(PCIR_SUBVEND_0, 2);
403                 cfg->subdevice  = REG(PCIR_SUBDEV_0, 2);
404                 cfg->nummaps    = PCI_MAXMAPS_0;
405                 break;
406         case 1:
407                 cfg->subvendor  = REG(PCIR_SUBVEND_1, 2);
408                 cfg->subdevice  = REG(PCIR_SUBDEV_1, 2);
409                 cfg->nummaps    = PCI_MAXMAPS_1;
410                 break;
411         case 2:
412                 cfg->subvendor  = REG(PCIR_SUBVEND_2, 2);
413                 cfg->subdevice  = REG(PCIR_SUBDEV_2, 2);
414                 cfg->nummaps    = PCI_MAXMAPS_2;
415                 break;
416         }
417 #undef  REG
418 }
419
420 static struct cardbus_devinfo *
421 cardbus_read_device(device_t brdev, int b, int s, int f)
422 {
423 #define REG(n, w)       PCIB_READ_CONFIG(brdev, b, s, f, n, w)
424         pcicfgregs *cfg = NULL;
425         struct cardbus_devinfo *devlist_entry = NULL;
426
427         if (REG(PCIR_DEVVENDOR, 4) != 0xffffffff) {
428                 devlist_entry = malloc(sizeof(struct cardbus_devinfo),
429                     M_DEVBUF, M_WAITOK | M_ZERO);
430                 if (devlist_entry == NULL)
431                         return (NULL);
432
433                 cfg = &devlist_entry->pci.cfg;
434
435                 cfg->bus                = b;
436                 cfg->slot               = s;
437                 cfg->func               = f;
438                 cfg->vendor             = REG(PCIR_VENDOR, 2);
439                 cfg->device             = REG(PCIR_DEVICE, 2);
440                 cfg->cmdreg             = REG(PCIR_COMMAND, 2);
441                 cfg->statreg            = REG(PCIR_STATUS, 2);
442                 cfg->baseclass          = REG(PCIR_CLASS, 1);
443                 cfg->subclass           = REG(PCIR_SUBCLASS, 1);
444                 cfg->progif             = REG(PCIR_PROGIF, 1);
445                 cfg->revid              = REG(PCIR_REVID, 1);
446                 cfg->hdrtype            = REG(PCIR_HDRTYPE, 1);
447                 cfg->cachelnsz          = REG(PCIR_CACHELNSZ, 1);
448                 cfg->lattimer           = REG(PCIR_LATTIMER, 1);
449                 cfg->intpin             = REG(PCIR_INTPIN, 1);
450                 cfg->intline            = REG(PCIR_INTLINE, 1);
451
452                 cfg->mingnt             = REG(PCIR_MINGNT, 1);
453                 cfg->maxlat             = REG(PCIR_MAXLAT, 1);
454
455                 cfg->mfdev              = (cfg->hdrtype & PCIM_MFDEV) != 0;
456                 cfg->hdrtype            &= ~PCIM_MFDEV;
457
458                 cardbus_hdrtypedata(brdev, b, s, f, cfg);
459
460                 if (REG(PCIR_STATUS, 2) & PCIM_STATUS_CAPPRESENT)
461                         cardbus_read_extcap(brdev, cfg);
462
463                 devlist_entry->pci.conf.pc_sel.pc_bus = cfg->bus;
464                 devlist_entry->pci.conf.pc_sel.pc_dev = cfg->slot;
465                 devlist_entry->pci.conf.pc_sel.pc_func = cfg->func;
466                 devlist_entry->pci.conf.pc_hdr = cfg->hdrtype;
467
468                 devlist_entry->pci.conf.pc_subvendor = cfg->subvendor;
469                 devlist_entry->pci.conf.pc_subdevice = cfg->subdevice;
470                 devlist_entry->pci.conf.pc_vendor = cfg->vendor;
471                 devlist_entry->pci.conf.pc_device = cfg->device;
472
473                 devlist_entry->pci.conf.pc_class = cfg->baseclass;
474                 devlist_entry->pci.conf.pc_subclass = cfg->subclass;
475                 devlist_entry->pci.conf.pc_progif = cfg->progif;
476                 devlist_entry->pci.conf.pc_revid = cfg->revid;
477         }
478         return (devlist_entry);
479 #undef  REG
480 }
481
482 /* free pcicfgregs structure and all depending data structures */
483
484 static int
485 cardbus_freecfg(struct cardbus_devinfo *dinfo)
486 {
487         free(dinfo, M_DEVBUF);
488
489         return (0);
490 }
491
492 static void
493 cardbus_print_verbose(struct cardbus_devinfo *dinfo)
494 {
495         if (bootverbose || cardbus_debug > 0)
496         {
497                 pcicfgregs *cfg = &dinfo->pci.cfg;
498
499                 printf("found->\tvendor=0x%04x, dev=0x%04x, revid=0x%02x\n",
500                     cfg->vendor, cfg->device, cfg->revid);
501                 printf("\tclass=[%s]%02x-%02x-%02x, hdrtype=0x%02x, mfdev=%d\n",
502                     pci_class_to_string(cfg->baseclass),
503                     cfg->baseclass, cfg->subclass, cfg->progif,
504                     cfg->hdrtype, cfg->mfdev);
505                 printf("\tcmdreg=0x%04x, statreg=0x%04x, "
506                     "cachelnsz=%d (dwords)\n",
507                     cfg->cmdreg, cfg->statreg, cfg->cachelnsz);
508                 printf("\tlattimer=0x%02x (%d ns), mingnt=0x%02x (%d ns), "
509                     "maxlat=0x%02x (%d ns)\n",
510                     cfg->lattimer, cfg->lattimer * 30,
511                     cfg->mingnt, cfg->mingnt * 250, cfg->maxlat,
512                     cfg->maxlat * 250);
513                 if (cfg->intpin > 0)
514                         printf("\tintpin=%c, irq=%d\n",
515                             cfg->intpin + 'a' - 1, cfg->intline);
516         }
517 }
518
519 /************************************************************************/
520 /* Resources                                                            */
521 /************************************************************************/
522
523 static int
524 cardbus_set_resource(device_t cbdev, device_t child, int type, int rid,
525     u_long start, u_long count, struct resource *res)
526 {
527         struct cardbus_devinfo *dinfo;
528         struct resource_list *rl;
529         struct resource_list_entry *rle;
530
531         if (device_get_parent(child) != cbdev)
532                 return ENOENT;
533
534         dinfo = device_get_ivars(child);
535         rl = &dinfo->pci.resources;
536         rle = resource_list_find(rl, type, rid);
537         if (rle == NULL) {
538                 resource_list_add(rl, type, rid, start, start + count - 1,
539                     count);
540                 if (res != NULL) {
541                         rle = resource_list_find(rl, type, rid);
542                         rle->res = res;
543                 }
544         } else {
545                 if (rle->res == NULL) {
546                 } else if (rle->res->r_dev == cbdev &&
547                     (!(rman_get_flags(rle->res) & RF_ACTIVE))) {
548                         int f;
549                         f = rman_get_flags(rle->res);
550                         bus_release_resource(cbdev, type, rid, res);
551                         rle->res = bus_alloc_resource(cbdev, type, &rid,
552                             start, start + count - 1,
553                             count, f);
554                 } else {
555                         device_printf(cbdev, "set_resource: resource busy\n");
556                         return EBUSY;
557                 }
558                 rle->start = start;
559                 rle->end = start + count - 1;
560                 rle->count = count;
561                 if (res != NULL)
562                         rle->res = res;
563         }
564         if (device_get_parent(child) == cbdev)
565                 pci_write_config(child, rid, start, 4);
566         return 0;
567 }
568
569 static int
570 cardbus_get_resource(device_t cbdev, device_t child, int type, int rid,
571     u_long *startp, u_long *countp)
572 {
573         struct cardbus_devinfo *dinfo;
574         struct resource_list *rl;
575         struct resource_list_entry *rle;
576
577         if (device_get_parent(child) != cbdev)
578                 return ENOENT;
579
580         dinfo = device_get_ivars(child);
581         rl = &dinfo->pci.resources;
582         rle = resource_list_find(rl, type, rid);
583         if (!rle)
584                 return ENOENT;
585         if (startp)
586                 *startp = rle->start;
587         if (countp)
588                 *countp = rle->count;
589         return 0;
590 }
591
592 static void
593 cardbus_delete_resource(device_t cbdev, device_t child, int type, int rid)
594 {
595         struct cardbus_devinfo *dinfo;
596         struct resource_list *rl;
597         struct resource_list_entry *rle;
598
599         if (device_get_parent(child) != cbdev)
600                 return;
601
602         dinfo = device_get_ivars(child);
603         rl = &dinfo->pci.resources;
604         rle = resource_list_find(rl, type, rid);
605         if (rle) {
606                 if (rle->res) {
607                         if (rle->res->r_dev != cbdev ||
608                             rman_get_flags(rle->res) & RF_ACTIVE) {
609                                 device_printf(cbdev, "delete_resource: "
610                                     "Resource still owned by child, oops. "
611                                     "(type=%d, rid=%d, addr=%lx)\n",
612                                     rle->type, rle->rid,
613                                     rman_get_start(rle->res));
614                                 return;
615                         }
616                         bus_release_resource(cbdev, type, rid, rle->res);
617                 }
618                 resource_list_delete(rl, type, rid);
619         }
620         if (device_get_parent(child) == cbdev)
621                 pci_write_config(child, rid, 0, 4);
622 }
623
624 static int
625 cardbus_set_resource_method(device_t cbdev, device_t child, int type, int rid,
626     u_long start, u_long count)
627 {
628         int ret;
629         ret = cardbus_set_resource(cbdev, child, type, rid, start, count, NULL);
630         if (ret != 0)
631                 return ret;
632         return BUS_SET_RESOURCE(device_get_parent(cbdev), child, type, rid,
633             start, count);
634 }
635
636 static int
637 cardbus_get_resource_method(device_t cbdev, device_t child, int type, int rid,
638     u_long *startp, u_long *countp)
639 {
640         int ret;
641         ret = cardbus_get_resource(cbdev, child, type, rid, startp, countp);
642         if (ret != 0)
643                 return ret;
644         return BUS_GET_RESOURCE(device_get_parent(cbdev), child, type, rid,
645             startp, countp);
646 }
647
648 static void
649 cardbus_delete_resource_method(device_t cbdev, device_t child,
650     int type, int rid)
651 {
652         cardbus_delete_resource(cbdev, child, type, rid);
653         BUS_DELETE_RESOURCE(device_get_parent(cbdev), child, type, rid);
654 }
655
656 static void
657 cardbus_release_all_resources(device_t cbdev, struct cardbus_devinfo *dinfo)
658 {
659         struct resource_list_entry *rle;
660
661         /* Free all allocated resources */
662         SLIST_FOREACH(rle, &dinfo->pci.resources, link) {
663                 if (rle->res) {
664                         if (rle->res->r_dev != cbdev)
665                                 device_printf(cbdev, "release_all_resource: "
666                                     "Resource still owned by child, oops. "
667                                     "(type=%d, rid=%d, addr=%lx)\n",
668                                     rle->type, rle->rid,
669                                     rman_get_start(rle->res));
670                         BUS_RELEASE_RESOURCE(device_get_parent(cbdev),
671                             rle->res->r_dev,
672                             rle->type, rle->rid,
673                             rle->res);
674                         rle->res = NULL;
675                         /*
676                          * zero out config so the card won't acknowledge
677                          * access to the space anymore
678                          */
679                         pci_write_config(dinfo->pci.cfg.dev, rle->rid, 0, 4);
680                 }
681         }
682         resource_list_free(&dinfo->pci.resources);
683 }
684
685 static struct resource *
686 cardbus_alloc_resource(device_t cbdev, device_t child, int type,
687     int *rid, u_long start, u_long end, u_long count, u_int flags)
688 {
689         struct cardbus_devinfo *dinfo;
690         struct resource_list_entry *rle = 0;
691         int passthrough = (device_get_parent(child) != cbdev);
692
693         if (passthrough) {
694                 return (BUS_ALLOC_RESOURCE(device_get_parent(cbdev), child,
695                     type, rid, start, end, count, flags));
696         }
697
698         dinfo = device_get_ivars(child);
699         rle = resource_list_find(&dinfo->pci.resources, type, *rid);
700
701         if (!rle)
702                 return NULL;            /* no resource of that type/rid */
703
704         if (!rle->res) {
705                 device_printf(cbdev, "WARNING: Resource not reserved by bus\n");
706                 return NULL;
707         } else {
708                 /* Release the cardbus hold on the resource */
709                 if (rle->res->r_dev != cbdev)
710                         return NULL;
711                 bus_release_resource(cbdev, type, *rid, rle->res);
712                 rle->res = NULL;
713                 switch (type) {
714                 case SYS_RES_IOPORT:
715                 case SYS_RES_MEMORY:
716                         if (!(flags & RF_ALIGNMENT_MASK))
717                                 flags |= rman_make_alignment_flags(rle->count);
718                         break;
719                 case SYS_RES_IRQ:
720                         flags |= RF_SHAREABLE;
721                         break;
722                 }
723                 /* Allocate the resource to the child */
724                 return resource_list_alloc(&dinfo->pci.resources, cbdev, child,
725                     type, rid, rle->start, rle->end, rle->count, flags);
726         }
727 }
728
729 static int
730 cardbus_release_resource(device_t cbdev, device_t child, int type, int rid,
731     struct resource *r)
732 {
733         struct cardbus_devinfo *dinfo;
734         int passthrough = (device_get_parent(child) != cbdev);
735         struct resource_list_entry *rle = 0;
736         int flags;
737         int ret;
738
739         if (passthrough) {
740                 return BUS_RELEASE_RESOURCE(device_get_parent(cbdev), child,
741                     type, rid, r);
742         }
743
744         dinfo = device_get_ivars(child);
745         /*
746          * According to the PCI 2.2 spec, devices may share an address
747          * decoder between memory mapped ROM access and memory
748          * mapped register access.  To be safe, disable ROM access
749          * whenever it is released.
750          */
751         if (rid == CARDBUS_ROM_REG) {
752                 uint32_t rom_reg;
753
754                 rom_reg = pci_read_config(child, rid, 4);
755                 rom_reg &= ~CARDBUS_ROM_ENABLE;
756                 pci_write_config(child, rid, rom_reg, 4);
757         }
758
759         rle = resource_list_find(&dinfo->pci.resources, type, rid);
760
761         if (!rle) {
762                 device_printf(cbdev, "Allocated resource not found\n");
763                 return ENOENT;
764         }
765         if (!rle->res) {
766                 device_printf(cbdev, "Allocated resource not recorded\n");
767                 return ENOENT;
768         }
769
770         ret = BUS_RELEASE_RESOURCE(device_get_parent(cbdev), child,
771             type, rid, r);
772         switch (type) {
773         case SYS_RES_IOPORT:
774         case SYS_RES_MEMORY:
775                 flags = rman_make_alignment_flags(rle->count);
776                 break;
777         case SYS_RES_IRQ:
778                 flags = RF_SHAREABLE;
779                 break;
780         default:
781                 flags = 0;
782         }
783         /* Restore cardbus hold on the resource */
784         rle->res = bus_alloc_resource(cbdev, type, &rid,
785             rle->start, rle->end, rle->count, flags);
786         if (rle->res == NULL)
787                 device_printf(cbdev, "release_resource: "
788                     "unable to reacquire resource\n");
789         return ret;
790 }
791
792 static int
793 cardbus_setup_intr(device_t cbdev, device_t child, struct resource *irq,
794     int flags, driver_intr_t *intr, void *arg, 
795     void **cookiep, lwkt_serialize_t serializer)
796 {
797         int ret;
798         device_t cdev;
799         struct cardbus_devinfo *dinfo;
800
801         ret = bus_generic_setup_intr(cbdev, child, irq, flags, intr, arg,
802                                      cookiep, serializer);
803         if (ret != 0)
804                 return ret;
805
806         for (cdev = child; cbdev != device_get_parent(cdev);
807             cdev = device_get_parent(cdev))
808                 /* NOTHING */;
809         dinfo = device_get_ivars(cdev);
810
811         return 0;
812 }
813
814 static int
815 cardbus_teardown_intr(device_t cbdev, device_t child, struct resource *irq,
816     void *cookie)
817 {
818         int ret;
819         device_t cdev;
820         struct cardbus_devinfo *dinfo;
821
822         ret = bus_generic_teardown_intr(cbdev, child, irq, cookie);
823         if (ret != 0)
824                 return ret;
825
826         for (cdev = child; cbdev != device_get_parent(cdev);
827             cdev = device_get_parent(cdev))
828                 /* NOTHING */;
829         dinfo = device_get_ivars(cdev);
830
831         return (0);
832 }
833
834
835 /************************************************************************/
836 /* Other Bus Methods                                                    */
837 /************************************************************************/
838
839 static int
840 cardbus_print_resources(struct resource_list *rl, const char *name,
841     int type, const char *format)
842 {
843         struct resource_list_entry *rle;
844         int printed, retval;
845
846         printed = 0;
847         retval = 0;
848         /* Yes, this is kinda cheating */
849         SLIST_FOREACH(rle, rl, link) {
850                 if (rle->type == type) {
851                         if (printed == 0)
852                                 retval += printf(" %s ", name);
853                         else if (printed > 0)
854                                 retval += printf(",");
855                         printed++;
856                         retval += printf(format, rle->start);
857                         if (rle->count > 1) {
858                                 retval += printf("-");
859                                 retval += printf(format, rle->start +
860                                     rle->count - 1);
861                         }
862                 }
863         }
864         return retval;
865 }
866
867 static int
868 cardbus_print_child(device_t cbdev, device_t child)
869 {
870         struct cardbus_devinfo *dinfo;
871         struct resource_list *rl;
872         pcicfgregs *cfg;
873         int retval = 0;
874
875         dinfo = device_get_ivars(child);
876         cfg = &dinfo->pci.cfg;
877         rl = &dinfo->pci.resources;
878
879         retval += bus_print_child_header(cbdev, child);
880
881         retval += cardbus_print_resources(rl, "port", SYS_RES_IOPORT, "%#lx");
882         retval += cardbus_print_resources(rl, "mem", SYS_RES_MEMORY, "%#lx");
883         retval += cardbus_print_resources(rl, "irq", SYS_RES_IRQ, "%ld");
884         if (device_get_flags(cbdev))
885                 retval += printf(" flags %#x", device_get_flags(cbdev));
886
887         retval += printf(" at device %d.%d", pci_get_slot(child),
888             pci_get_function(child));
889
890         retval += bus_print_child_footer(cbdev, child);
891
892         return (retval);
893 }
894
895 static void
896 cardbus_probe_nomatch(device_t cbdev, device_t child)
897 {
898         struct cardbus_devinfo *dinfo;
899         pcicfgregs *cfg;
900
901         dinfo = device_get_ivars(child);
902         cfg = &dinfo->pci.cfg;
903         device_printf(cbdev, "<unknown card>");
904         printf(" (vendor=0x%04x, dev=0x%04x)", cfg->vendor, cfg->device);
905         printf(" at %d.%d", pci_get_slot(child), pci_get_function(child));
906         if (cfg->intpin > 0 && cfg->intline != 255) {
907                 printf(" irq %d", cfg->intline);
908         }
909         printf("\n");
910
911         return;
912 }
913
914 static int
915 cardbus_child_location_str(device_t cbdev, device_t child, char *buf,
916     size_t buflen)
917 {
918         struct cardbus_devinfo *dinfo;
919         pcicfgregs *cfg;
920
921         dinfo = device_get_ivars(child);
922         cfg = &dinfo->pci.cfg;
923         snprintf(buf, buflen, "slot=%d function=%d", pci_get_slot(child),
924             pci_get_function(child));
925         return (0);
926 }
927
928 static int
929 cardbus_child_pnpinfo_str(device_t cbdev, device_t child, char *buf,
930     size_t buflen)
931 {
932         struct cardbus_devinfo *dinfo;
933         pcicfgregs *cfg;
934
935         dinfo = device_get_ivars(child);
936         cfg = &dinfo->pci.cfg;
937         snprintf(buf, buflen, "vendor=0x%04x device=0x%04x subvendor=0x%04x "
938             "subdevice=0x%04x", cfg->vendor, cfg->device, cfg->subvendor,
939             cfg->subdevice);
940         return (0);
941 }
942
943 static int
944 cardbus_read_ivar(device_t cbdev, device_t child, int which, u_long *result)
945 {
946         struct cardbus_devinfo *dinfo;
947         pcicfgregs *cfg;
948
949         dinfo = device_get_ivars(child);
950         cfg = &dinfo->pci.cfg;
951
952         switch (which) {
953         case PCI_IVAR_ETHADDR:
954                 /*
955                  * The generic accessor doesn't deal with failure, so
956                  * we set the return value, then return an error.
957                  */
958                 if ((dinfo->fepresent & (1 << TPL_FUNCE_LAN_NID)) == 0) {
959                         *((u_int8_t **) result) = NULL;
960                         return (EINVAL);
961                 }
962                 *((u_int8_t **) result) = dinfo->funce.lan.nid;
963                 break;
964         case PCI_IVAR_SUBVENDOR:
965                 *result = cfg->subvendor;
966                 break;
967         case PCI_IVAR_SUBDEVICE:
968                 *result = cfg->subdevice;
969                 break;
970         case PCI_IVAR_VENDOR:
971                 *result = cfg->vendor;
972                 break;
973         case PCI_IVAR_DEVICE:
974                 *result = cfg->device;
975                 break;
976         case PCI_IVAR_DEVID:
977                 *result = (cfg->device << 16) | cfg->vendor;
978                 break;
979         case PCI_IVAR_CLASS:
980                 *result = cfg->baseclass;
981                 break;
982         case PCI_IVAR_SUBCLASS:
983                 *result = cfg->subclass;
984                 break;
985         case PCI_IVAR_PROGIF:
986                 *result = cfg->progif;
987                 break;
988         case PCI_IVAR_REVID:
989                 *result = cfg->revid;
990                 break;
991         case PCI_IVAR_INTPIN:
992                 *result = cfg->intpin;
993                 break;
994         case PCI_IVAR_IRQ:
995                 *result = cfg->intline;
996                 break;
997         case PCI_IVAR_BUS:
998                 *result = cfg->bus;
999                 break;
1000         case PCI_IVAR_SLOT:
1001                 *result = cfg->slot;
1002                 break;
1003         case PCI_IVAR_FUNCTION:
1004                 *result = cfg->func;
1005                 break;
1006         default:
1007                 return ENOENT;
1008         }
1009         return 0;
1010 }
1011
1012 static int
1013 cardbus_write_ivar(device_t cbdev, device_t child, int which, uintptr_t value)
1014 {
1015         struct cardbus_devinfo *dinfo;
1016         pcicfgregs *cfg;
1017
1018         dinfo = device_get_ivars(child);
1019         cfg = &dinfo->pci.cfg;
1020
1021         switch (which) {
1022         case PCI_IVAR_ETHADDR:
1023         case PCI_IVAR_SUBVENDOR:
1024         case PCI_IVAR_SUBDEVICE:
1025         case PCI_IVAR_VENDOR:
1026         case PCI_IVAR_DEVICE:
1027         case PCI_IVAR_DEVID:
1028         case PCI_IVAR_CLASS:
1029         case PCI_IVAR_SUBCLASS:
1030         case PCI_IVAR_PROGIF:
1031         case PCI_IVAR_REVID:
1032         case PCI_IVAR_INTPIN:
1033         case PCI_IVAR_IRQ:
1034         case PCI_IVAR_BUS:
1035         case PCI_IVAR_SLOT:
1036         case PCI_IVAR_FUNCTION:
1037                 return EINVAL;  /* disallow for now */
1038         default:
1039                 return ENOENT;
1040         }
1041         return 0;
1042 }
1043
1044 /************************************************************************/
1045 /* Compatibility with PCI bus (XXX: Do we need this?)                   */
1046 /************************************************************************/
1047
1048 /*
1049  * PCI power manangement
1050  */
1051 static int
1052 cardbus_set_powerstate_method(device_t cbdev, device_t child, int state)
1053 {
1054         struct cardbus_devinfo *dinfo = device_get_ivars(child);
1055         pcicfgregs *cfg = &dinfo->pci.cfg;
1056         u_int16_t status;
1057         int result;
1058
1059         if (cfg->pp_cap != 0) {
1060                 status = PCI_READ_CONFIG(cbdev, child, cfg->pp_status, 2)
1061                     & ~PCIM_PSTAT_DMASK;
1062                 result = 0;
1063                 switch (state) {
1064                 case PCI_POWERSTATE_D0:
1065                         status |= PCIM_PSTAT_D0;
1066                         break;
1067                 case PCI_POWERSTATE_D1:
1068                         if (cfg->pp_cap & PCIM_PCAP_D1SUPP) {
1069                                 status |= PCIM_PSTAT_D1;
1070                         } else {
1071                                 result = EOPNOTSUPP;
1072                         }
1073                         break;
1074                 case PCI_POWERSTATE_D2:
1075                         if (cfg->pp_cap & PCIM_PCAP_D2SUPP) {
1076                                 status |= PCIM_PSTAT_D2;
1077                         } else {
1078                                 result = EOPNOTSUPP;
1079                         }
1080                         break;
1081                 case PCI_POWERSTATE_D3:
1082                         status |= PCIM_PSTAT_D3;
1083                         break;
1084                 default:
1085                         result = EINVAL;
1086                 }
1087                 if (result == 0)
1088                         PCI_WRITE_CONFIG(cbdev, child, cfg->pp_status,
1089                             status, 2);
1090         } else {
1091                 result = ENXIO;
1092         }
1093         return (result);
1094 }
1095
1096 static int
1097 cardbus_get_powerstate_method(device_t cbdev, device_t child)
1098 {
1099         struct cardbus_devinfo *dinfo = device_get_ivars(child);
1100         pcicfgregs *cfg = &dinfo->pci.cfg;
1101         u_int16_t status;
1102         int result;
1103
1104         if (cfg->pp_cap != 0) {
1105                 status = PCI_READ_CONFIG(cbdev, child, cfg->pp_status, 2);
1106                 switch (status & PCIM_PSTAT_DMASK) {
1107                 case PCIM_PSTAT_D0:
1108                         result = PCI_POWERSTATE_D0;
1109                         break;
1110                 case PCIM_PSTAT_D1:
1111                         result = PCI_POWERSTATE_D1;
1112                         break;
1113                 case PCIM_PSTAT_D2:
1114                         result = PCI_POWERSTATE_D2;
1115                         break;
1116                 case PCIM_PSTAT_D3:
1117                         result = PCI_POWERSTATE_D3;
1118                         break;
1119                 default:
1120                         result = PCI_POWERSTATE_UNKNOWN;
1121                         break;
1122                 }
1123         } else {
1124                 /* No support, device is always at D0 */
1125                 result = PCI_POWERSTATE_D0;
1126         }
1127         return (result);
1128 }
1129
1130 static u_int32_t
1131 cardbus_read_config_method(device_t cbdev, device_t child, int reg, int width)
1132 {
1133         struct cardbus_devinfo *dinfo = device_get_ivars(child);
1134         pcicfgregs *cfg = &dinfo->pci.cfg;
1135
1136         return PCIB_READ_CONFIG(device_get_parent(cbdev),
1137             cfg->bus, cfg->slot, cfg->func, reg, width);
1138 }
1139
1140 static void
1141 cardbus_write_config_method(device_t cbdev, device_t child, int reg,
1142     u_int32_t val, int width)
1143 {
1144         struct cardbus_devinfo *dinfo = device_get_ivars(child);
1145         pcicfgregs *cfg = &dinfo->pci.cfg;
1146
1147         PCIB_WRITE_CONFIG(device_get_parent(cbdev),
1148             cfg->bus, cfg->slot, cfg->func, reg, val, width);
1149 }
1150
1151 static __inline void
1152 cardbus_set_command_bit(device_t cbdev, device_t child, u_int16_t bit)
1153 {
1154         u_int16_t command;
1155
1156         command = PCI_READ_CONFIG(cbdev, child, PCIR_COMMAND, 2);
1157         command |= bit;
1158         PCI_WRITE_CONFIG(cbdev, child, PCIR_COMMAND, command, 2);
1159 }
1160
1161 static __inline void
1162 cardbus_clear_command_bit(device_t cbdev, device_t child, u_int16_t bit)
1163 {
1164         u_int16_t command;
1165
1166         command = PCI_READ_CONFIG(cbdev, child, PCIR_COMMAND, 2);
1167         command &= ~bit;
1168         PCI_WRITE_CONFIG(cbdev, child, PCIR_COMMAND, command, 2);
1169 }
1170
1171 static void
1172 cardbus_enable_busmaster_method(device_t cbdev, device_t child)
1173 {
1174         cardbus_set_command_bit(cbdev, child, PCIM_CMD_BUSMASTEREN);
1175 }
1176
1177 static void
1178 cardbus_disable_busmaster_method(device_t cbdev, device_t child)
1179 {
1180         cardbus_clear_command_bit(cbdev, child, PCIM_CMD_BUSMASTEREN);
1181 }
1182
1183 static void
1184 cardbus_enable_io_method(device_t cbdev, device_t child, int space)
1185 {
1186         switch (space) {
1187         case SYS_RES_IOPORT:
1188                 cardbus_set_command_bit(cbdev, child, PCIM_CMD_PORTEN);
1189                 break;
1190         case SYS_RES_MEMORY:
1191                 cardbus_set_command_bit(cbdev, child, PCIM_CMD_MEMEN);
1192                 break;
1193         }
1194 }
1195
1196 static void
1197 cardbus_disable_io_method(device_t cbdev, device_t child, int space)
1198 {
1199         switch (space) {
1200         case SYS_RES_IOPORT:
1201                 cardbus_clear_command_bit(cbdev, child, PCIM_CMD_PORTEN);
1202                 break;
1203         case SYS_RES_MEMORY:
1204                 cardbus_clear_command_bit(cbdev, child, PCIM_CMD_MEMEN);
1205                 break;
1206         }
1207 }
1208
1209 static device_method_t cardbus_methods[] = {
1210         /* Device interface */
1211         DEVMETHOD(device_probe,         cardbus_probe),
1212         DEVMETHOD(device_attach,        cardbus_attach),
1213         DEVMETHOD(device_detach,        cardbus_detach),
1214         DEVMETHOD(device_shutdown,      bus_generic_shutdown),
1215         DEVMETHOD(device_suspend,       cardbus_suspend),
1216         DEVMETHOD(device_resume,        cardbus_resume),
1217
1218         /* Bus interface */
1219         DEVMETHOD(bus_print_child,      cardbus_print_child),
1220         DEVMETHOD(bus_probe_nomatch,    cardbus_probe_nomatch),
1221         DEVMETHOD(bus_read_ivar,        cardbus_read_ivar),
1222         DEVMETHOD(bus_write_ivar,       cardbus_write_ivar),
1223         DEVMETHOD(bus_driver_added,     cardbus_driver_added),
1224         DEVMETHOD(bus_alloc_resource,   cardbus_alloc_resource),
1225         DEVMETHOD(bus_release_resource, cardbus_release_resource),
1226         DEVMETHOD(bus_activate_resource, bus_generic_activate_resource),
1227         DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource),
1228         DEVMETHOD(bus_setup_intr,       cardbus_setup_intr),
1229         DEVMETHOD(bus_teardown_intr,    cardbus_teardown_intr),
1230
1231         DEVMETHOD(bus_set_resource,     cardbus_set_resource_method),
1232         DEVMETHOD(bus_get_resource,     cardbus_get_resource_method),
1233         DEVMETHOD(bus_delete_resource,  cardbus_delete_resource_method),
1234         DEVMETHOD(bus_child_pnpinfo_str, cardbus_child_pnpinfo_str),
1235         DEVMETHOD(bus_child_location_str, cardbus_child_location_str),
1236
1237         /* Card Interface */
1238         DEVMETHOD(card_attach_card,     cardbus_attach_card),
1239         DEVMETHOD(card_detach_card,     cardbus_detach_card),
1240         DEVMETHOD(card_cis_read,        cardbus_cis_read),
1241         DEVMETHOD(card_cis_free,        cardbus_cis_free),
1242
1243         /* Cardbus/PCI interface */
1244         DEVMETHOD(pci_read_config,      cardbus_read_config_method),
1245         DEVMETHOD(pci_write_config,     cardbus_write_config_method),
1246         DEVMETHOD(pci_enable_busmaster, cardbus_enable_busmaster_method),
1247         DEVMETHOD(pci_disable_busmaster, cardbus_disable_busmaster_method),
1248         DEVMETHOD(pci_enable_io,        cardbus_enable_io_method),
1249         DEVMETHOD(pci_disable_io,       cardbus_disable_io_method),
1250         DEVMETHOD(pci_get_powerstate,   cardbus_get_powerstate_method),
1251         DEVMETHOD(pci_set_powerstate,   cardbus_set_powerstate_method),
1252
1253         {0,0}
1254 };
1255
1256 static driver_t cardbus_driver = {
1257         "cardbus",
1258         cardbus_methods,
1259         0 /* no softc */
1260 };
1261
1262 static devclass_t cardbus_devclass;
1263
1264 DRIVER_MODULE(cardbus, cbb, cardbus_driver, cardbus_devclass, 0, 0);
1265 MODULE_VERSION(cardbus, 1);
1266 MODULE_DEPEND(cardbus, exca, 1, 1, 1);
1267 /*
1268 MODULE_DEPEND(cardbus, pccbb, 1, 1, 1);
1269 */