|
|
BSD 3.0
#include "../h/param.h"
#include "../h/inode.h"
#include "../h/pte.h"
#include "../h/uba.h"
#include "saio.h"
#define EMULEX
#ifdef EMULEX
#define DELAY(N) { register int d; d = N; while (--d > 0); }
#else
#define DELAY(N)
#endif
struct upregs {
short upcs1; /* Control and Status register 1 */
short upwc; /* Word count register */
short upba; /* UNIBUS address register */
short upda; /* Desired address register */
short upcs2; /* Control and Status register 2*/
short upds; /* Drive Status */
short uper1; /* Error register 1 */
short upas; /* Attention Summary */
short upla; /* Look ahead */
short updb; /* Data buffer */
short upmr; /* Maintenance register */
short updt; /* Drive type */
short upsn; /* Serial number */
short upof; /* Offset register */
short upca; /* Desired Cylinder address register*/
short upcc; /* Current Cylinder */
short uper2; /* Error register 2 */
short uper3; /* Error register 3 */
short uppos; /* Burst error bit position */
short uppat; /* Burst error bit pattern */
short upbae; /* 11/70 bus extension */
};
#define UPADDR ((struct upregs *)(PHYSUMEM + 0776700 - UNIBASE))
char up_openf;
/* Drive Commands */
#define GO 01
#define PRESET 020
#define RECAL 06
#define RCLR 010
#define OFFSET 014
#define RCOM 070
#define WCOM 060
#define IENABLE 0100
#define READY 0200 /* upds - drive ready */
#define PIP 020000 /* upds - Positioning Operation in Progress */
#define ERR 040000 /* upcs1 - composite error */
#define DRY 0200 /* upcs1 - drive ready */
#define DTE 010000 /* uper1 - Drive Timing Error */
#define OPI 020000 /* uper1 - Operation Incomplete */
#define DU 040000 /* uper1 - Drive Unsafe */
/* Error Correction Code errors */
#define DCK 0100000 /* uper1 - Data Check error */
#define ECH 0100 /* uper1 - ECC hard error */
#define CLR 040 /* upcs2 - Controller Clear */
#define FMT22 010000 /* upof - 16 bit /word format */
struct devsize {
daddr_t cyloff;
} up_sizes[] = {
0, 27, 68, -1, -1, -1, -1, 82
};
upopen(io)
register struct iob *io;
{
if (up_sizes[io->i_boff].cyloff == -1 ||
io->i_boff < 0 || io->i_boff > 7)
_stop("up bad unit");
io->i_boff = up_sizes[io->i_boff].cyloff * 32 * 19;
}
upstrategy(io, func)
register struct iob *io;
{
int unit, nspc, ns, cn, tn, sn;
daddr_t bn;
int info;
register short *rp;
int occ = io->i_cc;
unit = io->i_unit;
bn = io->i_bn;
nspc = 32 * 19;
ns = 32;
cn = bn/nspc;
sn = bn%nspc;
tn = sn/ns;
sn = sn%ns;
if (!up_openf) {
up_openf++;
UPADDR->upcs2 = CLR;
DELAY(500);
UPADDR->upcs1 = RCLR|GO;
DELAY(500);
UPADDR->upcs1 = PRESET|GO;
DELAY(500);
UPADDR->upof = FMT22;
DELAY(500);
while ((UPADDR->upcs1 & DRY) == 0)
DELAY(500);
}
UPADDR->upcs2 = unit;
DELAY(500);
info = ubasetup(io, 1);
rp = (short *) &UPADDR->upda;
UPADDR->upca = cn;
*rp = (tn << 8) + sn;
*--rp = info;
*--rp = -io->i_cc / sizeof (short);
if (func == READ) {
*--rp = GO|RCOM;
} else {
*--rp = GO|WCOM;
}
DELAY(500);
do {
DELAY(200);
} while ((UPADDR->upcs1 & DRY) == 0);
DELAY(200);
if (UPADDR->upcs1&ERR) {
printf("disk error: cyl=%d track=%d sect=%d cs1=%X, er1=%X\n",
cn, tn, sn,
UPADDR->upcs1, UPADDR->uper1);
return (-1);
}
if (io->i_cc != occ)
printf("returned %d\n", io->i_cc);
ubafree(info);
return (io->i_cc);
}
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.