|
|
1.1 root 1: #ifndef lint
2: static char sccsid[] = "@(#)verify.c 1.5 (Berkeley/CCI) 6/7/88";
3: #endif
4:
5: #include "vdfmt.h"
6:
7: #define verbose 1
8:
9: /*
10: **
11: */
12:
13: verify()
14: {
15: extern boolean read_bad_sector_map();
16:
17: cur.state = vfy;
18: print("Starting verification on ");
19: printf("controller %d, drive %d, ", cur.controller, cur.drive);
20: printf("type %s.\n", lab->d_typename);
21:
22: if(is_formatted() == true) {
23: if(read_bad_sector_map() == true) {
24: if(bad_map->bs_id == D_INFO->id) {
25: verify_users_data_area();
26: writelabel();
27: return;
28: }
29: }
30: print("I can't verify drives with old formats.\n");
31: return;
32: }
33: print("I can't verify unformatted drives.\n");
34: }
35:
36:
37: /*
38: **
39: */
40:
41: load_verify_patterns()
42: {
43: register int index;
44: register struct flawpat *fp = (struct flawpat *)lab->d_pat;
45:
46: /* Init bad block pattern array */
47: for(index=0; index<MAXTRKSIZ; index++) {
48: pattern_0[index] = fp->fp_pat[0];
49: pattern_1[index] = fp->fp_pat[1];
50: pattern_2[index] = fp->fp_pat[2];
51: pattern_3[index] = fp->fp_pat[3];
52: pattern_4[index] = fp->fp_pat[4];
53: pattern_5[index] = fp->fp_pat[5];
54: pattern_6[index] = fp->fp_pat[6];
55: pattern_7[index] = fp->fp_pat[7];
56: pattern_8[index] = fp->fp_pat[8];
57: pattern_9[index] = fp->fp_pat[9];
58: pattern_10[index] = fp->fp_pat[10];
59: pattern_12[index] = fp->fp_pat[12];
60: pattern_13[index] = fp->fp_pat[13];
61: pattern_14[index] = fp->fp_pat[14];
62: pattern_15[index] = fp->fp_pat[15];
63: }
64: }
65:
66:
67: /*
68: **
69: */
70:
71: verify_relocation_area()
72: {
73: cur.substate = sub_vfy;
74: verify_cylinders((int)lab->d_ncylinders - NUMSYS, NUMREL, 16);
75: sync_bad_sector_map();
76: }
77:
78:
79: /*
80: **
81: */
82:
83: verify_users_data_area()
84: {
85: int pats = ops_to_do[cur.controller][cur.drive].numpat;
86:
87: cur.substate = sub_vfy;
88: verify_cylinders(0, (int)lab->d_ncylinders - NUMSYS, pats);
89: sync_bad_sector_map();
90: }
91:
92:
93: /*
94: **
95: */
96:
97: verify_maintenence_area()
98: {
99: cur.substate = sub_vfy;
100: verify_cylinders(lab->d_ncylinders - NUMSYS + NUMREL, NUMMNT, 16);
101: sync_bad_sector_map();
102: }
103:
104:
105: /*
106: ** verify_cylinders does full track certification for every track
107: ** on the cylinder.
108: */
109:
110: verify_cylinders(base_cyl, cyl_count, pats)
111: int base_cyl, cyl_count, pats;
112: {
113: dskadr dskaddr;
114:
115: if (pats == 0)
116: return;
117: /* verify each track of each cylinder */
118: for (dskaddr.cylinder = base_cyl;
119: dskaddr.cylinder < base_cyl + cyl_count; dskaddr.cylinder++)
120: for (dskaddr.track = 0; dskaddr.track < lab->d_ntracks;
121: dskaddr.track++)
122: verify_track(&dskaddr, pats, verbose);
123: }
124:
125:
126: /*
127: ** verify_track verifies a single track. If a full-track write fails,
128: ** the sector is flagged; if a full-track read fails, then each sector
129: ** is read individually to determine which sectors are really bad.
130: ** If a sector is bad it is flagged as bad by flag_sector.
131: */
132:
133: verify_track(dskaddr, pats, verbosity)
134: dskadr *dskaddr;
135: int pats;
136: int verbosity;
137: {
138: register int index, i;
139: register int count;
140: register long before;
141: register long *after;
142: register long offset = lab->d_secsize / sizeof(long);
143: int pattern_count = pats;
144:
145: if (pats == 0)
146: return;
147: dskaddr->sector = (char)0;
148: access_dsk((char *)pattern_address[0], dskaddr, VDOP_WD,
149: lab->d_nsectors, 1);
150: for (index = 0; index < pattern_count; index++) {
151: if (!data_ok()) {
152: if (dcb.operrsta & HEADER_ERROR &&
153: C_INFO->type == VDTYPE_SMDE) {
154: flag_sector(dskaddr, dcb.operrsta,
155: dcb.err_code, "write", verbosity);
156: break;
157: } else {
158: indent();
159: vd_error("write track");
160: exdent(1);
161: }
162: #ifdef notdef
163: /*
164: * we presume that write errors will be detected
165: * on read or data compare,
166: * don't bother with extra testing.
167: */
168: if (dcb.operrsta & DATA_ERROR)
169: pattern_count = 16;
170: #endif
171: /*
172: * Write track a sector at a time,
173: * so that a write aborted on one sector
174: * doesn't cause compare errors on all
175: * subsequent sectors on the track.
176: */
177: for (i = 0; i < lab->d_nsectors; i++) {
178: dskaddr->sector = i;
179: access_dsk((char *)pattern_address[index],
180: dskaddr, VDOP_WD, 1,1);
181: }
182: dskaddr->sector = (char)0;
183: }
184: access_dsk((char *)scratch, dskaddr, VDOP_RD,
185: lab->d_nsectors, 1);
186: if (!data_ok()) {
187: if (dcb.operrsta & HEADER_ERROR) {
188: flag_sector(dskaddr, dcb.operrsta,
189: dcb.err_code, "read", verbosity);
190: break;
191: }
192: for (i = 0; i < lab->d_nsectors; i++) {
193: dskaddr->sector = i;
194: access_dsk((char *)&scratch[i * offset],
195: dskaddr, VDOP_RD, 1,1);
196: if (!data_ok())
197: flag_sector(dskaddr, dcb.operrsta,
198: dcb.err_code, "read", verbosity);
199: }
200: dskaddr->sector = (char)0;
201: }
202: if (index+1 < pattern_count)
203: access_dsk((char *)pattern_address[index+1],
204: dskaddr, VDOP_WD, lab->d_nsectors, 0);
205: count = lab->d_nsectors * offset;
206: before = *pattern_address[index];
207: after = scratch;
208: for (i = 0; i < count; ) {
209: if (before != *(after++)) {
210: dskaddr->sector = (char)(i / offset);
211: flag_sector(dskaddr, 0, 0,
212: "data compare", verbosity);
213: i = (dskaddr->sector + 1) * offset;
214: after = scratch + i;
215: } else
216: ++i;
217: }
218: if (index+1 < pattern_count) {
219: poll(60);
220: if (vdtimeout <= 0) {
221: printf(" while writing track.\n");
222: _longjmp(abort_environ, 1);
223: }
224: }
225: if (kill_processes == true) {
226: sync_bad_sector_map();
227: _longjmp(quit_environ, 1);
228: }
229: }
230: /* check again in case of header error */
231: if (kill_processes == true) {
232: sync_bad_sector_map();
233: _longjmp(quit_environ, 1);
234: }
235: }
236:
237:
238: flag_sector(dskaddr, status, ecode, func, verbosity)
239: dskadr *dskaddr;
240: long status;
241: int ecode;
242: char *func;
243: int verbosity;
244: {
245: fmt_err error;
246: bs_entry entry;
247: int result;
248:
249: error.err_adr = *dskaddr;
250: error.err_stat = status;
251: (*C_INFO->code_pos)(&error, &entry);
252: result = add_flaw(&entry);
253: if (verbosity != 0 && result != 0) {
254: indent();
255: print("%s error at sector %d (cyl %d trk %d sect %d)",
256: func, to_sector(*dskaddr), dskaddr->cylinder,
257: dskaddr->track, dskaddr->sector);
258: if (status) {
259: printf(",\n");
260: print(" status=%b", status, VDERRBITS);
261: if (C_INFO->type == VDTYPE_SMDE && ecode)
262: printf(", ecode=0x%x", ecode);
263: }
264: printf(".\n");
265: switch (result) {
266: case 1:
267: print("%s will be relocated.\n",
268: (status & HEADER_ERROR &&
269: C_INFO->type == VDTYPE_SMDE) ? "Track" : "Sector");
270: break;
271: case -1:
272: print("Sector cannot be relocated.\n");
273: break;
274: }
275: exdent(1);
276: }
277: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.