Beispiel #1
0
static int verify_eraseblock(int ebnum)
{
	size_t read;
	int err = 0;
	loff_t addr = ebnum * mtd->erasesize;

	prandom_bytes_state(&rnd_state, writebuf, subpgsize);
	clear_data(readbuf, subpgsize);
	err = mtd_read(mtd, addr, subpgsize, &read, readbuf);
	if (unlikely(err || read != subpgsize)) {
		if (mtd_is_bitflip(err) && read == subpgsize) {
			pr_info("ECC correction at %#llx\n",
			       (long long)addr);
			err = 0;
		} else {
			pr_err("error: read failed at %#llx\n",
			       (long long)addr);
			return err ? err : -1;
		}
	}
	if (unlikely(memcmp(readbuf, writebuf, subpgsize))) {
		pr_err("error: verify failed at %#llx\n",
		       (long long)addr);
		pr_info("------------- written----------------\n");
		print_subpage(writebuf);
		pr_info("------------- read ------------------\n");
		print_subpage(readbuf);
		pr_info("-------------------------------------\n");
		errcnt += 1;
	}

	addr += subpgsize;

	prandom_bytes_state(&rnd_state, writebuf, subpgsize);
	clear_data(readbuf, subpgsize);
	err = mtd_read(mtd, addr, subpgsize, &read, readbuf);
	if (unlikely(err || read != subpgsize)) {
		if (mtd_is_bitflip(err) && read == subpgsize) {
			pr_info("ECC correction at %#llx\n",
			       (long long)addr);
			err = 0;
		} else {
			pr_err("error: read failed at %#llx\n",
			       (long long)addr);
			return err ? err : -1;
		}
	}
	if (unlikely(memcmp(readbuf, writebuf, subpgsize))) {
		pr_info("error: verify failed at %#llx\n",
		       (long long)addr);
		pr_info("------------- written----------------\n");
		print_subpage(writebuf);
		pr_info("------------- read ------------------\n");
		print_subpage(readbuf);
		pr_info("-------------------------------------\n");
		errcnt += 1;
	}

	return err;
}
static int nvram_init(void)
{
#ifdef CONFIG_MTD
	struct mtd_info *mtd;
	struct nvram_header header;
	size_t bytes_read;
	int err;

	mtd = get_mtd_device_nm("nvram");
	if (IS_ERR(mtd))
		return -ENODEV;

	err = mtd_read(mtd, 0, sizeof(header), &bytes_read, (uint8_t *)&header);
	if (!err && header.magic == NVRAM_MAGIC &&
	    header.len > sizeof(header)) {
		nvram_len = header.len;
		if (nvram_len >= NVRAM_SPACE) {
			pr_err("nvram on flash (%i bytes) is bigger than the reserved space in memory, will just copy the first %i bytes\n",
				header.len, NVRAM_SPACE);
			nvram_len = NVRAM_SPACE - 1;
		}

		err = mtd_read(mtd, 0, nvram_len, &nvram_len,
			       (u8 *)nvram_buf);
		return err;
	}
#endif

	return -ENXIO;
}
int mtd_torture(const struct mtd_dev_info *mtd, int fd, int eb)
{
	int err, i, patt_count;
	void *buf;

	normsg("run torture test for PEB %d", eb);
	patt_count = ARRAY_SIZE(patterns);

	buf = malloc(mtd->eb_size);
	if (!buf) {
		errmsg("cannot allocate %d bytes of memory", mtd->eb_size);
		return -1;
	}

	for (i = 0; i < patt_count; i++) {
		err = mtd_erase(mtd, fd, eb);
		if (err)
			goto out;

		/* Make sure the PEB contains only 0xFF bytes */
		err = mtd_read(mtd, fd, eb, 0, buf, mtd->eb_size);
		if (err)
			goto out;

		err = check_pattern(buf, 0xFF, mtd->eb_size);
		if (err == 0) {
			errmsg("erased PEB %d, but a non-0xFF byte found", eb);
			errno = EIO;
			goto out;
		}

		/* Write a pattern and check it */
		memset(buf, patterns[i], mtd->eb_size);
		err = mtd_write(mtd, fd, eb, 0, buf, mtd->eb_size);
		if (err)
			goto out;

		memset(buf, ~patterns[i], mtd->eb_size);
		err = mtd_read(mtd, fd, eb, 0, buf, mtd->eb_size);
		if (err)
			goto out;

		err = check_pattern(buf, patterns[i], mtd->eb_size);
		if (err == 0) {
			errmsg("pattern %x checking failed for PEB %d",
				patterns[i], eb);
			errno = EIO;
			goto out;
		}
	}

	err = 0;
	normsg("PEB %d passed torture test, do not mark it a bad", eb);

out:
	free(buf);
	return -1;
}
Beispiel #4
0
int syscfg_setup()
{
	int i;
	SCfgEntry curEntry;
	uint32_t cursor;

	mtd_t *dev = syscfg_device();
	if(!dev)
		return -1;

	mtd_prepare(dev);
	mtd_read(dev, &header, SCFG_LOCATION, sizeof(header));
	if(header.magic != SCFG_MAGIC)
	{
		mtd_finish(dev);
		bufferPrintf("syscfg: cannot find readable syscfg partition!\r\n");
		return -1;
	}

	bufferPrintf("syscfg: found version 0x%08x with %d entries using %d of %d bytes\r\n", header.version, header.entries, header.bytes_used, header.bytes_total);

	entries = (OIBSyscfgEntry*) malloc(sizeof(OIBSyscfgEntry) * header.entries);

	cursor = SCFG_LOCATION + sizeof(header);
	for(i = 0; i < header.entries; ++i)
	{
		mtd_read(dev, &curEntry, cursor, sizeof(curEntry));

		if(curEntry.magic != CNTB_MAGIC)
		{
			entries[i].type = curEntry.magic;
			entries[i].size = 16;
			entries[i].data = (uint8_t*) malloc(16);
			memcpy(entries[i].data, curEntry.data, 16);
		} else
		{
			entries[i].type = curEntry.cntb.type;
			entries[i].size = curEntry.cntb.size;
			entries[i].data = (uint8_t*) malloc(curEntry.cntb.size);
			mtd_read(dev, entries[i].data, SCFG_LOCATION + curEntry.cntb.offset, curEntry.cntb.size);
		}

		cursor += sizeof(curEntry);
	}

	mtd_finish(dev);

	return 0;
}
Beispiel #5
0
static int read_eraseblock_by_page(int ebnum)
{
	unsigned char *buf = iobuf, *oobbuf = iobuf1;
	uint64_t addr = ((uint64_t)ebnum) * ((uint64_t)mtd.eb_size);
	int i, ret;

	for (i = 0; i < pgcnt; ++i) {
		memset(buf, 0, pgsize);
		ret = mtd_read(&mtd, fd, ebnum, i*pgsize, buf, pgsize);
		if (ret) {
			fprintf(stderr, "Error reading block %d, page %d\n", ebnum, i);
			return -1;
		}
		if (mtd.oob_size) {
			ret = mtd_read_oob(mtd_desc, &mtd, fd,
							addr, mtd.oob_size, oobbuf);

			if (ret) {
				fprintf(stderr, "Error reading OOB in block %d, page %d\n",
						ebnum, i);
				return -1;
			}
			oobbuf += mtd.oob_size;
		}
		buf += pgsize;
		addr += pgsize;
	}

	if (flags & FLAG_VERBOSE)
		printf("Successfully read erase block %d\n", ebnum);

	return 0;
}
/**
 * ubi_dump_flash - dump a region of flash.
 * @ubi: UBI device description object
 * @pnum: the physical eraseblock number to dump
 * @offset: the starting offset within the physical eraseblock to dump
 * @len: the length of the region to dump
 */
