/*
 * File...........: arch/s390/tools/fdasd.c
 * Author(s)......: Volker Sameske <sameske@de.ibm.com>
 * Bugreports.to..: <Linux390@de.ibm.com>
 * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 2001
 *
 * History of changes (starts March 2001)
 * 2001-04-11 possibility to change volume serial added
 *            possibility to change partition type added
 *            some changes to DS4HPCHR and DS4DSREC
 * 2001-05-03 check for invalid partition numbers added
 *            wrong free_space calculation bug fixed
 * 2001-06-26 '-a' option added, it is now possible to add a single
 *            partition in non-interactive mode
 * 2001-06-26 long parameter support added
 *           
 */

#include <config.h>
#include <parted/vtoc.h>
#include <parted/fdasd.h>

#include <parted/parted.h>

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

static int
getpos (fdasd_anchor_t *anc, int dsn)
{
	PDEBUG
	return anc->partno[dsn];
}

static int
getdsn (fdasd_anchor_t *anc, int pos)
{
	PDEBUG
	int i;

	for (i=0; i<USABLE_PARTITIONS; i++) {
		if (anc->partno[i] == pos)
			return i;
	}

	return -1;
}

static void
setpos (fdasd_anchor_t *anc, int dsn, int pos)
{
	PDEBUG
	anc->partno[dsn] = pos;
}

void
fdasd_cleanup (fdasd_anchor_t *anchor) 
{
	PDEBUG
	int i;
	partition_info_t *p, *q;

	if (anchor == NULL)
		return;

	if (anchor->f4 != NULL)
		free(anchor->f4);

	if (anchor->f5 != NULL)
		free(anchor->f5);

	if (anchor->f7 != NULL)
		free(anchor->f7);

	if (anchor->vlabel != NULL)
		free(anchor->vlabel);

	p = anchor->first;
	if (p == NULL)
		return;

	for (i=1; i <= USABLE_PARTITIONS; i++) {
		if (p == NULL)
			return;
		q = p->next;
		free(p);
		p = q;
	}
}

static void 
fdasd_error (fdasd_anchor_t *anc, enum fdasd_failure why, char * str) 
{
	PDEBUG
	char error[2*LINE_LENGTH], *message = error;

	switch (why) {
		case unable_to_open_disk:
			sprintf(error, _("%s open error\n%s\n"), 
			FDASD_ERROR, str);
			break;
		case unable_to_seek_disk:
			sprintf(error, _("%s seek error\n%s\n"), FDASD_ERROR, str);
			break;
		case unable_to_read_disk:
			sprintf(error, _("%s read error\n%s\n"), FDASD_ERROR, str);
			break;
		case read_only_disk:
			sprintf(error, _("%s write error\n%s\n"), FDASD_ERROR, str);
			break;
		case unable_to_ioctl:
			sprintf(error, _("%s IOCTL error\n%s\n"), FDASD_ERROR, str);
			break;
		case api_version_mismatch:
			sprintf(error, _("%s API version mismatch\n%s\n"), FDASD_ERROR,str);
			break;     
		case wrong_disk_type:
			sprintf(error, _("%s Unsupported disk type\n%s\n"),
			        FDASD_ERROR, str);
			break; 
		case wrong_disk_format:
			sprintf(error, _("%s Unsupported disk format\n%s\n"),
			        FDASD_ERROR, str);
			break;   
		case disk_in_use:
			sprintf(error, _("%s Disk in use\n%s\n"), FDASD_ERROR, str);
			break;      
		case config_syntax_error:
			sprintf(error, _("%s Config file syntax error\n%s\n"),
			        FDASD_ERROR, str);
			break;       
		case vlabel_corrupted:
			sprintf(error, _("%s Volume label is corrupted.\n%s\n"), 
			        FDASD_ERROR, str);
			break;
		case dsname_corrupted:
			sprintf(error, _("%s a data set name is corrupted.\n%s\n"), 
			        FDASD_ERROR, str);
			break;
		case malloc_failed:
			sprintf(error, _("%s space allocation\n%s\n"),
			        FDASD_ERROR, str);
			break;
		case device_verification_failed:
			sprintf(error, _("%s device verification failed\n" \
			        "The specified device is not a valid DASD device\n"),
			        FDASD_ERROR);
			break;
		default: 
			sprintf(error, _("%s Fatal error\n%s\n"), FDASD_ERROR, str);
	}

	ped_exception_throw(PED_EXCEPTION_ERROR, PED_EXCEPTION_CANCEL, message);
}

