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