/* labmtd.c
 * MTD support in a module for LAB - Linux As Bootldr.
 */

#include <linux/module.h>
#include <linux/bootldr/commands.h>
#include <linux/init.h> 
#include <linux/kernel.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h>
#include <linux/slab.h>

#define MAX_PARTITIONS 6

static struct mtd_partition* partitions[MAX_PARTITIONS];
static int partitionsused[MAX_PARTITIONS];

void lab_partition_show(int argc,const char** argv);
void labmtd_add_partition(char* name, unsigned int addr, unsigned int size);

int labmtd_init()
{
	int i;
	
	lab_addcommand("partition", lab_partition_show, "Same as partition show");
	lab_addsubcommand("partition", "show", lab_partition_show, "Lists all defined partitions");
	for(i=0; i<MAX_PARTITIONS; i++)
		partitionsused[i]=0;
	labmtd_add_partition("bootldr", 0x00000000, 0x00040000);
	labmtd_add_partition("root", 0x00040000, 0x01FC0000);
	return 0;
};

void labmtd_cleanup()
{
	
};

void labmtd_add_partition(char* name, unsigned int addr, unsigned int size)
{
	int i,part;
	struct mtd_info* minfo;
	
	for (i=0; i < MAX_PARTITIONS; i++)
	{
		if (!partitionsused[i])
			break;
	};
	
	if (i == MAX_PARTITIONS)
	{
		printk(KERN_ERR "labmtd: out of partitions!\n");
		return;
	};
	
	part=i;
	partitionsused[part]=1;
	partitions[part] = kmalloc(sizeof(struct mtd_partition), GFP_KERNEL);
	partitions[part]->name = name;
	partitions[part]->size = size;
	partitions[part]->offset = addr;
	partitions[part]->mask_flags = 0;
	
	minfo = __get_mtd_device(NULL,0);
	if (!minfo)
		printk(KERN_ERR "labmtd: failed to getmtddevice??\n");
	add_mtd_partitions(minfo, partitions[part], 1);
};

void lab_partition_show(int argc,const char** argv)
{
	int i;
	
	for (i = 0; i < MAX_PARTITIONS; i++)
	{
		if (!partitionsused[i])
			continue;
		putstr(partitions[i]->name);
		putstr("\r\n");
		putLabeledWord("Size:    ", partitions[i]->size);
		putLabeledWord("Offset:  ", partitions[i]->offset);
	};
};

MODULE_AUTHOR("Joshua Wise");
MODULE_DESCRIPTION("LAB MTD Interface Module");
MODULE_LICENSE("GPL");
module_init(labmtd_init);
module_exit(labmtd_cleanup);