/*
 * converts cyl-cyl-head-head-blk to blk
 */
static unsigned long 
cchhb2blk (cchhb_t *p, struct fdasd_hd_geometry *geo) 
{
	PDEBUG
	return (unsigned long) (p->cc * geo->heads * geo->sectors
	                        + p->hh * geo->sectors + p->b);
}

/*
 * initializes the anchor structure and allocates some
 * memory for the labels
 */
void
fdasd_initialize_anchor (fdasd_anchor_t * anc) 
{
	PDEBUG
	int i;
	volume_label_t *v;
	partition_info_t *p = NULL;
	partition_info_t *q = NULL;

	anc->devno             = 0;
	anc->dev_type          = 0;
	anc->used_partitions   = 0;

	anc->silent            = 0;
	anc->verbose           = 0;
	anc->big_disk          = 0;
	anc->volid_specified   = 0;
	anc->config_specified  = 0;
	anc->auto_partition    = 0;
	anc->devname_specified = 0;
	anc->print_table       = 0;

	anc->option_reuse      = 0;
	anc->option_recreate   = 0;

	anc->vlabel_changed    = 0;
	anc->vtoc_changed      = 0;
	anc->blksize           = 0;
	anc->fspace_trk        = 0;
	anc->label_pos         = 0;

	for (i=0; i<USABLE_PARTITIONS; i++)
		setpos(anc, i, -1);

	bzero(anc->confdata, sizeof(config_data_t));

	anc->f4 = malloc(sizeof(format4_label_t));
	if (anc->f4 == NULL) 
		fdasd_error(anc, malloc_failed, 
			    "FMT4 DSCB memory allocation failed.");

	anc->f5 = malloc(sizeof(format5_label_t));
	if (anc->f5 == NULL) 
		fdasd_error(anc, malloc_failed,
			    "FMT5 DSCB memory allocation failed.");

	anc->f7 = malloc(sizeof(format7_label_t));
	if (anc->f7 == NULL) 
		fdasd_error(anc, malloc_failed,
			    "FMT7 DSCB memory allocation failed.");

	bzero(anc->f4, sizeof(format4_label_t));
	bzero(anc->f5, sizeof(format5_label_t));
	bzero(anc->f7, sizeof(format7_label_t));

	v = malloc(sizeof(volume_label_t));
	if (v == NULL) 
		fdasd_error(anc, malloc_failed,
			    "Volume label memory allocation failed.");
	bzero(v, sizeof(volume_label_t));
	anc->vlabel = v;

	for (i=1; i<=USABLE_PARTITIONS; i++) {
        p = malloc(sizeof(partition_info_t));
		if (p == NULL) 
			fdasd_error(anc, malloc_failed,
				   "Partition info memory allocation failed.");
		p->used       = 0x00;
		p->len_trk    = 0;
		p->start_trk  = 0;
		p->fspace_trk = 0;
		p->type       = 0;

		/* add p to double pointered list */
		if (i == 1) {
	        anc->first = p;
			p->prev = NULL;
		} else if (i == USABLE_PARTITIONS) {
	        anc->last = p;
	        p->next = NULL;
			p->prev = q;
			q->next = p;
		} else {
	        p->prev = q;
	        q->next = p;
		}

		p->f1 = malloc(sizeof(format1_label_t));
		if (p->f1 == NULL) 
			fdasd_error(anc, malloc_failed,
			    "FMT1 DSCB memory allocation failed.");
		bzero(p->f1, sizeof(format1_label_t));
		
		q = p;
	}
}

/*
 * writes all changes to dasd
 */
