'\"macro stdmacro
.if n .pH ddi_dki.biodone @(#)biodone	40.7 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} biodone D3DK "" "DDI/DKI" "\&"
.if \nX=1 .ds x} biodone D3DK "" "DDI/DKI"
.if \nX=2 .ds x} biodone D3DK "" "\&"
.if \nX=3 .ds x} biodone "" "" "\&"
.TH \*(x}
.SH NAME
\f4biodone\f1 \- release buffer after block I/O and wakeup processes
.IX "\f4biodone\fP(D3DK)"
.SH SYNOPSIS
.nf
.na
\f4#include <sys/types.h>
#include <sys/buf.h>
.sp 0.5
void biodone(\f4struct buf *\f1\f2bp\f4);\f1
.ad
.fi
.SH ARGUMENT
.RS 0n
.IP "\f2*bp\f1" 10n
Pointer to the buffer header structure defined in \f4buf.h\f1.  This
is the address of the buffer header associated with the buffer where the
I/O occurred.
.RE
.SH DESCRIPTION
The \f4biodone\f1 function is called by either the driver
\f4int\f1(D2D) or \f4strategy\f1(D2DK) routines when a block I/O
request is complete.  In general, \f4biodone\f1 awakens sleeping
processes waiting for the I/O to complete, sets the \f4B_DONE\f1
flag in the \f4buf\f1 structure \f4b_flags\f1 field, and releases
the block if the I/O is asynchronous.
.P
For drivers that wish to make multiple I/O requests without
releasing and reallocating a buffer header for each individual
request, \f4biodone\fP provides the capability to check for an
additional function to be called before the buffer header is
released.  Additional routines to be called from \f4biodone\fP are
referenced by the \f4(*b_biodone)\fP field of the \f4buf\fP
structure.
.P
\f4biodone\f1 performs the following functions in the order presented:
.IP
checks the \f4(*biodone)\fP field of the \f4buf\fP structure for
additional routines to be called.  If an additional routine is
referenced, it is called and the functions listed below are not completed.
.IP
awakens the process(es) that called \f4sleep\f1(D3DK) to wait for the buffer
header if I/O is synchronous
.IP
releases the block if I/O is asynchronous and awakens processes awaiting
asynchronous I/O
.IP
marks \f4b_flags\f1 of buffer with \f4B_DONE\f1
.SH "RETURN VALUE"
None
.SH LEVEL
Base or Interrupt
.SH SEE ALSO
\f2BCI Driver Development Guide\f1, Chapter 9, ``Synchronizing Hardware and Software Events''
.P
.na
\f4biowait\f1(D3DK),
\f4buf\f1(D4DK),
\f4delay\f1(D3DK),
\f4int\fP(D3D),
\f4strategy\fP(D3DK),
\f4sleep\f1(D3DK),
\f4timeout\f1(D3DK),
\f4untimeout\f1(D3DK),
\f4wakeup\f1(D3DK)
.ad
.SH EXAMPLE
Generally, the first validation test performed by any block device
\f4strategy\f1(D2DK) routine is a check for an end-of-file (EOF)
condition.  The \f4strategy\f1 routine is responsible for determining
an EOF condition when the device is accessed directly.  If a
\f4read\f1 request is made for one block beyond the limits of the
device (line 10), it will report an EOF condition.  Otherwise, if
the request is outside the limits of the device, the routine will
report an error condition.  In either case, report the I/O operation
as complete (line 27). 
.ne 4
.P
.nf
.ft 4
.ps 7
 1   #define RAMDNBLK    1000            /* Number of blocks in RAM disk */
 2   #define RAMDBSIZ     512            /* Number of bytes per block */
 3   char ramdblks[RAMDNBLK][RAMDBSIZ];  /* Array containing RAM disk */
 4
 5   ramdstrategy(bp)
 6           register struct buf *bp;
 7   {
 8           register daddr_t blkno = bp->b_blkno;   /* get block number */
 9
10           if (blkno < 0 || blkno >= RAMDNBLK) {
11                 /* 
12                  * If requested block is outside RAM disk
13                  * limits, test for EOF which could result
14                  * from a direct (physiock) request.
15                  */ 
16                if (blkno == RAMDNBLK && bp->b_flags & B_READ) {
17                  /*
18                   * If read is for block beyond RAM disk
19                   * limits, mark EOF condition.
20                   */
21                   bp->b_resid -= bp->b_bcount;/* compute return value */
22
23                } else {                      /* I/O attempt is beyond */
24                   bp->b_error = ENXIO;       /*    limits of RAM disk */
25                   bp->b_flags |= B_ERROR;    /* return error */
26                } /* endif */
27                biodone(bp);             /* mark I/O complete (B_DONE) */
28                  /*
29                   * Wake any processes awaiting this I/O 
30                   * or release buffer for asynchronous
31                   * (B_ASYNC) request.
32                   */
33                return;
34           } /* endif */
            \&...
.ps
.ft 1
.fi
