Author: jhb
Date: Fri Jun 24 21:39:38 2011
New Revision: 223520
URL: http://svn.freebsd.org/changeset/base/223520

Log:
  Split out host_pcib_get_busno() from the generic PCI-PCI bridge driver to
  start a new file that will hold utility APIs used by various Host-PCI
  bridge drivers and drivers that provide PCI domains.

Added:
  head/sys/dev/pci/pci_subr.c
     - copied, changed from r223482, head/sys/dev/pci/pci_pci.c
Modified:
  head/sys/conf/files
  head/sys/dev/pci/pci_pci.c

Modified: head/sys/conf/files
==============================================================================
--- head/sys/conf/files Fri Jun 24 21:32:03 2011        (r223519)
+++ head/sys/conf/files Fri Jun 24 21:39:38 2011        (r223520)
@@ -1552,6 +1552,7 @@ dev/pci/isa_pci.c         optional pci isa
 dev/pci/pci.c                  optional pci
 dev/pci/pci_if.m               standard
 dev/pci/pci_pci.c              optional pci
+dev/pci/pci_subr.c             optional pci
 dev/pci/pci_user.c             optional pci
 dev/pci/pcib_if.m              standard
 dev/pci/vga_pci.c              optional pci

Modified: head/sys/dev/pci/pci_pci.c
==============================================================================
--- head/sys/dev/pci/pci_pci.c  Fri Jun 24 21:32:03 2011        (r223519)
+++ head/sys/dev/pci/pci_pci.c  Fri Jun 24 21:39:38 2011        (r223520)
@@ -38,16 +38,12 @@ __FBSDID("$FreeBSD$");
 #include <sys/param.h>
 #include <sys/bus.h>
 #include <sys/kernel.h>
-#include <sys/libkern.h>
 #include <sys/malloc.h>
 #include <sys/module.h>
 #include <sys/rman.h>
 #include <sys/sysctl.h>
 #include <sys/systm.h>
 
-#include <machine/bus.h>
-#include <machine/resource.h>
-
 #include <dev/pci/pcivar.h>
 #include <dev/pci/pcireg.h>
 #include <dev/pci/pci_private.h>
@@ -1432,91 +1428,3 @@ pcib_power_for_sleep(device_t pcib, devi
        bus = device_get_parent(pcib);
        return (PCIB_POWER_FOR_SLEEP(bus, dev, pstate));
 }
-
-/*
- * Try to read the bus number of a host-PCI bridge using appropriate config
- * registers.
- */
-int
-host_pcib_get_busno(pci_read_config_fn read_config, int bus, int slot, int 
func,
-    uint8_t *busnum)
-{
-       uint32_t id;
-
-       id = read_config(bus, slot, func, PCIR_DEVVENDOR, 4);
-       if (id == 0xffffffff)
-               return (0);
-
-       switch (id) {
-       case 0x12258086:
-               /* Intel 824?? */
-               /* XXX This is a guess */
-               /* *busnum = read_config(bus, slot, func, 0x41, 1); */
-               *busnum = bus;
-               break;
-       case 0x84c48086:
-               /* Intel 82454KX/GX (Orion) */
-               *busnum = read_config(bus, slot, func, 0x4a, 1);
-               break;
-       case 0x84ca8086:
-               /*
-                * For the 450nx chipset, there is a whole bundle of
-                * things pretending to be host bridges. The MIOC will 
-                * be seen first and isn't really a pci bridge (the
-                * actual busses are attached to the PXB's). We need to 
-                * read the registers of the MIOC to figure out the
-                * bus numbers for the PXB channels.
-                *
-                * Since the MIOC doesn't have a pci bus attached, we
-                * pretend it wasn't there.
-                */
-               return (0);
-       case 0x84cb8086:
-               switch (slot) {
-               case 0x12:
-                       /* Intel 82454NX PXB#0, Bus#A */
-                       *busnum = read_config(bus, 0x10, func, 0xd0, 1);
-                       break;
-               case 0x13:
-                       /* Intel 82454NX PXB#0, Bus#B */
-                       *busnum = read_config(bus, 0x10, func, 0xd1, 1) + 1;
-                       break;
-               case 0x14:
-                       /* Intel 82454NX PXB#1, Bus#A */
-                       *busnum = read_config(bus, 0x10, func, 0xd3, 1);
-                       break;
-               case 0x15:
-                       /* Intel 82454NX PXB#1, Bus#B */
-                       *busnum = read_config(bus, 0x10, func, 0xd4, 1) + 1;
-                       break;
-               }
-               break;
-
-               /* ServerWorks -- vendor 0x1166 */
-       case 0x00051166:
-       case 0x00061166:
-       case 0x00081166:
-       case 0x00091166:
-       case 0x00101166:
-       case 0x00111166:
-       case 0x00171166:
-       case 0x01011166:
-       case 0x010f1014:
-       case 0x01101166:
-       case 0x02011166:
-       case 0x02251166:
-       case 0x03021014:
-               *busnum = read_config(bus, slot, func, 0x44, 1);
-               break;
-
-               /* Compaq/HP -- vendor 0x0e11 */
-       case 0x60100e11:
-               *busnum = read_config(bus, slot, func, 0xc8, 1);
-               break;
-       default:
-               /* Don't know how to read bus number. */
-               return 0;
-       }
-
-       return 1;
-}