void ubi_dump_flash(struct ubi_device *ubi, int pnum, int offset, int len)
{
	int err;
	size_t read;
	void *buf;
	loff_t addr = (loff_t)pnum * ubi->peb_size + offset;

	buf = vmalloc(len);
	if (!buf)
		return;
	err = mtd_read(ubi->mtd, addr, len, &read, buf);
	if (err && err != -EUCLEAN) {
		ubi_err(ubi->ubi_num,
		"err %d while reading %d bytes from PEB %d:%d, read %zd bytes",
			err, len, pnum, offset, read);
		goto out;
	}
	if (ubi->lookuptbl) {
		if (ubi->lookuptbl[pnum]->rc < UBI_MAX_READCOUNTER)
			ubi->lookuptbl[pnum]->rc++;
		else
			ubi_err(ubi->ubi_num,
				"read counter overflow at PEB %d, RC %d",
					pnum, ubi->lookuptbl[pnum]->rc);
	} else
		ubi_err(ubi->ubi_num, "Can't update RC. No lookuptbl");

	ubi_msg(ubi->ubi_num, "dumping %d bytes of data from PEB %d, offset %d",
		len, pnum, offset);
	print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 32, 1, buf, len, 1);
out:
	vfree(buf);
	return;
}
static int read_eraseblock_by_page(int ebnum)
{
	size_t read;
	int i, err = 0;
	loff_t addr = ebnum * mtd->erasesize;
	void *buf = iobuf;

	for (i = 0; i < pgcnt; i++) {
		err = mtd_read(mtd, addr, pgsize, &read, buf);
		/* Ignore corrected ECC errors */
		if (mtd_is_bitflip(err))
			err = 0;
		if (err || read != pgsize) {
			printk(PRINT_PREF "error: read failed at %#llx\n",
			       addr);
			if (!err)
				err = -EINVAL;
			break;
		}
		addr += pgsize;
		buf += pgsize;
	}

	return err;
}
Beispiel #8
0
int mtd_check_rootfs_magic(struct mtd_info *mtd, size_t offset,
                           enum mtdsplit_part_type *type)
{
    u32 magic;
    size_t retlen;
    int ret;

    ret = mtd_read(mtd, offset, sizeof(magic), &retlen,
                   (unsigned char *) &magic);
    if (ret)
        return ret;

