/* -*- Mode: c; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-

    libparted - a library for manipulating disk partitions
    Copyright (C) 2000, 2001, 2005, 2007 Free Software Foundation, Inc.

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA

    Contributor:  Ben Collins <bcollins@debian.org>
*/

#include <config.h>

#include <parted/parted.h>
#include <parted/debug.h>
#include <parted/endian.h>

#if ENABLE_NLS
#  include <libintl.h>
#  define _(String) dgettext (PACKAGE, String)
#else
#  define _(String) (String)
#endif /* ENABLE_NLS */

/* Most of this came from util-linux's sun support, which was mostly done
   by Jakub Jelinek.  */

#define SUN_DISK_MAGIC		0xDABE	/* Disk magic number */
#define SUN_DISK_MAXPARTITIONS	8

#define WHOLE_DISK_ID		0x05
#define WHOLE_DISK_PART		2	/* as in 0, 1, 2 (3rd partition) */
#define LINUX_SWAP_ID		0x82

typedef struct _SunRawPartition     SunRawPartition;
typedef struct _SunPartitionInfo    SunPartitionInfo;
typedef struct _SunRawLabel         SunRawLabel;
typedef struct _SunPartitionData    SunPartitionData;
typedef struct _SunDiskData         SunDiskData;

struct __attribute__ ((packed)) _SunRawPartition {
	u_int32_t	start_cylinder; /* where the part starts... */
	u_int32_t	num_sectors;	/* ...and it's length */
};

struct __attribute__ ((packed)) _SunPartitionInfo {
	u_int8_t	spare1;
	u_int8_t	id;		/* Partition type */
	u_int8_t	spare2;
	u_int8_t	flags;		/* Partition flags */
};

struct __attribute__ ((packed)) _SunRawLabel {
	char 		info[128];	/* Informative text string */
	u_int8_t	spare0[14];
	SunPartitionInfo infos[SUN_DISK_MAXPARTITIONS];
	u_int8_t	spare1[246];	/* Boot information etc. */
	u_int16_t	rspeed;		/* Disk rotational speed */
	u_int16_t	pcylcount;	/* Physical cylinder count */
	u_int16_t	sparecyl;	/* extra sects per cylinder */
	u_int8_t	spare2[4];	/* More magic... */
	u_int16_t	ilfact;		/* Interleave factor */
	u_int16_t	ncyl;		/* Data cylinder count */
	u_int16_t	nacyl;		/* Alt. cylinder count */
	u_int16_t	ntrks;		/* Tracks per cylinder */
	u_int16_t	nsect;		/* Sectors per track */
	u_int8_t	spare3[4];	/* Even more magic... */
	SunRawPartition partitions[SUN_DISK_MAXPARTITIONS];
	u_int16_t	magic;		/* Magic number */
	u_int16_t	csum;		/* Label xor'd checksum */
};

struct _SunPartitionData {
	u_int8_t		type;
	int			is_boot;
	int			is_root;
	int			is_lvm;
};

struct _SunDiskData {
	PedSector		length; /* This is based on cyl - alt-cyl */
	SunRawLabel		raw_label;
};

static PedDiskType sun_disk_type;

/* Checksum computation */
static void
sun_compute_checksum (SunRawLabel *label)
{
	u_int16_t *ush = (u_int16_t *)label;
	u_int16_t csum = 0;

        while(ush < (u_int16_t *)(&label->csum))
                csum ^= *ush++;
        label->csum = csum;
}

/* Checksum Verification */
static int
sun_verify_checksum (SunRawLabel *label)
{
	u_int16_t *ush = ((u_int16_t *)(label + 1)) - 1;
	u_int16_t csum = 0;

	while (ush >= (u_int16_t *)label)
		csum ^= *ush--;

	return !csum;
}

