/*
 * Solaris x86 partition parsing code
 *
 * Copyright (C) 2009 Karel Zak <kzak@redhat.com>
 *
 * This file may be redistributed under the terms of the
 * GNU Lesser General Public License.
 */
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdint.h>

#include "partitions.h"

/*
 * Solaris-x86 is always within primary dos partition (nested PT table).  The
 * solaris-x86 vtoc allows to split the entire partition to "slices". The
 * offset (start) of the slice is always relatively to the primary dos
 * partition.
 *
 * Note that Solaris-SPARC uses entire disk with a different partitioning
 * scheme.
 */

/* some other implementation than Linux kernel assume 8 partitions only */
#define SOLARIS_MAXPARTITIONS	16

/* disklabel (vtoc) location  */
#define SOLARIS_SECTOR		1			/* in 512-sectors */
#define SOLARIS_OFFSET		(SOLARIS_SECTOR << 9)	/* in bytes */
#define SOLARIS_MAGICOFFSET	(SOLARIS_OFFSET + 12)	/* v_sanity offset in bytes */

/* slice tags */
#define SOLARIS_TAG_WHOLEDISK	5

struct solaris_slice {
	uint16_t s_tag;      /* ID tag of partition */
	uint16_t s_flag;     /* permission flags */
	uint32_t s_start;    /* start sector no of partition */
	uint32_t s_size;     /* # of blocks in partition */
} __attribute__((packed));

struct solaris_vtoc {
	unsigned int v_bootinfo[3];     /* info needed by mboot (unsupported) */

	uint32_t     v_sanity;          /* to verify vtoc sanity */
	uint32_t     v_version;         /* layout version */
	char         v_volume[8];       /* volume name */
	uint16_t     v_sectorsz;        /* sector size in bytes */
	uint16_t     v_nparts;          /* number of partitions */
	unsigned int v_reserved[10];    /* free space */

	struct solaris_slice v_slice[SOLARIS_MAXPARTITIONS]; /* slices */

	unsigned int timestamp[SOLARIS_MAXPARTITIONS]; /* timestamp (unsupported) */
	char         v_asciilabel[128];	/* for compatibility */
} __attribute__((packed));

static int probe_solaris_pt(blkid_probe pr,
		const struct blkid_idmag *mag __attribute__((__unused__)))
{
	struct solaris_vtoc *l;	/* disk label */
	struct solaris_slice *p;	/* partition */
	blkid_parttable tab = NULL;
	blkid_partition parent;
	blkid_partlist ls;
	int i;
	uint16_t nparts;

	l = (struct solaris_vtoc *) blkid_probe_get_sector(pr, SOLARIS_SECTOR);
	if (!l) {
		if (errno)
			return -errno;
		goto nothing;
	}

	if (le32_to_cpu(l->v_version) != 1) {
		DBG(LOWPROBE, ul_debug(
			"WARNING: unsupported solaris x86 version %d, ignore",
			le32_to_cpu(l->v_version)));
		goto nothing;
	}

	if (blkid_partitions_need_typeonly(pr))
		/* caller does not ask for details about partitions */
		return BLKID_PROBE_OK;

	ls = blkid_probe_get_partlist(pr);
	if (!ls)
		goto nothing;

	parent = blkid_partlist_get_parent(ls);

	tab = blkid_partlist_new_parttable(ls, "solaris", SOLARIS_OFFSET);
	if (!tab)
		goto err;

	nparts = le16_to_cpu(l->v_nparts);
	if (nparts > SOLARIS_MAXPARTITIONS)
		nparts = SOLARIS_MAXPARTITIONS;

	for (i = 1, p = &l->v_slice[0];	i < nparts; i++, p++) {

		uint32_t start = le32_to_cpu(p->s_start);
		uint32_t size = le32_to_cpu(p->s_size);
		blkid_partition par;

		if (size == 0 || le16_to_cpu(p->s_tag) == SOLARIS_TAG_WHOLEDISK)
			continue;

		if (parent)
			/* Solaris slices are relative to the parent (primary
			 * DOS partition) */
			start += blkid_partition_get_start(parent);

		if (parent && !blkid_is_nested_dimension(parent, start, size)) {
			DBG(LOWPROBE, ul_debug(
				"WARNING: solaris partition (%d) overflow "
				"detected, ignore", i));
			continue;
		}

		par = blkid_partlist_add_partition(ls, tab, start, size);
		if (!par)
			goto err;

		blkid_partition_set_type(par, le16_to_cpu(p->s_tag));
		blkid_partition_set_flags(par, le16_to_cpu(p->s_flag));
	}

	return BLKID_PROBE_OK;

nothing:
	return BLKID_PROBE_NONE;
err:
	return -ENOMEM;
}

const struct blkid_idinfo solaris_x86_pt_idinfo =
{
	.name		= "solaris",
	.probefunc	= probe_solaris_pt,
	.magics		=
	{
		{
		  .magic = "\xEE\xDE\x0D\x60",	/* little-endian magic string */
		  .len = 4,			/* v_sanity size in bytes */
		  .sboff = SOLARIS_MAGICOFFSET	/* offset of v_sanity */
		},
		{ NULL }
	}
};

