|
|
1.1 ! root 1: #ifndef lint ! 2: static char sccsid[] = "@(#)relocate.c 1.7 (Berkeley/CCI) 6/24/90"; ! 3: #endif ! 4: ! 5: #include "vdfmt.h" ! 6: #include "cmd.h" ! 7: ! 8: /* ! 9: ** ! 10: */ ! 11: ! 12: relocate() ! 13: { ! 14: extern boolean is_formatted(); ! 15: ! 16: cur.state = rel; ! 17: print("Adding flaws to bad sector map on "); ! 18: printf("controller %d, drive %d, ", cur.controller, cur.drive); ! 19: printf("type %s.\n", lab->d_typename); ! 20: ! 21: indent(); ! 22: if(is_formatted() == true) { ! 23: if(read_bad_sector_map() == true) ! 24: if(bad_map->bs_id != D_INFO->id) { ! 25: print("Drive serial numbers do not match!\n"); ! 26: exdent(1); ! 27: _longjmp(abort_environ, 1); ! 28: } ! 29: get_new_relocations(); ! 30: cur.substate = sub_wmap; ! 31: sync_bad_sector_map(); ! 32: } ! 33: else ! 34: print("Drive must be formatted befor relocations are done.\n"); ! 35: exdent(1); ! 36: } ! 37: ! 38: ! 39: /* ! 40: ** ! 41: */ ! 42: ! 43: rel_help() ! 44: { ! 45: indent(); ! 46: print("Relocation commands are in the following form:\n"); ! 47: indent(); ! 48: print("[a-h] (block) - UNIX file system block (%s-byte) number.\n", ! 49: DEV_BSIZE); ! 50: print("SEctor (sector) - Absolute sector number on disk.\n"); ! 51: print("Track (track) - Absolute disk track number.\n"); ! 52: print("(cylinder) (head) (offset) (length) - CDC flaw map format.\n"); ! 53: print("STARt - Starts relocation process.\n\n"); ! 54: exdent(2); ! 55: } ! 56: ! 57: ! 58: /* ! 59: ** ! 60: */ ! 61: ! 62: get_new_relocations() ! 63: { ! 64: char line[256]; ! 65: char *ptr; ! 66: bs_entry entry; ! 67: dskadr dskaddr; ! 68: fmt_err dskerr; ! 69: int max_track; ! 70: register int block; ! 71: ! 72: dskaddr.cylinder = lab->d_ncylinders - 1; ! 73: dskaddr.track = lab->d_ntracks - 1; ! 74: max_track = to_track(dskaddr); ! 75: for(;;) { ! 76: print("Location? "); ! 77: get_string_cmd(line, rel_help); ! 78: if(kill_processes == true) ! 79: _longjmp(quit_environ, 1); ! 80: if(line[0] == '\0') ! 81: continue; ! 82: ptr = line; ! 83: trim_white(ptr); ! 84: if(!strncmp(ptr, "he", 2) || !strncmp(ptr, "?", 1) || ! 85: !strncmp(ptr, "stat", 4) || !strncmp(ptr, "!", 1)) ! 86: continue; ! 87: indent(); ! 88: if((*ptr >= 'a') && (*ptr <= 'h')) { ! 89: register char par = *(ptr++); ! 90: ! 91: block = get_next_digit(ptr); ! 92: dskerr.err_adr = *from_unix((unsigned char)par, ! 93: (unsigned int)block); ! 94: if((dskerr.err_adr.cylinder == -1) || (block == -1)) { ! 95: print("Invalid UNIX block number!\n"); ! 96: goto next; ! 97: } ! 98: print("Confirm block %d on file-system '%c'",block,par); ! 99: dskerr.err_stat = DATA_ERROR; ! 100: doreloc: ! 101: printf(" (cn %d tn %d sn %d)", dskerr.err_adr.cylinder, ! 102: dskerr.err_adr.track, dskerr.err_adr.sector); ! 103: if(get_yes_no("") == true) { ! 104: (*C_INFO->code_pos)(&dskerr, &entry); ! 105: add_user_relocations(&entry); ! 106: } ! 107: } ! 108: else if(*ptr == 't') { ! 109: block = get_next_digit(ptr); ! 110: if((block == -1) || (block >= max_track)) { ! 111: print("Invalid track number!\n"); ! 112: goto next; ! 113: } ! 114: dskerr.err_adr = *from_track(block); ! 115: dskerr.err_stat = HEADER_ERROR; ! 116: print("Confirm track %d", block); ! 117: goto doreloc; ! 118: } ! 119: else if(!strncmp(ptr, "se", 2)) { ! 120: block = get_next_digit(ptr); ! 121: ! 122: if((block == -1) || ! 123: ((lab->d_nsectors*lab->d_ntracks*lab->d_ncylinders)<block)){ ! 124: print("Invalid sector number!\n"); ! 125: goto next; ! 126: } ! 127: dskerr.err_adr = *from_sector((unsigned int)block); ! 128: dskerr.err_stat = DATA_ERROR; ! 129: goto doreloc; ! 130: } ! 131: else if(is_digit(*ptr)) { ! 132: entry.bs_cyl = get_next_digit(ptr); ! 133: skipdigits(ptr); ! 134: finddigit(ptr); ! 135: entry.bs_trk = get_next_digit(ptr); ! 136: skipdigits(ptr); ! 137: finddigit(ptr); ! 138: entry.bs_offset = get_next_digit(ptr); ! 139: skipdigits(ptr); ! 140: finddigit(ptr); ! 141: entry.bs_length = get_next_digit(ptr); ! 142: if((entry.bs_trk != -1) && (entry.bs_offset != -1) && ! 143: (entry.bs_length != -1)) { ! 144: if(entry.bs_cyl >= lab->d_ncylinders) ! 145: print("Cylinder number to high!\n"); ! 146: else if(entry.bs_trk >= lab->d_ntracks) ! 147: print("Head number to high!\n"); ! 148: else if(entry.bs_offset >= lab->d_traksize) ! 149: print("Offset too long!\n"); ! 150: else if(entry.bs_length == 0) ! 151: print("Can't have a 0 length error!\n"); ! 152: else { ! 153: print("Confirm Cyl %d, ",entry.bs_cyl); ! 154: printf("Head %d, ", entry.bs_trk); ! 155: printf("offset %d, ", entry.bs_offset); ! 156: printf("length %d", entry.bs_length); ! 157: if(get_yes_no("") == true) ! 158: add_user_relocations(&entry); ! 159: } ! 160: } ! 161: else ! 162: goto bad; ! 163: } ! 164: else if(!strncmp(ptr, "start", 4)) { ! 165: exdent(1); ! 166: break; ! 167: } ! 168: else ! 169: bad: print("What?\n"); ! 170: next: exdent(1); ! 171: } ! 172: } ! 173: ! 174: dskadr check_track_for_relocations(entry, i) ! 175: bs_entry entry; ! 176: register int i; ! 177: { ! 178: register int j = i; ! 179: fmt_err temp, cmp; ! 180: boolean bad_track = false; ! 181: ! 182: (*C_INFO->decode_pos)(&entry, &cmp); ! 183: /* Check to see if a alternate track is or will be on this track */ ! 184: while((bad_map->list[j].bs_cyl == entry.bs_cyl) && ! 185: (bad_map->list[j].bs_trk == entry.bs_trk)) { ! 186: (*C_INFO->decode_pos)(&bad_map->list[j], &temp); ! 187: if(temp.err_stat & HEADER_ERROR) { ! 188: bad_track = true; ! 189: /* if track was mapped out (it can't be us) */ ! 190: if(((bad_map->list[j].bs_alt.cylinder != 0)) || ! 191: (bad_map->list[j].bs_alt.track != 0) || ! 192: (bad_map->list[j].bs_alt.sector != 0)) { ! 193: return cmp.err_adr; ! 194: } ! 195: } ! 196: j++; ! 197: } ! 198: /* ! 199: ** If it was a bad track and it was not the current entry ! 200: ** that produced it then then map it ! 201: ** to itself and forget about it for now since it will be taken ! 202: ** care of later. ! 203: ** ! 204: ** If it was the current entry return zero and the track will be ! 205: ** mapped out correctly. ! 206: */ ! 207: if(bad_track == true) { ! 208: if(cmp.err_stat & HEADER_ERROR) ! 209: return entry.bs_alt; /* better known as zero */ ! 210: else ! 211: return cmp.err_adr; ! 212: } ! 213: /* ! 214: ** if we made it through all the bad track stuff then check for ! 215: ** multiple errors on the same sector that are already mapped! ! 216: */ ! 217: j = i; ! 218: while((bad_map->list[j].bs_cyl == entry.bs_cyl) && ! 219: (bad_map->list[j].bs_trk == entry.bs_trk)) { ! 220: (*C_INFO->decode_pos)(&bad_map->list[j], &temp); ! 221: if(temp.err_adr.sector == cmp.err_adr.sector) { ! 222: /* if it is not really the current entry */ ! 223: if((bad_map->list[j].bs_offset != entry.bs_offset) || ! 224: (bad_map->list[j].bs_length != entry.bs_length)) { ! 225: /* if the sector is already mapped out */ ! 226: if(((bad_map->list[j].bs_alt.cylinder != 0)) || ! 227: (bad_map->list[j].bs_alt.track != 0) || ! 228: (bad_map->list[j].bs_alt.sector != 0)) { ! 229: return temp.err_adr; ! 230: } ! 231: } ! 232: } ! 233: j++; ! 234: } ! 235: return entry.bs_alt; ! 236: } ! 237: ! 238: ! 239: /* ! 240: ** ! 241: */ ! 242: ! 243: dskadr is_relocated(entry) ! 244: bs_entry entry; ! 245: { ! 246: register int i; ! 247: ! 248: for(i=0; i<bad_map->bs_count; i++) ! 249: if((bad_map->list[i].bs_cyl == entry.bs_cyl) && ! 250: (bad_map->list[i].bs_trk == entry.bs_trk)) ! 251: return check_track_for_relocations(entry, i); ! 252: return entry.bs_alt; ! 253: } ! 254: ! 255: ! 256: ! 257: /* ! 258: ** ! 259: */ ! 260: ! 261: sync_bad_sector_map() ! 262: { ! 263: register int i; ! 264: dskadr dskaddr; ! 265: ! 266: /* ! 267: ** do all the relocation cylinders first to allocate all flaws in ! 268: ** relocation area. ! 269: */ ! 270: for(i=bad_map->bs_count-1; i>=0; i--) { ! 271: if((bad_map->list[i].bs_cyl >= lab->d_ncylinders-NUMSYS) && ! 272: (bad_map->list[i].bs_cyl < lab->d_ncylinders-NUMMAP-NUMMNT)) { ! 273: if((bad_map->list[i].bs_alt.cylinder == 0) && ! 274: (bad_map->list[i].bs_alt.track == 0) && ! 275: (bad_map->list[i].bs_alt.sector == 0)) { ! 276: bad_map->list[i].bs_alt = ! 277: *new_location(&bad_map->list[i]); ! 278: } ! 279: } ! 280: } ! 281: for(i=bad_map->bs_count-1; i>=0; i--) { ! 282: if((bad_map->list[i].bs_alt.cylinder == 0) && ! 283: (bad_map->list[i].bs_alt.track == 0) && ! 284: (bad_map->list[i].bs_alt.sector == 0)) { ! 285: dskaddr = is_relocated(bad_map->list[i]); ! 286: if((dskaddr.cylinder == 0) && (dskaddr.track == 0) && ! 287: (dskaddr.sector == 0)) { ! 288: bad_map->list[i].bs_alt = ! 289: *new_location(&bad_map->list[i]); ! 290: do_relocation(bad_map->list[i]); ! 291: } ! 292: else ! 293: bad_map->list[i].bs_alt = dskaddr; ! 294: } ! 295: } ! 296: write_bad_sector_map(); ! 297: } ! 298: ! 299: ! 300: ! 301: /* ! 302: ** ! 303: */ ! 304: ! 305: do_relocation(entry) ! 306: bs_entry entry; ! 307: { ! 308: fmt_err temp; ! 309: ! 310: if(entry.bs_cyl >= lab->d_ncylinders-NUMSYS) ! 311: if(entry.bs_cyl != (lab->d_ncylinders - NUMMAP - NUMMNT)) ! 312: return; ! 313: (*C_INFO->decode_pos)(&entry, &temp); ! 314: if((entry.bs_alt.cylinder == 0) && (entry.bs_alt.track == 0) && ! 315: (entry.bs_alt.sector == 0)) ! 316: print_unix_block(temp.err_adr); ! 317: else if(temp.err_stat & HEADER_ERROR) ! 318: if(C_INFO->type == VDTYPE_VDDC) { ! 319: print("Can't relocate tracks on VDDC controllers.\n"); ! 320: print_unix_block(temp.err_adr); ! 321: } ! 322: else ! 323: relocate_track(entry); ! 324: else ! 325: relocate_sector(entry); ! 326: } ! 327: ! 328: ! 329: /* ! 330: ** ! 331: */ ! 332: ! 333: relocate_sector(entry) ! 334: bs_entry entry; ! 335: { ! 336: dskadr phys, reloc; ! 337: fmt_err temp; ! 338: register long status; ! 339: ! 340: (*C_INFO->decode_pos)(&entry, &temp); ! 341: phys = temp.err_adr; ! 342: reloc = entry.bs_alt; ! 343: format_sectors(&phys, &reloc, RELOC_SECTOR, (long)1); ! 344: ! 345: format_sectors(&reloc, &phys, ALT_SECTOR, (long)1); ! 346: status = access_dsk((char *)save, &temp.err_adr, VDOP_WD, 1, 1); ! 347: if(!((status & DCBS_ATA) && !(status & (DCBS_HARD|DCBS_SOFT)))) { ! 348: print( ! 349: "Sector relocation failed (c %d t %d s %d). Status = 0x%x.\n", ! 350: phys.cylinder, phys.track, phys.sector, status); ! 351: print_unix_block(phys); ! 352: } ! 353: } ! 354: ! 355: ! 356: ! 357: /* ! 358: ** ! 359: */ ! 360: ! 361: relocate_track(entry) ! 362: bs_entry entry; ! 363: { ! 364: dskadr phys, reloc; ! 365: fmt_err temp; ! 366: register long status; ! 367: ! 368: (*C_INFO->decode_pos)(&entry, &temp); ! 369: temp.err_adr.sector = 0; ! 370: phys = temp.err_adr; ! 371: reloc = entry.bs_alt; ! 372: reloc.sector = 0xff; ! 373: format_sectors(&phys, &reloc, RELOC_SECTOR, (long)lab->d_nsectors); ! 374: ! 375: reloc.sector = 0x00; ! 376: format_sectors(&reloc, &phys, ALT_SECTOR, (long)lab->d_nsectors); ! 377: status = access_dsk((char *)save, &temp.err_adr, VDOP_WD, lab->d_nsectors, 1); ! 378: if(!((status & DCBS_ATA) && !(status & (DCBS_HARD|DCBS_SOFT)))) { ! 379: print("Track relocation failed. Status = 0x%x.\n", status); ! 380: print_unix_block(phys); ! 381: } ! 382: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.