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