pciio_intr(D3)
pciio_intr: pciio_intr_alloc, pciio_intr_connect, pciio_intr_disconnect, pciio_intr_free - manage PCI Interrupts
As shipped in IRIX 6.5.5. Unchanged since IRIX 6.5.
NAME pciio_intr: pciio_intr_alloc, pciio_intr_connect, pciio_intr_disconnect, pciio_intr_free - manage PCI Interrupts SYNOPSIS #include <sys/PCI/pciio.h> pciio_intr_t pciio_intr_alloc( vertex_hdl_t vhdl, device_desc_t desc, pciio_intr_line_t lines, vertex_hdl_t owner) int pciio_intr_connect( pciio_intr_t intr, intr_func_t func, intr_arg_t arg, void *thread) void pciio_intr_disconnect(pciio_intr_t intr) void pciio_intr_free(pciio_intr_t intr) Arguments arg A parameter to pass to func() when this particular interrupt occurs, commonly a pointer to a driver-private data structure. desc A device descriptor, usually zero. func The function to perform interrupt service. intr The interrupt channel handle returned by pciio_intr_alloc(). lines Specifies one or more of the PCI Interrupt pins used by the device. owner An appropriate vertex handle to use when printing messages about this particular interrupt, and is usually a vertex created by the device driver. vhdl The PCI device connection point as passed to the driver attach() entry point. thread Reserved, should be NULL. DESCRIPTION When a device driver wishes to accept interrupt events from a device, the system needs to make sure that there is a path from the PCI interrupt pin to the appropriate CPU interrupt hardware. This is split into two separate phases, establishing the channel and connecting a service function, so that the service function can be changed or disconnected without losing the allocated hardware resources. The driver is responsible for connecting an interrupt handler when the device needs one, and for disconnecting the handler when it does not. The interrupt delivery mechanism depends on the address of the interrupt function. It is important to disconnect interrupts before a driver unloads, otherwise the PCI infrastructure might call a nonexistent function. (A driver cannot be auto-loaded when an interrupt occurs.) The necessary sequence of calls is based on the use of the driver entry points, as follows: reg() Driver registers to handle a class of PCI devices, triggering attach() calls. attach() Driver calls pciio_intr_alloc() to establishe interrupt connectivity between the device and the processor. The designated interrupts are disabled at this point. If interrupts can occur and are needed at this time, a call to pciio_intr_connect() enables interrupts and directs them to the designated handler. unload() The driver is to be unloaded automatically or by operator command. The driver text is going to be removed, so it is important for all interrupts to be disconnected. pciio_iterate() can be used to apply to each of the driver's connection points, a function that can calls pciio_intr_disconnect() as appropriate. It is not necessary or desirable to call pciio_intr_free() at this time. init() The device driver is being loaded or reloaded. It can again use pciio_iterate(), this time to call a function that re- connects interrupts to the new addresses of their service functions. No special logic is needed to avoid this at the initial load time, because pciio_iterate() is a no-operation when the device driver is not registered. detach() A device is being detached and will no longer be accessible. The driver calls both pciio_intr_disconnect() and pciio_intr_free() for this particular device. unreg() The device driver is shutting down. It calls pciio_driver_unregister(). This triggers a call to the detach() entry point for every attached device. Some devices do not require interrupt service when they are not open. Leaving an interrupt allocated but not connected keeps the interrupt disabled, possibly reducing impact on the system from handling interrupts from devices that do not actually need service. If this is the situation, then the scenario above may be somewhat simplified: attach() Allocate the interrupt to establish a connection and disable the interrupt. Only connect the interrupt if interrupts are required as part of device initialization; then disconnect it. open() If the interrupt is not yet connected, connect it. close() No processes have the device open; disconnect the interrupt when all pending I/O is complete or purged. unload() The driver is not called to unload when one of its devices is open, so no interrupts should be connected. detach() Devices are closed before detaching, so no interrupts should be connected. Specifying PCI Interrupt Lines The lines parameter is formed by or-ing together appropriate flags: PCIIO_INTR_LINE_A PCIIO_INTR_LINE_B PCIIO_INTR_LINE_C PCIIO_INTR_LINE_D EXAMPLES Here is how a typical PCI device driver might get interrupt service started. pcifoo_attach(vertex_hdl_t pconn_vhdl) { pciio_intr_t intr; ... /* This device uses both INTA and INTB, * and this driver wants both routed to * the same interrupt service function. */ intr = pciio_intr_alloc(pconn_vhdl, 0, PCIIO_INTR_LINE_A| PCIIO_INTR_LINE_B, pcifoo_vhdl); pciio_intr_connect(intr, pcifoo_intr, (intr_arg_t)pcifoo_soft, (void *)0); ... } SEE ALSO pciio(D3), pciio_config(D3), pciio_dma(D3), pciio_error(D3), pciio_get(D3), pciio_pio(D3). DIAGNOSTICS pciio_intr_alloc() returns a null value if it can not allocate memory. pciio_intr_connect() returns a zero for success or a negative value on failure. Since the channel is preallocated, the only interesting failure for this function is the attempt to use a null interrupt handle value.