1 #ifndef lint
2 static char sccsid[] = "@(#)disklabel.c 1.3 (Berkeley/CCI) 06/24/90";
3 #endif
4
5 #include "vdfmt.h"
6 #include "cmd.h"
7
8 int lab_help();
9
10 /*
11 **
12 */
13
get_drive_type(ctlr,drive,op_mask)14 get_drive_type(ctlr, drive, op_mask)
15 int ctlr, drive, op_mask;
16 {
17 int tokens[20];
18 char line[132];
19 int savedevflags = 0;
20 register struct disklabel *lp;
21 struct disklabel *plp, *getdiskbyname(), *promptfordisk(), *findproto();
22
23 lp = lab;
24 if (lp->d_typename[0] == 0) {
25 print("Read label from drive %d, controller %d? ", drive, ctlr);
26 get_string_cmd(line, lab_help);
27 if (kill_processes == true)
28 return;
29 if (line[0] == 'y' || line[0] == 'Y') {
30 lp->d_secsize = 512;
31 lp->d_nsectors = 66;
32 lp->d_ntracks = 23;
33 lp->d_ncylinders = 850;
34 lp->d_secpercyl = 66*23;
35 if (D_INFO->alive != u_true)
36 spin_up_drive();
37 savedevflags = lab->d_devflags;
38 if (readlabel()) {
39 lp->d_devflags = savedevflags;
40 lp->d_pat = 0; /* this can't be what we want */
41 goto check;
42 }
43 lab->d_devflags = savedevflags;
44 lp->d_typename[0] = 0;
45 }
46 }
47 for (;;) {
48 print("Drive type for controller %d, drive %d? ", ctlr, drive);
49 if (lp->d_typename[0] != 0)
50 printf("(%s) ", lp->d_typename);
51 get_string_cmd(line, lab_help);
52 if (kill_processes == true)
53 return;
54 if (lp->d_typename[0] != 0 &&
55 (line[0] == 0 || strcmp(lp->d_typename, line) == 0))
56 break;
57 if (lp = findproto(line))
58 break;;
59 if (lp = getdiskbyname(line))
60 break;
61 if (lp = promptfordisk(line))
62 break;
63 if (kill_processes == true)
64 return;
65 lp = lab;
66 }
67 check:
68 plp = findproto(lp->d_typename);
69 while (lp->d_traksize == 0) {
70 print("number of bytes per track");
71 if (plp && plp->d_traksize)
72 printf(" (%d)", plp->d_traksize);
73 printf(": ");
74 get_string_cmd(line, lab_help);
75 if (kill_processes == true)
76 return;
77 if (line[0] == 0) {
78 if (plp->d_traksize == 0)
79 print("no default value\n");
80 lp->d_traksize = plp->d_traksize;
81 } else
82 lp->d_traksize = atol(line);
83 }
84 print("Drive geometry for controller %d, drive %d (%s):\n",
85 ctlr, drive, lp->d_typename);
86 print(" sector size %d; %d sectors, %d tracks, %d cylinders\n",
87 lp->d_secsize, lp->d_nsectors, lp->d_ntracks, lp->d_ncylinders);
88 if (lp->d_pat == 0 && op_mask & (FORMAT_OP | VERIFY_OP)) {
89 extern struct flawpat defpats, cdcpats;
90
91 print("media patterns for verify (default or cdc): ");
92 get_string_cmd(line, lab_help);
93 if (kill_processes == true)
94 return;
95 if (strcmp(line, "cdc") == 0)
96 lp->d_pat = (long) &cdcpats;
97 else
98 lp->d_pat = (long) &defpats;
99 }
100 if (lab->d_cylskew == -1)
101 lab->d_cylskew = 0;
102 if (lab->d_trackskew == -1)
103 lab->d_trackskew = 0;
104 if (lab->d_sparespertrack == -1)
105 lab->d_sparespertrack = 0;
106 if (lp != lab) {
107 *lab = *lp;
108 if (savedevflags)
109 lab->d_devflags = savedevflags;
110 }
111 configure_drive(1); /* set new parameters */
112 }
113
114 struct disklabel *
findproto(name)115 findproto(name)
116 char *name;
117 {
118 int count;
119
120 if (C_INFO->type == VDTYPE_VDDC)
121 count = smddrives;
122 else
123 count = 0;
124 for (; count < ndrives; count++)
125 if (strcmp(vdproto[count].d_typename, name) == 0)
126 return (&vdproto[count]);
127 return ((struct disklabel *) 0);
128 }
129
130 struct disklabel disk;
131
132 struct field {
133 char *f_name;
134 char *f_defaults;
135 u_long *f_location;
136 } fields[] = {
137 { "sector size", "512", &disk.d_secsize },
138 { "#sectors/track", 0, &disk.d_nsectors },
139 { "#tracks/cylinder", 0, &disk.d_ntracks },
140 { "#cylinders", 0, &disk.d_ncylinders },
141 { "#bytes/track", 0, &disk.d_traksize },
142 { 0, 0, 0 },
143 };
144
145 struct disklabel *
promptfordisk(name)146 promptfordisk(name)
147 char *name;
148 {
149 register struct disklabel *dp = &disk;
150 register struct field *fp;
151 register i;
152 char buf[132], *cp;
153
154 print("%s: unknown drive type\n", name);
155 if (get_yes_no("Enter drive parameters") == false)
156 return ((struct disklabel *)0);
157
158 strncpy(dp->d_typename, name, sizeof(dp->d_typename));
159 dp->d_type = DTYPE_SMD;
160 dp->d_flags = 0;
161
162 print("(type <cr> to get default value, if only one)\n");
163 for (fp = fields; fp->f_name != NULL; fp++) {
164 again:
165 print("%s ", fp->f_name);
166 if (fp->f_defaults != NULL)
167 printf("(%s)", fp->f_defaults);
168 printf("? ");
169 get_string_cmd(buf, lab_help);
170 if (kill_processes == true)
171 return ((struct disklabel *)0);
172 cp = buf;
173 if (*cp == '\0') {
174 if (fp->f_defaults == NULL) {
175 print("no default value\n");
176 goto again;
177 }
178 cp = fp->f_defaults;
179 }
180 *fp->f_location = atol(cp);
181 if (*fp->f_location == 0) {
182 print("%s: bad value\n", cp);
183 goto again;
184 }
185 }
186 print("sectors/cylinder (%d)? ", dp->d_nsectors * dp->d_ntracks);
187 get_string_cmd(buf, lab_help);
188 if (kill_processes == true)
189 return ((struct disklabel *)0);
190 if (buf[0] == 0)
191 dp->d_secpercyl = dp->d_nsectors * dp->d_ntracks;
192 else
193 dp->d_secpercyl = atol(buf);
194 return (dp);
195 }
196
lab_help()197 lab_help()
198 {
199 indent();
200 print("Entering drive type and parameters:\n");
201 indent();
202 print("Answer each question with a number or name, as appropriate.\n");
203 print("Questions with defaults show them in (parentheses);\n");
204 print("press return to accept the default.\n\n");
205 exdent(1);
206 print("Other commands available:\n");
207 indent();
208 print("QUIT - abort current operation\n");
209 exdent(2);
210 }
211
212 static char labelsector[VD_MAXSECSIZE];
213
214 /*
215 * Fetch disklabel for disk.
216 */
readlabel()217 readlabel()
218 {
219 register struct disklabel *lp;
220
221 bzero(labelsector, sizeof(labelsector));
222 if (vread(LABELSECTOR, labelsector, 1) < 1)
223 return (0);
224 for (lp = (struct disklabel *)labelsector;
225 lp <= (struct disklabel *)(labelsector+VD_MAXSECSIZE - sizeof(*lp));
226 lp = (struct disklabel *)((char *)lp + 16))
227 if (lp->d_magic == DISKMAGIC &&
228 lp->d_magic2 == DISKMAGIC)
229 break;
230 if (lp > (struct disklabel *)(labelsector+VD_MAXSECSIZE-sizeof(*lp)) ||
231 lp->d_magic != DISKMAGIC || lp->d_magic2 != DISKMAGIC ||
232 dkcksum(lp) != 0) {
233 print("Disk is unlabeled.\n");
234 return (0);
235 }
236 *lab = *lp;
237 return (1);
238 }
239
writelabel()240 writelabel()
241 {
242 register struct disklabel *lp;
243
244 bzero(labelsector, sizeof(labelsector));
245 lp = (struct disklabel *)(labelsector + LABELOFFSET);
246 *lp = *lab;
247 lp->d_magic = DISKMAGIC;
248 lp->d_magic2 = DISKMAGIC;
249 lp->d_checksum = 0;
250 lp->d_checksum = dkcksum(lp);
251 if (vwrite(LABELSECTOR, labelsector, 1) != 1)
252 printf("error writing disk label\n");
253 }
254