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/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  * All rights reserved.
    4  *
    5  * Redistribution and use in source and binary forms, with or without
    6  * modification, are permitted provided that the following conditions
    7  * are met:
    8  * 1. Redistributions of source code must retain the above copyright
    9  *    notice unmodified, this list of conditions, and the following
   10  *    disclaimer.
   11  * 2. Redistributions in binary form must reproduce the above copyright
   12  *    notice, this list of conditions and the following disclaimer in the
   13  *    documentation and/or other materials provided with the distribution.
   14  *
   15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
   16  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   17  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
   18  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
   19  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
   20  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   21  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
   22  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   23  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
   24  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   25  *
   26  * $FreeBSD$
   27  *
   28  */
   29 
   30 #include "opt_bus.h"
   31 #include "opt_pci.h"
   32 
   33 #include "opt_simos.h"
   34 
   35 #include <sys/param.h>
   36 #include <sys/systm.h>
   37 #include <sys/malloc.h>
   38 #include <sys/module.h>
   39 #include <sys/fcntl.h>
   40 #include <sys/conf.h>
   41 #include <sys/kernel.h>
   42 #include <sys/queue.h>
   43 #include <sys/types.h>
   44 #include <sys/buf.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 #include <machine/md_var.h>             /* For the Alpha */
   55 #ifdef __i386__
   56 #include <machine/pci_cfgreg.h>
   57 #endif
   58 
   59 #include <pci/pcireg.h>
   60 #include <pci/pcivar.h>
   61 #include <sys/pciio.h>
   62 
   63 #ifdef __alpha__
   64 #include <machine/rpb.h>
   65 #endif
   66 
   67 #ifdef APIC_IO
   68 #include <machine/smp.h>
   69 #endif /* APIC_IO */
   70 
   71 static void             pci_read_extcap(pcicfgregs *cfg);
   72 
   73 struct pci_quirk {
   74         u_int32_t devid;        /* Vendor/device of the card */
   75         int     type;
   76 #define PCI_QUIRK_MAP_REG       1 /* PCI map register in wierd place */
   77         int     arg1;
   78         int     arg2;
   79 };
   80 
   81 struct pci_quirk pci_quirks[] = {
   82         /*
   83          * The Intel 82371AB and 82443MX has a map register at offset 0x90.
   84          */
   85         { 0x71138086, PCI_QUIRK_MAP_REG,        0x90,    0 },
   86         { 0x719b8086, PCI_QUIRK_MAP_REG,        0x90,    0 },
   87 
   88         { 0 }
   89 };
   90 
   91 /* map register information */
   92 #define PCI_MAPMEM      0x01    /* memory map */
   93 #define PCI_MAPMEMP     0x02    /* prefetchable memory map */
   94 #define PCI_MAPPORT     0x04    /* port map */
   95 
   96 struct pci_devinfo {
   97         STAILQ_ENTRY(pci_devinfo) pci_links;
   98         struct resource_list resources;
   99         pcicfgregs              cfg;
  100         struct pci_conf         conf;
  101 };
  102 
  103 static STAILQ_HEAD(devlist, pci_devinfo) pci_devq;
  104 u_int32_t pci_numdevs = 0;
  105 static u_int32_t pci_generation = 0;
  106 
  107 device_t
  108 pci_find_bsf (u_int8_t bus, u_int8_t slot, u_int8_t func)
  109 {
  110         struct pci_devinfo *dinfo;
  111 
  112         STAILQ_FOREACH(dinfo, &pci_devq, pci_links) {
  113                 if ((dinfo->cfg.bus == bus) &&
  114                     (dinfo->cfg.slot == slot) &&
  115                     (dinfo->cfg.func == func)) {
  116                         return (dinfo->cfg.dev);
  117                 }
  118         }
  119 
  120         return (NULL);
  121 }
  122 
  123 device_t
  124 pci_find_device (u_int16_t vendor, u_int16_t device)
  125 {
  126         struct pci_devinfo *dinfo;
  127 
  128         STAILQ_FOREACH(dinfo, &pci_devq, pci_links) {
  129                 if ((dinfo->cfg.vendor == vendor) &&
  130                     (dinfo->cfg.device == device)) {
  131                         return (dinfo->cfg.dev);
  132                 }
  133         }
  134 
  135         return (NULL);
  136 }
  137 
  138 /* return base address of memory or port map */
  139 
  140 static u_int32_t
  141 pci_mapbase(unsigned mapreg)
  142 {
  143         int mask = 0x03;
  144         if ((mapreg & 0x01) == 0)
  145                 mask = 0x0f;
  146         return (mapreg & ~mask);
  147 }
  148 
  149 /* return map type of memory or port map */
  150 
  151 static int
  152 pci_maptype(unsigned mapreg)
  153 {
  154         static u_int8_t maptype[0x10] = {
  155                 PCI_MAPMEM,             PCI_MAPPORT,
  156                 PCI_MAPMEM,             0,
  157                 PCI_MAPMEM,             PCI_MAPPORT,
  158                 0,                      0,
  159                 PCI_MAPMEM|PCI_MAPMEMP, PCI_MAPPORT,
  160                 PCI_MAPMEM|PCI_MAPMEMP, 0,
  161                 PCI_MAPMEM|PCI_MAPMEMP, PCI_MAPPORT,
  162                 0,                      0,
  163         };
  164 
  165         return maptype[mapreg & 0x0f];
  166 }
  167 
  168 /* return log2 of map size decoded for memory or port map */
  169 
  170 static int
  171 pci_mapsize(unsigned testval)
  172 {
  173         int ln2size;
  174 
  175         testval = pci_mapbase(testval);
  176         ln2size = 0;
  177         if (testval != 0) {
  178                 while ((testval & 1) == 0)
  179                 {
  180                         ln2size++;
  181                         testval >>= 1;
  182                 }
  183         }
  184         return (ln2size);
  185 }
  186 
  187 /* return log2 of address range supported by map register */
  188 
  189 static int
  190 pci_maprange(unsigned mapreg)
  191 {
  192         int ln2range = 0;
  193         switch (mapreg & 0x07) {
  194         case 0x00:
  195         case 0x01:
  196         case 0x05:
  197                 ln2range = 32;
  198                 break;
  199         case 0x02:
  200                 ln2range = 20;
  201                 break;
  202         case 0x04:
  203                 ln2range = 64;
  204                 break;
  205         }
  206         return (ln2range);
  207 }
  208 
  209 /* adjust some values from PCI 1.0 devices to match 2.0 standards ... */
  210 
  211 static void
  212 pci_fixancient(pcicfgregs *cfg)
  213 {
  214         if (cfg->hdrtype != 0)
  215                 return;
  216 
  217         /* PCI to PCI bridges use header type 1 */
  218         if (cfg->baseclass == PCIC_BRIDGE && cfg->subclass == PCIS_BRIDGE_PCI)
  219                 cfg->hdrtype = 1;
  220 }
  221 
  222 /* read config data specific to header type 1 device (PCI to PCI bridge) */
  223 
  224 static void *
  225 pci_readppb(pcicfgregs *cfg)
  226 {
  227         pcih1cfgregs *p;
  228 
  229         p = malloc(sizeof (pcih1cfgregs), M_DEVBUF, M_WAITOK);
  230         if (p == NULL)
  231                 return (NULL);
  232 
  233         bzero(p, sizeof *p);
  234 
  235         p->secstat = pci_cfgread(cfg, PCIR_SECSTAT_1, 2);
  236         p->bridgectl = pci_cfgread(cfg, PCIR_BRIDGECTL_1, 2);
  237 
  238         p->seclat = pci_cfgread(cfg, PCIR_SECLAT_1, 1);
  239 
  240         p->iobase = PCI_PPBIOBASE (pci_cfgread(cfg, PCIR_IOBASEH_1, 2),
  241                                    pci_cfgread(cfg, PCIR_IOBASEL_1, 1));
  242         p->iolimit = PCI_PPBIOLIMIT (pci_cfgread(cfg, PCIR_IOLIMITH_1, 2),
  243                                      pci_cfgread(cfg, PCIR_IOLIMITL_1, 1));
  244 
  245         p->membase = PCI_PPBMEMBASE (0,
  246                                      pci_cfgread(cfg, PCIR_MEMBASE_1, 2));
  247         p->memlimit = PCI_PPBMEMLIMIT (0,
  248                                        pci_cfgread(cfg, PCIR_MEMLIMIT_1, 2));
  249 
  250         p->pmembase = PCI_PPBMEMBASE (
  251                 (pci_addr_t)pci_cfgread(cfg, PCIR_PMBASEH_1, 4),
  252                 pci_cfgread(cfg, PCIR_PMBASEL_1, 2));
  253 
  254         p->pmemlimit = PCI_PPBMEMLIMIT (
  255                 (pci_addr_t)pci_cfgread(cfg, PCIR_PMLIMITH_1, 4),
  256                 pci_cfgread(cfg, PCIR_PMLIMITL_1, 2));
  257         return (p);
  258 }
  259 
  260 /* read config data specific to header type 2 device (PCI to CardBus bridge) */
  261 
  262 static void *
  263 pci_readpcb(pcicfgregs *cfg)
  264 {
  265         pcih2cfgregs *p;
  266 
  267         p = malloc(sizeof (pcih2cfgregs), M_DEVBUF, M_WAITOK);
  268         if (p == NULL)
  269                 return (NULL);
  270 
  271         bzero(p, sizeof *p);
  272 
  273         p->secstat = pci_cfgread(cfg, PCIR_SECSTAT_2, 2);
  274         p->bridgectl = pci_cfgread(cfg, PCIR_BRIDGECTL_2, 2);
  275         
  276         p->seclat = pci_cfgread(cfg, PCIR_SECLAT_2, 1);
  277 
  278         p->membase0 = pci_cfgread(cfg, PCIR_MEMBASE0_2, 4);
  279         p->memlimit0 = pci_cfgread(cfg, PCIR_MEMLIMIT0_2, 4);
  280         p->membase1 = pci_cfgread(cfg, PCIR_MEMBASE1_2, 4);
  281         p->memlimit1 = pci_cfgread(cfg, PCIR_MEMLIMIT1_2, 4);
  282 
  283         p->iobase0 = pci_cfgread(cfg, PCIR_IOBASE0_2, 4);
  284         p->iolimit0 = pci_cfgread(cfg, PCIR_IOLIMIT0_2, 4);
  285         p->iobase1 = pci_cfgread(cfg, PCIR_IOBASE1_2, 4);
  286         p->iolimit1 = pci_cfgread(cfg, PCIR_IOLIMIT1_2, 4);
  287 
  288         p->pccardif = pci_cfgread(cfg, PCIR_PCCARDIF_2, 4);
  289         return p;
  290 }
  291 
  292 /* extract header type specific config data */
  293 
  294 static void
  295 pci_hdrtypedata(pcicfgregs *cfg)
  296 {
  297         switch (cfg->hdrtype) {
  298         case 0:
  299                 cfg->subvendor      = pci_cfgread(cfg, PCIR_SUBVEND_0, 2);
  300                 cfg->subdevice      = pci_cfgread(cfg, PCIR_SUBDEV_0, 2);
  301                 cfg->nummaps        = PCI_MAXMAPS_0;
  302                 break;
  303         case 1:
  304                 cfg->subvendor      = pci_cfgread(cfg, PCIR_SUBVEND_1, 2);
  305                 cfg->subdevice      = pci_cfgread(cfg, PCIR_SUBDEV_1, 2);
  306                 cfg->secondarybus   = pci_cfgread(cfg, PCIR_SECBUS_1, 1);
  307                 cfg->subordinatebus = pci_cfgread(cfg, PCIR_SUBBUS_1, 1);
  308                 cfg->nummaps        = PCI_MAXMAPS_1;
  309                 cfg->hdrspec        = pci_readppb(cfg);
  310                 break;
  311         case 2:
  312                 cfg->subvendor      = pci_cfgread(cfg, PCIR_SUBVEND_2, 2);
  313                 cfg->subdevice      = pci_cfgread(cfg, PCIR_SUBDEV_2, 2);
  314                 cfg->secondarybus   = pci_cfgread(cfg, PCIR_SECBUS_2, 1);
  315                 cfg->subordinatebus = pci_cfgread(cfg, PCIR_SUBBUS_2, 1);
  316                 cfg->nummaps        = PCI_MAXMAPS_2;
  317                 cfg->hdrspec        = pci_readpcb(cfg);
  318                 break;
  319         }
  320 }
  321 
  322 /* read configuration header into pcicfgrect structure */
  323 
  324 static struct pci_devinfo *
  325 pci_readcfg(pcicfgregs *probe, device_t bus)
  326 {
  327 #define REG(n, w)       pci_cfgread(probe, n, w)
  328 
  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 (pci_cfgread(probe, PCIR_DEVVENDOR, 4) != -1) {
  338 
  339                 devlist_entry = malloc(sizeof(struct pci_devinfo),
  340                                        M_DEVBUF, M_WAITOK);
  341                 if (devlist_entry == NULL)
  342                         return (NULL);
  343                 bzero(devlist_entry, sizeof *devlist_entry);
  344 
  345                 cfg = &devlist_entry->cfg;
  346                 
  347                 cfg->hose               = probe->hose;
  348                 cfg->bus                = probe->bus;
  349                 cfg->slot               = probe->slot;
  350                 cfg->func               = probe->func;
  351                 cfg->vendor             = pci_cfgread(cfg, PCIR_VENDOR, 2);
  352                 cfg->device             = pci_cfgread(cfg, PCIR_DEVICE, 2);
  353                 cfg->cmdreg             = pci_cfgread(cfg, PCIR_COMMAND, 2);
  354                 cfg->statreg            = pci_cfgread(cfg, PCIR_STATUS, 2);
  355                 cfg->baseclass          = pci_cfgread(cfg, PCIR_CLASS, 1);
  356                 cfg->subclass           = pci_cfgread(cfg, PCIR_SUBCLASS, 1);
  357                 cfg->progif             = pci_cfgread(cfg, PCIR_PROGIF, 1);
  358                 cfg->revid              = pci_cfgread(cfg, PCIR_REVID, 1);
  359                 cfg->hdrtype            = pci_cfgread(cfg, PCIR_HEADERTYPE, 1);
  360                 cfg->cachelnsz          = pci_cfgread(cfg, PCIR_CACHELNSZ, 1);
  361                 cfg->lattimer           = pci_cfgread(cfg, PCIR_LATTIMER, 1);
  362                 cfg->intpin             = pci_cfgread(cfg, PCIR_INTPIN, 1);
  363                 /*
  364                  * XXX: This actually ends up trying to route the IRQ
  365                  * even though the code below assumes it returns the raw
  366                  * value.  This is why 4.x is poo.
  367                  */
  368                 cfg->intline            = pci_cfgread(cfg, PCIR_INTLINE, 1);
  369 #ifdef __alpha__
  370                 alpha_platform_assign_pciintr(cfg);
  371 #endif
  372 
  373 #ifdef APIC_IO
  374                 if (cfg->intpin != 0) {
  375                         int airq;
  376 
  377                         airq = pci_apic_irq(cfg->bus, cfg->slot, cfg->intpin, bus);
  378                         if (airq >= 0) {
  379                                 /* PCI specific entry found in MP table */
  380                                 if (airq != cfg->intline) {
  381                                         undirect_pci_irq(cfg->intline);
  382                                         cfg->intline = airq;
  383                                 }
  384                         } else {
  385                                 /* 
  386                                  * PCI interrupts might be redirected to the
  387                                  * ISA bus according to some MP tables. Use the
  388                                  * same methods as used by the ISA devices
  389                                  * devices to find the proper IOAPIC int pin.
  390                                  */
  391                                 airq = isa_apic_irq(cfg->intline);
  392                                 if ((airq >= 0) && (airq != cfg->intline)) {
  393                                         /* XXX: undirect_pci_irq() ? */
  394                                         undirect_isa_irq(cfg->intline);
  395                                         cfg->intline = airq;
  396                                 }
  397                         }
  398                 }
  399 #endif /* APIC_IO */
  400 
  401                 cfg->mingnt             = pci_cfgread(cfg, PCIR_MINGNT, 1);
  402                 cfg->maxlat             = pci_cfgread(cfg, PCIR_MAXLAT, 1);
  403 
  404                 cfg->mfdev              = (cfg->hdrtype & PCIM_MFDEV) != 0;
  405                 cfg->hdrtype            &= ~PCIM_MFDEV;
  406 
  407                 pci_fixancient(cfg);
  408                 pci_hdrtypedata(cfg);
  409 
  410                 if (REG(PCIR_STATUS, 2) & PCIM_STATUS_CAPPRESENT)
  411                         pci_read_extcap(cfg);
  412 
  413                 STAILQ_INSERT_TAIL(devlist_head, devlist_entry, pci_links);
  414 
  415                 devlist_entry->conf.pc_sel.pc_bus = cfg->bus;
  416                 devlist_entry->conf.pc_sel.pc_dev = cfg->slot;
  417                 devlist_entry->conf.pc_sel.pc_func = cfg->func;
  418                 devlist_entry->conf.pc_hdr = cfg->hdrtype;
  419 
  420                 devlist_entry->conf.pc_subvendor = cfg->subvendor;
  421                 devlist_entry->conf.pc_subdevice = cfg->subdevice;
  422                 devlist_entry->conf.pc_vendor = cfg->vendor;
  423                 devlist_entry->conf.pc_device = cfg->device;
  424 
  425                 devlist_entry->conf.pc_class = cfg->baseclass;
  426                 devlist_entry->conf.pc_subclass = cfg->subclass;
  427                 devlist_entry->conf.pc_progif = cfg->progif;
  428                 devlist_entry->conf.pc_revid = cfg->revid;
  429 
  430                 pci_numdevs++;
  431                 pci_generation++;
  432         }
  433         return (devlist_entry);
  434 #undef REG
  435 }
  436 
  437 static void
  438 pci_read_extcap(pcicfgregs *cfg)
  439 {
  440 #define REG(n, w)       pci_cfgread(cfg, n, w)
  441         int     ptr, nextptr, ptrptr;
  442 
  443         switch (cfg->hdrtype) {
  444         case 0:
  445                 ptrptr = 0x34;
  446                 break;
  447         case 2:
  448                 ptrptr = 0x14;
  449                 break;
  450         default:
  451                 return;         /* no extended capabilities support */
  452         }
  453         nextptr = REG(ptrptr, 1);       /* sanity check? */
  454 
  455         /*
  456          * Read capability entries.
  457          */
  458         while (nextptr != 0) {
  459                 /* Sanity check */
  460                 if (nextptr > 255) {
  461                         printf("illegal PCI extended capability offset %d\n",
  462                             nextptr);
  463                         return;
  464                 }
  465                 /* Find the next entry */
  466                 ptr = nextptr;
  467                 nextptr = REG(ptr + 1, 1);
  468 
  469                 /* Process this entry */
  470                 switch (REG(ptr, 1)) {
  471                 case 0x01:              /* PCI power management */
  472                         if (cfg->pp_cap == 0) {
  473                                 cfg->pp_cap = REG(ptr + PCIR_POWER_CAP, 2);
  474                                 cfg->pp_status = ptr + PCIR_POWER_STATUS;
  475                                 cfg->pp_pmcsr = ptr + PCIR_POWER_PMCSR;
  476                                 if ((nextptr - ptr) > PCIR_POWER_DATA)
  477                                         cfg->pp_data = ptr + PCIR_POWER_DATA;
  478                         }
  479                         break;
  480                 default:
  481                         break;
  482                 }
  483         }
  484 #undef REG
  485 }
  486 
  487 #if 0
  488 /* free pcicfgregs structure and all depending data structures */
  489 
  490 static int
  491 pci_freecfg(struct pci_devinfo *dinfo)
  492 {
  493         struct devlist *devlist_head;
  494 
  495         devlist_head = &pci_devq;
  496 
  497         if (dinfo->cfg.hdrspec != NULL)
  498                 free(dinfo->cfg.hdrspec, M_DEVBUF);
  499         if (dinfo->cfg.map != NULL)
  500                 free(dinfo->cfg.map, M_DEVBUF);
  501         /* XXX this hasn't been tested */
  502         STAILQ_REMOVE(devlist_head, dinfo, pci_devinfo, pci_links);
  503         free(dinfo, M_DEVBUF);
  504 
  505         /* increment the generation count */
  506         pci_generation++;
  507 
  508         /* we're losing one device */
  509         pci_numdevs--;
  510         return (0);
  511 }
  512 #endif
  513 
  514 
  515 /*
  516  * PCI power manangement
  517  */
  518 static int
  519 pci_set_powerstate_method(device_t dev, device_t child, int state)
  520 {
  521         struct pci_devinfo *dinfo = device_get_ivars(child);
  522         pcicfgregs *cfg = &dinfo->cfg;
  523         u_int16_t status;
  524         int result;
  525 
  526         if (cfg->pp_cap != 0) {
  527                 status = PCI_READ_CONFIG(dev, child, cfg->pp_status, 2) & ~PCIM_PSTAT_DMASK;
  528                 result = 0;
  529                 switch (state) {
  530                 case PCI_POWERSTATE_D0:
  531                         status |= PCIM_PSTAT_D0;
  532                         break;
  533                 case PCI_POWERSTATE_D1:
  534                         if (cfg->pp_cap & PCIM_PCAP_D1SUPP) {
  535                                 status |= PCIM_PSTAT_D1;
  536                         } else {
  537                                 result = EOPNOTSUPP;
  538                         }
  539                         break;
  540                 case PCI_POWERSTATE_D2:
  541                         if (cfg->pp_cap & PCIM_PCAP_D2SUPP) {
  542                                 status |= PCIM_PSTAT_D2;
  543                         } else {
  544                                 result = EOPNOTSUPP;
  545                         }
  546                         break;
  547                 case PCI_POWERSTATE_D3:
  548                         status |= PCIM_PSTAT_D3;
  549                         break;
  550                 default:
  551                         result = EINVAL;
  552                 }
  553                 if (result == 0)
  554                         PCI_WRITE_CONFIG(dev, child, cfg->pp_status, status, 2);
  555         } else {
  556                 result = ENXIO;
  557         }
  558         return(result);
  559 }
  560 
  561 static int
  562 pci_get_powerstate_method(device_t dev, device_t child)
  563 {
  564         struct pci_devinfo *dinfo = device_get_ivars(child);
  565         pcicfgregs *cfg = &dinfo->cfg;
  566         u_int16_t status;
  567         int result;
  568 
  569         if (cfg->pp_cap != 0) {
  570                 status = PCI_READ_CONFIG(dev, child, cfg->pp_status, 2);
  571                 switch (status & PCIM_PSTAT_DMASK) {
  572                 case PCIM_PSTAT_D0:
  573                         result = PCI_POWERSTATE_D0;
  574                         break;
  575                 case PCIM_PSTAT_D1:
  576                         result = PCI_POWERSTATE_D1;
  577                         break;
  578                 case PCIM_PSTAT_D2:
  579                         result = PCI_POWERSTATE_D2;
  580                         break;
  581                 case PCIM_PSTAT_D3:
  582                         result = PCI_POWERSTATE_D3;
  583                         break;
  584                 default:
  585                         result = PCI_POWERSTATE_UNKNOWN;
  586                         break;
  587                 }
  588         } else {
  589                 /* No support, device is always at D0 */
  590                 result = PCI_POWERSTATE_D0;
  591         }
  592         return(result);
  593 }
  594 
  595 /*
  596  * Some convenience functions for PCI device drivers.
  597  */
  598 
  599 static __inline void
  600 pci_set_command_bit(device_t dev, device_t child, u_int16_t bit)
  601 {
  602     u_int16_t   command;
  603 
  604     command = PCI_READ_CONFIG(dev, child, PCIR_COMMAND, 2);
  605     command |= bit;
  606     PCI_WRITE_CONFIG(dev, child, PCIR_COMMAND, command, 2);
  607 }
  608 
  609 static __inline void
  610 pci_clear_command_bit(device_t dev, device_t child, u_int16_t bit)
  611 {
  612     u_int16_t   command;
  613 
  614     command = PCI_READ_CONFIG(dev, child, PCIR_COMMAND, 2);
  615     command &= ~bit;
  616     PCI_WRITE_CONFIG(dev, child, PCIR_COMMAND, command, 2);
  617 }
  618 
  619 static void
  620 pci_enable_busmaster_method(device_t dev, device_t child)
  621 {
  622     pci_set_command_bit(dev, child, PCIM_CMD_BUSMASTEREN);
  623 }
  624 
  625 static void
  626 pci_disable_busmaster_method(device_t dev, device_t child)
  627 {
  628     pci_clear_command_bit(dev, child, PCIM_CMD_BUSMASTEREN);
  629 }
  630 
  631 static void
  632 pci_enable_io_method(device_t dev, device_t child, int space)
  633 {
  634     switch(space) {
  635     case SYS_RES_IOPORT:
  636         pci_set_command_bit(dev, child, PCIM_CMD_PORTEN);
  637         break;
  638     case SYS_RES_MEMORY:
  639         pci_set_command_bit(dev, child, PCIM_CMD_MEMEN);
  640         break;
  641     }
  642 }
  643 
  644 static void
  645 pci_disable_io_method(device_t dev, device_t child, int space)
  646 {
  647     switch(space) {
  648     case SYS_RES_IOPORT:
  649         pci_clear_command_bit(dev, child, PCIM_CMD_PORTEN);
  650         break;
  651     case SYS_RES_MEMORY:
  652         pci_clear_command_bit(dev, child, PCIM_CMD_MEMEN);
  653         break;
  654     }
  655 }
  656 
  657 /*
  658  * This is the user interface to PCI configuration space.
  659  */
  660   
  661 static int
  662 pci_open(dev_t dev, int oflags, int devtype, struct proc *p)
  663 {
  664         if ((oflags & FWRITE) && securelevel > 0) {
  665                 return EPERM;
  666         }
  667         return 0;
  668 }
  669 
  670 static int
  671 pci_close(dev_t dev, int flag, int devtype, struct proc *p)
  672 {
  673         return 0;
  674 }
  675 
  676 /*
  677  * Match a single pci_conf structure against an array of pci_match_conf
  678  * structures.  The first argument, 'matches', is an array of num_matches
  679  * pci_match_conf structures.  match_buf is a pointer to the pci_conf
  680  * structure that will be compared to every entry in the matches array.
  681  * This function returns 1 on failure, 0 on success.
  682  */
  683 static int
  684 pci_conf_match(struct pci_match_conf *matches, int num_matches, 
  685                struct pci_conf *match_buf)
  686 {
  687         int i;
  688 
  689         if ((matches == NULL) || (match_buf == NULL) || (num_matches <= 0))
  690                 return(1);
  691 
  692         for (i = 0; i < num_matches; i++) {
  693                 /*
  694                  * I'm not sure why someone would do this...but...
  695                  */
  696                 if (matches[i].flags == PCI_GETCONF_NO_MATCH)
  697                         continue;
  698 
  699                 /*
  700                  * Look at each of the match flags.  If it's set, do the
  701                  * comparison.  If the comparison fails, we don't have a
  702                  * match, go on to the next item if there is one.
  703                  */
  704                 if (((matches[i].flags & PCI_GETCONF_MATCH_BUS) != 0)
  705                  && (match_buf->pc_sel.pc_bus != matches[i].pc_sel.pc_bus))
  706                         continue;
  707 
  708                 if (((matches[i].flags & PCI_GETCONF_MATCH_DEV) != 0)
  709                  && (match_buf->pc_sel.pc_dev != matches[i].pc_sel.pc_dev))
  710                         continue;
  711 
  712                 if (((matches[i].flags & PCI_GETCONF_MATCH_FUNC) != 0)
  713                  && (match_buf->pc_sel.pc_func != matches[i].pc_sel.pc_func))
  714                         continue;
  715 
  716                 if (((matches[i].flags & PCI_GETCONF_MATCH_VENDOR) != 0) 
  717                  && (match_buf->pc_vendor != matches[i].pc_vendor))
  718                         continue;
  719 
  720                 if (((matches[i].flags & PCI_GETCONF_MATCH_DEVICE) != 0)
  721                  && (match_buf->pc_device != matches[i].pc_device))
  722                         continue;
  723 
  724                 if (((matches[i].flags & PCI_GETCONF_MATCH_CLASS) != 0)
  725                  && (match_buf->pc_class != matches[i].pc_class))
  726                         continue;
  727 
  728                 if (((matches[i].flags & PCI_GETCONF_MATCH_UNIT) != 0)
  729                  && (match_buf->pd_unit != matches[i].pd_unit))
  730                         continue;
  731 
  732                 if (((matches[i].flags & PCI_GETCONF_MATCH_NAME) != 0)
  733                  && (strncmp(matches[i].pd_name, match_buf->pd_name,
  734                              sizeof(match_buf->pd_name)) != 0))
  735                         continue;
  736 
  737                 return(0);
  738         }
  739 
  740         return(1);
  741 }
  742 
  743 /*
  744  * Locate the parent of a PCI device by scanning the PCI devlist
  745  * and return the entry for the parent.
  746  * For devices on PCI Bus 0 (the host bus), this is the PCI Host.
  747  * For devices on secondary PCI busses, this is that bus' PCI-PCI Bridge.
  748  */
  749 
  750 pcicfgregs *
  751 pci_devlist_get_parent(pcicfgregs *cfg)
  752 {
  753         struct devlist *devlist_head;
  754         struct pci_devinfo *dinfo;
  755         pcicfgregs *bridge_cfg;
  756         int i;
  757 
  758         dinfo = STAILQ_FIRST(devlist_head = &pci_devq);
  759 
  760         /* If the device is on PCI bus 0, look for the host */
  761         if (cfg->bus == 0) {
  762                 for (i = 0; (dinfo != NULL) && (i < pci_numdevs);
  763                 dinfo = STAILQ_NEXT(dinfo, pci_links), i++) {
  764                         bridge_cfg = &dinfo->cfg;
  765                         if (bridge_cfg->baseclass == PCIC_BRIDGE
  766                                 && bridge_cfg->subclass == PCIS_BRIDGE_HOST
  767                                 && bridge_cfg->bus == cfg->bus) {
  768                                 return bridge_cfg;
  769                         }
  770                 }
  771         }
  772 
  773         /* If the device is not on PCI bus 0, look for the PCI-PCI bridge */
  774         if (cfg->bus > 0) {
  775                 for (i = 0; (dinfo != NULL) && (i < pci_numdevs);
  776                 dinfo = STAILQ_NEXT(dinfo, pci_links), i++) {
  777                         bridge_cfg = &dinfo->cfg;
  778                         if (bridge_cfg->baseclass == PCIC_BRIDGE
  779                                 && bridge_cfg->subclass == PCIS_BRIDGE_PCI
  780                                 && bridge_cfg->secondarybus == cfg->bus) {
  781                                 return bridge_cfg;
  782                         }
  783                 }
  784         }
  785 
  786         return NULL; 
  787 }
  788 
  789 static int
  790 pci_ioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
  791 {
  792         struct pci_io *io;
  793         const char *name;
  794         int error;
  795 
  796         if (!(flag & FWRITE))
  797                 return EPERM;
  798 
  799 
  800         switch(cmd) {
  801         case PCIOCGETCONF:
  802                 {
  803                 struct pci_devinfo *dinfo;
  804                 struct pci_conf_io *cio;
  805                 struct devlist *devlist_head;
  806                 struct pci_match_conf *pattern_buf;
  807                 int num_patterns;
  808                 size_t iolen;
  809                 int ionum, i;
  810 
  811                 cio = (struct pci_conf_io *)data;
  812 
  813                 num_patterns = 0;
  814                 dinfo = NULL;
  815 
  816                 /*
  817                  * Hopefully the user won't pass in a null pointer, but it
  818                  * can't hurt to check.
  819                  */
  820                 if (cio == NULL) {
  821                         error = EINVAL;
  822                         break;
  823                 }
  824 
  825                 /*
  826                  * If the user specified an offset into the device list,
  827                  * but the list has changed since they last called this
  828                  * ioctl, tell them that the list has changed.  They will
  829                  * have to get the list from the beginning.
  830                  */
  831                 if ((cio->offset != 0)
  832                  && (cio->generation != pci_generation)){
  833                         cio->num_matches = 0;   
  834                         cio->status = PCI_GETCONF_LIST_CHANGED;
  835                         error = 0;
  836                         break;
  837                 }
  838 
  839                 /*
  840                  * Check to see whether the user has asked for an offset
  841                  * past the end of our list.
  842                  */
  843                 if (cio->offset >= pci_numdevs) {
  844                         cio->num_matches = 0;
  845                         cio->status = PCI_GETCONF_LAST_DEVICE;
  846                         error = 0;
  847                         break;
  848                 }
  849 
  850                 /* get the head of the device queue */
  851                 devlist_head = &pci_devq;
  852 
  853                 /*
  854                  * Determine how much room we have for pci_conf structures.
  855                  * Round the user's buffer size down to the nearest
  856                  * multiple of sizeof(struct pci_conf) in case the user
  857                  * didn't specify a multiple of that size.
  858                  */
  859                 iolen = min(cio->match_buf_len - 
  860                             (cio->match_buf_len % sizeof(struct pci_conf)),
  861                             pci_numdevs * sizeof(struct pci_conf));
  862 
  863                 /*
  864                  * Since we know that iolen is a multiple of the size of
  865                  * the pciconf union, it's okay to do this.
  866                  */
  867                 ionum = iolen / sizeof(struct pci_conf);
  868 
  869                 /*
  870                  * If this test is true, the user wants the pci_conf
  871                  * structures returned to match the supplied entries.
  872                  */
  873                 if ((cio->num_patterns > 0)
  874                  && (cio->pat_buf_len > 0)) {
  875                         /*
  876                          * pat_buf_len needs to be:
  877                          * num_patterns * sizeof(struct pci_match_conf)
  878                          * While it is certainly possible the user just
  879                          * allocated a large buffer, but set the number of
  880                          * matches correctly, it is far more likely that
  881                          * their kernel doesn't match the userland utility
  882                          * they're using.  It's also possible that the user
  883                          * forgot to initialize some variables.  Yes, this
  884                          * may be overly picky, but I hazard to guess that
  885                          * it's far more likely to just catch folks that
  886                          * updated their kernel but not their userland.
  887                          */
  888                         if ((cio->num_patterns *
  889                             sizeof(struct pci_match_conf)) != cio->pat_buf_len){
  890                                 /* The user made a mistake, return an error*/
  891                                 cio->status = PCI_GETCONF_ERROR;
  892                                 printf("pci_ioctl: pat_buf_len %d != "
  893                                        "num_patterns (%d) * sizeof(struct "
  894                                        "pci_match_conf) (%d)\npci_ioctl: "
  895                                        "pat_buf_len should be = %d\n",
  896                                        cio->pat_buf_len, cio->num_patterns,
  897                                        (int)sizeof(struct pci_match_conf),
  898                                        (int)sizeof(struct pci_match_conf) * 
  899                                        cio->num_patterns);
  900                                 printf("pci_ioctl: do your headers match your "
  901                                        "kernel?\n");
  902                                 cio->num_matches = 0;
  903                                 error = EINVAL;
  904                                 break;
  905                         }
  906 
  907                         /*
  908                          * Check the user's buffer to make sure it's readable.
  909                          */
  910                         if (!useracc((caddr_t)cio->patterns,
  911                                     cio->pat_buf_len, VM_PROT_READ)) {
  912                                 printf("pci_ioctl: pattern buffer %p, "
  913                                        "length %u isn't user accessible for"
  914                                        " READ\n", cio->patterns,
  915                                        cio->pat_buf_len);
  916                                 error = EACCES;
  917                                 break;
  918                         }
  919                         /*
  920                          * Allocate a buffer to hold the patterns.
  921                          */
  922                         pattern_buf = malloc(cio->pat_buf_len, M_TEMP,
  923                                              M_WAITOK);
  924                         error = copyin(cio->patterns, pattern_buf,
  925                                        cio->pat_buf_len);
  926                         if (error != 0)
  927                                 break;
  928                         num_patterns = cio->num_patterns;
  929 
  930                 } else if ((cio->num_patterns > 0)
  931                         || (cio->pat_buf_len > 0)) {
  932                         /*
  933                          * The user made a mistake, spit out an error.
  934                          */
  935                         cio->status = PCI_GETCONF_ERROR;
  936                         cio->num_matches = 0;
  937                         printf("pci_ioctl: invalid GETCONF arguments\n");
  938                         error = EINVAL;
  939                         break;
  940                 } else
  941                         pattern_buf = NULL;
  942 
  943                 /*
  944                  * Make sure we can write to the match buffer.
  945                  */
  946                 if (!useracc((caddr_t)cio->matches,
  947                              cio->match_buf_len, VM_PROT_WRITE)) {
  948                         printf("pci_ioctl: match buffer %p, length %u "
  949                                "isn't user accessible for WRITE\n",
  950                                cio->matches, cio->match_buf_len);
  951                         error = EACCES;
  952                         break;
  953                 }
  954 
  955                 /*
  956                  * Go through the list of devices and copy out the devices
  957                  * that match the user's criteria.
  958                  */
  959                 for (cio->num_matches = 0, error = 0, i = 0,
  960                      dinfo = STAILQ_FIRST(devlist_head);
  961                      (dinfo != NULL) && (cio->num_matches < ionum)
  962                      && (error == 0) && (i < pci_numdevs);
  963                      dinfo = STAILQ_NEXT(dinfo, pci_links), i++) {
  964 
  965                         if (i < cio->offset)
  966                                 continue;
  967 
  968                         /* Populate pd_name and pd_unit */
  969                         name = NULL;
  970                         if (dinfo->cfg.dev && dinfo->conf.pd_name[0] == '\0')
  971                                 name = device_get_name(dinfo->cfg.dev);
  972                         if (name) {
  973                                 strncpy(dinfo->conf.pd_name, name,
  974                                         sizeof(dinfo->conf.pd_name));
  975                                 dinfo->conf.pd_name[PCI_MAXNAMELEN] = 0;
  976                                 dinfo->conf.pd_unit =
  977                                         device_get_unit(dinfo->cfg.dev);
  978                         }
  979 
  980                         if ((pattern_buf == NULL) ||
  981                             (pci_conf_match(pattern_buf, num_patterns,
  982                                             &dinfo->conf) == 0)) {
  983 
  984                                 /*
  985                                  * If we've filled up the user's buffer,
  986                                  * break out at this point.  Since we've
  987                                  * got a match here, we'll pick right back
  988                                  * up at the matching entry.  We can also
  989                                  * tell the user that there are more matches
  990                                  * left.
  991                                  */
  992                                 if (cio->num_matches >= ionum)
  993                                         break;
  994 
  995                                 error = copyout(&dinfo->conf,
  996                                                 &cio->matches[cio->num_matches],
  997                                                 sizeof(struct pci_conf));
  998                                 cio->num_matches++;
  999                         }
 1000                 }
 1001 
 1002                 /*
 1003                  * Set the pointer into the list, so if the user is getting
 1004                  * n records at a time, where n < pci_numdevs,
 1005                  */
 1006                 cio->offset = i;
 1007 
 1008                 /*
 1009                  * Set the generation, the user will need this if they make
 1010                  * another ioctl call with offset != 0.
 1011                  */
 1012                 cio->generation = pci_generation;
 1013                 
 1014                 /*
 1015                  * If this is the last device, inform the user so he won't
 1016                  * bother asking for more devices.  If dinfo isn't NULL, we
 1017                  * know that there are more matches in the list because of
 1018                  * the way the traversal is done.
 1019                  */
 1020                 if (dinfo == NULL)
 1021                         cio->status = PCI_GETCONF_LAST_DEVICE;
 1022                 else
 1023                         cio->status = PCI_GETCONF_MORE_DEVS;
 1024 
 1025                 if (pattern_buf != NULL)
 1026                         free(pattern_buf, M_TEMP);
 1027 
 1028                 break;
 1029                 }
 1030         case PCIOCREAD:
 1031                 io = (struct pci_io *)data;
 1032                 switch(io->pi_width) {
 1033                         pcicfgregs probe;
 1034                 case 4:
 1035                 case 2:
 1036                 case 1:
 1037                         probe.hose = -1;
 1038                         probe.bus = io->pi_sel.pc_bus;
 1039                         probe.slot = io->pi_sel.pc_dev;
 1040                         probe.func = io->pi_sel.pc_func;
 1041                         io->pi_data = pci_cfgread(&probe, 
 1042                                                   io->pi_reg, io->pi_width);
 1043                         error = 0;
 1044                         break;
 1045                 default:
 1046                         error = ENODEV;
 1047                         break;
 1048                 }
 1049                 break;
 1050 
 1051         case PCIOCWRITE:
 1052                 io = (struct pci_io *)data;
 1053                 switch(io->pi_width) {
 1054                         pcicfgregs probe;
 1055                 case 4:
 1056                 case 2:
 1057                 case 1:
 1058                         probe.hose = -1; 
 1059                         probe.bus = io->pi_sel.pc_bus;
 1060                         probe.slot = io->pi_sel.pc_dev;
 1061                         probe.func = io->pi_sel.pc_func;
 1062                         pci_cfgwrite(&probe, 
 1063                                     io->pi_reg, io->pi_data, io->pi_width);
 1064                         error = 0;
 1065                         break;
 1066                 default:
 1067                         error = ENODEV;
 1068                         break;
 1069                 }
 1070                 break;
 1071 
 1072         default:
 1073                 error = ENOTTY;
 1074                 break;
 1075         }
 1076 
 1077         return (error);
 1078 }
 1079 
 1080 #define PCI_CDEV        78
 1081 
 1082 static struct cdevsw pcicdev = {
 1083         /* open */      pci_open,
 1084         /* close */     pci_close,
 1085         /* read */      noread,
 1086         /* write */     nowrite,
 1087         /* ioctl */     pci_ioctl,
 1088         /* poll */      nopoll,
 1089         /* mmap */      nommap,
 1090         /* strategy */  nostrategy,
 1091         /* name */      "pci",
 1092         /* maj */       PCI_CDEV,
 1093         /* dump */      nodump,
 1094         /* psize */     nopsize,
 1095         /* flags */     0,
 1096         /* bmaj */      -1
 1097 };
 1098 
 1099 #include "pci_if.h"
 1100 
 1101 /*
 1102  * A simple driver to wrap the old pci driver mechanism for back-compat.
 1103  */
 1104 
 1105 static int
 1106 pci_compat_probe(device_t dev)
 1107 {
 1108         struct pci_device *dvp;
 1109         struct pci_devinfo *dinfo;
 1110         pcicfgregs *cfg;
 1111         const char *name;
 1112         int error;
 1113         
 1114         dinfo = device_get_ivars(dev);
 1115         cfg = &dinfo->cfg;
 1116         dvp = device_get_driver(dev)->priv;
 1117 
 1118         /*
 1119          * Do the wrapped probe.
 1120          */
 1121         error = ENXIO;
 1122         if (dvp && dvp->pd_probe) {
 1123                 name = dvp->pd_probe(cfg, (cfg->device << 16) + cfg->vendor);
 1124                 if (name) {
 1125                         device_set_desc_copy(dev, name);
 1126                         /* Allow newbus drivers to match "better" */
 1127                         error = -200;
 1128                 }
 1129         }
 1130 
 1131         return error;
 1132 }
 1133 
 1134 static int
 1135 pci_compat_attach(device_t dev)
 1136 {
 1137         struct pci_device *dvp;
 1138         struct pci_devinfo *dinfo;
 1139         pcicfgregs *cfg;
 1140         int unit;
 1141 
 1142         dinfo = device_get_ivars(dev);
 1143         cfg = &dinfo->cfg;
 1144         dvp = device_get_driver(dev)->priv;
 1145 
 1146         unit = device_get_unit(dev);
 1147         if (unit > *dvp->pd_count)
 1148                 *dvp->pd_count = unit;
 1149         if (dvp->pd_attach)
 1150                 dvp->pd_attach(cfg, unit);
 1151         device_printf(dev, "driver is using old-style compatibility shims\n");
 1152         return 0;
 1153 }
 1154 
 1155 static device_method_t pci_compat_methods[] = {
 1156         /* Device interface */
 1157         DEVMETHOD(device_probe,         pci_compat_probe),
 1158         DEVMETHOD(device_attach,        pci_compat_attach),
 1159 
 1160         { 0, 0 }
 1161 };
 1162 
 1163 static devclass_t       pci_devclass;
 1164 
 1165 /*
 1166  * Create a new style driver around each old pci driver.
 1167  */
 1168 int
 1169 compat_pci_handler(module_t mod, int type, void *data)
 1170 {
 1171         struct pci_device *dvp = (struct pci_device *)data;
 1172         driver_t *driver;
 1173 
 1174         switch (type) {
 1175         case MOD_LOAD:
 1176                 driver = malloc(sizeof(driver_t), M_DEVBUF, M_NOWAIT);
 1177                 if (!driver)
 1178                         return ENOMEM;
 1179                 bzero(driver, sizeof(driver_t));
 1180                 driver->name = dvp->pd_name;
 1181                 driver->methods = pci_compat_methods;
 1182                 driver->softc = sizeof(struct pci_devinfo *);
 1183                 driver->priv = dvp;
 1184                 devclass_add_driver(pci_devclass, driver);
 1185                 break;
 1186         case MOD_UNLOAD:
 1187                 printf("%s: module unload not supported!\n", dvp->pd_name);
 1188                 return EOPNOTSUPP;
 1189         default:
 1190                 break;
 1191         }
 1192         return 0;
 1193 }
 1194 
 1195 /*
 1196  * New style pci driver.  Parent device is either a pci-host-bridge or a
 1197  * pci-pci-bridge.  Both kinds are represented by instances of pcib.
 1198  */
 1199 
 1200 static void
 1201 pci_print_verbose(struct pci_devinfo *dinfo)
 1202 {
 1203         if (bootverbose) {
 1204                 pcicfgregs *cfg = &dinfo->cfg;
 1205 
 1206                 printf("found->\tvendor=0x%04x, dev=0x%04x, revid=0x%02x\n", 
 1207                        cfg->vendor, cfg->device, cfg->revid);
 1208                 printf("\tclass=%02x-%02x-%02x, hdrtype=0x%02x, mfdev=%d\n",
 1209                        cfg->baseclass, cfg->subclass, cfg->progif,
 1210                        cfg->hdrtype, cfg->mfdev);
 1211                 printf("\tsubordinatebus=%x \tsecondarybus=%x\n",
 1212                        cfg->subordinatebus, cfg->secondarybus);
 1213 #ifdef PCI_DEBUG
 1214                 printf("\tcmdreg=0x%04x, statreg=0x%04x, cachelnsz=%d (dwords)\n", 
 1215                        cfg->cmdreg, cfg->statreg, cfg->cachelnsz);
 1216                 printf("\tlattimer=0x%02x (%d ns), mingnt=0x%02x (%d ns), maxlat=0x%02x (%d ns)\n",
 1217                        cfg->lattimer, cfg->lattimer * 30, 
 1218                        cfg->mingnt, cfg->mingnt * 250, cfg->maxlat, cfg->maxlat * 250);
 1219 #endif /* PCI_DEBUG */
 1220                 if (cfg->intpin > 0)
 1221                         printf("\tintpin=%c, irq=%d\n", cfg->intpin +'a' -1, cfg->intline);
 1222         }
 1223 }
 1224 
 1225 static int
 1226 pci_porten(pcicfgregs *cfg)
 1227 {
 1228         return ((cfg->cmdreg & PCIM_CMD_PORTEN) != 0);
 1229 }
 1230 
 1231 static int
 1232 pci_memen(pcicfgregs *cfg)
 1233 {
 1234         return ((cfg->cmdreg & PCIM_CMD_MEMEN) != 0);
 1235 }
 1236 
 1237 /*
 1238  * Add a resource based on a pci map register. Return 1 if the map
 1239  * register is a 32bit map register or 2 if it is a 64bit register.
 1240  */
 1241 static int
 1242 pci_add_map(device_t dev, pcicfgregs* cfg, int reg)
 1243 {
 1244         struct pci_devinfo *dinfo = device_get_ivars(dev);
 1245         struct resource_list *rl = &dinfo->resources;
 1246         u_int32_t map;
 1247         u_int64_t base;
 1248         u_int8_t ln2size;
 1249         u_int8_t ln2range;
 1250         u_int32_t testval;
 1251                 
 1252         int type;
 1253 
 1254         map = pci_cfgread(cfg, reg, 4);
 1255 
 1256         if (map == 0 || map == 0xffffffff)
 1257                 return 1; /* skip invalid entry */
 1258 
 1259         pci_cfgwrite(cfg, reg, 0xffffffff, 4);
 1260         testval = pci_cfgread(cfg, reg, 4);
 1261         pci_cfgwrite(cfg, reg, map, 4);
 1262 
 1263         base = pci_mapbase(map);
 1264         if (pci_maptype(map) & PCI_MAPMEM)
 1265                 type = SYS_RES_MEMORY;
 1266         else
 1267                 type = SYS_RES_IOPORT;
 1268         ln2size = pci_mapsize(testval);
 1269         ln2range = pci_maprange(testval);
 1270         if (ln2range == 64) {
 1271                 /* Read the other half of a 64bit map register */
 1272                 base |= (u_int64_t) pci_cfgread(cfg, reg + 4, 4) << 32;
 1273         }
 1274 
 1275 #ifdef __alpha__
 1276         /* 
 1277          *  XXX: encode hose number in the base addr,
 1278          *  This will go away once the bus_space functions
 1279          *  can deal with multiple hoses 
 1280          */
 1281 
 1282         if (cfg->hose) {
 1283                 u_int32_t mask, shift, maxh;
 1284 
 1285                 switch (hwrpb->rpb_type) {
 1286                 case ST_DEC_4100:
 1287                 case -ST_DEC_4100:
 1288                         mask = 0xc0000000;
 1289                         shift = 30;
 1290                         maxh = 4;       /* not a hose. MCPCIA instance # */
 1291                         break;
 1292                 case ST_DEC_21000:
 1293                         mask = 0xf8000000;
 1294                         shift = 27;
 1295                         maxh = 32;
 1296                         break;
 1297                 case ST_DEC_6600:
 1298                         mask = 0x80000000;
 1299                         shift = 31;
 1300                         maxh = 2;
 1301                         break;
 1302                 default:
 1303                         mask = 0;
 1304                         shift = 0;
 1305                         maxh = 0;
 1306                         break;
 1307                 }
 1308                 if (base & mask) {
 1309                         printf("base   addr = 0x%llx\n", (long long) base);
 1310                         printf("mask   addr = 0x%lx\n", (long) mask);
 1311                         printf("hacked addr = 0x%llx\n", (long long)
 1312                                (base | ((u_int64_t)cfg->hose << shift)));
 1313                         panic("hose encoding hack would clobber base addr");
 1314                         /* NOTREACHED */
 1315                 }
 1316                 if (cfg->hose >= maxh) {
 1317                         panic("Hose %d - can only encode %d hose(s)",
 1318                             cfg->hose, maxh);
 1319                         /* NOTREACHED */
 1320                 }
 1321                 base |= ((u_int64_t)cfg->hose << shift);
 1322         }
 1323 #endif
 1324 
 1325         /*
 1326          * This code theoretically does the right thing, but has
 1327          * undesirable side effects in some cases where
 1328          * peripherals respond oddly to having these bits
 1329          * enabled.  Leave them alone by default.
 1330          */
 1331 #ifdef PCI_ENABLE_IO_MODES
 1332         if (type == SYS_RES_IOPORT && !pci_porten(cfg)) {
 1333                 cfg->cmdreg |= PCIM_CMD_PORTEN;
 1334                 pci_cfgwrite(cfg, PCIR_COMMAND, cfg->cmdreg, 2);
 1335         }
 1336         if (type == SYS_RES_MEMORY && !pci_memen(cfg)) {
 1337                 cfg->cmdreg |= PCIM_CMD_MEMEN;
 1338                 pci_cfgwrite(cfg, PCIR_COMMAND, cfg->cmdreg, 2);
 1339         }
 1340 #else
 1341         if (type == SYS_RES_IOPORT && !pci_porten(cfg))
 1342                 return 1;
 1343         if (type == SYS_RES_MEMORY && !pci_memen(cfg))
 1344                 return 1;
 1345 #endif
 1346 
 1347         resource_list_add(rl, type, reg,
 1348                           base, base + (1 << ln2size) - 1,
 1349                           (1 << ln2size));
 1350 
 1351         if (bootverbose) {
 1352                 printf("\tmap[%02x]: type %x, range %2d, base %08x, size %2d\n",
 1353                        reg, pci_maptype(base), ln2range,
 1354                        (unsigned int) base, ln2size);
 1355         }
 1356 
 1357         return (ln2range == 64) ? 2 : 1;
 1358 }
 1359 
 1360 static void
 1361 pci_add_resources(device_t dev, pcicfgregs* cfg)
 1362 {
 1363         struct pci_devinfo *dinfo = device_get_ivars(dev);
 1364         struct resource_list *rl = &dinfo->resources;
 1365         struct pci_quirk *q;
 1366         int i;
 1367 
 1368         for (i = 0; i < cfg->nummaps;) {
 1369                 i += pci_add_map(dev, cfg, PCIR_MAPS + i*4);
 1370         }
 1371 
 1372         for (q = &pci_quirks[0]; q->devid; q++) {
 1373                 if (q->devid == ((cfg->device << 16) | cfg->vendor)
 1374                     && q->type == PCI_QUIRK_MAP_REG)
 1375                         pci_add_map(dev, cfg, q->arg1);
 1376         }
 1377 
 1378         if (cfg->intpin > 0 && cfg->intline != 255)
 1379                 resource_list_add(rl, SYS_RES_IRQ, 0,
 1380                                   cfg->intline, cfg->intline, 1);
 1381 }
 1382 
 1383 static void
 1384 pci_add_children(device_t dev, int busno)
 1385 {
 1386         pcicfgregs probe;
 1387 
 1388 #ifdef SIMOS
 1389 #undef PCI_SLOTMAX
 1390 #define PCI_SLOTMAX 0
 1391 #endif
 1392 
 1393         bzero(&probe, sizeof probe);
 1394 #ifdef __alpha__
 1395         probe.hose = pcib_get_hose(dev);
 1396 #endif
 1397 #ifdef __i386__
 1398         probe.hose = 0;
 1399 #endif
 1400         probe.bus = busno;
 1401 
 1402         for (probe.slot = 0; probe.slot <= PCI_SLOTMAX; probe.slot++) {
 1403                 int pcifunchigh = 0;
 1404                 for (probe.func = 0; probe.func <= pcifunchigh; probe.func++) {
 1405                         struct pci_devinfo *dinfo = pci_readcfg(&probe, dev);
 1406                         if (dinfo != NULL) {
 1407                                 if (dinfo->cfg.mfdev)
 1408                                         pcifunchigh = 7;
 1409 
 1410                                 pci_print_verbose(dinfo);
 1411                                 dinfo->cfg.dev = device_add_child(dev, NULL, -1);
 1412                                 device_set_ivars(dinfo->cfg.dev, dinfo);
 1413                                 pci_add_resources(dinfo->cfg.dev, &dinfo->cfg);
 1414                         }
 1415                 }
 1416         }
 1417 }
 1418 
 1419 static int
 1420 pci_new_probe(device_t dev)
 1421 {
 1422         static int once;
 1423 
 1424         device_set_desc(dev, "PCI bus");
 1425         pci_add_children(dev, device_get_unit(dev));
 1426         if (!once) {
 1427                 make_dev(&pcicdev, 0, UID_ROOT, GID_WHEEL, 0644, "pci");
 1428                 once++;
 1429         }
 1430 
 1431         return 0;
 1432 }
 1433 
 1434 static int
 1435 pci_print_resources(struct resource_list *rl, const char *name, int type,
 1436                     const char *format)
 1437 {
 1438         struct resource_list_entry *rle;
 1439         int printed, retval;
 1440 
 1441         printed = 0;
 1442         retval = 0;
 1443         /* Yes, this is kinda cheating */
 1444         SLIST_FOREACH(rle, rl, link) {
 1445                 if (rle->type == type) {
 1446                         if (printed == 0)
 1447                                 retval += printf(" %s ", name);
 1448                         else if (printed > 0)
 1449                                 retval += printf(",");
 1450                         printed++;
 1451                         retval += printf(format, rle->start);
 1452                         if (rle->count > 1) {
 1453                                 retval += printf("-");
 1454                                 retval += printf(format, rle->start +
 1455                                                  rle->count - 1);
 1456                         }
 1457                 }
 1458         }
 1459         return retval;
 1460 }
 1461 
 1462 static int
 1463 pci_print_child(device_t dev, device_t child)
 1464 {
 1465         struct pci_devinfo *dinfo;
 1466         struct resource_list *rl;
 1467         pcicfgregs *cfg;
 1468         int retval = 0;
 1469 
 1470         dinfo = device_get_ivars(child);
 1471         cfg = &dinfo->cfg;
 1472         rl = &dinfo->resources;
 1473 
 1474         retval += bus_print_child_header(dev, child);
 1475 
 1476         retval += pci_print_resources(rl, "port", SYS_RES_IOPORT, "%#lx");
 1477         retval += pci_print_resources(rl, "mem", SYS_RES_MEMORY, "%#lx");
 1478         retval += pci_print_resources(rl, "irq", SYS_RES_IRQ, "%ld");
 1479         if (device_get_flags(dev))
 1480                 retval += printf(" flags %#x", device_get_flags(dev));
 1481 
 1482         retval += printf(" at device %d.%d", pci_get_slot(child),
 1483                          pci_get_function(child));
 1484 
 1485         retval += bus_print_child_footer(dev, child);
 1486 
 1487         return (retval);
 1488 }
 1489 
 1490 static void
 1491 pci_probe_nomatch(device_t dev, device_t child)
 1492 {
 1493         struct pci_devinfo *dinfo;
 1494         pcicfgregs *cfg;
 1495         const char *desc;
 1496         int unknown;
 1497 
 1498         unknown = 0;
 1499         dinfo = device_get_ivars(child);
 1500         cfg = &dinfo->cfg;
 1501         desc = pci_ata_match(child);
 1502         if (!desc) desc = pci_usb_match(child);
 1503         if (!desc) desc = pci_vga_match(child);
 1504         if (!desc) {
 1505                 desc = "unknown card";
 1506                 unknown++;
 1507         }
 1508         device_printf(dev, "<%s>", desc);
 1509         if (bootverbose || unknown) {
 1510                 printf(" (vendor=0x%04x, dev=0x%04x)",
 1511                         cfg->vendor,
 1512                         cfg->device);
 1513         }
 1514         printf(" at %d.%d",
 1515                 pci_get_slot(child),
 1516                 pci_get_function(child));
 1517         if (cfg->intpin > 0 && cfg->intline != 255) {
 1518                 printf(" irq %d", cfg->intline);
 1519         }
 1520         printf("\n");
 1521                                       
 1522         return;
 1523 }
 1524 
 1525 static int
 1526 pci_read_ivar(device_t dev, device_t child, int which, u_long *result)
 1527 {
 1528         struct pci_devinfo *dinfo;
 1529         pcicfgregs *cfg;
 1530 
 1531         dinfo = device_get_ivars(child);
 1532         cfg = &dinfo->cfg;
 1533 
 1534         switch (which) {
 1535         case PCI_IVAR_SUBVENDOR:
 1536                 *result = cfg->subvendor;
 1537                 break;
 1538         case PCI_IVAR_SUBDEVICE:
 1539                 *result = cfg->subdevice;
 1540                 break;
 1541         case PCI_IVAR_VENDOR:
 1542                 *result = cfg->vendor;
 1543                 break;
 1544         case PCI_IVAR_DEVICE:
 1545                 *result = cfg->device;
 1546                 break;
 1547         case PCI_IVAR_DEVID:
 1548                 *result = (cfg->device << 16) | cfg->vendor;
 1549                 break;
 1550         case PCI_IVAR_CLASS:
 1551                 *result = cfg->baseclass;
 1552                 break;
 1553         case PCI_IVAR_SUBCLASS:
 1554                 *result = cfg->subclass;
 1555                 break;
 1556         case PCI_IVAR_PROGIF:
 1557                 *result = cfg->progif;
 1558                 break;
 1559         case PCI_IVAR_REVID:
 1560                 *result = cfg->revid;
 1561                 break;
 1562         case PCI_IVAR_INTPIN:
 1563                 *result = cfg->intpin;
 1564                 break;
 1565         case PCI_IVAR_IRQ:
 1566                 *result = cfg->intline;
 1567                 break;
 1568         case PCI_IVAR_BUS:
 1569                 *result = cfg->bus;
 1570                 break;
 1571         case PCI_IVAR_SLOT:
 1572                 *result = cfg->slot;
 1573                 break;
 1574         case PCI_IVAR_FUNCTION:
 1575                 *result = cfg->func;
 1576                 break;
 1577         case PCI_IVAR_SECONDARYBUS:
 1578                 *result = cfg->secondarybus;
 1579                 break;
 1580         case PCI_IVAR_SUBORDINATEBUS:
 1581                 *result = cfg->subordinatebus;
 1582                 break;
 1583         case PCI_IVAR_HOSE:
 1584                 /*
 1585                  * Pass up to parent bridge.
 1586                  */
 1587                 *result = pcib_get_hose(dev);
 1588                 break;
 1589         default:
 1590                 return ENOENT;
 1591         }
 1592         return 0;
 1593 }
 1594 
 1595 static int
 1596 pci_write_ivar(device_t dev, device_t child, int which, uintptr_t value)
 1597 {
 1598         struct pci_devinfo *dinfo;
 1599         pcicfgregs *cfg;
 1600 
 1601         dinfo = device_get_ivars(child);
 1602         cfg = &dinfo->cfg;
 1603 
 1604         switch (which) {
 1605         case PCI_IVAR_SUBVENDOR:
 1606         case PCI_IVAR_SUBDEVICE:
 1607         case PCI_IVAR_VENDOR:
 1608         case PCI_IVAR_DEVICE:
 1609         case PCI_IVAR_DEVID:
 1610         case PCI_IVAR_CLASS:
 1611         case PCI_IVAR_SUBCLASS:
 1612         case PCI_IVAR_PROGIF:
 1613         case PCI_IVAR_REVID:
 1614         case PCI_IVAR_INTPIN:
 1615         case PCI_IVAR_IRQ:
 1616         case PCI_IVAR_BUS:
 1617         case PCI_IVAR_SLOT:
 1618         case PCI_IVAR_FUNCTION:
 1619                 return EINVAL;  /* disallow for now */
 1620 
 1621         case PCI_IVAR_SECONDARYBUS:
 1622                 cfg->secondarybus = value;
 1623                 break;
 1624         case PCI_IVAR_SUBORDINATEBUS:
 1625                 cfg->subordinatebus = value;
 1626                 break;
 1627         default:
 1628                 return ENOENT;
 1629         }
 1630         return 0;
 1631 }
 1632 
 1633 static struct resource *
 1634 pci_alloc_resource(device_t dev, device_t child, int type, int *rid,
 1635                    u_long start, u_long end, u_long count, u_int flags)
 1636 {
 1637         struct pci_devinfo *dinfo = device_get_ivars(child);
 1638         struct resource_list *rl = &dinfo->resources;
 1639 
 1640 #ifdef __i386__         /* Only supported on x86 in stable */
 1641         pcicfgregs *cfg = &dinfo->cfg;
 1642         /*
 1643          * Perform lazy resource allocation
 1644          *
 1645          * XXX add support here for SYS_RES_IOPORT and SYS_RES_MEMORY
 1646          */
 1647         if (device_get_parent(child) == dev) {
 1648                 /*
 1649                  * If device doesn't have an interrupt routed, and is
 1650                  * deserving of an interrupt, try to assign it one.
 1651                  */
 1652                 if ((type == SYS_RES_IRQ) &&
 1653                     (cfg->intline == 255 || cfg->intline == 0) &&
 1654                     (cfg->intpin != 0) && (start == 0) && (end == ~0UL)) {
 1655                         cfg->intline = pci_cfgintr(pci_get_bus(child),
 1656                             pci_get_slot(child), cfg->intpin);
 1657                         if (cfg->intline != 255) {
 1658                                 pci_write_config(child, PCIR_INTLINE,
 1659                                     cfg->intline, 1);
 1660                                 resource_list_add(rl, SYS_RES_IRQ, 0,
 1661                                     cfg->intline, cfg->intline, 1);
 1662                         }
 1663                 }
 1664         }
 1665 #endif
 1666         return resource_list_alloc(rl, dev, child, type, rid,
 1667                                    start, end, count, flags);
 1668 }
 1669 
 1670 static int
 1671 pci_release_resource(device_t dev, device_t child, int type, int rid,
 1672                      struct resource *r)
 1673 {
 1674         struct pci_devinfo *dinfo = device_get_ivars(child);
 1675         struct resource_list *rl = &dinfo->resources;
 1676 
 1677         return resource_list_release(rl, dev, child, type, rid, r);
 1678 }
 1679 
 1680 static int
 1681 pci_set_resource(device_t dev, device_t child, int type, int rid,
 1682                  u_long start, u_long count)
 1683 {
 1684         struct pci_devinfo *dinfo = device_get_ivars(child);
 1685         struct resource_list *rl = &dinfo->resources;
 1686 
 1687         resource_list_add(rl, type, rid, start, start + count - 1, count);
 1688         return 0;
 1689 }
 1690 
 1691 static int
 1692 pci_get_resource(device_t dev, device_t child, int type, int rid,
 1693                  u_long *startp, u_long *countp)
 1694 {
 1695         struct pci_devinfo *dinfo = device_get_ivars(child);
 1696         struct resource_list *rl = &dinfo->resources;
 1697         struct resource_list_entry *rle;
 1698 
 1699         rle = resource_list_find(rl, type, rid);
 1700         if (!rle)
 1701                 return ENOENT;
 1702         
 1703         if (startp)
 1704                 *startp = rle->start;
 1705         if (countp)
 1706                 *countp = rle->count;
 1707 
 1708         return 0;
 1709 }
 1710 
 1711 static void
 1712 pci_delete_resource(device_t dev, device_t child, int type, int rid)
 1713 {
 1714         printf("pci_delete_resource: PCI resources can not be deleted\n");
 1715 }
 1716 
 1717 static u_int32_t
 1718 pci_read_config_method(device_t dev, device_t child, int reg, int width)
 1719 {
 1720         struct pci_devinfo *dinfo = device_get_ivars(child);
 1721         pcicfgregs *cfg = &dinfo->cfg;
 1722         return pci_cfgread(cfg, reg, width);
 1723 }
 1724 
 1725 static void
 1726 pci_write_config_method(device_t dev, device_t child, int reg,
 1727                         u_int32_t val, int width)
 1728 {
 1729         struct pci_devinfo *dinfo = device_get_ivars(child);
 1730         pcicfgregs *cfg = &dinfo->cfg;
 1731         pci_cfgwrite(cfg, reg, val, width);
 1732 }
 1733 
 1734 static int
 1735 pci_modevent(module_t mod, int what, void *arg)
 1736 {
 1737         switch (what) {
 1738         case MOD_LOAD:
 1739                 STAILQ_INIT(&pci_devq);
 1740                 break;
 1741 
 1742         case MOD_UNLOAD:
 1743                 break;
 1744         }
 1745 
 1746         return 0;
 1747 }
 1748 
 1749 static device_method_t pci_methods[] = {
 1750         /* Device interface */
 1751         DEVMETHOD(device_probe,         pci_new_probe),
 1752         DEVMETHOD(device_attach,        bus_generic_attach),
 1753         DEVMETHOD(device_shutdown,      bus_generic_shutdown),
 1754         DEVMETHOD(device_suspend,       bus_generic_suspend),
 1755         DEVMETHOD(device_resume,        bus_generic_resume),
 1756 
 1757         /* Bus interface */
 1758         DEVMETHOD(bus_print_child,      pci_print_child),
 1759         DEVMETHOD(bus_probe_nomatch,    pci_probe_nomatch),
 1760         DEVMETHOD(bus_read_ivar,        pci_read_ivar),
 1761         DEVMETHOD(bus_write_ivar,       pci_write_ivar),
 1762         DEVMETHOD(bus_driver_added,     bus_generic_driver_added),
 1763         DEVMETHOD(bus_alloc_resource,   pci_alloc_resource),
 1764         DEVMETHOD(bus_release_resource, pci_release_resource),
 1765         DEVMETHOD(bus_activate_resource, bus_generic_activate_resource),
 1766         DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource),
 1767         DEVMETHOD(bus_setup_intr,       bus_generic_setup_intr),
 1768         DEVMETHOD(bus_teardown_intr,    bus_generic_teardown_intr),
 1769         DEVMETHOD(bus_set_resource,     pci_set_resource),
 1770         DEVMETHOD(bus_get_resource,     pci_get_resource),
 1771         DEVMETHOD(bus_delete_resource,  pci_delete_resource),
 1772 
 1773         /* PCI interface */
 1774         DEVMETHOD(pci_read_config,      pci_read_config_method),
 1775         DEVMETHOD(pci_write_config,     pci_write_config_method),
 1776         DEVMETHOD(pci_enable_busmaster, pci_enable_busmaster_method),
 1777         DEVMETHOD(pci_disable_busmaster, pci_disable_busmaster_method),
 1778         DEVMETHOD(pci_enable_io,        pci_enable_io_method),
 1779         DEVMETHOD(pci_disable_io,       pci_disable_io_method),
 1780         DEVMETHOD(pci_get_powerstate,   pci_get_powerstate_method),
 1781         DEVMETHOD(pci_set_powerstate,   pci_set_powerstate_method),
 1782 
 1783         { 0, 0 }
 1784 };
 1785 
 1786 static driver_t pci_driver = {
 1787         "pci",
 1788         pci_methods,
 1789         1,                      /* no softc */
 1790 };
 1791 
 1792 DRIVER_MODULE(pci, pcib, pci_driver, pci_devclass, pci_modevent, 0);

Cache object: 71cc2c1b82960bf62464b4f2e3e20dae


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