/* pointer to device registers */ volatile struct vdk_device *vdk_device; struct buf *vdk_curbp /* current buffer */ caddr_t vdk_curaddr; /* current address to transfer */ int vdk_curcount; vdkstrategy(bp) struct buf *bp; { ... vdk_curbp = bp; bp->b_resid = bp->b_bcount; /* * Initialize the current transfer address and count. * The first transfer must finish the rest of the * page, but do no more than the total byte count. */ vdk_curaddr = bp->b_un.b_addr; vdk_curcount = NBPC - ((unsigned int)vdk_curaddr & (NBPC-1)); if (bp->b_resid < vdk_curcount) vdk_curcount = bp->b_resid; /* Tell the device starting physical address, count, * and direction */ vdk_device->startaddr = kvtophys(vdk_curaddr); vdk_device->count = vdk_curcount; if (bp->b_flags & B_READ) == 0) vdk_device->direction = VDK_WRITE; else vdk_device->direction = VDK_READ; vdk_device->command = VDK_GO; vdk_curaddr += vdk_curcount; biowait(bp); ... } vdkintr(unit) int unit; { int count, error; register struct buf *bp = vdk_curbp; ... if(error) { bioerror (bp,EIO); biodone(bp); return; } /* On successful transfer of last chunk, continue * if necessary. */ vdk_curaddr -= vdk_curcount; if (bp->b_resid > 0) { count = (bp->b_resid < NBPC ? bp->b_resid : NBPC); vdk_device->startaddr = kvtophys(vdk_curaddr); vdk_device->count = count; if (bp->b_flags & B_READ) == 0) vdk_device->direction = VDK_WRITE; else vdk_device->direction = VDK_READ; vdk_device->command = VDK_GO; vdk_curaddr += count; } else { biodone(bp); } ... }