biodone -- release buffer after block I/O and wakeup processes


   #include <sys/types.h>
   #include <sys/buf.h>
   #include <sys/ddi.h>

void biodone(buf_t *bp);


The biodone( ) function is called by the driver to indicate that block I/O associated with the buffer header bp is complete, and that it can be reused.


Pointer to the buf(D4) buffer header structure.

Return values



biodone( ) is usually called from the driver's biostart(D2) routine or I/O completion handler (usually intr(D2)).

If a driver (or the kernel) had specified an iodone handler by initializing the b_iodone member of the buf(D4) structure to the address of a function, that function is called with the single argument, bp. Then biodone( ) returns.

If a b_iodone handler had not been specified, biodone( ) marks the buffer as completed. Then, if the B_ASYNC flag is set, the buffer is released back to the system. If the B_ASYNC flag is not set, any processes waiting for the I/O to complete using biowait(D3) are unblocked (awakened).

If the buffer was allocated with the getrbuf(D3) function, the driver must have specified a b_iodone handler.

Context and synchronization

Non-blockable, interrupt, user, or blockable context.


Generally, the first validation test performed by any block device's strategy( ) routine is a check to verify the bounds of the I/O request. If a read( ) request is made for one block beyond the limits of the device (line 8), it reports an end-of-media condition (line 10). Otherwise, if the request is outside the limits of the device, the routine reports an error condition (line 12). In either case, the I/O operation is completed by calling biodone( ) (line 14) and the driver returns.

This example is for DDI drivers prior to version 8. For DDI 8, use the biostart(D2) entry point rather than strategy( ). biostart( ) does not need to check for end-of-media because the kernel handles this using the size value returned by the DI_SIZE parameter from devinfo(D2), unless the device does not support DI_SIZE.

    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 ramdstrategy(bp) 5 struct buf *bp; 6 { 7 daddr_t blkno = bp->b_blkno;

8 if ((blkno < 0) || (blkno >= RAMDNBLK)) { 9 if ((blkno == RAMDNBLK) && (bp->b_flags & B_READ)) { 10 bp->b_resid = bp->b_bcount; /* nothing read */ 11 } else { 12 bioerror(bp, ENXIO); 13 } 14 biodone(bp); 15 return; 16 } . . .

Hardware applicability


Version applicability

ddi: 1, 2, 3, 4, 5, 5mp, 6, 6mp, 7, 7mp, 7.1, 7.1mp, 8, 8mp

Differences between versions

For DDI versions prior to version 8, biodone( ) is called from the driver's strategy(D2) routine rather than biostart( ).

DDI versions 1, 2, and 4 do not support the bioerror(D3) function. Drivers written for these versions can use the following code to replace the call to bioerror( ) in line 12 of the example above:

   bp->b_error = ENXIO;
   bp->b_flags |= B_ERROR;


biocanblock(D3), bioerror(D3), biowait(D3), brelse(D3), buf(D4) freerbuf(D3), getrbuf(D3), intr(D2), strategy(D2)
19 June 2005
© 2005 The SCO Group, Inc. All rights reserved.
OpenServer 6 and UnixWare (SVR5) HDK - June 2005