提交 877b58eb 编写于 作者: N Nicolas Pitre 提交者: Richard Weinberger

mtd: mtdram: properly handle the phys argument in the point method

When the phys pointer is non null, the point method is expected to return
the physical address for the pointed area. In the case of the mtdram
driver we have to retrieve the physical address for the corresponding
vmalloc area. However, there is no guarantee that the vmalloc area is
made of physically contiguous pages. In that case we simply limit retlen
to the actually contiguous pages.
Signed-off-by: NNicolas Pitre <nico@linaro.org>
Reviewed-by: NRichard Weinberger <richard@nod.at>
Acked-by: NBoris Brezillon <boris.brezillon@free-electrons.com>
Signed-off-by: NRichard Weinberger <richard@nod.at>
上级 a5929b64
......@@ -13,6 +13,7 @@
#include <linux/slab.h>
#include <linux/ioport.h>
#include <linux/vmalloc.h>
#include <linux/mm.h>
#include <linux/init.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/mtdram.h>
......@@ -69,6 +70,27 @@ static int ram_point(struct mtd_info *mtd, loff_t from, size_t len,
{
*virt = mtd->priv + from;
*retlen = len;
if (phys) {
/* limit retlen to the number of contiguous physical pages */
unsigned long page_ofs = offset_in_page(*virt);
void *addr = *virt - page_ofs;
unsigned long pfn1, pfn0 = vmalloc_to_pfn(addr);
*phys = __pfn_to_phys(pfn0) + page_ofs;
len += page_ofs;
while (len > PAGE_SIZE) {
len -= PAGE_SIZE;
addr += PAGE_SIZE;
pfn0++;
pfn1 = vmalloc_to_pfn(addr);
if (pfn1 != pfn0) {
*retlen = addr - *virt;
break;
}
}
}
return 0;
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册