++
++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;
++
++ for (off = (512*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) {
++ 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 = CFE_SIZE;
++
++ /* nvram (old config partition) */
++ bcm947xx_parts[3].offset = bcm947xx_parts[0].size;
++ bcm947xx_parts[3].size = NVRAM_SIZE;
++
++ /* Size linux (kernel and rootfs) */
++ /* do not count the elf loader, which is on one sector */
++ bcm947xx_parts[1].offset = bcm947xx_parts[0].size + bcm947xx_parts[3].size + mtd->erasesize;
++ bcm947xx_parts[1].size = size - NVRAM_SIZE - bcm947xx_parts[0].size -
++ bcm947xx_parts[3].size - mtd->erasesize;
++
++ /* Find and size rootfs */
++ if (find_root(mtd,size,&bcm947xx_parts[2])==0) {
++ /* entirely jffs2 */
++ bcm947xx_parts[2].size = size - bcm947xx_parts[2].offset - NVRAM_SIZE;
++ 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;
++ if ((bcm947xx_parts[4].offset % mtd->erasesize) > 0) {
++ bcm947xx_parts[4].offset += mtd->erasesize -
++ (bcm947xx_parts[4].offset % mtd->erasesize);
++ }
++ bcm947xx_parts[4].size = size - NVRAM_SIZE - bcm947xx_parts[4].offset;
++ }
++
++ return bcm947xx_parts;
++}
++
++EXPORT_SYMBOL(init_mtd_partitions);