static int
sun_probe (const PedDevice *dev)
{
	SunRawLabel	label;

	PED_ASSERT (dev != NULL, return 0);

        if (dev->sector_size != 512)
                return 0;

	if (!ped_device_read (dev, &label, 0, 1))
		return 0;

	/* check magic */
	if (PED_BE16_TO_CPU (label.magic) != SUN_DISK_MAGIC)
		return 0;

#ifndef DISCOVER_ONLY
	if (!sun_verify_checksum(&label)) {
		ped_exception_throw (
			PED_EXCEPTION_ERROR,
			PED_EXCEPTION_CANCEL,
			_("Corrupted Sun disk label detected."));
		return 0;
	}
#endif

	return 1;
}

#ifndef DISCOVER_ONLY
static int
sun_clobber (PedDevice* dev)
{
	SunRawLabel label;

	PED_ASSERT (dev != NULL, return 0);
	PED_ASSERT (sun_probe (dev), return 0);

	if (!ped_device_read (dev, &label, 0, 1))
		return 0;
	
	label.magic = 0;
	return ped_device_write (dev, &label, 0, 1);
}
#endif /* !DISCOVER_ONLY */

static PedDisk*
sun_alloc (const PedDevice* dev)
{
	PedDisk*	disk;
	SunRawLabel*	label;
	SunDiskData*	sun_specific;
	PedCHSGeometry*	bios_geom = &((PedDevice*)dev)->bios_geom;
	PedSector	cyl_size = bios_geom->sectors * bios_geom->heads;

        disk = _ped_disk_alloc (dev, &sun_disk_type);
	if (!disk)
		goto error;

	disk->disk_specific = (SunDiskData*) ped_malloc (sizeof (SunDiskData));
	if (!disk->disk_specific)
		goto error_free_disk;
	sun_specific = (SunDiskData*) disk->disk_specific;

	bios_geom->cylinders = dev->length / cyl_size;
	sun_specific->length = bios_geom->cylinders * cyl_size;

	label = &sun_specific->raw_label;
	memset(label, 0, sizeof(SunRawLabel));

	/* #gentoo-sparc people agree that nacyl = 0 is the best option */
	label->magic	= PED_CPU_TO_BE16 (SUN_DISK_MAGIC);
	label->nacyl	= 0;
	label->pcylcount	= PED_CPU_TO_BE16 (bios_geom->cylinders);
	label->rspeed	= PED_CPU_TO_BE16 (5400);
	label->ilfact	= PED_CPU_TO_BE16 (1);
	label->sparecyl	= 0;
	label->ntrks	= PED_CPU_TO_BE16 (bios_geom->heads);
	label->nsect	= PED_CPU_TO_BE16 (bios_geom->sectors);
	label->ncyl	= PED_CPU_TO_BE16 (bios_geom->cylinders - 0);

	/* Add a whole disk partition at a minimum */
	label->infos[WHOLE_DISK_PART].id = WHOLE_DISK_ID;
	label->partitions[WHOLE_DISK_PART].start_cylinder = 0;
	label->partitions[WHOLE_DISK_PART].num_sectors =
		PED_CPU_TO_BE32(bios_geom->cylinders * cyl_size);

	/* Now a neato string to describe this label */
	snprintf(label->info, sizeof(label->info) - 1,
		 "GNU Parted Custom cyl %d alt %d hd %d sec %d",
		 PED_BE16_TO_CPU(label->ncyl),
		 PED_BE16_TO_CPU(label->nacyl),
		 PED_BE16_TO_CPU(label->ntrks),
		 PED_BE16_TO_CPU(label->nsect));

	sun_compute_checksum(label);
	return disk;

error_free_disk:
	_ped_disk_free (disk);
error:
	return NULL;
}

static PedDisk*
sun_duplicate (const PedDisk* disk)
{
	PedDisk*	new_disk;
	SunDiskData*	new_sun_data;
	SunDiskData*	old_sun_data = (SunDiskData*) disk->disk_specific;
       
	new_disk = ped_disk_new_fresh (disk->dev, &sun_disk_type);
	if (!new_disk)
		return NULL;

	new_sun_data = (SunDiskData*) new_disk->disk_specific;
	memcpy (new_sun_data, old_sun_data, sizeof (SunDiskData));
	return new_disk;
}

