Most important part of this is that it fixes a regression in Samsung
NAND chip detection, introduced by some rework which went into 3.7. The initial fix wasn't quite complete, so it's in two parts. In fact the first part is committed twice (Artem committed his own copy of the same patch) and I've merged Artem's tree into mine which already had that fix. I'd have recommitted that to make it somewhat cleaner, but figured by this point in the release cycle it was better to merge *exactly* the commits which have been in linux-next. If I'd recommitted, I'd also omit the sparse warning fix. But it's there, and it's harmless — just marking one function as 'static' in onenand code. This also includes a couple more fixes for stable: an AB-BA deadlock in JFFS2, and an invalid range check in slram. -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.12 (GNU/Linux) iEYEABECAAYFAlCwEIsACgkQdwG7hYl686NfZgCfSYFA2q8yp7jEMdDaxpFPuuDm FFMAoI3V27BpWxRab6GylYh8erHp9ful =Wo+T -----END PGP SIGNATURE----- Merge tag 'for-linus-20121123' of git://git.infradead.org/mtd-2.6 Pull MTD fixes from David Woodhouse: "The most important part of this is that it fixes a regression in Samsung NAND chip detection, introduced by some rework which went into 3.7. The initial fix wasn't quite complete, so it's in two parts. In fact the first part is committed twice (Artem committed his own copy of the same patch) and I've merged Artem's tree into mine which already had that fix. I'd have recommitted that to make it somewhat cleaner, but figured by this point in the release cycle it was better to merge *exactly* the commits which have been in linux-next. If I'd recommitted, I'd also omit the sparse warning fix. But it's there, and it's harmless — just marking one function as 'static' in onenand code. This also includes a couple more fixes for stable: an AB-BA deadlock in JFFS2, and an invalid range check in slram." * tag 'for-linus-20121123' of git://git.infradead.org/mtd-2.6: mtd: nand: fix Samsung SLC detection regression mtd: nand: fix Samsung SLC NAND identification regression jffs2: Fix lock acquisition order bug in jffs2_write_begin mtd: onenand: Make flexonenand_set_boundary static mtd: slram: invalid checking of absolute end address mtd: ofpart: Fix incorrect NULL check in parse_ofoldpart_partitions() mtd: nand: fix Samsung SLC NAND identification regression
This commit is contained in:
commit
35f95d228e
|
@ -240,7 +240,7 @@ static int parse_cmdline(char *devname, char *szstart, char *szlength)
|
||||||
|
|
||||||
if (*(szlength) != '+') {
|
if (*(szlength) != '+') {
|
||||||
devlength = simple_strtoul(szlength, &buffer, 0);
|
devlength = simple_strtoul(szlength, &buffer, 0);
|
||||||
devlength = handle_unit(devlength, buffer) - devstart;
|
devlength = handle_unit(devlength, buffer);
|
||||||
if (devlength < devstart)
|
if (devlength < devstart)
|
||||||
goto err_out;
|
goto err_out;
|
||||||
|
|
||||||
|
|
|
@ -2983,13 +2983,15 @@ static void nand_decode_ext_id(struct mtd_info *mtd, struct nand_chip *chip,
|
||||||
/*
|
/*
|
||||||
* Field definitions are in the following datasheets:
|
* Field definitions are in the following datasheets:
|
||||||
* Old style (4,5 byte ID): Samsung K9GAG08U0M (p.32)
|
* Old style (4,5 byte ID): Samsung K9GAG08U0M (p.32)
|
||||||
* New style (6 byte ID): Samsung K9GAG08U0F (p.44)
|
* New Samsung (6 byte ID): Samsung K9GAG08U0F (p.44)
|
||||||
* Hynix MLC (6 byte ID): Hynix H27UBG8T2B (p.22)
|
* Hynix MLC (6 byte ID): Hynix H27UBG8T2B (p.22)
|
||||||
*
|
*
|
||||||
* Check for ID length, cell type, and Hynix/Samsung ID to decide what
|
* Check for ID length, non-zero 6th byte, cell type, and Hynix/Samsung
|
||||||
* to do.
|
* ID to decide what to do.
|
||||||
*/
|
*/
|
||||||
if (id_len == 6 && id_data[0] == NAND_MFR_SAMSUNG) {
|
if (id_len == 6 && id_data[0] == NAND_MFR_SAMSUNG &&
|
||||||
|
(chip->cellinfo & NAND_CI_CELLTYPE_MSK) &&
|
||||||
|
id_data[5] != 0x00) {
|
||||||
/* Calc pagesize */
|
/* Calc pagesize */
|
||||||
mtd->writesize = 2048 << (extid & 0x03);
|
mtd->writesize = 2048 << (extid & 0x03);
|
||||||
extid >>= 2;
|
extid >>= 2;
|
||||||
|
|
|
@ -121,7 +121,7 @@ static int parse_ofoldpart_partitions(struct mtd_info *master,
|
||||||
nr_parts = plen / sizeof(part[0]);
|
nr_parts = plen / sizeof(part[0]);
|
||||||
|
|
||||||
*pparts = kzalloc(nr_parts * sizeof(*(*pparts)), GFP_KERNEL);
|
*pparts = kzalloc(nr_parts * sizeof(*(*pparts)), GFP_KERNEL);
|
||||||
if (!pparts)
|
if (!*pparts)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
names = of_get_property(dp, "partition-names", &plen);
|
names = of_get_property(dp, "partition-names", &plen);
|
||||||
|
|
|
@ -3694,7 +3694,7 @@ static int flexonenand_check_blocks_erased(struct mtd_info *mtd, int start, int
|
||||||
* flexonenand_set_boundary - Writes the SLC boundary
|
* flexonenand_set_boundary - Writes the SLC boundary
|
||||||
* @param mtd - mtd info structure
|
* @param mtd - mtd info structure
|
||||||
*/
|
*/
|
||||||
int flexonenand_set_boundary(struct mtd_info *mtd, int die,
|
static int flexonenand_set_boundary(struct mtd_info *mtd, int die,
|
||||||
int boundary, int lock)
|
int boundary, int lock)
|
||||||
{
|
{
|
||||||
struct onenand_chip *this = mtd->priv;
|
struct onenand_chip *this = mtd->priv;
|
||||||
|
|
|
@ -138,33 +138,39 @@ static int jffs2_write_begin(struct file *filp, struct address_space *mapping,
|
||||||
struct page *pg;
|
struct page *pg;
|
||||||
struct inode *inode = mapping->host;
|
struct inode *inode = mapping->host;
|
||||||
struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode);
|
struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode);
|
||||||
|
struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb);
|
||||||
|
struct jffs2_raw_inode ri;
|
||||||
|
uint32_t alloc_len = 0;
|
||||||
pgoff_t index = pos >> PAGE_CACHE_SHIFT;
|
pgoff_t index = pos >> PAGE_CACHE_SHIFT;
|
||||||
uint32_t pageofs = index << PAGE_CACHE_SHIFT;
|
uint32_t pageofs = index << PAGE_CACHE_SHIFT;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
pg = grab_cache_page_write_begin(mapping, index, flags);
|
|
||||||
if (!pg)
|
|
||||||
return -ENOMEM;
|
|
||||||
*pagep = pg;
|
|
||||||
|
|
||||||
jffs2_dbg(1, "%s()\n", __func__);
|
jffs2_dbg(1, "%s()\n", __func__);
|
||||||
|
|
||||||
if (pageofs > inode->i_size) {
|
if (pageofs > inode->i_size) {
|
||||||
|
ret = jffs2_reserve_space(c, sizeof(ri), &alloc_len,
|
||||||
|
ALLOC_NORMAL, JFFS2_SUMMARY_INODE_SIZE);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
mutex_lock(&f->sem);
|
||||||
|
pg = grab_cache_page_write_begin(mapping, index, flags);
|
||||||
|
if (!pg) {
|
||||||
|
if (alloc_len)
|
||||||
|
jffs2_complete_reservation(c);
|
||||||
|
mutex_unlock(&f->sem);
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
*pagep = pg;
|
||||||
|
|
||||||
|
if (alloc_len) {
|
||||||
/* Make new hole frag from old EOF to new page */
|
/* Make new hole frag from old EOF to new page */
|
||||||
struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb);
|
|
||||||
struct jffs2_raw_inode ri;
|
|
||||||
struct jffs2_full_dnode *fn;
|
struct jffs2_full_dnode *fn;
|
||||||
uint32_t alloc_len;
|
|
||||||
|
|
||||||
jffs2_dbg(1, "Writing new hole frag 0x%x-0x%x between current EOF and new page\n",
|
jffs2_dbg(1, "Writing new hole frag 0x%x-0x%x between current EOF and new page\n",
|
||||||
(unsigned int)inode->i_size, pageofs);
|
(unsigned int)inode->i_size, pageofs);
|
||||||
|
|
||||||
ret = jffs2_reserve_space(c, sizeof(ri), &alloc_len,
|
|
||||||
ALLOC_NORMAL, JFFS2_SUMMARY_INODE_SIZE);
|
|
||||||
if (ret)
|
|
||||||
goto out_page;
|
|
||||||
|
|
||||||
mutex_lock(&f->sem);
|
|
||||||
memset(&ri, 0, sizeof(ri));
|
memset(&ri, 0, sizeof(ri));
|
||||||
|
|
||||||
ri.magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);
|
ri.magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);
|
||||||
|
@ -191,7 +197,6 @@ static int jffs2_write_begin(struct file *filp, struct address_space *mapping,
|
||||||
if (IS_ERR(fn)) {
|
if (IS_ERR(fn)) {
|
||||||
ret = PTR_ERR(fn);
|
ret = PTR_ERR(fn);
|
||||||
jffs2_complete_reservation(c);
|
jffs2_complete_reservation(c);
|
||||||
mutex_unlock(&f->sem);
|
|
||||||
goto out_page;
|
goto out_page;
|
||||||
}
|
}
|
||||||
ret = jffs2_add_full_dnode_to_inode(c, f, fn);
|
ret = jffs2_add_full_dnode_to_inode(c, f, fn);
|
||||||
|
@ -206,12 +211,10 @@ static int jffs2_write_begin(struct file *filp, struct address_space *mapping,
|
||||||
jffs2_mark_node_obsolete(c, fn->raw);
|
jffs2_mark_node_obsolete(c, fn->raw);
|
||||||
jffs2_free_full_dnode(fn);
|
jffs2_free_full_dnode(fn);
|
||||||
jffs2_complete_reservation(c);
|
jffs2_complete_reservation(c);
|
||||||
mutex_unlock(&f->sem);
|
|
||||||
goto out_page;
|
goto out_page;
|
||||||
}
|
}
|
||||||
jffs2_complete_reservation(c);
|
jffs2_complete_reservation(c);
|
||||||
inode->i_size = pageofs;
|
inode->i_size = pageofs;
|
||||||
mutex_unlock(&f->sem);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -220,18 +223,18 @@ static int jffs2_write_begin(struct file *filp, struct address_space *mapping,
|
||||||
* case of a short-copy.
|
* case of a short-copy.
|
||||||
*/
|
*/
|
||||||
if (!PageUptodate(pg)) {
|
if (!PageUptodate(pg)) {
|
||||||
mutex_lock(&f->sem);
|
|
||||||
ret = jffs2_do_readpage_nolock(inode, pg);
|
ret = jffs2_do_readpage_nolock(inode, pg);
|
||||||
mutex_unlock(&f->sem);
|
|
||||||
if (ret)
|
if (ret)
|
||||||
goto out_page;
|
goto out_page;
|
||||||
}
|
}
|
||||||
|
mutex_unlock(&f->sem);
|
||||||
jffs2_dbg(1, "end write_begin(). pg->flags %lx\n", pg->flags);
|
jffs2_dbg(1, "end write_begin(). pg->flags %lx\n", pg->flags);
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
out_page:
|
out_page:
|
||||||
unlock_page(pg);
|
unlock_page(pg);
|
||||||
page_cache_release(pg);
|
page_cache_release(pg);
|
||||||
|
mutex_unlock(&f->sem);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue