pci(HW)


pci -- PCI bus device

Description

The pci driver provides access to the PCI bus from user memory space through a set of IOCTL commands that can be issued to the /dev/pci special device file.

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.

Supported ioctls

The following ioctl(S) commands are available, as defined in <sys/pci.h>:

PCI_BUS_PRESENT
Determine the presence of a PCI local bus.

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.


PCI_FIND_DEVICE
Find a PCI device given its vendor and device IDs.

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.


PCI_FIND_CLASS
Find a PCI device given its class code.

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.


PCI_SPECIAL_CYCLE
Generate a PCI special cycle.

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.


PCI_READ_CONFIG
Read a byte, word, or 32-bit word of configuration space data.

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.


PCI_WRITE_CONFIG
Write a byte, word, or 32-bit word of configuration space data.

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.


PCI_SEARCH_BUS
Search the system's PCI buses for a device that matches some or all of the input parameters.

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.


PCI_TRANS_BASE
Allow remapping of base I/O address for devices connected to auxiliary PCI buses.

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.

Diagnostics

The following values may be returned in errno if an ioctl call fails:

[EFAULT]
The data transfer failed for some reason; for example, an invalid pointer was passed.

[EINVAL]
For PCI_READ_CONFIG and PCI_WRITE_CONFIG, an invalid 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.

Files


/dev/pci
special device file to access PCI bus

/usr/include/sys/pci.h
definitions of PCI ioctls and structures

See also

Information about developing device drivers for PCI devices is available at the consolidated Hardware and Driver Development (HDK) Web Page The documentation for the Consolidated Hardware Development Kit (covers SCO OpenServer, Open UNIX 8, and UnixWare 7) can be viewed at SCO OpenServer Documentation Web Pages Note especially the following manual pages: pci_buspresent(D3oddi), pci_findclass(D3oddi), pci_finddevice(D3oddi), pci_read(D3oddi), pci_search(D3oddi), pci_specialcycle(D3oddi), pci_write(D3oddi) pci(D5)

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

Examples

The following simple test program illustrates how to use these IOCTLs. The code displays the first 16 words of PCI configuration space for the Cirrus Logic (PCI ID 0x1013) audio device (ox6001) as words with no attempt at formatting or decoding the content. It is provided to illustrate how to access the PCI bus, not how to use the resulting data.
   #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");

}


© 2005 The SCO Group, Inc. All rights reserved.
SCO OpenServer Release 6.0.0 -- 03 June 2005