V7M/sys/dev/hs.c

Compare this file to the similar file:
Show the results in this format:

/*
 * RS03/04 disk driver
 *
 * This is a converted version six RS03/4 driver.
 * It has worked, but it has been modified slightly
 * and those modifications have NOT been tested !
 * The changes were to improve the block number overflow
 * test in hsstrategy and to use rh70hs in place of cputype.
 *
 * Fred Canter 8/8/81
 */

#include "../h/param.h"
#include "../h/systm.h"
#include "../h/buf.h"
#include "../h/conf.h"
#include "../h/dir.h"
#include "../h/user.h"


struct device {
	int	hscs1;	/* Control and Status register 1 */
	int	hswc;	/* Word count register */
	int	hsba;	/* UNIBUS address register */
	int	hsda;	/* Desired address register */
	int	hscs2;	/* Control and Status register 2 */
	int	hsds;	/* Drive Status */
	int	hser;	/* Error register */
	int	hsas;	/* not used */
	int	hsla;	/* not used */
	int	hsdb;	/* not used */
	int	hsmr;	/* not used */
	int	hsdt;	/* not used */
	int	hsbae;	/* 11/70 bus extension */
};

#define	HSADDR	((struct device *) 0172040)

struct	buf	hstab;
struct	buf	rhsbuf;


#define ERR	040000	/* hscs1 - composite error */

#define GO	01
#define RCLR	010
#define	DRY	0200	/* hsds - Drive Ready */
#define	WCOM	060
#define	RCOM	070
#define	IENABLE	0100

hsstrategy(bp)
register struct buf *bp;
{
	register int mblks;
	long sz;


	if((bp->b_flags&B_PHYS) && !rh70hs)
		mapalloc(bp);
	sz = bp->b_bcount;
	sz = (sz+511) >> 9;
	mblks = 1024; /* RJS03 */
	if(minor(bp->b_dev) >= 8)
		mblks = 2048; /* RJS04 */
	if((bp->b_blkno < 0) || ((bp->b_blkno + sz) > mblks)) {
		u.u_error = ENXIO;
		bp->b_flags |= B_ERROR;
		iodone(bp);
		return;
	}
	bp->av_forw = 0;
	spl5();
	if (hstab.b_actf==0)
		hstab.b_actf = bp; else
		hstab.b_actl->av_forw = bp;
	hstab.b_actl = bp;
	if (hstab.b_active==0)
		hsstart();
	spl0();
}

hsstart()
{
	register struct buf *bp;
	register addr;
	register unit;

	if ((bp = hstab.b_actf) == 0)
		return;
	hstab.b_active++;
	addr = bp->b_blkno;
	if(minor(bp->b_dev) < 8)
		addr <<= 1; /* RJS03 */
	HSADDR->hscs2 = minor(bp->b_dev) & 07;
	HSADDR->hsda = addr << 1;
	HSADDR->hsba = bp->b_un.b_addr;

	if(rh70hs)
		HSADDR->hsbae = bp->b_xmem;
	HSADDR->hswc = -(bp->b_bcount>>1);
	unit = ((bp->b_xmem&3) << 8) | IENABLE | GO;
	if(bp->b_flags & B_READ)
		unit |= RCOM; else
		unit |= WCOM;
	HSADDR->hscs1 = unit;
}

hsintr()
{
	register struct buf *bp;

	if (hstab.b_active == 0)
		return;
	bp = hstab.b_actf;
	hstab.b_active = 0;
	if(HSADDR->hscs1 & ERR){	/* error bit */
		deverror(bp, HSADDR->hscs2, HSADDR->hser);
		HSADDR->hscs1 = RCLR|GO;
		if (++hstab.b_errcnt <= 10) {
			hsstart();
			return;
		}
		bp->b_flags |= B_ERROR;
	}
	hstab.b_errcnt = 0;
	hstab.b_actf = bp->av_forw;
	iodone(bp);
	hsstart();
}

hsread(dev)
{

	physio(hsstrategy, &rhsbuf, dev, B_READ);
}

hswrite(dev)
{

	physio(hsstrategy, &rhsbuf, dev, B_WRITE);
}