]> CyberLeo.Net >> Repos - FreeBSD/releng/9.2.git/blob - lib/libdisk/write_sparc64_disk.c
- Copy stable/9 to releng/9.2 as part of the 9.2-RELEASE cycle.
[FreeBSD/releng/9.2.git] / lib / libdisk / write_sparc64_disk.c
1 /*
2  * ----------------------------------------------------------------------------
3  * "THE BEER-WARE LICENSE" (Revision 42):
4  * <phk@FreeBSD.org> wrote this file.  As long as you retain this notice you
5  * can do whatever you want with this stuff. If we meet some day, and you think
6  * this stuff is worth it, you can buy me a beer in return.   Poul-Henning Kamp
7  * ----------------------------------------------------------------------------
8  */
9
10 #include <sys/cdefs.h>
11 __FBSDID("$FreeBSD$");
12
13 #include <stdio.h>
14 #include <stdlib.h>
15 #include <unistd.h>
16 #include <fcntl.h>
17 #include <err.h>
18 #include <string.h>
19 #include <sys/types.h>
20 #include <sys/stat.h>
21 #include <sys/ioctl.h>
22 #include <sys/sun_disklabel.h>
23 #include <paths.h>
24 #include <errno.h>
25 #include "libdisk.h"
26
27 #include "geom_sunlabel_enc.c"
28
29 int
30 Write_Disk(const struct disk *d1)
31 {
32         struct sun_disklabel *sl;
33         struct chunk *c, *c1, *c2;
34         int i;
35         char *p;
36         u_long secpercyl;
37         char device[64];
38         u_char buf[SUN_SIZE];
39         int fd;
40
41         strcpy(device, _PATH_DEV);
42         strcat(device, d1->name);
43
44         fd = open(device, O_RDWR);
45         if (fd < 0) {
46                 warn("open(%s) failed", device);
47                 return (1);
48         }
49
50         sl = calloc(sizeof *sl, 1);
51         c = d1->chunks;
52         c2 = c->part;
53         secpercyl = d1->bios_sect * d1->bios_hd;
54         sl->sl_pcylinders = c->size / secpercyl;
55         sl->sl_ncylinders = c2->size / secpercyl;
56         sl->sl_acylinders = sl->sl_pcylinders - sl->sl_ncylinders;
57         sl->sl_magic = SUN_DKMAGIC;
58         sl->sl_nsectors = d1->bios_sect;
59         sl->sl_ntracks = d1->bios_hd;
60         if (c->size > 4999 * 1024 * 2) {
61                 sprintf(sl->sl_text, "FreeBSD%luG cyl %u alt %u hd %u sec %u",
62                         (c->size + 1024 * 1024) / (2 * 1024 * 1024),
63                         sl->sl_ncylinders, sl->sl_acylinders,
64                         sl->sl_ntracks, sl->sl_nsectors);
65         } else {
66                 sprintf(sl->sl_text, "FreeBSD%luM cyl %u alt %u hd %u sec %u",
67                         (c->size + 1024) / (2 * 1024),
68                         sl->sl_ncylinders, sl->sl_acylinders,
69                         sl->sl_ntracks, sl->sl_nsectors);
70         }
71         sl->sl_interleave = 1;
72         sl->sl_sparespercyl = 0;
73         sl->sl_rpm = 3600;
74
75         for (c1 = c2->part; c1 != NULL; c1 = c1->next) {
76                 p = c1->name;
77                 p += strlen(p);
78                 p--;
79                 if (*p < 'a')
80                         continue;
81                 i = *p - 'a';
82                 if (i >= SUN_NPART)
83                         continue;
84                 sl->sl_part[i].sdkp_cyloffset = c1->offset / secpercyl;
85                 sl->sl_part[i].sdkp_nsectors = c1->size;
86                 for (i = 1; i < 16; i++) {
87                         write_block(fd, c1->offset + i, d1->boot1 + (i * 512),
88                             512);
89                 }
90         }
91
92         /*
93          * We need to fill in the "RAW" partition as well.  Emperical data
94          * seems to indicate that this covers the "obviously" visible part
95          * of the disk, ie: sl->sl_ncylinders.
96          */
97         sl->sl_part[SUN_RAWPART].sdkp_cyloffset = 0;
98         sl->sl_part[SUN_RAWPART].sdkp_nsectors = sl->sl_ncylinders * secpercyl;
99
100         memset(buf, 0, sizeof buf);
101         sunlabel_enc(buf, sl);
102         write_block(fd, 0, buf, sizeof buf);
103
104         close(fd);
105         return 0;
106 }