Merge tag 'upstream-3.14-rc1' of git://git.infradead.org/linux-ubifs
Pull ubifs updates from Artem Bityutskiy: - Improve the NOR erasure quirk - now it tries to do as little writes as possible, because the eraseblock may be in an "unstable" state and write operation sometimes causes NOR chip lock-ups. - Both UBI and UBIFS changes are now maintainer in one single tree, because the amount of changes dropped significantly. * tag 'upstream-3.14-rc1' of git://git.infradead.org/linux-ubifs: UBI: avoid program operation on NOR flash after erasure interrupted MAINTAINERS: keep UBI and UBIFS stuff in the same tree UBI: fix error return code
This commit is contained in:
@@ -8960,7 +8960,7 @@ UNSORTED BLOCK IMAGES (UBI)
|
|||||||
M: Artem Bityutskiy <dedekind1@gmail.com>
|
M: Artem Bityutskiy <dedekind1@gmail.com>
|
||||||
W: http://www.linux-mtd.infradead.org/
|
W: http://www.linux-mtd.infradead.org/
|
||||||
L: linux-mtd@lists.infradead.org
|
L: linux-mtd@lists.infradead.org
|
||||||
T: git git://git.infradead.org/ubi-2.6.git
|
T: git git://git.infradead.org/ubifs-2.6.git
|
||||||
S: Maintained
|
S: Maintained
|
||||||
F: drivers/mtd/ubi/
|
F: drivers/mtd/ubi/
|
||||||
F: include/linux/mtd/ubi.h
|
F: include/linux/mtd/ubi.h
|
||||||
|
@@ -1453,8 +1453,10 @@ int ubi_attach(struct ubi_device *ubi, int force_scan)
|
|||||||
struct ubi_attach_info *scan_ai;
|
struct ubi_attach_info *scan_ai;
|
||||||
|
|
||||||
scan_ai = alloc_ai("ubi_ckh_aeb_slab_cache");
|
scan_ai = alloc_ai("ubi_ckh_aeb_slab_cache");
|
||||||
if (!scan_ai)
|
if (!scan_ai) {
|
||||||
|
err = -ENOMEM;
|
||||||
goto out_wl;
|
goto out_wl;
|
||||||
|
}
|
||||||
|
|
||||||
err = scan_all(ubi, scan_ai, 0);
|
err = scan_all(ubi, scan_ai, 0);
|
||||||
if (err) {
|
if (err) {
|
||||||
|
@@ -1245,8 +1245,10 @@ static int __init ubi_init(void)
|
|||||||
ubi_wl_entry_slab = kmem_cache_create("ubi_wl_entry_slab",
|
ubi_wl_entry_slab = kmem_cache_create("ubi_wl_entry_slab",
|
||||||
sizeof(struct ubi_wl_entry),
|
sizeof(struct ubi_wl_entry),
|
||||||
0, 0, NULL);
|
0, 0, NULL);
|
||||||
if (!ubi_wl_entry_slab)
|
if (!ubi_wl_entry_slab) {
|
||||||
|
err = -ENOMEM;
|
||||||
goto out_dev_unreg;
|
goto out_dev_unreg;
|
||||||
|
}
|
||||||
|
|
||||||
err = ubi_debugfs_init();
|
err = ubi_debugfs_init();
|
||||||
if (err)
|
if (err)
|
||||||
|
@@ -495,10 +495,12 @@ out:
|
|||||||
*/
|
*/
|
||||||
static int nor_erase_prepare(struct ubi_device *ubi, int pnum)
|
static int nor_erase_prepare(struct ubi_device *ubi, int pnum)
|
||||||
{
|
{
|
||||||
int err, err1;
|
int err;
|
||||||
size_t written;
|
size_t written;
|
||||||
loff_t addr;
|
loff_t addr;
|
||||||
uint32_t data = 0;
|
uint32_t data = 0;
|
||||||
|
struct ubi_ec_hdr ec_hdr;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Note, we cannot generally define VID header buffers on stack,
|
* Note, we cannot generally define VID header buffers on stack,
|
||||||
* because of the way we deal with these buffers (see the header
|
* because of the way we deal with these buffers (see the header
|
||||||
@@ -509,50 +511,38 @@ static int nor_erase_prepare(struct ubi_device *ubi, int pnum)
|
|||||||
struct ubi_vid_hdr vid_hdr;
|
struct ubi_vid_hdr vid_hdr;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
* If VID or EC is valid, we have to corrupt them before erasing.
|
||||||
* It is important to first invalidate the EC header, and then the VID
|
* It is important to first invalidate the EC header, and then the VID
|
||||||
* header. Otherwise a power cut may lead to valid EC header and
|
* header. Otherwise a power cut may lead to valid EC header and
|
||||||
* invalid VID header, in which case UBI will treat this PEB as
|
* invalid VID header, in which case UBI will treat this PEB as
|
||||||
* corrupted and will try to preserve it, and print scary warnings.
|
* corrupted and will try to preserve it, and print scary warnings.
|
||||||
*/
|
*/
|
||||||
addr = (loff_t)pnum * ubi->peb_size;
|
addr = (loff_t)pnum * ubi->peb_size;
|
||||||
err = mtd_write(ubi->mtd, addr, 4, &written, (void *)&data);
|
err = ubi_io_read_ec_hdr(ubi, pnum, &ec_hdr, 0);
|
||||||
if (!err) {
|
if (err != UBI_IO_BAD_HDR_EBADMSG && err != UBI_IO_BAD_HDR &&
|
||||||
|
err != UBI_IO_FF){
|
||||||
|
err = mtd_write(ubi->mtd, addr, 4, &written, (void *)&data);
|
||||||
|
if(err)
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
err = ubi_io_read_vid_hdr(ubi, pnum, &vid_hdr, 0);
|
||||||
|
if (err != UBI_IO_BAD_HDR_EBADMSG && err != UBI_IO_BAD_HDR &&
|
||||||
|
err != UBI_IO_FF){
|
||||||
addr += ubi->vid_hdr_aloffset;
|
addr += ubi->vid_hdr_aloffset;
|
||||||
err = mtd_write(ubi->mtd, addr, 4, &written, (void *)&data);
|
err = mtd_write(ubi->mtd, addr, 4, &written, (void *)&data);
|
||||||
if (!err)
|
if (err)
|
||||||
return 0;
|
goto error;
|
||||||
}
|
}
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
error:
|
||||||
/*
|
/*
|
||||||
* We failed to write to the media. This was observed with Spansion
|
* The PEB contains a valid VID or EC header, but we cannot invalidate
|
||||||
* S29GL512N NOR flash. Most probably the previously eraseblock erasure
|
* it. Supposedly the flash media or the driver is screwed up, so
|
||||||
* was interrupted at a very inappropriate moment, so it became
|
* return an error.
|
||||||
* unwritable. In this case we probably anyway have garbage in this
|
|
||||||
* PEB.
|
|
||||||
*/
|
*/
|
||||||
err1 = ubi_io_read_vid_hdr(ubi, pnum, &vid_hdr, 0);
|
ubi_err("cannot invalidate PEB %d, write returned %d", pnum, err);
|
||||||
if (err1 == UBI_IO_BAD_HDR_EBADMSG || err1 == UBI_IO_BAD_HDR ||
|
|
||||||
err1 == UBI_IO_FF) {
|
|
||||||
struct ubi_ec_hdr ec_hdr;
|
|
||||||
|
|
||||||
err1 = ubi_io_read_ec_hdr(ubi, pnum, &ec_hdr, 0);
|
|
||||||
if (err1 == UBI_IO_BAD_HDR_EBADMSG || err1 == UBI_IO_BAD_HDR ||
|
|
||||||
err1 == UBI_IO_FF)
|
|
||||||
/*
|
|
||||||
* Both VID and EC headers are corrupted, so we can
|
|
||||||
* safely erase this PEB and not afraid that it will be
|
|
||||||
* treated as a valid PEB in case of an unclean reboot.
|
|
||||||
*/
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The PEB contains a valid VID header, but we cannot invalidate it.
|
|
||||||
* Supposedly the flash media or the driver is screwed up, so return an
|
|
||||||
* error.
|
|
||||||
*/
|
|
||||||
ubi_err("cannot invalidate PEB %d, write returned %d read returned %d",
|
|
||||||
pnum, err, err1);
|
|
||||||
ubi_dump_flash(ubi, pnum, 0, ubi->peb_size);
|
ubi_dump_flash(ubi, pnum, 0, ubi->peb_size);
|
||||||
return -EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user