129540Ssam #ifndef lint
2*34667Skarels static char sccsid[] = "@(#)verify.c 1.5 (Berkeley/CCI) 06/07/88";
329540Ssam #endif
429540Ssam
529540Ssam #include "vdfmt.h"
629540Ssam
729981Skarels #define verbose 1
829540Ssam
929540Ssam /*
1029540Ssam **
1129540Ssam */
1229540Ssam
verify()1329540Ssam verify()
1429540Ssam {
1529540Ssam extern boolean read_bad_sector_map();
1629540Ssam
1729540Ssam cur.state = vfy;
1829540Ssam print("Starting verification on ");
1929540Ssam printf("controller %d, drive %d, ", cur.controller, cur.drive);
2032662Skarels printf("type %s.\n", lab->d_typename);
2129540Ssam
2229540Ssam if(is_formatted() == true) {
2329540Ssam if(read_bad_sector_map() == true) {
2432662Skarels if(bad_map->bs_id == D_INFO->id) {
2529540Ssam verify_users_data_area();
2632662Skarels writelabel();
2729540Ssam return;
2829540Ssam }
2929540Ssam }
3029540Ssam print("I can't verify drives with old formats.\n");
3129540Ssam return;
3229540Ssam }
3329540Ssam print("I can't verify unformatted drives.\n");
3429540Ssam }
3529540Ssam
3629540Ssam
3729540Ssam /*
3829540Ssam **
3929540Ssam */
4029540Ssam
load_verify_patterns()4129540Ssam load_verify_patterns()
4229540Ssam {
4329540Ssam register int index;
4432662Skarels register struct flawpat *fp = (struct flawpat *)lab->d_pat;
4529540Ssam
4629540Ssam /* Init bad block pattern array */
4732662Skarels for(index=0; index<MAXTRKSIZ; index++) {
4829540Ssam pattern_0[index] = fp->fp_pat[0];
4929540Ssam pattern_1[index] = fp->fp_pat[1];
5029540Ssam pattern_2[index] = fp->fp_pat[2];
5129540Ssam pattern_3[index] = fp->fp_pat[3];
5229540Ssam pattern_4[index] = fp->fp_pat[4];
5329540Ssam pattern_5[index] = fp->fp_pat[5];
5429540Ssam pattern_6[index] = fp->fp_pat[6];
5529540Ssam pattern_7[index] = fp->fp_pat[7];
5629540Ssam pattern_8[index] = fp->fp_pat[8];
5729540Ssam pattern_9[index] = fp->fp_pat[9];
5829540Ssam pattern_10[index] = fp->fp_pat[10];
5929540Ssam pattern_12[index] = fp->fp_pat[12];
6029540Ssam pattern_13[index] = fp->fp_pat[13];
6129540Ssam pattern_14[index] = fp->fp_pat[14];
6229540Ssam pattern_15[index] = fp->fp_pat[15];
6329540Ssam }
6429540Ssam }
6529540Ssam
6629540Ssam
6729540Ssam /*
6829540Ssam **
6929540Ssam */
7029540Ssam
verify_relocation_area()7129540Ssam verify_relocation_area()
7229540Ssam {
7329540Ssam cur.substate = sub_vfy;
7432662Skarels verify_cylinders((int)lab->d_ncylinders - NUMSYS, NUMREL, 16);
7529540Ssam sync_bad_sector_map();
7629540Ssam }
7729540Ssam
7829540Ssam
7929540Ssam /*
8029540Ssam **
8129540Ssam */
8229540Ssam
verify_users_data_area()8329540Ssam verify_users_data_area()
8429540Ssam {
8529540Ssam int pats = ops_to_do[cur.controller][cur.drive].numpat;
8629540Ssam
8729540Ssam cur.substate = sub_vfy;
8832662Skarels verify_cylinders(0, (int)lab->d_ncylinders - NUMSYS, pats);
8929540Ssam sync_bad_sector_map();
9029540Ssam }
9129540Ssam
9229540Ssam
9329540Ssam /*
9429540Ssam **
9529540Ssam */
9629540Ssam
verify_maintenence_area()9732662Skarels verify_maintenence_area()
9829540Ssam {
9929540Ssam cur.substate = sub_vfy;
10032662Skarels verify_cylinders(lab->d_ncylinders - NUMSYS + NUMREL, NUMMNT, 16);
10129540Ssam sync_bad_sector_map();
10229540Ssam }
10329540Ssam
10429540Ssam
10529540Ssam /*
10629540Ssam ** verify_cylinders does full track certification for every track
10729981Skarels ** on the cylinder.
10829540Ssam */
10929540Ssam
verify_cylinders(base_cyl,cyl_count,pats)11029540Ssam verify_cylinders(base_cyl, cyl_count, pats)
11129540Ssam int base_cyl, cyl_count, pats;
11229540Ssam {
11329540Ssam dskadr dskaddr;
11429540Ssam
11529981Skarels if (pats == 0)
11629981Skarels return;
11729540Ssam /* verify each track of each cylinder */
11829981Skarels for (dskaddr.cylinder = base_cyl;
11929981Skarels dskaddr.cylinder < base_cyl + cyl_count; dskaddr.cylinder++)
12032662Skarels for (dskaddr.track = 0; dskaddr.track < lab->d_ntracks;
12129540Ssam dskaddr.track++)
12229981Skarels verify_track(&dskaddr, pats, verbose);
12329540Ssam }
12429540Ssam
12529540Ssam
12629540Ssam /*
12729981Skarels ** verify_track verifies a single track. If a full-track write fails,
12829981Skarels ** the sector is flagged; if a full-track read fails, then each sector
12929981Skarels ** is read individually to determine which sectors are really bad.
13029981Skarels ** If a sector is bad it is flagged as bad by flag_sector.
13129540Ssam */
13229540Ssam
verify_track(dskaddr,pats,verbosity)13329540Ssam verify_track(dskaddr, pats, verbosity)
13429540Ssam dskadr *dskaddr;
13529540Ssam int pats;
13629540Ssam int verbosity;
13729540Ssam {
13829540Ssam register int index, i;
13929540Ssam register int count;
14029540Ssam register long before;
14129540Ssam register long *after;
14232662Skarels register long offset = lab->d_secsize / sizeof(long);
14329540Ssam int pattern_count = pats;
14429540Ssam
14529981Skarels if (pats == 0)
14629540Ssam return;
14729540Ssam dskaddr->sector = (char)0;
14831318Ssam access_dsk((char *)pattern_address[0], dskaddr, VDOP_WD,
14932662Skarels lab->d_nsectors, 1);
15029981Skarels for (index = 0; index < pattern_count; index++) {
15129981Skarels if (!data_ok()) {
152*34667Skarels if (dcb.operrsta & HEADER_ERROR &&
153*34667Skarels C_INFO->type == VDTYPE_SMDE) {
15429981Skarels flag_sector(dskaddr, dcb.operrsta,
155*34667Skarels dcb.err_code, "write", verbosity);
15629540Ssam break;
157*34667Skarels } else {
158*34667Skarels indent();
159*34667Skarels vd_error("write track");
160*34667Skarels exdent(1);
16129540Ssam }
162*34667Skarels #ifdef notdef
163*34667Skarels /*
164*34667Skarels * we presume that write errors will be detected
165*34667Skarels * on read or data compare,
166*34667Skarels * don't bother with extra testing.
167*34667Skarels */
16829981Skarels if (dcb.operrsta & DATA_ERROR)
16929540Ssam pattern_count = 16;
170*34667Skarels #endif
171*34667Skarels /*
172*34667Skarels * Write track a sector at a time,
173*34667Skarels * so that a write aborted on one sector
174*34667Skarels * doesn't cause compare errors on all
175*34667Skarels * subsequent sectors on the track.
176*34667Skarels */
177*34667Skarels for (i = 0; i < lab->d_nsectors; i++) {
178*34667Skarels dskaddr->sector = i;
179*34667Skarels access_dsk((char *)pattern_address[index],
180*34667Skarels dskaddr, VDOP_WD, 1,1);
181*34667Skarels }
182*34667Skarels dskaddr->sector = (char)0;
18329540Ssam }
18431318Ssam access_dsk((char *)scratch, dskaddr, VDOP_RD,
18532662Skarels lab->d_nsectors, 1);
18629981Skarels if (!data_ok()) {
18729981Skarels if (dcb.operrsta & HEADER_ERROR) {
18829981Skarels flag_sector(dskaddr, dcb.operrsta,
189*34667Skarels dcb.err_code, "read", verbosity);
19029540Ssam break;
19129540Ssam }
19232662Skarels for (i = 0; i < lab->d_nsectors; i++) {
19329540Ssam dskaddr->sector = i;
194*34667Skarels access_dsk((char *)&scratch[i * offset],
195*34667Skarels dskaddr, VDOP_RD, 1,1);
19629981Skarels if (!data_ok())
19729981Skarels flag_sector(dskaddr, dcb.operrsta,
198*34667Skarels dcb.err_code, "read", verbosity);
19929540Ssam }
20029540Ssam dskaddr->sector = (char)0;
20129540Ssam }
20229981Skarels if (index+1 < pattern_count)
20329540Ssam access_dsk((char *)pattern_address[index+1],
20432662Skarels dskaddr, VDOP_WD, lab->d_nsectors, 0);
20532662Skarels count = lab->d_nsectors * offset;
20629540Ssam before = *pattern_address[index];
20729540Ssam after = scratch;
208*34667Skarels for (i = 0; i < count; ) {
20929981Skarels if (before != *(after++)) {
21029981Skarels dskaddr->sector = (char)(i / offset);
211*34667Skarels flag_sector(dskaddr, 0, 0,
212*34667Skarels "data compare", verbosity);
213*34667Skarels i = (dskaddr->sector + 1) * offset;
214*34667Skarels after = scratch + i;
215*34667Skarels } else
216*34667Skarels ++i;
21729540Ssam }
21829981Skarels if (index+1 < pattern_count) {
21929540Ssam poll(60);
22029981Skarels if (vdtimeout <= 0) {
221*34667Skarels printf(" while writing track.\n");
22229540Ssam _longjmp(abort_environ, 1);
22329540Ssam }
22429540Ssam }
22529981Skarels if (kill_processes == true) {
22629540Ssam sync_bad_sector_map();
22729540Ssam _longjmp(quit_environ, 1);
22829540Ssam }
22929540Ssam }
23032662Skarels /* check again in case of header error */
23132662Skarels if (kill_processes == true) {
23232662Skarels sync_bad_sector_map();
23332662Skarels _longjmp(quit_environ, 1);
23432662Skarels }
23529540Ssam }
23629540Ssam
23729540Ssam
flag_sector(dskaddr,status,ecode,func,verbosity)238*34667Skarels flag_sector(dskaddr, status, ecode, func, verbosity)
23929540Ssam dskadr *dskaddr;
24029540Ssam long status;
24129981Skarels int ecode;
242*34667Skarels char *func;
24329981Skarels int verbosity;
24429540Ssam {
24529540Ssam fmt_err error;
24629540Ssam bs_entry entry;
247*34667Skarels int result;
24829540Ssam
249*34667Skarels error.err_adr = *dskaddr;
250*34667Skarels error.err_stat = status;
251*34667Skarels (*C_INFO->code_pos)(&error, &entry);
252*34667Skarels result = add_flaw(&entry);
253*34667Skarels if (verbosity != 0 && result != 0) {
254*34667Skarels indent();
255*34667Skarels print("%s error at sector %d (cyl %d trk %d sect %d)",
256*34667Skarels func, to_sector(*dskaddr), dskaddr->cylinder,
257*34667Skarels dskaddr->track, dskaddr->sector);
258*34667Skarels if (status) {
259*34667Skarels printf(",\n");
26031318Ssam print(" status=%b", status, VDERRBITS);
261*34667Skarels if (C_INFO->type == VDTYPE_SMDE && ecode)
262*34667Skarels printf(", ecode=0x%x", ecode);
263*34667Skarels }
264*34667Skarels printf(".\n");
265*34667Skarels switch (result) {
266*34667Skarels case 1:
267*34667Skarels print("%s will be relocated.\n",
268*34667Skarels (status & HEADER_ERROR &&
269*34667Skarels C_INFO->type == VDTYPE_SMDE) ? "Track" : "Sector");
270*34667Skarels break;
271*34667Skarels case -1:
272*34667Skarels print("Sector cannot be relocated.\n");
273*34667Skarels break;
274*34667Skarels }
275*34667Skarels exdent(1);
27629540Ssam }
27729540Ssam }
278