    if (retlen != sizeof(magic))
        return -EIO;

    if (le32_to_cpu(magic) == SQUASHFS_MAGIC) {
        if (type)
            *type = MTDSPLIT_PART_TYPE_SQUASHFS;
        return 0;
    } else if (magic == 0x19852003) {
        if (type)
            *type = MTDSPLIT_PART_TYPE_JFFS2;
        return 0;
    } else if (be32_to_cpu(magic) == UBI_EC_MAGIC) {
        if (type)
            *type = MTDSPLIT_PART_TYPE_UBI;
        return 0;
    }

    return -EINVAL;
}
Beispiel #9
0
static int qihoo_init_wmac(void)
{
	struct mtd_info * mtd;
	size_t nb = 0;
	u8 *art;
	int ret;

	if (!qihoo_c301_board)
		return 0;

	mtd = get_mtd_device_nm("radiocfg");
	if (IS_ERR(mtd))
		return PTR_ERR(mtd);

	if (mtd->size != 0x10000)
		return -1;

	art = kzalloc(0x1000, GFP_KERNEL);
	if (!art)
		return -1;

	ret = mtd_read(mtd, QIHOO_C301_WMAC_CALDATA_OFFSET, 0x1000, &nb, art);
	if (nb != 0x1000)
	{
		kfree(art);
		return ret;
	}

	ath79_register_wmac(art, wlan24mac);

	return 0;
}
Beispiel #10
0
int mtd_get_squashfs_len(struct mtd_info *master,
                         size_t offset,
                         size_t *squashfs_len)
{
    struct squashfs_super_block sb;
    size_t retlen;
    int err;

    err = mtd_read(master, offset, sizeof(sb), &retlen, (void *)&sb);
    if (err || (retlen != sizeof(sb))) {
        pr_alert("error occured while reading from \"%s\"\n",
                 master->name);
        return -EIO;
    }

    if (le32_to_cpu(sb.s_magic) != SQUASHFS_MAGIC) {
        pr_alert("no squashfs found in \"%s\"\n", master->name);
        return -EINVAL;
    }

    retlen = le64_to_cpu(sb.bytes_used);
    if (retlen <= 0) {
        pr_alert("squashfs is empty in \"%s\"\n", master->name);
        return -ENODEV;
    }

    if (offset + retlen > master->size) {
        pr_alert("squashfs has invalid size in \"%s\"\n",
                 master->name);
        return -EINVAL;
    }

    *squashfs_len = retlen;
    return 0;
}
Beispiel #11
0
void env_relocate_spec(void)
{
	struct mtd_info *mtd = &onenand_mtd;
#ifdef CONFIG_ENV_ADDR_FLEX
	struct onenand_chip *this = &onenand_chip;
#endif
	int rc;
	size_t retlen;
#ifdef ENV_IS_EMBEDDED
	char *buf = (char *)&environment;
#else
	loff_t env_addr = CONFIG_ENV_ADDR;
	char onenand_env[ONENAND_MAX_ENV_SIZE];
	char *buf = (char *)&onenand_env[0];
#endif /* ENV_IS_EMBEDDED */

#ifndef ENV_IS_EMBEDDED
# ifdef CONFIG_ENV_ADDR_FLEX
	if (FLEXONENAND(this))
		env_addr = CONFIG_ENV_ADDR_FLEX;
# endif
	/* Check OneNAND exist */
	if (mtd->writesize)
		/* Ignore read fail */
		mtd_read(mtd, env_addr, ONENAND_MAX_ENV_SIZE,
				&retlen, (u_char *)buf);
	else
		mtd->writesize = MAX_ONENAND_PAGESIZE;
#endif /* !ENV_IS_EMBEDDED */

	rc = env_import(buf, 1);
	if (rc)
		gd->env_valid = 1;
}
static int get_valid_cis_sector(struct mtd_info *mtd)
{
	int ret, k, cis_sector;
	size_t retlen;
	loff_t offset;
	uint8_t *sect_buf;

	cis_sector = -1;

	sect_buf = kmalloc(SECTOR_SIZE, GFP_KERNEL);
	if (!sect_buf)
		goto out;

	for (k = 0, offset = 0; k < 4; k++, offset += mtd->erasesize) {
		if (mtd_block_isbad(mtd, offset)) {
			ret = mtd_read(mtd, offset, SECTOR_SIZE, &retlen,
				       sect_buf);

			
			if (ret < 0 || retlen != SECTOR_SIZE) {
				printk(KERN_WARNING
					"SSFDC_RO:can't read CIS/IDI sector\n");
			} else if (!memcmp(sect_buf, cis_numbers,
					sizeof(cis_numbers))) {
				
				cis_sector = (int)(offset >> SECTOR_SHIFT);
			} else {
				pr_debug("SSFDC_RO: CIS/IDI sector not found"
					" on %s (mtd%d)\n", mtd->name,
					mtd->index);
			}
			break;
		}
Beispiel #13
0
static int verify_eraseblock2(int ebnum)
{
	size_t read;
	int err = 0, k;
	loff_t addr = ebnum * mtd->erasesize;

	for (k = 1; k < 33; ++k) {
		if (addr + (subpgsize * k) > (ebnum + 1) * mtd->erasesize)
			break;
		prandom_bytes_state(&rnd_state, writebuf, subpgsize * k);
		clear_data(readbuf, subpgsize * k);
		err = mtd_read(mtd, addr, subpgsize * k, &read, readbuf);
		if (unlikely(err || read != subpgsize * k)) {
			if (mtd_is_bitflip(err) && read == subpgsize * k) {
				pr_info("ECC correction at %#llx\n",
				       (long long)addr);
				err = 0;
			} else {
				pr_err("error: read failed at "
				       "%#llx\n", (long long)addr);
				return err ? err : -1;
			}
		}
		if (unlikely(memcmp(readbuf, writebuf, subpgsize * k))) {
			pr_err("error: verify failed at %#llx\n",
			       (long long)addr);
			errcnt += 1;
		}
		addr += subpgsize * k;
	}

	return err;
}
static int erasetest(void)
{
	size_t read, written;
	int err = 0, i, ebnum, ok = 1;
	loff_t addr0;

	printk(PRINT_PREF "erasetest\n");

	ebnum = 0;
	addr0 = 0;
	for (i = 0; i < ebcnt && bbt[i]; ++i) {
		addr0 += mtd->erasesize;
		ebnum += 1;
	}

	printk(PRINT_PREF "erasing block %d\n", ebnum);
	err = erase_eraseblock(ebnum);
	if (err)
		return err;

	printk(PRINT_PREF "writing 1st page of block %d\n", ebnum);
	set_random_data(writebuf, pgsize);
	err = mtd_write(mtd, addr0, pgsize, &written, writebuf);
	if (err || written != pgsize) {
		printk(PRINT_PREF "error: write failed at %#llx\n",
		       (long long)addr0);
		return err ? err : -1;
	}

	printk(PRINT_PREF "erasing block %d\n", ebnum);
	err = erase_eraseblock(ebnum);
	if (err)
		return err;

	printk(PRINT_PREF "reading 1st page of block %d\n", ebnum);
	err = mtd_read(mtd, addr0, pgsize, &read, twopages);
	if (mtd_is_bitflip(err))
		err = 0;
	if (err || read != pgsize) {
		printk(PRINT_PREF "error: read failed at %#llx\n",
		       (long long)addr0);
		return err ? err : -1;
	}

	printk(PRINT_PREF "verifying 1st page of block %d is all 0xff\n",
	       ebnum);
	for (i = 0; i < pgsize; ++i)
		if (twopages[i] != 0xff) {
			printk(PRINT_PREF "verifying all 0xff failed at %d\n",
			       i);
			errcnt += 1;
			ok = 0;
			break;
		}

	if (ok && !err)
		printk(PRINT_PREF "erasetest ok\n");

	return err;
}
Beispiel #15
0
int images_verify(Image* image) {
	uint8_t hash[0x40];
	int retVal = 0;

	if(image == NULL) {
		return 1;
	}

	mtd_t *dev = images_device();
	if(!dev)
	{
		return 1;
	}

	mtd_prepare(dev);

	if(!image->hashMatch)
		retVal |= 1 << 2;

	void* data = malloc(image->padded);
	mtd_read(dev, data, image->offset + sizeof(Img2Header), image->padded);
	calculateDataHash(data, image->padded, hash);
	free(data);

	if(memcmp(hash, image->dataHash, 0x40) != 0)
		retVal |= 1 << 3;

	mtd_finish(dev);

	return retVal;
}
Beispiel #16
0
static int
afs_read_iis_v1(struct mtd_info *mtd, struct image_info_v1 *iis, u_int ptr)
{
	size_t sz;
	int ret, i;

	memset(iis, 0, sizeof(*iis));
	ret = mtd_read(mtd, ptr, sizeof(*iis), &sz, (u_char *)iis);
	if (ret < 0)
		goto failed;

	if (sz != sizeof(*iis)) {
		ret = -EINVAL;
		goto failed;
	}

	ret = 0;

	/*
	 * Validate the name - it must be NUL terminated.
	 */
	for (i = 0; i < sizeof(iis->name); i++)
		if (iis->name[i] == '\0')
			break;

	if (i < sizeof(iis->name))
		ret = 1;

	return ret;

 failed:
	printk(KERN_ERR "AFS: mtd read failed at 0x%x: %d\n",
		ptr, ret);
	return ret;
}
Beispiel #17
0
static int do_read(void)
{
	size_t read;
	int eb = rand_eb();
	int offs = rand_offs();
	int len = rand_len(offs), err;
	loff_t addr;

	if (bbt[eb + 1]) {
		if (offs >= mtd->erasesize)
			offs -= mtd->erasesize;
		if (offs + len > mtd->erasesize)
			len = mtd->erasesize - offs;
	}
	addr = eb * mtd->erasesize + offs;
	err = mtd_read(mtd, addr, len, &read, readbuf);
	if (mtd_is_bitflip(err))
		err = 0;
	if (unlikely(err || read != len)) {
		pr_err("error: read failed at 0x%llx\n",
		       (long long)addr);
		if (!err)
			err = -EINVAL;
		return err;
	}
	return 0;
}
Beispiel #18
0
static int verify_eraseblock_ff(int ebnum)
{
	uint32_t j;
	size_t read;
	int err = 0;
	loff_t addr = ebnum * mtd->erasesize;

	memset(writebuf, 0xff, subpgsize);
	for (j = 0; j < mtd->erasesize / subpgsize; ++j) {
		clear_data(readbuf, subpgsize);
		err = mtd_read(mtd, addr, subpgsize, &read, readbuf);
		if (unlikely(err || read != subpgsize)) {
			if (mtd_is_bitflip(err) && read == subpgsize) {
				pr_info("ECC correction at %#llx\n",
				       (long long)addr);
				err = 0;
			} else {
				pr_err("error: read failed at "
				       "%#llx\n", (long long)addr);
				return err ? err : -1;
			}
		}
		if (unlikely(memcmp(readbuf, writebuf, subpgsize))) {
			pr_err("error: verify 0xff failed at "
			       "%#llx\n", (long long)addr);
			errcnt += 1;
		}
		addr += subpgsize;
	}

	return err;
}
Beispiel #19
0
static int
afs_read_footer(struct mtd_info *mtd, u_int *img_start, u_int *iis_start,
		u_int off, u_int mask)
{
	struct footer_struct fs;
	u_int ptr = off + mtd->erasesize - sizeof(fs);
	size_t sz;
	int ret;

	ret = mtd_read(mtd, ptr, sizeof(fs), &sz, (u_char *)&fs);
	if (ret >= 0 && sz != sizeof(fs))
		ret = -EINVAL;

	if (ret < 0) {
		printk(KERN_ERR "AFS: mtd read failed at 0x%x: %d\n",
			ptr, ret);
		return ret;
	}

	ret = 1;

	/*
	 * Does it contain the magic number?
	 */
	if (fs.signature != 0xa0ffff9f)
		ret = 0;

	/*
	 * Check the checksum.
	 */
	if (word_sum(&fs, sizeof(fs) / sizeof(u32)) != 0xffffffff)
		ret = 0;

	/*
	 * Don't touch the SIB.
	 */
	if (fs.type == 2)
		ret = 0;

	*iis_start = fs.image_info_base & mask;
	*img_start = fs.image_start & mask;

	/*
	 * Check the image info base.  This can not
	 * be located after the footer structure.
	 */
	if (*iis_start >= ptr)
		ret = 0;

	/*
	 * Check the start of this image.  The image
	 * data can not be located after this block.
	 */
	if (*img_start > off)
		ret = 0;

	return ret;
}
Beispiel #20
0
static int do_cached_read (struct mtdblk_dev *mtdblk, unsigned long pos,
			   int len, char *buf)
{
	struct mtd_info *mtd = mtdblk->mbd.mtd;
	unsigned int sect_size = mtdblk->cache_size;
	size_t retlen;
	int ret;

	pr_debug("mtdblock: read on \"%s\" at 0x%lx, size 0x%x\n",
			mtd->name, pos, len);

	if (!sect_size)
		return mtd_read(mtd, pos, len, &retlen, buf);

	while (len > 0) {
		unsigned long sect_start = (pos/sect_size)*sect_size;
		unsigned int offset = pos - sect_start;
		unsigned int size = sect_size - offset;
		if (size > len)
			size = len;

		/*
		 * Check if the requested data is already cached
		 * Read the requested amount of data from our internal cache if it
		 * contains what we want, otherwise we read the data directly
		 * from flash.
		 */
		if (mtdblk->cache_state != STATE_EMPTY &&
		    mtdblk->cache_offset == sect_start) {
			memcpy (buf, mtdblk->cache_data + offset, size);
		} else {
			ret = mtd_read(mtd, pos, size, &retlen, buf);
			if (ret)
				return ret;
			if (retlen != size)
				return -EIO;
		}

		buf += size;
		pos += size;
		len -= size;
	}

	return 0;
}
Beispiel #21
0
void images_write(Image* image, void* data, unsigned int length, int encrypt) {
	bufferPrintf("images_write(%x, %x, %x)\r\n", image, data, length);
	if(image == NULL)
		return;

	mtd_t *dev = images_device();
	if(!dev)
		return;

	mtd_prepare(dev);

	uint32_t padded = length;
	if((length & 0xF) != 0) {
		padded = (padded & ~0xF) + 0x10;
	}

	if(image->next != NULL && (image->offset + sizeof(Img2Header) + padded) >= image->next->offset) {
		bufferPrintf("**ABORTED** requested length greater than available space.\r\n");
		return;
	}

	uint32_t totalLen = sizeof(Img2Header) + padded;
	uint8_t* writeBuffer = (uint8_t*) malloc(totalLen);

	mtd_read(dev, writeBuffer, image->offset, sizeof(Img2Header));

	memcpy(writeBuffer + sizeof(Img2Header), data, length);

	if(encrypt)
		aes_838_encrypt(writeBuffer + sizeof(Img2Header), padded, NULL);

	Img2Header* header = (Img2Header*) writeBuffer;
	header->dataLen = length;
	header->dataLenPadded = padded;

	calculateDataHash(writeBuffer + sizeof(Img2Header), padded, header->dataHash);

	uint32_t checksum = 0;
	crc32(&checksum, writeBuffer, 0x64);
	header->header_checksum = checksum;

	calculateHash(header, header->hash);

	bufferPrintf("mtd_write(0x%p, %x, %x, %x)\r\n", dev, writeBuffer, image->offset, totalLen);

	mtd_write(dev, writeBuffer, image->offset, totalLen);

	bufferPrintf("mtd_write(0x%p, %x, %x, %x) done\r\n", dev, writeBuffer, image->offset, totalLen);

	free(writeBuffer);

	mtd_finish(dev);

	images_release();
	images_setup();

}
Beispiel #22
0
static int
concat_read(struct mtd_info *mtd, loff_t from, size_t len,
	    size_t * retlen, u_char * buf)
{
	struct mtd_concat *concat = CONCAT(mtd);
	int ret = 0, err;
	int i;

#ifdef __UBOOT__
	*retlen = 0;
#endif

	for (i = 0; i < concat->num_subdev; i++) {
		struct mtd_info *subdev = concat->subdev[i];
		size_t size, retsize;

		if (from >= subdev->size) {
			/* Not destined for this subdev */
			size = 0;
			from -= subdev->size;
			continue;
		}
		if (from + len > subdev->size)
			/* First part goes into this subdev */
			size = subdev->size - from;
		else
			/* Entire transaction goes into this subdev */
			size = len;

		err = mtd_read(subdev, from, size, &retsize, buf);

		/* Save information about bitflips! */
		if (unlikely(err)) {
			if (mtd_is_eccerr(err)) {
				mtd->ecc_stats.failed++;
				ret = err;
			} else if (mtd_is_bitflip(err)) {
				mtd->ecc_stats.corrected++;
				/* Do not overwrite -EBADMSG !! */
				if (!ret)
					ret = err;
			} else
				return err;
		}

		*retlen += retsize;
		len -= size;
		if (len == 0)
			return ret;

		buf += size;
		from = 0;
	}
	return -EINVAL;
}
Beispiel #23
0
static void find_next_position(struct mtdoops_context *cxt)
{
	struct mtd_info *mtd = cxt->mtd;
	int ret, page, maxpos = 0;
	u32 count[2], maxcount = 0xffffffff;
	size_t retlen;

	for (page = 0; page < cxt->oops_pages; page++) {
		if (mtd_can_have_bb(mtd) &&
		    mtd_block_isbad(mtd, page * record_size))
			continue;
		/* Assume the page is used */
		mark_page_used(cxt, page);
		ret = mtd_read(mtd, page * record_size, MTDOOPS_HEADER_SIZE,
			       &retlen, (u_char *)&count[0]);
		if (retlen != MTDOOPS_HEADER_SIZE ||
				(ret < 0 && !mtd_is_bitflip(ret))) {
			printk(KERN_ERR "mtdoops: read failure at %ld (%td of %d read), err %d\n",
			       page * record_size, retlen,
			       MTDOOPS_HEADER_SIZE, ret);
			continue;
		}

		if (count[0] == 0xffffffff && count[1] == 0xffffffff)
			mark_page_unused(cxt, page);
		if (count[0] == 0xffffffff)
			continue;
		if (maxcount == 0xffffffff) {
			maxcount = count[0];
			maxpos = page;
		} else if (count[0] < 0x40000000 && maxcount > 0xc0000000) {
			maxcount = count[0];
			maxpos = page;
		} else if (count[0] > maxcount && count[0] < 0xc0000000) {
			maxcount = count[0];
			maxpos = page;
		} else if (count[0] > maxcount && count[0] > 0xc0000000
					&& maxcount > 0x80000000) {
			maxcount = count[0];
			maxpos = page;
		}
	}
	if (maxcount == 0xffffffff) {
		cxt->nextpage = 0;
		cxt->nextcount = 1;
		schedule_work(&cxt->work_erase);
		return;
	}

	cxt->nextpage = maxpos;
	cxt->nextcount = maxcount;

	mtdoops_inc_counter(cxt);
}
Beispiel #24
0
static int
mt76_get_of_eeprom(struct mt76_dev *dev, int len)
{
#ifdef CONFIG_OF
	struct device_node *np = dev->dev->of_node;
	struct mtd_info *mtd;
	const __be32 *list;
	const char *part;
	phandle phandle;
	int offset = 0;
	int size;
	size_t retlen;
	int ret;

	if (!np)
		return -ENOENT;

	list = of_get_property(np, "mediatek,mtd-eeprom", &size);
	if (!list)
		return -ENOENT;

	phandle = be32_to_cpup(list++);
	if (!phandle)
		return -ENOENT;

	np = of_find_node_by_phandle(phandle);
	if (!np)
		return -EINVAL;

	part = of_get_property(np, "label", NULL);
	if (!part)
		part = np->name;

	mtd = get_mtd_device_nm(part);
	if (IS_ERR(mtd))
		return PTR_ERR(mtd);

	if (size <= sizeof(*list))
		return -EINVAL;

	offset = be32_to_cpup(list);
	ret = mtd_read(mtd, offset, len, &retlen, dev->eeprom.data);
	put_mtd_device(mtd);
	if (ret)
		return ret;

	if (retlen < len)
		return -EINVAL;

	return 0;
#else
	return -ENOENT;
#endif
}
Beispiel #25
0
/**
 * self_check_write - make sure write succeeded.
 * @ubi: UBI device description object
 * @buf: buffer with data which were written
 * @pnum: physical eraseblock number the data were written to
 * @offset: offset within the physical eraseblock the data were written to
 * @len: how many bytes were written
 *
 * This functions reads data which were recently written and compares it with
 * the original data buffer - the data have to match. Returns zero if the data
 * match and a negative error code if not or in case of failure.
 */
static int self_check_write(struct ubi_device *ubi, const void *buf, int pnum,
			    int offset, int len)
{
	int err, i;
	size_t read;
	void *buf1;
	loff_t addr = (loff_t)pnum * ubi->peb_size + offset;

	if (!ubi_dbg_chk_io(ubi))
		return 0;

	buf1 = __vmalloc(len, GFP_NOFS, PAGE_KERNEL);
	if (!buf1) {
		ubi_err("cannot allocate memory to check writes");
		return 0;
	}

	err = mtd_read(ubi->mtd, addr, len, &read, buf1);
	if (err && !mtd_is_bitflip(err))
		goto out_free;

	for (i = 0; i < len; i++) {
		uint8_t c = ((uint8_t *)buf)[i];
		uint8_t c1 = ((uint8_t *)buf1)[i];
#if !defined(CONFIG_UBI_SILENCE_MSG)
		int dump_len = max_t(int, 128, len - i);
#endif

		if (c == c1)
			continue;

		ubi_err("self-check failed for PEB %d:%d, len %d",
			pnum, offset, len);
		ubi_msg("data differ at position %d", i);
		ubi_msg("hex dump of the original buffer from %d to %d",
			i, i + dump_len);
		print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 32, 1,
			       buf + i, dump_len, 1);
		ubi_msg("hex dump of the read buffer from %d to %d",
			i, i + dump_len);
		print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 32, 1,
			       buf1 + i, dump_len, 1);
		dump_stack();
		err = -EINVAL;
		goto out_free;
	}

	vfree(buf1);
	return 0;

out_free:
	vfree(buf1);
	return err;
}
/*
 * Check that the contents of eraseblock number @enbum is equivalent to the
 * @buf buffer.
 */