static void
fdasd_write_vtoc_labels (fdasd_anchor_t * anc, int fd)
{ 
	PDEBUG
	partition_info_t *p;
	unsigned long b;
	char dsno[6], s1[7], s2[45], *c1, *c2, *ch;
	int i = 0, k = 0;
    
	b = (cchhb2blk (&anc->vlabel->vtoc, &anc->geo) - 1) * anc->blksize;
	if (b <= 0)
		fdasd_error (anc, vlabel_corrupted, "");

	/* write FMT4 DSCB */
	vtoc_write_label (fd, b, NULL, anc->f4, NULL, NULL);

	/* write FMT5 DSCB */
	b += anc->blksize;
	vtoc_write_label (fd, b, NULL, NULL, anc->f5, NULL);

	/* write FMT7 DSCB */
	if (anc->big_disk) {
		b += anc->blksize;
		vtoc_write_label (fd, b, NULL, NULL, NULL, anc->f7);
	}

	/* loop over all FMT1 DSCBs */
	p = anc->first;
	for (i = 0; i < USABLE_PARTITIONS; i++) {
		b += anc->blksize;

		if (p->used != 0x01) {
			vtoc_write_label (fd, b, p->f1, NULL, NULL, NULL);
			continue;
		}
  
		strncpy (p->f1->DS1DSSN, anc->vlabel->volid, 6);

		ch = p->f1->DS1DSNAM;
		vtoc_ebcdic_dec (ch, ch, 44);
		c1 = ch + 7;
  
		if (getdsn (anc, i) > -1) {
			/* re-use the existing data set name */
			c2 = strchr (c1, '.');
			if (c2 != NULL)
				strncpy (s2, c2, 31);
			else
				fdasd_error (anc, dsname_corrupted, "");

			strncpy (s1, anc->vlabel->volid, 6);
			vtoc_ebcdic_dec (s1, s1, 6);
			s1[6] = ' ';
			strncpy (c1, s1, 7);
			c1 = strchr (ch, ' ');
			strncpy (c1, s2, 31);
		} else {
			/* create a new data set name */
			while (getpos (anc, k) > -1)
				k++;

			setpos (anc, k, i);

			strncpy (s2, ch, 44);
			s2[44] = 0;
			vtoc_ebcdic_dec (s2, s2, 44);

			strncpy (ch, "LINUX.V               " "                      ", 44);

			strncpy (s1, anc->vlabel->volid, 6);
			vtoc_ebcdic_dec (s1, s1, 6);
			strncpy (c1, s1, 6);

			c1 = strchr (ch, ' ');
			strncpy (c1, ".PART", 5);
			c1 += 5;

			sprintf (dsno, "%04d.", k + 1);
			strncpy (c1, dsno, 5);

			c1 += 5;
			switch(p->type) {
				case PARTITION_LINUX_LVM:
					strncpy(c1, PART_TYPE_LVM, 6);
					break;
				case PARTITION_LINUX_RAID:
					strncpy(c1, PART_TYPE_RAID, 6);
					break;
				case PARTITION_LINUX:
					strncpy(c1, PART_TYPE_NATIVE, 6);
					break;
				case PARTITION_LINUX_SWAP:
					strncpy(c1, PART_TYPE_SWAP, 6);
					break;
				default:
					strncpy(c1, PART_TYPE_NATIVE, 6);
					break;
			}
		}

		vtoc_ebcdic_enc (ch, ch, 44);

		vtoc_write_label (fd, b, p->f1, NULL, NULL, NULL);
		p = p->next;
	}
}

/*
 * writes all changes to dasd
 */
int
fdasd_write_labels (fdasd_anchor_t * anc, int fd)
{
	PDEBUG
	if (anc->vlabel_changed)
		vtoc_write_volume_label (fd, anc->label_pos, anc->vlabel);

	if (anc->vtoc_changed)
		fdasd_write_vtoc_labels (anc, fd);

	return 1;
}

/*
 * writes all changes to dasd
 */
