⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 io.c

📁 uboot200903最新版本的通用uboot
💻 C
📖 第 1 页 / 共 3 页
字号:
		}	} else {		if (copy_flag == 0) {			if (data_crc != 0) {				dbg_err("non-zero data CRC");				goto bad;			}			if (data_size != 0) {				dbg_err("non-zero data_size");				goto bad;			}		} else {			if (data_size == 0) {				dbg_err("zero data_size of copy");				goto bad;			}		}		if (used_ebs != 0) {			dbg_err("bad used_ebs");			goto bad;		}	}	return 0;bad:	ubi_err("bad VID header");	ubi_dbg_dump_vid_hdr(vid_hdr);	ubi_dbg_dump_stack();	return 1;}/** * ubi_io_read_vid_hdr - read and check a volume identifier header. * @ubi: UBI device description object * @pnum: physical eraseblock number to read from * @vid_hdr: &struct ubi_vid_hdr object where to store the read volume * identifier header * @verbose: be verbose if the header is corrupted or wasn't found * * This function reads the volume identifier header from physical eraseblock * @pnum and stores it in @vid_hdr. It also checks CRC checksum of the read * volume identifier header. The following codes may be returned: * * o %0 if the CRC checksum is correct and the header was successfully read; * o %UBI_IO_BITFLIPS if the CRC is correct, but bit-flips were detected *   and corrected by the flash driver; this is harmless but may indicate that *   this eraseblock may become bad soon; * o %UBI_IO_BAD_VID_HRD if the volume identifier header is corrupted (a CRC *   error detected); * o %UBI_IO_PEB_FREE if the physical eraseblock is free (i.e., there is no VID *   header there); * o a negative error code in case of failure. */int ubi_io_read_vid_hdr(struct ubi_device *ubi, int pnum,			struct ubi_vid_hdr *vid_hdr, int verbose){	int err, read_err = 0;	uint32_t crc, magic, hdr_crc;	void *p;	dbg_io("read VID header from PEB %d", pnum);	ubi_assert(pnum >= 0 &&  pnum < ubi->peb_count);	if (UBI_IO_DEBUG)		verbose = 1;	p = (char *)vid_hdr - ubi->vid_hdr_shift;	err = ubi_io_read(ubi, p, pnum, ubi->vid_hdr_aloffset,			  ubi->vid_hdr_alsize);	if (err) {		if (err != UBI_IO_BITFLIPS && err != -EBADMSG)			return err;		/*		 * We read all the data, but either a correctable bit-flip		 * occurred, or MTD reported about some data integrity error,		 * like an ECC error in case of NAND. The former is harmless,		 * the later may mean the read data is corrupted. But we have a		 * CRC check-sum and we will identify this. If the VID header is		 * still OK, we just report this as there was a bit-flip.		 */		read_err = err;	}	magic = be32_to_cpu(vid_hdr->magic);	if (magic != UBI_VID_HDR_MAGIC) {		/*		 * If we have read all 0xFF bytes, the VID header probably does		 * not exist and the physical eraseblock is assumed to be free.		 *		 * But if there was a read error, we do not test the data for		 * 0xFFs. Even if it does contain all 0xFFs, this error		 * indicates that something is still wrong with this physical		 * eraseblock and it cannot be regarded as free.		 */		if (read_err != -EBADMSG &&		    check_pattern(vid_hdr, 0xFF, UBI_VID_HDR_SIZE)) {			/* The physical eraseblock is supposedly free */			/*			 * The below is just a paranoid check, it has to be			 * compiled out if paranoid checks are disabled.			 */			err = paranoid_check_all_ff(ubi, pnum, ubi->leb_start,						    ubi->leb_size);			if (err)				return err > 0 ? UBI_IO_BAD_VID_HDR : err;			if (verbose)				ubi_warn("no VID header found at PEB %d, "					 "only 0xFF bytes", pnum);			return UBI_IO_PEB_FREE;		}		/*		 * This is not a valid VID header, and these are not 0xFF		 * bytes. Report that the header is corrupted.		 */		if (verbose) {			ubi_warn("bad magic number at PEB %d: %08x instead of "				 "%08x", pnum, magic, UBI_VID_HDR_MAGIC);			ubi_dbg_dump_vid_hdr(vid_hdr);		}		return UBI_IO_BAD_VID_HDR;	}	crc = crc32(UBI_CRC32_INIT, vid_hdr, UBI_VID_HDR_SIZE_CRC);	hdr_crc = be32_to_cpu(vid_hdr->hdr_crc);	if (hdr_crc != crc) {		if (verbose) {			ubi_warn("bad CRC at PEB %d, calculated %#08x, "				 "read %#08x", pnum, crc, hdr_crc);			ubi_dbg_dump_vid_hdr(vid_hdr);		}		return UBI_IO_BAD_VID_HDR;	}	/* Validate the VID header that we have just read */	err = validate_vid_hdr(ubi, vid_hdr);	if (err) {		ubi_err("validation failed for PEB %d", pnum);		return -EINVAL;	}	return read_err ? UBI_IO_BITFLIPS : 0;}/** * ubi_io_write_vid_hdr - write a volume identifier header. * @ubi: UBI device description object * @pnum: the physical eraseblock number to write to * @vid_hdr: the volume identifier header to write * * This function writes the volume identifier header described by @vid_hdr to * physical eraseblock @pnum. This function automatically fills the * @vid_hdr->magic and the @vid_hdr->version fields, as well as calculates * header CRC checksum and stores it at vid_hdr->hdr_crc. * * This function returns zero in case of success and a negative error code in * case of failure. If %-EIO is returned, the physical eraseblock probably went * bad. */int ubi_io_write_vid_hdr(struct ubi_device *ubi, int pnum,			 struct ubi_vid_hdr *vid_hdr){	int err;	uint32_t crc;	void *p;	dbg_io("write VID header to PEB %d", pnum);	ubi_assert(pnum >= 0 &&  pnum < ubi->peb_count);	err = paranoid_check_peb_ec_hdr(ubi, pnum);	if (err)		return err > 0 ? -EINVAL: err;	vid_hdr->magic = cpu_to_be32(UBI_VID_HDR_MAGIC);	vid_hdr->version = UBI_VERSION;	crc = crc32(UBI_CRC32_INIT, vid_hdr, UBI_VID_HDR_SIZE_CRC);	vid_hdr->hdr_crc = cpu_to_be32(crc);	err = paranoid_check_vid_hdr(ubi, pnum, vid_hdr);	if (err)		return -EINVAL;	p = (char *)vid_hdr - ubi->vid_hdr_shift;	err = ubi_io_write(ubi, p, pnum, ubi->vid_hdr_aloffset,			   ubi->vid_hdr_alsize);	return err;}#ifdef CONFIG_MTD_UBI_DEBUG_PARANOID/** * paranoid_check_not_bad - ensure that a physical eraseblock is not bad. * @ubi: UBI device description object * @pnum: physical eraseblock number to check * * This function returns zero if the physical eraseblock is good, a positive * number if it is bad and a negative error code if an error occurred. */static int paranoid_check_not_bad(const struct ubi_device *ubi, int pnum){	int err;	err = ubi_io_is_bad(ubi, pnum);	if (!err)		return err;	ubi_err("paranoid check failed for PEB %d", pnum);	ubi_dbg_dump_stack();	return err;}/** * paranoid_check_ec_hdr - check if an erase counter header is all right. * @ubi: UBI device description object * @pnum: physical eraseblock number the erase counter header belongs to * @ec_hdr: the erase counter header to check * * This function returns zero if the erase counter header contains valid * values, and %1 if not. */static int paranoid_check_ec_hdr(const struct ubi_device *ubi, int pnum,				 const struct ubi_ec_hdr *ec_hdr){	int err;	uint32_t magic;	magic = be32_to_cpu(ec_hdr->magic);	if (magic != UBI_EC_HDR_MAGIC) {		ubi_err("bad magic %#08x, must be %#08x",			magic, UBI_EC_HDR_MAGIC);		goto fail;	}	err = validate_ec_hdr(ubi, ec_hdr);	if (err) {		ubi_err("paranoid check failed for PEB %d", pnum);		goto fail;	}	return 0;fail:	ubi_dbg_dump_ec_hdr(ec_hdr);	ubi_dbg_dump_stack();	return 1;}/** * paranoid_check_peb_ec_hdr - check that the erase counter header of a * physical eraseblock is in-place and is all right. * @ubi: UBI device description object * @pnum: the physical eraseblock number to check * * This function returns zero if the erase counter header is all right, %1 if * not, and a negative error code if an error occurred. */static int paranoid_check_peb_ec_hdr(const struct ubi_device *ubi, int pnum){	int err;	uint32_t crc, hdr_crc;	struct ubi_ec_hdr *ec_hdr;	ec_hdr = kzalloc(ubi->ec_hdr_alsize, GFP_NOFS);	if (!ec_hdr)		return -ENOMEM;	err = ubi_io_read(ubi, ec_hdr, pnum, 0, UBI_EC_HDR_SIZE);	if (err && err != UBI_IO_BITFLIPS && err != -EBADMSG)		goto exit;	crc = crc32(UBI_CRC32_INIT, ec_hdr, UBI_EC_HDR_SIZE_CRC);	hdr_crc = be32_to_cpu(ec_hdr->hdr_crc);	if (hdr_crc != crc) {		ubi_err("bad CRC, calculated %#08x, read %#08x", crc, hdr_crc);		ubi_err("paranoid check failed for PEB %d", pnum);		ubi_dbg_dump_ec_hdr(ec_hdr);		ubi_dbg_dump_stack();		err = 1;		goto exit;	}	err = paranoid_check_ec_hdr(ubi, pnum, ec_hdr);exit:	kfree(ec_hdr);	return err;}/** * paranoid_check_vid_hdr - check that a volume identifier header is all right. * @ubi: UBI device description object * @pnum: physical eraseblock number the volume identifier header belongs to * @vid_hdr: the volume identifier header to check * * This function returns zero if the volume identifier header is all right, and * %1 if not. */static int paranoid_check_vid_hdr(const struct ubi_device *ubi, int pnum,				  const struct ubi_vid_hdr *vid_hdr){	int err;	uint32_t magic;	magic = be32_to_cpu(vid_hdr->magic);	if (magic != UBI_VID_HDR_MAGIC) {		ubi_err("bad VID header magic %#08x at PEB %d, must be %#08x",			magic, pnum, UBI_VID_HDR_MAGIC);		goto fail;	}	err = validate_vid_hdr(ubi, vid_hdr);	if (err) {		ubi_err("paranoid check failed for PEB %d", pnum);		goto fail;	}	return err;fail:	ubi_err("paranoid check failed for PEB %d", pnum);	ubi_dbg_dump_vid_hdr(vid_hdr);	ubi_dbg_dump_stack();	return 1;}/** * paranoid_check_peb_vid_hdr - check that the volume identifier header of a * physical eraseblock is in-place and is all right. * @ubi: UBI device description object * @pnum: the physical eraseblock number to check * * This function returns zero if the volume identifier header is all right, * %1 if not, and a negative error code if an error occurred. */static int paranoid_check_peb_vid_hdr(const struct ubi_device *ubi, int pnum){	int err;	uint32_t crc, hdr_crc;	struct ubi_vid_hdr *vid_hdr;	void *p;	vid_hdr = ubi_zalloc_vid_hdr(ubi, GFP_NOFS);	if (!vid_hdr)		return -ENOMEM;	p = (char *)vid_hdr - ubi->vid_hdr_shift;	err = ubi_io_read(ubi, p, pnum, ubi->vid_hdr_aloffset,			  ubi->vid_hdr_alsize);	if (err && err != UBI_IO_BITFLIPS && err != -EBADMSG)		goto exit;	crc = crc32(UBI_CRC32_INIT, vid_hdr, UBI_EC_HDR_SIZE_CRC);	hdr_crc = be32_to_cpu(vid_hdr->hdr_crc);	if (hdr_crc != crc) {		ubi_err("bad VID header CRC at PEB %d, calculated %#08x, "			"read %#08x", pnum, crc, hdr_crc);		ubi_err("paranoid check failed for PEB %d", pnum);		ubi_dbg_dump_vid_hdr(vid_hdr);		ubi_dbg_dump_stack();		err = 1;		goto exit;	}	err = paranoid_check_vid_hdr(ubi, pnum, vid_hdr);exit:	ubi_free_vid_hdr(ubi, vid_hdr);	return err;}/** * paranoid_check_all_ff - check that a region of flash is empty. * @ubi: UBI device description object * @pnum: the physical eraseblock number to check * @offset: the starting offset within the physical eraseblock to check * @len: the length of the region to check * * This function returns zero if only 0xFF bytes are present at offset * @offset of the physical eraseblock @pnum, %1 if not, and a negative error * code if an error occurred. */static int paranoid_check_all_ff(struct ubi_device *ubi, int pnum, int offset,				 int len){	size_t read;	int err;	loff_t addr = (loff_t)pnum * ubi->peb_size + offset;	mutex_lock(&ubi->dbg_buf_mutex);	err = ubi->mtd->read(ubi->mtd, addr, len, &read, ubi->dbg_peb_buf);	if (err && err != -EUCLEAN) {		ubi_err("error %d while reading %d bytes from PEB %d:%d, "			"read %zd bytes", err, len, pnum, offset, read);		goto error;	}	err = check_pattern(ubi->dbg_peb_buf, 0xFF, len);	if (err == 0) {		ubi_err("flash region at PEB %d:%d, length %d does not "			"contain all 0xFF bytes", pnum, offset, len);		goto fail;	}	mutex_unlock(&ubi->dbg_buf_mutex);	return 0;fail:	ubi_err("paranoid check failed for PEB %d", pnum);	dbg_msg("hex dump of the %d-%d region", offset, offset + len);	print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 32, 1,		       ubi->dbg_peb_buf, len, 1);	err = 1;error:	ubi_dbg_dump_stack();	mutex_unlock(&ubi->dbg_buf_mutex);	return err;}#endif /* CONFIG_MTD_UBI_DEBUG_PARANOID */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -