MiniUnix/usr/sys/dev/hs.c
#
/*
*/
/*
* RS03/04 disk driver
*/
#include "../param.h"
#include "../buf.h"
#include "../conf.h"
#include "../user.h"
struct {
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 */
};
struct devtab hstab;
struct buf rhsbuf;
#define HSADDR 0172040
#define ERR 040000 /* hscs1 - composite error */
#define GO 01
#define RCLR 010
#define DRY 0200 /* hsds - Drive Ready */
hsstrategy(abp)
struct buf *abp;
{
register struct buf *bp;
register mblks;
bp = abp;
mblks = 1024; /* RJS03 */
if(bp->b_dev.d_minor >= 8)
mblks = 2048; /* RJS04 */
if(bp->b_blkno >= mblks) {
bp->b_flags =| B_ERROR;
iodone(bp);
return;
}
bp->av_forw = 0;
spl5();
if (hstab.d_actf==0)
hstab.d_actf = bp; else
hstab.d_actl->av_forw = bp;
hstab.d_actl = bp;
if (hstab.d_active==0)
hsstart();
spl0();
}
hsstart()
{
register struct buf *bp;
register addr;
if ((bp = hstab.d_actf) == 0)
return;
hstab.d_active++;
addr = bp->b_blkno;
if(bp->b_dev.d_minor < 8)
addr =<< 1; /* RJS03 */
HSADDR->hscs2 = bp->b_dev.d_minor & 07;
rhstart(bp, &HSADDR->hsda, addr<<1, &HSADDR->hsbae);
}
hsintr()
{
register struct buf *bp;
if (hstab.d_active == 0)
return;
bp = hstab.d_actf;
hstab.d_active = 0;
if(HSADDR->hscs1 & ERR){ /* error bit */
HSADDR->hscs1 = RCLR|GO;
if (++hstab.d_errcnt <= 10) {
hsstart();
return;
}
bp->b_flags =| B_ERROR;
}
hstab.d_errcnt = 0;
hstab.d_actf = bp->av_forw;
iodone(bp);
hsstart();
}
hsread(dev)
{
physio(hsstrategy, &rhsbuf, dev, B_READ);
}
hswrite(dev)
{
physio(hsstrategy, &rhsbuf, dev, B_WRITE);
}