Copied and modified: head/sys/dev/pci/pci_subr.c (from r223482, 
head/sys/dev/pci/pci_pci.c)
==============================================================================
--- head/sys/dev/pci/pci_pci.c  Thu Jun 23 17:42:27 2011        (r223482, copy 
source)
+++ head/sys/dev/pci/pci_subr.c Fri Jun 24 21:39:38 2011        (r223520)
@@ -1,7 +1,6 @@
 /*-
- * Copyright (c) 1994,1995 Stefan Esser, Wolfgang StanglMeier
- * Copyright (c) 2000 Michael Smith <msm...@freebsd.org>
- * Copyright (c) 2000 BSDi
+ * Copyright (c) 2011 Advanced Computing Technologies LLC
+ * Written by: John H. Baldwin <j...@freebsd.org>
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -12,8 +11,6 @@
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote products
- *    derived from this software without specific prior written permission.
  *
  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
@@ -32,1407 +29,18 @@
 __FBSDID("$FreeBSD$");
 
 /*
- * PCI:PCI bridge support.
+ * Support APIs for Host to PCI bridge drivers and drivers that
+ * provide PCI domains.
  */
 
-#include <sys/param.h>
+#include <sys/types.h>
 #include <sys/bus.h>
-#include <sys/kernel.h>
-#include <sys/libkern.h>
-#include <sys/malloc.h>
-#include <sys/module.h>
 #include <sys/rman.h>
-#include <sys/sysctl.h>
-#include <sys/systm.h>
 
-#include <machine/bus.h>
-#include <machine/resource.h>
-
-#include <dev/pci/pcivar.h>
 #include <dev/pci/pcireg.h>
-#include <dev/pci/pci_private.h>
+#include <dev/pci/pcivar.h>
 #include <dev/pci/pcib_private.h>
 
