geom_sunlabel_enc.c revision 113818
1177633Sdfr/*- 2177633Sdfr * Copyright (c) 2003 Jake Burkholder 3177633Sdfr * Copyright (c) 2003 Poul-Henning Kamp 4177633Sdfr * All rights reserved. 5177633Sdfr * 6177633Sdfr * Redistribution and use in source and binary forms, with or without 7177633Sdfr * modification, are permitted provided that the following conditions 8177633Sdfr * are met: 9177633Sdfr * 1. Redistributions of source code must retain the above copyright 10177633Sdfr * notice, this list of conditions and the following disclaimer. 11177633Sdfr * 2. Redistributions in binary form must reproduce the above copyright 12177633Sdfr * notice, this list of conditions and the following disclaimer in the 13177633Sdfr * documentation and/or other materials provided with the distribution. 14177633Sdfr * 15177633Sdfr * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16177633Sdfr * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17177633Sdfr * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18177633Sdfr * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19177633Sdfr * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20177633Sdfr * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21177633Sdfr * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22177633Sdfr * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23177633Sdfr * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24177633Sdfr * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25177633Sdfr * SUCH DAMAGE. 26177633Sdfr * 27177633Sdfr * $FreeBSD: head/sys/geom/geom_sunlabel_enc.c 113818 2003-04-21 19:42:36Z phk $ 28177633Sdfr * 29177633Sdfr * Functions to encode or decode struct sun_disklabel into a bytestream 30177633Sdfr * of correct endianess and packing. 31177633Sdfr * 32177633Sdfr * NB! This file must be usable both in kernel and userland. 33177633Sdfr * 34177633Sdfr */ 35177633Sdfr 36177633Sdfr#include <sys/types.h> 37177633Sdfr#include <sys/endian.h> 38177633Sdfr#include <sys/errno.h> 39177633Sdfr#include <sys/sun_disklabel.h> 40177633Sdfr 41177633Sdfr#define SL_TEXT 0x0 42177633Sdfr#define SL_TEXT_SIZEOF 0x80 43177633Sdfr#define SL_RPM 0x1a4 44177633Sdfr#define SL_PCYLINDERS 0x1a6 45177633Sdfr#define SL_SPARESPERCYL 0x1a8 46177633Sdfr#define SL_INTERLEAVE 0x1ae 47177633Sdfr#define SL_NCYLINDERS 0x1b0 48177633Sdfr#define SL_ACYLINDERS 0x1b2 49177633Sdfr#define SL_NTRACKS 0x1b4 50177633Sdfr#define SL_NSECTORS 0x1b6 51177633Sdfr#define SL_PART 0x1bc 52184588Sdfr#define SL_MAGIC 0x1fc 53177633Sdfr#define SL_CKSUM 0x1fe 54184588Sdfr 55177633Sdfr#define SDKP_CYLOFFSET 0 56184588Sdfr#define SDKP_NSECTORS 0x4 57177633Sdfr#define SDKP_SIZEOF 0x8 58184588Sdfr 59177633Sdfr/* 60177633Sdfr * Decode the relevant fields of a sun disk label, and return zero if the 61177633Sdfr * magic and checksum works out OK. 62177633Sdfr */ 63177633Sdfrint 64184588Sdfrsunlabel_dec(void const *pp, struct sun_disklabel *sl) 65177633Sdfr{ 66177685Sdfr const uint8_t *p; 67177633Sdfr size_t i; 68177633Sdfr u_int u; 69184588Sdfr 70177633Sdfr p = pp; 71177633Sdfr for (i = 0; i < sizeof(sl->sl_text); i++) 72177633Sdfr sl->sl_text[i] = p[SL_TEXT + i]; 73184588Sdfr sl->sl_rpm = be16dec(p + SL_RPM); 74184588Sdfr sl->sl_pcylinders = be16dec(p + SL_PCYLINDERS); 75177633Sdfr sl->sl_sparespercyl = be16dec(p + SL_SPARESPERCYL); 76177633Sdfr sl->sl_interleave = be16dec(p + SL_INTERLEAVE); 77177633Sdfr sl->sl_ncylinders = be16dec(p + SL_NCYLINDERS); 78184588Sdfr sl->sl_acylinders = be16dec(p + SL_ACYLINDERS); 79184588Sdfr sl->sl_ntracks = be16dec(p + SL_NTRACKS); 80184588Sdfr sl->sl_nsectors = be16dec(p + SL_NSECTORS); 81177633Sdfr for (i = 0; i < SUN_NPART; i++) { 82184588Sdfr sl->sl_part[i].sdkp_cyloffset = be32dec(p + SL_PART + 83177633Sdfr (i * SDKP_SIZEOF) + SDKP_CYLOFFSET); 84177633Sdfr sl->sl_part[i].sdkp_nsectors = be32dec(p + SL_PART + 85177633Sdfr (i * SDKP_SIZEOF) + SDKP_NSECTORS); 86177633Sdfr } 87177633Sdfr sl->sl_magic = be16dec(p + SL_MAGIC); 88177633Sdfr for (i = u = 0; i < SUN_SIZE; i += 2) 89184588Sdfr u ^= be16dec(p + i); 90184588Sdfr if (u == 0 && sl->sl_magic == SUN_DKMAGIC) 91184588Sdfr return (0); 92177633Sdfr else 93177633Sdfr return (EINVAL); 94177633Sdfr} 95184588Sdfr 96184588Sdfr/* 97184588Sdfr * Encode the relevant fields into a sun disklabel, compute new checksum. 98184588Sdfr */ 99184588Sdfrvoid 100177633Sdfrsunlabel_enc(void *pp, struct sun_disklabel *sl) 101184588Sdfr{ 102184588Sdfr uint8_t *p; 103184588Sdfr size_t i; 104184588Sdfr u_int u; 105184588Sdfr 106184588Sdfr p = pp; 107184588Sdfr for (i = 0; i < SL_TEXT_SIZEOF; i++) 108184588Sdfr p[SL_TEXT + i] = sl->sl_text[i]; 109184588Sdfr be16enc(p + SL_RPM, sl->sl_rpm); 110184588Sdfr be16enc(p + SL_PCYLINDERS, sl->sl_pcylinders); 111184588Sdfr be16enc(p + SL_SPARESPERCYL, sl->sl_sparespercyl); 112184588Sdfr be16enc(p + SL_INTERLEAVE, sl->sl_interleave); 113184588Sdfr be16enc(p + SL_NCYLINDERS, sl->sl_ncylinders); 114184588Sdfr be16enc(p + SL_ACYLINDERS, sl->sl_acylinders); 115184588Sdfr be16enc(p + SL_NTRACKS, sl->sl_ntracks); 116184588Sdfr be16enc(p + SL_NSECTORS, sl->sl_nsectors); 117184588Sdfr for (i = 0; i < SUN_NPART; i++) { 118184588Sdfr be32enc(p + SL_PART + (i * SDKP_SIZEOF) + SDKP_CYLOFFSET, 119184588Sdfr sl->sl_part[i].sdkp_cyloffset); 120184588Sdfr be32enc(p + SL_PART + (i * SDKP_SIZEOF) + SDKP_NSECTORS, 121184588Sdfr sl->sl_part[i].sdkp_nsectors); 122184588Sdfr } 123184588Sdfr be16enc(p + SL_MAGIC, sl->sl_magic); 124184588Sdfr for (i = u = 0; i < SUN_SIZE; i += 2) 125184588Sdfr u ^= be16dec(p + i); 126184588Sdfr be16enc(p + SL_CKSUM, u); 127184588Sdfr} 128184588Sdfr