1106113Sphk/*
2106113Sphk * ----------------------------------------------------------------------------
3106113Sphk * "THE BEER-WARE LICENSE" (Revision 42):
4106113Sphk * <phk@FreeBSD.org> wrote this file.  As long as you retain this notice you
5106113Sphk * can do whatever you want with this stuff. If we meet some day, and you think
6106113Sphk * this stuff is worth it, you can buy me a beer in return.   Poul-Henning Kamp
7106113Sphk * ----------------------------------------------------------------------------
8106113Sphk */
9106113Sphk
10106113Sphk#include <sys/cdefs.h>
11106113Sphk__FBSDID("$FreeBSD$");
12106113Sphk
13106113Sphk#include <stdio.h>
14106113Sphk#include <stdlib.h>
15106113Sphk#include <unistd.h>
16106113Sphk#include <fcntl.h>
17106113Sphk#include <err.h>
18106113Sphk#include <string.h>
19106113Sphk#include <sys/types.h>
20106113Sphk#include <sys/stat.h>
21106113Sphk#include <sys/ioctl.h>
22106113Sphk#include <sys/sun_disklabel.h>
23106113Sphk#include <paths.h>
24106113Sphk#include <errno.h>
25106113Sphk#include "libdisk.h"
26106113Sphk
27113823Sphk#include "geom_sunlabel_enc.c"
28113823Sphk
29106113Sphkint
30106113SphkWrite_Disk(const struct disk *d1)
31106113Sphk{
32106113Sphk	struct sun_disklabel *sl;
33106113Sphk	struct chunk *c, *c1, *c2;
34106113Sphk	int i;
35106113Sphk	char *p;
36106113Sphk	u_long secpercyl;
37106113Sphk	char device[64];
38113823Sphk	u_char buf[SUN_SIZE];
39106113Sphk	int fd;
40106113Sphk
41106949Snyan	strcpy(device, _PATH_DEV);
42106949Snyan	strcat(device, d1->name);
43106745Sjake
44106949Snyan	fd = open(device, O_RDWR);
45106745Sjake	if (fd < 0) {
46106745Sjake		warn("open(%s) failed", device);
47106745Sjake		return (1);
48106745Sjake	}
49106745Sjake
50106113Sphk	sl = calloc(sizeof *sl, 1);
51106113Sphk	c = d1->chunks;
52106113Sphk	c2 = c->part;
53106113Sphk	secpercyl = d1->bios_sect * d1->bios_hd;
54106113Sphk	sl->sl_pcylinders = c->size / secpercyl;
55106113Sphk	sl->sl_ncylinders = c2->size / secpercyl;
56106113Sphk	sl->sl_acylinders = sl->sl_pcylinders - sl->sl_ncylinders;
57106113Sphk	sl->sl_magic = SUN_DKMAGIC;
58106113Sphk	sl->sl_nsectors = d1->bios_sect;
59106113Sphk	sl->sl_ntracks = d1->bios_hd;
60106113Sphk	if (c->size > 4999 * 1024 * 2) {
61106113Sphk		sprintf(sl->sl_text, "FreeBSD%luG cyl %u alt %u hd %u sec %u",
62106949Snyan			(c->size + 1024 * 1024) / (2 * 1024 * 1024),
63106949Snyan			sl->sl_ncylinders, sl->sl_acylinders,
64106949Snyan			sl->sl_ntracks, sl->sl_nsectors);
65106113Sphk	} else {
66106113Sphk		sprintf(sl->sl_text, "FreeBSD%luM cyl %u alt %u hd %u sec %u",
67106949Snyan			(c->size + 1024) / (2 * 1024),
68106949Snyan			sl->sl_ncylinders, sl->sl_acylinders,
69106949Snyan			sl->sl_ntracks, sl->sl_nsectors);
70106113Sphk	}
71106113Sphk	sl->sl_interleave = 1;
72106113Sphk	sl->sl_sparespercyl = 0;
73106113Sphk	sl->sl_rpm = 3600;
74106113Sphk
75106113Sphk	for (c1 = c2->part; c1 != NULL; c1 = c1->next) {
76106113Sphk		p = c1->name;
77106113Sphk		p += strlen(p);
78106113Sphk		p--;
79113823Sphk		if (*p < 'a')
80106113Sphk			continue;
81106113Sphk		i = *p - 'a';
82113823Sphk		if (i >= SUN_NPART)
83113823Sphk			continue;
84106113Sphk		sl->sl_part[i].sdkp_cyloffset = c1->offset / secpercyl;
85106113Sphk		sl->sl_part[i].sdkp_nsectors = c1->size;
86106745Sjake		for (i = 1; i < 16; i++) {
87106745Sjake			write_block(fd, c1->offset + i, d1->boot1 + (i * 512),
88106745Sjake			    512);
89106745Sjake		}
90106113Sphk	}
91106113Sphk
92106303Sphk	/*
93106303Sphk	 * We need to fill in the "RAW" partition as well.  Emperical data
94106303Sphk	 * seems to indicate that this covers the "obviously" visible part
95106303Sphk	 * of the disk, ie: sl->sl_ncylinders.
96106303Sphk	 */
97113823Sphk	sl->sl_part[SUN_RAWPART].sdkp_cyloffset = 0;
98113823Sphk	sl->sl_part[SUN_RAWPART].sdkp_nsectors = sl->sl_ncylinders * secpercyl;
99106303Sphk
100113823Sphk	memset(buf, 0, sizeof buf);
101113840Sphk	sunlabel_enc(buf, sl);
102113823Sphk	write_block(fd, 0, buf, sizeof buf);
103106113Sphk
104106113Sphk	close(fd);
105106113Sphk	return 0;
106106113Sphk}
107