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.2/sys/dev/pci/pci.c 122849 2003-11-17 08:58:16Z peter $
   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 uint32_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 
   69 static int              pci_porten(device_t pcib, int b, int s, int f);
   70 static int              pci_memen(device_t pcib, int b, int s, int f);
   71 static int              pci_add_map(device_t pcib, int b, int s, int f, int reg, 
   72                                     struct resource_list *rl);
   73 static void             pci_add_resources(device_t pcib, device_t bus,
   74                                           device_t dev);
   75 static int              pci_probe(device_t dev);
   76 static int              pci_attach(device_t dev);
   77 static void             pci_load_vendor_data(void);
   78 static int              pci_describe_parse_line(char **ptr, int *vendor, 
   79                                                 int *device, char **desc);
   80 static char             *pci_describe_device(device_t dev);
   81 static int              pci_modevent(module_t mod, int what, void *arg);
   82 static void             pci_hdrtypedata(device_t pcib, int b, int s, int f, 
   83                                         pcicfgregs *cfg);
   84 static void             pci_read_extcap(device_t pcib, pcicfgregs *cfg);
   85 
   86 static device_method_t pci_methods[] = {
   87         /* Device interface */
   88         DEVMETHOD(device_probe,         pci_probe),
   89         DEVMETHOD(device_attach,        pci_attach),
   90         DEVMETHOD(device_shutdown,      bus_generic_shutdown),
   91         DEVMETHOD(device_suspend,       bus_generic_suspend),
   92         DEVMETHOD(device_resume,        pci_resume),
   93 
   94         /* Bus interface */
   95         DEVMETHOD(bus_print_child,      pci_print_child),
   96         DEVMETHOD(bus_probe_nomatch,    pci_probe_nomatch),
   97         DEVMETHOD(bus_read_ivar,        pci_read_ivar),
   98         DEVMETHOD(bus_write_ivar,       pci_write_ivar),
   99         DEVMETHOD(bus_driver_added,     bus_generic_driver_added),
  100         DEVMETHOD(bus_setup_intr,       bus_generic_setup_intr),
  101         DEVMETHOD(bus_teardown_intr,    bus_generic_teardown_intr),
  102 
  103         DEVMETHOD(bus_get_resource_list,pci_get_resource_list),
  104         DEVMETHOD(bus_set_resource,     bus_generic_rl_set_resource),
  105         DEVMETHOD(bus_get_resource,     bus_generic_rl_get_resource),
  106         DEVMETHOD(bus_delete_resource,  pci_delete_resource),
  107         DEVMETHOD(bus_alloc_resource,   pci_alloc_resource),
  108         DEVMETHOD(bus_release_resource, bus_generic_rl_release_resource),
  109         DEVMETHOD(bus_activate_resource, bus_generic_activate_resource),
  110         DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource),
  111         DEVMETHOD(bus_child_pnpinfo_str, pci_child_pnpinfo_str_method),
  112         DEVMETHOD(bus_child_location_str, pci_child_location_str_method),
  113 
  114         /* PCI interface */
  115         DEVMETHOD(pci_read_config,      pci_read_config_method),
  116         DEVMETHOD(pci_write_config,     pci_write_config_method),
  117         DEVMETHOD(pci_enable_busmaster, pci_enable_busmaster_method),
  118         DEVMETHOD(pci_disable_busmaster, pci_disable_busmaster_method),
  119         DEVMETHOD(pci_enable_io,        pci_enable_io_method),
  120         DEVMETHOD(pci_disable_io,       pci_disable_io_method),
  121         DEVMETHOD(pci_get_powerstate,   pci_get_powerstate_method),
  122         DEVMETHOD(pci_set_powerstate,   pci_set_powerstate_method),
  123         DEVMETHOD(pci_assign_interrupt, pci_assign_interrupt_method),
  124 
  125         { 0, 0 }
  126 };
  127 
  128 DEFINE_CLASS_0(pci, pci_driver, pci_methods, 0);
  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         uint32_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 uint32_t pci_generation;
  163 uint32_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(uint8_t bus, uint8_t slot, uint8_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(uint16_t vendor, uint16_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 uint32_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 uint8_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 (REG(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_HDRTYPE, 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 & PCIM_HDRTYPE) {
  402         case 0:
  403                 ptrptr = PCIR_CAP_PTR;
  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 PCIY_PMG:          /* PCI power management */
  430                         if (cfg->pp.pp_cap == 0) {
  431                                 cfg->pp.pp_cap = REG(ptr + PCIR_POWER_CAP, 2);
  432                                 cfg->pp.pp_status = ptr + PCIR_POWER_STATUS;
  433                                 cfg->pp.pp_pmcsr = ptr + PCIR_POWER_PMCSR;
  434                                 if ((nextptr - ptr) > PCIR_POWER_DATA)
  435                                         cfg->pp.pp_data = ptr + PCIR_POWER_DATA;
  436                         }
  437                         break;
  438                 case PCIY_MSI:          /* PCI MSI */
  439                         cfg->msi.msi_ctrl = REG(ptr + PCIR_MSI_CTRL, 2);
  440                         if (cfg->msi.msi_ctrl & PCIM_MSICTRL_64BIT)
  441                                 cfg->msi.msi_data = PCIR_MSI_DATA_64BIT;
  442                         else
  443                                 cfg->msi.msi_data = PCIR_MSI_DATA;
  444                         cfg->msi.msi_msgnum = 1 << ((cfg->msi.msi_ctrl &
  445                                                      PCIM_MSICTRL_MMC_MASK)>>1);
  446                 default:
  447                         break;
  448                 }
  449         }
  450 #undef REG
  451 }
  452 
  453 /* free pcicfgregs structure and all depending data structures */
  454 
  455 int
  456 pci_freecfg(struct pci_devinfo *dinfo)
  457 {
  458         struct devlist *devlist_head;
  459 
  460         devlist_head = &pci_devq;
  461 
  462         STAILQ_REMOVE(devlist_head, dinfo, pci_devinfo, pci_links);
  463         free(dinfo, M_DEVBUF);
  464 
  465         /* increment the generation count */
  466         pci_generation++;
  467 
  468         /* we're losing one device */
  469         pci_numdevs--;
  470         return (0);
  471 }
  472 
  473 /*
  474  * PCI power manangement
  475  */
  476 int
  477 pci_set_powerstate_method(device_t dev, device_t child, int state)
  478 {
  479         struct pci_devinfo *dinfo = device_get_ivars(child);
  480         pcicfgregs *cfg = &dinfo->cfg;
  481         uint16_t status;
  482         int result;
  483 
  484         if (cfg->pp.pp_cap != 0) {
  485                 status = PCI_READ_CONFIG(dev, child, cfg->pp.pp_status, 2)
  486                     & ~PCIM_PSTAT_DMASK;
  487                 result = 0;
  488                 switch (state) {
  489                 case PCI_POWERSTATE_D0:
  490                         status |= PCIM_PSTAT_D0;
  491                         break;
  492                 case PCI_POWERSTATE_D1:
  493                         if (cfg->pp.pp_cap & PCIM_PCAP_D1SUPP) {
  494                                 status |= PCIM_PSTAT_D1;
  495                         } else {
  496                                 result = EOPNOTSUPP;
  497                         }
  498                         break;
  499                 case PCI_POWERSTATE_D2:
  500                         if (cfg->pp.pp_cap & PCIM_PCAP_D2SUPP) {
  501                                 status |= PCIM_PSTAT_D2;
  502                         } else {
  503                                 result = EOPNOTSUPP;
  504                         }
  505                         break;
  506                 case PCI_POWERSTATE_D3:
  507                         status |= PCIM_PSTAT_D3;
  508                         break;
  509                 default:
  510                         result = EINVAL;
  511                 }
  512                 if (result == 0)
  513                         PCI_WRITE_CONFIG(dev, child, cfg->pp.pp_status, status,
  514                                          2);
  515         } else {
  516                 result = ENXIO;
  517         }
  518         return(result);
  519 }
  520 
  521 int
  522 pci_get_powerstate_method(device_t dev, device_t child)
  523 {
  524         struct pci_devinfo *dinfo = device_get_ivars(child);
  525         pcicfgregs *cfg = &dinfo->cfg;
  526         uint16_t status;
  527         int result;
  528 
  529         if (cfg->pp.pp_cap != 0) {
  530                 status = PCI_READ_CONFIG(dev, child, cfg->pp.pp_status, 2);
  531                 switch (status & PCIM_PSTAT_DMASK) {
  532                 case PCIM_PSTAT_D0:
  533                         result = PCI_POWERSTATE_D0;
  534                         break;
  535                 case PCIM_PSTAT_D1:
  536                         result = PCI_POWERSTATE_D1;
  537                         break;
  538                 case PCIM_PSTAT_D2:
  539                         result = PCI_POWERSTATE_D2;
  540                         break;
  541                 case PCIM_PSTAT_D3:
  542                         result = PCI_POWERSTATE_D3;
  543                         break;
  544                 default:
  545                         result = PCI_POWERSTATE_UNKNOWN;
  546                         break;
  547                 }
  548         } else {
  549                 /* No support, device is always at D0 */
  550                 result = PCI_POWERSTATE_D0;
  551         }
  552         return(result);
  553 }
  554 
  555 /*
  556  * Some convenience functions for PCI device drivers.
  557  */
  558 
  559 static __inline void
  560 pci_set_command_bit(device_t dev, device_t child, uint16_t bit)
  561 {
  562         uint16_t        command;
  563 
  564         command = PCI_READ_CONFIG(dev, child, PCIR_COMMAND, 2);
  565         command |= bit;
  566         PCI_WRITE_CONFIG(dev, child, PCIR_COMMAND, command, 2);
  567 }
  568 
  569 static __inline void
  570 pci_clear_command_bit(device_t dev, device_t child, uint16_t bit)
  571 {
  572         uint16_t        command;
  573 
  574         command = PCI_READ_CONFIG(dev, child, PCIR_COMMAND, 2);
  575         command &= ~bit;
  576         PCI_WRITE_CONFIG(dev, child, PCIR_COMMAND, command, 2);
  577 }
  578 
  579 int
  580 pci_enable_busmaster_method(device_t dev, device_t child)
  581 {
  582         pci_set_command_bit(dev, child, PCIM_CMD_BUSMASTEREN);
  583         return (0);
  584 }
  585 
  586 int
  587 pci_disable_busmaster_method(device_t dev, device_t child)
  588 {
  589         pci_clear_command_bit(dev, child, PCIM_CMD_BUSMASTEREN);
  590         return (0);
  591 }
  592 
  593 int
  594 pci_enable_io_method(device_t dev, device_t child, int space)
  595 {
  596         uint16_t command;
  597         uint16_t bit;
  598         char *error;
  599 
  600         bit = 0;
  601         error = NULL;
  602 
  603         switch(space) {
  604         case SYS_RES_IOPORT:
  605                 bit = PCIM_CMD_PORTEN;
  606                 error = "port";
  607                 break;
  608         case SYS_RES_MEMORY:
  609                 bit = PCIM_CMD_MEMEN;
  610                 error = "memory";
  611                 break;
  612         default:
  613                 return (EINVAL);
  614         }
  615         pci_set_command_bit(dev, child, bit);
  616         command = PCI_READ_CONFIG(dev, child, PCIR_COMMAND, 2);
  617         if (command & bit)
  618                 return (0);
  619         device_printf(child, "failed to enable %s mapping!\n", error);
  620         return (ENXIO);
  621 }
  622 
  623 int
  624 pci_disable_io_method(device_t dev, device_t child, int space)
  625 {
  626         uint16_t command;
  627         uint16_t bit;
  628         char *error;
  629 
  630         bit = 0;
  631         error = NULL;
  632 
  633         switch(space) {
  634         case SYS_RES_IOPORT:
  635                 bit = PCIM_CMD_PORTEN;
  636                 error = "port";
  637                 break;
  638         case SYS_RES_MEMORY:
  639                 bit = PCIM_CMD_MEMEN;
  640                 error = "memory";
  641                 break;
  642         default:
  643                 return (EINVAL);
  644         }
  645         pci_clear_command_bit(dev, child, bit);
  646         command = PCI_READ_CONFIG(dev, child, PCIR_COMMAND, 2);
  647         if (command & bit) {
  648                 device_printf(child, "failed to disable %s mapping!\n", error);
  649                 return (ENXIO);
  650         }
  651         return (0);
  652 }
  653 
  654 /*
  655  * New style pci driver.  Parent device is either a pci-host-bridge or a
  656  * pci-pci-bridge.  Both kinds are represented by instances of pcib.
  657  */
  658 
  659 void
  660 pci_print_verbose(struct pci_devinfo *dinfo)
  661 {
  662         if (bootverbose) {
  663                 pcicfgregs *cfg = &dinfo->cfg;
  664 
  665                 printf("found->\tvendor=0x%04x, dev=0x%04x, revid=0x%02x\n", 
  666                     cfg->vendor, cfg->device, cfg->revid);
  667                 printf("\tbus=%d, slot=%d, func=%d\n",
  668                     cfg->bus, cfg->slot, cfg->func);
  669                 printf("\tclass=%02x-%02x-%02x, hdrtype=0x%02x, mfdev=%d\n",
  670                     cfg->baseclass, cfg->subclass, cfg->progif, cfg->hdrtype,
  671                     cfg->mfdev);
  672                 printf("\tcmdreg=0x%04x, statreg=0x%04x, cachelnsz=%d (dwords)\n", 
  673                     cfg->cmdreg, cfg->statreg, cfg->cachelnsz);
  674                 printf("\tlattimer=0x%02x (%d ns), mingnt=0x%02x (%d ns), maxlat=0x%02x (%d ns)\n",
  675                     cfg->lattimer, cfg->lattimer * 30, cfg->mingnt,
  676                     cfg->mingnt * 250, cfg->maxlat, cfg->maxlat * 250);
  677                 if (cfg->intpin > 0)
  678                         printf("\tintpin=%c, irq=%d\n",
  679                             cfg->intpin +'a' -1, cfg->intline);
  680                 if (cfg->pp.pp_cap) {
  681                         uint16_t status;
  682 
  683                         status = pci_read_config(cfg->dev, cfg->pp.pp_status, 2);
  684                         printf("\tpowerspec %d  supports D0%s%s D3  current D%d\n",
  685                             cfg->pp.pp_cap & PCIM_PCAP_SPEC,
  686                             cfg->pp.pp_cap & PCIM_PCAP_D1SUPP ? " D1" : "",
  687                             cfg->pp.pp_cap & PCIM_PCAP_D2SUPP ? " D2" : "",
  688                             status & PCIM_PSTAT_DMASK);
  689                 }
  690                 if (cfg->msi.msi_data) {
  691                         int ctrl;
  692 
  693                         ctrl =  cfg->msi.msi_ctrl;
  694                         printf("\tMSI supports %d message%s%s%s\n",
  695                             cfg->msi.msi_msgnum,
  696                             (cfg->msi.msi_msgnum == 1) ? "" : "s",
  697                             (ctrl & PCIM_MSICTRL_64BIT) ? ", 64 bit" : "",
  698                             (ctrl & PCIM_MSICTRL_VECTOR) ? ", vector masks":"");
  699                 }
  700         }
  701 }
  702 
  703 static int
  704 pci_porten(device_t pcib, int b, int s, int f)
  705 {
  706         return (PCIB_READ_CONFIG(pcib, b, s, f, PCIR_COMMAND, 2)
  707                 & PCIM_CMD_PORTEN) != 0;
  708 }
  709 
  710 static int
  711 pci_memen(device_t pcib, int b, int s, int f)
  712 {
  713         return (PCIB_READ_CONFIG(pcib, b, s, f, PCIR_COMMAND, 2)
  714                 & PCIM_CMD_MEMEN) != 0;
  715 }
  716 
  717 /*
  718  * Add a resource based on a pci map register. Return 1 if the map
  719  * register is a 32bit map register or 2 if it is a 64bit register.
  720  */
  721 static int
  722 pci_add_map(device_t pcib, int b, int s, int f, int reg,
  723             struct resource_list *rl)
  724 {
  725         uint32_t map;
  726         uint64_t base;
  727         uint8_t ln2size;
  728         uint8_t ln2range;
  729         uint32_t testval;
  730         uint16_t cmd;
  731         int type;
  732 
  733         map = PCIB_READ_CONFIG(pcib, b, s, f, reg, 4);
  734 
  735         if (map == 0 || map == 0xffffffff)
  736                 return (1); /* skip invalid entry */
  737 
  738         PCIB_WRITE_CONFIG(pcib, b, s, f, reg, 0xffffffff, 4);
  739         testval = PCIB_READ_CONFIG(pcib, b, s, f, reg, 4);
  740         PCIB_WRITE_CONFIG(pcib, b, s, f, reg, map, 4);
  741 
  742         base = pci_mapbase(map);
  743         if (pci_maptype(map) & PCI_MAPMEM)
  744                 type = SYS_RES_MEMORY;
  745         else
  746                 type = SYS_RES_IOPORT;
  747         ln2size = pci_mapsize(testval);
  748         ln2range = pci_maprange(testval);
  749         if (ln2range == 64) {
  750                 /* Read the other half of a 64bit map register */
  751                 base |= (uint64_t) PCIB_READ_CONFIG(pcib, b, s, f, reg + 4, 4) << 32;
  752         }
  753 
  754         if (bootverbose) {
  755                 printf("\tmap[%02x]: type %x, range %2d, base %08x, size %2d",
  756                     reg, pci_maptype(map), ln2range, 
  757                     (unsigned int) base, ln2size);
  758                 if (type == SYS_RES_IOPORT && !pci_porten(pcib, b, s, f))
  759                         printf(", port disabled\n");
  760                 else if (type == SYS_RES_MEMORY && !pci_memen(pcib, b, s, f))
  761                         printf(", memory disabled\n");
  762                 else
  763                         printf(", enabled\n");
  764         }
  765 
  766         /*
  767          * This code theoretically does the right thing, but has
  768          * undesirable side effects in some cases where
  769          * peripherals respond oddly to having these bits
  770          * enabled.  Leave them alone by default.
  771          */
  772         if (pci_enable_io_modes) {
  773                 /* Turn on resources that have been left off by a lazy BIOS */
  774                 if (type == SYS_RES_IOPORT && !pci_porten(pcib, b, s, f)) {
  775                         cmd = PCIB_READ_CONFIG(pcib, b, s, f, PCIR_COMMAND, 2);
  776                         cmd |= PCIM_CMD_PORTEN;
  777                         PCIB_WRITE_CONFIG(pcib, b, s, f, PCIR_COMMAND, cmd, 2);
  778                 }
  779                 if (type == SYS_RES_MEMORY && !pci_memen(pcib, b, s, f)) {
  780                         cmd = PCIB_READ_CONFIG(pcib, b, s, f, PCIR_COMMAND, 2);
  781                         cmd |= PCIM_CMD_MEMEN;
  782                         PCIB_WRITE_CONFIG(pcib, b, s, f, PCIR_COMMAND, cmd, 2);
  783                 }
  784         } else {
  785                 if (type == SYS_RES_IOPORT && !pci_porten(pcib, b, s, f))
  786                         return (1);
  787                 if (type == SYS_RES_MEMORY && !pci_memen(pcib, b, s, f))
  788                         return (1);
  789         }
  790         resource_list_add(rl, type, reg, base, base + (1 << ln2size) - 1,
  791             (1 << ln2size));
  792 
  793         return ((ln2range == 64) ? 2 : 1);
  794 }
  795 
  796 static void
  797 pci_add_resources(device_t pcib, device_t bus, device_t dev)
  798 {
  799         struct pci_devinfo *dinfo = device_get_ivars(dev);
  800         pcicfgregs *cfg = &dinfo->cfg;
  801         struct resource_list *rl = &dinfo->resources;
  802         struct pci_quirk *q;
  803         int b, i, irq, f, s;
  804 
  805         b = cfg->bus;
  806         s = cfg->slot;
  807         f = cfg->func;
  808         for (i = 0; i < cfg->nummaps;) {
  809                 i += pci_add_map(pcib, b, s, f, PCIR_BAR(i), rl);
  810         }
  811 
  812         for (q = &pci_quirks[0]; q->devid; q++) {
  813                 if (q->devid == ((cfg->device << 16) | cfg->vendor)
  814                     && q->type == PCI_QUIRK_MAP_REG)
  815                         pci_add_map(pcib, b, s, f, q->arg1, rl);
  816         }
  817 
  818         if (cfg->intpin > 0 && PCI_INTERRUPT_VALID(cfg->intline)) {
  819 #if defined(__ia64__) || defined(__i386__) || defined(__amd64__)
  820                 /*
  821                  * Try to re-route interrupts. Sometimes the BIOS or
  822                  * firmware may leave bogus values in these registers.
  823                  * If the re-route fails, then just stick with what we
  824                  * have.
  825                  */
  826                 irq = PCI_ASSIGN_INTERRUPT(bus, dev);
  827                 if (PCI_INTERRUPT_VALID(irq)) {
  828                         pci_write_config(dev, PCIR_INTLINE, irq, 1);
  829                         cfg->intline = irq;
  830                 } else
  831 #endif
  832                         irq = cfg->intline;
  833                 resource_list_add(rl, SYS_RES_IRQ, 0, irq, irq, 1);
  834         }
  835 }
  836 
  837 void
  838 pci_add_children(device_t dev, int busno, size_t dinfo_size)
  839 {
  840 #define REG(n, w)       PCIB_READ_CONFIG(pcib, busno, s, f, n, w)
  841         device_t pcib = device_get_parent(dev);
  842         struct pci_devinfo *dinfo;
  843         int maxslots;
  844         int s, f, pcifunchigh;
  845         uint8_t hdrtype;
  846 
  847         KASSERT(dinfo_size >= sizeof(struct pci_devinfo),
  848             ("dinfo_size too small"));
  849         maxslots = PCIB_MAXSLOTS(pcib); 
  850         for (s = 0; s <= maxslots; s++) {
  851                 pcifunchigh = 0;
  852                 f = 0;
  853                 hdrtype = REG(PCIR_HDRTYPE, 1);
  854                 if ((hdrtype & PCIM_HDRTYPE) > PCI_MAXHDRTYPE)
  855                         continue;
  856                 if (hdrtype & PCIM_MFDEV)
  857                         pcifunchigh = PCI_FUNCMAX;
  858                 for (f = 0; f <= pcifunchigh; f++) {
  859                         dinfo = pci_read_device(pcib, busno, s, f, dinfo_size);
  860                         if (dinfo != NULL) {
  861                                 pci_add_child(dev, dinfo);
  862                         }
  863                 }
  864         }
  865 #undef REG
  866 }
  867 
  868 void
  869 pci_add_child(device_t bus, struct pci_devinfo *dinfo)
  870 {
  871         device_t pcib;
  872 
  873         pcib = device_get_parent(bus);
  874         dinfo->cfg.dev = device_add_child(bus, NULL, -1);
  875         device_set_ivars(dinfo->cfg.dev, dinfo);
  876         pci_add_resources(pcib, bus, dinfo->cfg.dev);
  877         pci_print_verbose(dinfo);
  878 }
  879 
  880 static int
  881 pci_probe(device_t dev)
  882 {
  883 
  884         device_set_desc(dev, "PCI bus");
  885 
  886         /* Allow other subclasses to override this driver. */
  887         return (-1000);
  888 }
  889 
  890 static int
  891 pci_attach(device_t dev)
  892 {
  893         int busno;
  894 
  895         /*
  896          * Since there can be multiple independantly numbered PCI
  897          * busses on some large alpha systems, we can't use the unit
  898          * number to decide what bus we are probing. We ask the parent 
  899          * pcib what our bus number is.
  900          */
  901         busno = pcib_get_bus(dev);
  902         if (bootverbose)
  903                 device_printf(dev, "physical bus=%d\n", busno);
  904 
  905         pci_add_children(dev, busno, sizeof(struct pci_devinfo));
  906 
  907         return (bus_generic_attach(dev));
  908 }
  909 
  910 static void
  911 pci_load_vendor_data(void)
  912 {
  913         caddr_t vendordata, info;
  914 
  915         if ((vendordata = preload_search_by_type("pci_vendor_data")) != NULL) {
  916                 info = preload_search_info(vendordata, MODINFO_ADDR);
  917                 pci_vendordata = *(char **)info;
  918                 info = preload_search_info(vendordata, MODINFO_SIZE);
  919                 pci_vendordata_size = *(size_t *)info;
  920                 /* terminate the database */
  921                 pci_vendordata[pci_vendordata_size] = '\n';
  922         }
  923 }
  924 
  925 int
  926 pci_print_child(device_t dev, device_t child)
  927 {
  928         struct pci_devinfo *dinfo;
  929         struct resource_list *rl;
  930         int retval = 0;
  931 
  932         dinfo = device_get_ivars(child);
  933         rl = &dinfo->resources;
  934 
  935         retval += bus_print_child_header(dev, child);
  936 
  937         retval += resource_list_print_type(rl, "port", SYS_RES_IOPORT, "%#lx");
  938         retval += resource_list_print_type(rl, "mem", SYS_RES_MEMORY, "%#lx");
  939         retval += resource_list_print_type(rl, "irq", SYS_RES_IRQ, "%ld");
  940         if (device_get_flags(dev))
  941                 retval += printf(" flags %#x", device_get_flags(dev));
  942 
  943         retval += printf(" at device %d.%d", pci_get_slot(child),
  944             pci_get_function(child));
  945 
  946         retval += bus_print_child_footer(dev, child);
  947 
  948         return (retval);
  949 }
  950 
  951 static struct
  952 {
  953         int     class;
  954         int     subclass;
  955         char    *desc;
  956 } pci_nomatch_tab[] = {
  957         {PCIC_OLD,              -1,                     "old"},
  958         {PCIC_OLD,              PCIS_OLD_NONVGA,        "non-VGA display device"},
  959         {PCIC_OLD,              PCIS_OLD_VGA,           "VGA-compatible display device"},
  960         {PCIC_STORAGE,          -1,                     "mass storage"},
  961         {PCIC_STORAGE,          PCIS_STORAGE_SCSI,      "SCSI"},
  962         {PCIC_STORAGE,          PCIS_STORAGE_IDE,       "ATA"},
  963         {PCIC_STORAGE,          PCIS_STORAGE_FLOPPY,    "floppy disk"},
  964         {PCIC_STORAGE,          PCIS_STORAGE_IPI,       "IPI"},
  965         {PCIC_STORAGE,          PCIS_STORAGE_RAID,      "RAID"},
  966         {PCIC_NETWORK,          -1,                     "network"},
  967         {PCIC_NETWORK,          PCIS_NETWORK_ETHERNET,  "ethernet"},
  968         {PCIC_NETWORK,          PCIS_NETWORK_TOKENRING, "token ring"},
  969         {PCIC_NETWORK,          PCIS_NETWORK_FDDI,      "fddi"},
  970         {PCIC_NETWORK,          PCIS_NETWORK_ATM,       "ATM"},
  971         {PCIC_DISPLAY,          -1,                     "display"},
  972         {PCIC_DISPLAY,          PCIS_DISPLAY_VGA,       "VGA"},
  973         {PCIC_DISPLAY,          PCIS_DISPLAY_XGA,       "XGA"},
  974         {PCIC_MULTIMEDIA,       -1,                     "multimedia"},
  975         {PCIC_MULTIMEDIA,       PCIS_MULTIMEDIA_VIDEO,  "video"},
  976         {PCIC_MULTIMEDIA,       PCIS_MULTIMEDIA_AUDIO,  "audio"},
  977         {PCIC_MEMORY,           -1,                     "memory"},
  978         {PCIC_MEMORY,           PCIS_MEMORY_RAM,        "RAM"},
  979         {PCIC_MEMORY,           PCIS_MEMORY_FLASH,      "flash"},
  980         {PCIC_BRIDGE,           -1,                     "bridge"},
  981         {PCIC_BRIDGE,           PCIS_BRIDGE_HOST,       "HOST-PCI"},
  982         {PCIC_BRIDGE,           PCIS_BRIDGE_ISA,        "PCI-ISA"},
  983         {PCIC_BRIDGE,           PCIS_BRIDGE_EISA,       "PCI-EISA"},
  984         {PCIC_BRIDGE,           PCIS_BRIDGE_MCA,        "PCI-MCA"},
  985         {PCIC_BRIDGE,           PCIS_BRIDGE_PCI,        "PCI-PCI"},
  986         {PCIC_BRIDGE,           PCIS_BRIDGE_PCMCIA,     "PCI-PCMCIA"},
  987         {PCIC_BRIDGE,           PCIS_BRIDGE_NUBUS,      "PCI-NuBus"},
  988         {PCIC_BRIDGE,           PCIS_BRIDGE_CARDBUS,    "PCI-CardBus"},
  989         {PCIC_BRIDGE,           PCIS_BRIDGE_OTHER,      "PCI-unknown"},
  990         {PCIC_SIMPLECOMM,       -1,                     "simple comms"},
  991         {PCIC_SIMPLECOMM,       PCIS_SIMPLECOMM_UART,   "UART"},        /* could detect 16550 */
  992         {PCIC_SIMPLECOMM,       PCIS_SIMPLECOMM_PAR,    "parallel port"},
  993         {PCIC_BASEPERIPH,       -1,                     "base peripheral"},
  994         {PCIC_BASEPERIPH,       PCIS_BASEPERIPH_PIC,    "interrupt controller"},
  995         {PCIC_BASEPERIPH,       PCIS_BASEPERIPH_DMA,    "DMA controller"},
  996         {PCIC_BASEPERIPH,       PCIS_BASEPERIPH_TIMER,  "timer"},
  997         {PCIC_BASEPERIPH,       PCIS_BASEPERIPH_RTC,    "realtime clock"},
  998         {PCIC_INPUTDEV,         -1,                     "input device"},
  999         {PCIC_INPUTDEV,         PCIS_INPUTDEV_KEYBOARD, "keyboard"},
 1000         {PCIC_INPUTDEV,         PCIS_INPUTDEV_DIGITIZER,"digitizer"},
 1001         {PCIC_INPUTDEV,         PCIS_INPUTDEV_MOUSE,    "mouse"},
 1002         {PCIC_DOCKING,          -1,                     "docking station"},
 1003         {PCIC_PROCESSOR,        -1,                     "processor"},
 1004         {PCIC_SERIALBUS,        -1,                     "serial bus"},
 1005         {PCIC_SERIALBUS,        PCIS_SERIALBUS_FW,      "FireWire"},
 1006         {PCIC_SERIALBUS,        PCIS_SERIALBUS_ACCESS,  "AccessBus"},    
 1007         {PCIC_SERIALBUS,        PCIS_SERIALBUS_SSA,     "SSA"},
 1008         {PCIC_SERIALBUS,        PCIS_SERIALBUS_USB,     "USB"},
 1009         {PCIC_SERIALBUS,        PCIS_SERIALBUS_FC,      "Fibre Channel"},
 1010         {PCIC_SERIALBUS,        PCIS_SERIALBUS_SMBUS,   "SMBus"},
 1011         {0, 0,          NULL}
 1012 };
 1013 
 1014 void
 1015 pci_probe_nomatch(device_t dev, device_t child)
 1016 {
 1017         int     i;
 1018         char    *cp, *scp, *device;
 1019         
 1020         /*
 1021          * Look for a listing for this device in a loaded device database.
 1022          */
 1023         if ((device = pci_describe_device(child)) != NULL) {
 1024                 device_printf(dev, "<%s>", device);
 1025                 free(device, M_DEVBUF);
 1026         } else {
 1027                 /*
 1028                  * Scan the class/subclass descriptions for a general
 1029                  * description.
 1030                  */
 1031                 cp = "unknown";
 1032                 scp = NULL;
 1033                 for (i = 0; pci_nomatch_tab[i].desc != NULL; i++) {
 1034                         if (pci_nomatch_tab[i].class == pci_get_class(child)) {
 1035                                 if (pci_nomatch_tab[i].subclass == -1) {
 1036                                         cp = pci_nomatch_tab[i].desc;
 1037                                 } else if (pci_nomatch_tab[i].subclass ==
 1038                                     pci_get_subclass(child)) {
 1039                                         scp = pci_nomatch_tab[i].desc;
 1040                                 }
 1041                         }
 1042                 }
 1043                 device_printf(dev, "<%s%s%s>", 
 1044                     cp ? cp : "",
 1045                     ((cp != NULL) && (scp != NULL)) ? ", " : "",
 1046                     scp ? scp : "");
 1047         }
 1048         printf(" at device %d.%d (no driver attached)\n",
 1049             pci_get_slot(child), pci_get_function(child));
 1050         return;
 1051 }
 1052 
 1053 /*
 1054  * Parse the PCI device database, if loaded, and return a pointer to a 
 1055  * description of the device.
 1056  *
 1057  * The database is flat text formatted as follows:
 1058  *
 1059  * Any line not in a valid format is ignored.
 1060  * Lines are terminated with newline '\n' characters.
 1061  * 
 1062  * A VENDOR line consists of the 4 digit (hex) vendor code, a TAB, then
 1063  * the vendor name.
 1064  * 
 1065  * A DEVICE line is entered immediately below the corresponding VENDOR ID.
 1066  * - devices cannot be listed without a corresponding VENDOR line.
 1067  * A DEVICE line consists of a TAB, the 4 digit (hex) device code,
 1068  * another TAB, then the device name.                                            
 1069  */
 1070 
 1071 /*
 1072  * Assuming (ptr) points to the beginning of a line in the database,
 1073  * return the vendor or device and description of the next entry.
 1074  * The value of (vendor) or (device) inappropriate for the entry type
 1075  * is set to -1.  Returns nonzero at the end of the database.
 1076  *
 1077  * Note that this is slightly unrobust in the face of corrupt data;
 1078  * we attempt to safeguard against this by spamming the end of the
 1079  * database with a newline when we initialise.
 1080  */
 1081 static int
 1082 pci_describe_parse_line(char **ptr, int *vendor, int *device, char **desc) 
 1083 {
 1084         char    *cp = *ptr;
 1085         int     left;
 1086 
 1087         *device = -1;
 1088         *vendor = -1;
 1089         **desc = '\0';
 1090         for (;;) {
 1091                 left = pci_vendordata_size - (cp - pci_vendordata);
 1092                 if (left <= 0) {
 1093                         *ptr = cp;
 1094                         return(1);
 1095                 }
 1096 
 1097                 /* vendor entry? */
 1098                 if (*cp != '\t' &&
 1099                     sscanf(cp, "%x\t%80[^\n]", vendor, *desc) == 2)
 1100                         break;
 1101                 /* device entry? */
 1102                 if (*cp == '\t' &&
 1103                     sscanf(cp, "%x\t%80[^\n]", device, *desc) == 2)
 1104                         break;
 1105                 
 1106                 /* skip to next line */
 1107                 while (*cp != '\n' && left > 0) {
 1108                         cp++;
 1109                         left--;
 1110                 }
 1111                 if (*cp == '\n') {
 1112                         cp++;
 1113                         left--;
 1114                 }
 1115         }
 1116         /* skip to next line */
 1117         while (*cp != '\n' && left > 0) {
 1118                 cp++;
 1119                 left--;
 1120         }
 1121         if (*cp == '\n' && left > 0)
 1122                 cp++;
 1123         *ptr = cp;
 1124         return(0);
 1125 }
 1126 
 1127 static char *
 1128 pci_describe_device(device_t dev)
 1129 {
 1130         int     vendor, device;
 1131         char    *desc, *vp, *dp, *line;
 1132 
 1133         desc = vp = dp = NULL;
 1134         
 1135         /*
 1136          * If we have no vendor data, we can't do anything.
 1137          */
 1138         if (pci_vendordata == NULL)
 1139                 goto out;
 1140 
 1141         /*
 1142          * Scan the vendor data looking for this device
 1143          */
 1144         line = pci_vendordata;
 1145         if ((vp = malloc(80, M_DEVBUF, M_NOWAIT)) == NULL)
 1146                 goto out;
 1147         for (;;) {
 1148                 if (pci_describe_parse_line(&line, &vendor, &device, &vp))
 1149                         goto out;
 1150                 if (vendor == pci_get_vendor(dev))
 1151                         break;
 1152         }
 1153         if ((dp = malloc(80, M_DEVBUF, M_NOWAIT)) == NULL)
 1154                 goto out;
 1155         for (;;) {
 1156                 if (pci_describe_parse_line(&line, &vendor, &device, &dp)) {
 1157                         *dp = 0;
 1158                         break;
 1159                 }
 1160                 if (vendor != -1) {
 1161                         *dp = 0;
 1162                         break;
 1163                 }
 1164                 if (device == pci_get_device(dev))
 1165                         break;
 1166         }
 1167         if (dp[0] == '\0')
 1168                 snprintf(dp, 80, "0x%x", pci_get_device(dev));
 1169         if ((desc = malloc(strlen(vp) + strlen(dp) + 3, M_DEVBUF, M_NOWAIT)) !=
 1170             NULL)
 1171                 sprintf(desc, "%s, %s", vp, dp);
 1172  out:
 1173         if (vp != NULL)
 1174                 free(vp, M_DEVBUF);
 1175         if (dp != NULL)
 1176                 free(dp, M_DEVBUF);
 1177         return(desc);
 1178 }
 1179 
 1180 int
 1181 pci_read_ivar(device_t dev, device_t child, int which, uintptr_t *result)
 1182 {
 1183         struct pci_devinfo *dinfo;
 1184         pcicfgregs *cfg;
 1185 
 1186         dinfo = device_get_ivars(child);
 1187         cfg = &dinfo->cfg;
 1188 
 1189         switch (which) {
 1190         case PCI_IVAR_ETHADDR:
 1191                 /*
 1192                  * The generic accessor doesn't deal with failure, so
 1193                  * we set the return value, then return an error.
 1194                  */
 1195                 *((uint8_t **) result) = NULL;
 1196                 return (EINVAL);
 1197         case PCI_IVAR_SUBVENDOR:
 1198                 *result = cfg->subvendor;
 1199                 break;
 1200         case PCI_IVAR_SUBDEVICE:
 1201                 *result = cfg->subdevice;
 1202                 break;
 1203         case PCI_IVAR_VENDOR:
 1204                 *result = cfg->vendor;
 1205                 break;
 1206         case PCI_IVAR_DEVICE:
 1207                 *result = cfg->device;
 1208                 break;
 1209         case PCI_IVAR_DEVID:
 1210                 *result = (cfg->device << 16) | cfg->vendor;
 1211                 break;
 1212         case PCI_IVAR_CLASS:
 1213                 *result = cfg->baseclass;
 1214                 break;
 1215         case PCI_IVAR_SUBCLASS:
 1216                 *result = cfg->subclass;
 1217                 break;
 1218         case PCI_IVAR_PROGIF:
 1219                 *result = cfg->progif;
 1220                 break;
 1221         case PCI_IVAR_REVID:
 1222                 *result = cfg->revid;
 1223                 break;
 1224         case PCI_IVAR_INTPIN:
 1225                 *result = cfg->intpin;
 1226                 break;
 1227         case PCI_IVAR_IRQ:
 1228                 *result = cfg->intline;
 1229                 break;
 1230         case PCI_IVAR_BUS:
 1231                 *result = cfg->bus;
 1232                 break;
 1233         case PCI_IVAR_SLOT:
 1234                 *result = cfg->slot;
 1235                 break;
 1236         case PCI_IVAR_FUNCTION:
 1237                 *result = cfg->func;
 1238                 break;
 1239         default:
 1240                 return (ENOENT);
 1241         }
 1242         return (0);
 1243 }
 1244 
 1245 int
 1246 pci_write_ivar(device_t dev, device_t child, int which, uintptr_t value)
 1247 {
 1248         struct pci_devinfo *dinfo;
 1249 
 1250         dinfo = device_get_ivars(child);
 1251 
 1252         switch (which) {
 1253         case PCI_IVAR_INTPIN:
 1254                 dinfo->cfg.intpin = value;
 1255                 return (0);
 1256         case PCI_IVAR_ETHADDR:
 1257         case PCI_IVAR_SUBVENDOR:
 1258         case PCI_IVAR_SUBDEVICE:
 1259         case PCI_IVAR_VENDOR:
 1260         case PCI_IVAR_DEVICE:
 1261         case PCI_IVAR_DEVID:
 1262         case PCI_IVAR_CLASS:
 1263         case PCI_IVAR_SUBCLASS:
 1264         case PCI_IVAR_PROGIF:
 1265         case PCI_IVAR_REVID:
 1266         case PCI_IVAR_IRQ:
 1267         case PCI_IVAR_BUS:
 1268         case PCI_IVAR_SLOT:
 1269         case PCI_IVAR_FUNCTION:
 1270                 return (EINVAL);        /* disallow for now */
 1271 
 1272         default:
 1273                 return (ENOENT);
 1274         }
 1275 }
 1276 
 1277 
 1278 #include "opt_ddb.h"
 1279 #ifdef DDB
 1280 #include <ddb/ddb.h>
 1281 #include <sys/cons.h>
 1282 
 1283 /*
 1284  * List resources based on pci map registers, used for within ddb
 1285  */
 1286 
 1287 DB_SHOW_COMMAND(pciregs, db_pci_dump)
 1288 {
 1289         struct pci_devinfo *dinfo;
 1290         struct devlist *devlist_head;
 1291         struct pci_conf *p;
 1292         const char *name;
 1293         int i, error, none_count, quit;
 1294 
 1295         none_count = 0;
 1296         /* get the head of the device queue */
 1297         devlist_head = &pci_devq;
 1298 
 1299         /*
 1300          * Go through the list of devices and print out devices
 1301          */
 1302         db_setup_paging(db_simple_pager, &quit, DB_LINES_PER_PAGE);
 1303         for (error = 0, i = 0, quit = 0,
 1304              dinfo = STAILQ_FIRST(devlist_head);
 1305              (dinfo != NULL) && (error == 0) && (i < pci_numdevs) && !quit;
 1306              dinfo = STAILQ_NEXT(dinfo, pci_links), i++) {
 1307 
 1308                 /* Populate pd_name and pd_unit */
 1309                 name = NULL;
 1310                 if (dinfo->cfg.dev)
 1311                         name = device_get_name(dinfo->cfg.dev);
 1312 
 1313                 p = &dinfo->conf;
 1314                 db_printf("%s%d@pci%d:%d:%d:\tclass=0x%06x card=0x%08x "
 1315                         "chip=0x%08x rev=0x%02x hdr=0x%02x\n",
 1316                         (name && *name) ? name : "none",
 1317                         (name && *name) ? (int)device_get_unit(dinfo->cfg.dev) :
 1318                         none_count++,
 1319                         p->pc_sel.pc_bus, p->pc_sel.pc_dev,
 1320                         p->pc_sel.pc_func, (p->pc_class << 16) |
 1321                         (p->pc_subclass << 8) | p->pc_progif,
 1322                         (p->pc_subdevice << 16) | p->pc_subvendor,
 1323                         (p->pc_device << 16) | p->pc_vendor,
 1324                         p->pc_revid, p->pc_hdr);
 1325         }
 1326 }
 1327 #endif /* DDB */
 1328 
 1329 struct resource *
 1330 pci_alloc_resource(device_t dev, device_t child, int type, int *rid,
 1331                    u_long start, u_long end, u_long count, u_int flags)
 1332 {
 1333         struct pci_devinfo *dinfo = device_get_ivars(child);
 1334         struct resource_list *rl = &dinfo->resources;
 1335         pcicfgregs *cfg = &dinfo->cfg;
 1336 
 1337         /*
 1338          * Perform lazy resource allocation
 1339          *
 1340          * XXX add support here for SYS_RES_IOPORT and SYS_RES_MEMORY
 1341          */
 1342         if (device_get_parent(child) == dev) {
 1343                 switch (type) {
 1344                 case SYS_RES_IRQ:
 1345                         /*
 1346                          * If the child device doesn't have an
 1347                          * interrupt routed and is deserving of an
 1348                          * interrupt, try to assign it one.
 1349                          */
 1350                         if (!PCI_INTERRUPT_VALID(cfg->intline) &&
 1351                             (cfg->intpin != 0)) {
 1352                                 cfg->intline = PCI_ASSIGN_INTERRUPT(dev, child);
 1353                                 if (PCI_INTERRUPT_VALID(cfg->intline)) {
 1354                                         pci_write_config(child, PCIR_INTLINE,
 1355                                             cfg->intline, 1);
 1356                                         resource_list_add(rl, SYS_RES_IRQ, 0,
 1357                                             cfg->intline, cfg->intline, 1);
 1358                                 }
 1359                         }
 1360                         break;
 1361                 case SYS_RES_IOPORT:
 1362                 case SYS_RES_MEMORY:
 1363                         if (*rid < PCIR_BAR(cfg->nummaps)) {
 1364                                 /*
 1365                                  * Enable the I/O mode.  We should
 1366                                  * also be allocating resources
 1367                                  * too. XXX
 1368                                  */
 1369                                 if (PCI_ENABLE_IO(dev, child, type))
 1370                                         return (NULL);
 1371                         }
 1372                         break;
 1373                 }
 1374         }
 1375 
 1376         return (resource_list_alloc(rl, dev, child, type, rid,
 1377             start, end, count, flags));
 1378 }
 1379 
 1380 void
 1381 pci_delete_resource(device_t dev, device_t child, int type, int rid)
 1382 {
 1383         struct pci_devinfo *dinfo;
 1384         struct resource_list *rl;
 1385         struct resource_list_entry *rle;
 1386 
 1387         if (device_get_parent(child) != dev)
 1388                 return;
 1389 
 1390         dinfo = device_get_ivars(child);
 1391         rl = &dinfo->resources;
 1392         rle = resource_list_find(rl, type, rid);
 1393         if (rle) {
 1394                 if (rle->res) {
 1395                         if (rman_get_device(rle->res) != dev ||
 1396                             rman_get_flags(rle->res) & RF_ACTIVE) {
 1397                                 device_printf(dev, "delete_resource: "
 1398                                     "Resource still owned by child, oops. "
 1399                                     "(type=%d, rid=%d, addr=%lx)\n",
 1400                                     rle->type, rle->rid,
 1401                                     rman_get_start(rle->res));
 1402                                 return;
 1403                         }
 1404                         bus_release_resource(dev, type, rid, rle->res);
 1405                 }
 1406                 resource_list_delete(rl, type, rid);
 1407         }
 1408         /* 
 1409          * Why do we turn off the PCI configuration BAR when we delete a
 1410          * resource? -- imp
 1411          */
 1412         pci_write_config(child, rid, 0, 4);
 1413         BUS_DELETE_RESOURCE(device_get_parent(dev), child, type, rid);
 1414 }
 1415 
 1416 struct resource_list *
 1417 pci_get_resource_list (device_t dev, device_t child)
 1418 {
 1419         struct pci_devinfo *    dinfo = device_get_ivars(child);
 1420         struct resource_list *  rl = &dinfo->resources;
 1421 
 1422         if (!rl)
 1423                 return (NULL);
 1424 
 1425         return (rl);
 1426 }
 1427 
 1428 uint32_t
 1429 pci_read_config_method(device_t dev, device_t child, int reg, int width)
 1430 {
 1431         struct pci_devinfo *dinfo = device_get_ivars(child);
 1432         pcicfgregs *cfg = &dinfo->cfg;
 1433 
 1434         return (PCIB_READ_CONFIG(device_get_parent(dev),
 1435             cfg->bus, cfg->slot, cfg->func, reg, width));
 1436 }
 1437 
 1438 void
 1439 pci_write_config_method(device_t dev, device_t child, int reg, 
 1440     uint32_t val, int width)
 1441 {
 1442         struct pci_devinfo *dinfo = device_get_ivars(child);
 1443         pcicfgregs *cfg = &dinfo->cfg;
 1444 
 1445         PCIB_WRITE_CONFIG(device_get_parent(dev),
 1446             cfg->bus, cfg->slot, cfg->func, reg, val, width);
 1447 }
 1448 
 1449 int
 1450 pci_child_location_str_method(device_t cbdev, device_t child, char *buf,
 1451     size_t buflen)
 1452 {
 1453         struct pci_devinfo *dinfo;
 1454 
 1455         dinfo = device_get_ivars(child);
 1456         snprintf(buf, buflen, "slot=%d function=%d", pci_get_slot(child),
 1457             pci_get_function(child));
 1458         return (0);
 1459 }
 1460 
 1461 int
 1462 pci_child_pnpinfo_str_method(device_t cbdev, device_t child, char *buf,
 1463     size_t buflen)
 1464 {
 1465         struct pci_devinfo *dinfo;
 1466         pcicfgregs *cfg;
 1467 
 1468         dinfo = device_get_ivars(child);
 1469         cfg = &dinfo->cfg;
 1470         snprintf(buf, buflen, "vendor=0x%04x device=0x%04x subvendor=0x%04x "
 1471             "subdevice=0x%04x class=0x%02x%02x%02x", cfg->vendor, cfg->device,
 1472             cfg->subvendor, cfg->subdevice, cfg->baseclass, cfg->subclass,
 1473             cfg->progif);
 1474         return (0);
 1475 }
 1476 
 1477 int
 1478 pci_assign_interrupt_method(device_t dev, device_t child)
 1479 {
 1480         struct pci_devinfo *dinfo = device_get_ivars(child);
 1481         pcicfgregs *cfg = &dinfo->cfg;
 1482 
 1483         return (PCIB_ROUTE_INTERRUPT(device_get_parent(dev), child,
 1484             cfg->intpin));
 1485 }
 1486 
 1487 static int
 1488 pci_modevent(module_t mod, int what, void *arg)
 1489 {
 1490         static dev_t pci_cdev;
 1491 
 1492         switch (what) {
 1493         case MOD_LOAD:
 1494                 STAILQ_INIT(&pci_devq);
 1495                 pci_generation = 0;
 1496                 pci_cdev = make_dev(&pcicdev, 0, UID_ROOT, GID_WHEEL, 0644,
 1497                     "pci");
 1498                 pci_load_vendor_data();
 1499                 break;
 1500 
 1501         case MOD_UNLOAD:
 1502                 destroy_dev(pci_cdev);
 1503                 break;
 1504         }
 1505 
 1506         return (0);
 1507 }
 1508 
 1509 int
 1510 pci_resume(device_t dev)
 1511 {
 1512         int                     numdevs;
 1513         int                     i;
 1514         device_t                *children;
 1515         device_t                child;
 1516         struct pci_devinfo      *dinfo;
 1517         pcicfgregs              *cfg;
 1518 
 1519         device_get_children(dev, &children, &numdevs);
 1520 
 1521         for (i = 0; i < numdevs; i++) {
 1522                 child = children[i];
 1523 
 1524                 dinfo = device_get_ivars(child);
 1525                 cfg = &dinfo->cfg;
 1526                 if (cfg->intpin > 0 && PCI_INTERRUPT_VALID(cfg->intline)) {
 1527                         cfg->intline = PCI_ASSIGN_INTERRUPT(dev, child);
 1528                         if (PCI_INTERRUPT_VALID(cfg->intline)) {
 1529                                 pci_write_config(child, PCIR_INTLINE,
 1530                                     cfg->intline, 1);
 1531                         }
 1532                 }
 1533         }
 1534 
 1535         free(children, M_TEMP);
 1536 
 1537         return (bus_generic_resume(dev));
 1538 }
 1539 

Cache object: 82cba88fbfdaffda39743f9451497229


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