Skip to content

Commit

Permalink
[MTD] fix CFI point method for discontiguous maps
Browse files Browse the repository at this point in the history
The CFI probe routine is capable of detecting flash banks consisting of
identical chips mapped to physically discontiguous addresses.  (One
common way this can occur is if a flash bank is populated with chips of
less capacity than the hardware was designed to support.)  The CFI
point() routine currently ignores any such gaps.  This patch fixes
the CFI point() routine so that it truncates any request that would
span a gap.

Signed-off-by: Andy Lowe <alowe@mvista.com>
Signed-off-by: Nicolas Pitre <nico@cam.org>
Signed-off-by: David Woodhouse <dwmw2@infradead.org>
  • Loading branch information
Andy Lowe authored and David Woodhouse committed Sep 23, 2007
1 parent e644f7d commit 097f257
Showing 1 changed file with 11 additions and 4 deletions.
15 changes: 11 additions & 4 deletions drivers/mtd/chips/cfi_cmdset_0001.c
Original file line number Diff line number Diff line change
Expand Up @@ -1166,28 +1166,34 @@ static int cfi_intelext_point (struct mtd_info *mtd, loff_t from, size_t len, si
{
struct map_info *map = mtd->priv;
struct cfi_private *cfi = map->fldrv_priv;
unsigned long ofs;
unsigned long ofs, last_end = 0;
int chipnum;
int ret = 0;

if (!map->virt || (from + len > mtd->size))
return -EINVAL;

*mtdbuf = (void *)map->virt + from;
*retlen = 0;

/* Now lock the chip(s) to POINT state */

/* ofs: offset within the first chip that the first read should start */
chipnum = (from >> cfi->chipshift);
ofs = from - (chipnum << cfi->chipshift);

*mtdbuf = (void *)map->virt + cfi->chips[chipnum].start + ofs;
*retlen = 0;

while (len) {
unsigned long thislen;

if (chipnum >= cfi->numchips)
break;

/* We cannot point across chips that are virtually disjoint */
if (!last_end)
last_end = cfi->chips[chipnum].start;
else if (cfi->chips[chipnum].start != last_end)
break;

if ((len + ofs -1) >> cfi->chipshift)
thislen = (1<<cfi->chipshift) - ofs;
else
Expand All @@ -1201,6 +1207,7 @@ static int cfi_intelext_point (struct mtd_info *mtd, loff_t from, size_t len, si
len -= thislen;

ofs = 0;
last_end += 1 << cfi->chipshift;
chipnum++;
}
return 0;
Expand Down

0 comments on commit 097f257

Please sign in to comment.