static void
sun_free (PedDisk *disk)
{
	ped_free (disk->disk_specific);
	_ped_disk_free (disk);
}

static int
_check_geometry_sanity (PedDisk* disk, SunRawLabel* label)
{
	PedDevice*	dev = disk->dev;

	if (PED_BE16_TO_CPU(label->nsect) == dev->hw_geom.sectors &&
	    PED_BE16_TO_CPU(label->ntrks) == dev->hw_geom.heads)
		dev->bios_geom = dev->hw_geom;

	if (PED_BE16_TO_CPU(label->nsect) != dev->bios_geom.sectors ||
	    PED_BE16_TO_CPU(label->ntrks) != dev->bios_geom.heads) {
#ifndef DISCOVER_ONLY
		if (ped_exception_throw (
				PED_EXCEPTION_WARNING,
				PED_EXCEPTION_IGNORE_CANCEL,
				_("The disk CHS geometry (%d,%d,%d) reported "
				  "by the operating system does not match "
				  "the geometry stored on the disk label "
				  "(%d,%d,%d)."),
				dev->bios_geom.cylinders,
			       	dev->bios_geom.heads,
			       	dev->bios_geom.sectors,
				PED_BE16_TO_CPU(label->pcylcount),
				PED_BE16_TO_CPU(label->ntrks),
				PED_BE16_TO_CPU(label->nsect))
			== PED_EXCEPTION_CANCEL)
			return 0;
#endif
		dev->bios_geom.sectors = PED_BE16_TO_CPU(label->nsect);
		dev->bios_geom.heads = PED_BE16_TO_CPU(label->ntrks);
		dev->bios_geom.cylinders = PED_BE16_TO_CPU(label->pcylcount);

		if (dev->bios_geom.sectors * dev->bios_geom.heads
			      	* dev->bios_geom.cylinders > dev->length) {
			if (ped_exception_throw (
				PED_EXCEPTION_WARNING,
				PED_EXCEPTION_IGNORE_CANCEL,
				_("The disk label describes a disk bigger than "
				  "%s."),
				dev->path)
				!= PED_EXCEPTION_IGNORE)
				return 0;
		}
	}
	return 1;
}

static int
sun_read (PedDisk* disk)
{
	SunRawLabel* label;
	SunPartitionData* sun_data;
	SunDiskData* disk_data;
	int i;
	PedPartition* part;
	PedSector end, start, block;
	PedConstraint* constraint_exact;
	
	PED_ASSERT (disk != NULL, return 0);
	PED_ASSERT (disk->dev != NULL, return 0);
	PED_ASSERT (disk->disk_specific != NULL, return 0);
	
	disk_data = (SunDiskData*) disk->disk_specific;
	label = &disk_data->raw_label;

	ped_disk_delete_all (disk);

	if (!ped_device_read (disk->dev, label, 0, 1))
		goto error;
	if (!_check_geometry_sanity (disk, label))
		goto error;

	block = disk->dev->bios_geom.sectors * disk->dev->bios_geom.heads;
	disk_data->length = block * disk->dev->bios_geom.cylinders;

	for (i = 0; i < SUN_DISK_MAXPARTITIONS; i++) {
		if (!PED_BE32_TO_CPU(label->partitions[i].num_sectors))
			continue;
		if (!label->infos[i].id)
			continue;
		if (label->infos[i].id == WHOLE_DISK_ID)
	       		continue;

		start = PED_BE32_TO_CPU(label->partitions[i].start_cylinder)
				    * block;
		end = start
		      + PED_BE32_TO_CPU(label->partitions[i].num_sectors) - 1;

		part = ped_partition_new (disk, 0, NULL, start, end);
		if (!part)
			goto error;

		sun_data = part->disk_specific;
		sun_data->type = label->infos[i].id;
		sun_data->is_boot = sun_data->type == 0x1;
		sun_data->is_root = sun_data->type == 0x2;
		sun_data->is_lvm = sun_data->type == 0x8e;

		part->num = i + 1;
		part->fs_type = ped_file_system_probe (&part->geom);
	
		constraint_exact = ped_constraint_exact (&part->geom);
		if (!ped_disk_add_partition (disk, part, constraint_exact))
			goto error;
		ped_constraint_destroy (constraint_exact);
	}

	return 1;

 error:
	return 0;
}

