|
|
1.1 root 1: /* up.c 4.1 11/9/80 */
2:
3: #define OLDUCODE
4:
5: #include "../h/param.h"
6: #include "../h/inode.h"
7: #include "../h/pte.h"
8: #include "../h/uba.h"
9: #include "saio.h"
10:
11: #define EMULEX
12: #ifdef EMULEX
13: #define DELAY(N) { register int d; d = N; while (--d > 0); }
14: #else
15: #define DELAY(N)
16: #endif
17:
18: struct upregs {
19: short upcs1; /* Control and Status register 1 */
20: short upwc; /* Word count register */
21: short upba; /* UNIBUS address register */
22: short upda; /* Desired address register */
23: short upcs2; /* Control and Status register 2*/
24: short upds; /* Drive Status */
25: short uper1; /* Error register 1 */
26: short upas; /* Attention Summary */
27: short upla; /* Look ahead */
28: short updb; /* Data buffer */
29: short upmr; /* Maintenance register */
30: short updt; /* Drive type */
31: short upsn; /* Serial number */
32: short upof; /* Offset register */
33: short upca; /* Desired Cylinder address register*/
34: short upcc; /* Current Cylinder */
35: short uper2; /* Error register 2 */
36: short uper3; /* Error register 3 */
37: short uppos; /* Burst error bit position */
38: short uppat; /* Burst error bit pattern */
39: short upbae; /* 11/70 bus extension */
40: };
41:
42: #ifdef OLDUCODE
43: #define SDELAY 500
44: #else
45: #define SDELAY 25
46: #endif
47: int sdelay = SDELAY;
48: int idelay = 500;
49:
50: #define UPADDR ((struct upregs *)(PHYSUMEM + 0776700 - UNIBASE))
51:
52: /* Drive commands, placed in upcs1 */
53: #define GO 01 /* Go bit, set in all commands */
54: #define PRESET 020 /* Preset drive at init or after errors */
55: #define OFFSET 014 /* Offset heads to try to recover error */
56: #define RTC 016 /* Return to center-line after OFFSET */
57: #define SEARCH 030 /* Search for cylinder+sector */
58: #define SEEK 04 /* Seek to cylinder */
59: #define RECAL 06 /* Recalibrate, needed after seek error */
60: #define DCLR 010 /* Drive clear, after error */
61: #define WCOM 060 /* Write */
62: #define RCOM 070 /* Read */
63:
64: /* Other bits of upcs1 */
65: #define IE 0100 /* Controller wide interrupt enable */
66: #define TRE 040000 /* Transfer error */
67: #define RDY 0200 /* Transfer terminated */
68:
69: /* Drive status bits of upds */
70: #define PIP 020000 /* Positioning in progress */
71: #define ERR 040000 /* Error has occurred, DCLR necessary */
72: #define VV 0100 /* Volume is valid, set by PRESET */
73: #define DPR 0400 /* Drive has been preset */
74: #define MOL 010000 /* Drive is online, heads loaded, etc */
75: #define DRY 0200 /* Drive ready */
76:
77: /* Bits of upcs2 */
78: #define CLR 040 /* Controller clear */
79: /* Bits of uper1 */
80: #define DCK 0100000 /* Ecc error occurred */
81: #define ECH 0100 /* Ecc error was unrecoverable */
82: #define WLE 04000 /* Attempt to write read-only drive */
83:
84: /* Bits of upof; the offset bits above are also in this register */
85: #define FMT22 010000 /* 16 bits/word, must be always set */
86:
87: struct devsize {
88: daddr_t cyloff;
89: } up_sizes[] = {
90: 0, 27, 68, -1, -1, -1, -1, 82
91: };
92:
93: upopen(io)
94: register struct iob *io;
95: {
96:
97: if (up_sizes[io->i_boff].cyloff == -1 ||
98: io->i_boff < 0 || io->i_boff > 7)
99: _stop("up bad unit");
100: io->i_boff = up_sizes[io->i_boff].cyloff * 32 * 19;
101: }
102:
103: upstrategy(io, func)
104: register struct iob *io;
105: {
106: int unit, nspc, ns, cn, tn, sn;
107: daddr_t bn;
108: int info;
109: register short *rp;
110: int occ = io->i_cc;
111: register struct upregs *upaddr = UPADDR;
112:
113: unit = io->i_unit;
114: bn = io->i_bn;
115: nspc = 32 * 19;
116: ns = 32;
117: cn = bn/nspc;
118: sn = bn%nspc;
119: tn = sn/ns;
120: sn = sn%ns;
121: upaddr->upcs2 = unit;
122: DELAY(sdelay);
123: if ((upaddr->upds & VV) == 0) {
124: upaddr->upcs1 = DCLR|GO;
125: DELAY(idelay);
126: upaddr->upcs1 = PRESET|GO;
127: DELAY(idelay);
128: upaddr->upof = FMT22;
129: }
130: if ((upaddr->upds & (DPR|MOL)) != (DPR|MOL)) {
131: printf("after fmt22 upds %o\n", upaddr->upds);
132: _stop("up !DPR || !MOL");
133: }
134: info = ubasetup(io, 1);
135: rp = (short *) &upaddr->upda;
136: upaddr->upca = cn;
137: *rp = (tn << 8) + sn;
138: *--rp = info;
139: *--rp = -io->i_cc / sizeof (short);
140: if (func == READ)
141: *--rp = GO|RCOM;
142: else
143: *--rp = GO|WCOM;
144: DELAY(sdelay);
145: do {
146: DELAY(25);
147: } while ((upaddr->upcs1 & RDY) == 0);
148: DELAY(200);
149: if (upaddr->upcs1&ERR) {
150: printf("disk error: cyl=%d track=%d sect=%d cs1=%X, er1=%X\n",
151: cn, tn, sn,
152: upaddr->upcs1, upaddr->uper1);
153: return (-1);
154: }
155: if (io->i_cc != occ)
156: printf("returned %d\n", io->i_cc);
157: ubafree(info);
158: return (io->i_cc);
159: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.