++ if (!buf)
++ return -ENOMEM;
++
++ // Get the tag
++ ret = master->read(master,master->erasesize,sizeof(struct bcm963xx_cfe_map), &retlen, (void *)buf);
++ if (retlen != sizeof(struct bcm963xx_cfe_map)){
++ vfree(buf);
++ return -EIO;
++ };
++ printk("bcm963xx: CFE boot tag found with version %s and board type %s.\n",buf->tagVersion,buf->boardid);
++ // Get the values and calculate
++ sscanf(buf->rootAddress,"%u", &rootfsaddr);
++ rootfsaddr = rootfsaddr - EXTENDED_SIZE;
++ sscanf(buf->rootLength, "%u", &rootfslen);
++ sscanf(buf->kernelAddress, "%u", &kerneladdr);
++ kerneladdr = kerneladdr - EXTENDED_SIZE;
++ sscanf(buf->kernelLength, "%u", &kernellen);
++ sscanf(buf->totalLength, "%u", &totallen);
++ spareaddr = ROUNDUP(totallen,master->erasesize) + master->erasesize;
++ sparelen = master->size - spareaddr - master->erasesize;
++ // Determine number of partitions
++ namelen = 8;
++ if (rootfslen > 0){
++ nrparts++;
++ namelen =+ 6;
++ };
++ if (kernellen > 0){
++ nrparts++;
++ namelen =+ 6;
++ };
++ if (sparelen > 0){
++ nrparts++;
++ namelen =+ 6;
++ };
++ // Ask kernel for more memory.
++ parts = kmalloc(sizeof(*parts)*nrparts+10*nrparts, GFP_KERNEL);
++ if (!parts){
++ vfree(buf);
++ return -ENOMEM;
++ };
++ memset(parts,0,sizeof(*parts)*nrparts+10*nrparts);
++ // Start building partition list
++ parts[curpart].name = "CFE";
++ parts[curpart].offset = 0;
++ parts[curpart].size = master->erasesize;
++ curpart++;
++ if (kernellen > 0){
++ parts[curpart].name = "Kernel";
++ parts[curpart].offset = kerneladdr;
++ parts[curpart].size = kernellen;
++ curpart++;
++ };
++ if (rootfslen > 0){
++ parts[curpart].name = "Rootfs";
++ parts[curpart].offset = rootfsaddr;
++ parts[curpart].size = rootfslen;
++ curpart++;
++ };
++ if (sparelen > 0){
++ parts[curpart].name = "OpenWrt";
++ parts[curpart].offset = spareaddr;
++ parts[curpart].size = sparelen;
++ curpart++;
++ };
++ parts[curpart].name = "NVRAM";
++ parts[curpart].offset = master->size - master->erasesize;
++ parts[curpart].size = master->erasesize;
++ for (i = 0; i < nrparts; i++) {
++ printk("bcm963xx: Partition %d is %s offset %x and length %x\n", i, parts[i].name, parts[i].offset, parts[i].size);
++ }
++ *pparts = parts;
++ vfree(buf);
++ return nrparts;
++};
++
++static struct mtd_partition bcm963xx_parts[] = {
++ { name: "bootloader", size: 0, offset: 0, mask_flags: MTD_WRITEABLE },
++ { name: "rootfs", size: 0, offset: 0},
++ { name: "jffs2", size: 5 * 0x10000, offset: 57*0x10000}