I would appreciate any donations. Wishlist or send e-mail type donations to maekawa AT daemon-systems.org.

Thank you.

PCI(9)                     Kernel Developer's Manual                    PCI(9)

     PCI, pci_activate, pci_bus_devorder, pci_chipset_tag_create,
     pci_chipset_tag_destroy, pci_conf_read, pci_conf_write, pci_conf_print,
     pci_conf_capture, pci_conf_restore, pci_find_device, pci_get_capability,
     pci_mapreg_type, pci_mapreg_map, pci_mapreg_info, pci_intr_map,
     pci_intr_string, pci_intr_evcnt, pci_intr_establish,
     pci_intr_disestablish, pci_get_powerstate, pci_set_powerstate,
     pci_vpd_read, pci_vpd_write, pci_make_tag, pci_decompose_tag,
     pci_findvendor, pci_devinfo, PCI_VENDOR, PCI_PRODUCT, PCI_REVISION --
     Peripheral Component Interconnect

     #include <sys/bus.h>
     #include <dev/pci/pcivar.h>
     #include <dev/pci/pcireg.h>
     #include <dev/pci/pcidevs.h>

     pci_bus_devorder(pci_chipset_tag_t pc, int bus, uint8_t *devs,
         int maxdevs);

     pci_activate(pci_chipset_tag_t pc, pcitag_t tag, device_t dev,
         int (*wakeup)(pci_chipset_tag_t pc, pcitag_t tag,
         device_t dev, pcireg_t reg));

     pci_chipset_tag_create(pci_chipset_tag_t opc, uint64_t present,
         const struct pci_overrides *ov, void *ctx, pci_chipset_tag_t *pcp);

     pci_chipset_tag_destroy(pci_chipset_tag_t pc);

     pci_conf_read(pci_chipset_tag_t pc, pcitag_t tag, int reg);

     pci_conf_write(pci_chipset_tag_t pc, pcitag_t tag, int reg,
         pcireg_t val);

     pci_conf_print(pci_chipset_tag_t pc, pcitag_t tag,
         void (*func)(pci_chipset_tag_t, pcitag_t, const pcireg_t *));

     pci_conf_capture(pci_chipset_tag_t pc, pcitag_t tag,
         struct pci_conf_state *);

     pci_conf_restore(pci_chipset_tag_t pc, pcitag_t tag,
         struct pci_conf_state *);

     pci_find_device(struct pci_attach_args *pa,
         int (*func)(const struct pci_attach_args *));

     pci_get_capability(pci_chipset_tag_t pc, pcitag_t tag, int capid,
         int *offsetp, pcireg_t *valuep);

     pci_mapreg_type(pci_chipset_tag_t pc, pcitag_t tag, int reg);

     pci_mapreg_map(const struct pci_attach_args *pa, int reg, pcireg_t type,
         int busflags, bus_space_tag_t *tagp, bus_space_handle_t *handlep,
         bus_addr_t *basep, bus_size_t *sizep);

     pci_mapreg_info(pci_chipset_tag_t pc, pcitag_t tag, int reg,
         pcireg_t type, bus_addr_t *basep, bus_size_t *sizep, int *flagsp);

     pci_find_rom(const struct pci_attach_args *pa, bus_space_tag_t bst,
         bus_space_handle_t bsh, int code, bus_space_handle_t *handlep,
         bus_space_size_t *sizep);

     pci_intr_map(const struct pci_attach_args *pa, pci_intr_handle_t *ih);

     const char *
     pci_intr_string(pci_chipset_tag_t pc, pci_intr_handle_t ih);

     const struct evcnt *
     pci_intr_evcnt(pci_chipset_tag_t pc, pci_intr_handle_t ih);

     void *
     pci_intr_establish(pci_chipset_tag_t pc, pci_intr_handle_t ih, int level,
         int (*handler)(void *), void *arg);

     pci_intr_disestablish(pci_chipset_tag_t pc, void *ih);

     pci_set_powerstate(pci_chipset_tag_t pc, pcitag_t tag,
         pcireg_t newstate);

     pci_get_powerstate(pci_chipset_tag_t pc, pcitag_t tag, pcireg_t *state);

     pci_vpd_read(pci_chipset_tag_t pc, pcitag_t tag, int offset, int count,
         pcireg_t *data);

     pci_vpd_write(pci_chipset_tag_t pc, pcitag_t tag, int offset, int count,
         pcireg_t *data);

     pci_make_tag(pci_chipset_tag_t pc, int bus, int device, int function);

     pci_decompose_tag(pci_chipset_tag_t pc, pcitag_t tag, int *busp,
         int *devicep, int *functionp);

     char *
     pci_findvendor(pcireg_t id);

     pci_devinfo(pcireg_t id, pcireg_t class, int show, char *cp, size_t len);

     pci_aprint_devinfo(struct pci_attach_args *pa, const char *naive);

     PCI_VENDOR(pcireg_t id);

     PCI_PRODUCT(pcireg_t id);

     PCI_REVISION(pcireg_t id);

     The machine-independent PCI subsystem provides support for PCI devices.

     The PCI bus was initially developed by Intel in the early 1990's to
     replace the ISA bus for interfacing with their Pentium processor.  The
     PCI specification is widely regarded as well designed, and the PCI bus
     has found widespread acceptance in machines ranging from Apple's PowerPC-
     based systems to Sun's UltraSPARC-based machines.

     The PCI bus is a multiplexed bus, allowing addresses and data on the same
     pins for a reduced number of pins.  Data transfers can be 8-bit, 16-bit
     or 32-bit.  A 64-bit extended PCI bus is also defined.  Multi-byte
     transfers are little-endian.  The PCI bus operates up to 33MHz and any
     device on the bus can be the bus master.

     AGP is a version of PCI optimised for high-throughput data rates,
     particularly for accelerated frame buffers.

     The PCI bus is a "plug and play" bus, in the sense that devices can be
     configured dynamically by software.  The PCI interface chip on a PCI
     device bus presents a small window of registers into the PCI
     configuration space.  These registers contain information about the
     device such as the vendor and a product ID.  The configuration registers
     can also be written to by software to alter how the device interfaces to
     the PCI bus.  An important register in the configuration space is the
     Base Address Register (BAR).  The BAR is written to by software to map
     the device registers into a window of processor address space.  Once this
     mapping is done, the device registers can be accessed relative to the
     base address.

     Drivers for devices attached to the PCI will make use of the following
     data types:

              Configuration space register.

              Chipset tag for the PCI bus.

              Configuration tag describing the location and function of the
              PCI device.  It contains the tuple <bus, device, function>.

              The opaque handle describing an established interrupt handler.

     struct pci_attach_args
              Devices have their identity recorded in this structure.  It
              contains the following members:

                      bus_space_tag_t pa_iot;         /* pci i/o space tag */
                      bus_space_tag_t pa_memt;        /* pci mem space tag */
                      bus_dma_tag_t pa_dmat;          /* DMA tag */
                      pci_chipset_tag_t pa_pc;
                      int pa_flags;                   /* flags */
                      pcitag_t pa_tag;
                      pcireg_t pa_id;
                      pcireg_t pa_class;

     struct pci_conf_state
              Stores the PCI configuration state of a device.  It contains the
              following member:

                      pcireg_t reg[16];                       /* pci conf register */

     struct pci_overrides
              Stores pointers to functions that override the architecture's
              default pci(9) and pci_intr(9) implementation.  It contains the
              following members:

                      pcireg_t (*ov_conf_read)(void *,
                          pci_chipset_tag_t, pcitag_t, int);
                      void (*ov_conf_write)(void *,
                          pci_chipset_tag_t, pcitag_t, int, pcireg_t);
                      int (*ov_intr_map)(void *,
                         const struct pci_attach_args *, pci_intr_handle_t *);
                      const char *(*ov_intr_string)(void *,
                          pci_chipset_tag_t, pci_intr_handle_t);
                      const struct evcnt *(*ov_intr_evcnt)(void *,
                          pci_chipset_tag_t, pci_intr_handle_t);
                      void *(*ov_intr_establish)(void *,
                          pci_chipset_tag_t, pci_intr_handle_t,
                          int, int (*)(void *), void *);
                      void (*ov_intr_disestablish)(void *,
                          pci_chipset_tag_t, void *);
                      pcitag_t (*ov_make_tag)(void *,
                          pci_chipset_tag_t, int, int, int);
                      void (*ov_decompose_tag)(void *,
                          pci_chipset_tag_t, pcitag_t, int *, int *, int *);

     pci_bus_devorder(pc, bus, devs, maxdevs)
              Tell how many devices a PCI bus driver should probe and in what
              order.  If maxdevs is less than or equal to zero, return 0 and
              do not modify devs.  Otherwise, return maxdevs or the number of
              devices on bus to probe, whichever is less, and copy to devs
              each of the PCI device numbers to probe in the order that they
              should be probed.  pci_bus_devorder() will not copy more than
              maxdevs device numbers to devs.

     pci_activate(pc, tag, dev, fun)
              Attempt to bring the device to state D0.  If the device is not
              in the D0 state call fun to restore its state.  If fun is NULL
              then restoring from state D3 is going to fail.

     pci_chipset_tag_create(opc, present, ov, ctx, pcp)
              Create a copy of the tag opc at *pcp.  Except for the behavior
              overridden by ov, *pcp inherits the behavior of opc under PCI

              ov contains function pointers corresponding to PCI routines.
              Each function pointer has a corresponding bit in present, and if
              that bit is 1, the function pointer overrides the corresponding
              PCI call for the new tag.  Any combination of these bits may be
              set in present:


              pci_chipset_tag_create() does not copy ov.  After a new tag is
              created by pci_chipset_tag_create(), ov must not be destroyed
              until after the tag is destroyed by pci_chipset_tag_destroy().

              The first argument of every override-function is a void *, and
              ctx is passed in that argument.

              Return 0 if the call succeeds.  Return EOPNOTSUPP if the
              architecture does not support overrides.  Return EINVAL if
              present is 0, if ov is NULL, or if present indicates that an
              override is present, but the corresponding override in ov is

              If the call does not succeed, *pcp is undefined.

              Destroy a tag, pc, created by a prior call to
              pci_chipset_tag_create().  If pc was not created by
              pci_chipset_tag_create(), results are undefined.  If pc was
              already destroyed, results are undefined.

     pci_conf_read(pc, tag, reg)
              Read from register reg in PCI configuration space.  The argument
              tag is the PCI tag for the current device attached to PCI
              chipset pc.

     pci_conf_write(pc, tag, reg, val)
              Write to register reg in PCI configuration space.  The argument
              tag is the PCI tag for the current device attached to PCI
              chipset pc.

     pci_conf_print(pc, tag, func)
              Print out most of the registers in the PCI configuration for the
              device.  The argument tag is the PCI tag for the current device
              attached to PCI chipset pc.  The argument func is a function
              called by pci_conf_print() to print the device-dependent
              registers.  This function is only useful for driver development
              and is usually wrapped in pre-processor declarations.

     pci_conf_capture(pc, tag, pcs)
              Capture PCI configuration space into structure pcs.  The
              argument tag is the PCI tag for the current device attached to
              the PCI chipset pc.

     pci_conf_restore(pc, tag, pcs)
              Restores PCI configuration space from structure pcs.  The
              argument tag is the PCI tag for the current device attached to
              the PCI chipset pc.

     pci_find_device(pa, func)
              Find a device using a match function on all probed busses.  The
              argument func is called by pci_find_device() to match a device.
              The argument pa is filled in if the device is matched.
              pci_find_device() returns 1 if the device is matched, and zero
              otherwise.  This function is specifically for use by kernel
              modules and its use otherwise is strongly discouraged.

     pci_get_capability(pc, tag, capid, offsetp, valuep)
              Parse the device capability list in configuration space looking
              for capability capid.  If offsetp is not NULL, the register
              offset in configuration space is returned in offsetp.  If valuep
              is not NULL, the value of the capability is returned in valuep.
              The argument tag is the PCI tag for the current device attached
              to PCI chipset pc.  This function returns 1 if the capability
              was found.  If the capability was not found, it returns zero,
              and offsetp and valuep remain unchanged.

     pci_mapreg_type(pc, tag, reg)
              Interrogates the Base Address Register (BAR) in configuration
              space specified by reg and returns the default (or current)
              mapping type.  Valid returns values are:

                       The mapping is to I/O address space.

                       The mapping is to memory address space.

                       The mapping is to 64-bit memory address space.

                       The mapping is to ROM.  Note that in the current
                       implementation, PCI_MAPREG_TYPE_ROM has the same
                       numeric value as PCI_MAPREG_TYPE_MEM.

              The argument tag is the PCI tag for the current device attached
              to PCI chipset pc.

     pci_mapreg_map(pa, reg, type, busflags, tagp, handlep, basep, sizep)
              Maps the register windows for the device into kernel virtual
              address space.  This function is generally only called during
              the driver attach step and takes a pointer to the struct
              pci_attach_args in pa.  The physical address of the mapping is
              in the Base Address Register (BAR) in configuration space
              specified by reg.  Valid values for the type of mapping type

                       The mapping should be to I/O address space.

                       The mapping should be to memory address space.

                       The mapping is to access ROM.  This type of mapping is
                       only permitted when the value for reg is

              The argument busflags are bus-space flags passed to
              bus_space_map() to perform the mapping (see bus_space(9)).  The
              bus-space tag and handle for the mapped register window are
              returned in tagp and handlep respectively.  The bus-address and
              size of the mapping are returned in basep and sizep
              respectively.  If any of tagp, handlep, basep, or sizep are NULL
              then pci_mapreg_map() does not define their return value.  This
              function returns zero on success and non-zero on error.

     pci_mapreg_info(pc, tag, reg, type, basep, sizep, flagsp)
              Performs the same operations as pci_mapreg_map() but doesn't
              actually map the register window into kernel virtual address
              space.  Returns the bus-address, size and bus flags in basep,
              sizep and flagsp respectively.  These return values can be used
              by bus_space_map() to actually map the register window into
              kernel virtual address space.  This function is useful for
              setting up the registers in configuration space and deferring
              the mapping to a later time, such as in a bus-independent
              attachment routine.  pci_mapreg_info returns zero on success and
              non-zero on failure.

     pci_find_rom(pa, bst, bsh, code, handlep, sizep)
              Locates a suitable ROM image within a PCI expansion ROM
              previously mapped with pci_mapreg_map() and creates a subregion
              for it with bus_space_subregion().  The bst and bsh arguments
              are the bus tag and handle obtained with the prior call to
              pci_mapreg_map().  Valid values for the image type code are:

                       Find a ROM image containing i386 executable code for
                       use by PC BIOS.

                       Find a ROM image containing Forth code for use by Open

                       Find a ROM image containing HP PA/RISC executable code.

              The created subregion will cover the entire selected ROM image,
              including header data.  The handle to this subregion is returned
              in handlep.  The size of the image (and the corresponding
              subregion) is returned in sizep.  This function can only be used
              with expansion ROMs located at the PCI_MAPREG_ROM base address
              register (BAR).

     pci_intr_map(pa, ih)
              See pci_intr(9).

     pci_intr_string(pc, ih)
              See pci_intr(9).

     pci_intr_evcnt(pc, ih)
              See pci_intr(9).

     pci_intr_establish(pc, ih, level, handler, arg)
              See pci_intr(9).

     pci_intr_disestablish(pc, ih)
              See pci_intr(9).

     pci_set_powerstate(pc, tag, newstate)
              Set power state of the device to newstate.  Valid values for
              newstate are:


     pci_get_powerstate(pc, tag, state)
              Get current power state of the device.

     pci_vpd_read(pc, tag, offset, count, data)
              Read count 32-bit words of Vital Product Data for the device
              starting at offset offset into the buffer pointed to by data.
              Returns 0 on success or non-zero if the device has no Vital
              Product Data capability or if reading the Vital Product Data

     pci_vpd_write(pc, tag, offset, count, data)
              Write count 32-bit words of Vital Product Data for the device
              starting at offset offset from the buffer pointed to by data.
              Returns 0 on success or non-zero if the device has no Vital
              Product Data capability of if writing the Vital Product Data

     pci_make_tag(pc, bus, device, function)
              Create a new PCI tag for the PCI device specified by the tuple
              <bus, device, function>.  This function is not useful to the
              usual PCI device driver.  It is generally used by drivers of
              multi-function devices when attaching other PCI device drivers
              to each function.

     pci_decompose_tag(pc, tag, busp, devicep, fnp)
              Decompose the PCI tag tag generated by pci_make_tag() into its
              <bus, device, function> tuple.

              Return the string of the vendor name for the device specified by

     pci_devinfo(id, class, show, cp, len)
              Returns the description string from the in-kernel PCI database
              for the device described by id and class.  The description
              string is returned in cp; the size of that storage is given in
              len.  The argument show specifies whether the PCI subsystem
              should report the string to the console.

     pci_aprint_devinfo(pa, naive)
              Print device information to the console and system log, using
              the aprint_normal(9) and aprint_naive(9) functions.  For the
              device information, the ``pci_devinfo'' function above is used,
              or the naive argument in the ``AB_QUIET'' case.  This function
              is intended to be used early in device attach.

              Return the PCI vendor id for device id.

              Return the PCI product id for device id.

              Return the PCI product revision for device id.

     During autoconfiguration, a PCI driver will receive a pointer to struct
     pci_attach_args describing the device attaches to the PCI bus.  Drivers
     match the device using the pa_id member using PCI_VENDOR().

     During the driver attach step, drivers can read the device configuration
     space using pci_conf_read().  The meaning attached to registers in the
     PCI configuration space are device-dependent, but will usually contain
     physical addresses of the device register windows.  Device options can
     also be stored into the PCI configuration space using pci_conf_write().
     For example, the driver can request support for bus-mastering DMA by
     writing the option to the PCI configuration space.

     Device capabilities can be queried using pci_get_capability(), and
     returns device-specific information which can be found in the PCI
     configuration space to alter device operation.

     After reading the physical addresses of the device register windows from
     configuration space, these windows must be mapped into kernel virtual
     address space using pci_mapreg_map().  Device registers can now be
     accessed using the standard bus-space API (see bus_space(9)).

     Details of using PCI interrupts is described in pci_intr(9).

     The PCI bus supports bus-mastering operations from any device on the bus.
     The DMA facilities are accessed through the standard bus_dma(9)
     interface.  To support DMA transfers from the device to the host, it is
     necessary to enable bus-mastering in the PCI configuration space for the

     During system shutdown, it is necessary to abort any DMA transfers in
     progress by registering a shutdown hook (see pmf(9)).

     The PCI subsystem itself is implemented within the files
     sys/dev/pci/pci.c, sys/dev/pci/pci_subr.c, sys/dev/pci/pci_map.c,
     sys/dev/pci/pci_quirks.c, and sys/dev/pci/pciconf.c.  Machine-dependent
     portions are implemented within the file

     The database of known devices exists within the file
     sys/dev/pci/pcidevs_data.h and is generated automatically from the file
     sys/dev/pci/pcidevs.  New vendor and product identifiers should be added
     to this file.  The database can be regenerated using the Makefile

     pci(4), autoconf(9), bus_dma(9), bus_space(9), driver(9),
     pci_configure_bus(9), pci_intr(9), pmf(9)

     The machine-independent PCI subsystem appeared in NetBSD 1.2.

NetBSD 7.1.2                   January 30, 2012                   NetBSD 7.1.2