129540Ssam #ifndef lint
2*29981Skarels static char sccsid[] = "@(#)verify.c	1.2 (Berkeley/CCI) 11/04/86";
329540Ssam #endif
429540Ssam 
529540Ssam #include	"vdfmt.h"
629540Ssam 
7*29981Skarels #define	verbose	1
829540Ssam 
929540Ssam /*
1029540Ssam **
1129540Ssam */
1229540Ssam 
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);
2029540Ssam 	printf("type %s.\n",CURRENT->vc_name);
2129540Ssam 
2229540Ssam 	if(is_formatted() == true) {
2329540Ssam 		if(read_bad_sector_map() == true) {
2429540Ssam 			if(bad_map->bs_id == D_INFO.id) {
2529540Ssam 				verify_users_data_area();
2629540Ssam 				return;
2729540Ssam 			}
2829540Ssam 		}
2929540Ssam 		print("I can't verify drives with old formats.\n");
3029540Ssam 		return;
3129540Ssam 	}
3229540Ssam 	print("I can't verify unformatted drives.\n");
3329540Ssam }
3429540Ssam 
3529540Ssam 
3629540Ssam /*
3729540Ssam **
3829540Ssam */
3929540Ssam 
4029540Ssam load_verify_patterns()
4129540Ssam {
4229540Ssam 	register int index;
4329540Ssam 	register struct flawpat *fp = CURRENT->vc_pat;
4429540Ssam 
4529540Ssam 	/* Init bad block pattern array */
4629540Ssam 	for(index=0; index<TRKSIZ; index++) {
4729540Ssam 		pattern_0[index] = fp->fp_pat[0];
4829540Ssam 		pattern_1[index] = fp->fp_pat[1];
4929540Ssam 		pattern_2[index] = fp->fp_pat[2];
5029540Ssam 		pattern_3[index] = fp->fp_pat[3];
5129540Ssam 		pattern_4[index] = fp->fp_pat[4];
5229540Ssam 		pattern_5[index] = fp->fp_pat[5];
5329540Ssam 		pattern_6[index] = fp->fp_pat[6];
5429540Ssam 		pattern_7[index] = fp->fp_pat[7];
5529540Ssam 		pattern_8[index] = fp->fp_pat[8];
5629540Ssam 		pattern_9[index] = fp->fp_pat[9];
5729540Ssam 		pattern_10[index] = fp->fp_pat[10];
5829540Ssam 		pattern_12[index] = fp->fp_pat[12];
5929540Ssam 		pattern_13[index] = fp->fp_pat[13];
6029540Ssam 		pattern_14[index] = fp->fp_pat[14];
6129540Ssam 		pattern_15[index] = fp->fp_pat[15];
6229540Ssam 	}
6329540Ssam }
6429540Ssam 
6529540Ssam 
6629540Ssam /*
6729540Ssam **
6829540Ssam */
6929540Ssam 
7029540Ssam verify_relocation_area()
7129540Ssam {
7229540Ssam 	cur.substate = sub_vfy;
7329540Ssam 	verify_cylinders((int)CURRENT->vc_ncyl - NUMSYS, NUMREL, 16);
7429540Ssam 	sync_bad_sector_map();
7529540Ssam }
7629540Ssam 
7729540Ssam 
7829540Ssam /*
7929540Ssam **
8029540Ssam */
8129540Ssam 
8229540Ssam verify_users_data_area()
8329540Ssam {
8429540Ssam 	int	pats = ops_to_do[cur.controller][cur.drive].numpat;
8529540Ssam 
8629540Ssam 	cur.substate = sub_vfy;
8729540Ssam 	verify_cylinders(0, (int)CURRENT->vc_ncyl - NUMSYS, pats);
8829540Ssam 	sync_bad_sector_map();
8929540Ssam }
9029540Ssam 
9129540Ssam 
9229540Ssam /*
9329540Ssam **
9429540Ssam */
9529540Ssam 
9629540Ssam verify_maintainence_area()
9729540Ssam {
9829540Ssam 	cur.substate = sub_vfy;
9929540Ssam 	verify_cylinders(CURRENT->vc_ncyl - NUMSYS + NUMREL, NUMMNT, 16);
10029540Ssam 	sync_bad_sector_map();
10129540Ssam }
10229540Ssam 
10329540Ssam 
10429540Ssam /*
10529540Ssam **	verify_cylinders does full track certification for every track
106*29981Skarels ** on the cylinder.
10729540Ssam */
10829540Ssam 
10929540Ssam verify_cylinders(base_cyl, cyl_count, pats)
11029540Ssam int	base_cyl, cyl_count, pats;
11129540Ssam {
11229540Ssam 	dskadr		dskaddr;
11329540Ssam 
114*29981Skarels 	if (pats == 0)
115*29981Skarels 		return;
11629540Ssam 	/* verify each track of each cylinder */
117*29981Skarels 	for (dskaddr.cylinder = base_cyl;
118*29981Skarels 	    dskaddr.cylinder < base_cyl + cyl_count; dskaddr.cylinder++)
119*29981Skarels 		for (dskaddr.track = 0; dskaddr.track < CURRENT->vc_ntrak;
12029540Ssam 		    dskaddr.track++)
121*29981Skarels 			verify_track(&dskaddr, pats, verbose);
12229540Ssam }
12329540Ssam 
12429540Ssam 
12529540Ssam /*
126*29981Skarels **	verify_track verifies a single track.  If a full-track write fails,
127*29981Skarels ** the sector is flagged; if a full-track read fails, then each sector
128*29981Skarels ** is read individually to determine which sectors are really bad.
129*29981Skarels ** If a sector is bad it is flagged as bad by flag_sector.
13029540Ssam */
13129540Ssam 
13229540Ssam verify_track(dskaddr, pats, verbosity)
13329540Ssam dskadr	*dskaddr;
13429540Ssam int	pats;
13529540Ssam int	verbosity;
13629540Ssam {
13729540Ssam 	register int	index, i;
13829540Ssam 	register int	count;
13929540Ssam 	register long	before;
14029540Ssam 	register long	*after;
14129540Ssam 	register long	offset = SECSIZ / sizeof(long);
14229540Ssam 	int		pattern_count = pats;
143*29981Skarels 	int		sectorflagged = -1;
14429540Ssam 
145*29981Skarels 	if (pats == 0)
14629540Ssam 		return;
14729540Ssam 	dskaddr->sector = (char)0;
148*29981Skarels 	access_dsk((char *)pattern_address[0], dskaddr, WD,
149*29981Skarels 	    CURRENT->vc_nsec, 1);
150*29981Skarels 	for (index = 0; index < pattern_count; index++) {
151*29981Skarels 		if (!data_ok()) {
152*29981Skarels 			if (dcb.operrsta & HEADER_ERROR)  {
153*29981Skarels 
154*29981Skarels 				flag_sector(dskaddr, dcb.operrsta,
155*29981Skarels 				    dcb.err_code, verbosity);
15629540Ssam 				break;
15729540Ssam 			}
158*29981Skarels 			if (dcb.operrsta & DATA_ERROR)
15929540Ssam 				pattern_count = 16;
16029540Ssam 		}
161*29981Skarels 		access_dsk((char *)scratch, dskaddr, RD, CURRENT->vc_nsec, 1);
162*29981Skarels 		if (!data_ok()) {
163*29981Skarels 			if (dcb.operrsta & HEADER_ERROR)  {
164*29981Skarels 				flag_sector(dskaddr, dcb.operrsta,
165*29981Skarels 				    dcb.err_code, verbosity);
16629540Ssam 				break;
16729540Ssam 			}
168*29981Skarels 			for (i = 0; i < CURRENT->vc_nsec; i++) {
16929540Ssam 				register long	*next;
17029540Ssam 
17129540Ssam 				dskaddr->sector = i;
17229540Ssam 				next = &scratch[i * offset];
173*29981Skarels 				access_dsk((char *)next, dskaddr, RD, 1, 1);
174*29981Skarels 				if (!data_ok())
175*29981Skarels 					flag_sector(dskaddr, dcb.operrsta,
176*29981Skarels 					    dcb.err_code, verbosity);
17729540Ssam 			}
17829540Ssam 			dskaddr->sector = (char)0;
17929540Ssam 		}
180*29981Skarels 		if (index+1 < pattern_count)
18129540Ssam 			access_dsk((char *)pattern_address[index+1],
18229540Ssam 			    dskaddr, WD, CURRENT->vc_nsec, 0);
18329540Ssam 		count = CURRENT->vc_nsec * offset;
18429540Ssam 		before = *pattern_address[index];
18529540Ssam 		after = scratch;
186*29981Skarels 		for (i = 0; i < count; i++) {
187*29981Skarels 			if (before != *(after++)) {
188*29981Skarels 				dskaddr->sector = (char)(i / offset);
189*29981Skarels 				if (dskaddr->sector != sectorflagged)
190*29981Skarels 					flag_sector(dskaddr, 0, 0,
191*29981Skarels 					    verbosity);
192*29981Skarels 				sectorflagged = dskaddr->sector;
19329540Ssam 			}
19429540Ssam 		}
195*29981Skarels 		if (index+1 < pattern_count) {
19629540Ssam 			poll(60);
197*29981Skarels 			if (vdtimeout <= 0) {
19829540Ssam 				printf(" while verifing track.\n");
19929540Ssam 				_longjmp(abort_environ, 1);
20029540Ssam 			}
20129540Ssam 		}
202*29981Skarels 		if (kill_processes == true) {
20329540Ssam 			sync_bad_sector_map();
20429540Ssam 			_longjmp(quit_environ, 1);
20529540Ssam 		}
20629540Ssam 	}
20729540Ssam }
20829540Ssam 
20929540Ssam 
210*29981Skarels flag_sector(dskaddr, status, ecode, verbosity)
21129540Ssam dskadr	*dskaddr;
21229540Ssam long	status;
213*29981Skarels int	ecode;
214*29981Skarels int	verbosity;
21529540Ssam {
21629540Ssam 	fmt_err		error;
21729540Ssam 	bs_entry	entry;
21829540Ssam 
21929540Ssam 	indent();
220*29981Skarels 	if (verbosity != 0) {
221*29981Skarels 		print("Error at sector %d (cyl %d trk %d sect %d),\n",
222*29981Skarels 		    to_sector(*dskaddr), dskaddr->cylinder, dskaddr->track,
223*29981Skarels 		    dskaddr->sector);
224*29981Skarels 		if (status)
225*29981Skarels 			print("  status=%b", status, ERRBITS);
226*29981Skarels 		else
227*29981Skarels 			printf("  data comparison error");
228*29981Skarels 		if (C_INFO.type == SMD_ECTLR && ecode)
229*29981Skarels 			printf(", ecode=0x%x", ecode);
230*29981Skarels 		printf(".\n  Sector will be relocated.\n");
23129540Ssam 	}
23229540Ssam 	if(is_in_map(dskaddr) == false) {
23329540Ssam 		error.err_adr = *dskaddr;
23429540Ssam 		error.err_stat = status;
23529540Ssam 		entry = (*C_INFO.code_pos)(error);
23629540Ssam 		add_flaw(&entry);
23729540Ssam 	}
23829540Ssam 	exdent(1);
23929540Ssam }
240