xref: /original-bsd/sys/vax/stand/idc.c (revision dddc135c)
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.4 (Berkeley) 07/09/88
7  */
8 
9 /*
10  * IDC (RB730)
11  */
12 
13 #include "param.h"
14 #include "inode.h"
15 #include "fs.h"
16 
17 #include "../vax/pte.h"
18 #include "../vaxuba/idcreg.h"
19 #include "../vaxuba/ubareg.h"
20 
21 #include "saio.h"
22 #include "savax.h"
23 
24 short	rb02_off[] = { 0, 400, 0, -1, -1, -1, -1, -1 };
25 short	rb80_off[] = { 0, 37, 0, -1, -1, -1, 115, 305 };
26 
27 #define	MAXCTLR		1
28 #define	MAXUNIT		4
29 #define	MAXPART		8
30 
31 int	idc_type[MAXUNIT];
32 
33 idcopen(io)
34 	register struct iob *io;
35 {
36 	register struct idcdevice *idcaddr;
37 	register int i;
38 
39 	if (io->i_adapt != 0)
40 		return (EADAPT);
41 	if ((u_int)io->i_ctlr >= MAXCTLR)
42 		return (ECTLR);
43 	if ((u_int)io->i_unit >= MAXUNIT)
44 		return (EUNIT);
45 	if ((u_int)io->i_part >= MAXPART)
46 		return (EPART);
47 	idcaddr = (struct idcdevice *)((caddr_t)ubauba(io->i_adapt) + 0x200);
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);
58 		return (EIO);
59 	}
60 	i = idcaddr->idcmpr;
61 	i = idcaddr->idcmpr;
62 	if (idcaddr->idccsr & IDC_R80) {
63 		idc_type[io->i_unit] = 1;
64 		io->i_boff = rb80_off[io->i_part] * NRB80SECT * NRB80TRK;
65 	} else {
66 		idc_type[io->i_unit] = 0;
67 		io->i_boff = rb02_off[io->i_part] * NRB02SECT/2 * NRB02TRK;
68 	}
69 	return (0);
70 }
71 
72 idcstrategy(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;
79 	short ccleft, thiscc = 0;
80 	int ubinfo, errcnt = 0;
81 
82 	idcaddr = (struct idcdevice *)((caddr_t)ubauba(io->i_adapt) + 0x200);
83 	ubinfo = ubasetup(io, 1);
84 	bn = io->i_bn;
85 	ccleft = io->i_cc;
86 retry:
87 	dn = io->i_unit;
88 	if (idc_type[dn]) {
89 		cn = bn/(NRB80SECT*NRB80TRK);
90 		sn = bn%NRB80SECT;
91 		tn = (bn / NRB80SECT) % NRB80TRK;
92 		thiscc = (NRB80SECT - sn) * 512;
93 	} else {
94 		cn = 2*bn/(NRB02SECT*NRB02TRK);
95 		sn = (2*bn)%NRB02SECT;
96 		tn = (2*bn / NRB02SECT) % NRB02TRK;
97 		thiscc = (NRB02SECT - sn) * 256;
98 	}
99 	thiscc = MIN(thiscc, ccleft);
100 	ccleft -= thiscc;
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;
113 	idcaddr->idcbcr = -thiscc;
114 	idcaddr->idcdar = (cn<<16)|(tn<<8)|sn;
115 	idcaddr->idccsr = com;
116 	idcwait(idcaddr);
117 	if (idcaddr->idccsr & IDC_ERR) {
118 		printf("idc%d error: (cyl,trk,sec)=(%d,%d,%d) csr=%b\n",
119 		    dn, cn, tn, sn, idcaddr->idccsr, IDCCSR_BITS);
120 		if (errcnt++ == 10) {
121 			printf("idc: unrecovered error\n");
122 			ubafree(io, ubinfo);
123 			return (-1);
124 		}
125 		goto retry;
126 	}
127 	if (errcnt)
128 		printf("idc: recovered by retry\n");
129 	if (ccleft) {
130 		bn += thiscc/NBPG;
131 		ubinfo += thiscc;
132 		goto retry;
133 	}
134 	ubafree(io, ubinfo);
135 	return (io->i_cc);
136 }
137 
138 static
139 idcwait(idcaddr)
140 	register struct idcdevice *idcaddr;
141 {
142 	while ((idcaddr->idccsr & (IDC_CRDY|IDC_DRDY)) != (IDC_CRDY|IDC_DRDY))
143 		DELAY(10);
144 }
145