|
|
1.1 ! root 1: #ifndef lint ! 2: static char sccsid[] = "@(#)maps.c 1.8 (Berkeley/CCI) 6/24/90"; ! 3: #endif ! 4: ! 5: ! 6: #include "vdfmt.h" ! 7: ! 8: ! 9: /* ! 10: ** ! 11: */ ! 12: ! 13: boolean align_buf(buf, sync) ! 14: unsigned long *buf; ! 15: unsigned long sync; ! 16: { ! 17: register int i, shift; ! 18: ! 19: /* find shift amount */ ! 20: for(shift=0; shift < 32; shift++) { ! 21: if((*buf >> shift ) == sync) { ! 22: for(i=(512/sizeof(long))-1; i >= 0; i--) { ! 23: *(buf+i+1) |= *(buf+i) << (32 - shift); ! 24: *(buf+i) = *(buf+i) >> shift; ! 25: } ! 26: return true; ! 27: } ! 28: } ! 29: return false; ! 30: } ! 31: ! 32: ! 33: /* ! 34: ** Looks for two maps in a row that are the same. ! 35: */ ! 36: ! 37: boolean ! 38: read_map(flags) ! 39: short flags; ! 40: { ! 41: register int trk, i; ! 42: register bs_map *map; ! 43: dskadr dskaddr; ! 44: ! 45: dskaddr.cylinder = (lab->d_ncylinders - 1) | flags; ! 46: for(trk=0; trk < lab->d_ntracks; trk++) { ! 47: dskaddr.track = trk; ! 48: dskaddr.sector = 0; ! 49: if(access_dsk((char *)map_space, &dskaddr, VDOP_RD, ! 50: lab->d_nsectors, 1) & VDERR_HARD) ! 51: continue; ! 52: map = &norm_bad_map; ! 53: /* ! 54: * If this doesn't look like a new-style map, ! 55: * but (as an old-style map) bs_count and bs_max are sensible, ! 56: * munge pointer to prepend fields missing in old map. ! 57: */ ! 58: if (map->bs_magic != BSMAGIC && ! 59: map->bs_cksum <= MAX_FLAWMAP(bytes_trk) /* bs_count */ ! 60: && map->bs_id <= MAX_FLAWMAP(bytes_trk)) /* bs_max */ ! 61: map = &offset_bad_map; ! 62: if (trk > 0 && ! 63: bcmp((char *)map_space, (char *)save, bytes_trk) == 0 && ! 64: map->bs_count <= MAX_FLAWMAP(bytes_trk)) { ! 65: for (i=0; i < map->bs_count; i++) { ! 66: if (map->list[i].bs_cyl >= ! 67: lab->d_ncylinders) ! 68: break; ! 69: if (map->list[i].bs_trk >= ! 70: lab->d_ntracks) ! 71: break; ! 72: if (map->list[i].bs_offset >= ! 73: lab->d_traksize) ! 74: break; ! 75: } ! 76: if (i == map->bs_count) { ! 77: bad_map = map; ! 78: load_free_table(); ! 79: return true; ! 80: } ! 81: } ! 82: bcopy((char *)map_space, (char *)save, bytes_trk); ! 83: } ! 84: map = &norm_bad_map; ! 85: bad_map = map; ! 86: bzero((char *)map, bytes_trk); ! 87: map->bs_magic = BSMAGIC; ! 88: map->bs_id = 0; ! 89: map->bs_max = MAX_FLAWS; ! 90: return false; ! 91: } ! 92: ! 93: ! 94: /* ! 95: ** ! 96: */ ! 97: ! 98: boolean read_bad_sector_map() ! 99: { ! 100: dskadr dskaddr; ! 101: ! 102: dskaddr.cylinder = lab->d_ncylinders - 1; ! 103: dskaddr.track = 0; ! 104: dskaddr.sector = 0; ! 105: offset_bad_map.bs_magic = BSMAGIC; ! 106: offset_bad_map.bs_cksum = 0; ! 107: bad_map = &norm_bad_map; ! 108: /* start with nothing in map */ ! 109: bzero(map_space, bytes_trk); ! 110: bad_map->bs_magic = BSMAGIC; ! 111: bad_map->bs_id = 0; ! 112: bad_map->bs_max = MAX_FLAWS; ! 113: if (C_INFO->type == VDTYPE_SMDE) { ! 114: access_dsk((char *)save, &dskaddr, VDOP_RDRAW, 1, 1); ! 115: if (align_buf((unsigned long *)save, CDCSYNC) == true) { ! 116: read_flaw_map(); ! 117: return (false); ! 118: } else if (read_map(NRM) == true) { ! 119: return (true); ! 120: } else { ! 121: get_smde_relocations(); ! 122: return false; ! 123: } ! 124: } else { ! 125: if (read_map(WPT) == true) ! 126: return (true); ! 127: else { ! 128: get_relocations_the_hard_way(); ! 129: return (false); ! 130: } ! 131: } ! 132: } ! 133: ! 134: ! 135: /* ! 136: ** ! 137: */ ! 138: ! 139: get_relocations_the_hard_way() ! 140: { ! 141: register int cyl, trk; ! 142: register int status; ! 143: dskadr dskaddr; ! 144: ! 145: dskaddr.sector = 0; ! 146: /* scan each sector to see if it is relocated and take note if it is */ ! 147: for(cyl=0; cyl < lab->d_ncylinders - NUMSYS; cyl++) { ! 148: dskaddr.cylinder = cyl; ! 149: for(trk=0; trk < lab->d_ntracks; trk++) { ! 150: dskaddr.track = trk; ! 151: status=access_dsk((char *)scratch, &dskaddr, ! 152: VDOP_RD, lab->d_nsectors, 1); ! 153: if(status & DCBS_ATA) ! 154: get_track_relocations(dskaddr); ! 155: } ! 156: } ! 157: load_free_table(); ! 158: } ! 159: ! 160: ! 161: /* ! 162: ** ! 163: */ ! 164: ! 165: get_track_relocations(dskaddr) ! 166: dskadr dskaddr; ! 167: { ! 168: register int status; ! 169: bs_entry temp; ! 170: fmt_err error; ! 171: ! 172: for(dskaddr.sector=0; dskaddr.sector < lab->d_nsectors; dskaddr.sector++) { ! 173: status = access_dsk((char *)scratch, &dskaddr, VDOP_RD, 1, 1); ! 174: if(status & DCBS_ATA) { ! 175: error.err_adr = dskaddr; ! 176: error.err_stat = DATA_ERROR; ! 177: (*C_INFO->code_pos)(&error, &temp); ! 178: temp.bs_how = operator; ! 179: add_flaw(&temp); ! 180: } ! 181: } ! 182: } ! 183: ! 184: ! 185: /* ! 186: ** ! 187: */ ! 188: ! 189: remove_user_relocations(entry) ! 190: bs_entry *entry; ! 191: { ! 192: register int i, j; ! 193: fmt_err temp; ! 194: fmt_err error; ! 195: register bs_entry *ptr; ! 196: ! 197: (*C_INFO->decode_pos)(entry, &error); ! 198: ptr = bad_map->list; ! 199: for(i=0; i < bad_map->bs_count; i++) { ! 200: if (ptr->bs_cyl != entry->bs_cyl || ! 201: ptr->bs_trk != entry->bs_trk) ! 202: continue; ! 203: (*C_INFO->decode_pos)(ptr, &temp); ! 204: if((ptr->bs_how != flaw_map) && ! 205: (temp.err_adr.cylinder == error.err_adr.cylinder) && ! 206: (temp.err_adr.track == error.err_adr.track) && ! 207: (temp.err_adr.sector == error.err_adr.sector)) { ! 208: if(temp.err_stat & HEADER_ERROR) ! 209: remove_track(&temp, ptr); ! 210: else ! 211: remove_sector(&temp, ptr); ! 212: for(j=i+1; j < bad_map->bs_count; j++) ! 213: bad_map->list[j-1] = bad_map->list[j]; ! 214: bad_map->bs_count--; ! 215: return; ! 216: } ! 217: ptr++; ! 218: } ! 219: indent(); ! 220: print("Sector %d is not in bad sector map!\n", ! 221: to_sector(error.err_adr)); ! 222: exdent(1); ! 223: } ! 224: ! 225: clear_relocations(reformat) ! 226: boolean reformat; ! 227: { ! 228: fmt_err temp; ! 229: register bs_entry *ptr1, *ptr2, *end; ! 230: int oldsub = cur.substate; ! 231: ! 232: cur.substate = sub_rel; ! 233: ptr1 = bad_map->list; ! 234: ptr2 = bad_map->list; ! 235: end = &bad_map->list[bad_map->bs_count]; ! 236: for (; ptr1 < end; ptr1++) { ! 237: if (ptr1->bs_how != flaw_map) { ! 238: if (reformat == true) { ! 239: (*C_INFO->decode_pos)(ptr1, &temp); ! 240: if(temp.err_stat & HEADER_ERROR) ! 241: remove_track(&temp, ptr1); ! 242: else ! 243: remove_sector(&temp, ptr1); ! 244: } ! 245: bad_map->bs_count--; ! 246: } else { ! 247: if (ptr1 != ptr2) ! 248: *ptr2 = *ptr1; ! 249: ptr2++; ! 250: } ! 251: } ! 252: cur.substate = oldsub; ! 253: } ! 254: ! 255: ! 256: /* ! 257: ** ! 258: */ ! 259: ! 260: remove_sector(error, entry) ! 261: fmt_err *error; ! 262: bs_entry *entry; ! 263: { ! 264: format_sectors(&error->err_adr, &error->err_adr, NRM, 1); ! 265: format_sectors(&entry->bs_alt, &entry->bs_alt, NRM, 1); ! 266: } ! 267: ! 268: ! 269: /* ! 270: ** ! 271: */ ! 272: ! 273: remove_track(error, entry) ! 274: fmt_err *error; ! 275: bs_entry *entry; ! 276: { ! 277: format_sectors(&error->err_adr,&error->err_adr,NRM,(long)lab->d_nsectors); ! 278: format_sectors(&entry->bs_alt,&entry->bs_alt,NRM,(long)lab->d_nsectors); ! 279: } ! 280: ! 281: ! 282: /* ! 283: ** ! 284: */ ! 285: ! 286: write_bad_sector_map() ! 287: { ! 288: register int trk, sec; ! 289: dskadr dskaddr; ! 290: ! 291: bad_map->bs_magic = BSMAGIC; ! 292: bad_map->bs_id = 0; ! 293: dskaddr.cylinder = (lab->d_ncylinders - NUMMAP); ! 294: for(trk=0; trk < lab->d_ntracks; trk++) { ! 295: for(sec = 0; sec < lab->d_nsectors; sec++) { ! 296: bcopy((char *)bad_map + (sec * lab->d_secsize), ! 297: (char *)scratch, lab->d_secsize); ! 298: dskaddr.track = trk; ! 299: dskaddr.sector = sec; ! 300: format_sectors(&dskaddr, &dskaddr, WPT, 1); ! 301: } ! 302: } ! 303: } ! 304: ! 305: ! 306: /* ! 307: ** ! 308: */ ! 309: ! 310: zero_bad_sector_map() ! 311: { ! 312: bs_map *bm = bad_map; ! 313: register int i; ! 314: dskadr zero; ! 315: ! 316: zero.cylinder = 0; ! 317: zero.track = 0; ! 318: zero.sector = 0; ! 319: for(i=0; i < bm->bs_count; i++) ! 320: bm->list[i].bs_alt = zero; ! 321: load_free_table(); ! 322: } ! 323: ! 324: ! 325: /* ! 326: ** ! 327: */ ! 328: ! 329: read_flaw_map() ! 330: { ! 331: register int cyl, trk; ! 332: dskadr dskaddr; ! 333: flaw buffer; ! 334: ! 335: dskaddr.sector = 0; ! 336: for (cyl=0; cyl < lab->d_ncylinders; cyl++) { ! 337: dskaddr.cylinder = cyl; ! 338: for (trk=0; trk < lab->d_ntracks; trk++) { ! 339: dskaddr.track = trk; ! 340: access_dsk(&buffer, &dskaddr, VDOP_RDRAW, 1, 1); ! 341: if(align_buf(&buffer, CDCSYNC) == true) { ! 342: add_flaw_entries(&buffer); ! 343: continue; ! 344: } ! 345: } ! 346: } ! 347: load_free_table(); ! 348: } ! 349: ! 350: ! 351: /* ! 352: ** ! 353: */ ! 354: ! 355: get_smde_relocations() ! 356: { ! 357: register int cyl, trk, sec; ! 358: smde_hdr buffer; ! 359: dskadr dskaddr; ! 360: fmt_err bad; ! 361: bs_entry temp; ! 362: boolean bad_track; ! 363: ! 364: /* Read any old drive relocations */ ! 365: for(cyl=0; cyl < NUMREL; cyl++) { ! 366: dskaddr.cylinder = lab->d_ncylinders - NUMSYS + cyl; ! 367: for(trk=0; trk < lab->d_ntracks; trk++) { ! 368: dskaddr.track = trk; ! 369: bad_track = true; ! 370: for(sec=0; sec < lab->d_nsectors; sec++) { ! 371: dskaddr.sector = sec; ! 372: access_dsk(&buffer, &dskaddr, VDOP_RDRAW, 1, 1); ! 373: if(align_buf(&buffer, SMDE1SYNC) == false) { ! 374: bad_track = false; ! 375: break; ! 376: } ! 377: } ! 378: if(bad_track == true) { ! 379: dskaddr.sector = 0; ! 380: bad.err_adr.cylinder = buffer.alt_cyl; ! 381: bad.err_adr.track = buffer.alt_trk; ! 382: bad.err_adr.sector = 0; ! 383: bad.err_stat = HEADER_ERROR; ! 384: (*C_INFO->code_pos)(&bad, &temp); ! 385: temp.bs_alt = dskaddr; ! 386: temp.bs_how = scanning; ! 387: add_flaw(&temp); ! 388: continue; ! 389: } ! 390: for(sec=0; sec < lab->d_nsectors; sec++) { ! 391: dskaddr.sector = sec; ! 392: access_dsk(&buffer, &dskaddr, VDOP_RDRAW, 1, 1); ! 393: if(align_buf(&buffer, SMDE1SYNC) == true) { ! 394: bad.err_adr.cylinder = buffer.alt_cyl; ! 395: bad.err_adr.track = buffer.alt_trk; ! 396: bad.err_adr.sector = buffer.alt_sec; ! 397: bad.err_stat = DATA_ERROR; ! 398: (*C_INFO->code_pos)(&bad, &temp); ! 399: temp.bs_alt = dskaddr; ! 400: temp.bs_how = scanning; ! 401: add_flaw(&temp); ! 402: } ! 403: } ! 404: } ! 405: } ! 406: load_free_table(); ! 407: } ! 408: ! 409: ! 410: /* ! 411: ** ! 412: */ ! 413: ! 414: add_flaw_entries(buffer) ! 415: flaw *buffer; ! 416: { ! 417: register int i; ! 418: bs_entry temp; ! 419: ! 420: temp.bs_cyl = buffer->flaw_cyl & 0x7fff; /* clear off bad track bit */ ! 421: temp.bs_trk = buffer->flaw_trk; ! 422: for(i=0; i < 4; i++) { ! 423: if(buffer->flaw_pos[i].flaw_length != 0) { ! 424: temp.bs_offset = buffer->flaw_pos[i].flaw_offset; ! 425: temp.bs_length = buffer->flaw_pos[i].flaw_length; ! 426: temp.bs_alt.cylinder = 0; ! 427: temp.bs_alt.track = 0; ! 428: temp.bs_alt.sector = 0; ! 429: temp.bs_how = flaw_map; ! 430: add_flaw(&temp); ! 431: } ! 432: } ! 433: } ! 434: ! 435: ! 436: cmp_entry(a, b) ! 437: bs_entry *a; ! 438: bs_entry *b; ! 439: { ! 440: if(a->bs_cyl == b->bs_cyl) { ! 441: if(a->bs_trk == b->bs_trk) { ! 442: if(a->bs_offset == b->bs_offset) ! 443: return 0; ! 444: else if(a->bs_offset < b->bs_offset) ! 445: return -1; ! 446: } ! 447: else if(a->bs_trk < b->bs_trk) ! 448: return -1; ! 449: } ! 450: else if(a->bs_cyl < b->bs_cyl) ! 451: return -1; ! 452: return 1; ! 453: } ! 454: ! 455: ! 456: /* ! 457: * Add flaw to map. ! 458: * Return value: ! 459: * 1 OK ! 460: * 0 sector was in map ! 461: * -1 failure ! 462: */ ! 463: add_flaw(entry) ! 464: bs_entry *entry; ! 465: { ! 466: extern int cmp_entry(); ! 467: bs_map *bm = bad_map; ! 468: register int i; ! 469: ! 470: if(bm->bs_count > MAX_FLAWS) ! 471: return (-1); ! 472: if (entry->bs_cyl >= lab->d_ncylinders || ! 473: entry->bs_trk >= lab->d_ntracks || ! 474: entry->bs_offset >= lab->d_traksize) ! 475: return (-1); ! 476: for(i=0; i < bm->bs_count; i++) { ! 477: if(((bm->list[i].bs_cyl == entry->bs_cyl)) && ! 478: (bm->list[i].bs_trk == entry->bs_trk) && ! 479: (bm->list[i].bs_offset == entry->bs_offset)) { ! 480: if((int)bm->list[i].bs_how > (int)entry->bs_how) ! 481: bm->list[i].bs_how = entry->bs_how; ! 482: return (0); ! 483: } ! 484: } ! 485: bm->list[i] = *entry; ! 486: bm->list[i].bs_alt.cylinder = 0; ! 487: bm->list[i].bs_alt.track = 0; ! 488: bm->list[i].bs_alt.sector = 0; ! 489: bm->bs_count++; ! 490: qsort((char *)&(bm->list[0]), (unsigned)bm->bs_count, ! 491: sizeof(bs_entry), cmp_entry); ! 492: return (1); ! 493: } ! 494: ! 495: ! 496: /* ! 497: ** Is_in_map checks to see if a block is known to be bad already. ! 498: */ ! 499: ! 500: boolean is_in_map(dskaddr) ! 501: dskadr *dskaddr; ! 502: { ! 503: register int i; ! 504: fmt_err temp; ! 505: ! 506: for(i=0; i < bad_map->bs_count; i++) { ! 507: (*C_INFO->decode_pos)(&bad_map->list[i], &temp); ! 508: if((temp.err_adr.cylinder == dskaddr->cylinder) && ! 509: (temp.err_adr.track == dskaddr->track) && ! 510: (temp.err_adr.sector == dskaddr->sector)) { ! 511: return true; ! 512: } ! 513: } ! 514: return false; ! 515: } ! 516: ! 517: ! 518: /* ! 519: ** ! 520: */ ! 521: ! 522: print_bad_sector_list() ! 523: { ! 524: register int i; ! 525: fmt_err errloc; ! 526: register bs_entry *bad; ! 527: ! 528: if(bad_map->bs_magic != BSMAGIC) ! 529: print("Bad-sector map magic number wrong! (%x != %x)\n", ! 530: bad_map->bs_magic, BSMAGIC); ! 531: if(bad_map->bs_count == 0) { ! 532: print("There are no bad sectors in bad sector map.\n"); ! 533: return; ! 534: } ! 535: print("The following %d sector%s known to be bad:\n", ! 536: bad_map->bs_count, (bad_map->bs_count == 1) ? " is" : "s are"); ! 537: exdent(0); ! 538: for(i=0, bad = bad_map->list; i < bad_map->bs_count; i++, bad++) { ! 539: (*C_INFO->decode_pos)(bad, &errloc); ! 540: print("%c %d cn %d tn %d sn %d pos %d len %d ", ! 541: errloc.err_stat & HEADER_ERROR ? 'T' : 'S', ! 542: to_sector(errloc.err_adr), ! 543: bad->bs_cyl, ! 544: bad->bs_trk, ! 545: errloc.err_adr.sector, ! 546: bad->bs_offset, ! 547: bad->bs_length); ! 548: if (bad->bs_how == flaw_map) ! 549: printf("(flawmap) "); ! 550: else if (bad->bs_how == scanning) ! 551: printf("(verify) "); ! 552: else ! 553: printf("(operator) "); ! 554: if((bad->bs_alt.cylinder != 0) || (bad->bs_alt.track != 0) || ! 555: (bad->bs_alt.sector != 0)) { ! 556: printf("-> "); ! 557: printf("cn %d tn %d sn %d", bad->bs_alt.cylinder, ! 558: bad->bs_alt.track, bad->bs_alt.sector); ! 559: } ! 560: printf("\n"); ! 561: } ! 562: } ! 563: ! 564: ! 565: /* ! 566: ** load_free_table checks each block in the bad block relocation area ! 567: ** to see if it is used. If it is, the free relocation block table is updated. ! 568: */ ! 569: ! 570: load_free_table() ! 571: { ! 572: register int i, j; ! 573: fmt_err temp; ! 574: ! 575: /* Clear free table before starting */ ! 576: for(i = 0; i < (lab->d_ntracks * NUMREL); i++) { ! 577: for(j=0; j < lab->d_nsectors; j++) ! 578: free_tbl[i][j].free_status = NOTALLOCATED; ! 579: } ! 580: for(i=0; i < bad_map->bs_count; i++) ! 581: if((bad_map->list[i].bs_alt.cylinder != 0) || ! 582: (bad_map->list[i].bs_alt.track != 0) || ! 583: (bad_map->list[i].bs_alt.sector != 0)) { ! 584: (*C_INFO->decode_pos)(&bad_map->list[i], &temp); ! 585: allocate(&(bad_map->list[i].bs_alt), temp.err_stat); ! 586: } ! 587: } ! 588: ! 589: ! 590: /* ! 591: ** allocate marks a replacement sector as used. ! 592: */ ! 593: ! 594: allocate(dskaddr, status) ! 595: dskadr *dskaddr; ! 596: long status; ! 597: { ! 598: register int trk, sec; ! 599: ! 600: trk = dskaddr->cylinder - (lab->d_ncylinders - NUMSYS); ! 601: if((trk < 0) || (trk >= NUMREL)) ! 602: return; ! 603: trk *= lab->d_ntracks; ! 604: trk += dskaddr->track; ! 605: if(status & HEADER_ERROR) ! 606: for(sec=0; sec < lab->d_nsectors; sec++) ! 607: free_tbl[trk][sec].free_status = ALLOCATED; ! 608: else ! 609: free_tbl[trk][dskaddr->sector].free_status = ALLOCATED; ! 610: } ! 611: ! 612: ! 613: /* ! 614: ** ! 615: */ ! 616: ! 617: boolean mapping_collision(entry) ! 618: bs_entry *entry; ! 619: { ! 620: register int trk, sec; ! 621: fmt_err temp; ! 622: ! 623: trk = entry->bs_cyl - (lab->d_ncylinders - NUMSYS); ! 624: if((trk < 0) || (trk >= NUMREL)) ! 625: return false; ! 626: trk *= lab->d_ntracks; ! 627: trk += entry->bs_trk; ! 628: (*C_INFO->decode_pos)(entry, &temp); ! 629: /* if this relocation should take up the whole track */ ! 630: if(temp.err_stat & HEADER_ERROR) { ! 631: for(sec=0; sec < lab->d_nsectors; sec++) ! 632: if(free_tbl[trk][sec].free_status == ALLOCATED) ! 633: return true; ! 634: } ! 635: /* else just check the current sector */ ! 636: else { ! 637: if(free_tbl[trk][temp.err_adr.sector].free_status == ALLOCATED) ! 638: return true; ! 639: } ! 640: return false; ! 641: } ! 642: ! 643: ! 644: /* ! 645: ** ! 646: */ ! 647: ! 648: report_collision() ! 649: { ! 650: indent(); ! 651: print("Sector resides in relocation area"); ! 652: printf("but it has a sector mapped to it already.\n"); ! 653: print("Please reformat disk with 0 patterns to eliminate problem.\n"); ! 654: exdent(1); ! 655: } ! 656: ! 657: ! 658: /* ! 659: ** ! 660: */ ! 661: ! 662: add_user_relocations(entry) ! 663: bs_entry *entry; ! 664: { ! 665: fmt_err error; ! 666: ! 667: (*C_INFO->decode_pos)(entry, &error); ! 668: if(is_in_map(&error.err_adr) == false) { ! 669: if(mapping_collision(entry) == true) ! 670: report_collision(); ! 671: entry->bs_how = operator; ! 672: add_flaw(entry); ! 673: } ! 674: else { ! 675: indent(); ! 676: print("Sector %d is already mapped out!\n", ! 677: to_sector(error.err_adr)); ! 678: exdent(1); ! 679: } ! 680: } ! 681: ! 682: ! 683: /* ! 684: ** New_location allocates a replacement block given a bad block address. ! 685: ** The algorithm is fairly simple; it simply searches for the first ! 686: ** free sector that has the same sector number of the bad sector. If no sector ! 687: ** is found then the drive should be considered bad because of a microcode bug ! 688: ** in the controller that forces us to use the same sector number as the bad ! 689: ** sector for relocation purposes. Using different tracks and cylinders is ok ! 690: ** of course. ! 691: */ ! 692: ! 693: dskadr *new_location(entry) ! 694: bs_entry *entry; ! 695: { ! 696: register int i, sec; ! 697: static fmt_err temp; ! 698: static dskadr newaddr; ! 699: ! 700: newaddr.cylinder = 0; ! 701: newaddr.track = 0; ! 702: newaddr.sector = 0; ! 703: (*C_INFO->decode_pos)(entry, &temp); ! 704: /* If it is ouside of the user's data area */ ! 705: if(entry->bs_cyl >= lab->d_ncylinders-NUMSYS) { ! 706: /* if it is in the relocation area */ ! 707: if(entry->bs_cyl < (lab->d_ncylinders - NUMMAP - NUMMNT)) { ! 708: /* mark space as allocated */ ! 709: allocate(&temp.err_adr, temp.err_stat); ! 710: return &temp.err_adr; ! 711: } ! 712: /* if it is in the map area forget about it */ ! 713: if(entry->bs_cyl != (lab->d_ncylinders - NUMMAP - NUMMNT)) ! 714: return &temp.err_adr; ! 715: /* otherwise treat maintainence cylinder normally */ ! 716: } ! 717: if(temp.err_stat & (HEADER_ERROR)) { ! 718: for(i = 0; i < (lab->d_ntracks * NUMREL); i++) { ! 719: for(sec=0; sec < lab->d_nsectors; sec++) { ! 720: if(free_tbl[i][sec].free_status == ALLOCATED) ! 721: break; ! 722: } ! 723: if(sec == lab->d_nsectors) { ! 724: for(sec = 0; sec < lab->d_nsectors; sec++) ! 725: free_tbl[i][sec].free_status=ALLOCATED; ! 726: newaddr.cylinder = i / lab->d_ntracks + ! 727: (lab->d_ncylinders - NUMSYS); ! 728: newaddr.track = i % lab->d_ntracks; ! 729: break; ! 730: } ! 731: } ! 732: } ! 733: else if(C_INFO->type == VDTYPE_VDDC) { ! 734: for(i = 0; i < (lab->d_ntracks * NUMREL); i++) { ! 735: if(free_tbl[i][temp.err_adr.sector].free_status != ! 736: ALLOCATED) { ! 737: free_tbl[i][temp.err_adr.sector].free_status = ! 738: ALLOCATED; ! 739: newaddr.cylinder = i / lab->d_ntracks + ! 740: (lab->d_ncylinders - NUMSYS); ! 741: newaddr.track = i % lab->d_ntracks; ! 742: newaddr.sector = temp.err_adr.sector; ! 743: break; ! 744: } ! 745: } ! 746: } ! 747: else { ! 748: for(i = 0; i < (lab->d_ntracks * NUMREL); i++) { ! 749: for(sec=0; sec < lab->d_nsectors; sec++) ! 750: if(free_tbl[i][sec].free_status != ALLOCATED) ! 751: break; ! 752: if(sec < lab->d_nsectors) { ! 753: free_tbl[i][sec].free_status = ALLOCATED; ! 754: newaddr.cylinder = i / lab->d_ntracks + ! 755: (lab->d_ncylinders - NUMSYS); ! 756: newaddr.track = i % lab->d_ntracks; ! 757: newaddr.sector = sec; ! 758: break; ! 759: } ! 760: } ! 761: } ! 762: return &newaddr; ! 763: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.