l_write returns a value; pass it on
[unix-history] / usr / src / sys / vax / stand / idc.c
CommitLineData
b5d17f4d 1/* idc.c 4.2 82/07/15 */
57fa886d
SL
2
3/*
4 * IDC (RB730)
5 *
6 * This driver is full of kludges!
7 * It depends heavily on the 1K file system.
8 */
9
10#include "../h/param.h"
11#include "../h/idcreg.h"
12#include "../h/inode.h"
13#include "../h/pte.h"
14#include "../h/ubareg.h"
b5d17f4d 15#include "../h/fs.h"
57fa886d
SL
16#include "saio.h"
17#include "savax.h"
18
19u_short idcstd[] = { 0175606 };
20short rb02_off[] = { 0, 400, 0, -1, -1, -1, -1, -1 };
21short rb80_off[] = { 0, 37, 0, -1, -1, -1, 115, 305 };
22
23int idc_type[4];
24
25idcopen(io)
26 register struct iob *io;
27{
28 register struct idcdevice *idcaddr;
29 register int i;
30
31 idcaddr = (struct idcdevice *)((caddr_t)ubauba(io->i_unit) + 0x200);
32 if (io->i_boff < 0 || io->i_boff > 7)
33 _stop("idc bad unit");
34 idcaddr->idcmpr = IDCGS_GETSTAT;
35 idcaddr->idccsr = IDC_GETSTAT|(io->i_unit<<8);
36 idcwait(idcaddr);
37 i = idcaddr->idcmpr;
38 idcaddr->idccsr = IDC_CRDY|(1<<(io->i_unit+16));
39 idcwait(idcaddr);
40 idcaddr->idccsr = (io->i_unit<<8)|IDC_RHDR;
41 idcwait(idcaddr);
42 if (idcaddr->idccsr & IDC_ERR) {
43 printf("idc error: idccsr %x\n", idcaddr->idccsr);
44 _stop("idc fatal error");
45 }
46 i = idcaddr->idcmpr;
47 i = idcaddr->idcmpr;
48 if (idcaddr->idccsr & IDC_R80) {
49 idc_type[io->i_unit] = 1;
50 io->i_boff = rb80_off[io->i_boff];
51 } else {
52 idc_type[io->i_unit] = 0;
53 io->i_boff = rb02_off[io->i_boff];
54 }
55 if (io->i_boff < 0)
56 _stop("idc bad unit");
57}
58
59idcstrategy(io, func)
60 register struct iob *io;
61{
62 register struct idcdevice *idcaddr;
63 int com;
64 daddr_t bn;
65 short dn, cn, sn, tn;
66 int ubinfo, errcnt = 0;
67
68 idcaddr = (struct idcdevice *)((caddr_t)ubauba(io->i_unit) + 0x200);
69retry:
70 ubinfo = ubasetup(io, 1);
71 bn = io->i_bn;
72 dn = io->i_unit;
73 if (io->i_cc != 1024) printf("idc: count %d != 1024\n", io->i_cc);
74 if (idc_type[dn]) {
75 cn = bn/(NRB80SECT*NRB80TRK);
76 sn = bn%NRB80SECT;
77 tn = (bn / NRB80SECT) % NRB80TRK;
78 if (sn == NRB80SECT)
79 io->i_cc = 512;
80 } else {
81 bn *= 2;
82 cn = bn/(NRB02SECT*NRB02TRK);
83 sn = bn%NRB02SECT;
84 tn = (bn / NRB02SECT) % NRB02TRK;
85 }
86 cn += io->i_boff;
87 idcaddr->idccsr = IDC_CRDY|IDC_SEEK|(dn<<8)|(1<<(dn+16));
88 idcaddr->idcdar = (cn<<16)|(tn<<8)|sn;
89 idcaddr->idccsr = IDC_SEEK|(dn<<8);
90 idcwait(idcaddr);
91 idcaddr->idccsr &= ~IDC_ATTN;
92 com = dn<<8;
93 if (func == READ)
94 com |= IDC_READ;
95 else
96 com |= IDC_WRITE;
97 idcaddr->idccsr = IDC_CRDY|com;
98 idcaddr->idcbar = ubinfo&0x3ffff;
99 idcaddr->idcbcr = -io->i_cc;
100 idcaddr->idcdar = (cn<<16)|(tn<<8)|sn;
101 idcaddr->idccsr = com;
102 idcwait(idcaddr);
103 ubafree(io, ubinfo);
104 if (idcaddr->idccsr & IDC_ERR) {
105 printf("idc error: (cyl,trk,sec)=(%d,%d,%d) csr=%b\n",
106 cn, tn, sn, idcaddr->idccsr, IDCCSR_BITS);
107 if (errcnt == 10) {
108 printf("idc: unrecovered error\n");
109 return (-1);
110 }
111 errcnt++;
112 goto retry;
113 }
114 if (errcnt)
115 printf("idc: recovered by retry\n");
116 if (idc_type[dn] && sn == NRB80SECT) {
117 io->i_bn++;
118 goto retry;
119 }
120 return (1024);
121}
122
123idcwait(idcaddr)
124 register struct idcdevice *idcaddr;
125{
126 register int i;
127
128 while ((idcaddr->idccsr & (IDC_CRDY|IDC_DRDY)) != (IDC_CRDY|IDC_DRDY))
129 for (i = 10; i; i--)
130 ;
131}