int
pci_activate(
pci_chipset_tag_t pc
, pcitag_t tag
, int reg
, void *sc
, int (*wakeup)(pci_chipset_tag_t pc, pcitag_t tag
, void *sc, pcireg_t reg)
)
pcireg_t
pci_conf_read(
pci_chipset_tag_t pc
, pcitag_t tag
, int reg
)
void
pci_conf_write(
pci_chipset_tag_t pc
, pcitag_t tag
, int reg
, pcireg_t val
)
void
pci_conf_print(
pci_chipset_tag_t pc
, pcitag_t tag
, void (*func)(pci_chipset_tag_t, pcitag_t, const pcireg_t *)
)
void
pci_conf_capture(
pci_chipset_tag_t pc
, pcitag_t tag
, struct pci_conf_state *
)
void
pci_conf_restore(
pci_chipset_tag_t pc
, pcitag_t tag
, struct pci_conf_state *
)
int
pci_find_device(
struct pci_attach_args *pa
, int (*func)(struct pci_attach_args *)
)
int
pci_get_capability(
pci_chipset_tag_t pc
, pcitag_t tag
, int capid
, int *offsetp
, pcireg_t *valuep
)
pcireg_t
pci_mapreg_type(
pci_chipset_tag_t pc
, pcitag_t tag
, int reg
)
int
pci_mapreg_map(
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
)
int
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
)
int
pci_find_rom(
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
)
int
pci_intr_map(
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
)
void
pci_intr_disestablish(
pci_chipset_tag_t pc
, void *ih
)
int
pci_set_powerstate(
pci_chipset_tag_t pc
, pcitag_t tag
, pcireg_t newstate
)
int
pci_get_powerstate(
pci_chipset_tag_t pc
, pcitag_t tag
, pcireg_t *state
)
int
pci_vpd_read(
pci_chipset_tag_t pc
, pcitag_t tag
, int offset
, int count
, pcireg_t *data
)
int
pci_vpd_write(
pci_chipset_tag_t pc
, pcitag_t tag
, int offset
, int count
, pcireg_t *data
)
pcitag_t
pci_make_tag(
pci_chipset_tag_t pc
, int bus
, int device
, int function
)
void
pci_decompose_tag(
pci_chipset_tag_t pc
, pcitag_t tag
, int *busp
, int *devicep
, int *functionp
)
char
*
pci_findvendor(
pcireg_t id
)
void
pci_devinfo(
pcireg_t id
, pcireg_t class
, int show
, char *cp
, size_t len
)
int
PCI_VENDOR(
pcireg_t id
)
int
PCI_PRODUCT(
pcireg_t id
)
int
PCI_REVISION(
pcireg_t id
)
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.
pcireg_t
pci_chipset_tag_t
pcitag_t
pci_intr_handle_t
struct
pci_attach_args
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
pcireg_t reg[16]; /* pci conf register */
pc
, tag
, sc
, fun
)
fun
to restore its state.
If
fun
is
NULL
then restoring from state D3 is going to fail.
pc
, tag
, reg
)
reg
in PCI configuration space.
The argument
tag
is the PCI tag for the current device attached to PCI chipset
pc
.
pc
, tag
, reg
, val
)
reg
in PCI configuration space.
The argument
tag
is the PCI tag for the current device attached to PCI chipset
pc
.
pc
, tag
, func
)
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.
pc
, tag
, pcs
)
pcs
.
The argument
tag
is the PCI tag for the current device attached to the PCI
chipset
pc
.
pc
, tag
, pcs
)
pcs
.
The argument
tag
is the PCI tag for the current device attached to the PCI
chipset
pc
.
pa
, func
)
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 LKMs (see
lkm(4))
and its use otherwise is strongly discouraged.
pc
, tag
, capid
, offsetp
, valuep
)
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.
pc
, tag
, reg
)
reg
and returns the default (or current) mapping type.
Valid returns values are:
PCI_MAPREG_TYPE_IO
PCI_MAPREG_TYPE_MEM
PCI_MAPREG_TYPE_MEM
|
PCI_MAPREG_MEM_TYPE_64BIT
PCI_MAPREG_TYPE_ROM
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
.
pa
, reg
, type
, busflags
, tagp
, handlep
, basep
, sizep
)
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
are:
PCI_MAPREG_TYPE_IO
PCI_MAPREG_TYPE_MEM
PCI_MAPREG_TYPE_ROM
reg
is
PCI_MAPREG_ROM
.
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.
pc
, tag
, reg
, type
, basep
, sizep
, flagsp
)
)
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.
pa
, bst
, bsh
, code
, handlep
, sizep
)
)
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:
PCI_ROM_CODE_TYPE_X86
PCI_ROM_CODE_TYPE_OFW
PCI_ROM_CODE_TYPE_HPPA
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).
pa
, ih
)
pc
, ih
)
pc
, ih
)
pc
, ih
, level
, handler
, arg
)
pc
, ih
)
pc
, tag
, newstate
)
newstate
are:
PCI_PMCSR_STATE_D0
PCI_PMCSR_STATE_D1
PCI_PMCSR_STATE_D2
PCI_PMCSR_STATE_D3
pc
, tag
, state
)
pc
, tag
, offset
, count
, data
)
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 fails.
pc
, tag
, offset
, count
, data
)
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 fails.
pc
, bus
, device
, function
)
pc
, tag
, busp
, devicep
, fnp
)
tag
generated by
pci_make_tag(
)
into its
<bus, device, function>
tuple.
id
)
id
.
id
, class
, show
, cp
, len
)
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.
id
)
id
.
id
)
id
.
id
)
id
.
struct
pci_attach_args
describing the device attaches to the PCI bus.
Drivers match the device using the
pa_id
member using
PCI_VENDOR(
).
PCI_PRODUCT(
)
and
PCI_REVISION(
).
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).
During system shutdown, it is necessary to abort any DMA transfers in progress by registering a shutdown hook (see shutdownhook_establish(9)).
/usr/src
.
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
sys/arch/<arch>/pci/pci_machdep.c
.
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
sys/dev/pci/Makefile.pcidevs
.