int
fdasd_prepare_labels (fdasd_anchor_t *anc, int fd) 
{
	PDEBUG
	partition_info_t *p = anc->first;
	char dsno[6], s1[7], s2[45], *c1, *c2, *ch;
	int i = 0, k = 0;

	/* loop over all FMT1 DSCBs */
	p = anc->first;
	for (i = 0; i < USABLE_PARTITIONS; i++) {
		strncpy (p->f1->DS1DSSN, anc->vlabel->volid, 6);

		ch = p->f1->DS1DSNAM;
		vtoc_ebcdic_dec (ch, ch, 44);
		c1 = ch + 7;
  
		if (getdsn (anc, i) > -1) {
			/* re-use the existing data set name */
			c2 = strchr (c1, '.');
			if (c2 != NULL)
				strncpy (s2, c2, 31);
			else
				fdasd_error (anc, dsname_corrupted, "");

			strncpy (s1, anc->vlabel->volid, 6);
			vtoc_ebcdic_dec (s1, s1, 6);
			s1[6] = ' ';
			strncpy (c1, s1, 7);
			c1 = strchr (ch, ' ');
			strncpy (c1, s2, 31);
		} else {
			/* create a new data set name */
			while (getpos (anc, k) > -1)
				k++;

			setpos (anc, k, i);

			strncpy (s2, ch, 44);
			s2[44] = 0;
			vtoc_ebcdic_dec (s2, s2, 44);

			strncpy (ch, "LINUX.V               " "                      ", 44);

			strncpy (s1, anc->vlabel->volid, 6);
			vtoc_ebcdic_dec (s1, s1, 6);
			strncpy (c1, s1, 6);

			c1 = strchr (ch, ' ');
			strncpy (c1, ".PART", 5);
			c1 += 5;

			sprintf (dsno, "%04d.", k + 1);
			strncpy (c1, dsno, 5);

			c1 += 5;
			switch(p->type) {
				case PARTITION_LINUX_LVM:
					strncpy(c1, PART_TYPE_LVM, 6);
					break;
				case PARTITION_LINUX_RAID:
					strncpy(c1, PART_TYPE_RAID, 6);
					break;
				case PARTITION_LINUX:
					strncpy(c1, PART_TYPE_NATIVE, 6);
					break;
				case PARTITION_LINUX_SWAP:
					strncpy(c1, PART_TYPE_SWAP, 6);
					break;
				default:
					strncpy(c1, PART_TYPE_NATIVE, 6);
					break;
			}
		}

		vtoc_ebcdic_enc (ch, ch, 44);
		p = p->next;
	}

	return 1;
}

void
fdasd_recreate_vtoc (fdasd_anchor_t *anc)
{
	PDEBUG
	partition_info_t *p = anc->first;
	int i;

	vtoc_init_format4_label(anc->f4,
							USABLE_PARTITIONS,
							anc->geo.cylinders,
							anc->geo.heads,
							anc->geo.sectors,
							anc->blksize,
							anc->dev_type);

	vtoc_init_format5_label(anc->f5);
	vtoc_init_format7_label(anc->f7);
	vtoc_set_freespace(anc->f4, anc->f5, anc->f7, 
					   '+', anc->verbose,
					   FIRST_USABLE_TRK,
					   anc->geo.cylinders * anc->geo.heads - 1,
					   anc->geo.cylinders, anc->geo.heads);

	for (i = 0; i < USABLE_PARTITIONS; i++) {
		bzero(p->f1, sizeof(format1_label_t));
		p->used       = 0x00;
		p->start_trk  = 0;
		p->end_trk    = 0;
		p->len_trk    = 0;
		p->fspace_trk = 0;
		p->type       = 0;
		p = p->next;
	}

	anc->used_partitions = 0;
	anc->fspace_trk = anc->geo.cylinders * anc->geo.heads - FIRST_USABLE_TRK;

	for (i=0; i<USABLE_PARTITIONS; i++)
		setpos(anc, i, -1);

	anc->vtoc_changed++;
}

/*
 * sets some important partition data
 * (like used, start_trk, end_trk, len_trk)
 * by calculating these values with the
 * information provided in the labels
 */
