2.11BSD/sys/pdpstand/si.c
/*
* Copyright (c) 1986 Regents of the University of California.
* All rights reserved. The Berkeley software License Agreement
* specifies the terms and conditions for redistribution.
*
* @(#)si.c 2.2 (2.11BSD) 1996/3/8
*
* SI 9500 CDC 9766 Stand Alone disk driver
*/
#include "../h/param.h"
#include "../pdpuba/sireg.h"
#include "saio.h"
#define NSI 2
struct sidevice *SIcsr[NSI + 1] =
{
(struct sidevice *)0176700,
(struct sidevice *)0,
(struct sidevice *)-1
};
/* defines for 9766 */
#define NHEADS 19
#define NSECT 32
#define NSPC NSECT*NHEADS
static u_char dualsi[NSI];
sistrategy(io, func)
register struct iob *io;
{
int unit = io->i_unit;
register int ctlr = io->i_ctlr;
register struct sidevice *siaddr = SIcsr[ctlr];
int ii;
daddr_t bn;
int sn, cn, tn, bae, lo16;
/*
* weirdness with bit 2 (04) removed - see xp.c for comments
* about this
*/
bn = io->i_bn;
cn = bn / (NSPC);
sn = bn % (NSPC);
tn = sn / (NSECT);
sn = sn % (NSECT);
if (!dualsi[ctlr]) {
if (siaddr->siscr != 0)
dualsi[ctlr]++;
else
if ((siaddr->sierr & (SIERR_ERR | SIERR_CNT)) == (SIERR_ERR | SIERR_CNT))
dualsi[ctlr]++;
}
if (dualsi[ctlr])
while (!(siaddr->siscr & 0200)) {
siaddr->sicnr = SI_RESET;
siaddr->siscr = 1;
}
iomapadr(io->i_ma, &bae, &lo16);
siaddr->sipcr = cn + (unit <<10);
siaddr->sihsr = (tn << 5) + sn;
siaddr->simar = (caddr_t)lo16;
siaddr->siwcr = io->i_cc >> 1;
ii = (bae << 4) | SI_GO;
if (func == READ)
ii |= SI_READ;
else if (func == WRITE)
ii |= SI_WRITE;
siaddr->sicnr = ii;
while ((siaddr->sicnr & SI_DONE) == 0)
continue;
if (siaddr->sierr & SIERR_ERR) {
printf("%s err cy=%d hd=%d sc=%d cnr=%o, err=%o\n",
devname(io), cn, tn, sn, siaddr->sicnr, siaddr->sierr);
return(-1);
}
return(io->i_cc);
}
siopen(io)
struct iob *io;
{
return(genopen(NSI, io));
}