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

Cache object: 8b169c5d6fa74a951b25897cda2945d7


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