|
|
BSD 4.1
/* up.c 4.1 11/9/80 */
#define OLDUCODE
#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 */
};
#ifdef OLDUCODE
#define SDELAY 500
#else
#define SDELAY 25
#endif
int sdelay = SDELAY;
int idelay = 500;
#define UPADDR ((struct upregs *)(PHYSUMEM + 0776700 - UNIBASE))
/* Drive commands, placed in upcs1 */
#define GO 01 /* Go bit, set in all commands */
#define PRESET 020 /* Preset drive at init or after errors */
#define OFFSET 014 /* Offset heads to try to recover error */
#define RTC 016 /* Return to center-line after OFFSET */
#define SEARCH 030 /* Search for cylinder+sector */
#define SEEK 04 /* Seek to cylinder */
#define RECAL 06 /* Recalibrate, needed after seek error */
#define DCLR 010 /* Drive clear, after error */
#define WCOM 060 /* Write */
#define RCOM 070 /* Read */
/* Other bits of upcs1 */
#define IE 0100 /* Controller wide interrupt enable */
#define TRE 040000 /* Transfer error */
#define RDY 0200 /* Transfer terminated */
/* Drive status bits of upds */
#define PIP 020000 /* Positioning in progress */
#define ERR 040000 /* Error has occurred, DCLR necessary */
#define VV 0100 /* Volume is valid, set by PRESET */
#define DPR 0400 /* Drive has been preset */
#define MOL 010000 /* Drive is online, heads loaded, etc */
#define DRY 0200 /* Drive ready */
/* Bits of upcs2 */
#define CLR 040 /* Controller clear */
/* Bits of uper1 */
#define DCK 0100000 /* Ecc error occurred */
#define ECH 0100 /* Ecc error was unrecoverable */
#define WLE 04000 /* Attempt to write read-only drive */
/* Bits of upof; the offset bits above are also in this register */
#define FMT22 010000 /* 16 bits/word, must be always set */
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;
register struct upregs *upaddr = UPADDR;
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;
upaddr->upcs2 = unit;
DELAY(sdelay);
if ((upaddr->upds & VV) == 0) {
upaddr->upcs1 = DCLR|GO;
DELAY(idelay);
upaddr->upcs1 = PRESET|GO;
DELAY(idelay);
upaddr->upof = FMT22;
}
if ((upaddr->upds & (DPR|MOL)) != (DPR|MOL))
_stop("up !DPR || !MOL");
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(sdelay);
do {
DELAY(25);
} while ((upaddr->upcs1 & RDY) == 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.