geom_sunlabel_enc.c revision 113813
1113813Sphk/*- 2113813Sphk * Copyright (c) 2003 Jake Burkholder 3113813Sphk * Copyright (c) 2003 Poul-Henning Kamp 4113813Sphk * All rights reserved. 5113813Sphk * 6113813Sphk * Redistribution and use in source and binary forms, with or without 7113813Sphk * modification, are permitted provided that the following conditions 8113813Sphk * are met: 9113813Sphk * 1. Redistributions of source code must retain the above copyright 10113813Sphk * notice, this list of conditions and the following disclaimer. 11113813Sphk * 2. Redistributions in binary form must reproduce the above copyright 12113813Sphk * notice, this list of conditions and the following disclaimer in the 13113813Sphk * documentation and/or other materials provided with the distribution. 14113813Sphk * 15113813Sphk * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16113813Sphk * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17113813Sphk * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18113813Sphk * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19113813Sphk * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20113813Sphk * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21113813Sphk * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22113813Sphk * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23113813Sphk * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24113813Sphk * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25113813Sphk * SUCH DAMAGE. 26113813Sphk * 27113813Sphk * $FreeBSD: head/sys/geom/geom_sunlabel_enc.c 113813 2003-04-21 18:41:12Z phk $ 28113813Sphk * 29113813Sphk * Functions to encode or decode struct sun_disklabel into a bytestream 30113813Sphk * of correct endianess and packing. 31113813Sphk * 32113813Sphk * NB! This file must be usable both in kernel and userland. 33113813Sphk * 34113813Sphk */ 35113813Sphk 36113813Sphk#include <sys/types.h> 37113813Sphk#include <sys/endian.h> 38113813Sphk#include <sys/errno.h> 39113813Sphk#include <sys/sun_disklabel.h> 40113813Sphk 41113813Sphk#define SL_TEXT 0x0 42113813Sphk#define SL_TEXT_SIZEOF 0x80 43113813Sphk#define SL_RPM 0x1a4 44113813Sphk#define SL_PCYLINDERS 0x1a6 45113813Sphk#define SL_SPARESPERCYL 0x1a8 46113813Sphk#define SL_INTERLEAVE 0x1ae 47113813Sphk#define SL_NCYLINDERS 0x1b0 48113813Sphk#define SL_ACYLINDERS 0x1b2 49113813Sphk#define SL_NTRACKS 0x1b4 50113813Sphk#define SL_NSECTORS 0x1b6 51113813Sphk#define SL_PART 0x1bc 52113813Sphk#define SL_MAGIC 0x1fc 53113813Sphk#define SL_CKSUM 0x1fe 54113813Sphk 55113813Sphk#define SL_LENGTH 0x200 56113813Sphk 57113813Sphk#define SL_NPART 0x8 58113813Sphk 59113813Sphk#define SDKP_CYLOFFSET 0 60113813Sphk#define SDKP_NSECTORS 0x4 61113813Sphk#define SDKP_SIZEOF 0x8 62113813Sphk 63113813Sphk/* 64113813Sphk * Decode the relevant fields of a sun disk label, and return zero if the 65113813Sphk * magic and checksum works out OK. 66113813Sphk */ 67113813Sphkint 68113813Sphksunlabel_dec(void const *pp, struct sun_disklabel *sl) 69113813Sphk{ 70113813Sphk const uint8_t *p; 71113813Sphk size_t i; 72113813Sphk u_int u; 73113813Sphk 74113813Sphk p = pp; 75113813Sphk for (i = 0; i < sizeof(sl->sl_text); i++) 76113813Sphk sl->sl_text[i] = p[SL_TEXT + i]; 77113813Sphk sl->sl_rpm = be16dec(p + SL_RPM); 78113813Sphk sl->sl_pcylinders = be16dec(p + SL_PCYLINDERS); 79113813Sphk sl->sl_sparespercyl = be16dec(p + SL_SPARESPERCYL); 80113813Sphk sl->sl_interleave = be16dec(p + SL_INTERLEAVE); 81113813Sphk sl->sl_ncylinders = be16dec(p + SL_NCYLINDERS); 82113813Sphk sl->sl_acylinders = be16dec(p + SL_ACYLINDERS); 83113813Sphk sl->sl_ntracks = be16dec(p + SL_NTRACKS); 84113813Sphk sl->sl_nsectors = be16dec(p + SL_NSECTORS); 85113813Sphk for (i = 0; i < SL_NPART; i++) { 86113813Sphk sl->sl_part[i].sdkp_cyloffset = be32dec(p + SL_PART + 87113813Sphk (i * SDKP_SIZEOF) + SDKP_CYLOFFSET); 88113813Sphk sl->sl_part[i].sdkp_nsectors = be32dec(p + SL_PART + 89113813Sphk (i * SDKP_SIZEOF) + SDKP_NSECTORS); 90113813Sphk } 91113813Sphk sl->sl_magic = be16dec(p + SL_MAGIC); 92113813Sphk for (i = u = 0; i < SL_LENGTH; i += 2) 93113813Sphk u ^= be16dec(p + i); 94113813Sphk if (u == 0 && sl->sl_magic == SUN_DKMAGIC) 95113813Sphk return (0); 96113813Sphk else 97113813Sphk return (EINVAL); 98113813Sphk} 99113813Sphk 100113813Sphk/* 101113813Sphk * Encode the relevant fields into a sun disklabel, compute new checksum. 102113813Sphk */ 103113813Sphkvoid 104113813Sphksunlabel_enc(void *pp, struct sun_disklabel *sl) 105113813Sphk{ 106113813Sphk uint8_t *p; 107113813Sphk size_t i; 108113813Sphk u_int u; 109113813Sphk 110113813Sphk p = pp; 111113813Sphk for (i = 0; i < SL_TEXT_SIZEOF; i++) 112113813Sphk p[SL_TEXT + i] = sl->sl_text[i]; 113113813Sphk be16enc(p + SL_RPM, sl->sl_rpm); 114113813Sphk be16enc(p + SL_PCYLINDERS, sl->sl_pcylinders); 115113813Sphk be16enc(p + SL_SPARESPERCYL, sl->sl_sparespercyl); 116113813Sphk be16enc(p + SL_INTERLEAVE, sl->sl_interleave); 117113813Sphk be16enc(p + SL_NCYLINDERS, sl->sl_ncylinders); 118113813Sphk be16enc(p + SL_ACYLINDERS, sl->sl_acylinders); 119113813Sphk be16enc(p + SL_NTRACKS, sl->sl_ntracks); 120113813Sphk be16enc(p + SL_NSECTORS, sl->sl_nsectors); 121113813Sphk for (i = 0; i < SL_NPART; i++) { 122113813Sphk be32enc(p + SL_PART + (i * SDKP_SIZEOF) + SDKP_CYLOFFSET, 123113813Sphk sl->sl_part[i].sdkp_cyloffset); 124113813Sphk be32enc(p + SL_PART + (i * SDKP_SIZEOF) + SDKP_NSECTORS, 125113813Sphk sl->sl_part[i].sdkp_nsectors); 126113813Sphk } 127113813Sphk be16enc(p + SL_MAGIC, sl->sl_magic); 128113813Sphk for (i = u = 0; i < SL_LENGTH; i += 2) 129113813Sphk u ^= be16dec(p + i); 130113813Sphk be16enc(p + SL_CKSUM, u); 131113813Sphk} 132