129533Ssam #ifndef lint 2*34667Skarels static char sccsid[] = "@(#)maps.c 1.7 (Berkeley/CCI) 06/07/88"; 329533Ssam #endif 429533Ssam 529533Ssam 629533Ssam #include "vdfmt.h" 729533Ssam 829533Ssam 929533Ssam /* 1029533Ssam ** 1129533Ssam */ 1229533Ssam 1329533Ssam boolean align_buf(buf, sync) 1429533Ssam unsigned long *buf; 1529533Ssam unsigned long sync; 1629533Ssam { 1729533Ssam register int i, shift; 1829533Ssam 1929533Ssam /* find shift amount */ 2032662Skarels for(shift=0; shift < 32; shift++) { 2129533Ssam if((*buf >> shift ) == sync) { 2229533Ssam for(i=(512/sizeof(long))-1; i >= 0; i--) { 2329533Ssam *(buf+i+1) |= *(buf+i) << (32 - shift); 2429533Ssam *(buf+i) = *(buf+i) >> shift; 2529533Ssam } 2629533Ssam return true; 2729533Ssam } 2829533Ssam } 2929533Ssam return false; 3029533Ssam } 3129533Ssam 3229533Ssam 3329533Ssam /* 3429533Ssam ** Looks for two maps in a row that are the same. 3529533Ssam */ 3629533Ssam 3729981Skarels boolean 3829981Skarels read_map(flags) 3929533Ssam short flags; 4029533Ssam { 4129533Ssam register int trk, i; 4229533Ssam dskadr dskaddr; 4329533Ssam 4432662Skarels dskaddr.cylinder = (lab->d_ncylinders - 1) | flags; 4532662Skarels for(i=0; i < 100; i++) 4629533Ssam scratch[i] = -1; 4732662Skarels for(trk=0; trk < lab->d_ntracks; trk++) { 4829533Ssam dskaddr.track = trk; 4929533Ssam dskaddr.sector = 0; 5031318Ssam if(access_dsk((char *)save,&dskaddr, VDOP_RD, 5132662Skarels lab->d_nsectors,1)& VDERR_HARD) 5229533Ssam continue; 5334558Skarels if(bcmp((char *)scratch, (char *)save, bytes_trk) == true) { 5434558Skarels bcopy((char *)save, (char *)bad_map, bytes_trk); 5529533Ssam if(bad_map->bs_count <= MAX_FLAWS) { 5632662Skarels for(i=0; i < bad_map->bs_count; i++) { 5729533Ssam if(bad_map->list[i].bs_cyl >= 5832662Skarels lab->d_ncylinders) 5929533Ssam break; 6029533Ssam if(bad_map->list[i].bs_trk >= 6132662Skarels lab->d_ntracks) 6229533Ssam break; 6329533Ssam if(bad_map->list[i].bs_offset >= 6432662Skarels lab->d_traksize) 6529533Ssam break; 6629533Ssam } 6729533Ssam if(i == bad_map->bs_count) { 6829533Ssam load_free_table(); 6929533Ssam return true; 7029533Ssam } 7129981Skarels } 7234558Skarels bzero(bad_map, bytes_trk); 7329533Ssam bad_map->bs_id = 0; 7429533Ssam bad_map->bs_max = MAX_FLAWS; 7529533Ssam } 7634558Skarels bcopy((char *)save, (char *)scratch, bytes_trk); 7729533Ssam } 7829533Ssam return false; 7929533Ssam } 8029533Ssam 8129533Ssam 8229533Ssam /* 8329533Ssam ** 8429533Ssam */ 8529533Ssam 8629533Ssam boolean read_bad_sector_map() 8729533Ssam { 8829533Ssam dskadr dskaddr; 8929533Ssam 9032662Skarels dskaddr.cylinder = lab->d_ncylinders - 1; 9129533Ssam dskaddr.track = 0; 9229533Ssam dskaddr.sector = 0; 9329533Ssam /* start with nothing in map */ 9434558Skarels bzero(bad_map, bytes_trk); 9529533Ssam bad_map->bs_id = 0; 9629533Ssam bad_map->bs_max = MAX_FLAWS; 9732662Skarels if (C_INFO->type == VDTYPE_SMDE) { 9831318Ssam access_dsk((char *)save, &dskaddr, VDOP_RDRAW, 1, 1); 9929981Skarels if (align_buf((unsigned long *)save, CDCSYNC) == true) { 10029533Ssam read_flaw_map(); 10129981Skarels return (false); 10229981Skarels } else if (read_map(NRM) == true) { 10329981Skarels return (true); 10429981Skarels } else { 10529533Ssam get_smde_relocations(); 10629533Ssam return false; 10729533Ssam } 10829981Skarels } else { 10929981Skarels if (read_map(WPT) == true) 11029981Skarels return (true); 11129981Skarels else { 11229981Skarels get_relocations_the_hard_way(); 11329981Skarels return (false); 11429981Skarels } 11529533Ssam } 11629533Ssam } 11729533Ssam 11829533Ssam 11929533Ssam /* 12029533Ssam ** 12129533Ssam */ 12229533Ssam 12329533Ssam get_relocations_the_hard_way() 12429533Ssam { 12529533Ssam register int cyl, trk; 12629533Ssam register int status; 12729533Ssam dskadr dskaddr; 12829533Ssam 12929533Ssam dskaddr.sector = 0; 13029533Ssam /* scan each sector to see if it is relocated and take note if it is */ 13132662Skarels for(cyl=0; cyl < lab->d_ncylinders - NUMSYS; cyl++) { 13229533Ssam dskaddr.cylinder = cyl; 13332662Skarels for(trk=0; trk < lab->d_ntracks; trk++) { 13429533Ssam dskaddr.track = trk; 13529533Ssam status=access_dsk((char *)scratch, &dskaddr, 13632662Skarels VDOP_RD, lab->d_nsectors, 1); 13731318Ssam if(status & DCBS_ATA) 13829533Ssam get_track_relocations(dskaddr); 13929533Ssam } 14029533Ssam } 14129533Ssam load_free_table(); 14229533Ssam } 14329533Ssam 14429533Ssam 14529533Ssam /* 14629533Ssam ** 14729533Ssam */ 14829533Ssam 14929533Ssam get_track_relocations(dskaddr) 15029533Ssam dskadr dskaddr; 15129533Ssam { 15229533Ssam register int status; 15329533Ssam bs_entry temp; 15429533Ssam fmt_err error; 15529533Ssam 15632662Skarels for(dskaddr.sector=0; dskaddr.sector < lab->d_nsectors; dskaddr.sector++) { 15731318Ssam status = access_dsk((char *)scratch, &dskaddr, VDOP_RD, 1, 1); 15831318Ssam if(status & DCBS_ATA) { 15929533Ssam error.err_adr = dskaddr; 16029533Ssam error.err_stat = DATA_ERROR; 161*34667Skarels (*C_INFO->code_pos)(&error, &temp); 16229533Ssam temp.bs_how = operator; 16329533Ssam add_flaw(&temp); 16429533Ssam } 16529533Ssam } 16629533Ssam } 16729533Ssam 16829533Ssam 16929533Ssam /* 17029533Ssam ** 17129533Ssam */ 17229533Ssam 17329533Ssam remove_user_relocations(entry) 174*34667Skarels bs_entry *entry; 17529533Ssam { 17629533Ssam register int i, j; 17729533Ssam fmt_err temp; 17829533Ssam fmt_err error; 179*34667Skarels register bs_entry *ptr; 18029533Ssam 181*34667Skarels (*C_INFO->decode_pos)(entry, &error); 182*34667Skarels ptr = bad_map->list; 183*34667Skarels for(i=0; i < bad_map->bs_count; i++) { 184*34667Skarels if (ptr->bs_cyl != entry->bs_cyl || 185*34667Skarels ptr->bs_trk != entry->bs_trk) 186*34667Skarels continue; 187*34667Skarels (*C_INFO->decode_pos)(ptr, &temp); 188*34667Skarels if((ptr->bs_how != flaw_map) && 189*34667Skarels (temp.err_adr.cylinder == error.err_adr.cylinder) && 190*34667Skarels (temp.err_adr.track == error.err_adr.track) && 191*34667Skarels (temp.err_adr.sector == error.err_adr.sector)) { 192*34667Skarels if(temp.err_stat & HEADER_ERROR) 193*34667Skarels remove_track(&temp, ptr); 194*34667Skarels else 195*34667Skarels remove_sector(&temp, ptr); 196*34667Skarels for(j=i+1; j < bad_map->bs_count; j++) 197*34667Skarels bad_map->list[j-1] = bad_map->list[j]; 198*34667Skarels bad_map->bs_count--; 199*34667Skarels return; 200*34667Skarels } 201*34667Skarels ptr++; 202*34667Skarels } 203*34667Skarels indent(); 204*34667Skarels print("Sector %d is not in bad sector map!\n", 205*34667Skarels to_sector(error.err_adr)); 206*34667Skarels exdent(1); 207*34667Skarels } 208*34667Skarels 209*34667Skarels clear_relocations(reformat) 210*34667Skarels boolean reformat; 211*34667Skarels { 212*34667Skarels fmt_err temp; 213*34667Skarels register bs_entry *ptr1, *ptr2, *end; 214*34667Skarels int oldsub = cur.substate; 215*34667Skarels 216*34667Skarels cur.substate = sub_rel; 217*34667Skarels ptr1 = bad_map->list; 218*34667Skarels ptr2 = bad_map->list; 219*34667Skarels end = &bad_map->list[bad_map->bs_count]; 220*34667Skarels for (; ptr1 < end; ptr1++) { 221*34667Skarels if (ptr1->bs_how != flaw_map) { 222*34667Skarels if (reformat == true) { 223*34667Skarels (*C_INFO->decode_pos)(ptr1, &temp); 22429533Ssam if(temp.err_stat & HEADER_ERROR) 225*34667Skarels remove_track(&temp, ptr1); 22629533Ssam else 227*34667Skarels remove_sector(&temp, ptr1); 22829533Ssam } 229*34667Skarels bad_map->bs_count--; 230*34667Skarels } else { 231*34667Skarels if (ptr1 != ptr2) 232*34667Skarels *ptr2 = *ptr1; 233*34667Skarels ptr2++; 23429533Ssam } 23529533Ssam } 236*34667Skarels cur.substate = oldsub; 23729533Ssam } 23829533Ssam 23929533Ssam 24029533Ssam /* 24129533Ssam ** 24229533Ssam */ 24329533Ssam 24429533Ssam remove_sector(error, entry) 245*34667Skarels fmt_err *error; 24629533Ssam bs_entry *entry; 24729533Ssam { 248*34667Skarels format_sectors(&error->err_adr, &error->err_adr, NRM, 1); 24929533Ssam format_sectors(&entry->bs_alt, &entry->bs_alt, NRM, 1); 25029533Ssam } 25129533Ssam 25229533Ssam 25329533Ssam /* 25429533Ssam ** 25529533Ssam */ 25629533Ssam 25729533Ssam remove_track(error, entry) 258*34667Skarels fmt_err *error; 25929533Ssam bs_entry *entry; 26029533Ssam { 261*34667Skarels format_sectors(&error->err_adr,&error->err_adr,NRM,(long)lab->d_nsectors); 26232662Skarels format_sectors(&entry->bs_alt,&entry->bs_alt,NRM,(long)lab->d_nsectors); 26329533Ssam } 26429533Ssam 26529533Ssam 26629533Ssam /* 26729533Ssam ** 26829533Ssam */ 26929533Ssam 27029533Ssam write_bad_sector_map() 27129533Ssam { 27229533Ssam register int trk, sec; 27329533Ssam dskadr dskaddr; 27429533Ssam 27532662Skarels dskaddr.cylinder = (lab->d_ncylinders - NUMMAP); 27632662Skarels for(trk=0; trk < lab->d_ntracks; trk++) { 27732662Skarels for(sec = 0; sec < lab->d_nsectors; sec++) { 27834558Skarels bcopy((char *)bs_map_space + (sec * lab->d_secsize), 27932662Skarels (char *)scratch, lab->d_secsize); 28029533Ssam dskaddr.track = trk; 28129533Ssam dskaddr.sector = sec; 28229533Ssam format_sectors(&dskaddr, &dskaddr, WPT, 1); 28329533Ssam } 28429533Ssam } 28529533Ssam } 28629533Ssam 28729533Ssam 28829533Ssam /* 28929533Ssam ** 29029533Ssam */ 29129533Ssam 29229533Ssam zero_bad_sector_map() 29329533Ssam { 29429533Ssam bs_map *bm = bad_map; 29529533Ssam register int i; 29629533Ssam dskadr zero; 29729533Ssam 29829533Ssam zero.cylinder = 0; 29929533Ssam zero.track = 0; 30029533Ssam zero.sector = 0; 30132662Skarels for(i=0; i < bm->bs_count; i++) 30229533Ssam bm->list[i].bs_alt = zero; 30329533Ssam load_free_table(); 30429533Ssam } 30529533Ssam 30629533Ssam 30729533Ssam /* 30829533Ssam ** 30929533Ssam */ 31029533Ssam 31129533Ssam read_flaw_map() 31229533Ssam { 31329533Ssam register int cyl, trk; 31429533Ssam dskadr dskaddr; 31529533Ssam flaw buffer; 31629533Ssam 31729533Ssam dskaddr.sector = 0; 31832662Skarels for (cyl=0; cyl < lab->d_ncylinders; cyl++) { 31929533Ssam dskaddr.cylinder = cyl; 32032662Skarels for (trk=0; trk < lab->d_ntracks; trk++) { 32129533Ssam dskaddr.track = trk; 32231318Ssam access_dsk(&buffer, &dskaddr, VDOP_RDRAW, 1, 1); 32329533Ssam if(align_buf(&buffer, CDCSYNC) == true) { 32429533Ssam add_flaw_entries(&buffer); 32529533Ssam continue; 32629533Ssam } 32729533Ssam } 32829533Ssam } 32929533Ssam load_free_table(); 33029533Ssam } 33129533Ssam 33229533Ssam 33329533Ssam /* 33429533Ssam ** 33529533Ssam */ 33629533Ssam 33729533Ssam get_smde_relocations() 33829533Ssam { 33929533Ssam register int cyl, trk, sec; 34029533Ssam smde_hdr buffer; 34129533Ssam dskadr dskaddr; 34229533Ssam fmt_err bad; 34329533Ssam bs_entry temp; 34429533Ssam boolean bad_track; 34529533Ssam 34629533Ssam /* Read any old drive relocations */ 34732662Skarels for(cyl=0; cyl < NUMREL; cyl++) { 34832662Skarels dskaddr.cylinder = lab->d_ncylinders - NUMSYS + cyl; 34932662Skarels for(trk=0; trk < lab->d_ntracks; trk++) { 35029533Ssam dskaddr.track = trk; 35129533Ssam bad_track = true; 35232662Skarels for(sec=0; sec < lab->d_nsectors; sec++) { 35329533Ssam dskaddr.sector = sec; 35431318Ssam access_dsk(&buffer, &dskaddr, VDOP_RDRAW, 1, 1); 35529533Ssam if(align_buf(&buffer, SMDE1SYNC) == false) { 35629533Ssam bad_track = false; 35729533Ssam break; 35829533Ssam } 35929533Ssam } 36029533Ssam if(bad_track == true) { 36129533Ssam dskaddr.sector = 0; 36229533Ssam bad.err_adr.cylinder = buffer.alt_cyl; 36329533Ssam bad.err_adr.track = buffer.alt_trk; 36429533Ssam bad.err_adr.sector = 0; 36529533Ssam bad.err_stat = HEADER_ERROR; 366*34667Skarels (*C_INFO->code_pos)(&bad, &temp); 36729533Ssam temp.bs_alt = dskaddr; 36829533Ssam temp.bs_how = scanning; 36929533Ssam add_flaw(&temp); 37029533Ssam continue; 37129533Ssam } 37232662Skarels for(sec=0; sec < lab->d_nsectors; sec++) { 37329533Ssam dskaddr.sector = sec; 37431318Ssam access_dsk(&buffer, &dskaddr, VDOP_RDRAW, 1, 1); 37529533Ssam if(align_buf(&buffer, SMDE1SYNC) == true) { 37629533Ssam bad.err_adr.cylinder = buffer.alt_cyl; 37729533Ssam bad.err_adr.track = buffer.alt_trk; 37829533Ssam bad.err_adr.sector = buffer.alt_sec; 37929533Ssam bad.err_stat = DATA_ERROR; 380*34667Skarels (*C_INFO->code_pos)(&bad, &temp); 38129533Ssam temp.bs_alt = dskaddr; 38229533Ssam temp.bs_how = scanning; 38329533Ssam add_flaw(&temp); 38429533Ssam } 38529533Ssam } 38629533Ssam } 38729533Ssam } 38829533Ssam load_free_table(); 38929533Ssam } 39029533Ssam 39129533Ssam 39229533Ssam /* 39329533Ssam ** 39429533Ssam */ 39529533Ssam 39629533Ssam add_flaw_entries(buffer) 39729533Ssam flaw *buffer; 39829533Ssam { 39929533Ssam register int i; 40029533Ssam bs_entry temp; 40129533Ssam 40229533Ssam temp.bs_cyl = buffer->flaw_cyl & 0x7fff; /* clear off bad track bit */ 40329533Ssam temp.bs_trk = buffer->flaw_trk; 40432662Skarels for(i=0; i < 4; i++) { 40529533Ssam if(buffer->flaw_pos[i].flaw_length != 0) { 40629533Ssam temp.bs_offset = buffer->flaw_pos[i].flaw_offset; 40729533Ssam temp.bs_length = buffer->flaw_pos[i].flaw_length; 40829533Ssam temp.bs_alt.cylinder = 0; 40929533Ssam temp.bs_alt.track = 0; 41029533Ssam temp.bs_alt.sector = 0; 41129533Ssam temp.bs_how = flaw_map; 41229533Ssam add_flaw(&temp); 41329533Ssam } 41429533Ssam } 41529533Ssam } 41629533Ssam 41729533Ssam 41829533Ssam cmp_entry(a, b) 41929533Ssam bs_entry *a; 42029533Ssam bs_entry *b; 42129533Ssam { 42229533Ssam if(a->bs_cyl == b->bs_cyl) { 42329533Ssam if(a->bs_trk == b->bs_trk) { 42429533Ssam if(a->bs_offset == b->bs_offset) 42529533Ssam return 0; 42629533Ssam else if(a->bs_offset < b->bs_offset) 42729533Ssam return -1; 42829981Skarels } 42929533Ssam else if(a->bs_trk < b->bs_trk) 43029533Ssam return -1; 43129533Ssam } 43229533Ssam else if(a->bs_cyl < b->bs_cyl) 43329533Ssam return -1; 43429533Ssam return 1; 43529533Ssam } 43629533Ssam 43729533Ssam 438*34667Skarels /* 439*34667Skarels * Add flaw to map. 440*34667Skarels * Return value: 441*34667Skarels * 1 OK 442*34667Skarels * 0 sector was in map 443*34667Skarels * -1 failure 444*34667Skarels */ 44529533Ssam add_flaw(entry) 44629533Ssam bs_entry *entry; 44729533Ssam { 44829533Ssam extern int cmp_entry(); 44929533Ssam bs_map *bm = bad_map; 45029533Ssam register int i; 45129533Ssam 45229533Ssam if(bm->bs_count > MAX_FLAWS) 453*34667Skarels return (-1); 45432662Skarels if (entry->bs_cyl >= lab->d_ncylinders || 45532662Skarels entry->bs_trk >= lab->d_ntracks || 45632662Skarels entry->bs_offset >= lab->d_traksize) 457*34667Skarels return (-1); 45832662Skarels for(i=0; i < bm->bs_count; i++) { 45929533Ssam if(((bm->list[i].bs_cyl == entry->bs_cyl)) && 46029533Ssam (bm->list[i].bs_trk == entry->bs_trk) && 46129533Ssam (bm->list[i].bs_offset == entry->bs_offset)) { 46229533Ssam if((int)bm->list[i].bs_how > (int)entry->bs_how) 46329533Ssam bm->list[i].bs_how = entry->bs_how; 464*34667Skarels return (0); 46529533Ssam } 46629533Ssam } 46729533Ssam bm->list[i] = *entry; 46829533Ssam bm->list[i].bs_alt.cylinder = 0; 46929533Ssam bm->list[i].bs_alt.track = 0; 47029533Ssam bm->list[i].bs_alt.sector = 0; 47129533Ssam bm->bs_count++; 47229533Ssam qsort((char *)&(bm->list[0]), (unsigned)bm->bs_count, 47329533Ssam sizeof(bs_entry), cmp_entry); 474*34667Skarels return (1); 47529533Ssam } 47629533Ssam 47729533Ssam 47829533Ssam /* 47929533Ssam ** Is_in_map checks to see if a block is known to be bad already. 48029533Ssam */ 48129533Ssam 48229533Ssam boolean is_in_map(dskaddr) 48329533Ssam dskadr *dskaddr; 48429533Ssam { 48529533Ssam register int i; 48629533Ssam fmt_err temp; 48729533Ssam 48832662Skarels for(i=0; i < bad_map->bs_count; i++) { 489*34667Skarels (*C_INFO->decode_pos)(&bad_map->list[i], &temp); 49029533Ssam if((temp.err_adr.cylinder == dskaddr->cylinder) && 49129533Ssam (temp.err_adr.track == dskaddr->track) && 49229533Ssam (temp.err_adr.sector == dskaddr->sector)) { 49329533Ssam return true; 49429533Ssam } 49529533Ssam } 49629533Ssam return false; 49729533Ssam } 49829533Ssam 49929533Ssam 50029533Ssam /* 50129533Ssam ** 50229533Ssam */ 50329533Ssam 50429533Ssam print_bad_sector_list() 50529533Ssam { 50629533Ssam register int i; 50729533Ssam fmt_err errloc; 508*34667Skarels register bs_entry *bad; 50929533Ssam 51029533Ssam if(bad_map->bs_count == 0) { 51129533Ssam print("There are no bad sectors in bad sector map.\n"); 51229533Ssam return; 51329533Ssam } 51429533Ssam print("The following sector%s known to be bad:\n", 51529533Ssam (bad_map->bs_count == 1) ? " is" : "s are"); 51629533Ssam indent(); 517*34667Skarels for(i=0, bad = bad_map->list; i < bad_map->bs_count; i++, bad++) { 518*34667Skarels (*C_INFO->decode_pos)(bad, &errloc); 519*34667Skarels print("%s %d cn %d tn %d sn %d pos %d len %d ", 520*34667Skarels errloc.err_stat & HEADER_ERROR ? "Track@" : "Sector", 521*34667Skarels to_sector(errloc.err_adr), 522*34667Skarels bad->bs_cyl, 523*34667Skarels bad->bs_trk, 524*34667Skarels errloc.err_adr.sector, 525*34667Skarels bad->bs_offset, 526*34667Skarels bad->bs_length); 527*34667Skarels if (bad->bs_how == flaw_map) 528*34667Skarels printf("(flawmap) "); 529*34667Skarels else if (bad->bs_how == scanning) 530*34667Skarels printf("(verify) "); 531*34667Skarels else 532*34667Skarels printf("(operator) "); 533*34667Skarels if((bad->bs_alt.cylinder != 0) || (bad->bs_alt.track != 0) || 534*34667Skarels (bad->bs_alt.sector != 0)) { 535*34667Skarels printf("-> "); 536*34667Skarels printf("cn %d tn %d sn %d", bad->bs_alt.cylinder, 537*34667Skarels bad->bs_alt.track, bad->bs_alt.sector); 53829533Ssam } 539*34667Skarels printf("\n"); 54029533Ssam } 54129533Ssam exdent(1); 54229533Ssam } 54329533Ssam 54429533Ssam 54529533Ssam /* 546*34667Skarels ** load_free_table checks each block in the bad block relocation area 54729533Ssam ** to see if it is used. If it is, the free relocation block table is updated. 54829533Ssam */ 54929533Ssam 55029533Ssam load_free_table() 55129533Ssam { 55229533Ssam register int i, j; 55329533Ssam fmt_err temp; 55429533Ssam 55529533Ssam /* Clear free table before starting */ 55632662Skarels for(i = 0; i < (lab->d_ntracks * NUMREL); i++) { 55732662Skarels for(j=0; j < lab->d_nsectors; j++) 55829533Ssam free_tbl[i][j].free_status = NOTALLOCATED; 55929533Ssam } 56032662Skarels for(i=0; i < bad_map->bs_count; i++) 56129533Ssam if((bad_map->list[i].bs_alt.cylinder != 0) || 56229533Ssam (bad_map->list[i].bs_alt.track != 0) || 56329533Ssam (bad_map->list[i].bs_alt.sector != 0)) { 564*34667Skarels (*C_INFO->decode_pos)(&bad_map->list[i], &temp); 56529533Ssam allocate(&(bad_map->list[i].bs_alt), temp.err_stat); 56629533Ssam } 56729533Ssam } 56829533Ssam 56929533Ssam 57029533Ssam /* 57129533Ssam ** allocate marks a replacement sector as used. 57229533Ssam */ 57329533Ssam 57429533Ssam allocate(dskaddr, status) 57529533Ssam dskadr *dskaddr; 57629533Ssam long status; 57729533Ssam { 57829533Ssam register int trk, sec; 57929533Ssam 58032662Skarels trk = dskaddr->cylinder - (lab->d_ncylinders - NUMSYS); 58129533Ssam if((trk < 0) || (trk >= NUMREL)) 58229533Ssam return; 58332662Skarels trk *= lab->d_ntracks; 58429533Ssam trk += dskaddr->track; 58529533Ssam if(status & HEADER_ERROR) 58632662Skarels for(sec=0; sec < lab->d_nsectors; sec++) 58729533Ssam free_tbl[trk][sec].free_status = ALLOCATED; 58829533Ssam else 58929533Ssam free_tbl[trk][dskaddr->sector].free_status = ALLOCATED; 59029533Ssam } 59129533Ssam 59229533Ssam 59329533Ssam /* 59429533Ssam ** 59529533Ssam */ 59629533Ssam 59729533Ssam boolean mapping_collision(entry) 59829533Ssam bs_entry *entry; 59929533Ssam { 60029533Ssam register int trk, sec; 60129533Ssam fmt_err temp; 60229533Ssam 60332662Skarels trk = entry->bs_cyl - (lab->d_ncylinders - NUMSYS); 60429533Ssam if((trk < 0) || (trk >= NUMREL)) 60529533Ssam return false; 60632662Skarels trk *= lab->d_ntracks; 60729533Ssam trk += entry->bs_trk; 608*34667Skarels (*C_INFO->decode_pos)(entry, &temp); 60929533Ssam /* if this relocation should take up the whole track */ 61029533Ssam if(temp.err_stat & HEADER_ERROR) { 61132662Skarels for(sec=0; sec < lab->d_nsectors; sec++) 61229533Ssam if(free_tbl[trk][sec].free_status == ALLOCATED) 61329533Ssam return true; 61429533Ssam } 61529533Ssam /* else just check the current sector */ 61629533Ssam else { 61729533Ssam if(free_tbl[trk][temp.err_adr.sector].free_status == ALLOCATED) 61829533Ssam return true; 61929533Ssam } 62029533Ssam return false; 62129533Ssam } 62229533Ssam 62329533Ssam 62429533Ssam /* 62529533Ssam ** 62629533Ssam */ 62729533Ssam 62829533Ssam report_collision() 62929533Ssam { 63029533Ssam indent(); 63129533Ssam print("Sector resides in relocation area"); 63229533Ssam printf("but it has a sector mapped to it already.\n"); 63329533Ssam print("Please reformat disk with 0 patterns to eliminate problem.\n"); 63429533Ssam exdent(1); 63529533Ssam } 63629533Ssam 63729533Ssam 63829533Ssam /* 63929533Ssam ** 64029533Ssam */ 64129533Ssam 64229533Ssam add_user_relocations(entry) 64329533Ssam bs_entry *entry; 64429533Ssam { 64529533Ssam fmt_err error; 64629533Ssam 647*34667Skarels (*C_INFO->decode_pos)(entry, &error); 64829533Ssam if(is_in_map(&error.err_adr) == false) { 64929533Ssam if(mapping_collision(entry) == true) 65029533Ssam report_collision(); 65129533Ssam entry->bs_how = operator; 65229533Ssam add_flaw(entry); 65329533Ssam } 65429533Ssam else { 65529533Ssam indent(); 65629533Ssam print("Sector %d is already mapped out!\n", 65729533Ssam to_sector(error.err_adr)); 65829533Ssam exdent(1); 65929533Ssam } 66029533Ssam } 66129533Ssam 66229533Ssam 66329533Ssam /* 66429533Ssam ** New_location allocates a replacement block given a bad block address. 66529533Ssam ** The algorithm is fairly simple; it simply searches for the first 66629533Ssam ** free sector that has the same sector number of the bad sector. If no sector 66729533Ssam ** is found then the drive should be considered bad because of a microcode bug 66829533Ssam ** in the controller that forces us to use the same sector number as the bad 66929533Ssam ** sector for relocation purposes. Using different tracks and cylinders is ok 67029533Ssam ** of course. 67129533Ssam */ 67229533Ssam 67329533Ssam dskadr *new_location(entry) 67429533Ssam bs_entry *entry; 67529533Ssam { 67629533Ssam register int i, sec; 67729533Ssam static fmt_err temp; 67829533Ssam static dskadr newaddr; 67929533Ssam 68029533Ssam newaddr.cylinder = 0; 68129533Ssam newaddr.track = 0; 68229533Ssam newaddr.sector = 0; 683*34667Skarels (*C_INFO->decode_pos)(entry, &temp); 68429533Ssam /* If it is ouside of the user's data area */ 68532662Skarels if(entry->bs_cyl >= lab->d_ncylinders-NUMSYS) { 68629533Ssam /* if it is in the relocation area */ 68732662Skarels if(entry->bs_cyl < (lab->d_ncylinders - NUMMAP - NUMMNT)) { 68829533Ssam /* mark space as allocated */ 68929533Ssam allocate(&temp.err_adr, temp.err_stat); 69029533Ssam return &temp.err_adr; 69129533Ssam } 69229533Ssam /* if it is in the map area forget about it */ 69332662Skarels if(entry->bs_cyl != (lab->d_ncylinders - NUMMAP - NUMMNT)) 69429533Ssam return &temp.err_adr; 69529533Ssam /* otherwise treat maintainence cylinder normally */ 69629533Ssam } 69729533Ssam if(temp.err_stat & (HEADER_ERROR)) { 69832662Skarels for(i = 0; i < (lab->d_ntracks * NUMREL); i++) { 69932662Skarels for(sec=0; sec < lab->d_nsectors; sec++) { 70029533Ssam if(free_tbl[i][sec].free_status == ALLOCATED) 70129533Ssam break; 70229533Ssam } 70332662Skarels if(sec == lab->d_nsectors) { 70432662Skarels for(sec = 0; sec < lab->d_nsectors; sec++) 70529533Ssam free_tbl[i][sec].free_status=ALLOCATED; 70632662Skarels newaddr.cylinder = i / lab->d_ntracks + 70732662Skarels (lab->d_ncylinders - NUMSYS); 70832662Skarels newaddr.track = i % lab->d_ntracks; 70929533Ssam break; 71029533Ssam } 71129533Ssam } 71229533Ssam } 71332662Skarels else if(C_INFO->type == VDTYPE_VDDC) { 71432662Skarels for(i = 0; i < (lab->d_ntracks * NUMREL); i++) { 71529533Ssam if(free_tbl[i][temp.err_adr.sector].free_status != 71629533Ssam ALLOCATED) { 71729533Ssam free_tbl[i][temp.err_adr.sector].free_status = 71829533Ssam ALLOCATED; 71932662Skarels newaddr.cylinder = i / lab->d_ntracks + 72032662Skarels (lab->d_ncylinders - NUMSYS); 72132662Skarels newaddr.track = i % lab->d_ntracks; 72229533Ssam newaddr.sector = temp.err_adr.sector; 72329533Ssam break; 72429533Ssam } 72529533Ssam } 72629533Ssam } 72729533Ssam else { 72832662Skarels for(i = 0; i < (lab->d_ntracks * NUMREL); i++) { 72932662Skarels for(sec=0; sec < lab->d_nsectors; sec++) 73029533Ssam if(free_tbl[i][sec].free_status != ALLOCATED) 73129533Ssam break; 73232662Skarels if(sec < lab->d_nsectors) { 73329533Ssam free_tbl[i][sec].free_status = ALLOCATED; 73432662Skarels newaddr.cylinder = i / lab->d_ntracks + 73532662Skarels (lab->d_ncylinders - NUMSYS); 73632662Skarels newaddr.track = i % lab->d_ntracks; 73729533Ssam newaddr.sector = sec; 73829533Ssam break; 73929533Ssam } 74029533Ssam } 74129533Ssam } 74229533Ssam return &newaddr; 74329533Ssam } 744