static void
fdasd_update_partition_info (fdasd_anchor_t *anc) 
{
	PDEBUG
	partition_info_t *q = NULL, *p = anc->first;
	unsigned int h = anc->geo.heads;
	unsigned long max = anc->geo.cylinders * h - 1;
	int i;
	char *ch;

	anc->used_partitions = anc->geo.sectors - 2 - anc->f4->DS4DSREC;

	for (i = 1; i <= USABLE_PARTITIONS; i++) {
		if (p->f1->DS1FMTID != 0xf1) {
			if (i == 1)
				/* there is no partition at all */
				anc->fspace_trk = max - FIRST_USABLE_TRK + 1;
			else
				/* previous partition was the last one */
				q->fspace_trk = max - q->end_trk;
			break;
		}

		/* this is a valid format 1 label */
		p->used = 0x01;
		p->start_trk = p->f1->DS1EXT1.llimit.cc * h + p->f1->DS1EXT1.llimit.hh;
		p->end_trk   = p->f1->DS1EXT1.ulimit.cc * h + p->f1->DS1EXT1.ulimit.hh;
		p->len_trk   = p->end_trk - p->start_trk + 1;

		if (i == 1) {
			/* first partition, there is at least one */
			anc->fspace_trk = p->start_trk - FIRST_USABLE_TRK;
		} else {
			if (i == USABLE_PARTITIONS)
				/* last possible partition */
				p->fspace_trk = max - p->end_trk;

			/* set free space values of previous partition */
			q->fspace_trk = p->start_trk - q->end_trk - 1;
		}

		ch = p->f1->DS1DSNAM;
		vtoc_ebcdic_dec (ch, ch, 44);
		if (strstr(ch, PART_TYPE_LVM))
			p->type = PARTITION_LINUX_LVM;
		else if (strstr(ch, PART_TYPE_RAID))
			p->type = PARTITION_LINUX_RAID;
		else if (strstr(ch, PART_TYPE_NATIVE))
			p->type = PARTITION_LINUX;
		else if (strstr(ch, PART_TYPE_SWAP))
			p->type = PARTITION_LINUX_SWAP;
		else
			p->type = PARTITION_LINUX;
		vtoc_ebcdic_enc (ch, ch, 44);

		q = p;
		p = p->next;
	}
}

/*
 * reorganizes all FMT1s, after that all used FMT1s should be right in 
 * front of all unused FMT1s
 */
static void
fdasd_reorganize_FMT1s (fdasd_anchor_t *anc) 
{
	PDEBUG
	int i, j;
	format1_label_t *ltmp;
	partition_info_t *ptmp;

	for (i=1; i<=USABLE_PARTITIONS - 1; i++) {
		ptmp = anc->first;

		for (j=1; j<=USABLE_PARTITIONS - i; j++) {
			if (ptmp->f1->DS1FMTID < ptmp->next->f1->DS1FMTID) {
				ltmp = ptmp->f1;
				ptmp->f1 = ptmp->next->f1;
				ptmp->next->f1 = ltmp;
			}

			ptmp=ptmp->next;
		}
	}
}