#ifndef DISCOVER_ONLY
static void
_probe_and_use_old_info (const PedDisk* disk)
{
	SunDiskData*		sun_specific;
	SunRawLabel		old_label;

	sun_specific = (SunDiskData*) disk->disk_specific;

	if (!ped_device_read (disk->dev, &old_label, 0, 1))
		return;
	if (old_label.info [0]
	    && PED_BE16_TO_CPU (old_label.magic) == SUN_DISK_MAGIC)
		memcpy (&sun_specific->raw_label, &old_label, 512);
}

static int
sun_write (const PedDisk* disk)
{
	SunRawLabel*		label;
	SunPartitionData*	sun_data;
	SunDiskData*		disk_data;
	PedPartition*		part;
	int			i;

	PED_ASSERT (disk != NULL, return 0);
	PED_ASSERT (disk->dev != NULL, return 0);

	_probe_and_use_old_info (disk);

	disk_data = (SunDiskData*) disk->disk_specific;
	label = &disk_data->raw_label;

	memset (label->partitions, 0,
		sizeof (SunRawPartition) * SUN_DISK_MAXPARTITIONS);
	memset (label->infos, 0,
		sizeof (SunPartitionInfo) * SUN_DISK_MAXPARTITIONS);

	for (i = 0; i < SUN_DISK_MAXPARTITIONS; i++) {
		part = ped_disk_get_partition (disk, i + 1);

		if (!part && i == WHOLE_DISK_PART) {
			/* Ok, nothing explicitly in the whole disk
			   partition, so let's put it there for safety
			   sake.  */

			label->infos[i].id = WHOLE_DISK_ID;
			label->partitions[i].start_cylinder = 0;
			label->partitions[i].num_sectors = 
				PED_CPU_TO_BE32(disk_data->length);
			continue;
		}
		if (!part)
			continue;

		sun_data = part->disk_specific;
		label->infos[i].id = sun_data->type;
		label->partitions[i].start_cylinder
			= PED_CPU_TO_BE32 (part->geom.start
				/ (disk->dev->bios_geom.sectors
				       	* disk->dev->bios_geom.heads));
		label->partitions[i].num_sectors
			= PED_CPU_TO_BE32 (part->geom.end
					   - part->geom.start + 1);
	}

	/* We assume the harddrive is always right, and that the label may
	   be wrong. I don't think this will cause any problems, since the
	   cylinder count is always enforced by our alignment, and we
	   sanity checked the sectors/heads when we detected the device. The
	   worst that could happen here is that the drive seems bigger or
	   smaller than it really is, but we'll have that problem even if we
	   don't do this.  */

	if (disk->dev->bios_geom.cylinders > 65536) {
		ped_exception_throw (
			PED_EXCEPTION_WARNING,
			PED_EXCEPTION_IGNORE,
			_("The disk has %d cylinders, which is greater than "
			  "the maximum of 65536."),
			disk->dev->bios_geom.cylinders);
	}

	label->pcylcount = PED_CPU_TO_BE16 (disk->dev->bios_geom.cylinders);
	label->ncyl = PED_CPU_TO_BE16 (disk->dev->bios_geom.cylinders
			- PED_BE16_TO_CPU (label->nacyl));

	sun_compute_checksum (label);

	if (!ped_device_write (disk->dev, label, 0, 1))
		goto error;
	return ped_device_sync (disk->dev);

error:
	return 0;
}
#endif /* !DISCOVER_ONLY */

