++
++static int __init
++find_root(struct mtd_info *mtd, size_t size, struct mtd_partition *part)
++{
++ struct trx_header *trx;
++ unsigned char buf[512];
++ int off;
++ size_t len;
++
++ trx = (struct trx_header *) buf;
++
++ printk(KERN_NOTICE
++ "MTD erasesize: %d, Size: %d\n",
++ mtd->erasesize, size);
++
++ for (off = (384*1024); off < size; off += mtd->erasesize) {
++ memset(buf, 0xe5, sizeof(buf));
++
++ /*
++ * Read into buffer
++ */
++ if (MTD_READ(mtd, off, sizeof(buf), &len, buf) ||
++ len != sizeof(buf))
++ continue;
++
++ /* found a TRX header */
++ if (le32_to_cpu(trx->magic) == TRX_MAGIC) {
++ printk(KERN_NOTICE "Found TRX Header!\n");
++
++ part->offset = le32_to_cpu(trx->offsets[2]) ? :
++ le32_to_cpu(trx->offsets[1]);
++ part->size = le32_to_cpu(trx->len);
++
++ part->size -= part->offset;
++ part->offset += off;
++
++ goto done;
++ }
++ }
++
++ printk(KERN_NOTICE
++ "%s: Couldn't find root filesystem\n",
++ mtd->name);
++ return -1;
++
++ done:
++ return part->size;
++}
++
++struct mtd_partition * __init
++init_mtd_partitions(struct mtd_info *mtd, size_t size)
++{
++
++ /* boot loader */
++ bcm947xx_parts[0].offset=0;
++ bcm947xx_parts[0].size=384*1024;
++
++ /* nvram */
++ bcm947xx_parts[3].offset = size - (128*1024);
++ bcm947xx_parts[3].size = size - bcm947xx_parts[3].offset;
++
++ /* Size linux (kernel and rootfs) */
++ bcm947xx_parts[1].offset = bcm947xx_parts[0].size;
++ bcm947xx_parts[1].size = bcm947xx_parts[3].offset - bcm947xx_parts[1].offset;
++
++ /* Find and size rootfs */
++ if (find_root(mtd,size,&bcm947xx_parts[2])==0) {
++ /* entirely jffs2 */
++ bcm947xx_parts[2].size = bcm947xx_parts[3].offset - bcm947xx_parts[2].offset;
++ bcm947xx_parts[4].name = NULL;
++ } else {
++ /* legacy setup */
++ /* calculate leftover flash, and assign it to the jffs2 partition */
++ bcm947xx_parts[4].offset = bcm947xx_parts[2].offset + bcm947xx_parts[2].size;
++ bcm947xx_parts[4].offset = ROUNDUP(bcm947xx_parts[4].offset, mtd->erasesize);
++ bcm947xx_parts[4].size = bcm947xx_parts[3].offset - bcm947xx_parts[4].offset;
++ }
++
++ return bcm947xx_parts;
++}
++
++EXPORT_SYMBOL(init_mtd_partitions);