2 * Copyright (c) 2000,2001 Jonathan Chen.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
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
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
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.4 2005/02/08 15:51:24 joerg Exp $
35 * much of the bus code was stolen directly from sys/pci/pci.c
36 * (Copyright (c) 1997, Stefan Esser <se@freebsd.org>)
38 * Written by Jonathan Chen <jon@freebsd.org>
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>
48 #include <machine/bus.h>
50 #include <machine/resource.h>
52 #include <sys/pciio.h>
53 #include <bus/pci/pcivar.h>
54 #include <bus/pci/pcireg.h>
55 #include <bus/pci/pci_private.h>
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>
66 SYSCTL_NODE(_hw, OID_AUTO, cardbus, CTLFLAG_RD, 0, "CardBus parameters");
68 int cardbus_debug = 0;
69 TUNABLE_INT("hw.cardbus.debug", &cardbus_debug);
70 SYSCTL_INT(_hw_cardbus, OID_AUTO, debug, CTLFLAG_RW,
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,
80 #define DPRINTF(a) if (cardbus_debug) printf a
81 #define DEVPRINTF(x) if (cardbus_debug) device_printf x
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,
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,
91 static int cardbus_child_pnpinfo_str(device_t cbdev, device_t child,
93 static __inline void cardbus_clear_command_bit(device_t cbdev, device_t child,
95 static void cardbus_delete_resource(device_t cbdev, device_t child,
97 static void cardbus_delete_resource_method(device_t cbdev, device_t child,
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,
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,
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,
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,
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,
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,
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,
137 static int cardbus_set_powerstate_method(device_t cbdev, device_t child,
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);
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,
153 /************************************************************************/
155 /************************************************************************/
158 cardbus_probe(device_t cbdev)
160 device_set_desc(cbdev, "CardBus bus");
165 cardbus_attach(device_t cbdev)
171 cardbus_detach(device_t cbdev)
173 cardbus_detach_card(cbdev);
178 cardbus_suspend(device_t self)
180 cardbus_detach_card(self);
185 cardbus_resume(device_t self)
190 /************************************************************************/
191 /* Attach/Detach card */
192 /************************************************************************/
195 cardbus_device_setup_regs(device_t brdev, int b, int s, int f, pcicfgregs *cfg)
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);
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);
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);
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);
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);
215 cardbus_attach_card(device_t cbdev)
217 device_t brdev = device_get_parent(cbdev);
218 int cardattached = 0;
219 static int curr_bus_number = 2; /* XXX EVILE BAD (see below) */
222 cardbus_detach_card(cbdev); /* detach existing cards */
224 POWER_ENABLE_SOCKET(brdev, cbdev);
225 bus = pcib_get_bus(cbdev);
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
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;
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);
247 if (dinfo->pci.cfg.mfdev)
248 cardbusfunchigh = CARDBUS_FUNCMAX;
250 cardbus_device_setup_regs(brdev, bus, slot, func,
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);
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);
269 if (cardattached > 0)
271 POWER_DISABLE_SOCKET(brdev, cbdev);
276 cardbus_detach_card(device_t cbdev)
283 device_get_children(cbdev, &devlist, &numdevs);
286 free(devlist, M_TEMP);
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]);
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);
302 POWER_DISABLE_SOCKET(device_get_parent(cbdev), cbdev);
303 free(devlist, M_TEMP);
308 cardbus_driver_added(device_t cbdev, driver_t *driver)
313 struct cardbus_devinfo *dinfo;
315 device_get_children(cbdev, &devlist, &numdevs);
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]);
323 cardbus_device_setup_regs(brdev, bus, slot, func,
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);
335 free(devlist, M_TEMP);
338 /************************************************************************/
339 /* PCI-Like config reading (copied from pci.c */
340 /************************************************************************/
342 /* read configuration header into pcicfgrect structure */
345 cardbus_read_extcap(device_t cbdev, pcicfgregs *cfg)
347 #define REG(n, w) PCIB_READ_CONFIG(cbdev, cfg->bus, cfg->slot, cfg->func, n, w)
348 int ptr, nextptr, ptrptr;
350 switch (cfg->hdrtype) {
358 return; /* no extended capabilities support */
360 nextptr = REG(ptrptr, 1); /* sanity check? */
363 * Read capability entries.
365 while (nextptr != 0) {
368 printf("illegal PCI extended capability offset %d\n",
372 /* Find the next entry */
374 nextptr = REG(ptr + 1, 1);
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;
394 /* extract header type specific config data */
397 cardbus_hdrtypedata(device_t brdev, int b, int s, int f, pcicfgregs *cfg)
399 #define REG(n, w) PCIB_READ_CONFIG(brdev, b, s, f, n, w)
400 switch (cfg->hdrtype) {
402 cfg->subvendor = REG(PCIR_SUBVEND_0, 2);
403 cfg->subdevice = REG(PCIR_SUBDEV_0, 2);
404 cfg->nummaps = PCI_MAXMAPS_0;
407 cfg->subvendor = REG(PCIR_SUBVEND_1, 2);
408 cfg->subdevice = REG(PCIR_SUBDEV_1, 2);
409 cfg->nummaps = PCI_MAXMAPS_1;
412 cfg->subvendor = REG(PCIR_SUBVEND_2, 2);
413 cfg->subdevice = REG(PCIR_SUBDEV_2, 2);
414 cfg->nummaps = PCI_MAXMAPS_2;
420 static struct cardbus_devinfo *
421 cardbus_read_device(device_t brdev, int b, int s, int f)
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;
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)
433 cfg = &devlist_entry->pci.cfg;
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);
452 cfg->mingnt = REG(PCIR_MINGNT, 1);
453 cfg->maxlat = REG(PCIR_MAXLAT, 1);
455 cfg->mfdev = (cfg->hdrtype & PCIM_MFDEV) != 0;
456 cfg->hdrtype &= ~PCIM_MFDEV;
458 cardbus_hdrtypedata(brdev, b, s, f, cfg);
460 if (REG(PCIR_STATUS, 2) & PCIM_STATUS_CAPPRESENT)
461 cardbus_read_extcap(brdev, cfg);
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;
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;
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;
478 return (devlist_entry);
482 /* free pcicfgregs structure and all depending data structures */
485 cardbus_freecfg(struct cardbus_devinfo *dinfo)
487 free(dinfo, M_DEVBUF);
493 cardbus_print_verbose(struct cardbus_devinfo *dinfo)
495 if (bootverbose || cardbus_debug > 0)
497 pcicfgregs *cfg = &dinfo->pci.cfg;
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,
514 printf("\tintpin=%c, irq=%d\n",
515 cfg->intpin + 'a' - 1, cfg->intline);
519 /************************************************************************/
521 /************************************************************************/
524 cardbus_set_resource(device_t cbdev, device_t child, int type, int rid,
525 u_long start, u_long count, struct resource *res)
527 struct cardbus_devinfo *dinfo;
528 struct resource_list *rl;
529 struct resource_list_entry *rle;
531 if (device_get_parent(child) != cbdev)
534 dinfo = device_get_ivars(child);
535 rl = &dinfo->pci.resources;
536 rle = resource_list_find(rl, type, rid);
538 resource_list_add(rl, type, rid, start, start + count - 1,
541 rle = resource_list_find(rl, type, rid);
545 if (rle->res == NULL) {
546 } else if (rle->res->r_dev == cbdev &&
547 (!(rman_get_flags(rle->res) & RF_ACTIVE))) {
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,
555 device_printf(cbdev, "set_resource: resource busy\n");
559 rle->end = start + count - 1;
564 if (device_get_parent(child) == cbdev)
565 pci_write_config(child, rid, start, 4);
570 cardbus_get_resource(device_t cbdev, device_t child, int type, int rid,
571 u_long *startp, u_long *countp)
573 struct cardbus_devinfo *dinfo;
574 struct resource_list *rl;
575 struct resource_list_entry *rle;
577 if (device_get_parent(child) != cbdev)
580 dinfo = device_get_ivars(child);
581 rl = &dinfo->pci.resources;
582 rle = resource_list_find(rl, type, rid);
586 *startp = rle->start;
588 *countp = rle->count;
593 cardbus_delete_resource(device_t cbdev, device_t child, int type, int rid)
595 struct cardbus_devinfo *dinfo;
596 struct resource_list *rl;
597 struct resource_list_entry *rle;
599 if (device_get_parent(child) != cbdev)
602 dinfo = device_get_ivars(child);
603 rl = &dinfo->pci.resources;
604 rle = resource_list_find(rl, type, rid);
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",
613 rman_get_start(rle->res));
616 bus_release_resource(cbdev, type, rid, rle->res);
618 resource_list_delete(rl, type, rid);
620 if (device_get_parent(child) == cbdev)
621 pci_write_config(child, rid, 0, 4);
625 cardbus_set_resource_method(device_t cbdev, device_t child, int type, int rid,
626 u_long start, u_long count)
629 ret = cardbus_set_resource(cbdev, child, type, rid, start, count, NULL);
632 return BUS_SET_RESOURCE(device_get_parent(cbdev), child, type, rid,
637 cardbus_get_resource_method(device_t cbdev, device_t child, int type, int rid,
638 u_long *startp, u_long *countp)
641 ret = cardbus_get_resource(cbdev, child, type, rid, startp, countp);
644 return BUS_GET_RESOURCE(device_get_parent(cbdev), child, type, rid,
649 cardbus_delete_resource_method(device_t cbdev, device_t child,
652 cardbus_delete_resource(cbdev, child, type, rid);
653 BUS_DELETE_RESOURCE(device_get_parent(cbdev), child, type, rid);
657 cardbus_release_all_resources(device_t cbdev, struct cardbus_devinfo *dinfo)
659 struct resource_list_entry *rle;
661 /* Free all allocated resources */
662 SLIST_FOREACH(rle, &dinfo->pci.resources, link) {
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",
669 rman_get_start(rle->res));
670 BUS_RELEASE_RESOURCE(device_get_parent(cbdev),
676 * zero out config so the card won't acknowledge
677 * access to the space anymore
679 pci_write_config(dinfo->pci.cfg.dev, rle->rid, 0, 4);
682 resource_list_free(&dinfo->pci.resources);
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)
689 struct cardbus_devinfo *dinfo;
690 struct resource_list_entry *rle = 0;
691 int passthrough = (device_get_parent(child) != cbdev);
694 return (BUS_ALLOC_RESOURCE(device_get_parent(cbdev), child,
695 type, rid, start, end, count, flags));
698 dinfo = device_get_ivars(child);
699 rle = resource_list_find(&dinfo->pci.resources, type, *rid);
702 return NULL; /* no resource of that type/rid */
705 device_printf(cbdev, "WARNING: Resource not reserved by bus\n");
708 /* Release the cardbus hold on the resource */
709 if (rle->res->r_dev != cbdev)
711 bus_release_resource(cbdev, type, *rid, rle->res);
716 if (!(flags & RF_ALIGNMENT_MASK))
717 flags |= rman_make_alignment_flags(rle->count);
720 flags |= RF_SHAREABLE;
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);
730 cardbus_release_resource(device_t cbdev, device_t child, int type, int rid,
733 struct cardbus_devinfo *dinfo;
734 int passthrough = (device_get_parent(child) != cbdev);
735 struct resource_list_entry *rle = 0;
740 return BUS_RELEASE_RESOURCE(device_get_parent(cbdev), child,
744 dinfo = device_get_ivars(child);
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.
751 if (rid == CARDBUS_ROM_REG) {
754 rom_reg = pci_read_config(child, rid, 4);
755 rom_reg &= ~CARDBUS_ROM_ENABLE;
756 pci_write_config(child, rid, rom_reg, 4);
759 rle = resource_list_find(&dinfo->pci.resources, type, rid);
762 device_printf(cbdev, "Allocated resource not found\n");
766 device_printf(cbdev, "Allocated resource not recorded\n");
770 ret = BUS_RELEASE_RESOURCE(device_get_parent(cbdev), child,
775 flags = rman_make_alignment_flags(rle->count);
778 flags = RF_SHAREABLE;
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");
793 cardbus_setup_intr(device_t cbdev, device_t child, struct resource *irq,
794 int flags, driver_intr_t *intr, void *arg, void **cookiep)
798 struct cardbus_devinfo *dinfo;
800 ret = bus_generic_setup_intr(cbdev, child, irq, flags, intr, arg,
805 for (cdev = child; cbdev != device_get_parent(cdev);
806 cdev = device_get_parent(cdev))
808 dinfo = device_get_ivars(cdev);
814 cardbus_teardown_intr(device_t cbdev, device_t child, struct resource *irq,
819 struct cardbus_devinfo *dinfo;
821 ret = bus_generic_teardown_intr(cbdev, child, irq, cookie);
825 for (cdev = child; cbdev != device_get_parent(cdev);
826 cdev = device_get_parent(cdev))
828 dinfo = device_get_ivars(cdev);
834 /************************************************************************/
835 /* Other Bus Methods */
836 /************************************************************************/
839 cardbus_print_resources(struct resource_list *rl, const char *name,
840 int type, const char *format)
842 struct resource_list_entry *rle;
847 /* Yes, this is kinda cheating */
848 SLIST_FOREACH(rle, rl, link) {
849 if (rle->type == type) {
851 retval += printf(" %s ", name);
852 else if (printed > 0)
853 retval += printf(",");
855 retval += printf(format, rle->start);
856 if (rle->count > 1) {
857 retval += printf("-");
858 retval += printf(format, rle->start +
867 cardbus_print_child(device_t cbdev, device_t child)
869 struct cardbus_devinfo *dinfo;
870 struct resource_list *rl;
874 dinfo = device_get_ivars(child);
875 cfg = &dinfo->pci.cfg;
876 rl = &dinfo->pci.resources;
878 retval += bus_print_child_header(cbdev, child);
880 retval += cardbus_print_resources(rl, "port", SYS_RES_IOPORT, "%#lx");
881 retval += cardbus_print_resources(rl, "mem", SYS_RES_MEMORY, "%#lx");
882 retval += cardbus_print_resources(rl, "irq", SYS_RES_IRQ, "%ld");
883 if (device_get_flags(cbdev))
884 retval += printf(" flags %#x", device_get_flags(cbdev));
886 retval += printf(" at device %d.%d", pci_get_slot(child),
887 pci_get_function(child));
889 retval += bus_print_child_footer(cbdev, child);
895 cardbus_probe_nomatch(device_t cbdev, device_t child)
897 struct cardbus_devinfo *dinfo;
900 dinfo = device_get_ivars(child);
901 cfg = &dinfo->pci.cfg;
902 device_printf(cbdev, "<unknown card>");
903 printf(" (vendor=0x%04x, dev=0x%04x)", cfg->vendor, cfg->device);
904 printf(" at %d.%d", pci_get_slot(child), pci_get_function(child));
905 if (cfg->intpin > 0 && cfg->intline != 255) {
906 printf(" irq %d", cfg->intline);
914 cardbus_child_location_str(device_t cbdev, device_t child, char *buf,
917 struct cardbus_devinfo *dinfo;
920 dinfo = device_get_ivars(child);
921 cfg = &dinfo->pci.cfg;
922 snprintf(buf, buflen, "slot=%d function=%d", pci_get_slot(child),
923 pci_get_function(child));
928 cardbus_child_pnpinfo_str(device_t cbdev, device_t child, char *buf,
931 struct cardbus_devinfo *dinfo;
934 dinfo = device_get_ivars(child);
935 cfg = &dinfo->pci.cfg;
936 snprintf(buf, buflen, "vendor=0x%04x device=0x%04x subvendor=0x%04x "
937 "subdevice=0x%04x", cfg->vendor, cfg->device, cfg->subvendor,
943 cardbus_read_ivar(device_t cbdev, device_t child, int which, u_long *result)
945 struct cardbus_devinfo *dinfo;
948 dinfo = device_get_ivars(child);
949 cfg = &dinfo->pci.cfg;
952 case PCI_IVAR_ETHADDR:
954 * The generic accessor doesn't deal with failure, so
955 * we set the return value, then return an error.
957 if ((dinfo->fepresent & (1 << TPL_FUNCE_LAN_NID)) == 0) {
958 *((u_int8_t **) result) = NULL;
961 *((u_int8_t **) result) = dinfo->funce.lan.nid;
963 case PCI_IVAR_SUBVENDOR:
964 *result = cfg->subvendor;
966 case PCI_IVAR_SUBDEVICE:
967 *result = cfg->subdevice;
969 case PCI_IVAR_VENDOR:
970 *result = cfg->vendor;
972 case PCI_IVAR_DEVICE:
973 *result = cfg->device;
976 *result = (cfg->device << 16) | cfg->vendor;
979 *result = cfg->baseclass;
981 case PCI_IVAR_SUBCLASS:
982 *result = cfg->subclass;
984 case PCI_IVAR_PROGIF:
985 *result = cfg->progif;
988 *result = cfg->revid;
990 case PCI_IVAR_INTPIN:
991 *result = cfg->intpin;
994 *result = cfg->intline;
1000 *result = cfg->slot;
1002 case PCI_IVAR_FUNCTION:
1003 *result = cfg->func;
1012 cardbus_write_ivar(device_t cbdev, device_t child, int which, uintptr_t value)
1014 struct cardbus_devinfo *dinfo;
1017 dinfo = device_get_ivars(child);
1018 cfg = &dinfo->pci.cfg;
1021 case PCI_IVAR_ETHADDR:
1022 case PCI_IVAR_SUBVENDOR:
1023 case PCI_IVAR_SUBDEVICE:
1024 case PCI_IVAR_VENDOR:
1025 case PCI_IVAR_DEVICE:
1026 case PCI_IVAR_DEVID:
1027 case PCI_IVAR_CLASS:
1028 case PCI_IVAR_SUBCLASS:
1029 case PCI_IVAR_PROGIF:
1030 case PCI_IVAR_REVID:
1031 case PCI_IVAR_INTPIN:
1035 case PCI_IVAR_FUNCTION:
1036 return EINVAL; /* disallow for now */
1043 /************************************************************************/
1044 /* Compatibility with PCI bus (XXX: Do we need this?) */
1045 /************************************************************************/
1048 * PCI power manangement
1051 cardbus_set_powerstate_method(device_t cbdev, device_t child, int state)
1053 struct cardbus_devinfo *dinfo = device_get_ivars(child);
1054 pcicfgregs *cfg = &dinfo->pci.cfg;
1058 if (cfg->pp_cap != 0) {
1059 status = PCI_READ_CONFIG(cbdev, child, cfg->pp_status, 2)
1060 & ~PCIM_PSTAT_DMASK;
1063 case PCI_POWERSTATE_D0:
1064 status |= PCIM_PSTAT_D0;
1066 case PCI_POWERSTATE_D1:
1067 if (cfg->pp_cap & PCIM_PCAP_D1SUPP) {
1068 status |= PCIM_PSTAT_D1;
1070 result = EOPNOTSUPP;
1073 case PCI_POWERSTATE_D2:
1074 if (cfg->pp_cap & PCIM_PCAP_D2SUPP) {
1075 status |= PCIM_PSTAT_D2;
1077 result = EOPNOTSUPP;
1080 case PCI_POWERSTATE_D3:
1081 status |= PCIM_PSTAT_D3;
1087 PCI_WRITE_CONFIG(cbdev, child, cfg->pp_status,
1096 cardbus_get_powerstate_method(device_t cbdev, device_t child)
1098 struct cardbus_devinfo *dinfo = device_get_ivars(child);
1099 pcicfgregs *cfg = &dinfo->pci.cfg;
1103 if (cfg->pp_cap != 0) {
1104 status = PCI_READ_CONFIG(cbdev, child, cfg->pp_status, 2);
1105 switch (status & PCIM_PSTAT_DMASK) {
1107 result = PCI_POWERSTATE_D0;
1110 result = PCI_POWERSTATE_D1;
1113 result = PCI_POWERSTATE_D2;
1116 result = PCI_POWERSTATE_D3;
1119 result = PCI_POWERSTATE_UNKNOWN;
1123 /* No support, device is always at D0 */
1124 result = PCI_POWERSTATE_D0;
1130 cardbus_read_config_method(device_t cbdev, device_t child, int reg, int width)
1132 struct cardbus_devinfo *dinfo = device_get_ivars(child);
1133 pcicfgregs *cfg = &dinfo->pci.cfg;
1135 return PCIB_READ_CONFIG(device_get_parent(cbdev),
1136 cfg->bus, cfg->slot, cfg->func, reg, width);
1140 cardbus_write_config_method(device_t cbdev, device_t child, int reg,
1141 u_int32_t val, int width)
1143 struct cardbus_devinfo *dinfo = device_get_ivars(child);
1144 pcicfgregs *cfg = &dinfo->pci.cfg;
1146 PCIB_WRITE_CONFIG(device_get_parent(cbdev),
1147 cfg->bus, cfg->slot, cfg->func, reg, val, width);
1150 static __inline void
1151 cardbus_set_command_bit(device_t cbdev, device_t child, u_int16_t bit)
1155 command = PCI_READ_CONFIG(cbdev, child, PCIR_COMMAND, 2);
1157 PCI_WRITE_CONFIG(cbdev, child, PCIR_COMMAND, command, 2);
1160 static __inline void
1161 cardbus_clear_command_bit(device_t cbdev, device_t child, u_int16_t bit)
1165 command = PCI_READ_CONFIG(cbdev, child, PCIR_COMMAND, 2);
1167 PCI_WRITE_CONFIG(cbdev, child, PCIR_COMMAND, command, 2);
1171 cardbus_enable_busmaster_method(device_t cbdev, device_t child)
1173 cardbus_set_command_bit(cbdev, child, PCIM_CMD_BUSMASTEREN);
1177 cardbus_disable_busmaster_method(device_t cbdev, device_t child)
1179 cardbus_clear_command_bit(cbdev, child, PCIM_CMD_BUSMASTEREN);
1183 cardbus_enable_io_method(device_t cbdev, device_t child, int space)
1186 case SYS_RES_IOPORT:
1187 cardbus_set_command_bit(cbdev, child, PCIM_CMD_PORTEN);
1189 case SYS_RES_MEMORY:
1190 cardbus_set_command_bit(cbdev, child, PCIM_CMD_MEMEN);
1196 cardbus_disable_io_method(device_t cbdev, device_t child, int space)
1199 case SYS_RES_IOPORT:
1200 cardbus_clear_command_bit(cbdev, child, PCIM_CMD_PORTEN);
1202 case SYS_RES_MEMORY:
1203 cardbus_clear_command_bit(cbdev, child, PCIM_CMD_MEMEN);
1208 static device_method_t cardbus_methods[] = {
1209 /* Device interface */
1210 DEVMETHOD(device_probe, cardbus_probe),
1211 DEVMETHOD(device_attach, cardbus_attach),
1212 DEVMETHOD(device_detach, cardbus_detach),
1213 DEVMETHOD(device_shutdown, bus_generic_shutdown),
1214 DEVMETHOD(device_suspend, cardbus_suspend),
1215 DEVMETHOD(device_resume, cardbus_resume),
1218 DEVMETHOD(bus_print_child, cardbus_print_child),
1219 DEVMETHOD(bus_probe_nomatch, cardbus_probe_nomatch),
1220 DEVMETHOD(bus_read_ivar, cardbus_read_ivar),
1221 DEVMETHOD(bus_write_ivar, cardbus_write_ivar),
1222 DEVMETHOD(bus_driver_added, cardbus_driver_added),
1223 DEVMETHOD(bus_alloc_resource, cardbus_alloc_resource),
1224 DEVMETHOD(bus_release_resource, cardbus_release_resource),
1225 DEVMETHOD(bus_activate_resource, bus_generic_activate_resource),
1226 DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource),
1227 DEVMETHOD(bus_setup_intr, cardbus_setup_intr),
1228 DEVMETHOD(bus_teardown_intr, cardbus_teardown_intr),
1230 DEVMETHOD(bus_set_resource, cardbus_set_resource_method),
1231 DEVMETHOD(bus_get_resource, cardbus_get_resource_method),
1232 DEVMETHOD(bus_delete_resource, cardbus_delete_resource_method),
1233 DEVMETHOD(bus_child_pnpinfo_str, cardbus_child_pnpinfo_str),
1234 DEVMETHOD(bus_child_location_str, cardbus_child_location_str),
1236 /* Card Interface */
1237 DEVMETHOD(card_attach_card, cardbus_attach_card),
1238 DEVMETHOD(card_detach_card, cardbus_detach_card),
1239 DEVMETHOD(card_cis_read, cardbus_cis_read),
1240 DEVMETHOD(card_cis_free, cardbus_cis_free),
1242 /* Cardbus/PCI interface */
1243 DEVMETHOD(pci_read_config, cardbus_read_config_method),
1244 DEVMETHOD(pci_write_config, cardbus_write_config_method),
1245 DEVMETHOD(pci_enable_busmaster, cardbus_enable_busmaster_method),
1246 DEVMETHOD(pci_disable_busmaster, cardbus_disable_busmaster_method),
1247 DEVMETHOD(pci_enable_io, cardbus_enable_io_method),
1248 DEVMETHOD(pci_disable_io, cardbus_disable_io_method),
1249 DEVMETHOD(pci_get_powerstate, cardbus_get_powerstate_method),
1250 DEVMETHOD(pci_set_powerstate, cardbus_set_powerstate_method),
1255 static driver_t cardbus_driver = {
1261 static devclass_t cardbus_devclass;
1263 DRIVER_MODULE(cardbus, cbb, cardbus_driver, cardbus_devclass, 0, 0);
1264 MODULE_VERSION(cardbus, 1);
1265 MODULE_DEPEND(cardbus, exca, 1, 1, 1);
1267 MODULE_DEPEND(cardbus, pccbb, 1, 1, 1);