xref: /original-bsd/sys/tahoe/stand/vdformat/format.c (revision 77e11d34)
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