1 /* $NetBSD: ahdilabel.c,v 1.7 2008/04/28 20:23:15 martin Exp $ */
4 * Copyright (c) 1999 The NetBSD Foundation, Inc.
7 * This code is derived from software contributed to The NetBSD Foundation
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
40 * I think we can safely assume a fixed blocksize - AHDI won't support
41 * something different...
43 #define BLPM ((1024 * 1024) / DEV_BSIZE)
44 #define UNITS_SECTORS 0
50 int main (int, char*[]);
51 void show_parts (struct ahdi_ptable
*, int, int, int);
52 int get_input (char *, int);
53 char *sec_to_cts (struct ahdi_ptable
*, u_int32_t
, char *);
54 u_int32_t
read_sector (struct ahdi_ptable
*, char *, int, int);
55 void change_part (struct ahdi_ptable
*, int, int);
58 main (int argc
, char *argv
[])
60 struct ahdi_ptable ptable
;
61 int flags
, rv
, key
, units
;
64 fprintf (stderr
, "usage: %s raw_disk\n", argv
[0]);
68 flags
= AHDI_IGN_CKSUM
;
69 while ((rv
= ahdi_readlabel(&ptable
, argv
[1], flags
)) != 1) {
73 "%s: %s: %s\n", argv
[0], argv
[1],
79 "%s: disk not 512 bytes/sector\n", argv
[0]);
84 printf ("No AHDI partitions found. Continue (y/N)?");
85 if (toupper(getchar()) == 'Y') {
94 printf ("Errors reading AHDI partition table. Override (y/N)? ");
95 if (toupper(getchar()) == 'Y') {
96 flags
|= AHDI_IGN_EXISTS
| AHDI_IGN_EXT
|
102 /* Everything is OK */
110 units
= UNITS_SECTORS
;
111 flags
= AHDI_KEEP_BOOT
| AHDI_KEEP_BSL
;
112 show_parts (&ptable
, 0, ptable
.nparts
, units
);
113 printf ("Preserve boot sector - ");
114 flags
& AHDI_KEEP_BOOT
? printf ("yes\n") :
116 printf ("Preserve bad sector list - ");
117 flags
& AHDI_KEEP_BSL
? printf ("yes\n") :
121 (void) fpurge(stdin
);
122 printf ("Change [a-p], r)ecalculate, s)how, u)nits, w)rite, z)ero or q)uit ");
123 key
= toupper(getchar());
126 if (key
>= 'A' && key
<= 'P')
127 change_part (&ptable
, key
- 'A', units
);
129 if (ahdi_buildlabel (&ptable
)) {
130 printf ("Partiton table adjusted\n");
132 printf ("No changes necessary\n");
136 show_parts (&ptable
, 0, ptable
.nparts
, units
);
137 printf ("Preserve boot sector - ");
138 flags
& AHDI_KEEP_BOOT
? printf ("yes\n") :
140 printf ("Preserve bad sector list - ");
141 flags
& AHDI_KEEP_BSL
? printf ("yes\n") :
145 if (units
== UNITS_SECTORS
) {
146 printf ("Units now cylinder/track/sector\n");
149 printf ("Units now sector\n");
150 units
= UNITS_SECTORS
;
154 if ((rv
= ahdi_writelabel (&ptable
, argv
[1], flags
)) < 0) {
158 printf ("Invalid number of partitions!\n");
160 printf ("GEM partition should be BGM or BGM partition should be GEM!\n");
162 printf ("Partition overlaps root sector or bad sector list (starts before sector 2)!\n");
164 printf ("Partition extends past end of disk!\n");
166 printf ("Partitions overlap!\n");
168 printf ("Partition overlaps auxiliary root!\n");
170 printf ("More than 4 partitions in root sector!\n");
172 printf ("More than 1 partition in an auxiliary root!\n");
173 if (rv
< -1 && ahdi_errp1
!= -1)
174 printf ("\tpartition %c has errors.\n",
176 if (rv
< -1 && ahdi_errp2
!= -1)
177 printf ("\tpartition %c has errors.\n",
182 (void) fpurge(stdin
);
183 printf ("Preserve boot sector? ");
184 if (flags
& AHDI_KEEP_BOOT
) {
186 if (toupper (getchar ()) == 'N')
187 flags
&= ~AHDI_KEEP_BOOT
;
190 if (toupper (getchar ()) == 'Y')
191 flags
|= AHDI_KEEP_BOOT
;
193 (void) fpurge(stdin
);
194 printf ("Preserve bad sector list? ");
195 if (flags
& AHDI_KEEP_BSL
) {
197 if (toupper (getchar ()) == 'N')
198 flags
&= ~AHDI_KEEP_BSL
;
201 if (toupper (getchar ()) == 'Y')
202 flags
|= AHDI_KEEP_BSL
;
210 show_parts (struct ahdi_ptable
*ptable
, int start
, int finish
, int units
)
214 printf ("Disk information :\n");
215 printf (" sectors/track: %d\n", ptable
->nsectors
);
216 printf (" tracks/cylinder: %d\n", ptable
->ntracks
);
217 printf (" sectors/cylinder: %d\n", ptable
->secpercyl
);
218 printf (" cylinders: %d\n", ptable
->ncylinders
);
219 printf (" total sectors: %d\n", ptable
->secperunit
);
221 if (units
== UNITS_SECTORS
) {
222 printf (" # id root start end size MBs\n");
223 for (i
= start
; i
< finish
; i
++) {
224 if (finish
- start
> 10 && i
- start
== 8) {
225 (void) fpurge(stdin
);
226 printf ("-- Press return for more -- ");
229 printf (" %c %c%c%c %8u %8u %8u %8u (%4u)\n",
230 i
+ 'a', ptable
->parts
[i
].id
[0],
231 ptable
->parts
[i
].id
[1], ptable
->parts
[i
].id
[2],
232 ptable
->parts
[i
].root
, ptable
->parts
[i
].start
,
233 ptable
->parts
[i
].start
+
234 (ptable
->parts
[i
].size
?
235 ptable
->parts
[i
].size
- 1 : 0),
236 ptable
->parts
[i
].size
,
237 (ptable
->parts
[i
].size
+ (BLPM
>> 1)) / BLPM
);
240 u_int32_t cylinder
, track
, sector
;
241 printf (" # id root start end size MBs\n");
242 for (i
= start
; i
< finish
; i
++) {
243 if (finish
- start
> 10 && i
- start
== 8) {
244 (void) fpurge(stdin
);
245 printf ("-- Press return for more -- ");
248 printf (" %c %c%c%c ", i
+ 'a',
249 ptable
->parts
[i
].id
[0], ptable
->parts
[i
].id
[1],
250 ptable
->parts
[i
].id
[2]);
251 sector
= ptable
->parts
[i
].root
;
252 cylinder
= sector
/ ptable
->secpercyl
;
253 sector
-= cylinder
* ptable
->secpercyl
;
254 track
= sector
/ ptable
->nsectors
;
255 sector
-= track
* ptable
->nsectors
;
256 printf ("%5u/%2u/%3u ", cylinder
, track
, sector
);
257 sector
= ptable
->parts
[i
].start
;
258 cylinder
= sector
/ ptable
->secpercyl
;
259 sector
-= cylinder
* ptable
->secpercyl
;
260 track
= sector
/ ptable
->nsectors
;
261 sector
-= track
* ptable
->nsectors
;
262 printf ("%5u/%2u/%3u ", cylinder
, track
, sector
);
263 sector
= ptable
->parts
[i
].start
+
264 (ptable
->parts
[i
].size
?
265 ptable
->parts
[i
].size
- 1 : 0),
266 cylinder
= sector
/ ptable
->secpercyl
;
267 sector
-= cylinder
* ptable
->secpercyl
;
268 track
= sector
/ ptable
->nsectors
;
269 sector
-= track
* ptable
->nsectors
;
270 printf ("%5u/%2u/%3u ", cylinder
, track
, sector
);
271 sector
= ptable
->parts
[i
].size
;
272 cylinder
= sector
/ ptable
->secpercyl
;
273 sector
-= cylinder
* ptable
->secpercyl
;
274 track
= sector
/ ptable
->nsectors
;
275 sector
-= track
* ptable
->nsectors
;
276 printf ("%5u/%2u/%3u ", cylinder
, track
, sector
);
278 (ptable
->parts
[i
].size
+ (BLPM
>> 1)) / BLPM
);
284 get_input (char *buf
, int len
)
289 (void) fpurge(stdin
);
290 while (count
< (len
- 1) && (key
= getchar()) != '\n' && key
!= '\r') {
299 sec_to_cts (struct ahdi_ptable
*ptable
, u_int32_t sector
, char *cts
)
301 u_int32_t cylinder
, track
;
303 cylinder
= sector
/ ptable
->secpercyl
;
304 sector
-= cylinder
* ptable
->secpercyl
;
305 track
= sector
/ ptable
->nsectors
;
306 sector
-= track
* ptable
->nsectors
;
307 sprintf (cts
, "%u/%u/%u", cylinder
, track
, sector
);
312 read_sector (struct ahdi_ptable
*ptable
, char *buf
, int part
, int se
)
314 u_int32_t sector
, track
, cylinder
;
317 sector
= track
= cylinder
= 0;
318 if ((strchr (buf
, '/') != NULL
) &&
319 ((sscanf (buf
, "%u/%u/%u", &cylinder
, &track
, §or
) == 3) ||
320 (sscanf (buf
, "%u/%u/", &cylinder
, &track
) == 2) ||
321 (sscanf (buf
, "%u/", &cylinder
) == 1))) {
322 if (sector
> ptable
->nsectors
|| track
> ptable
->ntracks
||
323 cylinder
> ptable
->ncylinders
)
325 sector
+= ptable
->nsectors
* track
;
326 sector
+= ptable
->secpercyl
* cylinder
;
329 if (buf
[0] == '-' && buf
[1]) {
330 if (buf
[1] == '1' && se
== PART_END
)
331 /* Extend to end of disk */
332 return (ptable
->secperunit
-
333 ptable
->parts
[part
].start
);
334 i
= (int) (toupper ((unsigned char)(buf
[1]) - 'A'));
335 if (i
>= 0 && i
<= ptable
->nparts
) {
336 if (se
== PART_ROOT
&& part
> i
)
337 /* Root after partition ... */
338 return (ptable
->parts
[i
].start
+
339 ptable
->parts
[i
].size
);
340 if (se
== PART_START
&& part
> i
) {
341 /* Start after partition ... */
342 if (ptable
->parts
[part
].root
)
343 return (ptable
->parts
[i
].start
+
344 ptable
->parts
[i
].size
+ 1);
346 return (ptable
->parts
[i
].start
+
347 ptable
->parts
[i
].size
);
349 if (se
== PART_END
&& part
< i
)
350 /* End before partition ... */
351 return (ptable
->parts
[i
].root
-
352 ptable
->parts
[part
].start
);
356 if (sscanf (buf
, "%u", §or
) == 1) {
357 if (buf
[strlen (buf
) - 1] == 'm' ||
358 buf
[strlen (buf
) - 1] == 'M')
366 change_part (struct ahdi_ptable
*ptable
, int part
, int units
)
370 char buf
[BUFLEN
], cts
[CTSLEN
];
373 if (part
> ptable
->nparts
) {
374 part
= ptable
->nparts
;
375 printf ("Changing partition %c!\n", part
+ 'a');
378 if (part
== ptable
->nparts
)
380 show_parts (ptable
, part
, part
+ 1, units
);
382 printf ("id [%c%c%c] ", ptable
->parts
[part
].id
[0],
383 ptable
->parts
[part
].id
[1], ptable
->parts
[part
].id
[2]);
384 if (get_input (&buf
[0], BUFLEN
) > 2) {
385 ptable
->parts
[part
].id
[0] = buf
[0];
386 ptable
->parts
[part
].id
[1] = buf
[1];
387 ptable
->parts
[part
].id
[2] = buf
[2];
390 printf ("root [%8u (%s)] ", ptable
->parts
[part
].root
,
391 sec_to_cts (ptable
, ptable
->parts
[part
].root
, &cts
[0]));
392 if (get_input (&buf
[0], BUFLEN
)) {
393 sector
= read_sector (ptable
, buf
, part
, PART_ROOT
);
394 ptable
->parts
[part
].root
= sector
;
397 printf ("start [%8u (%s)] ", ptable
->parts
[part
].start
,
398 sec_to_cts (ptable
, ptable
->parts
[part
].start
, &cts
[0]));
399 if (get_input (&buf
[0], BUFLEN
)) {
400 sector
= read_sector (ptable
, buf
, part
, PART_START
);
401 ptable
->parts
[part
].start
= sector
;
404 printf ("size [%8u (%s) (%4uM)] ", ptable
->parts
[part
].size
,
405 sec_to_cts (ptable
, ptable
->parts
[part
].size
, &cts
[0]),
406 (ptable
->parts
[part
].size
+ (BLPM
>> 1)) / BLPM
);
407 if (get_input (&buf
[0], BUFLEN
)) {
408 sector
= read_sector (ptable
, buf
, part
, PART_END
);
409 ptable
->parts
[part
].size
= sector
;
413 printf ("NetBSD disk letter [%c] ", ptable->parts[part].letter + 'a');
414 if (get_input (&buf[0], BUFLEN)) {
415 buf[0] = tolower(buf[0]);
416 if (buf[0] == 'a' || (buf[0] >= 'd' && buf[0] <= 'p'))
417 ptable->parts[part].letter = buf[0] - 'a';
420 if (!ptable
->parts
[part
].start
&& !ptable
->parts
[part
].size
) {
421 if (part
== ptable
->nparts
- 1)