pciio(D3)
pciio: pciio_driver_register, pciio_driver_unregister, pciio_iterate, pciio_reset - control PCI driver infrastructure
As shipped in IRIX 6.5.7. Unchanged since IRIX 6.5.
NAME pciio: pciio_driver_register, pciio_driver_unregister, pciio_iterate, pciio_reset - control PCI driver infrastructure SYNOPSIS #include <sys/PCI/pciio.h> int pciio_driver_register ( pciio_vendor_id_t vendor_id, pciio_device_id_t device_id, char *driver_prefix, unsigned flags); void pciio_driver_unregister (char *driver_prefix); void pciio_iterate ( char *driver_prefix, pciio_iter_f *func); void pciio_reset (vertex_hdl_t pconn); Arguments vendor_id device_id Values that the PCI device will present in its configuration space as its vendor and device ID codes. driver_prefix The prefix string for the driver's standard entry points as configured in /var/sysgen/system. The infrastructure uses this prefix to locate the driver's cdevsw entry, in order to call the driver's attach and detach entry points. flags Normally passed as zero. func Address of a function to be applied to each of the connection points attached by this driver. pconn is an appropriate PCI connection point. DESCRIPTION The PCI infrastructure is a package of kernel services used by drivers for PCI devices to set up services for their devices. These services include: o Locating all instances of the device in the system (documented in this page). o Manipulating the PCI configuration space for the device (see pciio_config(D3)). o Constructing physical addresses to use for PIO access to the device (see pciio_pio(D3)). o Constructing PCI addresses for the device to use for DMA access to memory (see pciio_dma(D3)). o Arranging for a function to be called when the device requests interrupt service (see pciio_intr(D3)). o Arranging for a function to be called when an error occurs during PIO to, or DMA from the device (see pciio_error(D3)). o Accessing useful fields in some otherwise opaque data structures (see pciio_get(D3)). Driver Registration pciio_driver_register() is used by drivers to inform the infrastructure that they are interested in all PCI devices designated by specified device and vendor ID numbers. The infrastructure associates the specified ID numbers with the specified device driver prefix. When a device with these IDs is discovered, the infrastructure calls the attach entry point with that driver prefix, passing the hardware graph connection point vertex as the only parameter. This connection point is used in most calls to the infrastructure to identify the PCI device of interest. A loadable device driver calls pciio_driver_register() from its reg() entry point. A driver prelinked into the kernel should also make the call from reg() for consistency, but may call from the init() entry point if necessary. Device drivers may make multiple calls with different vendor and device ID numbers, representing several compatible PCI devices. Wildcard values PCIIO_VENDOR_ID_NONE and PCIIO_DEVICE_ID_NONE may be used if cards from any vendor or cards with any device code are of supported. When both vendor and device are wildcarded, the attach() routine is called for every PCI device connected to the system. When a loadable device driver calls pciio_driver_register(), one or more calls to the driver's attach() function can occur before the infrastructure returns control to the caller. On some large systems, the attach() calls can be executed by other threads and possibly on other processors, concurrently with continued execution of the reg() entry point. pciio_driver_unregister() should be called by any unloadable device driver, from within the driver's unreg() entry point. This will trigger calls to the driver's detach() entry point, and remove the association between the driver and any vendor and device IDs. Connection Point Iteration It is sometimes important for driver code to be able to go back and revisit each connection point that was passed to its attach() entry point; for example to disconnect interrupt and error handling functions before the driver unloads, or to reconnect these handlers after the driver is reloaded. pciio_iterate() provides a quick mechanism to have a private function called with each connection point that the infrastructure has matched with the specified driver. On large systems, the calls to func() can take place in multiple separate threads on multiple processors, so the function must use appropriate locking when accessing driver-global structures. Resetting a PCI card pciio_reset() is used to attempt to activate the PCI Reset line connected to a specific card without affecting other devices on the PCI bus. When this can be done, the device is reset and basic configuration information is reloaded. EXAMPLES Here is how a typical driver might make use of these functions: static char pcifoo_prefix[] = "pcifoo_"; static char pcifoo_edge[] = "foo"; pcifoo_init(void) { /* the first time through, we are not * registered, so this is a no-op. * after that, it triggers reload_me. */ pciio_iterate(pcifoo_prefix, pcifoo_reload_me); } pcifoo_unload(void) { ... pciio_iterate(pcifoo_prefix, pcifoo_unload_me); ... } pcifoo_reg(void) { pciio_driver_register( PCIFOO_VENDOR_ID, PCIFOO_DEVICE_ID, pcifoo_prefix, 0); } pcifoo_unreg(void) { pciio_driver_unregister(pcifoo_prefix); } pcifoo_reload_me(vertex_hdl_t conn) { vertex_hdl_t vhdl; pcifoo_soft_t pcifoo_soft; if (GRAPH_SUCCESS != hwgraph_traverse(conn, pcifoo_edge, &vhdl)) return; pcifoo_soft = device_info_get(vhdl); if (!pcifoo_soft) return; if (pcifoo_soft->intr) pciio_intr_connect( pcifoo_soft->intr, pcifoo_intr, pcifoo_soft); } pcifoo_unload_me(vertex_hdl_t conn) { vertex_hdl_t vhdl; pcifoo_soft_t pcifoo_soft; if (GRAPH_SUCCESS != hwgraph_traverse(conn, pcifoo_edge, &vhdl)) return; pcifoo_soft = device_info_get(vhdl); if (pcifoo_soft->intr) pciio_intr_disconnect(pcifoo_soft->intr); } SEE ALSO pciio_config(D3), pciio_dma(D3), pciio_error(D3), pciio_get(D3), pciio_intr(D3), pciio_pio(D3).