2.9BSD/usr/net/sys/stand/libsa/rm.c
/*
* RM02/3 disk driver
*/
#include <sys/param.h>
#include <sys/inode.h>
#include "../saio.h"
struct device
{
union {
int w;
char c[2];
} rmcs1; /* Control and Status register 1 */
int rmwc; /* Word count register */
caddr_t rmba; /* UNIBUS address register */
int rmda; /* Desired address register */
union {
int w;
char c[2];
} rmcs2; /* Control and Status register 2*/
int rmds; /* Drive Status */
int rmer1; /* Error register 1 */
int rmas; /* Attention Summary */
int rmla; /* Look ahead */
int rmdb; /* Data buffer */
int rmmr1; /* Maintenance register 1 */
int rmdt; /* Drive type */
int rmsn; /* Serial number */
int rmof; /* Offset register */
int rmdc; /* Desired Cylinder register*/
int rmhr; /* Holding register - unused*/
int rmmr2; /* Maintenence register 2 */
int rmer2; /* Error register 2 */
int rmec1; /* Burst error bit position */
int rmec2; /* Burst error bit pattern */
int rmbae; /* 11/70 bus extension */
int rmcs3;
};
#define RMADDR ((struct device *)0176700)
#define NSECT 32
#define NTRAC 5
#define SDIST 2
#define RDIST 6
#define P400 020
#define M400 0220
#define P800 040
#define M800 0240
#define P1200 060
#define M1200 0260
#define GO 01
#define PRESET 020
#define RTC 016
#define OFFSET 014
#define SEARCH 030
#define RECAL 06
#define DCLR 010
#define WCOM 060
#define RCOM 070
#define IE 0100
#define PIP 020000
#define DRY 0200
#define ERR 040000
#define TRE 040000
#define DCK 0100000
#define WLE 04000
#define ECH 0100
#define VV 0100
#define FMT16 010000
rmstrategy(io, func)
register struct iob *io;
{
register unit;
register i;
daddr_t bn;
int sn, cn, tn;
if (((unit = io->i_unit) & 04) == 0)
bn = io->i_bn;
else {
unit &= 03;
bn = io->i_bn;
bn -= io->i_boff;
i = unit + 1;
unit = bn%i;
bn /= i;
bn += io->i_boff;
}
RMADDR->rmcs2.w = unit;
if((RMADDR->rmds & VV) == 0) {
RMADDR->rmcs1.c[0] = PRESET|GO;
RMADDR->rmof = FMT16;
}
cn = bn/(NSECT*NTRAC);
sn = bn%(NSECT*NTRAC);
tn = sn/NSECT;
sn = sn%NSECT;
RMADDR->rmdc = cn;
RMADDR->rmda = (tn << 8) + sn;
RMADDR->rmba = io->i_ma;
RMADDR->rmwc = -(io->i_cc>>1);
unit = (segflag << 8) | GO;
if (func == READ)
unit |= RCOM;
else if (func == WRITE)
unit |= WCOM;
RMADDR->rmcs1.w = unit;
while ((RMADDR->rmcs1.w&DRY) == 0)
;
if (RMADDR->rmcs1.w & TRE) {
printf("disk error: cyl=%d track=%d sect=%d cs2=%o, er1=%o\n",
cn, tn, sn, RMADDR->rmcs2, RMADDR->rmer1);
return(-1);
}
return(io->i_cc);
}