1*29540Ssam #ifndef lint
2*29540Ssam static char sccsid[] = "@(#)verify.c	1.1 (Berkeley/CCI) 07/05/86";
3*29540Ssam #endif
4*29540Ssam 
5*29540Ssam #include	"vdfmt.h"
6*29540Ssam 
7*29540Ssam #define	quiet 0
8*29540Ssam 
9*29540Ssam /*
10*29540Ssam **
11*29540Ssam */
12*29540Ssam 
13*29540Ssam verify()
14*29540Ssam {
15*29540Ssam 	extern boolean	read_bad_sector_map();
16*29540Ssam 
17*29540Ssam 	cur.state = vfy;
18*29540Ssam 	print("Starting verification on ");
19*29540Ssam 	printf("controller %d, drive %d, ", cur.controller, cur.drive);
20*29540Ssam 	printf("type %s.\n",CURRENT->vc_name);
21*29540Ssam 
22*29540Ssam 	if(is_formatted() == true) {
23*29540Ssam 		if(read_bad_sector_map() == true) {
24*29540Ssam 			if(bad_map->bs_id == D_INFO.id) {
25*29540Ssam 				verify_users_data_area();
26*29540Ssam 				return;
27*29540Ssam 			}
28*29540Ssam 		}
29*29540Ssam 		print("I can't verify drives with old formats.\n");
30*29540Ssam 		return;
31*29540Ssam 	}
32*29540Ssam 	print("I can't verify unformatted drives.\n");
33*29540Ssam }
34*29540Ssam 
35*29540Ssam 
36*29540Ssam /*
37*29540Ssam **
38*29540Ssam */
39*29540Ssam 
40*29540Ssam load_verify_patterns()
41*29540Ssam {
42*29540Ssam 	register int index;
43*29540Ssam 	register struct flawpat *fp = CURRENT->vc_pat;
44*29540Ssam 
45*29540Ssam 	/* Init bad block pattern array */
46*29540Ssam 	for(index=0; index<TRKSIZ; index++) {
47*29540Ssam 		pattern_0[index] = fp->fp_pat[0];
48*29540Ssam 		pattern_1[index] = fp->fp_pat[1];
49*29540Ssam 		pattern_2[index] = fp->fp_pat[2];
50*29540Ssam 		pattern_3[index] = fp->fp_pat[3];
51*29540Ssam 		pattern_4[index] = fp->fp_pat[4];
52*29540Ssam 		pattern_5[index] = fp->fp_pat[5];
53*29540Ssam 		pattern_6[index] = fp->fp_pat[6];
54*29540Ssam 		pattern_7[index] = fp->fp_pat[7];
55*29540Ssam 		pattern_8[index] = fp->fp_pat[8];
56*29540Ssam 		pattern_9[index] = fp->fp_pat[9];
57*29540Ssam 		pattern_10[index] = fp->fp_pat[10];
58*29540Ssam 		pattern_12[index] = fp->fp_pat[12];
59*29540Ssam 		pattern_13[index] = fp->fp_pat[13];
60*29540Ssam 		pattern_14[index] = fp->fp_pat[14];
61*29540Ssam 		pattern_15[index] = fp->fp_pat[15];
62*29540Ssam 	}
63*29540Ssam }
64*29540Ssam 
65*29540Ssam 
66*29540Ssam /*
67*29540Ssam **
68*29540Ssam */
69*29540Ssam 
70*29540Ssam verify_relocation_area()
71*29540Ssam {
72*29540Ssam 	cur.substate = sub_vfy;
73*29540Ssam 	verify_cylinders((int)CURRENT->vc_ncyl - NUMSYS, NUMREL, 16);
74*29540Ssam 	sync_bad_sector_map();
75*29540Ssam }
76*29540Ssam 
77*29540Ssam 
78*29540Ssam /*
79*29540Ssam **
80*29540Ssam */
81*29540Ssam 
82*29540Ssam verify_users_data_area()
83*29540Ssam {
84*29540Ssam 	int	pats = ops_to_do[cur.controller][cur.drive].numpat;
85*29540Ssam 
86*29540Ssam 	cur.substate = sub_vfy;
87*29540Ssam 	verify_cylinders(0, (int)CURRENT->vc_ncyl - NUMSYS, pats);
88*29540Ssam 	sync_bad_sector_map();
89*29540Ssam }
90*29540Ssam 
91*29540Ssam 
92*29540Ssam /*
93*29540Ssam **
94*29540Ssam */
95*29540Ssam 
96*29540Ssam verify_maintainence_area()
97*29540Ssam {
98*29540Ssam 	cur.substate = sub_vfy;
99*29540Ssam 	verify_cylinders(CURRENT->vc_ncyl - NUMSYS + NUMREL, NUMMNT, 16);
100*29540Ssam 	sync_bad_sector_map();
101*29540Ssam }
102*29540Ssam 
103*29540Ssam 
104*29540Ssam /*
105*29540Ssam **	verify_cylinders does full track certification for every track
106*29540Ssam ** on the cylinder.  This is done for speed and minimal head movement.  If
107*29540Ssam ** an error occurs on any single track the track is flagged for later
108*29540Ssam ** verification by verify sectors.
109*29540Ssam */
110*29540Ssam 
111*29540Ssam verify_cylinders(base_cyl, cyl_count, pats)
112*29540Ssam int	base_cyl, cyl_count, pats;
113*29540Ssam {
114*29540Ssam 	dskadr		dskaddr;
115*29540Ssam 
116*29540Ssam 	/* verify each track of each cylinder */
117*29540Ssam 	for (dskaddr.cylinder=base_cyl; dskaddr.cylinder<(base_cyl+cyl_count);
118*29540Ssam 	    dskaddr.cylinder++)
119*29540Ssam 		for (dskaddr.track=0; dskaddr.track<CURRENT->vc_ntrak;
120*29540Ssam 		    dskaddr.track++)
121*29540Ssam 			verify_track(&dskaddr, pats, quiet);
122*29540Ssam }
123*29540Ssam 
124*29540Ssam 
125*29540Ssam /*
126*29540Ssam **	verify_track verifies a single track. If the full track write and
127*29540Ssam ** compare operation fails then each sector is read individually to determin
128*29540Ssam ** which sectors are really bad.  If a sector is bad it is flagged as bad by
129*29540Ssam ** the verify sector routine.
130*29540Ssam */
131*29540Ssam 
132*29540Ssam verify_track(dskaddr, pats, verbosity)
133*29540Ssam dskadr	*dskaddr;
134*29540Ssam int	pats;
135*29540Ssam int	verbosity;
136*29540Ssam {
137*29540Ssam 	register int	index, i;
138*29540Ssam 	register int	count;
139*29540Ssam 	register long	before;
140*29540Ssam 	register long	*after;
141*29540Ssam 	register long	offset = SECSIZ / sizeof(long);
142*29540Ssam 	int		pattern_count = pats;
143*29540Ssam 
144*29540Ssam 	if(pats == 0)
145*29540Ssam 		return;
146*29540Ssam 	dskaddr->sector = (char)0;
147*29540Ssam 	access_dsk((char *)pattern_address[0], dskaddr, WD, CURRENT->vc_nsec, 1);
148*29540Ssam 	for(index = 0; index < pattern_count; index++) {
149*29540Ssam 		if(!data_ok()) {
150*29540Ssam 			if(dcb.operrsta & HEADER_ERROR)  {
151*29540Ssam 				flag_sector(dskaddr, dcb.operrsta, verbosity);
152*29540Ssam 				break;
153*29540Ssam 			}
154*29540Ssam 			if(dcb.operrsta & DATA_ERROR)
155*29540Ssam 				pattern_count = 16;
156*29540Ssam 		}
157*29540Ssam 		access_dsk((char *)scratch,dskaddr,RD,CURRENT->vc_nsec,1);
158*29540Ssam 		if(!data_ok()) {
159*29540Ssam 			if(dcb.operrsta & HEADER_ERROR)  {
160*29540Ssam 				flag_sector(dskaddr, dcb.operrsta, verbosity);
161*29540Ssam 				break;
162*29540Ssam 			}
163*29540Ssam 			pattern_count = 16;
164*29540Ssam 			for(i = 0; i < CURRENT->vc_nsec; i++) {
165*29540Ssam 				register long	*next;
166*29540Ssam 
167*29540Ssam 				dskaddr->sector = i;
168*29540Ssam 				next = &scratch[i * offset];
169*29540Ssam 				access_dsk((char *)next,dskaddr,RD,1,1);
170*29540Ssam 				if(!data_ok()) {
171*29540Ssam 					flag_sector(dskaddr,
172*29540Ssam 					    dcb.operrsta,verbosity);
173*29540Ssam 				}
174*29540Ssam 			}
175*29540Ssam 			dskaddr->sector = (char)0;
176*29540Ssam 		}
177*29540Ssam 		if(index+1 < pattern_count)
178*29540Ssam 			access_dsk((char *)pattern_address[index+1],
179*29540Ssam 			    dskaddr, WD, CURRENT->vc_nsec, 0);
180*29540Ssam 		count = CURRENT->vc_nsec * offset;
181*29540Ssam 		before = *pattern_address[index];
182*29540Ssam 		after = scratch;
183*29540Ssam 		for(i=0; i<count; i++) {
184*29540Ssam 			if(before != *(after++)) {
185*29540Ssam 				dskaddr->sector = i / offset;
186*29540Ssam 				flag_sector(dskaddr, DATA_ERROR, verbosity);
187*29540Ssam 			}
188*29540Ssam 		}
189*29540Ssam 		if(index+1 <= pattern_count) {
190*29540Ssam 			poll(60);
191*29540Ssam 			if(vdtimeout <= 0) {
192*29540Ssam 				printf(" while verifing track.\n");
193*29540Ssam 				_longjmp(abort_environ, 1);
194*29540Ssam 			}
195*29540Ssam 		}
196*29540Ssam 		if(kill_processes == true) {
197*29540Ssam 			sync_bad_sector_map();
198*29540Ssam 			_longjmp(quit_environ, 1);
199*29540Ssam 		}
200*29540Ssam 	}
201*29540Ssam }
202*29540Ssam 
203*29540Ssam 
204*29540Ssam flag_sector(dskaddr, status, verbose)
205*29540Ssam dskadr	*dskaddr;
206*29540Ssam long	status;
207*29540Ssam int	verbose;
208*29540Ssam {
209*29540Ssam 	fmt_err		error;
210*29540Ssam 	bs_entry	entry;
211*29540Ssam 
212*29540Ssam 	indent();
213*29540Ssam 	if(verbose) {
214*29540Ssam 		print("Error at sector %d, status=0x%x.",
215*29540Ssam 		    to_sector(*dskaddr), status);
216*29540Ssam 		printf("  Sector will be relocated.\n");
217*29540Ssam 	}
218*29540Ssam 	if(is_in_map(dskaddr) == false) {
219*29540Ssam 		error.err_adr = *dskaddr;
220*29540Ssam 		error.err_stat = status;
221*29540Ssam 		entry = (*C_INFO.code_pos)(error);
222*29540Ssam 		add_flaw(&entry);
223*29540Ssam 	}
224*29540Ssam 	exdent(1);
225*29540Ssam }
226