strategy -- start an old-style block I/O transfer

Synopsis (Not in current DDI version)

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

int prefixstrategy(buf_t *bp);


The driver's strategy( ) entry point routine is called to read and write blocks of data on the block device. strategy may also be called directly or indirectly (via a call to the physiock(D3) function) to support the raw character interface of a block device from read(D2), write(D2) or ioctl(D2). The strategy routine's responsibility is to set up and initiate the data transfer.


Pointer to the buffer header structure.

Return values

Ignored. Errors are returned by using the bioerror(D3) function to mark the buffer as being in error.


This entry point is required in all block device drivers. All read/write I/O requests for block devices come through this entry point. It is only called when the device is open.

The strategy( ) routine is a named entry point and must be defined as a global symbol.

The starting device offset for the I/O transfer is given by the bp->b_blkno and bp->b_blkoff members of the buf(D4) structure and is guaranteed to be non-negative. The number of bytes to transfer is given by the bp->b_bcount member. If the driver informs the core kernel of its device's size with the size(D2) routine, the special device offset range is guaranteed not to extend beyond the end of the device.

If the driver does not report its device's size, the driver itself must check for end-of-media itself. It does this by setting the bp->b_resid member to the number of bytes beyond the end of the device. It must also call the bioerror(D3) function to fail the transfer with the ENXIO error number, unless the B_READ flag is set in the bp->b_flags member and the starting device offset is exactly at the end of the device.

Typically, the driver calls the buf_breakup(D3) function from its strategy routine to ensure that the transfer data buffer meets the requirements of the driver and its device.

If there is any valid data to transfer, the driver may either start the device I/O immediately or queue it for later processing. The driver then returns from this entry point routine. At a later time, when the I/O has completed or failed, the driver must call the biodone(D3) function to inform the caller of the completion. If the request does not actually require any I/O, the driver may call biodone( ) before returning.

Before calling biodone( ), the driver must reflect the status of the transfer into the buffer header. It must set the bp->b_resid member to the number of bytes not transferred for any rason. If no bytes were transferred, bp->b_resid must be set to the initial value of the bp->b_bcount member; if all of the data bytes were transferred, bp->b_resid must be set to 0. If some portion of the data failed to be transferred because of some error condition, the appropriate error number from errnos(D5) must be stored in the buffer header with bioerror(D3).

See the description of the b_addrtype member of the buf(D4) structure for a description of how to access the actual transfer data in the buffer.

Context and synchronization

Blockable context. The driver can block but cannot do operations such as copyout(D3) that require access to the requesting process's address space.


Synchronization constraints

The strategy entry point has the necessary context to sleep, but it cannot assume it is called from the same context of the process that initiated the I/O request. Furthermore, the process that initiated the I/O might not even be in existence when the strategy routine is called.

Hardware applicability


Version applicability

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

External dependencies

Named entry point routines must be declared in the driver's Master(DSP/4dsp) file. The declaration for this entry point is $entry strategy.

Differences between versions

Starting with DDI version 8, the strategy(D2) entry point is replaced by the biostart(D2) entry point routine.

In DDI versions 1, 2, and 4, the bioerror(D3) function is not supported, so errors must be reported by setting the B_ERROR flag in the b_error member of the buf(D4) structure and setting the bp_b_resid member equal to the number of bytes not transferred (or to 0 if all the bytes were transferred).


biodone(D3), bioerror(D3), biowait(D3), bp_mapin(D3), buf(D4), devflag(D1), errnos(D5), getnextpg(D3), physiock(D3), pptophys(D3), read(D2), size(D2), write(D2)
19 June 2005
© 2005 The SCO Group, Inc. All rights reserved.
OpenServer 6 and UnixWare (SVR5) HDK - June 2005