'\"macro stdmacro
.if n .pH ddi_dki.untimeout @(#)untimeout	40.6 of 10/10/89
.\" Copyright 1989 AT&T
.de IX
.ie '\\n(.z'' .tm .Index: \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9	\\n%
.el \\!.IX \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9
..
.nr X
.if \nX=0 .ds x} untimeout D3DK "" "DDI/DKI" "\&"
.if \nX=1 .ds x} untimeout D3DK "" "DDI/DKI"
.if \nX=2 .ds x} untimeout D3DK "" "\&"
.if \nX=3 .ds x} untimeout "" "" "\&"
.TH \*(x}
.IX "\f4untimeout\fP(D3DK)"
.SH NAME
\f4untimeout\f1 \- cancel previous \f4timeout\f1(D3DK) function call
.SH SYNOPSIS
.nf
.na
\f4#include <sys/types.h>
.sp 0.5
int untimeout(int\f2 id\f4);\f1
.ad
.fi
.SH ARGUMENTS
.RS 0n 10
.IP "\f2id\f1" 10n
Identification value generated by a previous \f4timeout\f1 function
call.
.RE
.SH DESCRIPTION
\f4untimeout\f1 cancels a pending \f4timeout\f1(D3DK) request.
.SH RETURN VALUE
None
.SH LEVEL
Base or Interrupt
.SH SEE ALSO
\f2BCI Driver Development Guide\f1, Chapter 10, ``Synchronizing Hardware and Software Events''
.P
.na
\f4delay\f1(D3DK),
\f4biodone\f1(D3DK),
\f4biowait\f1(D3DK), 
\f4sleep\f1(D3DK),
\f4timeout\f1(D3DK),
\f4wakeup\f1(D3DK)
.ad
.SH EXAMPLE
.IX "\f4wakeup\fP(D3DK), example"
.IX "\f4untimeout\fP(D3DK), example"
.IX "\f4timeout\fP(D3DK), example"
.P
A driver may have to repeatedly 
request outside help from a computer operator.
The \f4timeout\f1 function is used 
to delay a certain amount of time
between requests.
However,
once the request is honored,
the driver will want
to
cancel the \f4timeout\f1 operation.
This is done with the \f4untimeout\f1
function.
.P
In a driver \f4open\f1(D2DK)
routine,
after the input arguments have been verified,
the status of the device is tested.
If the device is not on-line, a
message is displayed on the system console.
The driver schedules a \f4wakeup\f1(D3DK)
call and waits for five minutes (line 41).
If the device is still not ready,
the procedure is repeated.
.P
When the device is made ready,
an interrupt is generated.
The driver
interrupt handling routine notes there is a suspended process.
It cancels
the\f4 timeout\f1 request (line 59) and wakens the
suspended process (line 61).
.ne 4
.P
.nf
.ft 4
.ps 7
 1  struct  mtu_device  {   
 2                             /* layout of physical device registers */
 3          int      control;  /* physical device control word        */
 4          int      status;   /* physical device status word         */
 5          int      byte_cnt; /* number of bytes to be transferred   */
 6          paddr_t  baddr:    /* DMA starting physical address       */
 7  }; /* end device */
 8
 9  struct mtu     {            
10                             /* magnetic tape unit logical structure */
11         struct buf *mtu_head;  /* pointer to I/O queue head         */
12         struct buf *mtu_tail;  /* pointer to buffer I/O queue tail  */
13         int         mtu_flag;  /* logical status flag               */
14         int         mtu_to_id; /* time out ID number                */
             ...
15  }; /* end mtu */
16
17  extern struct mtu_device *mtu_addr[];      /* location of dev regs */
18  extern struct mtu         mtu_tbl[];    /* location of dev structs */
19  extern int    mtu_cnt;
      ...
20  mtu_open(dev, flag, type, c_ptr)
21      dev_t dev;
22  {
23      register struct mtu *dp;
24      register struct mtu_device *rp;
25      if ((getminor(dev) >> 3) > mtu_cnt) { /* if dev doesn't exist */
26          return(ENXIO);             /* then return error condition  */
27      } /* endif */
28
29      dp = &mtu_tbl[getminor(dev)];    /* get logical device struct */
30      if  (dp->mtu_flag & MTU_BUSY) != 0) {  /* if device is in use, */
31          return(EBUSY);                       /* return busy status */
32      } /* endif */
33
34      dp->mtu_flag = MTU_BUSY;   /* mark device in use & clear flags */
35      rp = xx_addr[getminor(dev) >> 3];          /* get device regs */
36      oldlevel2 = splhi();
37      while((rp->status & MTU_LOAD) == 0) { /* while tape not loaded */
38                                 /* display mount request on console */
39          cmn_err(CE_NOTE, "!Tape MOUNT, drive %d", minor(dev) & 0x3);
40          dp->mtu_flag |= MTU_WAIT;   /* indicate process suspended  */
41          dp->mtu_to_id = timeout(wakeup, dp, 5*60*HZ); /* wait 5 min */
42          if (sleep(dp, (PCATCH | PZERO+2)) == 1){/*wait on tape load */
43                                  /* if user aborts process, release */
44              dp->mtu_flag = 0;     /* tape device by clearing flags */
45              untimeout(dp->mtu_to_id);
46              splx(oldlevel2);
47           } /* endif */
48      } /* endwhile */
49      splx(oldlevel2);
50  } /* end mtu_open */
       ...
51  mtu_int(cntr)
52      int cntr;              /* controller that caused the interrupt */
53  {
54  register struct mtu_device *rp = xx_addr[cntr]; /* get device regs */
55  register struct mtu *dp = &mtu_tbl[cntr << 3 | (rp->status & 0x3)];
       ...
56     if ((dp->mtu_flag & MTU_WAIT) != 0){ /* if process is suspended */
57                                          /* waiting for tape mount, */
58          untimeout(dp->mtu_to_id);        /* cancel timeout request */
59          dp->flag &= ~MTU_WAIT;                  /* clear wait flag */
60          wakeup(dp);                    /* awaken suspended process */
61     } /* endif */
       \&...
.ps
.ft 1
.fi
.P
.FG "untimeout \- cancel previous timeout(D3DK) call"
