1 #ifndef lint
2 static char sccsid[] = "@(#)relocate.c 1.7 (Berkeley/CCI) 06/24/90";
3 #endif
4
5 #include "vdfmt.h"
6 #include "cmd.h"
7
8 /*
9 **
10 */
11
relocate()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
rel_help()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
get_new_relocations()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
check_track_for_relocations(entry,i)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
is_relocated(entry)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
sync_bad_sector_map()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
do_relocation(entry)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
relocate_sector(entry)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
relocate_track(entry)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 }
383