|
|
Power 6/32 Unix version 1.21
#include "vdfmt.h"
#include "cmd.h"
/*
**
*/
relocate()
{
extern boolean is_formatted();
cur.state = rel;
print("Adding flaws to bad setor map on ");
printf("controller %d, drive %d, ", cur.controller, cur.drive);
printf("type %s.\n",CURRENT->type_name);
indent();
if(is_formatted() == true) {
if(read_bad_sector_map() == true)
if(bad_map->bs_id != D_INFO.id) {
print("Drive serial numbers do not match!\n");
exdent(1);
_longjmp(abort_environ, 1);
}
get_new_relocations();
sync_bad_sector_map();
}
else
print("Drive must be formatted befor relocations are done.\n");
exdent(1);
}
/*
**
*/
rel_help()
{
indent();
print("Relocation commands are in the following form:\n");
indent();
print("[a-h] (block) - UNIX file system format.\n");
print("SEctor (sector) - Absolute sector number on disk.\n");
print("Track (track) - Absolute disk track number.\n");
print("(cylinder) (head) (offset) (length) - CDC flaw map format.\n");
print("STARt - Starts relocation process.\n\n");
exdent(2);
}
/*
**
*/
get_new_relocations()
{
char line[256];
char *ptr;
bs_entry entry;
dskadr dskaddr;
int max_track;
dskaddr.cylinder = CURRENT->ncyl - 1;
dskaddr.cylinder = CURRENT->ntrak - 1;
max_track = to_track(dskaddr);
for(;;) {
print("Location? ");
get_string_cmd(line, rel_help);
if(kill_processes == true)
_longjmp(quit_environ, 1);
if(line[0] == '\0')
continue;
ptr = line;
trim_white(ptr);
if(!strncmp(ptr, "he", 2) || !strncmp(ptr, "?", 1) ||
!strncmp(ptr, "stat", 4) || !strncmp(ptr, "!", 1))
continue;
indent();
if((*ptr >= 'a') && (*ptr <= 'h')) {
register char par = *(ptr++);
register int block = get_next_digit(ptr);
dskaddr = *from_unix((unsigned char)par,
(unsigned int)block);
if((dskaddr.cylinder == -1) || (block == -1)) {
print("Invalid UNIX block number!\n");
goto next;
}
print("Confirm block %d on file-system '%c'",block,par);
if(get_yes_no("") == true) {
entry=(*C_INFO.code_pos)(dskaddr,HEADER_ERROR);
add_user_relocations(&entry);
}
}
else if(*ptr == 't') {
register int trk = get_next_digit(ptr);
if((trk == -1) || (trk >= max_track)) {
print("Invalid track number!\n");
goto next;
}
print("Confirm track %d", trk);
if(get_yes_no("") == true) {
dskaddr = *from_track(trk);
entry=(*C_INFO.code_pos)(dskaddr,HEADER_ERROR);
add_user_relocations(&entry);
}
}
else if(!strncmp(ptr, "se", 2)) {
register int sec = get_next_digit(ptr);
if((sec == -1) ||
((CURRENT->nsec*CURRENT->ntrak*CURRENT->ncyl)<sec)){
print("Invalid sector number!\n");
goto next;
}
print("Confirm sector %d", sec);
if(get_yes_no("") == true) {
dskaddr = *from_sector((unsigned int)sec);
entry = (*C_INFO.code_pos)(dskaddr, DATA_ERROR);
add_user_relocations(&entry);
}
}
else if(is_digit(*ptr)) {
entry.bs_cyl = get_next_digit(ptr);
skipdigits(ptr);
finddigit(ptr);
entry.bs_trk = get_next_digit(ptr);
skipdigits(ptr);
finddigit(ptr);
entry.bs_offset = get_next_digit(ptr);
skipdigits(ptr);
finddigit(ptr);
entry.bs_length = get_next_digit(ptr);
if((entry.bs_trk != -1) && (entry.bs_offset != -1) &&
(entry.bs_length != -1)) {
if(entry.bs_cyl >= CURRENT->ncyl)
print("Cylinder number to high!\n");
else if(entry.bs_trk >= CURRENT->ntrak)
print("Head number to high!\n");
else if(entry.bs_offset >= CURRENT->nbyte)
print("Offset too long!\n");
else if(entry.bs_length == 0)
print("Can't have a 0 length error!\n");
else {
print("Confirm Cyl %d, ",entry.bs_cyl);
printf("Head %d, ", entry.bs_trk);
printf("offset %d, ", entry.bs_offset);
printf("length %d", entry.bs_length);
if(get_yes_no("") == true)
add_user_relocations(&entry);
}
}
else
goto bad;
}
else if(!strncmp(ptr, "star", 4)) {
exdent(1);
break;
}
else
bad: print("What?\n");
next: exdent(1);
}
}
dskadr check_track_for_relocations(entry, i)
bs_entry entry;
register int i;
{
register int j = i;
fmt_err temp, cmp;
boolean bad_track = false;
cmp = (*C_INFO.decode_pos)(entry);
/* Check to see if a alternate track is or will be on this track */
while((bad_map->list[j].bs_cyl == entry.bs_cyl) &&
(bad_map->list[j].bs_trk == entry.bs_trk)) {
temp = (*C_INFO.decode_pos)(bad_map->list[j]);
if(temp.err_stat & HEADER_ERROR) {
bad_track = true;
/* if track was mapped out (it can't be us) */
if(((bad_map->list[j].bs_alt.cylinder != 0)) ||
(bad_map->list[j].bs_alt.track != 0) ||
(bad_map->list[j].bs_alt.sector != 0)) {
return cmp.err_adr;
}
}
j++;
}
/*
** If it was a bad track and it was not the current entry
** that produced it then then map it
** to itself and forget about it for now since it will be taken
** care of later.
**
** If it was the current entry return zero and the track will be
** mapped out correctly.
*/
if(bad_track == true) {
if(cmp.err_stat & HEADER_ERROR)
return entry.bs_alt; /* better known as zero */
else
return cmp.err_adr;
}
/*
** if we made it through all the bad track stuff then check for
** multiple errors on the same sector that are already mapped!
*/
j = i;
while((bad_map->list[j].bs_cyl == entry.bs_cyl) &&
(bad_map->list[j].bs_trk == entry.bs_trk)) {
temp = (*C_INFO.decode_pos)(bad_map->list[j]);
if(temp.err_adr.sector == cmp.err_adr.sector) {
/* if it is not really the current entry */
if((bad_map->list[j].bs_offset != entry.bs_offset) ||
(bad_map->list[j].bs_length != entry.bs_length)) {
/* if the sector is already mapped out */
if(((bad_map->list[j].bs_alt.cylinder != 0)) ||
(bad_map->list[j].bs_alt.track != 0) ||
(bad_map->list[j].bs_alt.sector != 0)) {
return temp.err_adr;
}
}
}
j++;
}
return entry.bs_alt;
}
/*
**
*/
dskadr is_relocated(entry)
bs_entry entry;
{
register int i;
for(i=0; i<bad_map->bs_count; i++)
if((bad_map->list[i].bs_cyl == entry.bs_cyl) &&
(bad_map->list[i].bs_trk == entry.bs_trk))
return check_track_for_relocations(entry, i);
return entry.bs_alt;
}
/*
**
*/
sync_bad_sector_map()
{
register int i;
dskadr dskaddr;
/*
** do all the relocation cylinders first to allocate all flaws in
** relocation area.
*/
for(i=bad_map->bs_count-1; i>=0; i--) {
if((bad_map->list[i].bs_cyl >= CURRENT->ncyl-NUMSYS) &&
(bad_map->list[i].bs_cyl < CURRENT->ncyl-NUMMAP-NUMMNT)) {
if((bad_map->list[i].bs_alt.cylinder == 0) &&
(bad_map->list[i].bs_alt.track == 0) &&
(bad_map->list[i].bs_alt.sector == 0)) {
bad_map->list[i].bs_alt =
*new_location(&bad_map->list[i]);
}
}
}
for(i=bad_map->bs_count-1; i>=0; i--) {
if((bad_map->list[i].bs_alt.cylinder == 0) &&
(bad_map->list[i].bs_alt.track == 0) &&
(bad_map->list[i].bs_alt.sector == 0)) {
dskaddr = is_relocated(bad_map->list[i]);
if((dskaddr.cylinder == 0) && (dskaddr.track == 0) &&
(dskaddr.sector == 0)) {
bad_map->list[i].bs_alt =
*new_location(&bad_map->list[i]);
do_relocation(bad_map->list[i]);
}
else
bad_map->list[i].bs_alt = dskaddr;
}
}
write_bad_sector_map();
}
/*
**
*/
do_relocation(entry)
bs_entry entry;
{
fmt_err temp;
if(entry.bs_cyl >= CURRENT->ncyl-NUMSYS)
if(entry.bs_cyl != (CURRENT->ncyl - NUMMAP - NUMMNT))
return;
temp = (*C_INFO.decode_pos)(entry);
if((entry.bs_alt.cylinder == 0) && (entry.bs_alt.track == 0) &&
(entry.bs_alt.sector == 0))
print_unix_block(temp.err_adr);
else if(temp.err_stat & HEADER_ERROR)
if(C_INFO.type == SMDCTLR) {
print("Can't relocate tracks on VDDC controllers.\n");
print_unix_block(temp.err_adr);
}
else
relocate_track(entry);
else
relocate_sector(entry);
}
/*
**
*/
relocate_sector(entry)
bs_entry entry;
{
dskadr phys, reloc;
fmt_err temp;
register long status;
temp = (*C_INFO.decode_pos)(entry);
phys = temp.err_adr;
reloc = entry.bs_alt;
format_sectors(&phys, &reloc, RELOC_SECTOR, (long)1);
format_sectors(&reloc, &phys, ALT_SECTOR, (long)1);
status = access_dsk((char *)save, &temp.err_adr, WD, 1, 1);
if(!((status & ALTACC) && !(status & (HRDERR |SFTERR)))) {
print("Sector relocation failed. Status = 0x%x.\n", status);
print_unix_block(phys);
}
}
/*
**
*/
relocate_track(entry)
bs_entry entry;
{
dskadr phys, reloc;
fmt_err temp;
register long status;
temp = (*C_INFO.decode_pos)(entry);
temp.err_adr.sector = 0;
phys = temp.err_adr;
reloc = entry.bs_alt;
reloc.sector = 0xff;
format_sectors(&phys, &reloc, RELOC_SECTOR, (long)CURRENT->nsec);
reloc.sector = 0x00;
format_sectors(&reloc, &phys, ALT_SECTOR, (long)CURRENT->nsec);
status = access_dsk((char *)save, &temp.err_adr, WD, CURRENT->nsec, 1);
if(!((status & ALTACC) && !(status & (HRDERR | SFTERR)))) {
print("Track relocation failed. Status = 0x%x.\n", status);
print_unix_block(phys);
}
}
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.