USG_PG3/usr/source/io1/hs.c
#
/*
* RS03/04 disk driver
*/
#include "../head/param.h"
#include "../head/systm.h"
#include "../head/buf.h"
#include "../head/bufx.h"
#include "../head/conf.h"
#include "../head/user.h"
#include "../head/userx.h"
#include "../head/elog.h"
struct hsregs {
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 */
int hscs3; /* 11/70 Control and status register 3 */
};
#define NHS 1
#define HSADDR 0172040
struct devtab hstab;
struct buf rhsbuf;
struct iostat hsstat[NHS];
struct errtab hsetab { etabinit(E_BLK|E_RH70,NHS,HS,hsstat) };
#define ERR 040000 /* hscs1 - composite error */
#define GO 01
#define RCLR 010
#define DRY 0200 /* hsds - Drive Ready */
#define DK_N 0
hsopen(dev, flag)
{
if((dev.d_minor&07) >= NHS)
u.u_error = ENXIO;
}
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) {
if (bp->b_flags&B_READ)
bp->b_resid = bp->b_wcount;
else {
bp->b_flags =| B_ERROR;
bp->b_error = ENXIO;
}
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, minor;
if ((bp = hstab.d_actf) == 0)
return;
hstab.d_active++;
addr = bp->b_blkno;
if((minor = bp->b_dev.d_minor) < 8)
addr =<< 1; /* RJS03 */
minor =& 07;
hsetab.e_aunit = &hsstat[minor];
hsetab.e_aunit->io_ops++;
blkacty =| (1<<HS);
HSADDR->hscs2 = minor;
rhstart(bp, &HSADDR->hsda, addr<<1, &HSADDR->hsbae);
dk_busy =| 1<<DK_N;
dk_numb[DK_N] =+ 1;
dk_wds[DK_N] =+ (-bp->b_wcount>>5) & 03777;
}
hsintr()
{
register struct buf *bp;
struct hsregs hsregs[0];
if (hstab.d_active == 0)
return;
bp = hstab.d_actf;
blkacty =& ~(1<<HS);
dk_busy =& ~(1<<DK_N);
hstab.d_active = 0;
if(HSADDR->hscs1 & ERR){ /* error bit */
/* deverror(bp, HSADDR->hscs2, 0);/**/
fmtblk(&hsetab,HSADDR,sizeof(hsregs[0])/2,bp);
HSADDR->hscs1 = RCLR|GO;
hsetab.e_aunit->io_misc++;
if (hstab.d_errcnt < 10) {
if(hstab.d_errcnt++ == 0)
logerr(&hsetab,E_FIRST);
hsstart();
return;
}
bp->b_flags =| B_ERROR;
}
if(hsetab.e_emsg != NULL)
logerr(&hsetab,E_RETRY);
hstab.d_errcnt = 0;
hstab.d_actf = bp->av_forw;
bp->b_resid = HSADDR->hswc;
iodone(bp);
hsstart();
}
hsread(dev)
{
physio(hsstrategy, &rhsbuf, dev, B_READ,
dev.d_minor >= 8 ? 2048 : 1024);
}
hswrite(dev)
{
physio(hsstrategy, &rhsbuf, dev, B_WRITE,
dev.d_minor >= 8 ? 2048 : 1024);
}