Magellan Linux

Annotation of /trunk/mkinitrd-magellan/busybox/util-linux/fdisk_sun.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 816 - (hide annotations) (download)
Fri Apr 24 18:33:46 2009 UTC (15 years, 1 month ago) by niro
File MIME type: text/plain
File size: 20420 byte(s)
-updated to busybox-1.13.4
1 niro 532 #if ENABLE_FEATURE_SUN_LABEL
2    
3 niro 816 #define SUNOS_SWAP 3
4     #define SUN_WHOLE_DISK 5
5    
6 niro 532 #define SUN_LABEL_MAGIC 0xDABE
7     #define SUN_LABEL_MAGIC_SWAPPED 0xBEDA
8     #define SUN_SSWAP16(x) (sun_other_endian ? fdisk_swap16(x) : (uint16_t)(x))
9     #define SUN_SSWAP32(x) (sun_other_endian ? fdisk_swap32(x) : (uint32_t)(x))
10    
11     /* Copied from linux/major.h */
12     #define FLOPPY_MAJOR 2
13    
14     #define SCSI_IOCTL_GET_IDLUN 0x5382
15    
16     /*
17     * fdisksunlabel.c
18     *
19     * I think this is mostly, or entirely, due to
20     * Jakub Jelinek (jj@sunsite.mff.cuni.cz), July 1996
21     *
22     * Merged with fdisk for other architectures, aeb, June 1998.
23     *
24     * Sat Mar 20 EST 1999 Arnaldo Carvalho de Melo <acme@conectiva.com.br>
25     * Internationalization
26     */
27    
28    
29     static int sun_other_endian;
30     static int scsi_disk;
31     static int floppy;
32    
33     #ifndef IDE0_MAJOR
34     #define IDE0_MAJOR 3
35     #endif
36     #ifndef IDE1_MAJOR
37     #define IDE1_MAJOR 22
38     #endif
39    
40     static void
41     guess_device_type(void)
42     {
43     struct stat bootstat;
44    
45 niro 816 if (fstat(dev_fd, &bootstat) < 0) {
46 niro 532 scsi_disk = 0;
47     floppy = 0;
48     } else if (S_ISBLK(bootstat.st_mode)
49     && (major(bootstat.st_rdev) == IDE0_MAJOR ||
50     major(bootstat.st_rdev) == IDE1_MAJOR)) {
51     scsi_disk = 0;
52     floppy = 0;
53     } else if (S_ISBLK(bootstat.st_mode)
54     && major(bootstat.st_rdev) == FLOPPY_MAJOR) {
55     scsi_disk = 0;
56     floppy = 1;
57     } else {
58     scsi_disk = 1;
59     floppy = 0;
60     }
61     }
62    
63 niro 816 static const char *const sun_sys_types[] = {
64     "\x00" "Empty" , /* 0 */
65     "\x01" "Boot" , /* 1 */
66     "\x02" "SunOS root" , /* 2 */
67     "\x03" "SunOS swap" , /* SUNOS_SWAP */
68     "\x04" "SunOS usr" , /* 4 */
69     "\x05" "Whole disk" , /* SUN_WHOLE_DISK */
70     "\x06" "SunOS stand" , /* 6 */
71     "\x07" "SunOS var" , /* 7 */
72     "\x08" "SunOS home" , /* 8 */
73     "\x82" "Linux swap" , /* LINUX_SWAP */
74     "\x83" "Linux native", /* LINUX_NATIVE */
75     "\x8e" "Linux LVM" , /* 0x8e */
76 niro 532 /* New (2.2.x) raid partition with autodetect using persistent superblock */
77 niro 816 "\xfd" "Linux raid autodetect", /* 0xfd */
78     NULL
79 niro 532 };
80    
81    
82     static void
83     set_sun_partition(int i, uint start, uint stop, int sysid)
84     {
85     sunlabel->infos[i].id = sysid;
86     sunlabel->partitions[i].start_cylinder =
87 niro 816 SUN_SSWAP32(start / (g_heads * g_sectors));
88 niro 532 sunlabel->partitions[i].num_sectors =
89     SUN_SSWAP32(stop - start);
90     set_changed(i);
91     }
92    
93     static int
94     check_sun_label(void)
95     {
96     unsigned short *ush;
97     int csum;
98    
99     if (sunlabel->magic != SUN_LABEL_MAGIC
100     && sunlabel->magic != SUN_LABEL_MAGIC_SWAPPED) {
101 niro 816 current_label_type = LABEL_DOS;
102 niro 532 sun_other_endian = 0;
103     return 0;
104     }
105     sun_other_endian = (sunlabel->magic == SUN_LABEL_MAGIC_SWAPPED);
106     ush = ((unsigned short *) (sunlabel + 1)) - 1;
107     for (csum = 0; ush >= (unsigned short *)sunlabel;) csum ^= *ush--;
108     if (csum) {
109 niro 816 printf("Detected sun disklabel with wrong checksum.\n"
110     "Probably you'll have to set all the values,\n"
111     "e.g. heads, sectors, cylinders and partitions\n"
112     "or force a fresh label (s command in main menu)\n");
113 niro 532 } else {
114 niro 816 g_heads = SUN_SSWAP16(sunlabel->ntrks);
115     g_cylinders = SUN_SSWAP16(sunlabel->ncyl);
116     g_sectors = SUN_SSWAP16(sunlabel->nsect);
117 niro 532 }
118     update_units();
119 niro 816 current_label_type = LABEL_SUN;
120     g_partitions = 8;
121 niro 532 return 1;
122     }
123    
124     static const struct sun_predefined_drives {
125     const char *vendor;
126     const char *model;
127     unsigned short sparecyl;
128     unsigned short ncyl;
129     unsigned short nacyl;
130     unsigned short pcylcount;
131     unsigned short ntrks;
132     unsigned short nsect;
133     unsigned short rspeed;
134     } sun_drives[] = {
135     { "Quantum","ProDrive 80S",1,832,2,834,6,34,3662},
136     { "Quantum","ProDrive 105S",1,974,2,1019,6,35,3662},
137     { "CDC","Wren IV 94171-344",3,1545,2,1549,9,46,3600},
138     { "IBM","DPES-31080",0,4901,2,4903,4,108,5400},
139     { "IBM","DORS-32160",0,1015,2,1017,67,62,5400},
140     { "IBM","DNES-318350",0,11199,2,11474,10,320,7200},
141     { "SEAGATE","ST34371",0,3880,2,3882,16,135,7228},
142     { "","SUN0104",1,974,2,1019,6,35,3662},
143     { "","SUN0207",4,1254,2,1272,9,36,3600},
144     { "","SUN0327",3,1545,2,1549,9,46,3600},
145     { "","SUN0340",0,1538,2,1544,6,72,4200},
146     { "","SUN0424",2,1151,2,2500,9,80,4400},
147     { "","SUN0535",0,1866,2,2500,7,80,5400},
148     { "","SUN0669",5,1614,2,1632,15,54,3600},
149     { "","SUN1.0G",5,1703,2,1931,15,80,3597},
150     { "","SUN1.05",0,2036,2,2038,14,72,5400},
151     { "","SUN1.3G",6,1965,2,3500,17,80,5400},
152     { "","SUN2.1G",0,2733,2,3500,19,80,5400},
153     { "IOMEGA","Jaz",0,1019,2,1021,64,32,5394},
154     };
155    
156     static const struct sun_predefined_drives *
157     sun_autoconfigure_scsi(void)
158     {
159     const struct sun_predefined_drives *p = NULL;
160    
161     #ifdef SCSI_IOCTL_GET_IDLUN
162     unsigned int id[2];
163     char buffer[2048];
164     char buffer2[2048];
165     FILE *pfd;
166     char *vendor;
167     char *model;
168     char *q;
169     int i;
170    
171 niro 816 if (ioctl(dev_fd, SCSI_IOCTL_GET_IDLUN, &id))
172 niro 532 return NULL;
173    
174     sprintf(buffer,
175     "Host: scsi%d Channel: %02d Id: %02d Lun: %02d\n",
176     /* This is very wrong (works only if you have one HBA),
177     but I haven't found a way how to get hostno
178     from the current kernel */
179     0,
180     (id[0]>>16) & 0xff,
181     id[0] & 0xff,
182     (id[0]>>8) & 0xff
183     );
184 niro 816 pfd = fopen_for_read("/proc/scsi/scsi");
185 niro 532 if (!pfd) {
186     return NULL;
187     }
188     while (fgets(buffer2, 2048, pfd)) {
189     if (strcmp(buffer, buffer2))
190     continue;
191     if (!fgets(buffer2, 2048, pfd))
192     break;
193     q = strstr(buffer2, "Vendor: ");
194     if (!q)
195     break;
196     q += 8;
197     vendor = q;
198     q = strstr(q, " ");
199     *q++ = '\0'; /* truncate vendor name */
200     q = strstr(q, "Model: ");
201     if (!q)
202     break;
203     *q = '\0';
204     q += 7;
205     model = q;
206     q = strstr(q, " Rev: ");
207     if (!q)
208     break;
209     *q = '\0';
210 niro 816 for (i = 0; i < ARRAY_SIZE(sun_drives); i++) {
211 niro 532 if (*sun_drives[i].vendor && strcasecmp(sun_drives[i].vendor, vendor))
212     continue;
213     if (!strstr(model, sun_drives[i].model))
214     continue;
215 niro 816 printf("Autoconfigure found a %s%s%s\n",
216 niro 532 sun_drives[i].vendor,
217     (*sun_drives[i].vendor) ? " " : "",
218     sun_drives[i].model);
219     p = sun_drives + i;
220     break;
221     }
222     break;
223     }
224     fclose(pfd);
225     #endif
226     return p;
227     }
228    
229     static void
230     create_sunlabel(void)
231     {
232     struct hd_geometry geometry;
233 niro 816 unsigned ndiv;
234 niro 532 unsigned char c;
235     const struct sun_predefined_drives *p = NULL;
236    
237 niro 816 printf(msg_building_new_label, "sun disklabel");
238    
239 niro 532 sun_other_endian = BB_LITTLE_ENDIAN;
240     memset(MBRbuffer, 0, sizeof(MBRbuffer));
241     sunlabel->magic = SUN_SSWAP16(SUN_LABEL_MAGIC);
242     if (!floppy) {
243 niro 816 unsigned i;
244     puts("Drive type\n"
245 niro 532 " ? auto configure\n"
246 niro 816 " 0 custom (with hardware detected defaults)");
247     for (i = 0; i < ARRAY_SIZE(sun_drives); i++) {
248 niro 532 printf(" %c %s%s%s\n",
249     i + 'a', sun_drives[i].vendor,
250     (*sun_drives[i].vendor) ? " " : "",
251     sun_drives[i].model);
252     }
253     while (1) {
254 niro 816 c = read_nonempty("Select type (? for auto, 0 for custom): ");
255     if (c == '0') {
256     break;
257     }
258     if (c >= 'a' && c < 'a' + ARRAY_SIZE(sun_drives)) {
259 niro 532 p = sun_drives + c - 'a';
260     break;
261 niro 816 }
262     if (c >= 'A' && c < 'A' + ARRAY_SIZE(sun_drives)) {
263 niro 532 p = sun_drives + c - 'A';
264     break;
265 niro 816 }
266     if (c == '?' && scsi_disk) {
267 niro 532 p = sun_autoconfigure_scsi();
268 niro 816 if (p)
269     break;
270     printf("Autoconfigure failed\n");
271 niro 532 }
272     }
273     }
274     if (!p || floppy) {
275 niro 816 if (!ioctl(dev_fd, HDIO_GETGEO, &geometry)) {
276     g_heads = geometry.heads;
277     g_sectors = geometry.sectors;
278     g_cylinders = geometry.cylinders;
279 niro 532 } else {
280 niro 816 g_heads = 0;
281     g_sectors = 0;
282     g_cylinders = 0;
283 niro 532 }
284     if (floppy) {
285     sunlabel->nacyl = 0;
286 niro 816 sunlabel->pcylcount = SUN_SSWAP16(g_cylinders);
287 niro 532 sunlabel->rspeed = SUN_SSWAP16(300);
288     sunlabel->ilfact = SUN_SSWAP16(1);
289     sunlabel->sparecyl = 0;
290     } else {
291 niro 816 g_heads = read_int(1, g_heads, 1024, 0, "Heads");
292     g_sectors = read_int(1, g_sectors, 1024, 0, "Sectors/track");
293     if (g_cylinders)
294     g_cylinders = read_int(1, g_cylinders - 2, 65535, 0, "Cylinders");
295 niro 532 else
296 niro 816 g_cylinders = read_int(1, 0, 65535, 0, "Cylinders");
297     sunlabel->nacyl = SUN_SSWAP16(read_int(0, 2, 65535, 0, "Alternate cylinders"));
298     sunlabel->pcylcount = SUN_SSWAP16(read_int(0, g_cylinders + SUN_SSWAP16(sunlabel->nacyl), 65535, 0, "Physical cylinders"));
299     sunlabel->rspeed = SUN_SSWAP16(read_int(1, 5400, 100000, 0, "Rotation speed (rpm)"));
300     sunlabel->ilfact = SUN_SSWAP16(read_int(1, 1, 32, 0, "Interleave factor"));
301     sunlabel->sparecyl = SUN_SSWAP16(read_int(0, 0, g_sectors, 0, "Extra sectors per cylinder"));
302 niro 532 }
303     } else {
304     sunlabel->sparecyl = SUN_SSWAP16(p->sparecyl);
305     sunlabel->ncyl = SUN_SSWAP16(p->ncyl);
306     sunlabel->nacyl = SUN_SSWAP16(p->nacyl);
307     sunlabel->pcylcount = SUN_SSWAP16(p->pcylcount);
308     sunlabel->ntrks = SUN_SSWAP16(p->ntrks);
309     sunlabel->nsect = SUN_SSWAP16(p->nsect);
310     sunlabel->rspeed = SUN_SSWAP16(p->rspeed);
311     sunlabel->ilfact = SUN_SSWAP16(1);
312 niro 816 g_cylinders = p->ncyl;
313     g_heads = p->ntrks;
314     g_sectors = p->nsect;
315     puts("You may change all the disk params from the x menu");
316 niro 532 }
317    
318     snprintf((char *)(sunlabel->info), sizeof(sunlabel->info),
319     "%s%s%s cyl %d alt %d hd %d sec %d",
320     p ? p->vendor : "", (p && *p->vendor) ? " " : "",
321 niro 816 p ? p->model : (floppy ? "3,5\" floppy" : "Linux custom"),
322     g_cylinders, SUN_SSWAP16(sunlabel->nacyl), g_heads, g_sectors);
323 niro 532
324 niro 816 sunlabel->ntrks = SUN_SSWAP16(g_heads);
325     sunlabel->nsect = SUN_SSWAP16(g_sectors);
326     sunlabel->ncyl = SUN_SSWAP16(g_cylinders);
327 niro 532 if (floppy)
328 niro 816 set_sun_partition(0, 0, g_cylinders * g_heads * g_sectors, LINUX_NATIVE);
329 niro 532 else {
330 niro 816 if (g_cylinders * g_heads * g_sectors >= 150 * 2048) {
331     ndiv = g_cylinders - (50 * 2048 / (g_heads * g_sectors)); /* 50M swap */
332 niro 532 } else
333 niro 816 ndiv = g_cylinders * 2 / 3;
334     set_sun_partition(0, 0, ndiv * g_heads * g_sectors, LINUX_NATIVE);
335     set_sun_partition(1, ndiv * g_heads * g_sectors, g_cylinders * g_heads * g_sectors, LINUX_SWAP);
336 niro 532 sunlabel->infos[1].flags |= 0x01; /* Not mountable */
337     }
338 niro 816 set_sun_partition(2, 0, g_cylinders * g_heads * g_sectors, SUN_WHOLE_DISK);
339 niro 532 {
340     unsigned short *ush = (unsigned short *)sunlabel;
341     unsigned short csum = 0;
342     while (ush < (unsigned short *)(&sunlabel->csum))
343     csum ^= *ush++;
344     sunlabel->csum = csum;
345     }
346    
347     set_all_unchanged();
348     set_changed(0);
349 niro 816 get_boot(CREATE_EMPTY_SUN);
350 niro 532 }
351    
352     static void
353     toggle_sunflags(int i, unsigned char mask)
354     {
355     if (sunlabel->infos[i].flags & mask)
356     sunlabel->infos[i].flags &= ~mask;
357     else
358     sunlabel->infos[i].flags |= mask;
359     set_changed(i);
360     }
361    
362     static void
363     fetch_sun(uint *starts, uint *lens, uint *start, uint *stop)
364     {
365     int i, continuous = 1;
366    
367     *start = 0;
368 niro 816 *stop = g_cylinders * g_heads * g_sectors;
369     for (i = 0; i < g_partitions; i++) {
370 niro 532 if (sunlabel->partitions[i].num_sectors
371     && sunlabel->infos[i].id
372     && sunlabel->infos[i].id != SUN_WHOLE_DISK) {
373 niro 816 starts[i] = SUN_SSWAP32(sunlabel->partitions[i].start_cylinder) * g_heads * g_sectors;
374 niro 532 lens[i] = SUN_SSWAP32(sunlabel->partitions[i].num_sectors);
375     if (continuous) {
376     if (starts[i] == *start)
377     *start += lens[i];
378     else if (starts[i] + lens[i] >= *stop)
379     *stop = starts[i];
380     else
381     continuous = 0;
382     /* There will be probably more gaps
383     than one, so lets check afterwards */
384     }
385     } else {
386     starts[i] = 0;
387     lens[i] = 0;
388     }
389     }
390     }
391    
392     static uint *verify_sun_starts;
393    
394     static int
395     verify_sun_cmp(int *a, int *b)
396     {
397     if (*a == -1) return 1;
398     if (*b == -1) return -1;
399     if (verify_sun_starts[*a] > verify_sun_starts[*b]) return 1;
400     return -1;
401     }
402    
403     static void
404     verify_sun(void)
405     {
406     uint starts[8], lens[8], start, stop;
407     int i,j,k,starto,endo;
408     int array[8];
409    
410     verify_sun_starts = starts;
411 niro 816 fetch_sun(starts, lens, &start, &stop);
412 niro 532 for (k = 0; k < 7; k++) {
413     for (i = 0; i < 8; i++) {
414 niro 816 if (k && (lens[i] % (g_heads * g_sectors))) {
415     printf("Partition %d doesn't end on cylinder boundary\n", i+1);
416 niro 532 }
417     if (lens[i]) {
418     for (j = 0; j < i; j++)
419     if (lens[j]) {
420     if (starts[j] == starts[i]+lens[i]) {
421     starts[j] = starts[i]; lens[j] += lens[i];
422     lens[i] = 0;
423     } else if (starts[i] == starts[j]+lens[j]){
424     lens[j] += lens[i];
425     lens[i] = 0;
426     } else if (!k) {
427     if (starts[i] < starts[j]+lens[j]
428     && starts[j] < starts[i]+lens[i]) {
429     starto = starts[i];
430     if (starts[j] > starto)
431     starto = starts[j];
432     endo = starts[i]+lens[i];
433     if (starts[j]+lens[j] < endo)
434     endo = starts[j]+lens[j];
435 niro 816 printf("Partition %d overlaps with others in "
436     "sectors %d-%d\n", i+1, starto, endo);
437 niro 532 }
438     }
439     }
440     }
441     }
442     }
443     for (i = 0; i < 8; i++) {
444     if (lens[i])
445     array[i] = i;
446     else
447     array[i] = -1;
448     }
449 niro 816 qsort(array, ARRAY_SIZE(array), sizeof(array[0]),
450 niro 532 (int (*)(const void *,const void *)) verify_sun_cmp);
451     if (array[0] == -1) {
452 niro 816 printf("No partitions defined\n");
453 niro 532 return;
454     }
455 niro 816 stop = g_cylinders * g_heads * g_sectors;
456 niro 532 if (starts[array[0]])
457 niro 816 printf("Unused gap - sectors 0-%d\n", starts[array[0]]);
458 niro 532 for (i = 0; i < 7 && array[i+1] != -1; i++) {
459 niro 816 printf("Unused gap - sectors %d-%d\n", starts[array[i]]+lens[array[i]], starts[array[i+1]]);
460 niro 532 }
461     start = starts[array[i]] + lens[array[i]];
462     if (start < stop)
463 niro 816 printf("Unused gap - sectors %d-%d\n", start, stop);
464 niro 532 }
465    
466     static void
467     add_sun_partition(int n, int sys)
468     {
469     uint start, stop, stop2;
470     uint starts[8], lens[8];
471     int whole_disk = 0;
472    
473     char mesg[256];
474     int i, first, last;
475    
476     if (sunlabel->partitions[n].num_sectors && sunlabel->infos[n].id) {
477 niro 816 printf(msg_part_already_defined, n + 1);
478 niro 532 return;
479     }
480    
481     fetch_sun(starts,lens,&start,&stop);
482     if (stop <= start) {
483     if (n == 2)
484     whole_disk = 1;
485     else {
486 niro 816 printf("Other partitions already cover the whole disk.\n"
487     "Delete/shrink them before retry.\n");
488 niro 532 return;
489     }
490     }
491 niro 816 snprintf(mesg, sizeof(mesg), "First %s", str_units(SINGULAR));
492 niro 532 while (1) {
493     if (whole_disk)
494     first = read_int(0, 0, 0, 0, mesg);
495     else
496     first = read_int(scround(start), scround(stop)+1,
497     scround(stop), 0, mesg);
498     if (display_in_cyl_units)
499     first *= units_per_sector;
500     else
501     /* Starting sector has to be properly aligned */
502 niro 816 first = (first + g_heads * g_sectors - 1) / (g_heads * g_sectors);
503 niro 532 if (n == 2 && first != 0)
504     printf("\
505     It is highly recommended that the third partition covers the whole disk\n\
506 niro 816 and is of type 'Whole disk'\n");
507 niro 532 /* ewt asks to add: "don't start a partition at cyl 0"
508     However, edmundo@rano.demon.co.uk writes:
509     "In addition to having a Sun partition table, to be able to
510     boot from the disc, the first partition, /dev/sdX1, must
511     start at cylinder 0. This means that /dev/sdX1 contains
512     the partition table and the boot block, as these are the
513     first two sectors of the disc. Therefore you must be
514     careful what you use /dev/sdX1 for. In particular, you must
515     not use a partition starting at cylinder 0 for Linux swap,
516     as that would overwrite the partition table and the boot
517     block. You may, however, use such a partition for a UFS
518     or EXT2 file system, as these file systems leave the first
519     1024 bytes undisturbed. */
520     /* On the other hand, one should not use partitions
521     starting at block 0 in an md, or the label will
522     be trashed. */
523 niro 816 for (i = 0; i < g_partitions; i++)
524 niro 532 if (lens[i] && starts[i] <= first && starts[i] + lens[i] > first)
525     break;
526 niro 816 if (i < g_partitions && !whole_disk) {
527 niro 532 if (n == 2 && !first) {
528     whole_disk = 1;
529     break;
530     }
531 niro 816 printf("Sector %d is already allocated\n", first);
532 niro 532 } else
533     break;
534     }
535 niro 816 stop = g_cylinders * g_heads * g_sectors;
536 niro 532 stop2 = stop;
537 niro 816 for (i = 0; i < g_partitions; i++) {
538 niro 532 if (starts[i] > first && starts[i] < stop)
539     stop = starts[i];
540     }
541     snprintf(mesg, sizeof(mesg),
542 niro 816 "Last %s or +size or +sizeM or +sizeK",
543 niro 532 str_units(SINGULAR));
544     if (whole_disk)
545     last = read_int(scround(stop2), scround(stop2), scround(stop2),
546     0, mesg);
547     else if (n == 2 && !first)
548     last = read_int(scround(first), scround(stop2), scround(stop2),
549     scround(first), mesg);
550     else
551     last = read_int(scround(first), scround(stop), scround(stop),
552     scround(first), mesg);
553     if (display_in_cyl_units)
554     last *= units_per_sector;
555     if (n == 2 && !first) {
556     if (last >= stop2) {
557     whole_disk = 1;
558     last = stop2;
559     } else if (last > stop) {
560 niro 816 printf(
561     "You haven't covered the whole disk with the 3rd partition,\n"
562     "but your value %d %s covers some other partition.\n"
563     "Your entry has been changed to %d %s\n",
564 niro 532 scround(last), str_units(SINGULAR),
565     scround(stop), str_units(SINGULAR));
566     last = stop;
567     }
568     } else if (!whole_disk && last > stop)
569     last = stop;
570    
571     if (whole_disk)
572     sys = SUN_WHOLE_DISK;
573     set_sun_partition(n, first, last, sys);
574     }
575    
576     static void
577     sun_delete_partition(int i)
578     {
579     unsigned int nsec;
580    
581     if (i == 2
582     && sunlabel->infos[i].id == SUN_WHOLE_DISK
583     && !sunlabel->partitions[i].start_cylinder
584 niro 816 && (nsec = SUN_SSWAP32(sunlabel->partitions[i].num_sectors)) == g_heads * g_sectors * g_cylinders)
585     printf("If you want to maintain SunOS/Solaris compatibility, "
586 niro 532 "consider leaving this\n"
587     "partition as Whole disk (5), starting at 0, with %u "
588 niro 816 "sectors\n", nsec);
589 niro 532 sunlabel->infos[i].id = 0;
590     sunlabel->partitions[i].num_sectors = 0;
591     }
592    
593     static void
594     sun_change_sysid(int i, int sys)
595     {
596     if (sys == LINUX_SWAP && !sunlabel->partitions[i].start_cylinder) {
597     read_maybe_empty(
598 niro 816 "It is highly recommended that the partition at offset 0\n"
599 niro 532 "is UFS, EXT2FS filesystem or SunOS swap. Putting Linux swap\n"
600     "there may destroy your partition table and bootblock.\n"
601     "Type YES if you're very sure you would like that partition\n"
602 niro 816 "tagged with 82 (Linux swap): ");
603     if (strcmp (line_ptr, "YES\n"))
604 niro 532 return;
605     }
606     switch (sys) {
607     case SUNOS_SWAP:
608     case LINUX_SWAP:
609     /* swaps are not mountable by default */
610     sunlabel->infos[i].flags |= 0x01;
611     break;
612     default:
613     /* assume other types are mountable;
614     user can change it anyway */
615     sunlabel->infos[i].flags &= ~0x01;
616     break;
617     }
618     sunlabel->infos[i].id = sys;
619     }
620    
621     static void
622     sun_list_table(int xtra)
623     {
624     int i, w;
625    
626     w = strlen(disk_device);
627     if (xtra)
628     printf(
629 niro 816 "\nDisk %s (Sun disk label): %d heads, %d sectors, %d rpm\n"
630 niro 532 "%d cylinders, %d alternate cylinders, %d physical cylinders\n"
631     "%d extra sects/cyl, interleave %d:1\n"
632     "%s\n"
633 niro 816 "Units = %s of %d * 512 bytes\n\n",
634     disk_device, g_heads, g_sectors, SUN_SSWAP16(sunlabel->rspeed),
635     g_cylinders, SUN_SSWAP16(sunlabel->nacyl),
636 niro 532 SUN_SSWAP16(sunlabel->pcylcount),
637     SUN_SSWAP16(sunlabel->sparecyl),
638     SUN_SSWAP16(sunlabel->ilfact),
639     (char *)sunlabel,
640     str_units(PLURAL), units_per_sector);
641     else
642     printf(
643 niro 816 "\nDisk %s (Sun disk label): %d heads, %d sectors, %d cylinders\n"
644     "Units = %s of %d * 512 bytes\n\n",
645     disk_device, g_heads, g_sectors, g_cylinders,
646 niro 532 str_units(PLURAL), units_per_sector);
647    
648 niro 816 printf("%*s Flag Start End Blocks Id System\n",
649     w + 1, "Device");
650     for (i = 0; i < g_partitions; i++) {
651 niro 532 if (sunlabel->partitions[i].num_sectors) {
652 niro 816 uint32_t start = SUN_SSWAP32(sunlabel->partitions[i].start_cylinder) * g_heads * g_sectors;
653 niro 532 uint32_t len = SUN_SSWAP32(sunlabel->partitions[i].num_sectors);
654     printf("%s %c%c %9ld %9ld %9ld%c %2x %s\n",
655     partname(disk_device, i+1, w), /* device */
656     (sunlabel->infos[i].flags & 0x01) ? 'u' : ' ', /* flags */
657     (sunlabel->infos[i].flags & 0x10) ? 'r' : ' ',
658     (long) scround(start), /* start */
659     (long) scround(start+len), /* end */
660     (long) len / 2, len & 1 ? '+' : ' ', /* odd flag on end */
661     sunlabel->infos[i].id, /* type id */
662     partition_type(sunlabel->infos[i].id)); /* type name */
663     }
664     }
665     }
666    
667     #if ENABLE_FEATURE_FDISK_ADVANCED
668    
669     static void
670     sun_set_alt_cyl(void)
671     {
672     sunlabel->nacyl =
673 niro 816 SUN_SSWAP16(read_int(0, SUN_SSWAP16(sunlabel->nacyl), 65535, 0,
674     "Number of alternate cylinders"));
675 niro 532 }
676    
677     static void
678     sun_set_ncyl(int cyl)
679     {
680     sunlabel->ncyl = SUN_SSWAP16(cyl);
681     }
682    
683     static void
684     sun_set_xcyl(void)
685     {
686     sunlabel->sparecyl =
687 niro 816 SUN_SSWAP16(read_int(0, SUN_SSWAP16(sunlabel->sparecyl), g_sectors, 0,
688     "Extra sectors per cylinder"));
689 niro 532 }
690    
691     static void
692     sun_set_ilfact(void)
693     {
694     sunlabel->ilfact =
695     SUN_SSWAP16(read_int(1, SUN_SSWAP16(sunlabel->ilfact), 32, 0,
696 niro 816 "Interleave factor"));
697 niro 532 }
698    
699     static void
700     sun_set_rspeed(void)
701     {
702     sunlabel->rspeed =
703     SUN_SSWAP16(read_int(1, SUN_SSWAP16(sunlabel->rspeed), 100000, 0,
704 niro 816 "Rotation speed (rpm)"));
705 niro 532 }
706    
707     static void
708     sun_set_pcylcount(void)
709     {
710     sunlabel->pcylcount =
711     SUN_SSWAP16(read_int(0, SUN_SSWAP16(sunlabel->pcylcount), 65535, 0,
712 niro 816 "Number of physical cylinders"));
713 niro 532 }
714     #endif /* FEATURE_FDISK_ADVANCED */
715    
716     static void
717     sun_write_table(void)
718     {
719     unsigned short *ush = (unsigned short *)sunlabel;
720     unsigned short csum = 0;
721    
722     while (ush < (unsigned short *)(&sunlabel->csum))
723     csum ^= *ush++;
724     sunlabel->csum = csum;
725 niro 816 write_sector(0, sunlabel);
726 niro 532 }
727     #endif /* SUN_LABEL */