geom_sunlabel_enc.c revision 116196
1176772Sraj/*- 2176772Sraj * Copyright (c) 2003 Jake Burkholder 3176772Sraj * Copyright (c) 2003 Poul-Henning Kamp 4176772Sraj * All rights reserved. 5176772Sraj * 6176772Sraj * Redistribution and use in source and binary forms, with or without 7176772Sraj * modification, are permitted provided that the following conditions 8176772Sraj * are met: 9176772Sraj * 1. Redistributions of source code must retain the above copyright 10176772Sraj * notice, this list of conditions and the following disclaimer. 11176772Sraj * 2. Redistributions in binary form must reproduce the above copyright 12176772Sraj * notice, this list of conditions and the following disclaimer in the 13176772Sraj * documentation and/or other materials provided with the distribution. 14176772Sraj * 15176772Sraj * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16176772Sraj * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17176772Sraj * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18176772Sraj * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19176772Sraj * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20176772Sraj * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21176772Sraj * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22176772Sraj * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23176772Sraj * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24176772Sraj * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25176772Sraj * SUCH DAMAGE. 26176772Sraj * 27176772Sraj * Functions to encode or decode struct sun_disklabel into a bytestream 28176772Sraj * of correct endianess and packing. 29176772Sraj * 30176772Sraj * NB! This file must be usable both in kernel and userland. 31176772Sraj */ 32176772Sraj 33176772Sraj#include <sys/cdefs.h> 34176772Sraj__FBSDID("$FreeBSD: head/sys/geom/geom_sunlabel_enc.c 116196 2003-06-11 06:49:16Z obrien $"); 35176772Sraj 36176772Sraj#include <sys/types.h> 37176772Sraj#include <sys/endian.h> 38176772Sraj#include <sys/errno.h> 39176772Sraj#include <sys/sun_disklabel.h> 40176772Sraj 41176772Sraj#define SL_TEXT 0x0 42176772Sraj#define SL_TEXT_SIZEOF 0x80 43176772Sraj#define SL_RPM 0x1a4 44176772Sraj#define SL_PCYLINDERS 0x1a6 45176772Sraj#define SL_SPARESPERCYL 0x1a8 46176772Sraj#define SL_INTERLEAVE 0x1ae 47176772Sraj#define SL_NCYLINDERS 0x1b0 48176772Sraj#define SL_ACYLINDERS 0x1b2 49176772Sraj#define SL_NTRACKS 0x1b4 50176772Sraj#define SL_NSECTORS 0x1b6 51176772Sraj#define SL_PART 0x1bc 52176772Sraj#define SL_MAGIC 0x1fc 53176772Sraj#define SL_CKSUM 0x1fe 54176772Sraj 55176772Sraj#define SDKP_CYLOFFSET 0 56176772Sraj#define SDKP_NSECTORS 0x4 57176772Sraj#define SDKP_SIZEOF 0x8 58176772Sraj 59176772Sraj/* 60176772Sraj * Decode the relevant fields of a sun disk label, and return zero if the 61176772Sraj * magic and checksum works out OK. 62176772Sraj */ 63176772Srajint 64176772Srajsunlabel_dec(void const *pp, struct sun_disklabel *sl) 65176772Sraj{ 66176772Sraj const uint8_t *p; 67176772Sraj size_t i; 68176772Sraj u_int u; 69176772Sraj 70176772Sraj p = pp; 71176772Sraj for (i = 0; i < sizeof(sl->sl_text); i++) 72176772Sraj sl->sl_text[i] = p[SL_TEXT + i]; 73176772Sraj sl->sl_rpm = be16dec(p + SL_RPM); 74176772Sraj sl->sl_pcylinders = be16dec(p + SL_PCYLINDERS); 75176772Sraj sl->sl_sparespercyl = be16dec(p + SL_SPARESPERCYL); 76176772Sraj sl->sl_interleave = be16dec(p + SL_INTERLEAVE); 77176772Sraj sl->sl_ncylinders = be16dec(p + SL_NCYLINDERS); 78176772Sraj sl->sl_acylinders = be16dec(p + SL_ACYLINDERS); 79176772Sraj sl->sl_ntracks = be16dec(p + SL_NTRACKS); 80176772Sraj sl->sl_nsectors = be16dec(p + SL_NSECTORS); 81176772Sraj for (i = 0; i < SUN_NPART; i++) { 82176772Sraj sl->sl_part[i].sdkp_cyloffset = be32dec(p + SL_PART + 83176772Sraj (i * SDKP_SIZEOF) + SDKP_CYLOFFSET); 84176772Sraj sl->sl_part[i].sdkp_nsectors = be32dec(p + SL_PART + 85176772Sraj (i * SDKP_SIZEOF) + SDKP_NSECTORS); 86176772Sraj } 87176772Sraj sl->sl_magic = be16dec(p + SL_MAGIC); 88176772Sraj for (i = u = 0; i < SUN_SIZE; i += 2) 89176772Sraj u ^= be16dec(p + i); 90176772Sraj if (u == 0 && sl->sl_magic == SUN_DKMAGIC) 91176772Sraj return (0); 92176772Sraj else 93176772Sraj return (EINVAL); 94176772Sraj} 95176772Sraj 96176772Sraj/* 97176772Sraj * Encode the relevant fields into a sun disklabel, compute new checksum. 98176772Sraj */ 99176772Srajvoid 100176772Srajsunlabel_enc(void *pp, struct sun_disklabel *sl) 101176772Sraj{ 102176772Sraj uint8_t *p; 103176772Sraj size_t i; 104176772Sraj u_int u; 105176772Sraj 106176772Sraj p = pp; 107176772Sraj for (i = 0; i < SL_TEXT_SIZEOF; i++) 108176772Sraj p[SL_TEXT + i] = sl->sl_text[i]; 109176772Sraj be16enc(p + SL_RPM, sl->sl_rpm); 110176772Sraj be16enc(p + SL_PCYLINDERS, sl->sl_pcylinders); 111176772Sraj be16enc(p + SL_SPARESPERCYL, sl->sl_sparespercyl); 112176772Sraj be16enc(p + SL_INTERLEAVE, sl->sl_interleave); 113176772Sraj be16enc(p + SL_NCYLINDERS, sl->sl_ncylinders); 114176772Sraj be16enc(p + SL_ACYLINDERS, sl->sl_acylinders); 115176772Sraj be16enc(p + SL_NTRACKS, sl->sl_ntracks); 116176772Sraj be16enc(p + SL_NSECTORS, sl->sl_nsectors); 117176772Sraj for (i = 0; i < SUN_NPART; i++) { 118176772Sraj be32enc(p + SL_PART + (i * SDKP_SIZEOF) + SDKP_CYLOFFSET, 119176772Sraj sl->sl_part[i].sdkp_cyloffset); 120176772Sraj be32enc(p + SL_PART + (i * SDKP_SIZEOF) + SDKP_NSECTORS, 121176772Sraj sl->sl_part[i].sdkp_nsectors); 122176772Sraj } 123176772Sraj be16enc(p + SL_MAGIC, sl->sl_magic); 124176772Sraj for (i = u = 0; i < SUN_SIZE; i += 2) 125176772Sraj u ^= be16dec(p + i); 126176772Sraj be16enc(p + SL_CKSUM, u); 127176772Sraj} 128176772Sraj