static PedPartition*
sun_partition_new (const PedDisk* disk, PedPartitionType part_type,
		   const PedFileSystemType* fs_type,
		   PedSector start, PedSector end)
{
	PedPartition*		part;
	SunPartitionData*	sun_data;

	part = _ped_partition_alloc (disk, part_type, fs_type, start, end);
	if (!part)
		goto error;

	if (ped_partition_is_active (part)) {
		part->disk_specific
		       	= sun_data = ped_malloc (sizeof (SunPartitionData));
		if (!sun_data)
			goto error_free_part;
		sun_data->type = 0;
		sun_data->is_boot = 0;
		sun_data->is_root = 0;
		sun_data->is_lvm = 0;
	} else {
		part->disk_specific = NULL;
	}

	return part;

	ped_free (sun_data);
error_free_part:
	ped_free (part);
error:
	return NULL;
}

static PedPartition*
sun_partition_duplicate (const PedPartition* part)
{
	PedPartition*		new_part;
	SunPartitionData*	new_sun_data;
	SunPartitionData*	old_sun_data;

	new_part = ped_partition_new (part->disk, part->type,
				      part->fs_type, part->geom.start,
				      part->geom.end);
	if (!new_part)
		return NULL;
	new_part->num = part->num;

	old_sun_data = (SunPartitionData*) part->disk_specific;
	new_sun_data = (SunPartitionData*) new_part->disk_specific;
	new_sun_data->type = old_sun_data->type;
	new_sun_data->is_boot = old_sun_data->is_boot;
	new_sun_data->is_root = old_sun_data->is_root;
	new_sun_data->is_lvm = old_sun_data->is_lvm;
	return new_part;
}

static void
sun_partition_destroy (PedPartition* part)
{
	PED_ASSERT (part != NULL, return);

	if (ped_partition_is_active (part))
		ped_free (part->disk_specific);
	ped_free (part);
}

static int
sun_partition_set_system (PedPartition* part, const PedFileSystemType* fs_type)
{
	SunPartitionData*		sun_data = part->disk_specific;

	part->fs_type = fs_type;

	if (sun_data->is_boot) {
		sun_data->type = 0x1;
		return 1;
	}
	if (sun_data->is_root) {
		sun_data->type = 0x2;
		return 1;
	}
	if (sun_data->is_lvm) {
		sun_data->type = 0x8e;
		return 1;
	}

	sun_data->type = 0x83;
	if (fs_type) {
		if (!strcmp (fs_type->name, "linux-swap"))
			sun_data->type = 0x82;
		else if (!strcmp (fs_type->name, "ufs"))
			sun_data->type = 0x6;
	}

	return 1;
}

static int
sun_partition_set_flag (PedPartition* part, PedPartitionFlag flag, int state)
{
	SunPartitionData*		sun_data;

	PED_ASSERT (part != NULL, return 0);
	PED_ASSERT (part->disk_specific != NULL, return 0);
	PED_ASSERT (ped_partition_is_flag_available (part, flag), return 0);

	sun_data = part->disk_specific;

	switch (flag) {
		case PED_PARTITION_BOOT:
			sun_data->is_boot = state;
			if (state)
				sun_data->is_root = sun_data->is_lvm = 0;
			return ped_partition_set_system (part, part->fs_type);

		case PED_PARTITION_ROOT:
			sun_data->is_root = state;
			if (state)
				sun_data->is_boot = sun_data->is_lvm = 0;
			return ped_partition_set_system (part, part->fs_type);

		case PED_PARTITION_LVM:
			sun_data->is_lvm = state;
			if (state)
				sun_data->is_root = sun_data->is_boot = 0;
			return ped_partition_set_system (part, part->fs_type);

		default:
			return 0;
	}
}


