merge in NFS code from Rick Macklem
[unix-history] / usr / src / sys / vax / stand / idc.c
CommitLineData
8ae0e4b4 1/*
99152021 2 * Copyright (c) 1982, 1986, 1988 Regents of the University of California.
8ae0e4b4
KM
3 * All rights reserved. The Berkeley software License Agreement
4 * specifies the terms and conditions for redistribution.
5 *
99152021 6 * @(#)idc.c 7.4 (Berkeley) %G%
8ae0e4b4 7 */
57fa886d
SL
8
9/*
10 * IDC (RB730)
57fa886d
SL
11 */
12
39c71180
MK
13#include "param.h"
14#include "inode.h"
15#include "fs.h"
a031a31b 16
99152021 17#include "../vax/pte.h"
a031a31b
SL
18#include "../vaxuba/idcreg.h"
19#include "../vaxuba/ubareg.h"
20
57fa886d
SL
21#include "saio.h"
22#include "savax.h"
23
57fa886d
SL
24short rb02_off[] = { 0, 400, 0, -1, -1, -1, -1, -1 };
25short rb80_off[] = { 0, 37, 0, -1, -1, -1, 115, 305 };
26
cfeb3635
KB
27#define MAXCTLR 1
28#define MAXUNIT 4
29#define MAXPART 8
30
31int idc_type[MAXUNIT];
57fa886d
SL
32
33idcopen(io)
34 register struct iob *io;
35{
36 register struct idcdevice *idcaddr;
37 register int i;
38
99152021 39 if (io->i_adapt != 0)
cfeb3635
KB
40 return (EADAPT);
41 if ((u_int)io->i_ctlr >= MAXCTLR)
42 return (ECTLR);
43 if ((u_int)io->i_unit >= MAXUNIT)
39c71180 44 return (EUNIT);
cfeb3635
KB
45 if ((u_int)io->i_part >= MAXPART)
46 return (EPART);
47 idcaddr = (struct idcdevice *)((caddr_t)ubauba(io->i_adapt) + 0x200);
57fa886d
SL
48 idcaddr->idcmpr = IDCGS_GETSTAT;
49 idcaddr->idccsr = IDC_GETSTAT|(io->i_unit<<8);
50 idcwait(idcaddr);
51 i = idcaddr->idcmpr;
52 idcaddr->idccsr = IDC_CRDY|(1<<(io->i_unit+16));
53 idcwait(idcaddr);
54 idcaddr->idccsr = (io->i_unit<<8)|IDC_RHDR;
55 idcwait(idcaddr);
56 if (idcaddr->idccsr & IDC_ERR) {
57 printf("idc error: idccsr %x\n", idcaddr->idccsr);
39c71180 58 return (EIO);
57fa886d
SL
59 }
60 i = idcaddr->idcmpr;
61 i = idcaddr->idcmpr;
62 if (idcaddr->idccsr & IDC_R80) {
63 idc_type[io->i_unit] = 1;
cfeb3635 64 io->i_boff = rb80_off[io->i_part] * NRB80SECT * NRB80TRK;
57fa886d
SL
65 } else {
66 idc_type[io->i_unit] = 0;
cfeb3635 67 io->i_boff = rb02_off[io->i_part] * NRB02SECT/2 * NRB02TRK;
39c71180
MK
68 }
69 return (0);
57fa886d
SL
70}
71
72idcstrategy(io, func)
73 register struct iob *io;
74{
75 register struct idcdevice *idcaddr;
76 int com;
77 daddr_t bn;
78 short dn, cn, sn, tn;
695069ba 79 short ccleft, thiscc = 0;
57fa886d
SL
80 int ubinfo, errcnt = 0;
81
cfeb3635 82 idcaddr = (struct idcdevice *)((caddr_t)ubauba(io->i_adapt) + 0x200);
57fa886d
SL
83 ubinfo = ubasetup(io, 1);
84 bn = io->i_bn;
695069ba
BF
85 ccleft = io->i_cc;
86retry:
57fa886d 87 dn = io->i_unit;
57fa886d
SL
88 if (idc_type[dn]) {
89 cn = bn/(NRB80SECT*NRB80TRK);
90 sn = bn%NRB80SECT;
91 tn = (bn / NRB80SECT) % NRB80TRK;
695069ba 92 thiscc = (NRB80SECT - sn) * 512;
57fa886d 93 } else {
695069ba
BF
94 cn = 2*bn/(NRB02SECT*NRB02TRK);
95 sn = (2*bn)%NRB02SECT;
96 tn = (2*bn / NRB02SECT) % NRB02TRK;
97 thiscc = (NRB02SECT - sn) * 256;
57fa886d 98 }
695069ba
BF
99 thiscc = MIN(thiscc, ccleft);
100 ccleft -= thiscc;
57fa886d
SL
101 idcaddr->idccsr = IDC_CRDY|IDC_SEEK|(dn<<8)|(1<<(dn+16));
102 idcaddr->idcdar = (cn<<16)|(tn<<8)|sn;
103 idcaddr->idccsr = IDC_SEEK|(dn<<8);
104 idcwait(idcaddr);
105 idcaddr->idccsr &= ~IDC_ATTN;
106 com = dn<<8;
107 if (func == READ)
108 com |= IDC_READ;
109 else
110 com |= IDC_WRITE;
111 idcaddr->idccsr = IDC_CRDY|com;
112 idcaddr->idcbar = ubinfo&0x3ffff;
695069ba 113 idcaddr->idcbcr = -thiscc;
57fa886d
SL
114 idcaddr->idcdar = (cn<<16)|(tn<<8)|sn;
115 idcaddr->idccsr = com;
116 idcwait(idcaddr);
57fa886d 117 if (idcaddr->idccsr & IDC_ERR) {
b65f093e
MK
118 printf("idc%d error: (cyl,trk,sec)=(%d,%d,%d) csr=%b\n",
119 dn, cn, tn, sn, idcaddr->idccsr, IDCCSR_BITS);
cfeb3635 120 if (errcnt++ == 10) {
57fa886d 121 printf("idc: unrecovered error\n");
695069ba 122 ubafree(io, ubinfo);
57fa886d
SL
123 return (-1);
124 }
57fa886d
SL
125 goto retry;
126 }
127 if (errcnt)
128 printf("idc: recovered by retry\n");
695069ba 129 if (ccleft) {
2e4ee04a 130 bn += thiscc/NBPG;
695069ba 131 ubinfo += thiscc;
57fa886d
SL
132 goto retry;
133 }
695069ba
BF
134 ubafree(io, ubinfo);
135 return (io->i_cc);
57fa886d
SL
136}
137
cfeb3635 138static
57fa886d
SL
139idcwait(idcaddr)
140 register struct idcdevice *idcaddr;
141{
57fa886d 142 while ((idcaddr->idccsr & (IDC_CRDY|IDC_DRDY)) != (IDC_CRDY|IDC_DRDY))
cfeb3635 143 DELAY(10);
75f313ad 144}