diff options
| -rw-r--r-- | target/linux/ar71xx/files/drivers/mtd/wrt160nl_part.c | 174 | 
1 files changed, 106 insertions, 68 deletions
| diff --git a/target/linux/ar71xx/files/drivers/mtd/wrt160nl_part.c b/target/linux/ar71xx/files/drivers/mtd/wrt160nl_part.c index d76be1a39..da54e0ff4 100644 --- a/target/linux/ar71xx/files/drivers/mtd/wrt160nl_part.c +++ b/target/linux/ar71xx/files/drivers/mtd/wrt160nl_part.c @@ -1,5 +1,6 @@  /* - * Copyright © 2009 Christian Daniel <cd@maintech.de> + * Copyright (C) 2009 Christian Daniel <cd@maintech.de> + * Copyright (C) 2009 Gabor Juhos <juhosg@openwrt.org>   *   * 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 @@ -22,11 +23,22 @@  #include <linux/kernel.h>  #include <linux/slab.h> +#include <linux/vmalloc.h>  #include <linux/mtd/mtd.h>  #include <linux/mtd/partitions.h> -#include <linux/bootmem.h> -#include <linux/magic.h> + +struct cybertan_header { +	char	magic[4]; +	u8	res1[4]; +	char	fw_date[3]; +	char	fw_ver[3]; +	char	id[4]; +	char	hw_ver; +	char	unused; +	u8	flags[2]; +	u8	res2[10]; +};  #define TRX_PARTS	6  #define TRX_MAGIC	0x30524448 @@ -58,91 +70,117 @@ struct uimage_header {  	uint8_t		ih_name[IH_NMLEN];	/* Image Name */  }; +struct wrt160nl_header { +	struct cybertan_header	cybertan; +	struct trx_header	trx; +	struct uimage_header	uimage; +} __attribute__ ((packed)); +  static struct mtd_partition trx_parts[TRX_PARTS]; -static int create_mtd_partitions(struct mtd_info *master, -				 struct mtd_partition **pparts, -				 unsigned long origin) +static int wrt160nl_parse_partitions(struct mtd_info *master, +				     struct mtd_partition **pparts, +				     unsigned long origin)  { -	uint8_t buf[512]; -	int len; -	struct trx_header *header; +	struct wrt160nl_header *header; +	struct trx_header *theader;  	struct uimage_header *uheader; +	size_t retlen;  	unsigned int kernel_len; +	int ret; + +	header = vmalloc(sizeof(*header)); +	if (!header) { +		return -ENOMEM; +		goto out; +	} + +	ret = master->read(master, 4 * master->erasesize, sizeof(*header), +			   &retlen, (void *) header); +	if (ret) +		goto free_hdr; -	master->read(master, 4 * master->erasesize, sizeof(buf), &len, buf); -	if (strncmp(buf, "NL16", 4) == 0) { -		printk(KERN_INFO "TRX on WRT160NL detected\n"); +	if (retlen != sizeof(*header)) { +		ret = -EIO; +		goto free_hdr; +	} -		header = (struct trx_header *)(buf + 32); -		if (le32_to_cpu(header->magic) != TRX_MAGIC) { -			printk(KERN_WARNING "TRX messed up\n"); -			return 0; -		} +	if (strncmp(header->cybertan.magic, "NL16", 4) != 0) { +		printk(KERN_NOTICE "%s: no WRT160NL signature found\n", +			master->name); +		goto free_hdr; +	} -		uheader = (struct uimage_header *)(buf + 60); -		if (uheader->ih_magic != IH_MAGIC) { -			printk(KERN_WARNING "uImage messed up\n"); -			return 0; -		} +	theader = &header->trx; +	if (le32_to_cpu(theader->magic) != TRX_MAGIC) { +		printk(KERN_NOTICE "%s: no TRX header found\n", master->name); +		goto free_hdr; +	} -		kernel_len = uheader->ih_size / master->erasesize; -		if (uheader->ih_size % master->erasesize) -			kernel_len++; +	uheader = &header->uimage; +	if (uheader->ih_magic != IH_MAGIC) { +		printk(KERN_NOTICE "%s: no uImage found\n", master->name); +		goto free_hdr; +	} +	kernel_len = uheader->ih_size / master->erasesize; +	if (uheader->ih_size % master->erasesize)  		kernel_len++; -		kernel_len *= master->erasesize; - -		trx_parts[0].name = "u-boot"; -		trx_parts[0].offset = 0; -		trx_parts[0].size = 4 * master->erasesize; -		trx_parts[0].mask_flags = MTD_WRITEABLE; - -		trx_parts[1].name = "kernel"; -		trx_parts[1].offset = trx_parts[0].offset + trx_parts[0].size; -		trx_parts[1].size = kernel_len; -		trx_parts[1].mask_flags = 0; - -		trx_parts[2].name = "rootfs"; -		trx_parts[2].offset = trx_parts[1].offset + trx_parts[1].size; -		trx_parts[2].size = master->size - 6 * master->erasesize - trx_parts[1].size; -		trx_parts[2].mask_flags = 0; - -		trx_parts[3].name = "nvram"; -		trx_parts[3].offset = master->size - 2 * master->erasesize; -		trx_parts[3].size = master->erasesize; -		trx_parts[3].mask_flags = MTD_WRITEABLE; - -		trx_parts[4].name = "art"; -		trx_parts[4].offset = master->size - master->erasesize; -		trx_parts[4].size = master->erasesize; -		trx_parts[4].mask_flags = MTD_WRITEABLE; - -		trx_parts[5].name = "firmware"; -		trx_parts[5].offset = 4 * master->erasesize; -		trx_parts[5].size = master->size - 6 * master->erasesize; -		trx_parts[5].mask_flags = 0; - -		*pparts = trx_parts; - -		return TRX_PARTS; -	} else { -		return 0; -	} + +	kernel_len++; +	kernel_len *= master->erasesize; + +	trx_parts[0].name = "u-boot"; +	trx_parts[0].offset = 0; +	trx_parts[0].size = 4 * master->erasesize; +	trx_parts[0].mask_flags = MTD_WRITEABLE; + +	trx_parts[1].name = "kernel"; +	trx_parts[1].offset = trx_parts[0].offset + trx_parts[0].size; +	trx_parts[1].size = kernel_len; +	trx_parts[1].mask_flags = 0; + +	trx_parts[2].name = "rootfs"; +	trx_parts[2].offset = trx_parts[1].offset + trx_parts[1].size; +	trx_parts[2].size = master->size - 6 * master->erasesize - trx_parts[1].size; +	trx_parts[2].mask_flags = 0; + +	trx_parts[3].name = "nvram"; +	trx_parts[3].offset = master->size - 2 * master->erasesize; +	trx_parts[3].size = master->erasesize; +	trx_parts[3].mask_flags = MTD_WRITEABLE; + +	trx_parts[4].name = "art"; +	trx_parts[4].offset = master->size - master->erasesize; +	trx_parts[4].size = master->erasesize; +	trx_parts[4].mask_flags = MTD_WRITEABLE; + +	trx_parts[5].name = "firmware"; +	trx_parts[5].offset = 4 * master->erasesize; +	trx_parts[5].size = master->size - 6 * master->erasesize; +	trx_parts[5].mask_flags = 0; + +	*pparts = trx_parts; +	ret = TRX_PARTS; + + free_hdr: +	vfree(header); + out: +	return ret;  } -static struct mtd_part_parser trx_parser = { +static struct mtd_part_parser wrt160nl_parser = {  	.owner		= THIS_MODULE, -	.parse_fn	= create_mtd_partitions, +	.parse_fn	= wrt160nl_parse_partitions,  	.name		= "wrt160nl",  }; -static int __init trx_parser_init(void) +static int __init wrt160nl_parser_init(void)  { -	return register_mtd_parser(&trx_parser); +	return register_mtd_parser(&wrt160nl_parser);  } -module_init(trx_parser_init); +module_init(wrt160nl_parser_init);  MODULE_LICENSE("GPL");  MODULE_AUTHOR("Christian Daniel <cd@maintech.de>"); | 
