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