Commit f248488b authored by Linus Torvalds's avatar Linus Torvalds
Browse files
* git://git.infradead.org/mtd-2.6:
  [MTD] fix mtdconcat for subpage-write NAND
  [MTD] [OneNAND] Avoid deadlock in erase callback; release chip lock first.
  [MTD] [OneNAND] Return only negative error codes
  [MTD] [OneNAND] Synchronize block locking operations
  UBI: return correct error code
  UBI: remove useless inlines
  UBI: fix atomic LEB change problems
  UBI: use byte hexdump
  UBI: do not use vmalloc on I/O path
  UBI: allocate memory with GFP_NOFS
  UBI: use linux print_hex_dump(), not home-grown one
  UBI: don't use array index before testing if it is negative
  UBI: add more prints
  UBI: fix sparse warnings
  UBI: fix leak in ubi_scan_erase_peb
parents cbe619b1 e3d18658
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -726,6 +726,7 @@ struct mtd_info *mtd_concat_create(struct mtd_info *subdev[], /* subdevices to c
	concat->mtd.size = subdev[0]->size;
	concat->mtd.erasesize = subdev[0]->erasesize;
	concat->mtd.writesize = subdev[0]->writesize;
	concat->mtd.subpage_sft = subdev[0]->subpage_sft;
	concat->mtd.oobsize = subdev[0]->oobsize;
	concat->mtd.oobavail = subdev[0]->oobavail;
	if (subdev[0]->writev)
+20 −9
Original line number Diff line number Diff line
@@ -327,7 +327,7 @@ static int onenand_wait(struct mtd_info *mtd, int state)
		printk(KERN_ERR "onenand_wait: controller error = 0x%04x\n", ctrl);
		if (ctrl & ONENAND_CTRL_LOCK)
			printk(KERN_ERR "onenand_wait: it's locked error.\n");
		return ctrl;
		return -EIO;
	}

	if (interrupt & ONENAND_INT_READ) {
@@ -336,7 +336,7 @@ static int onenand_wait(struct mtd_info *mtd, int state)
			if (ecc & ONENAND_ECC_2BIT_ALL) {
				printk(KERN_ERR "onenand_wait: ECC error = 0x%04x\n", ecc);
				mtd->ecc_stats.failed++;
				return ecc;
				return -EBADMSG;
			} else if (ecc & ONENAND_ECC_1BIT_ALL) {
				printk(KERN_INFO "onenand_wait: correctable ECC error = 0x%04x\n", ecc);
				mtd->ecc_stats.corrected++;
@@ -1711,13 +1711,14 @@ static int onenand_erase(struct mtd_info *mtd, struct erase_info *instr)
erase_exit:

	ret = instr->state == MTD_ERASE_DONE ? 0 : -EIO;
	/* Do call back function */
	if (!ret)
		mtd_erase_callback(instr);

	/* Deselect and wake up anyone waiting on the device */
	onenand_release_device(mtd);

	/* Do call back function */
	if (!ret)
		mtd_erase_callback(instr);

	return ret;
}

