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