static inline int check_eraseblock(int ebnum, unsigned char *buf)
{
	int err, retries = 0;
	size_t read;
	loff_t addr = ebnum * mtd->erasesize;
	size_t len = mtd->erasesize;

	if (pgcnt) {
		addr = (ebnum + 1) * mtd->erasesize - pgcnt * pgsize;
		len = pgcnt * pgsize;
	}

retry:
	err = mtd_read(mtd, addr, len, &read, check_buf);
	if (mtd_is_bitflip(err))
		pr_err("single bit flip occurred at EB %d "
		       "MTD reported that it was fixed.\n", ebnum);
	else if (err) {
		pr_err("error %d while reading EB %d, "
		       "read %zd\n", err, ebnum, read);
		return err;
	}

	if (read != len) {
		pr_err("failed to read %zd bytes from EB %d, "
		       "read only %zd, but no error reported\n",
		       len, ebnum, read);
		return -EIO;
	}

	if (memcmp(buf, check_buf, len)) {
		pr_err("read wrong data from EB %d\n", ebnum);
		report_corrupt(check_buf, buf);

		if (retries++ < RETRIES) {
			/* Try read again */
			yield();
			pr_info("re-try reading data from EB %d\n",
			       ebnum);
			goto retry;
		} else {
			pr_info("retried %d times, still errors, "
			       "give-up\n", RETRIES);
			return -EINVAL;
		}
	}

	if (retries != 0)
		pr_info("only attempt number %d was OK (!!!)\n",
		       retries);

	return 0;
}
Beispiel #27
0
static void da850_evm_m25p80_notify_add(struct mtd_info *mtd)
{
	char *mac_addr = davinci_soc_info.emac_pdata->mac_addr;
	size_t retlen;

	if (!strcmp(mtd->name, "MAC-Address")) {
		mtd_read(mtd, 0, ETH_ALEN, &retlen, mac_addr);
		if (retlen == ETH_ALEN)
			pr_info("Read MAC addr from SPI Flash: %pM\n",
				mac_addr);
	}
}
Beispiel #28
0
static int mtdsplit_parse_wrgg(struct mtd_info *master,
				struct mtd_partition **pparts,
				struct mtd_part_parser_data *data)
{
	struct wrgg03_header hdr;
	size_t hdr_len, retlen, kernel_ent_size;
	size_t rootfs_offset;
	struct mtd_partition *parts;
	enum mtdsplit_part_type type;
	int err;