@@ -1904,7 +1905,12 @@ static int onenand_do_lock_cmd(struct mtd_info *mtd, loff_t ofs, size_t len, int
 */
static int onenand_lock(struct mtd_info *mtd, loff_t ofs, size_t len)
{
	return onenand_do_lock_cmd(mtd, ofs, len, ONENAND_CMD_LOCK);
	int ret;

	onenand_get_device(mtd, FL_LOCKING);
	ret = onenand_do_lock_cmd(mtd, ofs, len, ONENAND_CMD_LOCK);
	onenand_release_device(mtd);
	return ret;
}

/**
@@ -1917,7 +1923,12 @@ static int onenand_lock(struct mtd_info *mtd, loff_t ofs, size_t len)
 */
static int onenand_unlock(struct mtd_info *mtd, loff_t ofs, size_t len)
{
	return onenand_do_lock_cmd(mtd, ofs, len, ONENAND_CMD_UNLOCK);
	int ret;

	onenand_get_device(mtd, FL_LOCKING);
	ret = onenand_do_lock_cmd(mtd, ofs, len, ONENAND_CMD_UNLOCK);
	onenand_release_device(mtd);
	return ret;
}

/**
@@ -1979,7 +1990,7 @@ static int onenand_unlock_all(struct mtd_info *mtd)
			loff_t ofs = this->chipsize >> 1;
			size_t len = mtd->erasesize;

			onenand_unlock(mtd, ofs, len);
			onenand_do_lock_cmd(mtd, ofs, len, ONENAND_CMD_UNLOCK);
		}

		onenand_check_lock_status(this);
@@ -1987,7 +1998,7 @@ static int onenand_unlock_all(struct mtd_info *mtd)
		return 0;
	}

	onenand_unlock(mtd, 0x0, this->chipsize);
	onenand_do_lock_cmd(mtd, 0x0, this->chipsize, ONENAND_CMD_UNLOCK);

	return 0;
}
+27 −1
Original line number Diff line number Diff line
@@ -583,6 +583,22 @@ static int attach_mtd_dev(const char *mtd_dev, int vid_hdr_offset,
	if (err)
		goto out_free;

	mutex_init(&ubi->buf_mutex);
	ubi->peb_buf1 = vmalloc(ubi->peb_size);
	if (!ubi->peb_buf1)
		goto out_free;

	ubi->peb_buf2 = vmalloc(ubi->peb_size);
	if (!ubi->peb_buf2)
		 goto out_free;

#ifdef CONFIG_MTD_UBI_DEBUG
	mutex_init(&ubi->dbg_buf_mutex);
	ubi->dbg_peb_buf = vmalloc(ubi->peb_size);
	if (!ubi->dbg_peb_buf)
		 goto out_free;
#endif

	err = attach_by_scanning(ubi);
	if (err) {
		dbg_err("failed to attach by scanning, error %d", err);
@@ -630,6 +646,11 @@ out_detach:
	ubi_wl_close(ubi);
	vfree(ubi->vtbl);
out_free:
	vfree(ubi->peb_buf1);
	vfree(ubi->peb_buf2);
#ifdef CONFIG_MTD_UBI_DEBUG
	vfree(ubi->dbg_peb_buf);
#endif
	kfree(ubi);
out_mtd:
	put_mtd_device(mtd);
@@ -651,6 +672,11 @@ static void detach_mtd_dev(struct ubi_device *ubi)
	ubi_wl_close(ubi);
	vfree(ubi->vtbl);
	put_mtd_device(ubi->mtd);
	vfree(ubi->peb_buf1);
	vfree(ubi->peb_buf2);
#ifdef CONFIG_MTD_UBI_DEBUG
	vfree(ubi->dbg_peb_buf);
#endif
	kfree(ubi_devices[ubi_num]);
	ubi_devices[ubi_num] = NULL;
	ubi_devices_cnt -= 1;
+2 −35
Original line number Diff line number Diff line
@@ -42,7 +42,8 @@ void ubi_dbg_dump_ec_hdr(const struct ubi_ec_hdr *ec_hdr)
	dbg_msg("data_offset    %d",    be32_to_cpu(ec_hdr->data_offset));
	dbg_msg("hdr_crc        %#08x", be32_to_cpu(ec_hdr->hdr_crc));
	dbg_msg("erase counter header hexdump:");
	ubi_dbg_hexdump(ec_hdr, UBI_EC_HDR_SIZE);
	print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 32, 1,
		       ec_hdr, UBI_EC_HDR_SIZE, 1);
}

/**
@@ -187,38 +188,4 @@ void ubi_dbg_dump_mkvol_req(const struct ubi_mkvol_req *req)
	dbg_msg("the 1st 16 characters of the name: %s", nm);
}

#define BYTES_PER_LINE 32

/**
 * ubi_dbg_hexdump - dump a buffer.
 * @ptr: the buffer to dump
 * @size: buffer size which must be multiple of 4 bytes
 */
void ubi_dbg_hexdump(const void *ptr, int size)
{
	int i, k = 0, rows, columns;
	const uint8_t *p = ptr;

	size = ALIGN(size, 4);
	rows = size/BYTES_PER_LINE + size % BYTES_PER_LINE;
	for (i = 0; i < rows; i++) {
		int j;

		cond_resched();
		columns = min(size - k, BYTES_PER_LINE) / 4;
		if (columns == 0)
			break;
		printk(KERN_DEBUG "%5d:  ", i * BYTES_PER_LINE);
		for (j = 0; j < columns; j++) {
			int n, N;

			N = size - k > 4 ? 4 : size - k;
			for (n = 0; n < N; n++)
				printk("%02x", p[k++]);
			printk(" ");
		}
		printk("\n");
	}
}

#endif /* CONFIG_MTD_UBI_DEBUG_MSG */
+0 −2
Original line number Diff line number Diff line
@@ -59,7 +59,6 @@ void ubi_dbg_dump_vtbl_record(const struct ubi_vtbl_record *r, int idx);
void ubi_dbg_dump_sv(const struct ubi_scan_volume *sv);
void ubi_dbg_dump_seb(const struct ubi_scan_leb *seb, int type);
void ubi_dbg_dump_mkvol_req(const struct ubi_mkvol_req *req);
void ubi_dbg_hexdump(const void *buf, int size);

#else

@@ -72,7 +71,6 @@ void ubi_dbg_hexdump(const void *buf, int size);
#define ubi_dbg_dump_sv(sv)              ({})
#define ubi_dbg_dump_seb(seb, type)      ({})
#define ubi_dbg_dump_mkvol_req(req)      ({})
#define ubi_dbg_hexdump(buf, size)       ({})

#endif /* CONFIG_MTD_UBI_DEBUG_MSG */

Loading