Next | Prev | Up | Top | Contents | Index

VME Interrupt Handler

Your driver module must contain a routine of the form drvintr(), where drv is the driver prefix. When the device generates an interrupt, the general VME interrupt handler calls your driver's drvintr() routine.

When the VME interrupt handler calls your drvintr(), it passes it the value registered with the vme_ivec_set() routine for the device. Within your drvintr() routine, you must set flags to indicate the state of the transfer and to wake any sleeping processes waiting for the transfer to complete. Usually, the interrupt routine calls biodone() to indicate that an I/O transfer for the buffer is complete.

Caution: Interrupt routines (drvintr()) must not try to sleep themselves by using biowait(), sleep(), psema(), or delay() kernel calls. With the new dynamic interrupt vector allocation scheme, the argument passed to the individual drvintr() is arg, which is set by vme_ivec_set() in edtinit(). arg can be an index, a controller number, the address, or any argument that the driver wants to pass to interrupt the service routine.

The IRIX 5.x and 6.0 vme_ivec structure is shown below:

struct vme_ivec {
    int   (*vm_intr)(int);
    int    vm_arg;
}vme_ivec[ADAPTER][MAX_VME_VECTS];

Note: Although the prototype for the VME interrupt handler routine in the vme_intrs (field v_vintr) and vme_ivec (field vintr) structures indicates that it returns an integer value, the return value is not used. The prototype should indicate that the function is of type void*. It was left unchanged to avoid breaking existing VME device drivers. To support the loadable device drivers, multiple adapters, and multiple interrupt vectors, the vem_ivec table is changed to be dynamically allocated at system boot time. The size depends on the number of VME adapters currently supported by the running system. After the table is allocated, the kernel fills the entries for the devices specified in the irix.sm file.


Next | Prev | Up | Top | Contents | Index