Writing Device Drivers

gldm_intr() Entry Point

int prefix_intr(gld_mac_info_t * macinfo);

gldm_intr() is called when the device might have interrupted. Because interrupts can be shared with other devices, the driver must check the device status to determine whether it actually caused an interrupt. If the device that the driver controls did not cause the interrupt, then this routine must return DDI_INTR_UNCLAIMED. Otherwise, it must service the interrupt and should return DDI_INTR_CLAIMED. If the interrupt was caused by successful receipt of a packet, this routine should put the received packet into a STREAMS message of type M_DATA and pass that message to gld_recv().

gld_recv() will pass the inbound packet upstream to the appropriate next layer of the network protocol stack. The routine must correctly set the b_rptr and b_wptr members of the STREAMS message before calling gld_recv().

The driver should avoid holding mutex or other locks during the call to gld_recv(). In particular, locks that could be taken by a transmit thread must not be held during a call to gld_recv(): the interrupt thread that calls gld_recv() will in some cases carry out processing that includes sending an outgoing packet, resulting in a call to the driver's gldm_send() routine. If the gldm_send() routine were to try to acquire a mutex being held by the gldm_intr() routine at the time it calls gld_recv(), a panic occurs due to recursive mutex entry. If other driver entry points attempt to acquire a mutex that the driver holds across a call to gld_recv(), deadlock can result.

The interrupt code should increment statistics counters for any errors. This includes failure to allocate a buffer needed for the received data and any hardware-specific errors, such as CRC errors or framing errors.