static int
sun_partition_get_flag (const PedPartition* part, PedPartitionFlag flag)
{
	SunPartitionData*       sun_data;

	PED_ASSERT (part != NULL, return 0);
	PED_ASSERT (part->disk_specific != NULL, return 0);

	sun_data = part->disk_specific;

	switch (flag) {
		case PED_PARTITION_BOOT:
			return sun_data->is_boot;
		case PED_PARTITION_ROOT:
			return sun_data->is_root;
		case PED_PARTITION_LVM:
			return sun_data->is_lvm;

		default:
			return 0;
	}
}


static int
sun_partition_is_flag_available (const PedPartition* part,
				 PedPartitionFlag flag)
{
	switch (flag) {
		case PED_PARTITION_BOOT:
		case PED_PARTITION_ROOT:
		case PED_PARTITION_LVM:
			return 1;

		default:
			return 0;
	}
}


static int
sun_get_max_primary_partition_count (const PedDisk* disk)
{
	return SUN_DISK_MAXPARTITIONS;
}

static PedConstraint*
_get_strict_constraint (PedDisk* disk)
{
	PedDevice*	dev = disk->dev;
        PedAlignment    start_align;
        PedAlignment    end_align;
        PedGeometry     max_geom;
	SunDiskData*	disk_data = disk->disk_specific;
	PedSector	block = dev->bios_geom.sectors * dev->bios_geom.heads;

        if (!ped_alignment_init (&start_align, 0, block))
                return NULL;
        if (!ped_alignment_init (&end_align, -1, block))
                return NULL;
	if (!ped_geometry_init (&max_geom, dev, 0, disk_data->length))
		return NULL;

        return ped_constraint_new (&start_align, &end_align, &max_geom,
                                   &max_geom, 1, dev->length);
}

static PedConstraint*
_get_lax_constraint (PedDisk* disk)
{
	PedDevice*	dev = disk->dev;
        PedAlignment    start_align;
        PedGeometry     max_geom;
	SunDiskData*	disk_data = disk->disk_specific;
	PedSector	block = dev->bios_geom.sectors * dev->bios_geom.heads;

        if (!ped_alignment_init (&start_align, 0, block))
                return NULL;
	if (!ped_geometry_init (&max_geom, dev, 0, disk_data->length))
		return NULL;

        return ped_constraint_new (&start_align, ped_alignment_any, &max_geom,
                                   &max_geom, 1, dev->length);
}

/* _get_strict_constraint() will align the partition to the end of the cylinder.
 * This isn't required, but since partitions must start at the start of the
 * cylinder, space between the end of a partition and the end of a cylinder
 * is unusable, so there's no point wasting space!
 *	However, if they really insist (via constraint)... which they will
 * if they're reading a weird table of the disk... then we allow the end to
 * be anywhere, with _get_lax_constraint()
 */
static int
sun_partition_align (PedPartition* part, const PedConstraint* constraint)
{
        PED_ASSERT (part != NULL, return 0);

	if (_ped_partition_attempt_align (part, constraint,
					  _get_strict_constraint (part->disk)))
	       	return 1;
	if (_ped_partition_attempt_align (part, constraint,
					  _get_lax_constraint (part->disk)))
	       	return 1;

#ifndef DISCOVER_ONLY
	ped_exception_throw (
		PED_EXCEPTION_ERROR,
		PED_EXCEPTION_CANCEL,
		_("Unable to satisfy all constraints on the partition."));
#endif
	return 0;
}