	hdr_len = sizeof(hdr);
	err = mtd_read(master, 0, hdr_len, &retlen, (void *) &hdr);
	if (err)
		return err;

	if (retlen != hdr_len)
		return -EIO;

	/* sanity checks */
	if (le32_to_cpu(hdr.magic1) != WRGG03_MAGIC)
		return -EINVAL;

	kernel_ent_size = hdr_len + be32_to_cpu(hdr.size);

	if (kernel_ent_size > master->size)
		return -EINVAL;

	/*
	 * The size in the header covers the rootfs as well.
	 * Start the search from an arbitrary offset.
	 */
	err = mtd_find_rootfs_from(master, WRGG_MIN_ROOTFS_OFFS,
				   master->size, &rootfs_offset, &type);
	if (err)
		return err;

	parts = kzalloc(WRGG_NR_PARTS * sizeof(*parts), GFP_KERNEL);
	if (!parts)
		return -ENOMEM;

	parts[0].name = KERNEL_PART_NAME;
	parts[0].offset = 0;
	parts[0].size = rootfs_offset;

	parts[1].name = ROOTFS_PART_NAME;
	parts[1].offset = rootfs_offset;
	parts[1].size = master->size - rootfs_offset;

	*pparts = parts;
	return WRGG_NR_PARTS;
}
static int rt2800lib_read_eeprom_mtd(struct rt2x00_dev *rt2x00dev)
{
	int ret = -EINVAL;
#ifdef CONFIG_OF
	static struct firmware mtd_fw;
	struct device_node *np = rt2x00dev->dev->of_node, *mtd_np = NULL;
	size_t retlen, len = rt2x00dev->ops->eeprom_size;
	int size, offset = 0;
	struct mtd_info *mtd;
	const char *part;
	const __be32 *list;
	phandle phandle;

	list = of_get_property(np, "ralink,mtd-eeprom", &size);
	if (!list) {
		dev_err(rt2x00dev->dev, "failed to load eeprom property\n");
		return -ENOENT;
	}

	phandle = be32_to_cpup(list++);
	if (phandle)
		mtd_np = of_find_node_by_phandle(phandle);
	if (!mtd_np) {
		dev_err(rt2x00dev->dev, "failed to load mtd phandle\n");
		return -EINVAL;
	}

	part = of_get_property(mtd_np, "label", NULL);
	if (!part)
		part = mtd_np->name;

	mtd = get_mtd_device_nm(part);
	if (IS_ERR(mtd)) {
		dev_err(rt2x00dev->dev, "failed to get mtd device \"%s\"\n", part);
		return PTR_ERR(mtd);
	}

	if (size > sizeof(*list))
		offset = be32_to_cpup(list);

	ret = mtd_read(mtd, offset, len, &retlen, (u_char *) rt2x00dev->eeprom);
	put_mtd_device(mtd);

	if (!ret) {
		rt2x00dev->eeprom_file = &mtd_fw;
		mtd_fw.size = len;
		mtd_fw.data = (const u8 *) rt2x00dev->eeprom;
	}
#endif

	return ret;
}
Beispiel #30
0
static int mtdsplit_parse_lzma(struct mtd_info *master,
			       const struct mtd_partition **pparts,
			       struct mtd_part_parser_data *data)
{
	struct lzma_header hdr;
	size_t hdr_len, retlen;
	size_t rootfs_offset;
	u32 t;
	struct mtd_partition *parts;
	int err;

	hdr_len = sizeof(hdr);
	err = mtd_read(master, 0, hdr_len, &retlen, (void *) &hdr);
	if (err)
		return err;

	if (retlen != hdr_len)
		return -EIO;

	/* verify LZMA properties */
	if (hdr.props[0] >= (9 * 5 * 5))
		return -EINVAL;

	t = get_unaligned_le32(&hdr.props[1]);
	if (!is_power_of_2(t))
		return -EINVAL;

	t = get_unaligned_le32(&hdr.size_high);
	if (t)
		return -EINVAL;

	err = mtd_find_rootfs_from(master, master->erasesize, master->size,
				   &rootfs_offset, NULL);
	if (err)
		return err;

	parts = kzalloc(LZMA_NR_PARTS * sizeof(*parts), GFP_KERNEL);
	if (!parts)
		return -ENOMEM;

	parts[0].name = KERNEL_PART_NAME;
	parts[0].offset = 0;
	parts[0].size = rootfs_offset;

	parts[1].name = ROOTFS_PART_NAME;
	parts[1].offset = rootfs_offset;
	parts[1].size = master->size - rootfs_offset;

	*pparts = parts;
	return LZMA_NR_PARTS;
}