Add copyright
[unix-history] / usr / src / sys / vax / stand / idc.c
/*
* Copyright (c) 1982 Regents of the University of California.
* All rights reserved. The Berkeley software License Agreement
* specifies the terms and conditions for redistribution.
*
* @(#)idc.c 6.3 (Berkeley) %G%
*/
/*
* IDC (RB730)
*/
#include "../machine/pte.h"
#include "../h/param.h"
#include "../h/inode.h"
#include "../h/fs.h"
#include "../vaxuba/idcreg.h"
#include "../vaxuba/ubareg.h"
#include "saio.h"
#include "savax.h"
u_short idcstd[] = { 0175606 };
short rb02_off[] = { 0, 400, 0, -1, -1, -1, -1, -1 };
short rb80_off[] = { 0, 37, 0, -1, -1, -1, 115, 305 };
int idc_type[4];
idcopen(io)
register struct iob *io;
{
register struct idcdevice *idcaddr;
register int i;
idcaddr = (struct idcdevice *)((caddr_t)ubauba(io->i_unit) + 0x200);
if (io->i_boff < 0 || io->i_boff > 7)
_stop("idc bad unit");
idcaddr->idcmpr = IDCGS_GETSTAT;
idcaddr->idccsr = IDC_GETSTAT|(io->i_unit<<8);
idcwait(idcaddr);
i = idcaddr->idcmpr;
idcaddr->idccsr = IDC_CRDY|(1<<(io->i_unit+16));
idcwait(idcaddr);
idcaddr->idccsr = (io->i_unit<<8)|IDC_RHDR;
idcwait(idcaddr);
if (idcaddr->idccsr & IDC_ERR) {
printf("idc error: idccsr %x\n", idcaddr->idccsr);
_stop("idc fatal error");
}
i = idcaddr->idcmpr;
i = idcaddr->idcmpr;
if (idcaddr->idccsr & IDC_R80) {
idc_type[io->i_unit] = 1;
io->i_boff = rb80_off[io->i_boff] * NRB80SECT * NRB80TRK;
} else {
idc_type[io->i_unit] = 0;
io->i_boff = rb02_off[io->i_boff] * NRB02SECT/2 * NRB02TRK;
}
if (io->i_boff < 0)
_stop("idc%d: bad unit type", io->i_unit);
}
idcstrategy(io, func)
register struct iob *io;
{
register struct idcdevice *idcaddr;
int com;
daddr_t bn;
short dn, cn, sn, tn;
short ccleft, thiscc = 0;
int ubinfo, errcnt = 0;
idcaddr = (struct idcdevice *)((caddr_t)ubauba(io->i_unit) + 0x200);
ubinfo = ubasetup(io, 1);
bn = io->i_bn;
ccleft = io->i_cc;
retry:
dn = io->i_unit;
if (idc_type[dn]) {
cn = bn/(NRB80SECT*NRB80TRK);
sn = bn%NRB80SECT;
tn = (bn / NRB80SECT) % NRB80TRK;
thiscc = (NRB80SECT - sn) * 512;
} else {
cn = 2*bn/(NRB02SECT*NRB02TRK);
sn = (2*bn)%NRB02SECT;
tn = (2*bn / NRB02SECT) % NRB02TRK;
thiscc = (NRB02SECT - sn) * 256;
}
thiscc = MIN(thiscc, ccleft);
ccleft -= thiscc;
idcaddr->idccsr = IDC_CRDY|IDC_SEEK|(dn<<8)|(1<<(dn+16));
idcaddr->idcdar = (cn<<16)|(tn<<8)|sn;
idcaddr->idccsr = IDC_SEEK|(dn<<8);
idcwait(idcaddr);
idcaddr->idccsr &= ~IDC_ATTN;
com = dn<<8;
if (func == READ)
com |= IDC_READ;
else
com |= IDC_WRITE;
idcaddr->idccsr = IDC_CRDY|com;
idcaddr->idcbar = ubinfo&0x3ffff;
idcaddr->idcbcr = -thiscc;
idcaddr->idcdar = (cn<<16)|(tn<<8)|sn;
idcaddr->idccsr = com;
idcwait(idcaddr);
if (idcaddr->idccsr & IDC_ERR) {
printf("idc%d error: (cyl,trk,sec)=(%d,%d,%d) csr=%b\n",
dn, cn, tn, sn, idcaddr->idccsr, IDCCSR_BITS);
if (errcnt == 10) {
printf("idc: unrecovered error\n");
ubafree(io, ubinfo);
return (-1);
}
errcnt++;
goto retry;
}
if (errcnt)
printf("idc: recovered by retry\n");
if (ccleft) {
bn += thiscc/NBPG;
ubinfo += thiscc;
goto retry;
}
ubafree(io, ubinfo);
return (io->i_cc);
}
idcwait(idcaddr)
register struct idcdevice *idcaddr;
{
register int i;
while ((idcaddr->idccsr & (IDC_CRDY|IDC_DRDY)) != (IDC_CRDY|IDC_DRDY))
for (i = 10; i; i--)
;
}
/*ARGSUSED*/
idcioctl(io, cmd, arg)
struct iob *io;
int cmd;
caddr_t arg;
{
return (ECMD);
}