write_sparc64_disk.c revision 113823
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: head/lib/libdisk/write_sparc64_disk.c 113823 2003-04-21 20:36:44Z phk $"); 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 29int 30Write_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 u_short *sp1, *sp2, cksum; 38 char device[64]; 39 u_char buf[SUN_SIZE]; 40 int fd; 41 42 strcpy(device, _PATH_DEV); 43 strcat(device, d1->name); 44 45 fd = open(device, O_RDWR); 46 if (fd < 0) { 47 warn("open(%s) failed", device); 48 return (1); 49 } 50 51 sl = calloc(sizeof *sl, 1); 52 c = d1->chunks; 53 c2 = c->part; 54 secpercyl = d1->bios_sect * d1->bios_hd; 55 sl->sl_pcylinders = c->size / secpercyl; 56 sl->sl_ncylinders = c2->size / secpercyl; 57 sl->sl_acylinders = sl->sl_pcylinders - sl->sl_ncylinders; 58 sl->sl_magic = SUN_DKMAGIC; 59 sl->sl_nsectors = d1->bios_sect; 60 sl->sl_ntracks = d1->bios_hd; 61 if (c->size > 4999 * 1024 * 2) { 62 sprintf(sl->sl_text, "FreeBSD%luG cyl %u alt %u hd %u sec %u", 63 (c->size + 1024 * 1024) / (2 * 1024 * 1024), 64 sl->sl_ncylinders, sl->sl_acylinders, 65 sl->sl_ntracks, sl->sl_nsectors); 66 } else { 67 sprintf(sl->sl_text, "FreeBSD%luM cyl %u alt %u hd %u sec %u", 68 (c->size + 1024) / (2 * 1024), 69 sl->sl_ncylinders, sl->sl_acylinders, 70 sl->sl_ntracks, sl->sl_nsectors); 71 } 72 sl->sl_interleave = 1; 73 sl->sl_sparespercyl = 0; 74 sl->sl_rpm = 3600; 75 76 for (c1 = c2->part; c1 != NULL; c1 = c1->next) { 77 p = c1->name; 78 p += strlen(p); 79 p--; 80 if (*p < 'a') 81 continue; 82 i = *p - 'a'; 83 if (i >= SUN_NPART) 84 continue; 85 sl->sl_part[i].sdkp_cyloffset = c1->offset / secpercyl; 86 sl->sl_part[i].sdkp_nsectors = c1->size; 87 for (i = 1; i < 16; i++) { 88 write_block(fd, c1->offset + i, d1->boot1 + (i * 512), 89 512); 90 } 91 } 92 93 /* 94 * We need to fill in the "RAW" partition as well. Emperical data 95 * seems to indicate that this covers the "obviously" visible part 96 * of the disk, ie: sl->sl_ncylinders. 97 */ 98 sl->sl_part[SUN_RAWPART].sdkp_cyloffset = 0; 99 sl->sl_part[SUN_RAWPART].sdkp_nsectors = sl->sl_ncylinders * secpercyl; 100 101 memset(buf, 0, sizeof buf); 102 sunlabel_enc(buf, &sl); 103 write_block(fd, 0, buf, sizeof buf); 104 105 close(fd); 106 return 0; 107} 108