static void
fdasd_process_valid_vtoc (fdasd_anchor_t * anc, unsigned long b, int fd)
{
	PDEBUG
	int f5_counter = 0, f7_counter = 0, f1_counter = 0, oldfmt = 0;
	int i, n, f1size = sizeof (format1_label_t);
	partition_info_t *p = anc->first;
	format1_label_t q;
	char s[5], *ch;

	b += anc->blksize;

	for (i = 1; i <= anc->geo.sectors; i++) {
		bzero (&q, f1size);
		vtoc_read_label (fd, b, &q, NULL, NULL, NULL);

		switch (q.DS1FMTID) {
			case 0xf1:
				if (p == NULL)
					break;
				memcpy (p->f1, &q, f1size);

				n = -1;
				vtoc_ebcdic_dec (p->f1->DS1DSNAM, p->f1->DS1DSNAM, 44);
				ch = strstr (p->f1->DS1DSNAM, "PART");
				if (ch != NULL) {
					strncpy (s, ch + 4, 4);
					s[4] = '\0';
					n = atoi (s) - 1;
				}

				vtoc_ebcdic_enc (p->f1->DS1DSNAM, p->f1->DS1DSNAM, 44);

				/* this dasd has data set names 0000-0002
				but we use now 0001-0003 */
				if (n == -1)
					oldfmt++;

				if (((oldfmt == 0) && (n < 0)) || (n >= USABLE_PARTITIONS)) {
					/* no op */
				} else {
					if (oldfmt) {
						/* correct +1 */
						setpos (anc, n + 1, f1_counter);
					} else {
						setpos (anc, n, f1_counter);
					}
				}

				p = p->next;
				f1_counter++;
				break;
			case 0xf5:
				memcpy (anc->f5, &q, f1size);
				f5_counter++;
				break;
			case 0xf7:
				if (f7_counter == 0)
					memcpy (anc->f7, &q, f1size);
				f7_counter++;
				break;
		}

		b += anc->blksize;
	}

	if (oldfmt > 0) {
		/* this is the old format PART0000 - PART0002 */
		anc->vtoc_changed++;
	}

	if ((f5_counter == 0) || (anc->big_disk))
		vtoc_init_format5_label (anc->f5);

	if (f7_counter == 0)
		vtoc_init_format7_label (anc->f7);

	fdasd_reorganize_FMT1s (anc);
	fdasd_update_partition_info (anc);
}

static int
fdasd_valid_vtoc_pointer(fdasd_anchor_t *anc, unsigned long b, int fd)
{
	PDEBUG
	char str[LINE_LENGTH];

	/* VOL1 label contains valid VTOC pointer */ 
	vtoc_read_label (fd, b, NULL, anc->f4, NULL, NULL);

	if (anc->f4->DS4IDFMT != 0xf4) {
		if (strncmp(anc->vlabel->volkey,vtoc_ebcdic_enc("LNX1",str,4),4) == 0)
			return 0;
		fdasd_error(anc, wrong_disk_format, "Invalid VTOC");
	} else {
		fdasd_process_valid_vtoc (anc, b, fd);
	}

	return 0;
}

/*
 * check the dasd for a volume label
 */
int 
fdasd_check_volume (fdasd_anchor_t *anc, int fd) 
{
	PDEBUG
	volume_label_t *v = anc->vlabel;
	unsigned long b = -1;
	char str[LINE_LENGTH];

	vtoc_read_volume_label (fd, anc->label_pos, v);

	if (strncmp(v->vollbl, vtoc_ebcdic_enc ("VOL1", str, 4), 4) == 0) {
		/* found VOL1 volume label */
		b = (cchhb2blk (&v->vtoc, &anc->geo) - 1) * anc->blksize;

		if (b > 0) {
			int rc;
			rc = fdasd_valid_vtoc_pointer (anc, b, fd);

			if (rc < 0)
				return 1;
			else
				return 0;
		} else {
			return 1;
		}
	} else if (strncmp (v->volkey, vtoc_ebcdic_enc ("LNX1", str, 4), 4) == 0) {
		return 0;
	}

	return 1;
}

/*
 * checks the current API version with the API version of the dasd driver
 */
void
fdasd_check_api_version (fdasd_anchor_t *anc, int f)
{
	PDEBUG
	int api;
	char s[LINE_LENGTH];
 
	if (ioctl(f, DASDAPIVER, &api) != 0)
		fdasd_error(anc, unable_to_ioctl, "Could not retrieve API version.");
 
	if (api != DASD_MIN_API_VERSION) {
		sprintf(s, "The current API version '%d' doesn't " \
				"match dasd driver API version " \
				"'%d'!", api, DASD_MIN_API_VERSION);
		fdasd_error(anc, api_version_mismatch, s);
	}
}                                      

/*
 * reads dasd geometry data
 */
