1 #ifndef lint 2 static char sccsid[] = "@(#)format.c 1.8.1.1 (Berkeley/CCI) 07/24/92"; 3 #endif 4 5 #include "vdfmt.h" 6 7 /* 8 ** 9 */ 10 11 format() 12 { 13 boolean read_bad_sector_map(); 14 cur.state = fmt; 15 print("Starting format on "); 16 printf("controller %d, drive %d, ", cur.controller, cur.drive); 17 printf("type %s.\n", lab->d_typename); 18 19 if (lab->d_nsectors > MAXSECS_PER_TRK || 20 lab->d_ntracks > MAXTRKS) { 21 print( 22 "Drive geometry (number of sectors or tracks) is too large;\n"); 23 print("vdformat must be recompiled with larger value\n"); 24 print("for MAXTRKS or MAXSECS_PER_TRK.\n"); 25 _longjmp(abort_environ, 1); 26 } 27 /* Read the flaw map from the disk (where ever it may be) */ 28 if(read_bad_sector_map() == true) { 29 if(bad_map->bs_id != D_INFO->id) { 30 print("Module serial numbers do not match!\n"); 31 #ifdef notdef 32 print("Use `info' to find the real serial number.\n"); 33 _longjmp(abort_environ, 1); 34 #else 35 printf("Using serial number from drive, %d\n", 36 bad_map->bs_id); 37 D_INFO->id = bad_map->bs_id; 38 #endif 39 } 40 clear_relocations(false); 41 } 42 else 43 bad_map->bs_id = D_INFO->id; 44 45 #ifndef ONE 46 /* Re-Initialize bad sector map relocation pointers */ 47 zero_bad_sector_map(); 48 write_bad_sector_map(); 49 if(kill_processes == true) 50 _longjmp(quit_environ, 1); 51 52 /* format the disk surface */ 53 format_relocation_area(); 54 format_maintenence_area(); 55 #endif /* ONE */ 56 format_users_data_area(); 57 58 59 #ifndef ONE 60 /* verify the surface */ 61 verify_relocation_area(); 62 verify_maintenence_area(); 63 verify_users_data_area(); 64 #endif /* ONE */ 65 66 (void) writelabel(); 67 } 68 69 70 /* 71 ** 72 */ 73 74 format_relocation_area() 75 { 76 register long sector_count; 77 dskadr dskaddr; 78 79 cur.substate = sub_fmt; 80 dskaddr.cylinder = (short)(lab->d_ncylinders - NUMSYS); 81 dskaddr.track = (char)0; 82 dskaddr.sector = (char)0; 83 sector_count = (long)(NUMREL * lab->d_ntracks * lab->d_nsectors); 84 format_sectors(&dskaddr, &dskaddr, NRM, sector_count); 85 } 86 87 88 /* 89 ** 90 */ 91 92 format_users_data_area() 93 { 94 register long sector_count; 95 dskadr dskaddr; 96 register int cyl; 97 98 cur.substate = sub_fmt; 99 #ifndef ONE 100 sector_count = (long)(lab->d_ntracks * lab->d_nsectors); 101 #else /* ONE */ 102 sector_count = (long)(lab->d_nsectors); 103 #endif /* ONE */ 104 dskaddr.track = (char)0; 105 dskaddr.sector = (char)0; 106 #ifndef ONE 107 for(cyl=0; cyl < (lab->d_ncylinders - NUMSYS); cyl++) { 108 dskaddr.cylinder = cyl; 109 #else /* ONE */ 110 dskaddr.cylinder = 183; 111 dskaddr.track = 7; 112 #endif /* ONE */ 113 format_sectors(&dskaddr, &dskaddr, NRM, sector_count); 114 if (kill_processes) 115 return; 116 #ifndef ONE 117 } 118 #endif /* ONE */ 119 } 120 121 122 /* 123 ** 124 */ 125 126 format_maintenence_area() 127 { 128 register long sector_count; 129 dskadr dskaddr; 130 131 cur.substate = sub_fmt; 132 dskaddr.cylinder = (short)(lab->d_ncylinders - NUMMNT - NUMMAP); 133 dskaddr.track = (char)0; 134 dskaddr.sector = (char)0; 135 sector_count = (long)(NUMMNT * lab->d_ntracks * lab->d_nsectors); 136 format_sectors(&dskaddr, &dskaddr, NRM, sector_count); 137 } 138 139 140 /* 141 ** 142 */ 143 144 boolean is_formatted() 145 { 146 extern boolean align_buf(); 147 dskadr dskaddr; 148 149 dskaddr.cylinder = 0; 150 dskaddr.track = 0; 151 dskaddr.sector = 0; 152 if(C_INFO->type == VDTYPE_SMDE) { 153 access_dsk((char *)save, &dskaddr, VDOP_RDRAW, 1, 1); 154 if(align_buf((unsigned long *)save, CDCSYNC) == false) 155 return true; 156 return false; 157 } 158 else if(access_dsk((char *)save, &dskaddr, VDOP_RD, 1, 1)&HEADER_ERROR) 159 return false; 160 return true; 161 } 162 163 164 /* 165 ** Vdformat_sectors is used to do the actual formatting of a block. 166 */ 167 168 format_sectors(dskaddr, hdraddr, flags, count) 169 dskadr *dskaddr, *hdraddr; 170 short flags; 171 long count; 172 { 173 cur.daddr.cylinder = dskaddr->cylinder & 0xfff; 174 cur.daddr.track = dskaddr->track; 175 dcb.opcode = VDOP_FSECT; /* format sector command */ 176 dcb.intflg = DCBINT_NONE; 177 dcb.nxtdcb = (struct dcb *)0; /* end of chain */ 178 dcb.operrsta = 0; 179 dcb.devselect = (char)cur.drive | lab->d_devflags; 180 dcb.trailcnt = (char)(sizeof(struct trfmt) / sizeof(long)); 181 dcb.trail.fmtrail.addr = (char *)scratch; 182 #ifdef ONE 183 printf("format %d @ %d/%d/%d\n", count, dskaddr->cylinder, dskaddr->track, dskaddr->sector); 184 #endif /* ONE */ 185 dcb.trail.fmtrail.nsectors = count; 186 dcb.trail.fmtrail.disk.cylinder = dskaddr->cylinder | flags; 187 dcb.trail.fmtrail.disk.track = dskaddr->track; 188 dcb.trail.fmtrail.disk.sector = dskaddr->sector; 189 dcb.trail.fmtrail.hdr.cylinder = hdraddr->cylinder | flags; 190 dcb.trail.fmtrail.hdr.track = hdraddr->track; 191 dcb.trail.fmtrail.hdr.sector = hdraddr->sector; 192 mdcb.mdcb_head = &dcb; 193 mdcb.mdcb_status = 0; 194 VDGO(C_INFO->addr, (u_long)&mdcb, C_INFO->type); 195 poll((int)(((count+849)/850)+120)); 196 if(vdtimeout <= 0) { 197 printf(" while formatting sectors.\n"); 198 _longjmp(abort_environ, 1); 199 } 200 if (dcb.operrsta & DCBS_HARD) 201 vd_error("format"); 202 } 203