/*
 *  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];
};

#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,2,0))
static int myloader_parse_partitions(struct mtd_info *master,
				     struct mtd_partition **pparts,
				     struct mtd_part_parser_data *data)
#else
static int myloader_parse_partitions(struct mtd_info *master,
				     struct mtd_partition **pparts,
				     unsigned long origin)
#endif
{
	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)
{
	return register_mtd_parser(&myloader_mtd_parser);
}

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");
