Example 9–6 shows the interrupt handling for the printer driver.
lpintr is the driver-interrupt handler registered by the attach routine.
lpout takes a single character from the queue and sends it to the printer. For convenience, the message currently being output is stored in lp->msg in the per-instance structure. This assumes that the message is called with the mutex held.
lpoutchar sends a single character to the printer (in this case the system console using cmn_err(9F)) and interrupts when complete. Of course, hardware would generate a hard interrupt, so the call to ddi_trigger_softintr(9F) would be unnecessary.
/* Device interrupt routine */static uint lpintr(caddr_t lp) /* minor device number of lp */ { struct lp *lpp = (struct lp *)lp; mutex_enter(&lpp->lp_lock); if (!(lpp->flags & BUSY)) { mutex_exit(&lpp->lp_lock); return (DDI_INTR_UNCLAIMED); } lpp->flags &= ~BUSY; lpout(lpp); mutex_exit(&lpp->lp_lock); return (DDI_INTR_CLAIMED); } /* Start output to device - used by put procedure and driver */ static void lpout( struct lp *lp) { mblk_t *bp; queue_t *q; q = lp->qptr; loop: if ((bp = lp->msg) == NULL) { /*no current message*/ if ((bp = getq(q)) == NULL) { lp->flags &= ~BUSY; return; } if (bp->b_datap->db_type == M_IOCTL) { /* lpdoioctl(lp, bp); */ goto loop; } lp->msg = bp; /* new message */ } if (bp->b_rptr >= bp->b_wptr) { /* validate message */ bp = lp->msg->b_cont; lp->msg->b_cont = NULL; freeb(lp->msg); lp->msg = bp; goto loop; } lpoutchar(lp, *bp->b_rptr++); /*output one character*/ lp->flags |= BUSY; } static void lpoutchar( struct lp *lp, char c) { cmn_err(CE_CONT, “%c”, c); ddi_trigger_softintr(lp->siid); }