Home | History | Annotate | Line # | Download | only in ews4800mips
      1 /*	$NetBSD: disklabel_conv.c,v 1.4 2008/04/28 20:23:18 martin Exp $	*/
      2 
      3 /*-
      4  * Copyright (c) 2004 The NetBSD Foundation, Inc.
      5  * All rights reserved.
      6  *
      7  * This code is derived from software contributed to The NetBSD Foundation
      8  * by UCHIYAMA Yasushi.
      9  *
     10  * Redistribution and use in source and binary forms, with or without
     11  * modification, are permitted provided that the following conditions
     12  * are met:
     13  * 1. Redistributions of source code must retain the above copyright
     14  *    notice, this list of conditions and the following disclaimer.
     15  * 2. Redistributions in binary form must reproduce the above copyright
     16  *    notice, this list of conditions and the following disclaimer in the
     17  *    documentation and/or other materials provided with the distribution.
     18  *
     19  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     20  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     21  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     22  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     23  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     27  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     29  * POSSIBILITY OF SUCH DAMAGE.
     30  */
     31 
     32 #include <sys/cdefs.h>
     33 __KERNEL_RCSID(0, "$NetBSD: disklabel_conv.c,v 1.4 2008/04/28 20:23:18 martin Exp $");
     34 
     35 #include <sys/systm.h>
     36 #include <sys/param.h>
     37 
     38 #ifndef _KERNEL
     39 #include "local.h"
     40 #endif
     41 
     42 #include <sys/disklabel.h>
     43 
     44 /*
     45  * NetBSD/ews4800mips EWS-UX compatible disk layout.
     46  *
     47  * 0============================+ cylinder 0
     48  * 1	1stboot	program (4KB)	|
     49  * .				.
     50  * 7----------------------------+
     51  * 8	PDINFO			| UX unvisible region.
     52  * 9    BSD disklabel           | I (uch) decided to locate disklabel here.
     53  * .				.
     54  * .	error log	(UX)	|
     55  * +============================+ cylinder 1
     56  * |	logical_start	(UX)	|
     57  * |	VTOC			|
     58  * .				. UX Boot block	(partition 7)
     59  * .				. 100 blocks (default. at least 2 blocks)
     60  * .				.
     61  * .				.
     62  * +============================+
     63  * |   BFS			|
     64  * |		boot loader	|
     65  * .		disklabel	.
     66  * .		and etc.	. BFS		(partition 3)
     67  * .				.
     68  * .				.
     69  * .				.
     70  * -----------------------------+
     71  */
     72 
     73 #define	_BFS_SIZE			16384	/* 8MB */
     74 #define	_BOOTBLOCK_SIZE			100	/* UX default */
     75 #define	_FAKE_TRACKS_PER_CYLINDER	16
     76 #define	_FAKE_SECTORS_PER_TRACK		1
     77 
     78 void
     79 disklabel_set_default(struct disklabel *d)
     80 {
     81 
     82 	d->d_magic = DISKMAGIC;
     83 	d->d_magic2 = DISKMAGIC;
     84 	d->d_secsize = DEV_BSIZE;
     85 	d->d_npartitions = MAXPARTITIONS;
     86 }
     87 
     88 void
     89 vtoc_set_default( struct cpu_disklabel *ux, struct disklabel *d)
     90 {
     91 	struct pdinfo_sector *pdinfo = &ux->pdinfo;
     92 	struct vtoc_sector *vtoc = &ux->vtoc;
     93 	struct ux_partition *bfs;
     94 	struct ux_partition *boot;
     95 	struct ux_partition *bsdraw;
     96 	int nsectors, logical_sector, cylinder_blocks, res;
     97 
     98 	memset(vtoc, 0, sizeof *vtoc);
     99 	memset(pdinfo, 0, sizeof *pdinfo);
    100 	if (d)
    101 		cylinder_blocks = d->d_ntracks * d->d_nsectors;
    102 	else
    103 		cylinder_blocks =
    104 		    _FAKE_TRACKS_PER_CYLINDER * _FAKE_SECTORS_PER_TRACK;
    105 	logical_sector = cylinder_blocks;
    106 
    107 	pdinfo->drive_id = 0x5c512000;	/* Fake for EWS-UX */
    108 	pdinfo->magic = PDINFO_MAGIC;
    109 	pdinfo->version = PDINFO_VERSION;
    110 	pdinfo->logical_sector = logical_sector;
    111 	pdinfo->ux.errorlog_sector = logical_sector - 1;
    112 	pdinfo->ux.errorlog_size_byte = DEV_BSIZE;
    113 
    114 	if (d) { /* use drivers disk geometory */
    115 		pdinfo->geometory.cylinders_per_drive = d->d_ncylinders;
    116 		pdinfo->geometory.tracks_per_cylinder = d->d_ntracks;
    117 		pdinfo->geometory.sectors_per_track = d->d_nsectors;
    118 		pdinfo->geometory.bytes_per_sector = d->d_secsize;
    119 		nsectors = d->d_ncylinders * d->d_ntracks * d->d_nsectors;
    120 	} else { /* set fake */
    121 		pdinfo->geometory.sectors_per_track =
    122 		    _FAKE_SECTORS_PER_TRACK;
    123 		pdinfo->geometory.tracks_per_cylinder =
    124 		    _FAKE_TRACKS_PER_CYLINDER;
    125 		pdinfo->geometory.cylinders_per_drive = 0x1fffffff;
    126 		pdinfo->geometory.bytes_per_sector = DEV_BSIZE;
    127 		nsectors = 0x1fffffff;
    128 	}
    129 
    130 	/* following magic numbers are required for EWS-UX */
    131 	pdinfo->device_depend[15] = 0xfb7e10;
    132 	pdinfo->device_depend[16] = 0x200;
    133 	pdinfo->device_depend[17] = 0x10;
    134 
    135 	vtoc->magic = VTOC_MAGIC;
    136 	vtoc->version = VTOC_VERSION;
    137 	vtoc->sector_size_byte = DEV_BSIZE;
    138 	vtoc->npartitions = VTOC_MAXPARTITIONS;
    139 
    140 	boot = &vtoc->partition[7];
    141 	boot->tag = VTOC_TAG_BOOT;
    142 	boot->flags = VTOC_FLAG_UNMOUNT;
    143 	boot->start_sector = 0;
    144 	boot->nsectors = _BOOTBLOCK_SIZE;
    145 
    146 	bfs = &vtoc->partition[3];
    147 	bfs->tag = VTOC_TAG_STAND;
    148 	bfs->flags = 0;
    149 	bfs->start_sector = _BOOTBLOCK_SIZE;
    150 
    151 	res = nsectors - bfs->start_sector;
    152 	bfs->nsectors = res > _BFS_SIZE ? _BFS_SIZE : res;
    153 
    154 	bsdraw = &vtoc->partition[RAW_PART];
    155 	bsdraw->tag = VTOC_TAG_NONAME;
    156 	bsdraw->flags = VTOC_FLAG_UNMOUNT;
    157 	bsdraw->start_sector = -pdinfo->logical_sector;
    158 	bsdraw->nsectors = nsectors;
    159 }
    160 
    161 void
    162 disklabel_to_vtoc(struct cpu_disklabel *ux, struct disklabel *d)
    163 {
    164 	struct pdinfo_sector *pdinfo = &ux->pdinfo;
    165 	struct vtoc_sector *vtoc = &ux->vtoc;
    166 	struct ux_partition *up;
    167 	struct partition *p;
    168 	uint32_t offset = pdinfo->logical_sector;
    169 	int i;
    170 
    171 	pdinfo->geometory.cylinders_per_drive = d->d_ncylinders;
    172 	pdinfo->geometory.tracks_per_cylinder = d->d_ntracks;
    173 	pdinfo->geometory.sectors_per_track = d->d_nsectors;
    174 	pdinfo->geometory.bytes_per_sector = d->d_secsize;
    175 
    176 	vtoc->npartitions = d->d_npartitions;
    177 	vtoc->sector_size_byte = d->d_secsize;
    178 
    179 	up = vtoc->partition;
    180 	p = d->d_partitions;
    181 	for (i = 0; i < vtoc->npartitions; i++, up++, p++) {
    182 		if ((up->nsectors = p->p_size) != 0)
    183 			up->start_sector = p->p_offset - offset;
    184 		else
    185 			up->start_sector = 0;
    186 
    187 		switch (p->p_fstype) {
    188 		case FS_BOOT:
    189 			up->tag = VTOC_TAG_BOOT;
    190 			up->flags = VTOC_FLAG_UNMOUNT;
    191 			break;
    192 		case FS_SYSVBFS:
    193 			up->tag = VTOC_TAG_STAND;
    194 			break;
    195 		case FS_SWAP:
    196 			up->tag = VTOC_TAG_SWAP;
    197 			up->flags = VTOC_FLAG_UNMOUNT;
    198 			break;
    199 		case FS_BSDFFS:
    200 			up->tag = __VTOC_TAG_BSDFFS;
    201 			break;
    202 		case FS_UNUSED:
    203 			if (i != RAW_PART && p->p_size > 0) {
    204 				up->tag = VTOC_TAG_RAWDISK;
    205 				up->flags = VTOC_FLAG_UNMOUNT;
    206 			}
    207 			break;
    208 		default:
    209 			break;
    210 		}
    211 	}
    212 }
    213 
    214 void
    215 vtoc_to_disklabel(struct cpu_disklabel *ux, struct disklabel *d)
    216 {
    217 	struct pdinfo_sector *pdinfo = &ux->pdinfo;
    218 	struct vtoc_sector *vtoc = &ux->vtoc;
    219 	struct ux_partition *up;
    220 	struct partition *p;
    221 	uint32_t offset = pdinfo->logical_sector;
    222 	int i;
    223 
    224 	d->d_secsize = pdinfo->geometory.bytes_per_sector;
    225 	d->d_nsectors = pdinfo->geometory.sectors_per_track;
    226 	d->d_ntracks = pdinfo->geometory.tracks_per_cylinder;
    227 	d->d_ncylinders = pdinfo->geometory.cylinders_per_drive;
    228 	d->d_secpercyl = d->d_nsectors * d->d_ntracks;
    229 	d->d_secperunit = d->d_ncylinders * d->d_secpercyl;
    230 
    231 	d->d_npartitions = vtoc->npartitions;
    232 	d->d_secsize = vtoc->sector_size_byte;
    233 
    234 	up = vtoc->partition;
    235 	p = d->d_partitions;
    236 	for (i = 0; i < vtoc->npartitions; i++, up++, p++) {
    237 
    238 		if ((p->p_size = up->nsectors) != 0)
    239 			p->p_offset = up->start_sector + offset;
    240 		else
    241 			p->p_offset = 0;
    242 
    243 		switch (up->tag) {
    244 		case VTOC_TAG_BOOT:
    245 			p->p_fstype = FS_BOOT;
    246 			break;
    247 		case VTOC_TAG_STAND:
    248 			p->p_fstype = FS_SYSVBFS;
    249 			break;
    250 		case VTOC_TAG_RAWDISK:
    251 			p->p_fstype = FS_UNUSED;
    252 			break;
    253 		case VTOC_TAG_SWAP:
    254 			p->p_fstype = FS_SWAP;
    255 			break;
    256 		case VTOC_TAG_NONAME:
    257 		case VTOC_TAG_ROOT:
    258 		case VTOC_TAG_USR:
    259 		case VTOC_TAG_VAR:
    260 		case VTOC_TAG_HOME:
    261 			p->p_fstype = FS_SYSV;
    262 			break;
    263 		default:
    264 			if (up->nsectors != 0)
    265 				p->p_fstype = FS_SYSV;
    266 			else
    267 				p->p_fstype = FS_UNUSED;
    268 			break;
    269 		}
    270 	}
    271 
    272 	d->d_checksum = 0;
    273 	d->d_checksum = dkcksum(d);
    274 }
    275 
    276 bool
    277 disklabel_sanity(struct disklabel *d)
    278 {
    279 
    280 	if (d->d_magic != DISKMAGIC || d->d_magic2 != DISKMAGIC ||
    281 	    dkcksum(d) != 0)
    282 		return false;
    283 
    284 	return true;
    285 }
    286