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/pci/pci.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) 1997, Stefan Esser <se@freebsd.org>
    3  * Copyright (c) 2000, Michael Smith <msmith@freebsd.org>
    4  * Copyright (c) 2000, BSDi
    5  * All rights reserved.
    6  *
    7  * Redistribution and use in source and binary forms, with or without
    8  * modification, are permitted provided that the following conditions
    9  * are met:
   10  * 1. Redistributions of source code must retain the above copyright
   11  *    notice unmodified, this list of conditions, and the following
   12  *    disclaimer.
   13  * 2. Redistributions in binary form must reproduce the above copyright
   14  *    notice, this list of conditions and the following disclaimer in the
   15  *    documentation and/or other materials provided with the distribution.
   16  *
   17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
   18  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   19  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
   20  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
   21  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
   22  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   23  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
   24  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
   26  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   27  *
   28  * $FreeBSD: releng/5.0/sys/dev/pci/pci.c 107300 2002-11-27 06:41:28Z imp $
   29  *
   30  */
   31 
   32 #include "opt_bus.h"
   33 
   34 #include <sys/param.h>
   35 #include <sys/systm.h>
   36 #include <sys/malloc.h>
   37 #include <sys/module.h>
   38 #include <sys/linker.h>
   39 #include <sys/fcntl.h>
   40 #include <sys/conf.h>
   41 #include <sys/kernel.h>
   42 #include <sys/queue.h>
   43 #include <sys/sysctl.h>
   44 #include <sys/types.h>
   45 
   46 #include <vm/vm.h>
   47 #include <vm/pmap.h>
   48 #include <vm/vm_extern.h>
   49 
   50 #include <sys/bus.h>
   51 #include <machine/bus.h>
   52 #include <sys/rman.h>
   53 #include <machine/resource.h>
   54 
   55 #include <sys/pciio.h>
   56 #include <dev/pci/pcireg.h>
   57 #include <dev/pci/pcivar.h>
   58 #include <dev/pci/pci_private.h>
   59 
   60 #include "pcib_if.h"
   61 #include "pci_if.h"
   62 
   63 static u_int32_t        pci_mapbase(unsigned mapreg);
   64 static int              pci_maptype(unsigned mapreg);
   65 static int              pci_mapsize(unsigned testval);
   66 static int              pci_maprange(unsigned mapreg);
   67 static void             pci_fixancient(pcicfgregs *cfg);
   68 static void             pci_hdrtypedata(device_t pcib, int b, int s, int f, 
   69                                         pcicfgregs *cfg);
   70 static void             pci_read_extcap(device_t pcib, pcicfgregs *cfg);
   71 
   72 static int              pci_porten(device_t pcib, int b, int s, int f);
   73 static int              pci_memen(device_t pcib, int b, int s, int f);
   74 static int              pci_add_map(device_t pcib, int b, int s, int f, int reg, 
   75                                     struct resource_list *rl);
   76 static void             pci_add_resources(device_t pcib, device_t dev);
   77 static int              pci_probe(device_t dev);
   78 static int              pci_attach(device_t dev);
   79 static void             pci_load_vendor_data(void);
   80 static int              pci_describe_parse_line(char **ptr, int *vendor, 
   81                                                 int *device, char **desc);
   82 static char             *pci_describe_device(device_t dev);
   83 static int              pci_modevent(module_t mod, int what, void *arg);
   84 
   85 static device_method_t pci_methods[] = {
   86         /* Device interface */
   87         DEVMETHOD(device_probe,         pci_probe),
   88         DEVMETHOD(device_attach,        pci_attach),
   89         DEVMETHOD(device_shutdown,      bus_generic_shutdown),
   90         DEVMETHOD(device_suspend,       bus_generic_suspend),
   91         DEVMETHOD(device_resume,        bus_generic_resume),
   92 
   93         /* Bus interface */
   94         DEVMETHOD(bus_print_child,      pci_print_child),
   95         DEVMETHOD(bus_probe_nomatch,    pci_probe_nomatch),
   96         DEVMETHOD(bus_read_ivar,        pci_read_ivar),
   97         DEVMETHOD(bus_write_ivar,       pci_write_ivar),
   98         DEVMETHOD(bus_driver_added,     bus_generic_driver_added),
   99         DEVMETHOD(bus_setup_intr,       bus_generic_setup_intr),
  100         DEVMETHOD(bus_teardown_intr,    bus_generic_teardown_intr),
  101 
  102         DEVMETHOD(bus_get_resource_list,pci_get_resource_list),
  103         DEVMETHOD(bus_set_resource,     bus_generic_rl_set_resource),
  104         DEVMETHOD(bus_get_resource,     bus_generic_rl_get_resource),
  105         DEVMETHOD(bus_delete_resource,  pci_delete_resource),
  106         DEVMETHOD(bus_alloc_resource,   pci_alloc_resource),
  107         DEVMETHOD(bus_release_resource, bus_generic_rl_release_resource),
  108         DEVMETHOD(bus_activate_resource, bus_generic_activate_resource),
  109         DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource),
  110 
  111         /* PCI interface */
  112         DEVMETHOD(pci_read_config,      pci_read_config_method),
  113         DEVMETHOD(pci_write_config,     pci_write_config_method),
  114         DEVMETHOD(pci_enable_busmaster, pci_enable_busmaster_method),
  115         DEVMETHOD(pci_disable_busmaster, pci_disable_busmaster_method),
  116         DEVMETHOD(pci_enable_io,        pci_enable_io_method),
  117         DEVMETHOD(pci_disable_io,       pci_disable_io_method),
  118         DEVMETHOD(pci_get_powerstate,   pci_get_powerstate_method),
  119         DEVMETHOD(pci_set_powerstate,   pci_set_powerstate_method),
  120 
  121         { 0, 0 }
  122 };
  123 
  124 static driver_t pci_driver = {
  125         "pci",
  126         pci_methods,
  127         0,                      /* no softc */
  128 };
  129 
  130 devclass_t      pci_devclass;
  131 DRIVER_MODULE(pci, pcib, pci_driver, pci_devclass, pci_modevent, 0);
  132 MODULE_VERSION(pci, 1);
  133 
  134 static char     *pci_vendordata;
  135 static size_t   pci_vendordata_size;
  136 
  137 
  138 struct pci_quirk {
  139         u_int32_t devid;        /* Vendor/device of the card */
  140         int     type;
  141 #define PCI_QUIRK_MAP_REG       1 /* PCI map register in weird place */
  142         int     arg1;
  143         int     arg2;
  144 };
  145 
  146 struct pci_quirk pci_quirks[] = {
  147         /* The Intel 82371AB and 82443MX has a map register at offset 0x90. */
  148         { 0x71138086, PCI_QUIRK_MAP_REG,        0x90,    0 },
  149         { 0x719b8086, PCI_QUIRK_MAP_REG,        0x90,    0 },
  150         /* As does the Serverworks OSB4 (the SMBus mapping register) */
  151         { 0x02001166, PCI_QUIRK_MAP_REG,        0x90,    0 },
  152 
  153         { 0 }
  154 };
  155 
  156 /* map register information */
  157 #define PCI_MAPMEM      0x01    /* memory map */
  158 #define PCI_MAPMEMP     0x02    /* prefetchable memory map */
  159 #define PCI_MAPPORT     0x04    /* port map */
  160 
  161 struct devlist pci_devq;
  162 u_int32_t pci_generation;
  163 u_int32_t pci_numdevs = 0;
  164 
  165 /* sysctl vars */
  166 SYSCTL_NODE(_hw, OID_AUTO, pci, CTLFLAG_RD, 0, "PCI bus tuning parameters");
  167 
  168 static int pci_enable_io_modes = 1;
  169 TUNABLE_INT("hw.pci.enable_io_modes", (int *)&pci_enable_io_modes);
  170 SYSCTL_INT(_hw_pci, OID_AUTO, enable_io_modes, CTLFLAG_RW,
  171     &pci_enable_io_modes, 1,
  172     "Enable I/O and memory bits in the config register.  Some BIOSes do not\n\
  173 enable these bits correctly.  We'd like to do this all the time, but there\n\
  174 are some peripherals that this causes problems with.");
  175 
  176 /* Find a device_t by bus/slot/function */
  177 
  178 device_t
  179 pci_find_bsf(u_int8_t bus, u_int8_t slot, u_int8_t func)
  180 {
  181         struct pci_devinfo *dinfo;
  182 
  183         STAILQ_FOREACH(dinfo, &pci_devq, pci_links) {
  184                 if ((dinfo->cfg.bus == bus) &&
  185                     (dinfo->cfg.slot == slot) &&
  186                     (dinfo->cfg.func == func)) {
  187                         return (dinfo->cfg.dev);
  188                 }
  189         }
  190 
  191         return (NULL);
  192 }
  193 
  194 /* Find a device_t by vendor/device ID */
  195 
  196 device_t
  197 pci_find_device(u_int16_t vendor, u_int16_t device)
  198 {
  199         struct pci_devinfo *dinfo;
  200 
  201         STAILQ_FOREACH(dinfo, &pci_devq, pci_links) {
  202                 if ((dinfo->cfg.vendor == vendor) &&
  203                     (dinfo->cfg.device == device)) {
  204                         return (dinfo->cfg.dev);
  205                 }
  206         }
  207 
  208         return (NULL);
  209 }
  210 
  211 /* return base address of memory or port map */
  212 
  213 static u_int32_t
  214 pci_mapbase(unsigned mapreg)
  215 {
  216         int mask = 0x03;
  217         if ((mapreg & 0x01) == 0)
  218                 mask = 0x0f;
  219         return (mapreg & ~mask);
  220 }
  221 
  222 /* return map type of memory or port map */
  223 
  224 static int
  225 pci_maptype(unsigned mapreg)
  226 {
  227         static u_int8_t maptype[0x10] = {
  228                 PCI_MAPMEM,             PCI_MAPPORT,
  229                 PCI_MAPMEM,             0,
  230                 PCI_MAPMEM,             PCI_MAPPORT,
  231                 0,                      0,
  232                 PCI_MAPMEM|PCI_MAPMEMP, PCI_MAPPORT,
  233                 PCI_MAPMEM|PCI_MAPMEMP, 0,
  234                 PCI_MAPMEM|PCI_MAPMEMP, PCI_MAPPORT,
  235                 0,                      0,
  236         };
  237 
  238         return maptype[mapreg & 0x0f];
  239 }
  240 
  241 /* return log2 of map size decoded for memory or port map */
  242 
  243 static int
  244 pci_mapsize(unsigned testval)
  245 {
  246         int ln2size;
  247 
  248         testval = pci_mapbase(testval);
  249         ln2size = 0;
  250         if (testval != 0) {
  251                 while ((testval & 1) == 0)
  252                 {
  253                         ln2size++;
  254                         testval >>= 1;
  255                 }
  256         }
  257         return (ln2size);
  258 }
  259 
  260 /* return log2 of address range supported by map register */
  261 
  262 static int
  263 pci_maprange(unsigned mapreg)
  264 {
  265         int ln2range = 0;
  266         switch (mapreg & 0x07) {
  267         case 0x00:
  268         case 0x01:
  269         case 0x05:
  270                 ln2range = 32;
  271                 break;
  272         case 0x02:
  273                 ln2range = 20;
  274                 break;
  275         case 0x04:
  276                 ln2range = 64;
  277                 break;
  278         }
  279         return (ln2range);
  280 }
  281 
  282 /* adjust some values from PCI 1.0 devices to match 2.0 standards ... */
  283 
  284 static void
  285 pci_fixancient(pcicfgregs *cfg)
  286 {
  287         if (cfg->hdrtype != 0)
  288                 return;
  289 
  290         /* PCI to PCI bridges use header type 1 */
  291         if (cfg->baseclass == PCIC_BRIDGE && cfg->subclass == PCIS_BRIDGE_PCI)
  292                 cfg->hdrtype = 1;
  293 }
  294 
  295 /* extract header type specific config data */
  296 
  297 static void
  298 pci_hdrtypedata(device_t pcib, int b, int s, int f, pcicfgregs *cfg)
  299 {
  300 #define REG(n, w)       PCIB_READ_CONFIG(pcib, b, s, f, n, w)
  301         switch (cfg->hdrtype) {
  302         case 0:
  303                 cfg->subvendor      = REG(PCIR_SUBVEND_0, 2);
  304                 cfg->subdevice      = REG(PCIR_SUBDEV_0, 2);
  305                 cfg->nummaps        = PCI_MAXMAPS_0;
  306                 break;
  307         case 1:
  308                 cfg->subvendor      = REG(PCIR_SUBVEND_1, 2);
  309                 cfg->subdevice      = REG(PCIR_SUBDEV_1, 2);
  310                 cfg->nummaps        = PCI_MAXMAPS_1;
  311                 break;
  312         case 2:
  313                 cfg->subvendor      = REG(PCIR_SUBVEND_2, 2);
  314                 cfg->subdevice      = REG(PCIR_SUBDEV_2, 2);
  315                 cfg->nummaps        = PCI_MAXMAPS_2;
  316                 break;
  317         }
  318 #undef REG
  319 }
  320 
  321 /* read configuration header into pcicfgregs structure */
  322 
  323 struct pci_devinfo *
  324 pci_read_device(device_t pcib, int b, int s, int f, size_t size)
  325 {
  326 #define REG(n, w)       PCIB_READ_CONFIG(pcib, b, s, f, n, w)
  327         pcicfgregs *cfg = NULL;
  328         struct pci_devinfo *devlist_entry;
  329         struct devlist *devlist_head;
  330 
  331         devlist_head = &pci_devq;
  332 
  333         devlist_entry = NULL;
  334 
  335         if (PCIB_READ_CONFIG(pcib, b, s, f, PCIR_DEVVENDOR, 4) != -1) {
  336                 devlist_entry = malloc(size, M_DEVBUF, M_WAITOK | M_ZERO);
  337                 if (devlist_entry == NULL)
  338                         return (NULL);
  339 
  340                 cfg = &devlist_entry->cfg;
  341                 
  342                 cfg->bus                = b;
  343                 cfg->slot               = s;
  344                 cfg->func               = f;
  345                 cfg->vendor             = REG(PCIR_VENDOR, 2);
  346                 cfg->device             = REG(PCIR_DEVICE, 2);
  347                 cfg->cmdreg             = REG(PCIR_COMMAND, 2);
  348                 cfg->statreg            = REG(PCIR_STATUS, 2);
  349                 cfg->baseclass          = REG(PCIR_CLASS, 1);
  350                 cfg->subclass           = REG(PCIR_SUBCLASS, 1);
  351                 cfg->progif             = REG(PCIR_PROGIF, 1);
  352                 cfg->revid              = REG(PCIR_REVID, 1);
  353                 cfg->hdrtype            = REG(PCIR_HEADERTYPE, 1);
  354                 cfg->cachelnsz          = REG(PCIR_CACHELNSZ, 1);
  355                 cfg->lattimer           = REG(PCIR_LATTIMER, 1);
  356                 cfg->intpin             = REG(PCIR_INTPIN, 1);
  357                 cfg->intline            = REG(PCIR_INTLINE, 1);
  358 
  359                 cfg->mingnt             = REG(PCIR_MINGNT, 1);
  360                 cfg->maxlat             = REG(PCIR_MAXLAT, 1);
  361 
  362                 cfg->mfdev              = (cfg->hdrtype & PCIM_MFDEV) != 0;
  363                 cfg->hdrtype            &= ~PCIM_MFDEV;
  364 
  365                 pci_fixancient(cfg);
  366                 pci_hdrtypedata(pcib, b, s, f, cfg);
  367 
  368                 if (REG(PCIR_STATUS, 2) & PCIM_STATUS_CAPPRESENT)
  369                         pci_read_extcap(pcib, cfg);
  370 
  371                 STAILQ_INSERT_TAIL(devlist_head, devlist_entry, pci_links);
  372 
  373                 devlist_entry->conf.pc_sel.pc_bus = cfg->bus;
  374                 devlist_entry->conf.pc_sel.pc_dev = cfg->slot;
  375                 devlist_entry->conf.pc_sel.pc_func = cfg->func;
  376                 devlist_entry->conf.pc_hdr = cfg->hdrtype;
  377 
  378                 devlist_entry->conf.pc_subvendor = cfg->subvendor;
  379                 devlist_entry->conf.pc_subdevice = cfg->subdevice;
  380                 devlist_entry->conf.pc_vendor = cfg->vendor;
  381                 devlist_entry->conf.pc_device = cfg->device;
  382 
  383                 devlist_entry->conf.pc_class = cfg->baseclass;
  384                 devlist_entry->conf.pc_subclass = cfg->subclass;
  385                 devlist_entry->conf.pc_progif = cfg->progif;
  386                 devlist_entry->conf.pc_revid = cfg->revid;
  387 
  388                 pci_numdevs++;
  389                 pci_generation++;
  390         }
  391         return (devlist_entry);
  392 #undef REG
  393 }
  394 
  395 static void
  396 pci_read_extcap(device_t pcib, pcicfgregs *cfg)
  397 {
  398 #define REG(n, w)       PCIB_READ_CONFIG(pcib, cfg->bus, cfg->slot, cfg->func, n, w)
  399         int     ptr, nextptr, ptrptr;
  400 
  401         switch (cfg->hdrtype) {
  402         case 0:
  403                 ptrptr = 0x34;
  404                 break;
  405         case 2:
  406                 ptrptr = 0x14;
  407                 break;
  408         default:
  409                 return;         /* no extended capabilities support */
  410         }
  411         nextptr = REG(ptrptr, 1);       /* sanity check? */
  412 
  413         /*
  414          * Read capability entries.
  415          */
  416         while (nextptr != 0) {
  417                 /* Sanity check */
  418                 if (nextptr > 255) {
  419                         printf("illegal PCI extended capability offset %d\n",
  420                             nextptr);
  421                         return;
  422                 }
  423                 /* Find the next entry */
  424                 ptr = nextptr;
  425                 nextptr = REG(ptr + 1, 1);
  426 
  427                 /* Process this entry */
  428                 switch (REG(ptr, 1)) {
  429                 case 0x01:              /* PCI power management */
  430                         if (cfg->pp_cap == 0) {
  431                                 cfg->pp_cap = REG(ptr + PCIR_POWER_CAP, 2);
  432                                 cfg->pp_status = ptr + PCIR_POWER_STATUS;
  433                                 cfg->pp_pmcsr = ptr + PCIR_POWER_PMCSR;
  434                                 if ((nextptr - ptr) > PCIR_POWER_DATA)
  435                                         cfg->pp_data = ptr + PCIR_POWER_DATA;
  436                         }
  437                         break;
  438                 default:
  439                         break;
  440                 }
  441         }
  442 #undef REG
  443 }
  444 
  445 /* free pcicfgregs structure and all depending data structures */
  446 
  447 int
  448 pci_freecfg(struct pci_devinfo *dinfo)
  449 {
  450         struct devlist *devlist_head;
  451 
  452         devlist_head = &pci_devq;
  453 
  454         /* XXX this hasn't been tested */
  455         STAILQ_REMOVE(devlist_head, dinfo, pci_devinfo, pci_links);
  456         free(dinfo, M_DEVBUF);
  457 
  458         /* increment the generation count */
  459         pci_generation++;
  460 
  461         /* we're losing one device */
  462         pci_numdevs--;
  463         return (0);
  464 }
  465 
  466 /*
  467  * PCI power manangement
  468  */
  469 int
  470 pci_set_powerstate_method(device_t dev, device_t child, int state)
  471 {
  472         struct pci_devinfo *dinfo = device_get_ivars(child);
  473         pcicfgregs *cfg = &dinfo->cfg;
  474         u_int16_t status;
  475         int result;
  476 
  477         if (cfg->pp_cap != 0) {
  478                 status = PCI_READ_CONFIG(dev, child, cfg->pp_status, 2) & ~PCIM_PSTAT_DMASK;
  479                 result = 0;
  480                 switch (state) {
  481                 case PCI_POWERSTATE_D0:
  482                         status |= PCIM_PSTAT_D0;
  483                         break;
  484                 case PCI_POWERSTATE_D1:
  485                         if (cfg->pp_cap & PCIM_PCAP_D1SUPP) {
  486                                 status |= PCIM_PSTAT_D1;
  487                         } else {
  488                                 result = EOPNOTSUPP;
  489                         }
  490                         break;
  491                 case PCI_POWERSTATE_D2:
  492                         if (cfg->pp_cap & PCIM_PCAP_D2SUPP) {
  493                                 status |= PCIM_PSTAT_D2;
  494                         } else {
  495                                 result = EOPNOTSUPP;
  496                         }
  497                         break;
  498                 case PCI_POWERSTATE_D3:
  499                         status |= PCIM_PSTAT_D3;
  500                         break;
  501                 default:
  502                         result = EINVAL;
  503                 }
  504                 if (result == 0)
  505                         PCI_WRITE_CONFIG(dev, child, cfg->pp_status, status, 2);
  506         } else {
  507                 result = ENXIO;
  508         }
  509         return(result);
  510 }
  511 
  512 int
  513 pci_get_powerstate_method(device_t dev, device_t child)
  514 {
  515         struct pci_devinfo *dinfo = device_get_ivars(child);
  516         pcicfgregs *cfg = &dinfo->cfg;
  517         u_int16_t status;
  518         int result;
  519 
  520         if (cfg->pp_cap != 0) {
  521                 status = PCI_READ_CONFIG(dev, child, cfg->pp_status, 2);
  522                 switch (status & PCIM_PSTAT_DMASK) {
  523                 case PCIM_PSTAT_D0:
  524                         result = PCI_POWERSTATE_D0;
  525                         break;
  526                 case PCIM_PSTAT_D1:
  527                         result = PCI_POWERSTATE_D1;
  528                         break;
  529                 case PCIM_PSTAT_D2:
  530                         result = PCI_POWERSTATE_D2;
  531                         break;
  532                 case PCIM_PSTAT_D3:
  533                         result = PCI_POWERSTATE_D3;
  534                         break;
  535                 default:
  536                         result = PCI_POWERSTATE_UNKNOWN;
  537                         break;
  538                 }
  539         } else {
  540                 /* No support, device is always at D0 */
  541                 result = PCI_POWERSTATE_D0;
  542         }
  543         return(result);
  544 }
  545 
  546 /*
  547  * Some convenience functions for PCI device drivers.
  548  */
  549 
  550 static __inline void
  551 pci_set_command_bit(device_t dev, device_t child, u_int16_t bit)
  552 {
  553         u_int16_t       command;
  554 
  555         command = PCI_READ_CONFIG(dev, child, PCIR_COMMAND, 2);
  556         command |= bit;
  557         PCI_WRITE_CONFIG(dev, child, PCIR_COMMAND, command, 2);
  558 }
  559 
  560 static __inline void
  561 pci_clear_command_bit(device_t dev, device_t child, u_int16_t bit)
  562 {
  563         u_int16_t       command;
  564 
  565         command = PCI_READ_CONFIG(dev, child, PCIR_COMMAND, 2);
  566         command &= ~bit;
  567         PCI_WRITE_CONFIG(dev, child, PCIR_COMMAND, command, 2);
  568 }
  569 
  570 void
  571 pci_enable_busmaster_method(device_t dev, device_t child)
  572 {
  573         pci_set_command_bit(dev, child, PCIM_CMD_BUSMASTEREN);
  574 }
  575 
  576 void
  577 pci_disable_busmaster_method(device_t dev, device_t child)
  578 {
  579         pci_clear_command_bit(dev, child, PCIM_CMD_BUSMASTEREN);
  580 }
  581 
  582 void
  583 pci_enable_io_method(device_t dev, device_t child, int space)
  584 {
  585         switch(space) {
  586         case SYS_RES_IOPORT:
  587                 pci_set_command_bit(dev, child, PCIM_CMD_PORTEN);
  588                 break;
  589         case SYS_RES_MEMORY:
  590                 pci_set_command_bit(dev, child, PCIM_CMD_MEMEN);
  591                 break;
  592         }
  593 }
  594 
  595 void
  596 pci_disable_io_method(device_t dev, device_t child, int space)
  597 {
  598         switch(space) {
  599         case SYS_RES_IOPORT:
  600                 pci_clear_command_bit(dev, child, PCIM_CMD_PORTEN);
  601                 break;
  602         case SYS_RES_MEMORY:
  603                 pci_clear_command_bit(dev, child, PCIM_CMD_MEMEN);
  604                 break;
  605         }
  606 }
  607 
  608 /*
  609  * New style pci driver.  Parent device is either a pci-host-bridge or a
  610  * pci-pci-bridge.  Both kinds are represented by instances of pcib.
  611  */
  612 
  613 void
  614 pci_print_verbose(struct pci_devinfo *dinfo)
  615 {
  616         if (bootverbose) {
  617                 pcicfgregs *cfg = &dinfo->cfg;
  618 
  619                 printf("found->\tvendor=0x%04x, dev=0x%04x, revid=0x%02x\n", 
  620                     cfg->vendor, cfg->device, cfg->revid);
  621                 printf("\tbus=%d, slot=%d, func=%d\n",
  622                     cfg->bus, cfg->slot, cfg->func);
  623                 printf("\tclass=%02x-%02x-%02x, hdrtype=0x%02x, mfdev=%d\n",
  624                     cfg->baseclass, cfg->subclass, cfg->progif, cfg->hdrtype,
  625                     cfg->mfdev);
  626                 printf("\tcmdreg=0x%04x, statreg=0x%04x, cachelnsz=%d (dwords)\n", 
  627                     cfg->cmdreg, cfg->statreg, cfg->cachelnsz);
  628                 printf("\tlattimer=0x%02x (%d ns), mingnt=0x%02x (%d ns), maxlat=0x%02x (%d ns)\n",
  629                     cfg->lattimer, cfg->lattimer * 30, cfg->mingnt,
  630                     cfg->mingnt * 250, cfg->maxlat, cfg->maxlat * 250);
  631                 if (cfg->intpin > 0)
  632                         printf("\tintpin=%c, irq=%d\n",
  633                             cfg->intpin +'a' -1, cfg->intline);
  634                 if (cfg->pp_cap) {
  635                         u_int16_t status;
  636 
  637                         status = pci_read_config(cfg->dev, cfg->pp_status, 2);
  638                         printf("\tpowerspec %d  supports D0%s%s D3  current D%d\n",
  639                             cfg->pp_cap & PCIM_PCAP_SPEC,
  640                             cfg->pp_cap & PCIM_PCAP_D1SUPP ? " D1" : "",
  641                             cfg->pp_cap & PCIM_PCAP_D2SUPP ? " D2" : "",
  642                             status & PCIM_PSTAT_DMASK);
  643                 }
  644         }
  645 }
  646 
  647 static int
  648 pci_porten(device_t pcib, int b, int s, int f)
  649 {
  650         return (PCIB_READ_CONFIG(pcib, b, s, f, PCIR_COMMAND, 2)
  651                 & PCIM_CMD_PORTEN) != 0;
  652 }
  653 
  654 static int
  655 pci_memen(device_t pcib, int b, int s, int f)
  656 {
  657         return (PCIB_READ_CONFIG(pcib, b, s, f, PCIR_COMMAND, 2)
  658                 & PCIM_CMD_MEMEN) != 0;
  659 }
  660 
  661 /*
  662  * Add a resource based on a pci map register. Return 1 if the map
  663  * register is a 32bit map register or 2 if it is a 64bit register.
  664  */
  665 static int
  666 pci_add_map(device_t pcib, int b, int s, int f, int reg,
  667             struct resource_list *rl)
  668 {
  669         u_int32_t map;
  670         u_int64_t base;
  671         u_int8_t ln2size;
  672         u_int8_t ln2range;
  673         u_int32_t testval;
  674         u_int16_t cmd;
  675         int type;
  676 
  677         map = PCIB_READ_CONFIG(pcib, b, s, f, reg, 4);
  678 
  679         if (map == 0 || map == 0xffffffff)
  680                 return (1); /* skip invalid entry */
  681 
  682         PCIB_WRITE_CONFIG(pcib, b, s, f, reg, 0xffffffff, 4);
  683         testval = PCIB_READ_CONFIG(pcib, b, s, f, reg, 4);
  684         PCIB_WRITE_CONFIG(pcib, b, s, f, reg, map, 4);
  685 
  686         base = pci_mapbase(map);
  687         if (pci_maptype(map) & PCI_MAPMEM)
  688                 type = SYS_RES_MEMORY;
  689         else
  690                 type = SYS_RES_IOPORT;
  691         ln2size = pci_mapsize(testval);
  692         ln2range = pci_maprange(testval);
  693         if (ln2range == 64) {
  694                 /* Read the other half of a 64bit map register */
  695                 base |= (u_int64_t) PCIB_READ_CONFIG(pcib, b, s, f, reg + 4, 4) << 32;
  696         }
  697 
  698         if (bootverbose) {
  699                 printf("\tmap[%02x]: type %x, range %2d, base %08x, size %2d",
  700                     reg, pci_maptype(map), ln2range, 
  701                     (unsigned int) base, ln2size);
  702                 if (type == SYS_RES_IOPORT && !pci_porten(pcib, b, s, f))
  703                         printf(", port disabled\n");
  704                 else if (type == SYS_RES_MEMORY && !pci_memen(pcib, b, s, f))
  705                         printf(", memory disabled\n");
  706                 else
  707                         printf(", enabled\n");
  708         }
  709 
  710         /*
  711          * This code theoretically does the right thing, but has
  712          * undesirable side effects in some cases where
  713          * peripherals respond oddly to having these bits
  714          * enabled.  Leave them alone by default.
  715          */
  716         if (pci_enable_io_modes) {
  717                 /* Turn on resources that have been left off by a lazy BIOS */
  718                 if (type == SYS_RES_IOPORT && !pci_porten(pcib, b, s, f)) {
  719                         cmd = PCIB_READ_CONFIG(pcib, b, s, f, PCIR_COMMAND, 2);
  720                         cmd |= PCIM_CMD_PORTEN;
  721                         PCIB_WRITE_CONFIG(pcib, b, s, f, PCIR_COMMAND, cmd, 2);
  722                 }
  723                 if (type == SYS_RES_MEMORY && !pci_memen(pcib, b, s, f)) {
  724                         cmd = PCIB_READ_CONFIG(pcib, b, s, f, PCIR_COMMAND, 2);
  725                         cmd |= PCIM_CMD_MEMEN;
  726                         PCIB_WRITE_CONFIG(pcib, b, s, f, PCIR_COMMAND, cmd, 2);
  727                 }
  728         } else {
  729                 if (type == SYS_RES_IOPORT && !pci_porten(pcib, b, s, f))
  730                         return (1);
  731                 if (type == SYS_RES_MEMORY && !pci_memen(pcib, b, s, f))
  732                         return (1);
  733         }
  734         resource_list_add(rl, type, reg, base, base + (1 << ln2size) - 1,
  735             (1 << ln2size));
  736 
  737         return ((ln2range == 64) ? 2 : 1);
  738 }
  739 
  740 static void
  741 pci_add_resources(device_t pcib, device_t dev)
  742 {
  743         struct pci_devinfo *dinfo = device_get_ivars(dev);
  744         pcicfgregs *cfg = &dinfo->cfg;
  745         struct resource_list *rl = &dinfo->resources;
  746         struct pci_quirk *q;
  747         int b, i, f, s;
  748 
  749         b = cfg->bus;
  750         s = cfg->slot;
  751         f = cfg->func;
  752         for (i = 0; i < cfg->nummaps;) {
  753                 i += pci_add_map(pcib, b, s, f, PCIR_MAPS + i*4, rl);
  754         }
  755 
  756         for (q = &pci_quirks[0]; q->devid; q++) {
  757                 if (q->devid == ((cfg->device << 16) | cfg->vendor)
  758                     && q->type == PCI_QUIRK_MAP_REG)
  759                         pci_add_map(pcib, b, s, f, q->arg1, rl);
  760         }
  761 
  762         if (cfg->intpin > 0 && PCI_INTERRUPT_VALID(cfg->intline)) {
  763 #ifdef __ia64__
  764                 /*
  765                  * Re-route interrupts on ia64 so that we can get the
  766                  * I/O SAPIC interrupt numbers (the BIOS leaves legacy
  767                  * PIC interrupt numbers in the intline registers).
  768                  */
  769                 cfg->intline = PCIB_ROUTE_INTERRUPT(pcib, dev, cfg->intpin);
  770 #endif
  771                 resource_list_add(rl, SYS_RES_IRQ, 0, cfg->intline,
  772                   cfg->intline, 1);
  773         }
  774 }
  775 
  776 void
  777 pci_add_children(device_t dev, int busno, size_t dinfo_size)
  778 {
  779         device_t pcib = device_get_parent(dev);
  780         struct pci_devinfo *dinfo;
  781         int maxslots;
  782         int s, f, pcifunchigh;
  783 
  784         KASSERT(dinfo_size >= sizeof(struct pci_devinfo),
  785             ("dinfo_size too small"));
  786         maxslots = PCIB_MAXSLOTS(pcib); 
  787         for (s = 0; s <= maxslots; s++) {
  788                 pcifunchigh = 0;
  789                 for (f = 0; f <= pcifunchigh; f++) {
  790                         dinfo = pci_read_device(pcib, busno, s, f, dinfo_size);
  791                         if (dinfo != NULL) {
  792                                 if (dinfo->cfg.mfdev)
  793                                         pcifunchigh = PCI_FUNCMAX;
  794                                 pci_add_child(dev, dinfo);
  795                         }
  796                 }
  797         }
  798 }
  799 
  800 void
  801 pci_add_child(device_t bus, struct pci_devinfo *dinfo)
  802 {
  803         device_t pcib;
  804 
  805         pcib = device_get_parent(bus);
  806         dinfo->cfg.dev = device_add_child(bus, NULL, -1);
  807         device_set_ivars(dinfo->cfg.dev, dinfo);
  808         pci_add_resources(pcib, dinfo->cfg.dev);
  809         pci_print_verbose(dinfo);
  810 }
  811 
  812 static int
  813 pci_probe(device_t dev)
  814 {
  815 
  816         device_set_desc(dev, "PCI bus");
  817 
  818         /* Allow other subclasses to override this driver. */
  819         return (-1000);
  820 }
  821 
  822 static int
  823 pci_attach(device_t dev)
  824 {
  825         int busno;
  826 
  827         /*
  828          * Since there can be multiple independantly numbered PCI
  829          * busses on some large alpha systems, we can't use the unit
  830          * number to decide what bus we are probing. We ask the parent 
  831          * pcib what our bus number is.
  832          */
  833         busno = pcib_get_bus(dev);
  834         if (bootverbose)
  835                 device_printf(dev, "physical bus=%d\n", busno);
  836 
  837         pci_add_children(dev, busno, sizeof(struct pci_devinfo));
  838 
  839         return (bus_generic_attach(dev));
  840 }
  841 
  842 static void
  843 pci_load_vendor_data(void)
  844 {
  845         caddr_t vendordata, info;
  846 
  847         if ((vendordata = preload_search_by_type("pci_vendor_data")) != NULL) {
  848                 info = preload_search_info(vendordata, MODINFO_ADDR);
  849                 pci_vendordata = *(char **)info;
  850                 info = preload_search_info(vendordata, MODINFO_SIZE);
  851                 pci_vendordata_size = *(size_t *)info;
  852                 /* terminate the database */
  853                 pci_vendordata[pci_vendordata_size] = '\n';
  854         }
  855 }
  856 
  857 int
  858 pci_print_child(device_t dev, device_t child)
  859 {
  860         struct pci_devinfo *dinfo;
  861         struct resource_list *rl;
  862         pcicfgregs *cfg;
  863         int retval = 0;
  864 
  865         dinfo = device_get_ivars(child);
  866         cfg = &dinfo->cfg;
  867         rl = &dinfo->resources;
  868 
  869         retval += bus_print_child_header(dev, child);
  870 
  871         retval += resource_list_print_type(rl, "port", SYS_RES_IOPORT, "%#lx");
  872         retval += resource_list_print_type(rl, "mem", SYS_RES_MEMORY, "%#lx");
  873         retval += resource_list_print_type(rl, "irq", SYS_RES_IRQ, "%ld");
  874         if (device_get_flags(dev))
  875                 retval += printf(" flags %#x", device_get_flags(dev));
  876 
  877         retval += printf(" at device %d.%d", pci_get_slot(child),
  878             pci_get_function(child));
  879 
  880         retval += bus_print_child_footer(dev, child);
  881 
  882         return (retval);
  883 }
  884 
  885 static struct
  886 {
  887         int     class;
  888         int     subclass;
  889         char    *desc;
  890 } pci_nomatch_tab[] = {
  891         {PCIC_OLD,              -1,                     "old"},
  892         {PCIC_OLD,              PCIS_OLD_NONVGA,        "non-VGA display device"},
  893         {PCIC_OLD,              PCIS_OLD_VGA,           "VGA-compatible display device"},
  894         {PCIC_STORAGE,          -1,                     "mass storage"},
  895         {PCIC_STORAGE,          PCIS_STORAGE_SCSI,      "SCSI"},
  896         {PCIC_STORAGE,          PCIS_STORAGE_IDE,       "ATA"},
  897         {PCIC_STORAGE,          PCIS_STORAGE_FLOPPY,    "floppy disk"},
  898         {PCIC_STORAGE,          PCIS_STORAGE_IPI,       "IPI"},
  899         {PCIC_STORAGE,          PCIS_STORAGE_RAID,      "RAID"},
  900         {PCIC_NETWORK,          -1,                     "network"},
  901         {PCIC_NETWORK,          PCIS_NETWORK_ETHERNET,  "ethernet"},
  902         {PCIC_NETWORK,          PCIS_NETWORK_TOKENRING, "token ring"},
  903         {PCIC_NETWORK,          PCIS_NETWORK_FDDI,      "fddi"},
  904         {PCIC_NETWORK,          PCIS_NETWORK_ATM,       "ATM"},
  905         {PCIC_DISPLAY,          -1,                     "display"},
  906         {PCIC_DISPLAY,          PCIS_DISPLAY_VGA,       "VGA"},
  907         {PCIC_DISPLAY,          PCIS_DISPLAY_XGA,       "XGA"},
  908         {PCIC_MULTIMEDIA,       -1,                     "multimedia"},
  909         {PCIC_MULTIMEDIA,       PCIS_MULTIMEDIA_VIDEO,  "video"},
  910         {PCIC_MULTIMEDIA,       PCIS_MULTIMEDIA_AUDIO,  "audio"},
  911         {PCIC_MEMORY,           -1,                     "memory"},
  912         {PCIC_MEMORY,           PCIS_MEMORY_RAM,        "RAM"},
  913         {PCIC_MEMORY,           PCIS_MEMORY_FLASH,      "flash"},
  914         {PCIC_BRIDGE,           -1,                     "bridge"},
  915         {PCIC_BRIDGE,           PCIS_BRIDGE_HOST,       "HOST-PCI"},
  916         {PCIC_BRIDGE,           PCIS_BRIDGE_ISA,        "PCI-ISA"},
  917         {PCIC_BRIDGE,           PCIS_BRIDGE_EISA,       "PCI-EISA"},
  918         {PCIC_BRIDGE,           PCIS_BRIDGE_MCA,        "PCI-MCA"},
  919         {PCIC_BRIDGE,           PCIS_BRIDGE_PCI,        "PCI-PCI"},
  920         {PCIC_BRIDGE,           PCIS_BRIDGE_PCMCIA,     "PCI-PCMCIA"},
  921         {PCIC_BRIDGE,           PCIS_BRIDGE_NUBUS,      "PCI-NuBus"},
  922         {PCIC_BRIDGE,           PCIS_BRIDGE_CARDBUS,    "PCI-CardBus"},
  923         {PCIC_BRIDGE,           PCIS_BRIDGE_OTHER,      "PCI-unknown"},
  924         {PCIC_SIMPLECOMM,       -1,                     "simple comms"},
  925         {PCIC_SIMPLECOMM,       PCIS_SIMPLECOMM_UART,   "UART"},        /* could detect 16550 */
  926         {PCIC_SIMPLECOMM,       PCIS_SIMPLECOMM_PAR,    "parallel port"},
  927         {PCIC_BASEPERIPH,       -1,                     "base peripheral"},
  928         {PCIC_BASEPERIPH,       PCIS_BASEPERIPH_PIC,    "interrupt controller"},
  929         {PCIC_BASEPERIPH,       PCIS_BASEPERIPH_DMA,    "DMA controller"},
  930         {PCIC_BASEPERIPH,       PCIS_BASEPERIPH_TIMER,  "timer"},
  931         {PCIC_BASEPERIPH,       PCIS_BASEPERIPH_RTC,    "realtime clock"},
  932         {PCIC_INPUTDEV,         -1,                     "input device"},
  933         {PCIC_INPUTDEV,         PCIS_INPUTDEV_KEYBOARD, "keyboard"},
  934         {PCIC_INPUTDEV,         PCIS_INPUTDEV_DIGITIZER,"digitizer"},
  935         {PCIC_INPUTDEV,         PCIS_INPUTDEV_MOUSE,    "mouse"},
  936         {PCIC_DOCKING,          -1,                     "docking station"},
  937         {PCIC_PROCESSOR,        -1,                     "processor"},
  938         {PCIC_SERIALBUS,        -1,                     "serial bus"},
  939         {PCIC_SERIALBUS,        PCIS_SERIALBUS_FW,      "FireWire"},
  940         {PCIC_SERIALBUS,        PCIS_SERIALBUS_ACCESS,  "AccessBus"},    
  941         {PCIC_SERIALBUS,        PCIS_SERIALBUS_SSA,     "SSA"},
  942         {PCIC_SERIALBUS,        PCIS_SERIALBUS_USB,     "USB"},
  943         {PCIC_SERIALBUS,        PCIS_SERIALBUS_FC,      "Fibre Channel"},
  944         {PCIC_SERIALBUS,        PCIS_SERIALBUS_SMBUS,   "SMBus"},
  945         {0, 0,          NULL}
  946 };
  947 
  948 void
  949 pci_probe_nomatch(device_t dev, device_t child)
  950 {
  951         int     i;
  952         char    *cp, *scp, *device;
  953         
  954         /*
  955          * Look for a listing for this device in a loaded device database.
  956          */
  957         if ((device = pci_describe_device(child)) != NULL) {
  958                 device_printf(dev, "<%s>", device);
  959                 free(device, M_DEVBUF);
  960         } else {
  961                 /*
  962                  * Scan the class/subclass descriptions for a general
  963                  * description.
  964                  */
  965                 cp = "unknown";
  966                 scp = NULL;
  967                 for (i = 0; pci_nomatch_tab[i].desc != NULL; i++) {
  968                         if (pci_nomatch_tab[i].class == pci_get_class(child)) {
  969                                 if (pci_nomatch_tab[i].subclass == -1) {
  970                                         cp = pci_nomatch_tab[i].desc;
  971                                 } else if (pci_nomatch_tab[i].subclass ==
  972                                     pci_get_subclass(child)) {
  973                                         scp = pci_nomatch_tab[i].desc;
  974                                 }
  975                         }
  976                 }
  977                 device_printf(dev, "<%s%s%s>", 
  978                     cp ? cp : "",
  979                     ((cp != NULL) && (scp != NULL)) ? ", " : "",
  980                     scp ? scp : "");
  981         }
  982         printf(" at device %d.%d (no driver attached)\n",
  983             pci_get_slot(child), pci_get_function(child));
  984         return;
  985 }
  986 
  987 /*
  988  * Parse the PCI device database, if loaded, and return a pointer to a 
  989  * description of the device.
  990  *
  991  * The database is flat text formatted as follows:
  992  *
  993  * Any line not in a valid format is ignored.
  994  * Lines are terminated with newline '\n' characters.
  995  * 
  996  * A VENDOR line consists of the 4 digit (hex) vendor code, a TAB, then
  997  * the vendor name.
  998  * 
  999  * A DEVICE line is entered immediately below the corresponding VENDOR ID.
 1000  * - devices cannot be listed without a corresponding VENDOR line.
 1001  * A DEVICE line consists of a TAB, the 4 digit (hex) device code,
 1002  * another TAB, then the device name.                                            
 1003  */
 1004 
 1005 /*
 1006  * Assuming (ptr) points to the beginning of a line in the database,
 1007  * return the vendor or device and description of the next entry.
 1008  * The value of (vendor) or (device) inappropriate for the entry type
 1009  * is set to -1.  Returns nonzero at the end of the database.
 1010  *
 1011  * Note that this is slightly unrobust in the face of corrupt data;
 1012  * we attempt to safeguard against this by spamming the end of the
 1013  * database with a newline when we initialise.
 1014  */
 1015 static int
 1016 pci_describe_parse_line(char **ptr, int *vendor, int *device, char **desc) 
 1017 {
 1018         char    *cp = *ptr;
 1019         int     left;
 1020 
 1021         *device = -1;
 1022         *vendor = -1;
 1023         **desc = '\0';
 1024         for (;;) {
 1025                 left = pci_vendordata_size - (cp - pci_vendordata);
 1026                 if (left <= 0) {
 1027                         *ptr = cp;
 1028                         return(1);
 1029                 }
 1030 
 1031                 /* vendor entry? */
 1032                 if (*cp != '\t' &&
 1033                     sscanf(cp, "%x\t%80[^\n]", vendor, *desc) == 2)
 1034                         break;
 1035                 /* device entry? */
 1036                 if (*cp == '\t' &&
 1037                     sscanf(cp, "%x\t%80[^\n]", device, *desc) == 2)
 1038                         break;
 1039                 
 1040                 /* skip to next line */
 1041                 while (*cp != '\n' && left > 0) {
 1042                         cp++;
 1043                         left--;
 1044                 }
 1045                 if (*cp == '\n') {
 1046                         cp++;
 1047                         left--;
 1048                 }
 1049         }
 1050         /* skip to next line */
 1051         while (*cp != '\n' && left > 0) {
 1052                 cp++;
 1053                 left--;
 1054         }
 1055         if (*cp == '\n' && left > 0)
 1056                 cp++;
 1057         *ptr = cp;
 1058         return(0);
 1059 }
 1060 
 1061 static char *
 1062 pci_describe_device(device_t dev)
 1063 {
 1064         int     vendor, device;
 1065         char    *desc, *vp, *dp, *line;
 1066 
 1067         desc = vp = dp = NULL;
 1068         
 1069         /*
 1070          * If we have no vendor data, we can't do anything.
 1071          */
 1072         if (pci_vendordata == NULL)
 1073                 goto out;
 1074 
 1075         /*
 1076          * Scan the vendor data looking for this device
 1077          */
 1078         line = pci_vendordata;
 1079         if ((vp = malloc(80, M_DEVBUF, M_NOWAIT)) == NULL)
 1080                 goto out;
 1081         for (;;) {
 1082                 if (pci_describe_parse_line(&line, &vendor, &device, &vp))
 1083                         goto out;
 1084                 if (vendor == pci_get_vendor(dev))
 1085                         break;
 1086         }
 1087         if ((dp = malloc(80, M_DEVBUF, M_NOWAIT)) == NULL)
 1088                 goto out;
 1089         for (;;) {
 1090                 if (pci_describe_parse_line(&line, &vendor, &device, &dp)) {
 1091                         *dp = 0;
 1092                         break;
 1093                 }
 1094                 if (vendor != -1) {
 1095                         *dp = 0;
 1096                         break;
 1097                 }
 1098                 if (device == pci_get_device(dev))
 1099                         break;
 1100         }
 1101         if (dp[0] == '\0')
 1102                 snprintf(dp, 80, "0x%x", pci_get_device(dev));
 1103         if ((desc = malloc(strlen(vp) + strlen(dp) + 3, M_DEVBUF, M_NOWAIT)) !=
 1104             NULL)
 1105                 sprintf(desc, "%s, %s", vp, dp);
 1106  out:
 1107         if (vp != NULL)
 1108                 free(vp, M_DEVBUF);
 1109         if (dp != NULL)
 1110                 free(dp, M_DEVBUF);
 1111         return(desc);
 1112 }
 1113 
 1114 int
 1115 pci_read_ivar(device_t dev, device_t child, int which, uintptr_t *result)
 1116 {
 1117         struct pci_devinfo *dinfo;
 1118         pcicfgregs *cfg;
 1119 
 1120         dinfo = device_get_ivars(child);
 1121         cfg = &dinfo->cfg;
 1122 
 1123         switch (which) {
 1124         case PCI_IVAR_ETHADDR:
 1125                 /*
 1126                  * The generic accessor doesn't deal with failure, so
 1127                  * we set the return value, then return an error.
 1128                  */
 1129                 *((u_int8_t **) result) = NULL;
 1130                 return (EINVAL);
 1131         case PCI_IVAR_SUBVENDOR:
 1132                 *result = cfg->subvendor;
 1133                 break;
 1134         case PCI_IVAR_SUBDEVICE:
 1135                 *result = cfg->subdevice;
 1136                 break;
 1137         case PCI_IVAR_VENDOR:
 1138                 *result = cfg->vendor;
 1139                 break;
 1140         case PCI_IVAR_DEVICE:
 1141                 *result = cfg->device;
 1142                 break;
 1143         case PCI_IVAR_DEVID:
 1144                 *result = (cfg->device << 16) | cfg->vendor;
 1145                 break;
 1146         case PCI_IVAR_CLASS:
 1147                 *result = cfg->baseclass;
 1148                 break;
 1149         case PCI_IVAR_SUBCLASS:
 1150                 *result = cfg->subclass;
 1151                 break;
 1152         case PCI_IVAR_PROGIF:
 1153                 *result = cfg->progif;
 1154                 break;
 1155         case PCI_IVAR_REVID:
 1156                 *result = cfg->revid;
 1157                 break;
 1158         case PCI_IVAR_INTPIN:
 1159                 *result = cfg->intpin;
 1160                 break;
 1161         case PCI_IVAR_IRQ:
 1162                 *result = cfg->intline;
 1163                 break;
 1164         case PCI_IVAR_BUS:
 1165                 *result = cfg->bus;
 1166                 break;
 1167         case PCI_IVAR_SLOT:
 1168                 *result = cfg->slot;
 1169                 break;
 1170         case PCI_IVAR_FUNCTION:
 1171                 *result = cfg->func;
 1172                 break;
 1173         default:
 1174                 return (ENOENT);
 1175         }
 1176         return (0);
 1177 }
 1178 
 1179 int
 1180 pci_write_ivar(device_t dev, device_t child, int which, uintptr_t value)
 1181 {
 1182         struct pci_devinfo *dinfo;
 1183         pcicfgregs *cfg;
 1184 
 1185         dinfo = device_get_ivars(child);
 1186         cfg = &dinfo->cfg;
 1187 
 1188         switch (which) {
 1189         case PCI_IVAR_ETHADDR:
 1190         case PCI_IVAR_SUBVENDOR:
 1191         case PCI_IVAR_SUBDEVICE:
 1192         case PCI_IVAR_VENDOR:
 1193         case PCI_IVAR_DEVICE:
 1194         case PCI_IVAR_DEVID:
 1195         case PCI_IVAR_CLASS:
 1196         case PCI_IVAR_SUBCLASS:
 1197         case PCI_IVAR_PROGIF:
 1198         case PCI_IVAR_REVID:
 1199         case PCI_IVAR_INTPIN:
 1200         case PCI_IVAR_IRQ:
 1201         case PCI_IVAR_BUS:
 1202         case PCI_IVAR_SLOT:
 1203         case PCI_IVAR_FUNCTION:
 1204                 return (EINVAL);        /* disallow for now */
 1205 
 1206         default:
 1207                 return (ENOENT);
 1208         }
 1209         return (0);
 1210 }
 1211 
 1212 
 1213 #include "opt_ddb.h"
 1214 #ifdef DDB
 1215 #include <ddb/ddb.h>
 1216 #include <sys/cons.h>
 1217 
 1218 /*
 1219  * List resources based on pci map registers, used for within ddb
 1220  */
 1221 
 1222 DB_SHOW_COMMAND(pciregs, db_pci_dump)
 1223 {
 1224         struct pci_devinfo *dinfo;
 1225         struct devlist *devlist_head;
 1226         struct pci_conf *p;
 1227         const char *name;
 1228         int i, error, none_count, nl;
 1229 
 1230         none_count = 0;
 1231         nl = 0;
 1232         /* get the head of the device queue */
 1233         devlist_head = &pci_devq;
 1234 
 1235         /*
 1236          * Go through the list of devices and print out devices
 1237          */
 1238         for (error = 0, i = 0,
 1239              dinfo = STAILQ_FIRST(devlist_head);
 1240              (dinfo != NULL) && (error == 0) && (i < pci_numdevs);
 1241              dinfo = STAILQ_NEXT(dinfo, pci_links), i++) {
 1242 
 1243                 /* Populate pd_name and pd_unit */
 1244                 name = NULL;
 1245                 if (dinfo->cfg.dev)
 1246                         name = device_get_name(dinfo->cfg.dev);
 1247 
 1248                 p = &dinfo->conf;
 1249                 /*
 1250                  * XXX just take 20 for now...
 1251                  */
 1252                 if (nl++ == 20) {
 1253                         int c;
 1254 
 1255                         db_printf("--More--");
 1256                         c = cngetc();
 1257                         db_printf("\r");
 1258                         /*
 1259                          * A whole screenfull or just one line?
 1260                          */
 1261                         switch (c) {
 1262                         case '\n':              /* just one line */
 1263                                 nl = 20;
 1264                                 break;
 1265                         case ' ':
 1266                                 nl = 0;         /* another screenfull */
 1267                                 break;
 1268                         default:                /* exit */
 1269                                 db_printf("\n");
 1270                                 return;
 1271                         }
 1272                 }
 1273 
 1274                 db_printf("%s%d@pci%d:%d:%d:\tclass=0x%06x card=0x%08x "
 1275                         "chip=0x%08x rev=0x%02x hdr=0x%02x\n",
 1276                         (name && *name) ? name : "none",
 1277                         (name && *name) ? (int)device_get_unit(dinfo->cfg.dev) :
 1278                         none_count++,
 1279                         p->pc_sel.pc_bus, p->pc_sel.pc_dev,
 1280                         p->pc_sel.pc_func, (p->pc_class << 16) |
 1281                         (p->pc_subclass << 8) | p->pc_progif,
 1282                         (p->pc_subdevice << 16) | p->pc_subvendor,
 1283                         (p->pc_device << 16) | p->pc_vendor,
 1284                         p->pc_revid, p->pc_hdr);
 1285         }
 1286 }
 1287 #endif /* DDB */
 1288 
 1289 struct resource *
 1290 pci_alloc_resource(device_t dev, device_t child, int type, int *rid,
 1291                    u_long start, u_long end, u_long count, u_int flags)
 1292 {
 1293         struct pci_devinfo *dinfo = device_get_ivars(child);
 1294         struct resource_list *rl = &dinfo->resources;
 1295         pcicfgregs *cfg = &dinfo->cfg;
 1296 
 1297         /*
 1298          * Perform lazy resource allocation
 1299          *
 1300          * XXX add support here for SYS_RES_IOPORT and SYS_RES_MEMORY
 1301          */
 1302         if (device_get_parent(child) == dev) {
 1303                 /*
 1304                  * If the child device doesn't have an interrupt routed
 1305                  * and is deserving of an interrupt, try to assign it one.
 1306                  */
 1307                 if ((type == SYS_RES_IRQ) &&
 1308                     !PCI_INTERRUPT_VALID(cfg->intline) &&
 1309                     (cfg->intpin != 0)) {
 1310                         cfg->intline = PCIB_ROUTE_INTERRUPT(
 1311                                 device_get_parent(dev), child, cfg->intpin);
 1312                         if (PCI_INTERRUPT_VALID(cfg->intline)) {
 1313                                 pci_write_config(child, PCIR_INTLINE,
 1314                                     cfg->intline, 1);
 1315                                 resource_list_add(rl, SYS_RES_IRQ, 0,
 1316                                     cfg->intline, cfg->intline, 1);
 1317                         }
 1318                 }
 1319         }
 1320 
 1321         return (resource_list_alloc(rl, dev, child, type, rid,
 1322             start, end, count, flags));
 1323 }
 1324 
 1325 void
 1326 pci_delete_resource(device_t dev, device_t child, int type, int rid)
 1327 {
 1328         struct pci_devinfo *dinfo;
 1329         struct resource_list *rl;
 1330         struct resource_list_entry *rle;
 1331 
 1332         if (device_get_parent(child) != dev)
 1333                 return;
 1334 
 1335         dinfo = device_get_ivars(child);
 1336         rl = &dinfo->resources;
 1337         rle = resource_list_find(rl, type, rid);
 1338         if (rle) {
 1339                 if (rle->res) {
 1340                         if (rle->res->r_dev != dev ||
 1341                             rman_get_flags(rle->res) & RF_ACTIVE) {
 1342                                 device_printf(dev, "delete_resource: "
 1343                                     "Resource still owned by child, oops. "
 1344                                     "(type=%d, rid=%d, addr=%lx)\n",
 1345                                     rle->type, rle->rid,
 1346                                     rman_get_start(rle->res));
 1347                                 return;
 1348                         }
 1349                         bus_release_resource(dev, type, rid, rle->res);
 1350                 }
 1351                 resource_list_delete(rl, type, rid);
 1352         }
 1353         /* 
 1354          * Why do we turn off the PCI configuration BAR when we delete a
 1355          * resource? -- imp
 1356          */
 1357         pci_write_config(child, rid, 0, 4);
 1358         BUS_DELETE_RESOURCE(device_get_parent(dev), child, type, rid);
 1359 }
 1360 
 1361 struct resource_list *
 1362 pci_get_resource_list (device_t dev, device_t child)
 1363 {
 1364         struct pci_devinfo *    dinfo = device_get_ivars(child);
 1365         struct resource_list *  rl = &dinfo->resources;
 1366 
 1367         if (!rl)
 1368                 return (NULL);
 1369 
 1370         return (rl);
 1371 }
 1372 
 1373 u_int32_t
 1374 pci_read_config_method(device_t dev, device_t child, int reg, int width)
 1375 {
 1376         struct pci_devinfo *dinfo = device_get_ivars(child);
 1377         pcicfgregs *cfg = &dinfo->cfg;
 1378 
 1379         return (PCIB_READ_CONFIG(device_get_parent(dev),
 1380             cfg->bus, cfg->slot, cfg->func, reg, width));
 1381 }
 1382 
 1383 void
 1384 pci_write_config_method(device_t dev, device_t child, int reg, 
 1385     u_int32_t val, int width)
 1386 {
 1387         struct pci_devinfo *dinfo = device_get_ivars(child);
 1388         pcicfgregs *cfg = &dinfo->cfg;
 1389 
 1390         PCIB_WRITE_CONFIG(device_get_parent(dev),
 1391             cfg->bus, cfg->slot, cfg->func, reg, val, width);
 1392 }
 1393 
 1394 static int
 1395 pci_modevent(module_t mod, int what, void *arg)
 1396 {
 1397         static dev_t pci_cdev;
 1398 
 1399         switch (what) {
 1400         case MOD_LOAD:
 1401                 STAILQ_INIT(&pci_devq);
 1402                 pci_generation = 0;
 1403                 pci_cdev = make_dev(&pcicdev, 0, UID_ROOT, GID_WHEEL, 0644,
 1404                     "pci");
 1405                 pci_load_vendor_data();
 1406                 break;
 1407 
 1408         case MOD_UNLOAD:
 1409                 destroy_dev(pci_cdev);
 1410                 break;
 1411         }
 1412 
 1413         return (0);
 1414 }

Cache object: 37a935e0dfc6a946573bf354273eacd3


[ 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.