2.11BSD/sys/OTHERS/rs03.04/hs.c
/*
* SCCS id @(#)hs.c 2.2 1/3/93
*/
/*
* RS03/04 disk driver
*/
#ifdef AUTOCONFIG
#include "param.h"
#include "hsreg.h"
#include "autoconfig.h"
hsprobe(addr)
struct hsdevice *addr;
{
stuff(HS_IE | HS_DCLR | HS_GO, (&(addr->hscs1)));
WAIT(10);
stuff(0, (&(addr->hscs1)));
return(ACP_IFINTR);
}
#else !AUTOCONFIG
#include "hs.h"
#if NHS > 0
#include "param.h"
#include "systm.h"
#include "buf.h"
#include "conf.h"
#include "user.h"
#include "seg.h"
#include "hsreg.h"
#define HS_NRS03BLKS 1024
#define HS_NRS04BLKS 2048
struct hsdevice *HSADDR = (struct hsdevice *)0172040;
struct buf hstab;
hsroot()
{
hsattach(HSADDR, 0);
}
hsattach(addr, unit)
register struct hsdevice *addr;
{
if (unit != 0)
return(0);
if (fioword(addr) != -1) {
HSADDR = addr;
if (fioword(&(addr->hsbae)) != -1)
hstab.b_flags |= B_RH70;
return(1);
}
HSADDR = (struct hsdevice *) NULL;
return(0);
}
hsstrategy(bp)
register struct buf *bp;
{
register s, mblks;
if (minor(bp->b_dev) < 8)
mblks = HS_NRS03BLKS;
else
mblks = HS_NRS04BLKS;
if (HSADDR == (struct hsdevice *) NULL) {
bp->b_error = ENXIO;
goto errexit;
}
if (bp->b_blkno < 0 || bp->b_blkno >= mblks) {
bp->b_error = EINVAL;
errexit:
bp->b_flags |= B_ERROR;
iodone(bp);
return;
}
if ((hstab.b_flags & B_RH70) == 0)
mapalloc(bp);
bp->av_forw = 0;
s = 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();
splx(s);
}
hsstart()
{
register struct hsdevice *hsaddr = HSADDR;
register struct buf *bp;
register com_addr;
if ((bp = hstab.b_actf) == 0)
return;
hstab.b_active++;
com_addr = bp->b_blkno;
if(minor(bp->b_dev) < 8)
com_addr <<= 1; /* RJS03 */
hsaddr->hscs2 = minor(bp->b_dev) & 07;
hsaddr->hsda = com_addr << 1;
if (hstab.b_flags & B_RH70)
hsaddr->hsbae = bp->b_xmem;
hsaddr->hsba = bp->b_un.b_addr;
hsaddr->hswc = -(bp->b_bcount >> 1);
com_addr = HS_IE | HS_GO | ((bp->b_xmem & 03) << 8);
if(bp->b_flags & B_READ)
hsaddr->hscs1 = com_addr | HS_RCOM;
else
hsaddr->hscs1 = com_addr | HS_WCOM;
#ifdef HS_DKN
dk_busy |= 1 << HS_DKN;
dk_numb[HS_DKN]++;
dk_wds[HS_DKN] += (bp->b_bcount >> 6) & 01777;
#endif HS_DKN
}
hsintr()
{
register struct hsdevice *hsaddr = HSADDR;
register struct buf *bp;
register i;
if (hstab.b_active == 0)
return;
#ifdef HS_DKN
dk_busy &= ~(1 << HS_DKN);
#endif HS_DKN
bp = hstab.b_actf;
hstab.b_active = 0;
if(hsaddr->hscs1 & HS_TRE) {
#ifdef UCB_DEVERR
harderr(bp, "hs");
printf("cs1=%b cs2=%b\n", hsaddr->hscs1,
HS_BITS, hsaddr->hscs2, HSCS2_BITS);
#else
deverror(bp, hsaddr->hscs1, hsaddr->hscs2);
#endif
hsaddr->hscs1 = HS_DCLR | HS_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();
}
#endif NHS
#endif AUTOCONFIG