The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/cardbus/cardbus.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

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

Cache object: d573870e122f5fa83cb803274a05afa5


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.