-#include "pcib_if.h"
-
-static int             pcib_probe(device_t dev);
-static int             pcib_suspend(device_t dev);
-static int             pcib_resume(device_t dev);
-static int             pcib_power_for_sleep(device_t pcib, device_t dev,
-                           int *pstate);
-
-static device_method_t pcib_methods[] = {
-    /* Device interface */
-    DEVMETHOD(device_probe,            pcib_probe),
-    DEVMETHOD(device_attach,           pcib_attach),
-    DEVMETHOD(device_detach,           bus_generic_detach),
-    DEVMETHOD(device_shutdown,         bus_generic_shutdown),
-    DEVMETHOD(device_suspend,          pcib_suspend),
-    DEVMETHOD(device_resume,           pcib_resume),
-
-    /* Bus interface */
-    DEVMETHOD(bus_print_child,         bus_generic_print_child),
-    DEVMETHOD(bus_read_ivar,           pcib_read_ivar),
-    DEVMETHOD(bus_write_ivar,          pcib_write_ivar),
-    DEVMETHOD(bus_alloc_resource,      pcib_alloc_resource),
-#ifdef NEW_PCIB
-    DEVMETHOD(bus_adjust_resource,     pcib_adjust_resource),
-    DEVMETHOD(bus_release_resource,    pcib_release_resource),
-#else
-    DEVMETHOD(bus_adjust_resource,     bus_generic_adjust_resource),
-    DEVMETHOD(bus_release_resource,    bus_generic_release_resource),
-#endif
-    DEVMETHOD(bus_activate_resource,   bus_generic_activate_resource),
-    DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource),
-    DEVMETHOD(bus_setup_intr,          bus_generic_setup_intr),
-    DEVMETHOD(bus_teardown_intr,       bus_generic_teardown_intr),
-
-    /* pcib interface */
-    DEVMETHOD(pcib_maxslots,           pcib_maxslots),
-    DEVMETHOD(pcib_read_config,                pcib_read_config),
-    DEVMETHOD(pcib_write_config,       pcib_write_config),
-    DEVMETHOD(pcib_route_interrupt,    pcib_route_interrupt),
-    DEVMETHOD(pcib_alloc_msi,          pcib_alloc_msi),
-    DEVMETHOD(pcib_release_msi,                pcib_release_msi),
-    DEVMETHOD(pcib_alloc_msix,         pcib_alloc_msix),
-    DEVMETHOD(pcib_release_msix,       pcib_release_msix),
-    DEVMETHOD(pcib_map_msi,            pcib_map_msi),
-    DEVMETHOD(pcib_power_for_sleep,    pcib_power_for_sleep),
-
-    { 0, 0 }
-};
-
-static devclass_t pcib_devclass;
-
-DEFINE_CLASS_0(pcib, pcib_driver, pcib_methods, sizeof(struct pcib_softc));
-DRIVER_MODULE(pcib, pci, pcib_driver, pcib_devclass, 0, 0);
-
-#ifdef NEW_PCIB
-/*
- * XXX Todo:
- * - properly handle the ISA enable bit.  If it is set, we should change
- *   the behavior of the I/O window resource and rman to not allocate the
- *   blocked ranges (upper 768 bytes of each 1K in the first 64k of the
- *   I/O port address space).
- */
-
-/*
- * Is a resource from a child device sub-allocated from one of our
- * resource managers?
- */
-static int
-pcib_is_resource_managed(struct pcib_softc *sc, int type, struct resource *r)
-{
-
-       switch (type) {
-       case SYS_RES_IOPORT:
-               return (rman_is_region_manager(r, &sc->io.rman));
-       case SYS_RES_MEMORY:
-               /* Prefetchable resources may live in either memory rman. */
-               if (rman_get_flags(r) & RF_PREFETCHABLE &&
-                   rman_is_region_manager(r, &sc->pmem.rman))
-                       return (1);
-               return (rman_is_region_manager(r, &sc->mem.rman));
-       }
-       return (0);
-}
-
-static int
-pcib_is_window_open(struct pcib_window *pw)
-{
-
-       return (pw->valid && pw->base < pw->limit);
-}
-
-/*
- * XXX: If RF_ACTIVE did not also imply allocating a bus space tag and
- * handle for the resource, we could pass RF_ACTIVE up to the PCI bus
- * when allocating the resource windows and rely on the PCI bus driver
- * to do this for us.
- */
-static void
-pcib_activate_window(struct pcib_softc *sc, int type)
-{
-
-       PCI_ENABLE_IO(device_get_parent(sc->dev), sc->dev, type);
-}
-
-static void
-pcib_write_windows(struct pcib_softc *sc, int mask)
-{
-       device_t dev;
-       uint32_t val;
-
-       dev = sc->dev;
-       if (sc->io.valid && mask & WIN_IO) {
-               val = pci_read_config(dev, PCIR_IOBASEL_1, 1);
-               if ((val & PCIM_BRIO_MASK) == PCIM_BRIO_32) {
-                       pci_write_config(dev, PCIR_IOBASEH_1,
-                           sc->io.base >> 16, 2);
-                       pci_write_config(dev, PCIR_IOLIMITH_1,
-                           sc->io.limit >> 16, 2);
-               }
-               pci_write_config(dev, PCIR_IOBASEL_1, sc->io.base >> 8, 1);
-               pci_write_config(dev, PCIR_IOLIMITL_1, sc->io.limit >> 8, 1);
-       }
-
-       if (mask & WIN_MEM) {
-               pci_write_config(dev, PCIR_MEMBASE_1, sc->mem.base >> 16, 2);
-               pci_write_config(dev, PCIR_MEMLIMIT_1, sc->mem.limit >> 16, 2);
-       }
-
-       if (sc->pmem.valid && mask & WIN_PMEM) {
-               val = pci_read_config(dev, PCIR_PMBASEL_1, 2);
-               if ((val & PCIM_BRPM_MASK) == PCIM_BRPM_64) {
-                       pci_write_config(dev, PCIR_PMBASEH_1,
-                           sc->pmem.base >> 32, 4);
-                       pci_write_config(dev, PCIR_PMLIMITH_1,
-                           sc->pmem.limit >> 32, 4);
-               }
-               pci_write_config(dev, PCIR_PMBASEL_1, sc->pmem.base >> 16, 2);
-               pci_write_config(dev, PCIR_PMLIMITL_1, sc->pmem.limit >> 16, 2);
-       }
-}
-
-static void
-pcib_alloc_window(struct pcib_softc *sc, struct pcib_window *w, int type,
-    int flags, pci_addr_t max_address)
-{
-       char buf[64];
-       int error, rid;
-
-       if (max_address != (u_long)max_address)
-               max_address = ~0ul;
-       w->rman.rm_start = 0;
-       w->rman.rm_end = max_address;
-       w->rman.rm_type = RMAN_ARRAY;
-       snprintf(buf, sizeof(buf), "%s %s window",
-           device_get_nameunit(sc->dev), w->name);
-       w->rman.rm_descr = strdup(buf, M_DEVBUF);
-       error = rman_init(&w->rman);
-       if (error)
-               panic("Failed to initialize %s %s rman",
-                   device_get_nameunit(sc->dev), w->name);
-
-       if (!pcib_is_window_open(w))
-               return;
-
-       if (w->base > max_address || w->limit > max_address) {
-               device_printf(sc->dev,
-                   "initial %s window has too many bits, ignoring\n", w->name);
-               return;
-       }
-       rid = w->reg;
-       w->res = bus_alloc_resource(sc->dev, type, &rid, w->base, w->limit,
-           w->limit - w->base + 1, flags);
-       if (w->res == NULL) {
-               device_printf(sc->dev,
-                   "failed to allocate initial %s window: %#jx-%#jx\n",
-                   w->name, (uintmax_t)w->base, (uintmax_t)w->limit);
-               w->base = max_address;
-               w->limit = 0;
-               pcib_write_windows(sc, w->mask);
-               return;
-       }
-       pcib_activate_window(sc, type);
-
-       error = rman_manage_region(&w->rman, rman_get_start(w->res),
-           rman_get_end(w->res));
-       if (error)
-               panic("Failed to initialize rman with resource");
-}
-
-/*
- * Initialize I/O windows.
- */
-static void
-pcib_probe_windows(struct pcib_softc *sc)
-{
-       pci_addr_t max;
-       device_t dev;
-       uint32_t val;
-
-       dev = sc->dev;
-
-       /* Determine if the I/O port window is implemented. */
-       val = pci_read_config(dev, PCIR_IOBASEL_1, 1);
-       if (val == 0) {
-               /*
-                * If 'val' is zero, then only 16-bits of I/O space
-                * are supported.
-                */
-               pci_write_config(dev, PCIR_IOBASEL_1, 0xff, 1);
-               if (pci_read_config(dev, PCIR_IOBASEL_1, 1) != 0) {
-                       sc->io.valid = 1;
-                       pci_write_config(dev, PCIR_IOBASEL_1, 0, 1);
-               }
-       } else
-               sc->io.valid = 1;
-
-       /* Read the existing I/O port window. */
-       if (sc->io.valid) {
-               sc->io.reg = PCIR_IOBASEL_1;
-               sc->io.step = 12;
-               sc->io.mask = WIN_IO;
-               sc->io.name = "I/O port";
-               if ((val & PCIM_BRIO_MASK) == PCIM_BRIO_32) {
-                       sc->io.base = PCI_PPBIOBASE(
-                           pci_read_config(dev, PCIR_IOBASEH_1, 2), val);
-                       sc->io.limit = PCI_PPBIOLIMIT(
-                           pci_read_config(dev, PCIR_IOLIMITH_1, 2),
-                           pci_read_config(dev, PCIR_IOLIMITL_1, 1));
-                       max = 0xffffffff;
-               } else {
-                       sc->io.base = PCI_PPBIOBASE(0, val);
-                       sc->io.limit = PCI_PPBIOLIMIT(0,
-                           pci_read_config(dev, PCIR_IOLIMITL_1, 1));
-                       max = 0xffff;
-               }
-               pcib_alloc_window(sc, &sc->io, SYS_RES_IOPORT, 0, max);
-       }
-
-       /* Read the existing memory window. */
-       sc->mem.valid = 1;
-       sc->mem.reg = PCIR_MEMBASE_1;
-       sc->mem.step = 20;
-       sc->mem.mask = WIN_MEM;
-       sc->mem.name = "memory";
-       sc->mem.base = PCI_PPBMEMBASE(0,
-           pci_read_config(dev, PCIR_MEMBASE_1, 2));
-       sc->mem.limit = PCI_PPBMEMLIMIT(0,
-           pci_read_config(dev, PCIR_MEMLIMIT_1, 2));
-       pcib_alloc_window(sc, &sc->mem, SYS_RES_MEMORY, 0, 0xffffffff);
-
-       /* Determine if the prefetchable memory window is implemented. */
-       val = pci_read_config(dev, PCIR_PMBASEL_1, 2);
-       if (val == 0) {
-               /*
-                * If 'val' is zero, then only 32-bits of memory space
-                * are supported.
-                */
-               pci_write_config(dev, PCIR_PMBASEL_1, 0xffff, 2);
-               if (pci_read_config(dev, PCIR_PMBASEL_1, 2) != 0) {
-                       sc->pmem.valid = 1;
-                       pci_write_config(dev, PCIR_PMBASEL_1, 0, 2);
-               }
-       } else
-               sc->pmem.valid = 1;
-
-       /* Read the existing prefetchable memory window. */
-       if (sc->pmem.valid) {
-               sc->pmem.reg = PCIR_PMBASEL_1;
-               sc->pmem.step = 20;
-               sc->pmem.mask = WIN_PMEM;
-               sc->pmem.name = "prefetch";
-               if ((val & PCIM_BRPM_MASK) == PCIM_BRPM_64) {
-                       sc->pmem.base = PCI_PPBMEMBASE(
-                           pci_read_config(dev, PCIR_PMBASEH_1, 4), val);
-                       sc->pmem.limit = PCI_PPBMEMLIMIT(
-                           pci_read_config(dev, PCIR_PMLIMITH_1, 4),
-                           pci_read_config(dev, PCIR_PMLIMITL_1, 2));
-                       max = 0xffffffffffffffff;
-               } else {
-                       sc->pmem.base = PCI_PPBMEMBASE(0, val);
-                       sc->pmem.limit = PCI_PPBMEMLIMIT(0,
-                           pci_read_config(dev, PCIR_PMLIMITL_1, 2));
-                       max = 0xffffffff;
-               }
-               pcib_alloc_window(sc, &sc->pmem, SYS_RES_MEMORY,
-                   RF_PREFETCHABLE, max);
-       }
-}
-
-#else
-
-/*
- * Is the prefetch window open (eg, can we allocate memory in it?)
- */
-static int
-pcib_is_prefetch_open(struct pcib_softc *sc)
-{
-       return (sc->pmembase > 0 && sc->pmembase < sc->pmemlimit);
-}
-
-/*
- * Is the nonprefetch window open (eg, can we allocate memory in it?)
- */
-static int
-pcib_is_nonprefetch_open(struct pcib_softc *sc)
-{
-       return (sc->membase > 0 && sc->membase < sc->memlimit);
-}
-
-/*
- * Is the io window open (eg, can we allocate ports in it?)
- */
-static int
-pcib_is_io_open(struct pcib_softc *sc)
-{
-       return (sc->iobase > 0 && sc->iobase < sc->iolimit);
-}
-
-/*
- * Get current I/O decode.
- */
-static void
-pcib_get_io_decode(struct pcib_softc *sc)
-{
-       device_t        dev;
-       uint32_t        iolow;
-
-       dev = sc->dev;
-
-       iolow = pci_read_config(dev, PCIR_IOBASEL_1, 1);
-       if ((iolow & PCIM_BRIO_MASK) == PCIM_BRIO_32)
-               sc->iobase = PCI_PPBIOBASE(
-                   pci_read_config(dev, PCIR_IOBASEH_1, 2), iolow);
-       else
-               sc->iobase = PCI_PPBIOBASE(0, iolow);
-
-       iolow = pci_read_config(dev, PCIR_IOLIMITL_1, 1);
-       if ((iolow & PCIM_BRIO_MASK) == PCIM_BRIO_32)
-               sc->iolimit = PCI_PPBIOLIMIT(
-                   pci_read_config(dev, PCIR_IOLIMITH_1, 2), iolow);
-       else
-               sc->iolimit = PCI_PPBIOLIMIT(0, iolow);
-}
-
-/*
- * Get current memory decode.
- */
-static void
-pcib_get_mem_decode(struct pcib_softc *sc)
-{
-       device_t        dev;
-       pci_addr_t      pmemlow;
-
-       dev = sc->dev;
-
-       sc->membase = PCI_PPBMEMBASE(0,
-           pci_read_config(dev, PCIR_MEMBASE_1, 2));
-       sc->memlimit = PCI_PPBMEMLIMIT(0,
-           pci_read_config(dev, PCIR_MEMLIMIT_1, 2));
-
-       pmemlow = pci_read_config(dev, PCIR_PMBASEL_1, 2);
-       if ((pmemlow & PCIM_BRPM_MASK) == PCIM_BRPM_64)
-               sc->pmembase = PCI_PPBMEMBASE(
-                   pci_read_config(dev, PCIR_PMBASEH_1, 4), pmemlow);
-       else
-               sc->pmembase = PCI_PPBMEMBASE(0, pmemlow);
-
-       pmemlow = pci_read_config(dev, PCIR_PMLIMITL_1, 2);
-       if ((pmemlow & PCIM_BRPM_MASK) == PCIM_BRPM_64) 
-               sc->pmemlimit = PCI_PPBMEMLIMIT(
-                   pci_read_config(dev, PCIR_PMLIMITH_1, 4), pmemlow);
-       else
-               sc->pmemlimit = PCI_PPBMEMLIMIT(0, pmemlow);
-}
-
-/*
- * Restore previous I/O decode.
- */
-static void
-pcib_set_io_decode(struct pcib_softc *sc)
-{
-       device_t        dev;
-       uint32_t        iohi;
-
-       dev = sc->dev;
-
-       iohi = sc->iobase >> 16;
-       if (iohi > 0)
-               pci_write_config(dev, PCIR_IOBASEH_1, iohi, 2);
-       pci_write_config(dev, PCIR_IOBASEL_1, sc->iobase >> 8, 1);
-
-       iohi = sc->iolimit >> 16;
-       if (iohi > 0)
-               pci_write_config(dev, PCIR_IOLIMITH_1, iohi, 2);
-       pci_write_config(dev, PCIR_IOLIMITL_1, sc->iolimit >> 8, 1);
-}
-
-/*
- * Restore previous memory decode.
- */
-static void
-pcib_set_mem_decode(struct pcib_softc *sc)
-{
-       device_t        dev;
-       pci_addr_t      pmemhi;
-
-       dev = sc->dev;
-
-       pci_write_config(dev, PCIR_MEMBASE_1, sc->membase >> 16, 2);
-       pci_write_config(dev, PCIR_MEMLIMIT_1, sc->memlimit >> 16, 2);
-
-       pmemhi = sc->pmembase >> 32;
-       if (pmemhi > 0)
-               pci_write_config(dev, PCIR_PMBASEH_1, pmemhi, 4);
-       pci_write_config(dev, PCIR_PMBASEL_1, sc->pmembase >> 16, 2);
-
-       pmemhi = sc->pmemlimit >> 32;
-       if (pmemhi > 0)
-               pci_write_config(dev, PCIR_PMLIMITH_1, pmemhi, 4);
-       pci_write_config(dev, PCIR_PMLIMITL_1, sc->pmemlimit >> 16, 2);
-}
-#endif
-
-/*
- * Get current bridge configuration.
- */
-static void
-pcib_cfg_save(struct pcib_softc *sc)
-{
-       device_t        dev;
-
-       dev = sc->dev;
-
-       sc->command = pci_read_config(dev, PCIR_COMMAND, 2);
-       sc->pribus = pci_read_config(dev, PCIR_PRIBUS_1, 1);
-       sc->secbus = pci_read_config(dev, PCIR_SECBUS_1, 1);
-       sc->subbus = pci_read_config(dev, PCIR_SUBBUS_1, 1);
-       sc->bridgectl = pci_read_config(dev, PCIR_BRIDGECTL_1, 2);
-       sc->seclat = pci_read_config(dev, PCIR_SECLAT_1, 1);
-#ifndef NEW_PCIB
-       if (sc->command & PCIM_CMD_PORTEN)
-               pcib_get_io_decode(sc);
-       if (sc->command & PCIM_CMD_MEMEN)
-               pcib_get_mem_decode(sc);
-#endif
-}
-
-/*
- * Restore previous bridge configuration.
- */
-static void
-pcib_cfg_restore(struct pcib_softc *sc)
-{
-       device_t        dev;
-
-       dev = sc->dev;
-
-       pci_write_config(dev, PCIR_COMMAND, sc->command, 2);
-       pci_write_config(dev, PCIR_PRIBUS_1, sc->pribus, 1);
-       pci_write_config(dev, PCIR_SECBUS_1, sc->secbus, 1);
-       pci_write_config(dev, PCIR_SUBBUS_1, sc->subbus, 1);
-       pci_write_config(dev, PCIR_BRIDGECTL_1, sc->bridgectl, 2);
-       pci_write_config(dev, PCIR_SECLAT_1, sc->seclat, 1);
-#ifdef NEW_PCIB
-       pcib_write_windows(sc, WIN_IO | WIN_MEM | WIN_PMEM);
-#else
-       if (sc->command & PCIM_CMD_PORTEN)
-               pcib_set_io_decode(sc);
-       if (sc->command & PCIM_CMD_MEMEN)
-               pcib_set_mem_decode(sc);
-#endif
-}
-
-/*
- * Generic device interface
- */
-static int
-pcib_probe(device_t dev)
-{
-    if ((pci_get_class(dev) == PCIC_BRIDGE) &&
-       (pci_get_subclass(dev) == PCIS_BRIDGE_PCI)) {
-       device_set_desc(dev, "PCI-PCI bridge");
-       return(-10000);
-    }
-    return(ENXIO);
-}
-
-void
-pcib_attach_common(device_t dev)
-{
-    struct pcib_softc  *sc;
-    struct sysctl_ctx_list *sctx;
-    struct sysctl_oid  *soid;
-
-    sc = device_get_softc(dev);
-    sc->dev = dev;
-
-    /*
-     * Get current bridge configuration.
-     */
-    sc->domain = pci_get_domain(dev);
-    sc->secstat = pci_read_config(dev, PCIR_SECSTAT_1, 2);
-    pcib_cfg_save(sc);
-
-    /*
-     * Setup sysctl reporting nodes
-     */
-    sctx = device_get_sysctl_ctx(dev);
-    soid = device_get_sysctl_tree(dev);
-    SYSCTL_ADD_UINT(sctx, SYSCTL_CHILDREN(soid), OID_AUTO, "domain",
-      CTLFLAG_RD, &sc->domain, 0, "Domain number");
-    SYSCTL_ADD_UINT(sctx, SYSCTL_CHILDREN(soid), OID_AUTO, "pribus",
-      CTLFLAG_RD, &sc->pribus, 0, "Primary bus number");
-    SYSCTL_ADD_UINT(sctx, SYSCTL_CHILDREN(soid), OID_AUTO, "secbus",
-      CTLFLAG_RD, &sc->secbus, 0, "Secondary bus number");
-    SYSCTL_ADD_UINT(sctx, SYSCTL_CHILDREN(soid), OID_AUTO, "subbus",
-      CTLFLAG_RD, &sc->subbus, 0, "Subordinate bus number");
-
-    /*
-     * Quirk handling.
-     */
-    switch (pci_get_devid(dev)) {
-    case 0x12258086:           /* Intel 82454KX/GX (Orion) */
-       {
-           uint8_t     supbus;
-
-           supbus = pci_read_config(dev, 0x41, 1);
-           if (supbus != 0xff) {
-               sc->secbus = supbus + 1;
-               sc->subbus = supbus + 1;
-           }
-           break;
-       }
-
-    /*
-     * The i82380FB mobile docking controller is a PCI-PCI bridge,
-     * and it is a subtractive bridge.  However, the ProgIf is wrong
-     * so the normal setting of PCIB_SUBTRACTIVE bit doesn't
-     * happen.  There's also a Toshiba bridge that behaves this
-     * way.
-     */
-    case 0x124b8086:           /* Intel 82380FB Mobile */
-    case 0x060513d7:           /* Toshiba ???? */
-       sc->flags |= PCIB_SUBTRACTIVE;
-       break;
-
-    /* Compaq R3000 BIOS sets wrong subordinate bus number. */
-    case 0x00dd10de:
-       {
-           char *cp;
-
-           if ((cp = getenv("smbios.planar.maker")) == NULL)
-               break;
-           if (strncmp(cp, "Compal", 6) != 0) {
-               freeenv(cp);
-               break;
-           }
-           freeenv(cp);
-           if ((cp = getenv("smbios.planar.product")) == NULL)
-               break;
-           if (strncmp(cp, "08A0", 4) != 0) {
-               freeenv(cp);
-               break;
-           }
-           freeenv(cp);
-           if (sc->subbus < 0xa) {
-               pci_write_config(dev, PCIR_SUBBUS_1, 0xa, 1);
-               sc->subbus = pci_read_config(dev, PCIR_SUBBUS_1, 1);
-           }
-           break;
-       }
-    }
-
-    if (pci_msi_device_blacklisted(dev))
-       sc->flags |= PCIB_DISABLE_MSI;
-
-    /*
-     * Intel 815, 845 and other chipsets say they are PCI-PCI bridges,
-     * but have a ProgIF of 0x80.  The 82801 family (AA, AB, BAM/CAM,
-     * BA/CA/DB and E) PCI bridges are HUB-PCI bridges, in Intelese.
-     * This means they act as if they were subtractively decoding
-     * bridges and pass all transactions.  Mark them and real ProgIf 1
-     * parts as subtractive.
-     */
-    if ((pci_get_devid(dev) & 0xff00ffff) == 0x24008086 ||
-      pci_read_config(dev, PCIR_PROGIF, 1) == PCIP_BRIDGE_PCI_SUBTRACTIVE)
-       sc->flags |= PCIB_SUBTRACTIVE;
-
-#ifdef NEW_PCIB
-    pcib_probe_windows(sc);
-#endif
-    if (bootverbose) {
-       device_printf(dev, "  domain            %d\n", sc->domain);
-       device_printf(dev, "  secondary bus     %d\n", sc->secbus);
-       device_printf(dev, "  subordinate bus   %d\n", sc->subbus);
-#ifdef NEW_PCIB
-       if (pcib_is_window_open(&sc->io))
-           device_printf(dev, "  I/O decode        0x%jx-0x%jx\n",
-             (uintmax_t)sc->io.base, (uintmax_t)sc->io.limit);
-       if (pcib_is_window_open(&sc->mem))
-           device_printf(dev, "  memory decode     0x%jx-0x%jx\n",
-             (uintmax_t)sc->mem.base, (uintmax_t)sc->mem.limit);
-       if (pcib_is_window_open(&sc->pmem))
-           device_printf(dev, "  prefetched decode 0x%jx-0x%jx\n",
-             (uintmax_t)sc->pmem.base, (uintmax_t)sc->pmem.limit);
-#else
-       if (pcib_is_io_open(sc))
-           device_printf(dev, "  I/O decode        0x%x-0x%x\n",
-             sc->iobase, sc->iolimit);
-       if (pcib_is_nonprefetch_open(sc))
-           device_printf(dev, "  memory decode     0x%jx-0x%jx\n",
-             (uintmax_t)sc->membase, (uintmax_t)sc->memlimit);
-       if (pcib_is_prefetch_open(sc))
-           device_printf(dev, "  prefetched decode 0x%jx-0x%jx\n",
-             (uintmax_t)sc->pmembase, (uintmax_t)sc->pmemlimit);
-#endif
-       else
-           device_printf(dev, "  no prefetched decode\n");
-       if (sc->flags & PCIB_SUBTRACTIVE)
-           device_printf(dev, "  Subtractively decoded bridge.\n");
-    }
-
-    /*
-     * XXX If the secondary bus number is zero, we should assign a bus number
-     *     since the BIOS hasn't, then initialise the bridge.  A simple
-     *     bus_alloc_resource with the a couple of busses seems like the right
-     *     approach, but we don't know what busses the BIOS might have already
-     *     assigned to other bridges on this bus that probe later than we do.
-     *
-     *     If the subordinate bus number is less than the secondary bus number,
-     *     we should pick a better value.  One sensible alternative would be to
-     *     pick 255; the only tradeoff here is that configuration transactions
-     *     would be more widely routed than absolutely necessary.  We could
-     *     then do a walk of the tree later and fix it.
-     */
-}
-
-int
-pcib_attach(device_t dev)
-{
-    struct pcib_softc  *sc;
-    device_t           child;
-
-    pcib_attach_common(dev);
-    sc = device_get_softc(dev);
-    if (sc->secbus != 0) {
-       child = device_add_child(dev, "pci", sc->secbus);
-       if (child != NULL)
-           return(bus_generic_attach(dev));
-    }
-
-    /* no secondary bus; we should have fixed this */
-    return(0);
-}
-
-int
-pcib_suspend(device_t dev)
-{
-       device_t        pcib;
-       int             dstate, error;
-
-       pcib_cfg_save(device_get_softc(dev));
-       error = bus_generic_suspend(dev);
-       if (error == 0 && pci_do_power_suspend) {
-               dstate = PCI_POWERSTATE_D3;
-               pcib = device_get_parent(device_get_parent(dev));
-               if (PCIB_POWER_FOR_SLEEP(pcib, dev, &dstate) == 0)
-                       pci_set_powerstate(dev, dstate);
-       }
-       return (error);
-}
-
-int
-pcib_resume(device_t dev)
-{
-       device_t        pcib;
-
-       if (pci_do_power_resume) {
-               pcib = device_get_parent(device_get_parent(dev));
-               if (PCIB_POWER_FOR_SLEEP(pcib, dev, NULL) == 0)
-                       pci_set_powerstate(dev, PCI_POWERSTATE_D0);
-       }
-       pcib_cfg_restore(device_get_softc(dev));
-       return (bus_generic_resume(dev));
-}
-
-int
-pcib_read_ivar(device_t dev, device_t child, int which, uintptr_t *result)
-{
-    struct pcib_softc  *sc = device_get_softc(dev);
-    
-    switch (which) {
-    case PCIB_IVAR_DOMAIN:
-       *result = sc->domain;
-       return(0);
-    case PCIB_IVAR_BUS:
-       *result = sc->secbus;
-       return(0);
-    }
-    return(ENOENT);
-}
-
-int
-pcib_write_ivar(device_t dev, device_t child, int which, uintptr_t value)
-{
-    struct pcib_softc  *sc = device_get_softc(dev);
-
-    switch (which) {
-    case PCIB_IVAR_DOMAIN:
-       return(EINVAL);
-    case PCIB_IVAR_BUS:
-       sc->secbus = value;
-       return(0);
-    }
-    return(ENOENT);
-}
-
-#ifdef NEW_PCIB
-static const char *
-pcib_child_name(device_t child)
-{
-       static char buf[64];
-
-       if (device_get_nameunit(child) != NULL)
-               return (device_get_nameunit(child));
-       snprintf(buf, sizeof(buf), "pci%d:%d:%d:%d", pci_get_domain(child),
-           pci_get_bus(child), pci_get_slot(child), pci_get_function(child));
-       return (buf);
-}
-
-/*
- * Attempt to allocate a resource from the existing resources assigned
- * to a window.
- */
-static struct resource *
-pcib_suballoc_resource(struct pcib_softc *sc, struct pcib_window *w,
-    device_t child, int type, int *rid, u_long start, u_long end, u_long count,
-    u_int flags)
-{
-       struct resource *res;
-
-       if (!pcib_is_window_open(w))
-               return (NULL);
-
-       res = rman_reserve_resource(&w->rman, start, end, count,
-           flags & ~RF_ACTIVE, child);
-       if (res == NULL)
-               return (NULL);
-
-       if (bootverbose)
-               device_printf(sc->dev,
-                   "allocated %s range (%#lx-%#lx) for rid %x of %s\n",
-                   w->name, rman_get_start(res), rman_get_end(res), *rid,
-                   pcib_child_name(child));
-       rman_set_rid(res, *rid);
-
-       /*
-        * If the resource should be active, pass that request up the
-        * tree.  This assumes the parent drivers can handle
-        * activating sub-allocated resources.
-        */
-       if (flags & RF_ACTIVE) {
-               if (bus_activate_resource(child, type, *rid, res) != 0) {
-                       rman_release_resource(res);
-                       return (NULL);
-               }
-       }
-
-       return (res);
-}
-
-/*
- * Attempt to grow a window to make room for a given resource request.
- * The 'step' parameter is log_2 of the desired I/O window's alignment.
- */
-static int
-pcib_grow_window(struct pcib_softc *sc, struct pcib_window *w, int type,
-    u_long start, u_long end, u_long count, u_int flags)
-{
-       u_long align, start_free, end_free, front, back;
-       int error, rid;
-
-       /*
-        * Clamp the desired resource range to the maximum address
-        * this window supports.  Reject impossible requests.
-        */
-       if (!w->valid)
-               return (EINVAL);
-       if (end > w->rman.rm_end)
-               end = w->rman.rm_end;
-       if (start + count - 1 > end || start + count < start)
-               return (EINVAL);
-
-       /*
-        * If there is no resource at all, just try to allocate enough
-        * aligned space for this resource.
-        */
-       if (w->res == NULL) {
-               if (RF_ALIGNMENT(flags) < w->step) {
-                       flags &= ~RF_ALIGNMENT_MASK;
-                       flags |= RF_ALIGNMENT_LOG2(w->step);
-               }
-               start &= ~((1ul << w->step) - 1);
-               end |= ((1ul << w->step) - 1);
-               count = roundup2(count, 1ul << w->step);
-               rid = w->reg;
-               w->res = bus_alloc_resource(sc->dev, type, &rid, start, end,
-                   count, flags & ~RF_ACTIVE);
-               if (w->res == NULL) {
-                       if (bootverbose)
-                               device_printf(sc->dev,
-                   "failed to allocate initial %s window (%#lx-%#lx,%#lx)\n",
-                                   w->name, start, end, count);
-                       return (ENXIO);
-               }
-               if (bootverbose)
-                       device_printf(sc->dev,
-                           "allocated initial %s window of %#lx-%#lx\n",
-                           w->name, rman_get_start(w->res),
-                           rman_get_end(w->res));
-               error = rman_manage_region(&w->rman, rman_get_start(w->res),
-                   rman_get_end(w->res));
-               if (error) {
-                       if (bootverbose)
-                               device_printf(sc->dev,
-                                   "failed to add initial %s window to rman\n",
-                                   w->name);
-                       bus_release_resource(sc->dev, type, w->reg, w->res);
-                       w->res = NULL;

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to