void 
fdasd_get_geometry (fdasd_anchor_t *anc, int f) 
{
	PDEBUG
	int blksize = 0;
	dasd_information_t dasd_info;
	char s[LINE_LENGTH];

	if (ioctl(f, HDIO_GETGEO, &anc->geo) != 0) 
		fdasd_error(anc, unable_to_ioctl,
					"Could not retrieve disk geometry information.");

	if (ioctl(f, BLKSSZGET, &blksize) != 0)
		fdasd_error(anc, unable_to_ioctl,
					"Could not retrieve blocksize information.");

	/* get disk type */
	if (ioctl(f, BIODASDINFO, &dasd_info) != 0) 
		fdasd_error(anc, unable_to_ioctl, 
					"Could not retrieve disk information.");

	if (strncmp(dasd_info.type, "ECKD", 4) != 0) {
		sprintf(s, "This is not an ECKD disk! This disk type " \
				"is not supported!");
		fdasd_error(anc,wrong_disk_type, s);
	}

	anc->dev_type   = dasd_info.dev_type;
	anc->blksize    = blksize;
	anc->label_pos  = dasd_info.label_block * blksize;
	anc->devno      = dasd_info.devno;
	anc->fspace_trk = anc->geo.cylinders * anc->geo.heads - FIRST_USABLE_TRK;
}

/*
 * returns unused partition info pointer if there
 * is a free partition, otherwise NULL
 */
static partition_info_t * 
fdasd_get_empty_f1_label (fdasd_anchor_t * anc) 
{
	PDEBUG
	if (anc->used_partitions < USABLE_PARTITIONS)	  
		return anc->last;	      
	else
		return NULL;
}

/*
 * asks for and sets some important partition data
 */
static int 
fdasd_get_partition_data (fdasd_anchor_t *anc, extent_t *part_extent,
                          partition_info_t *p, unsigned int *start_ptr,
                          unsigned int *stop_ptr) 
{
	PDEBUG
	unsigned int limit, cc, hh;
	cchh_t llimit, ulimit;
	partition_info_t *q;
	u_int8_t b1, b2;
	u_int16_t c, h;
	unsigned int start = *start_ptr, stop = *stop_ptr;
	int i;
	char *ch;

	if (anc->f4->DS4DEVCT.DS4DEVFG & ALTERNATE_CYLINDERS_USED)
		c = anc->f4->DS4DEVCT.DS4DSCYL - (u_int16_t) anc->f4->DS4DEVAC;
	else
		c = anc->f4->DS4DEVCT.DS4DSCYL;

	h = anc->f4->DS4DEVCT.DS4DSTRK;
	limit = (h * c - 1);

	/* check start value from user */
	q = anc->first;
	for (i = 0; i < USABLE_PARTITIONS; i++) {
		if ( q->next == NULL )
			break;

		if (start >= q->start_trk && start <= q->end_trk) {
			/* start is within another partition */
			start = q->end_trk + 1;

			if (start > limit) {
				start = FIRST_USABLE_TRK;
				q = anc->first;
			}
		}

		if (start < q->start_trk) {
			limit = q->start_trk - 1;
			break;
		}

		q = q->next;
	}

	if (start == limit)
		stop = start;

	/* update partition info */
	p->len_trk    = stop - start + 1;
	p->start_trk  = start;
	p->end_trk    = stop;

	cc = start / anc->geo.heads;
	hh = start - (cc * anc->geo.heads);
	vtoc_set_cchh(&llimit, cc, hh);

	/* check for cylinder boundary */
	if (hh == 0)  
		b1 = 0x81;
	else
		b1 = 0x01;

	cc = stop / anc->geo.heads;
	hh = stop - cc * anc->geo.heads;
	vtoc_set_cchh(&ulimit, cc, hh);

	/* it is always the 1st extent */
	b2 = 0x00;

	vtoc_set_extent(part_extent, b1, b2, &llimit, &ulimit);

	*start_ptr = start;
	*stop_ptr = stop;

	ch = p->f1->DS1DSNAM;
	vtoc_ebcdic_dec (ch, ch, 44);

	if (strstr(ch, PART_TYPE_LVM))
		p->type = PARTITION_LINUX_LVM;
	else if (strstr(ch, PART_TYPE_RAID))
		p->type = PARTITION_LINUX_RAID;
	else if (strstr(ch, PART_TYPE_NATIVE))
		p->type = PARTITION_LINUX;
	else if (strstr(ch, PART_TYPE_SWAP))
		p->type = PARTITION_LINUX_SWAP;
	else
		p->type = PARTITION_LINUX;

	vtoc_ebcdic_enc (ch, ch, 44);

	return 0;
}

