16d7a1e15Ssam #ifndef lint
2*ab4ebc48Skarels static char sccsid[] = "@(#)relocate.c 1.7 (Berkeley/CCI) 06/24/90";
36d7a1e15Ssam #endif
46d7a1e15Ssam
56d7a1e15Ssam #include "vdfmt.h"
66d7a1e15Ssam #include "cmd.h"
76d7a1e15Ssam
86d7a1e15Ssam /*
96d7a1e15Ssam **
106d7a1e15Ssam */
116d7a1e15Ssam
relocate()126d7a1e15Ssam relocate()
136d7a1e15Ssam {
146d7a1e15Ssam extern boolean is_formatted();
156d7a1e15Ssam
166d7a1e15Ssam cur.state = rel;
17f31d5e62Skarels print("Adding flaws to bad sector map on ");
186d7a1e15Ssam printf("controller %d, drive %d, ", cur.controller, cur.drive);
19d5d660dcSkarels printf("type %s.\n", lab->d_typename);
206d7a1e15Ssam
216d7a1e15Ssam indent();
226d7a1e15Ssam if(is_formatted() == true) {
236d7a1e15Ssam if(read_bad_sector_map() == true)
24d5d660dcSkarels if(bad_map->bs_id != D_INFO->id) {
256d7a1e15Ssam print("Drive serial numbers do not match!\n");
266d7a1e15Ssam exdent(1);
276d7a1e15Ssam _longjmp(abort_environ, 1);
286d7a1e15Ssam }
296d7a1e15Ssam get_new_relocations();
30319dde04Skarels cur.substate = sub_wmap;
316d7a1e15Ssam sync_bad_sector_map();
326d7a1e15Ssam }
336d7a1e15Ssam else
346d7a1e15Ssam print("Drive must be formatted befor relocations are done.\n");
356d7a1e15Ssam exdent(1);
366d7a1e15Ssam }
376d7a1e15Ssam
386d7a1e15Ssam
396d7a1e15Ssam /*
406d7a1e15Ssam **
416d7a1e15Ssam */
426d7a1e15Ssam
rel_help()436d7a1e15Ssam rel_help()
446d7a1e15Ssam {
456d7a1e15Ssam indent();
466d7a1e15Ssam print("Relocation commands are in the following form:\n");
476d7a1e15Ssam indent();
48e996412dSkarels print("[a-h] (block) - UNIX file system block (%s-byte) number.\n",
49e996412dSkarels DEV_BSIZE);
506d7a1e15Ssam print("SEctor (sector) - Absolute sector number on disk.\n");
516d7a1e15Ssam print("Track (track) - Absolute disk track number.\n");
526d7a1e15Ssam print("(cylinder) (head) (offset) (length) - CDC flaw map format.\n");
536d7a1e15Ssam print("STARt - Starts relocation process.\n\n");
546d7a1e15Ssam exdent(2);
556d7a1e15Ssam }
566d7a1e15Ssam
576d7a1e15Ssam
586d7a1e15Ssam /*
596d7a1e15Ssam **
606d7a1e15Ssam */
616d7a1e15Ssam
get_new_relocations()626d7a1e15Ssam get_new_relocations()
636d7a1e15Ssam {
646d7a1e15Ssam char line[256];
656d7a1e15Ssam char *ptr;
666d7a1e15Ssam bs_entry entry;
676d7a1e15Ssam dskadr dskaddr;
68319dde04Skarels fmt_err dskerr;
696d7a1e15Ssam int max_track;
70319dde04Skarels register int block;
716d7a1e15Ssam
72d5d660dcSkarels dskaddr.cylinder = lab->d_ncylinders - 1;
73*ab4ebc48Skarels dskaddr.track = lab->d_ntracks - 1;
746d7a1e15Ssam max_track = to_track(dskaddr);
756d7a1e15Ssam for(;;) {
766d7a1e15Ssam print("Location? ");
776d7a1e15Ssam get_string_cmd(line, rel_help);
786d7a1e15Ssam if(kill_processes == true)
796d7a1e15Ssam _longjmp(quit_environ, 1);
806d7a1e15Ssam if(line[0] == '\0')
816d7a1e15Ssam continue;
826d7a1e15Ssam ptr = line;
836d7a1e15Ssam trim_white(ptr);
846d7a1e15Ssam if(!strncmp(ptr, "he", 2) || !strncmp(ptr, "?", 1) ||
856d7a1e15Ssam !strncmp(ptr, "stat", 4) || !strncmp(ptr, "!", 1))
866d7a1e15Ssam continue;
876d7a1e15Ssam indent();
886d7a1e15Ssam if((*ptr >= 'a') && (*ptr <= 'h')) {
896d7a1e15Ssam register char par = *(ptr++);
906d7a1e15Ssam
91319dde04Skarels block = get_next_digit(ptr);
92319dde04Skarels dskerr.err_adr = *from_unix((unsigned char)par,
936d7a1e15Ssam (unsigned int)block);
94319dde04Skarels if((dskerr.err_adr.cylinder == -1) || (block == -1)) {
956d7a1e15Ssam print("Invalid UNIX block number!\n");
966d7a1e15Ssam goto next;
976d7a1e15Ssam }
986d7a1e15Ssam print("Confirm block %d on file-system '%c'",block,par);
99319dde04Skarels dskerr.err_stat = DATA_ERROR;
100319dde04Skarels doreloc:
101319dde04Skarels printf(" (cn %d tn %d sn %d)", dskerr.err_adr.cylinder,
102319dde04Skarels dskerr.err_adr.track, dskerr.err_adr.sector);
1036d7a1e15Ssam if(get_yes_no("") == true) {
104319dde04Skarels (*C_INFO->code_pos)(&dskerr, &entry);
1056d7a1e15Ssam add_user_relocations(&entry);
1066d7a1e15Ssam }
1076d7a1e15Ssam }
1086d7a1e15Ssam else if(*ptr == 't') {
109319dde04Skarels block = get_next_digit(ptr);
110319dde04Skarels if((block == -1) || (block >= max_track)) {
1116d7a1e15Ssam print("Invalid track number!\n");
1126d7a1e15Ssam goto next;
1136d7a1e15Ssam }
114319dde04Skarels dskerr.err_adr = *from_track(block);
115319dde04Skarels dskerr.err_stat = HEADER_ERROR;
116319dde04Skarels print("Confirm track %d", block);
117319dde04Skarels goto doreloc;
1186d7a1e15Ssam }
1196d7a1e15Ssam else if(!strncmp(ptr, "se", 2)) {
120319dde04Skarels block = get_next_digit(ptr);
1216d7a1e15Ssam
122319dde04Skarels if((block == -1) ||
123319dde04Skarels ((lab->d_nsectors*lab->d_ntracks*lab->d_ncylinders)<block)){
1246d7a1e15Ssam print("Invalid sector number!\n");
1256d7a1e15Ssam goto next;
1266d7a1e15Ssam }
127319dde04Skarels dskerr.err_adr = *from_sector((unsigned int)block);
128319dde04Skarels dskerr.err_stat = DATA_ERROR;
129319dde04Skarels goto doreloc;
1306d7a1e15Ssam }
1316d7a1e15Ssam else if(is_digit(*ptr)) {
1326d7a1e15Ssam entry.bs_cyl = get_next_digit(ptr);
1336d7a1e15Ssam skipdigits(ptr);
1346d7a1e15Ssam finddigit(ptr);
1356d7a1e15Ssam entry.bs_trk = get_next_digit(ptr);
1366d7a1e15Ssam skipdigits(ptr);
1376d7a1e15Ssam finddigit(ptr);
1386d7a1e15Ssam entry.bs_offset = get_next_digit(ptr);
1396d7a1e15Ssam skipdigits(ptr);
1406d7a1e15Ssam finddigit(ptr);
1416d7a1e15Ssam entry.bs_length = get_next_digit(ptr);
1426d7a1e15Ssam if((entry.bs_trk != -1) && (entry.bs_offset != -1) &&
1436d7a1e15Ssam (entry.bs_length != -1)) {
144d5d660dcSkarels if(entry.bs_cyl >= lab->d_ncylinders)
1456d7a1e15Ssam print("Cylinder number to high!\n");
146d5d660dcSkarels else if(entry.bs_trk >= lab->d_ntracks)
1476d7a1e15Ssam print("Head number to high!\n");
148d5d660dcSkarels else if(entry.bs_offset >= lab->d_traksize)
1496d7a1e15Ssam print("Offset too long!\n");
1506d7a1e15Ssam else if(entry.bs_length == 0)
1516d7a1e15Ssam print("Can't have a 0 length error!\n");
1526d7a1e15Ssam else {
1536d7a1e15Ssam print("Confirm Cyl %d, ",entry.bs_cyl);
1546d7a1e15Ssam printf("Head %d, ", entry.bs_trk);
1556d7a1e15Ssam printf("offset %d, ", entry.bs_offset);
1566d7a1e15Ssam printf("length %d", entry.bs_length);
1576d7a1e15Ssam if(get_yes_no("") == true)
1586d7a1e15Ssam add_user_relocations(&entry);
1596d7a1e15Ssam }
1606d7a1e15Ssam }
1616d7a1e15Ssam else
1626d7a1e15Ssam goto bad;
1636d7a1e15Ssam }
164f31d5e62Skarels else if(!strncmp(ptr, "start", 4)) {
1656d7a1e15Ssam exdent(1);
1666d7a1e15Ssam break;
1676d7a1e15Ssam }
1686d7a1e15Ssam else
1696d7a1e15Ssam bad: print("What?\n");
1706d7a1e15Ssam next: exdent(1);
1716d7a1e15Ssam }
1726d7a1e15Ssam }
1736d7a1e15Ssam
check_track_for_relocations(entry,i)1746d7a1e15Ssam dskadr check_track_for_relocations(entry, i)
1756d7a1e15Ssam bs_entry entry;
1766d7a1e15Ssam register int i;
1776d7a1e15Ssam {
1786d7a1e15Ssam register int j = i;
1796d7a1e15Ssam fmt_err temp, cmp;
1806d7a1e15Ssam boolean bad_track = false;
1816d7a1e15Ssam
182319dde04Skarels (*C_INFO->decode_pos)(&entry, &cmp);
1836d7a1e15Ssam /* Check to see if a alternate track is or will be on this track */
1846d7a1e15Ssam while((bad_map->list[j].bs_cyl == entry.bs_cyl) &&
1856d7a1e15Ssam (bad_map->list[j].bs_trk == entry.bs_trk)) {
186319dde04Skarels (*C_INFO->decode_pos)(&bad_map->list[j], &temp);
1876d7a1e15Ssam if(temp.err_stat & HEADER_ERROR) {
1886d7a1e15Ssam bad_track = true;
1896d7a1e15Ssam /* if track was mapped out (it can't be us) */
1906d7a1e15Ssam if(((bad_map->list[j].bs_alt.cylinder != 0)) ||
1916d7a1e15Ssam (bad_map->list[j].bs_alt.track != 0) ||
1926d7a1e15Ssam (bad_map->list[j].bs_alt.sector != 0)) {
1936d7a1e15Ssam return cmp.err_adr;
1946d7a1e15Ssam }
1956d7a1e15Ssam }
1966d7a1e15Ssam j++;
1976d7a1e15Ssam }
1986d7a1e15Ssam /*
1996d7a1e15Ssam ** If it was a bad track and it was not the current entry
2006d7a1e15Ssam ** that produced it then then map it
2016d7a1e15Ssam ** to itself and forget about it for now since it will be taken
2026d7a1e15Ssam ** care of later.
2036d7a1e15Ssam **
2046d7a1e15Ssam ** If it was the current entry return zero and the track will be
2056d7a1e15Ssam ** mapped out correctly.
2066d7a1e15Ssam */
2076d7a1e15Ssam if(bad_track == true) {
2086d7a1e15Ssam if(cmp.err_stat & HEADER_ERROR)
2096d7a1e15Ssam return entry.bs_alt; /* better known as zero */
2106d7a1e15Ssam else
2116d7a1e15Ssam return cmp.err_adr;
2126d7a1e15Ssam }
2136d7a1e15Ssam /*
2146d7a1e15Ssam ** if we made it through all the bad track stuff then check for
2156d7a1e15Ssam ** multiple errors on the same sector that are already mapped!
2166d7a1e15Ssam */
2176d7a1e15Ssam j = i;
2186d7a1e15Ssam while((bad_map->list[j].bs_cyl == entry.bs_cyl) &&
2196d7a1e15Ssam (bad_map->list[j].bs_trk == entry.bs_trk)) {
220319dde04Skarels (*C_INFO->decode_pos)(&bad_map->list[j], &temp);
2216d7a1e15Ssam if(temp.err_adr.sector == cmp.err_adr.sector) {
2226d7a1e15Ssam /* if it is not really the current entry */
2236d7a1e15Ssam if((bad_map->list[j].bs_offset != entry.bs_offset) ||
2246d7a1e15Ssam (bad_map->list[j].bs_length != entry.bs_length)) {
2256d7a1e15Ssam /* if the sector is already mapped out */
2266d7a1e15Ssam if(((bad_map->list[j].bs_alt.cylinder != 0)) ||
2276d7a1e15Ssam (bad_map->list[j].bs_alt.track != 0) ||
2286d7a1e15Ssam (bad_map->list[j].bs_alt.sector != 0)) {
2296d7a1e15Ssam return temp.err_adr;
2306d7a1e15Ssam }
2316d7a1e15Ssam }
2326d7a1e15Ssam }
2336d7a1e15Ssam j++;
2346d7a1e15Ssam }
2356d7a1e15Ssam return entry.bs_alt;
2366d7a1e15Ssam }
2376d7a1e15Ssam
2386d7a1e15Ssam
2396d7a1e15Ssam /*
2406d7a1e15Ssam **
2416d7a1e15Ssam */
2426d7a1e15Ssam
is_relocated(entry)2436d7a1e15Ssam dskadr is_relocated(entry)
2446d7a1e15Ssam bs_entry entry;
2456d7a1e15Ssam {
2466d7a1e15Ssam register int i;
2476d7a1e15Ssam
2486d7a1e15Ssam for(i=0; i<bad_map->bs_count; i++)
2496d7a1e15Ssam if((bad_map->list[i].bs_cyl == entry.bs_cyl) &&
2506d7a1e15Ssam (bad_map->list[i].bs_trk == entry.bs_trk))
2516d7a1e15Ssam return check_track_for_relocations(entry, i);
2526d7a1e15Ssam return entry.bs_alt;
2536d7a1e15Ssam }
2546d7a1e15Ssam
2556d7a1e15Ssam
2566d7a1e15Ssam
2576d7a1e15Ssam /*
2586d7a1e15Ssam **
2596d7a1e15Ssam */
2606d7a1e15Ssam
sync_bad_sector_map()2616d7a1e15Ssam sync_bad_sector_map()
2626d7a1e15Ssam {
2636d7a1e15Ssam register int i;
2646d7a1e15Ssam dskadr dskaddr;
2656d7a1e15Ssam
2666d7a1e15Ssam /*
2676d7a1e15Ssam ** do all the relocation cylinders first to allocate all flaws in
2686d7a1e15Ssam ** relocation area.
2696d7a1e15Ssam */
2706d7a1e15Ssam for(i=bad_map->bs_count-1; i>=0; i--) {
271d5d660dcSkarels if((bad_map->list[i].bs_cyl >= lab->d_ncylinders-NUMSYS) &&
272d5d660dcSkarels (bad_map->list[i].bs_cyl < lab->d_ncylinders-NUMMAP-NUMMNT)) {
2736d7a1e15Ssam if((bad_map->list[i].bs_alt.cylinder == 0) &&
2746d7a1e15Ssam (bad_map->list[i].bs_alt.track == 0) &&
2756d7a1e15Ssam (bad_map->list[i].bs_alt.sector == 0)) {
2766d7a1e15Ssam bad_map->list[i].bs_alt =
2776d7a1e15Ssam *new_location(&bad_map->list[i]);
2786d7a1e15Ssam }
2796d7a1e15Ssam }
2806d7a1e15Ssam }
2816d7a1e15Ssam for(i=bad_map->bs_count-1; i>=0; i--) {
2826d7a1e15Ssam if((bad_map->list[i].bs_alt.cylinder == 0) &&
2836d7a1e15Ssam (bad_map->list[i].bs_alt.track == 0) &&
2846d7a1e15Ssam (bad_map->list[i].bs_alt.sector == 0)) {
2856d7a1e15Ssam dskaddr = is_relocated(bad_map->list[i]);
2866d7a1e15Ssam if((dskaddr.cylinder == 0) && (dskaddr.track == 0) &&
2876d7a1e15Ssam (dskaddr.sector == 0)) {
2886d7a1e15Ssam bad_map->list[i].bs_alt =
2896d7a1e15Ssam *new_location(&bad_map->list[i]);
2906d7a1e15Ssam do_relocation(bad_map->list[i]);
2916d7a1e15Ssam }
2926d7a1e15Ssam else
2936d7a1e15Ssam bad_map->list[i].bs_alt = dskaddr;
2946d7a1e15Ssam }
2956d7a1e15Ssam }
2966d7a1e15Ssam write_bad_sector_map();
2976d7a1e15Ssam }
2986d7a1e15Ssam
2996d7a1e15Ssam
3006d7a1e15Ssam
3016d7a1e15Ssam /*
3026d7a1e15Ssam **
3036d7a1e15Ssam */
3046d7a1e15Ssam
do_relocation(entry)3056d7a1e15Ssam do_relocation(entry)
3066d7a1e15Ssam bs_entry entry;
3076d7a1e15Ssam {
3086d7a1e15Ssam fmt_err temp;
3096d7a1e15Ssam
310d5d660dcSkarels if(entry.bs_cyl >= lab->d_ncylinders-NUMSYS)
311d5d660dcSkarels if(entry.bs_cyl != (lab->d_ncylinders - NUMMAP - NUMMNT))
3126d7a1e15Ssam return;
313319dde04Skarels (*C_INFO->decode_pos)(&entry, &temp);
3146d7a1e15Ssam if((entry.bs_alt.cylinder == 0) && (entry.bs_alt.track == 0) &&
3156d7a1e15Ssam (entry.bs_alt.sector == 0))
3166d7a1e15Ssam print_unix_block(temp.err_adr);
3176d7a1e15Ssam else if(temp.err_stat & HEADER_ERROR)
318d5d660dcSkarels if(C_INFO->type == VDTYPE_VDDC) {
3196d7a1e15Ssam print("Can't relocate tracks on VDDC controllers.\n");
3206d7a1e15Ssam print_unix_block(temp.err_adr);
3216d7a1e15Ssam }
3226d7a1e15Ssam else
3236d7a1e15Ssam relocate_track(entry);
3246d7a1e15Ssam else
3256d7a1e15Ssam relocate_sector(entry);
3266d7a1e15Ssam }
3276d7a1e15Ssam
3286d7a1e15Ssam
3296d7a1e15Ssam /*
3306d7a1e15Ssam **
3316d7a1e15Ssam */
3326d7a1e15Ssam
relocate_sector(entry)3336d7a1e15Ssam relocate_sector(entry)
3346d7a1e15Ssam bs_entry entry;
3356d7a1e15Ssam {
3366d7a1e15Ssam dskadr phys, reloc;
3376d7a1e15Ssam fmt_err temp;
3386d7a1e15Ssam register long status;
3396d7a1e15Ssam
340319dde04Skarels (*C_INFO->decode_pos)(&entry, &temp);
3416d7a1e15Ssam phys = temp.err_adr;
3426d7a1e15Ssam reloc = entry.bs_alt;
3436d7a1e15Ssam format_sectors(&phys, &reloc, RELOC_SECTOR, (long)1);
3446d7a1e15Ssam
3456d7a1e15Ssam format_sectors(&reloc, &phys, ALT_SECTOR, (long)1);
34668c7fc27Ssam status = access_dsk((char *)save, &temp.err_adr, VDOP_WD, 1, 1);
34768c7fc27Ssam if(!((status & DCBS_ATA) && !(status & (DCBS_HARD|DCBS_SOFT)))) {
348f31d5e62Skarels print(
349f31d5e62Skarels "Sector relocation failed (c %d t %d s %d). Status = 0x%x.\n",
350f31d5e62Skarels phys.cylinder, phys.track, phys.sector, status);
3516d7a1e15Ssam print_unix_block(phys);
3526d7a1e15Ssam }
3536d7a1e15Ssam }
3546d7a1e15Ssam
3556d7a1e15Ssam
3566d7a1e15Ssam
3576d7a1e15Ssam /*
3586d7a1e15Ssam **
3596d7a1e15Ssam */
3606d7a1e15Ssam
relocate_track(entry)3616d7a1e15Ssam relocate_track(entry)
3626d7a1e15Ssam bs_entry entry;
3636d7a1e15Ssam {
3646d7a1e15Ssam dskadr phys, reloc;
3656d7a1e15Ssam fmt_err temp;
3666d7a1e15Ssam register long status;
3676d7a1e15Ssam
368319dde04Skarels (*C_INFO->decode_pos)(&entry, &temp);
3696d7a1e15Ssam temp.err_adr.sector = 0;
3706d7a1e15Ssam phys = temp.err_adr;
3716d7a1e15Ssam reloc = entry.bs_alt;
3726d7a1e15Ssam reloc.sector = 0xff;
373d5d660dcSkarels format_sectors(&phys, &reloc, RELOC_SECTOR, (long)lab->d_nsectors);
3746d7a1e15Ssam
3756d7a1e15Ssam reloc.sector = 0x00;
376d5d660dcSkarels format_sectors(&reloc, &phys, ALT_SECTOR, (long)lab->d_nsectors);
377d5d660dcSkarels status = access_dsk((char *)save, &temp.err_adr, VDOP_WD, lab->d_nsectors, 1);
37868c7fc27Ssam if(!((status & DCBS_ATA) && !(status & (DCBS_HARD|DCBS_SOFT)))) {
3796d7a1e15Ssam print("Track relocation failed. Status = 0x%x.\n", status);
3806d7a1e15Ssam print_unix_block(phys);
3816d7a1e15Ssam }
3826d7a1e15Ssam }
383