Beispiel #1
0
static struct nvram_header *
BCMINITFN(nand_find_nvram)(hndnand_t *nfl, uint32 off)
{
	int blocksize = nfl->blocksize;
	unsigned char *buf = nflash_nvh;
	int rlen = sizeof(nflash_nvh);
	int len;

	for (; off < NFL_BOOT_SIZE; off += blocksize) {
		if (hndnand_checkbadb(nfl, off) != 0)
			continue;

		len = blocksize;
		if (len >= rlen)
			len = rlen;

		if (hndnand_read(nfl, off, len, buf) == 0)
			break;

		buf += len;
		rlen -= len;
		if (rlen == 0)
			return (struct nvram_header *)nflash_nvh;
	}

	return NULL;
}
Beispiel #2
0
static int
_nflash_mtd_read(struct mtd_info *mtd, struct mtd_partition *part,
	loff_t from, size_t len, size_t *retlen, u_char *buf)
{
	struct nflash_mtd *nflash = (struct nflash_mtd *) mtd->priv;
	int bytes, ret = 0;
	uint extra = 0;
	uchar *tmpbuf = NULL;
	int size;
	uint offset, blocksize, mask, blk_offset, off;
	uint skip_bytes = 0, good_bytes = 0, page_size;
	int blk_idx, i;
	int need_copy = 0;
	uchar *ptr = NULL;

	/* Locate the part */
	if (!part) {
		for (i = 0; nflash_parts[i].name; i++) {
			if (from >= nflash_parts[i].offset &&
			((nflash_parts[i+1].name == NULL) || (from < nflash_parts[i+1].offset))) {
				part = &nflash_parts[i];
				break;
			}
		}
		if (!part)
			return -EINVAL;
	}
	/* Check address range */
	if (!len)
		return 0;
	if ((from + len) > mtd->size)
		return -EINVAL;
	offset = from;
	page_size = nflash->nfl->pagesize;
	if ((offset & (page_size - 1)) != 0) {
		extra = offset & (page_size - 1);
		offset -= extra;
		len += extra;
		need_copy = 1;
	}
	size = (len + (page_size - 1)) & ~(page_size - 1);
	if (size != len)
		need_copy = 1;
	if (!need_copy) {
		ptr = buf;
	} else {
		NFLASH_UNLOCK(nflash);
		tmpbuf = (uchar *)kmalloc(size, GFP_KERNEL);
		NFLASH_LOCK(nflash);
		ptr = tmpbuf;
	}

	blocksize = mtd->erasesize;
	mask = blocksize - 1;
	blk_offset = offset & ~mask;
	good_bytes = part->offset & ~mask;
	/* Check and skip bad blocks */
	for (blk_idx = good_bytes/blocksize; blk_idx < mtd->eraseregions->numblocks; blk_idx++) {
		if (nflash->map[blk_idx] != 0) {
			skip_bytes += blocksize;
		} else {
			if (good_bytes == blk_offset)
				break;
			good_bytes += blocksize;
		}
	}
	if (blk_idx == mtd->eraseregions->numblocks) {
		ret = -EINVAL;
		goto done;
	}
	blk_offset = blocksize * blk_idx;
	*retlen = 0;
	while (len > 0) {
		off = offset + skip_bytes;

		/* Check and skip bad blocks */
		if (off >= (blk_offset + blocksize)) {
			blk_offset += blocksize;
			blk_idx++;
			while ((nflash->map[blk_idx] != 0) &&
			       (blk_offset < mtd->size)) {
				skip_bytes += blocksize;
				blk_offset += blocksize;
				blk_idx++;
			}
			if (blk_offset >= mtd->size) {
				ret = -EINVAL;
				goto done;
			}
			off = offset + skip_bytes;
		}

		if ((bytes = hndnand_read(nflash->nfl,
			off, page_size, ptr)) < 0) {
			ret = bytes;
			goto done;
		}
		if (bytes > len)
			bytes = len;
		offset += bytes;
		len -= bytes;
		ptr += bytes;
		*retlen += bytes;
	}

done:
	if (tmpbuf) {
		*retlen -= extra;
		memcpy(buf, tmpbuf+extra, *retlen);
		kfree(tmpbuf);
	}
	return ret;
}
Beispiel #3
0
static uint lookup_nflash_rootfs_offset(hndnand_t *nfl, struct mtd_info *mtd, int offset, size_t size)
{
	struct romfs_super_block *romfsb;
	struct cramfs_super *cramfsb;
	struct squashfs_super_block *squashfsb;
	struct trx_header *trx;
	unsigned char buf[NFL_SECTOR_SIZE];
	uint blocksize, mask, blk_offset, off, shift = 0;
	int ret;
	
	romfsb = (struct romfs_super_block *) buf;
	cramfsb = (struct cramfs_super *) buf;
	squashfsb = (struct squashfs_super_block *) buf;
	trx = (struct trx_header *) buf;


	/* Look at every block boundary till 16MB; higher space is reserved for application data. */
	blocksize = mtd->erasesize;
	printk("lookup_nflash_rootfs_offset: offset = 0x%x\n", offset);
	for (off = offset; off < NFL_BOOT_OS_SIZE; off += 4096) {
		mask = blocksize - 1;
		blk_offset = off & ~mask;
		if (hndnand_checkbadb(nfl, blk_offset) != 0)
			continue;
		memset(buf, 0xe5, sizeof(buf));
		if ((ret = hndnand_read(nfl, off, sizeof(buf), buf)) != sizeof(buf)) {
			printk(KERN_NOTICE
			       "%s: nflash_read return %d\n", mtd->name, ret);
			continue;
		}
			
		if (le32_to_cpu(trx->magic) == TRX_MAGIC)
		{
		
		printk(KERN_NOTICE "found trx at %X, len =%d\n",off,trx->len);
		int offset = le32_to_cpu(trx->offsets[2]) ? : le32_to_cpu(trx->offsets[1]);
		offset+=off;
		printk(KERN_NOTICE "scan filesys at %X\n",offset);

		if ((ret = hndnand_read(nfl, offset, sizeof(buf), buf)) != sizeof(buf)) {
			printk(KERN_NOTICE
			       "%s: nflash_read return %d\n", mtd->name, ret);
			continue;
		}
		
		if (*((__u32 *) buf) == SQUASHFS_MAGIC) {
			printk(KERN_NOTICE
			       "%s: squash filesystem with lzma found at offset %d\n",
			       mtd->name, off );
		int size = squashfsb->bytes_used;
		//part->size = part->size + 1024; /* uncomment for belkin v2000 ! */
		int len = offset + size;
		len +=  (mtd->erasesize - 1);
		len &= ~(mtd->erasesize - 1);
		ddwrtoffset = len;
		ddwrtsize = mtd->size - ddwrtoffset;
		return offset;
		}
		}

	}