/*
 * sun (solaris-sparc) 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 <stddef.h>

#include "pt-sun.h"
#include "partitions.h"

static int probe_sun_pt(blkid_probe pr,
		const struct blkid_idmag *mag __attribute__((__unused__)))
{
	struct sun_disklabel *l;
	struct sun_partition *p;
	blkid_parttable tab = NULL;
	blkid_partlist ls;
	uint16_t nparts;
	blkid_loff_t spc;
	int i, use_vtoc;

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

	if (sun_pt_checksum(l)) {
		DBG(LOWPROBE, ul_debug(
			"detected corrupted sun disk label -- ignore"));
		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;

	tab = blkid_partlist_new_parttable(ls, "sun", 0);
	if (!tab)
		goto err;

	/* sectors per cylinder (partition offset is in cylinders...) */
	spc = be16_to_cpu(l->nhead) * be16_to_cpu(l->nsect);

	DBG(LOWPROBE, ul_debug("Sun VTOC sanity=%u version=%u nparts=%u",
			be32_to_cpu(l->vtoc.sanity),
			be32_to_cpu(l->vtoc.version),
			be16_to_cpu(l->vtoc.nparts)));

	/* Check to see if we can use the VTOC table */
	use_vtoc = ((be32_to_cpu(l->vtoc.sanity) == SUN_VTOC_SANITY) &&
		    (be32_to_cpu(l->vtoc.version) == SUN_VTOC_VERSION) &&
		    (be16_to_cpu(l->vtoc.nparts) <= SUN_MAXPARTITIONS));

	/* Use 8 partition entries if not specified in validated VTOC */
	nparts = use_vtoc ? be16_to_cpu(l->vtoc.nparts) : SUN_MAXPARTITIONS;

	/*
	 * So that old Linux-Sun partitions continue to work,
	 * alow the VTOC to be used under the additional condition ...
	 */
	use_vtoc = use_vtoc || !(l->vtoc.sanity || l->vtoc.version || l->vtoc.nparts);

	for (i = 0, p = l->partitions; i < nparts; i++, p++) {

		blkid_loff_t start, size;
		uint16_t type = 0, flags = 0;
		blkid_partition par;

		start = be32_to_cpu(p->start_cylinder) * spc;
		size = be32_to_cpu(p->num_sectors);
		if (use_vtoc) {
			type = be16_to_cpu(l->vtoc.infos[i].id);
			flags = be16_to_cpu(l->vtoc.infos[i].flags);
		}

		if (type == SUN_TAG_WHOLEDISK || !size) {
			blkid_partlist_increment_partno(ls);
			continue;
		}
		par = blkid_partlist_add_partition(ls, tab, start, size);
		if (!par)
			goto err;

		if (type)
			blkid_partition_set_type(par, type);
		if (flags)
			blkid_partition_set_flags(par, flags);
	}
	return BLKID_PROBE_OK;

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


const struct blkid_idinfo sun_pt_idinfo =
{
	.name		= "sun",
	.probefunc	= probe_sun_pt,
	.magics		=
	{
		{
		  .magic = "\xDA\xBE",		/* big-endian magic string */
		  .len = 2,
		  .sboff = offsetof(struct sun_disklabel, magic)
		},
		{ NULL }
	}
};