static int
sun_partition_enumerate (PedPartition* part)
{
	int i;
	PedPartition* p;
	
	/* never change the partition numbers */
	if (part->num != -1)
		return 1;
	for (i = 1; i <= SUN_DISK_MAXPARTITIONS; i++) {
		/* skip the Whole Disk partition for now */
		if (i == WHOLE_DISK_PART + 1)
			continue;
		p = ped_disk_get_partition (part->disk, i);
		if (!p) {
			part->num = i;
			return 1;
		}
	}

#ifndef DISCOVER_ONLY
	/* Ok, now allocate the Whole disk if it isn't already */
	p = ped_disk_get_partition (part->disk, WHOLE_DISK_PART + 1);
	if (!p) {
		int j = ped_exception_throw (
				PED_EXCEPTION_WARNING,
				PED_EXCEPTION_IGNORE_CANCEL,
				_("The Whole Disk partition is the only "
				  "available one left.  Generally, it is not a "
				  "good idea to overwrite this partition with "
				  "a real one.  Solaris may not be able to "
				  "boot without it, and SILO (the sparc boot "
				  "loader) appreciates it as well."));
		if (j == PED_EXCEPTION_IGNORE) {
			/* bad bad bad...you will suffer your own fate */
			part->num = WHOLE_DISK_PART + 1;
			return 1;
		}
	}

	/* failed to allocate a number, this means we are full */
	ped_exception_throw (PED_EXCEPTION_ERROR, PED_EXCEPTION_CANCEL,
			     _("Sun disk label is full."));
#endif
	return 0;
}

static int
sun_alloc_metadata (PedDisk* disk)
{
	PedPartition*	new_part;
	SunDiskData*	disk_data;
	PedConstraint*	constraint_any;

	PED_ASSERT (disk != NULL, return 0);
	PED_ASSERT (disk->disk_specific != NULL, return 0);
	PED_ASSERT (disk->dev != NULL, return 0);

	constraint_any = ped_constraint_any (disk->dev);

	/* Sun disk label does not need to allocate a sector. The disk
	   label is contained within the first 512 bytes, which should not
	   be overwritten by any boot loader or superblock. It is safe for
	   most partitions to start at sector 0. We do however, allocate
	   the space used by alt-cyl's, since we cannot use those. Put them
	   at the end of the disk.  */

	disk_data = disk->disk_specific;

	if (disk->dev->length <= 0 ||
	    disk_data->length <= 0 ||
	    disk->dev->length == disk_data->length)
		goto error;

	new_part = ped_partition_new (disk, PED_PARTITION_METADATA, NULL,
			disk_data->length, disk->dev->length - 1);
	if (!new_part)
		goto error;

	if (!ped_disk_add_partition (disk, new_part, constraint_any)) {
		ped_partition_destroy (new_part);
		goto error;
	}

	ped_constraint_destroy (constraint_any);
	return 1;
error:
	ped_constraint_destroy (constraint_any);
	return 0;
}

static PedDiskOps sun_disk_ops = {
	probe:			sun_probe,
#ifndef DISCOVER_ONLY
	clobber:		sun_clobber,
#else
	clobber:		NULL,
#endif
	alloc:			sun_alloc,
	duplicate:		sun_duplicate,
	free:			sun_free,
	read:			sun_read,
#ifndef DISCOVER_ONLY
	write:			sun_write,
#else
	write:			NULL,
#endif

	partition_new:		sun_partition_new,
	partition_duplicate:	sun_partition_duplicate,
	partition_destroy:	sun_partition_destroy,
	partition_set_system:	sun_partition_set_system,
	partition_set_flag:	sun_partition_set_flag,
	partition_get_flag:	sun_partition_get_flag,
	partition_is_flag_available:	sun_partition_is_flag_available,
	partition_align:	sun_partition_align,
	partition_enumerate:	sun_partition_enumerate,
	alloc_metadata:		sun_alloc_metadata,
	get_max_primary_partition_count:
				sun_get_max_primary_partition_count,

	partition_set_name:		NULL,
	partition_get_name:		NULL,
};

static PedDiskType sun_disk_type = {
	next:		NULL,
	name:		"sun",
	ops:		&sun_disk_ops,
	features:	0
};

void
ped_disk_sun_init ()
{
	PED_ASSERT (sizeof (SunRawLabel) == 512, return);
	ped_disk_type_register (&sun_disk_type);
}

void
ped_disk_sun_done ()
{
	ped_disk_type_unregister (&sun_disk_type);
}