static void
fdasd_enqueue_new_partition (fdasd_anchor_t *anc) 
{
	PDEBUG
	partition_info_t *q = anc->first, *p = anc->last;
	int i, k=0;

	for (i=1; i<USABLE_PARTITIONS; i++) {
		if ((q->end_trk == 0) || (p->start_trk < q->start_trk)) {
			break;
		} else { 
			q = q->next;
			k++;
		}
	}

	if (anc->first == q)
		anc->first = p;
	
	if (p != q) {
		anc->last->prev->next = NULL;
		anc->last = anc->last->prev;

		p->next = q;
		p->prev = q->prev;
		q->prev = p;
		
		if (p->prev != NULL)
			p->prev->next = p;
	}

	p->used = 0x01;
	p->type = PARTITION_LINUX;

	for (i=0; i<USABLE_PARTITIONS; i++) {
		int j = getpos(anc, i);
		if (j >= k)
			setpos(anc, i, j + 1);
	}

	/* update free-space counters */
	if (anc->first == p) {
		/* partition is the first used partition */
		if (p->start_trk == FIRST_USABLE_TRK) {
			/* partition starts right behind VTOC */
			p->fspace_trk = anc->fspace_trk - p->len_trk;
			anc->fspace_trk = 0;
		} else {
			/* there is some space between VTOC and partition */
			p->fspace_trk = anc->fspace_trk - p->len_trk - p->start_trk
							+ FIRST_USABLE_TRK;
			anc->fspace_trk = p->start_trk - FIRST_USABLE_TRK;
		}
	} else {
		/* there are partitons in front of the new one */
		if (p->start_trk == p->prev->end_trk + 1) {
			/* new partition is right behind the previous one */
			p->fspace_trk = p->prev->fspace_trk - p->len_trk;
			p->prev->fspace_trk = 0;
		} else {
			/* there is some space between new and prev. part. */
			p->fspace_trk = p->prev->fspace_trk - p->len_trk
							- p->start_trk + p->prev->end_trk + 1;
			p->prev->fspace_trk = p->start_trk - p->prev->end_trk - 1;
		}
	}
}

/*
 * adds a new partition to the 'partition table'
 */
partition_info_t *
fdasd_add_partition (fdasd_anchor_t *anc, unsigned int start,
                     unsigned int stop) 
{
	PDEBUG
	cchhb_t hf1;
	partition_info_t *p;
	extent_t ext;
	int i;

	PDEBUG;

	if ((p = fdasd_get_empty_f1_label(anc)) == NULL) {
		PDEBUG;
		return 0;
	}

	PDEBUG;
	if (fdasd_get_partition_data(anc, &ext, p, &start, &stop) != 0)
		return 0;

	PDEBUG;
	vtoc_init_format1_label(anc->vlabel->volid, anc->blksize, &ext, p->f1);

	PDEBUG;
	fdasd_enqueue_new_partition(anc);
	
	PDEBUG;
	anc->used_partitions += 1;

	i = anc->used_partitions + 2;
	if (anc->big_disk)
		i++;
	PDEBUG;

	vtoc_set_cchhb(&hf1, VTOC_START_CC, VTOC_START_HH, i);

	vtoc_update_format4_label(anc->f4, &hf1, anc->f4->DS4DSREC - 1);

	PDEBUG;

	start = ext.llimit.cc * anc->geo.heads + ext.llimit.hh;
	stop  = ext.ulimit.cc * anc->geo.heads + ext.ulimit.hh;

	PDEBUG;
	vtoc_set_freespace(anc->f4, anc->f5, anc->f7, '-', anc->verbose,
					   start, stop, anc->geo.cylinders, anc->geo.heads);

	anc->vtoc_changed++;

	PDEBUG;
	return p;
}

/* vim:set tabstop=4 shiftwidth=4 softtabstop=4: */
