提交 d107bc34 编写于 作者: R Robert Jarzmik 提交者: David Woodhouse

mtd: docg3 reduce read alignment burden

The read function was so far requiring the reads to be aligned on page
boundaries, and be page length multiples in size. Relieve these
constraints to ease the userspace ubifs programs runs, which read ubifs
headers of 64 bytes.

Artem: squashed a later fix from Robert Jarzmik into this patch.
Signed-off-by: NRobert Jarzmik <robert.jarzmik@free.fr>
Signed-off-by: NDavid Woodhouse <David.Woodhouse@intel.com>
上级 cfe78194
...@@ -734,7 +734,7 @@ static int doc_read_page_prepare(struct docg3 *docg3, int block0, int block1, ...@@ -734,7 +734,7 @@ static int doc_read_page_prepare(struct docg3 *docg3, int block0, int block1,
* doc_read_page_getbytes - Reads bytes from a prepared page * doc_read_page_getbytes - Reads bytes from a prepared page
* @docg3: the device * @docg3: the device
* @len: the number of bytes to be read (must be a multiple of 4) * @len: the number of bytes to be read (must be a multiple of 4)
* @buf: the buffer to be filled in * @buf: the buffer to be filled in (or NULL is forget bytes)
* @first: 1 if first time read, DOC_READADDRESS should be set * @first: 1 if first time read, DOC_READADDRESS should be set
* *
*/ */
...@@ -849,7 +849,7 @@ static int doc_read_oob(struct mtd_info *mtd, loff_t from, ...@@ -849,7 +849,7 @@ static int doc_read_oob(struct mtd_info *mtd, loff_t from,
struct mtd_oob_ops *ops) struct mtd_oob_ops *ops)
{ {
struct docg3 *docg3 = mtd->priv; struct docg3 *docg3 = mtd->priv;
int block0, block1, page, ret, ofs = 0; int block0, block1, page, ret, skip, ofs = 0;
u8 *oobbuf = ops->oobbuf; u8 *oobbuf = ops->oobbuf;
u8 *buf = ops->datbuf; u8 *buf = ops->datbuf;
size_t len, ooblen, nbdata, nboob; size_t len, ooblen, nbdata, nboob;
...@@ -869,8 +869,7 @@ static int doc_read_oob(struct mtd_info *mtd, loff_t from, ...@@ -869,8 +869,7 @@ static int doc_read_oob(struct mtd_info *mtd, loff_t from,
doc_dbg("doc_read_oob(from=%lld, mode=%d, data=(%p:%zu), oob=(%p:%zu))\n", doc_dbg("doc_read_oob(from=%lld, mode=%d, data=(%p:%zu), oob=(%p:%zu))\n",
from, ops->mode, buf, len, oobbuf, ooblen); from, ops->mode, buf, len, oobbuf, ooblen);
if ((len % DOC_LAYOUT_PAGE_SIZE) || (ooblen % DOC_LAYOUT_OOB_SIZE) || if (ooblen % DOC_LAYOUT_OOB_SIZE)
(from % DOC_LAYOUT_PAGE_SIZE))
return -EINVAL; return -EINVAL;
ret = -EINVAL; ret = -EINVAL;
...@@ -882,10 +881,11 @@ static int doc_read_oob(struct mtd_info *mtd, loff_t from, ...@@ -882,10 +881,11 @@ static int doc_read_oob(struct mtd_info *mtd, loff_t from,
ops->oobretlen = 0; ops->oobretlen = 0;
ops->retlen = 0; ops->retlen = 0;
ret = 0; ret = 0;
skip = from % DOC_LAYOUT_PAGE_SIZE;
while (!ret && (len > 0 || ooblen > 0)) { while (!ret && (len > 0 || ooblen > 0)) {
calc_block_sector(from, &block0, &block1, &page, &ofs, calc_block_sector(from - skip, &block0, &block1, &page, &ofs,
docg3->reliable); docg3->reliable);
nbdata = min_t(size_t, len, (size_t)DOC_LAYOUT_PAGE_SIZE); nbdata = min_t(size_t, len, DOC_LAYOUT_PAGE_SIZE - skip);
nboob = min_t(size_t, ooblen, (size_t)DOC_LAYOUT_OOB_SIZE); nboob = min_t(size_t, ooblen, (size_t)DOC_LAYOUT_OOB_SIZE);
ret = doc_read_page_prepare(docg3, block0, block1, page, ofs); ret = doc_read_page_prepare(docg3, block0, block1, page, ofs);
if (ret < 0) if (ret < 0)
...@@ -893,10 +893,14 @@ static int doc_read_oob(struct mtd_info *mtd, loff_t from, ...@@ -893,10 +893,14 @@ static int doc_read_oob(struct mtd_info *mtd, loff_t from,
ret = doc_read_page_ecc_init(docg3, DOC_ECC_BCH_TOTAL_BYTES); ret = doc_read_page_ecc_init(docg3, DOC_ECC_BCH_TOTAL_BYTES);
if (ret < 0) if (ret < 0)
goto err_in_read; goto err_in_read;
ret = doc_read_page_getbytes(docg3, nbdata, buf, 1); ret = doc_read_page_getbytes(docg3, skip, NULL, 1);
if (ret < skip)
goto err_in_read;
ret = doc_read_page_getbytes(docg3, nbdata, buf, 0);
if (ret < nbdata) if (ret < nbdata)
goto err_in_read; goto err_in_read;
doc_read_page_getbytes(docg3, DOC_LAYOUT_PAGE_SIZE - nbdata, doc_read_page_getbytes(docg3,
DOC_LAYOUT_PAGE_SIZE - nbdata - skip,
NULL, 0); NULL, 0);
ret = doc_read_page_getbytes(docg3, nboob, oobbuf, 0); ret = doc_read_page_getbytes(docg3, nboob, oobbuf, 0);
if (ret < nboob) if (ret < nboob)
...@@ -950,6 +954,7 @@ static int doc_read_oob(struct mtd_info *mtd, loff_t from, ...@@ -950,6 +954,7 @@ static int doc_read_oob(struct mtd_info *mtd, loff_t from,
len -= nbdata; len -= nbdata;
ooblen -= nboob; ooblen -= nboob;
from += DOC_LAYOUT_PAGE_SIZE; from += DOC_LAYOUT_PAGE_SIZE;
skip = 0;
} }
return ret; return ret;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册