/*
 *  Parse MyLoader-style flash partition tables and produce a Linux partition
 *  array to match.
 *
 *  Copyright (C) 2007-2009 Gabor Juhos <juhosg@openwrt.org>
 *
 *  This file was based on drivers/mtd/redboot.c
 *  Author: Red Hat, Inc. - David Woodhouse <dwmw2@cambridge.redhat.com>
 *
 *  This program is free software; you can redistribute it and/or modify it
 *  under the terms of the GNU General Public License version 2 as published
 *  by the Free Software Foundation.
 */

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/version.h>
#include <linux/slab.h>
#include <linux/init.h>
#include <linux/vmalloc.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h>
#include <linux/byteorder/generic.h>
#include <linux/myloader.h>

#define BLOCK_LEN_MIN		0x10000
#define PART_NAME_LEN		32

struct part_data {
	struct mylo_partition_table	tab;
	char names[MYLO_MAX_PARTITIONS][PART_NAME_LEN];
};

static int myloader_parse_partitions(struct mtd_info *master,
				     const struct mtd_partition **pparts,
				     struct mtd_part_parser_data *data)
{
	struct part_data *buf;
	struct mylo_partition_table *tab;
	struct mylo_partition *part;
	struct mtd_partition *mtd_parts;
	struct mtd_partition *mtd_part;
	int num_parts;
	int ret, i;
	size_t retlen;
	char *names;
	unsigned long offset;
	unsigned long blocklen;

	buf = vmalloc(sizeof(*buf));
	if (!buf) {
		return -ENOMEM;
		goto out;
	}
	tab = &buf->tab;

	blocklen = master->erasesize;
	if (blocklen < BLOCK_LEN_MIN)
		blocklen = BLOCK_LEN_MIN;

	offset = blocklen;

	/* Find the partition table */
	for (i = 0; i < 4; i++, offset += blocklen) {
		printk(KERN_DEBUG "%s: searching for MyLoader partition table"
				" at offset 0x%lx\n", master->name, offset);

		ret = mtd_read(master, offset, sizeof(*buf), &retlen,
			       (void *)buf);
		if (ret)
			goto out_free_buf;

		if (retlen != sizeof(*buf)) {
			ret = -EIO;
			goto out_free_buf;
		}

		/* Check for Partition Table magic number */
		if (tab->magic == le32_to_cpu(MYLO_MAGIC_PARTITIONS))
			break;

	}

	if (tab->magic != le32_to_cpu(MYLO_MAGIC_PARTITIONS)) {
		printk(KERN_DEBUG "%s: no MyLoader partition table found\n",
			master->name);
		ret = 0;
		goto out_free_buf;
	}

	/* The MyLoader and the Partition Table is always present */
	num_parts = 2;

	/* Detect number of used partitions */
	for (i = 0; i < MYLO_MAX_PARTITIONS; i++) {
		part = &tab->partitions[i];

		if (le16_to_cpu(part->type) == PARTITION_TYPE_FREE)
			continue;

		num_parts++;
	}

	mtd_parts = kzalloc((num_parts * sizeof(*mtd_part) +
				num_parts * PART_NAME_LEN), GFP_KERNEL);

	if (!mtd_parts) {
		ret = -ENOMEM;
		goto out_free_buf;
	}

	mtd_part = mtd_parts;
	names = (char *)&mtd_parts[num_parts];

	strncpy(names, "myloader", PART_NAME_LEN);
	mtd_part->name = names;
	mtd_part->offset = 0;
	mtd_part->size = offset;
	mtd_part->mask_flags = MTD_WRITEABLE;
	mtd_part++;
	names += PART_NAME_LEN;

	strncpy(names, "partition_table", PART_NAME_LEN);
	mtd_part->name = names;
	mtd_part->offset = offset;
	mtd_part->size = blocklen;
	mtd_part->mask_flags = MTD_WRITEABLE;
	mtd_part++;
	names += PART_NAME_LEN;

	for (i = 0; i < MYLO_MAX_PARTITIONS; i++) {
		part = &tab->partitions[i];

		if (le16_to_cpu(part->type) == PARTITION_TYPE_FREE)
			continue;

		if ((buf->names[i][0]) && (buf->names[i][0] != '\xff'))
			strncpy(names, buf->names[i], PART_NAME_LEN);
		else
			snprintf(names, PART_NAME_LEN, "partition%d", i);

		mtd_part->offset = le32_to_cpu(part->addr);
		mtd_part->size = le32_to_cpu(part->size);
		mtd_part->name = names;
		mtd_part++;
		names += PART_NAME_LEN;
	}

	*pparts = mtd_parts;
	ret = num_parts;

 out_free_buf:
	vfree(buf);
 out:
	return ret;
}

static struct mtd_part_parser myloader_mtd_parser = {
	.owner		= THIS_MODULE,
	.parse_fn	= myloader_parse_partitions,
	.name		= "MyLoader",
};

static int __init myloader_mtd_parser_init(void)
{
	register_mtd_parser(&myloader_mtd_parser);

	return 0;
}

static void __exit myloader_mtd_parser_exit(void)
{
	deregister_mtd_parser(&myloader_mtd_parser);
}

module_init(myloader_mtd_parser_init);
module_exit(myloader_mtd_parser_exit);

MODULE_AUTHOR("Gabor Juhos <juhosg@openwrt.org>");
MODULE_DESCRIPTION("Parsing code for MyLoader partition tables");
MODULE_LICENSE("GPL v2");
