This enables user-level applications to access PCI configuration space. This is useful in cases such as the following:
Note that these IOCTLs must never be issued to a device that another process or kernel driver is accessing. The program should include appropriate locking (exclusive access) for the device.
arg points to a struct pci_busdata, defined as follows:
struct pci_busdata { int bus_present; /* PCI present flag */ struct pci_businfo businfo; /* Bus info structure */ };All members are output parameters.
A bus_present
value of 0 indicates there are no
PCI buses in the system and the contents of the
pci_businfo
structure are undefined. A
bus_present
value of 1 indicates one or more
PCI buses have been found and the
pci_businfo structure will be filled in as
appropriate.
arg points to a struct pci_devicedata, defined as follows:
struct pci_devicedata{ unsigned short vend_id; /* Vendor ID */ unsigned short dev_id; /* Device ID */ unsigned short index; /* Number of matches */ int device_present; /* Device found flag */ struct pci_devinfo info; /* Device info structure */ };
vend_id
, dev_id
, and index
are input parameters. The device_present
integer
and pci_devinfo
structure are output parameters.
An index number n will return details of the nth device whose vendor and device IDs match the input. (Index numbering begins at 0.)
If the required device is not found,
device_present
will return as 0 and the
pci_devinfo structure is undefined. If the
device is found, device_present
will return as 1
and the pci_devinfo structure will be filled in
as appropriate.
arg points to a struct pci_classdata, defined as follows:
struct pci_classdata{ unsigned short base_class; /* Base class code */ unsigned short sub_class; /* Sub class code */ unsigned short index; /* Number of matches */ int device_present; /* Device found flag */ struct pci_devinfo info; /* Device info structure */ };The first three parameters
base_class
,
sub_class
, and index
are input
parameters; device_present
and info
are output parameters.
An index number n will return details of the nth device whose base and subclass codes match the input. (Index numbering begins at 0.)
If the required device is not found,
device_present
will return as 0 and the
pci_devinfo structure is undefined. If the
device is found, device_present
will return as 1,
and the pci_devinfo structure will be filled in
as appropriate.
arg points to a struct pci_specialdata, defined as follows:
struct pci_specialdata{ unsigned short busno; /* Bus number for cycle */ unsigned long busdata; /* Special cycle data */ };All members in the structure are input parameters.
Given the bus number and a 32-bit word (double word) of data, this ioctl will broadcast the data on the specified bus using a PCI special cycle.
arg points to a struct pci_configdata, defined as follows:
struct pci_configdata{ struct pci_devinfo info; /* Device info structure */ unsigned short size; /* Size of data to pass */ unsigned short reg; /* Register in config space */ int status; /* Completion status */ unsigned long data; /* Config space data */ };The first three members
info
, size
,
and reg
and are input parameters;
status
and data
are output parameters.
Information in the pci_devinfo structure is used
to select the correct device, then size
bytes
from reg
are read into data
. The
size
member may be 1, 2, or 4 bytes; the
reg
offset must be aligned correspondingly.
If the status
member returns as 1, then the
data
member is valid. If the status
member returns as 0, the register could not be read and the
data
member is undefined. A failure can occur if
the device was not found, the register was invalid, or the
register offset was incorrectly aligned.
arg points to a struct pci_configdata, as described under PCI_READ_CONFIG.
PCI_WRITE_CONFIG is similar to
PCI_READ_CONFIG in all respects except that
data
is an input parameter and the data is
written into the configuration space instead of being read
from it.
arg points to a struct pci_headerinfo, defined as follows:
struct pci_headerinfo{ unsigned short vend_id; /* Vendor ID */ unsigned short dev_id; /* Device ID */ unsigned short base_class; /* Base class code */ unsigned short sub_class; /* Sub class code */ unsigned short index; /* Number of matches */ int device_present; /* Device found flag */ struct pci_devinfo info; /* Device info structure */ };The first five members are input parameters;
device_present
and info
are output
parameters.
Given an index number n, this ioctl
will return details of the nth device whose
parameters match those specified in the input. Any of the
input parameters except index
may be wildcards,
which are indicated by the value 0xFFFF. Index numbering
begins at 0.
If a device matching the specified parameters is found,
device_present
will return as 1 and the
pci_devinfo structure will be filled in as
appropriate. If a device is not found,
device_present
will return as 0 and the
pci_devinfo structure is undefined.
arg points to a struct pci_baseinfo, defined as follows:
struct pci_baseinfo{ struct pci_devinfo info; /* Device info structure */ int status; /* Completion status */ unsigned long iobase; /* Un-mapped IO base address */ unsigned long mappedbase; /* Re-mapped IO base address */ };On entry,
iobase
contains the unmapped base
I/O address and the pci_devinfo
structure is filled in as appropriate. On exit,
mappedbase
contains the remapped base
I/O address. status
is set to 1 if the
remapping was successful; otherwise, status
is
set to 0.
size
value
was passed (size
must be a byte, word, or 32-bit
word), or the register alignment was not consistent with
the data size. Otherwise, an invalid ioctl
command was issued.
The following specifications may be ordered from the PCI Special Interest Group. Telephone 1 (800) 433-5177 within the United States, or (503) 696 8448 otherwise.
PCI Specification
PCI BIOS Specification
PCI System Design Guide
#include <assert.h> #include <fcntl.h> #include <sys/pci.h>main() { struct pci_devicedata devdata; struct pci_configdata configdata;
int fd = open("/dev/pci", O_RDWR); assert(fd >= 0);
devdata.vend_id = 0x1013; devdata.dev_id = 0x6001;
if (ioctl(fd, PCI_FIND_DEVICE, &devdata) < 0) { perror("FIND_DEVICE failed\n"); exit(1); }
if (devdata.device_present) { int i;
printf("index %d\n", devdata.index); printf("slot %d\n", devdata.info.slotnum); printf("func %d\n", devdata.info.funcnum); printf("bus %d\n", devdata.info.busnum);
configdata.info = devdata.info; configdata.size = 4;
for (i=0;i<0x40;i+=4) { configdata.reg = i; if (ioctl(fd, PCI_READ_CONFIG, &configdata) < 0) { perror("READ_CONFIG failed\n"); exit(1); } if ((i & 0xf) == 0) { printf("\n%04x: ", i); } if (configdata.status) { printf("%08x ", configdata.data); } else { perror("Bad status\n"); exit(1); } }
} else { printf("Card not found\n"); } printf("\n");
}