/************************************************************************
*									*
*				Copyright 1984				*
*			VALID LOGIC SYSTEMS INCORPORATED		*
*									*
*	This listing contains confidential proprietary information	*
*	which is not to be disclosed to unauthorized persons without	*
*	written consent of an officer of Valid Logic Systems 		*
*	Incorporated.							*
*									*
*	The copyright notice appearing above is included to provide	*
*	statutory protection in the event of unauthorized or 		*
*	unintentional public disclosure.				*
*									*
************************************************************************/

/*\fP
 * Ram Disk driver
 */


#include "../h/param.h"
#include "../h/types.h"
#include "../h/buf.h"
#include "../h/systm.h"
#include "../h/dir.h"
#include "../h/file.h"
#include "../h/inode.h"
#include "../h/ioctl.h"
#include "../h/user.h"
#include "../h/uio.h"
#include "../h/kernel.h"
#include "../h/vm.h"
#include "../machine/mem.h"
#include "../machine/param.h"

short	ramdiskdebug = 0;
short	ramdiskenabled = 1;

#define	RAMD_NBLKS	2048


ramdstrategy(bp)
register struct buf *bp;
{
	register u_int 	v;
	register int 	o, nblk, retval;
	caddr_t		srcaddr, destaddr;

	if( !ramdiskenabled )
	{
		bp->b_flags |= B_ERROR;
		iodone(bp);
		return;
	}

	if( ramdiskdebug )
	{
		printf( "in ramdstrategy: attempting to %s %d bytes, starting at block %d\n", bp->b_flags & B_READ ? "read" : "write", bp->b_bcount, bp->b_blkno );
		printf( "B_PHYS is %d, bp->b_bufsize is %d, bp->b_un.b_addr is 0x%x\n", bp->b_flags & B_PHYS, bp->b_bufsize, bp->b_un.b_addr );
	}

	nblk = bp->b_bcount >> DEV_BSHIFT;
	if (nblk == 0) 
	{
		if( ramdiskdebug )
			printf("ramdstrategy: bcount %d, nblk %d, bcount < DEV_BSIZE.\n", bp->b_bcount, nblk );
		bp->b_resid = bp->b_bcount;
		iodone(bp);
		return;
	}

	if(bp->b_blkno < 0 || bp->b_blkno + nblk > RAMD_NBLKS)
	{
		if( ramdiskdebug )
			printf("ramdstrategy: bad blkno %d, bcount %d, nblk %d.\n", bp->b_blkno, bp->b_bcount, nblk );
		bp->b_flags |= B_ERROR;
		iodone(bp);
		return;
	}

	v = btop(boardmap[minor(bp->b_dev)].paddr + ( bp->b_blkno * DEV_BSIZE ) );
	*(int *)mmap = v | PG_V | ( bp->b_flags & B_READ ? PG_KR : PG_KW);

#ifdef s32
	setsysmap(btop(vmmap), mmap, 1);
#else s32
	mtpr(TBIS, vmmap);
#endif s32

	o = (int) (boardmap[minor(bp->b_dev)].paddr + ( bp->b_blkno * DEV_BSIZE ) ) & PGOFSET;
	

	if( bp->b_flags & B_READ )
	{
		srcaddr = (caddr_t)&vmmap[o];
		destaddr = (caddr_t) bp->b_un.b_addr;
	}
	else
	{
		destaddr = (caddr_t)&vmmap[o];
		srcaddr = (caddr_t) bp->b_un.b_addr;
	}
	if( ramdiskdebug )
		printf( "ramdstrategy: about to transfer %d blocks (%d bytes) from 0x%x to 0x%x\n", nblk, nblk*DEV_BSIZE, srcaddr, destaddr );


	bcopy( srcaddr, destaddr, nblk*DEV_BSIZE );


	if( ramdiskdebug )
		printf( "ramdstrategy: transferred %d blocks (%d bytes) from 0x%x to 0x%x\n", nblk, nblk*DEV_BSIZE, srcaddr, destaddr );

	bp->b_resid = 0;

	iodone(bp);

	return;
}
