129540Ssam #ifndef lint 2*31318Ssam static char sccsid[] = "@(#)verify.c 1.3 (Berkeley/CCI) 06/01/87"; 329540Ssam #endif 429540Ssam 529540Ssam #include "vdfmt.h" 629540Ssam 729981Skarels #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 10629981Skarels ** 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 11429981Skarels if (pats == 0) 11529981Skarels return; 11629540Ssam /* verify each track of each cylinder */ 11729981Skarels for (dskaddr.cylinder = base_cyl; 11829981Skarels dskaddr.cylinder < base_cyl + cyl_count; dskaddr.cylinder++) 11929981Skarels for (dskaddr.track = 0; dskaddr.track < CURRENT->vc_ntrak; 12029540Ssam dskaddr.track++) 12129981Skarels verify_track(&dskaddr, pats, verbose); 12229540Ssam } 12329540Ssam 12429540Ssam 12529540Ssam /* 12629981Skarels ** verify_track verifies a single track. If a full-track write fails, 12729981Skarels ** the sector is flagged; if a full-track read fails, then each sector 12829981Skarels ** is read individually to determine which sectors are really bad. 12929981Skarels ** 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; 14329981Skarels int sectorflagged = -1; 14429540Ssam 14529981Skarels if (pats == 0) 14629540Ssam return; 14729540Ssam dskaddr->sector = (char)0; 148*31318Ssam access_dsk((char *)pattern_address[0], dskaddr, VDOP_WD, 14929981Skarels CURRENT->vc_nsec, 1); 15029981Skarels for (index = 0; index < pattern_count; index++) { 15129981Skarels if (!data_ok()) { 15229981Skarels if (dcb.operrsta & HEADER_ERROR) { 15329981Skarels 15429981Skarels flag_sector(dskaddr, dcb.operrsta, 15529981Skarels dcb.err_code, verbosity); 15629540Ssam break; 15729540Ssam } 15829981Skarels if (dcb.operrsta & DATA_ERROR) 15929540Ssam pattern_count = 16; 16029540Ssam } 161*31318Ssam access_dsk((char *)scratch, dskaddr, VDOP_RD, 162*31318Ssam CURRENT->vc_nsec, 1); 16329981Skarels if (!data_ok()) { 16429981Skarels if (dcb.operrsta & HEADER_ERROR) { 16529981Skarels flag_sector(dskaddr, dcb.operrsta, 16629981Skarels dcb.err_code, verbosity); 16729540Ssam break; 16829540Ssam } 16929981Skarels for (i = 0; i < CURRENT->vc_nsec; i++) { 17029540Ssam register long *next; 17129540Ssam 17229540Ssam dskaddr->sector = i; 17329540Ssam next = &scratch[i * offset]; 174*31318Ssam access_dsk((char *)next, dskaddr, VDOP_RD, 1,1); 17529981Skarels if (!data_ok()) 17629981Skarels flag_sector(dskaddr, dcb.operrsta, 17729981Skarels dcb.err_code, verbosity); 17829540Ssam } 17929540Ssam dskaddr->sector = (char)0; 18029540Ssam } 18129981Skarels if (index+1 < pattern_count) 18229540Ssam access_dsk((char *)pattern_address[index+1], 183*31318Ssam dskaddr, VDOP_WD, CURRENT->vc_nsec, 0); 18429540Ssam count = CURRENT->vc_nsec * offset; 18529540Ssam before = *pattern_address[index]; 18629540Ssam after = scratch; 18729981Skarels for (i = 0; i < count; i++) { 18829981Skarels if (before != *(after++)) { 18929981Skarels dskaddr->sector = (char)(i / offset); 19029981Skarels if (dskaddr->sector != sectorflagged) 19129981Skarels flag_sector(dskaddr, 0, 0, 19229981Skarels verbosity); 19329981Skarels sectorflagged = dskaddr->sector; 19429540Ssam } 19529540Ssam } 19629981Skarels if (index+1 < pattern_count) { 19729540Ssam poll(60); 19829981Skarels if (vdtimeout <= 0) { 19929540Ssam printf(" while verifing track.\n"); 20029540Ssam _longjmp(abort_environ, 1); 20129540Ssam } 20229540Ssam } 20329981Skarels if (kill_processes == true) { 20429540Ssam sync_bad_sector_map(); 20529540Ssam _longjmp(quit_environ, 1); 20629540Ssam } 20729540Ssam } 20829540Ssam } 20929540Ssam 21029540Ssam 21129981Skarels flag_sector(dskaddr, status, ecode, verbosity) 21229540Ssam dskadr *dskaddr; 21329540Ssam long status; 21429981Skarels int ecode; 21529981Skarels int verbosity; 21629540Ssam { 21729540Ssam fmt_err error; 21829540Ssam bs_entry entry; 21929540Ssam 22029540Ssam indent(); 22129981Skarels if (verbosity != 0) { 22229981Skarels print("Error at sector %d (cyl %d trk %d sect %d),\n", 22329981Skarels to_sector(*dskaddr), dskaddr->cylinder, dskaddr->track, 22429981Skarels dskaddr->sector); 22529981Skarels if (status) 226*31318Ssam print(" status=%b", status, VDERRBITS); 22729981Skarels else 22829981Skarels printf(" data comparison error"); 229*31318Ssam if (C_INFO.type == VDTYPE_SMDE && ecode) 23029981Skarels printf(", ecode=0x%x", ecode); 23129981Skarels printf(".\n Sector will be relocated.\n"); 23229540Ssam } 23329540Ssam if(is_in_map(dskaddr) == false) { 23429540Ssam error.err_adr = *dskaddr; 23529540Ssam error.err_stat = status; 23629540Ssam entry = (*C_INFO.code_pos)(error); 23729540Ssam add_flaw(&entry); 23829540Ssam } 23929540Ssam exdent(1); 24029540Ssam } 241