aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mtd
diff options
context:
space:
mode:
authorRobert Jarzmik <robert.jarzmik@free.fr>2012-03-11 06:28:45 -0400
committerDavid Woodhouse <David.Woodhouse@intel.com>2012-03-26 19:53:43 -0400
commitd107bc34f4953852834f086968fc7963125d6943 (patch)
tree1745742d24f175f88b2c8cf51acaa87b2ad45982 /drivers/mtd
parentcfe781946dac7f5ff42e23cd7054c75e7201fbdc (diff)
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: Robert Jarzmik <robert.jarzmik@free.fr> Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
Diffstat (limited to 'drivers/mtd')
-rw-r--r--drivers/mtd/devices/docg3.c21
1 files changed, 13 insertions, 8 deletions
diff --git a/drivers/mtd/devices/docg3.c b/drivers/mtd/devices/docg3.c
index 3eafef383a3..2c1d0fca675 100644
--- a/drivers/mtd/devices/docg3.c
+++ b/drivers/mtd/devices/docg3.c
@@ -734,7 +734,7 @@ err:
734 * doc_read_page_getbytes - Reads bytes from a prepared page 734 * doc_read_page_getbytes - Reads bytes from a prepared page
735 * @docg3: the device 735 * @docg3: the device
736 * @len: the number of bytes to be read (must be a multiple of 4) 736 * @len: the number of bytes to be read (must be a multiple of 4)
737 * @buf: the buffer to be filled in 737 * @buf: the buffer to be filled in (or NULL is forget bytes)
738 * @first: 1 if first time read, DOC_READADDRESS should be set 738 * @first: 1 if first time read, DOC_READADDRESS should be set
739 * 739 *
740 */ 740 */
@@ -849,7 +849,7 @@ static int doc_read_oob(struct mtd_info *mtd, loff_t from,
849 struct mtd_oob_ops *ops) 849 struct mtd_oob_ops *ops)
850{ 850{
851 struct docg3 *docg3 = mtd->priv; 851 struct docg3 *docg3 = mtd->priv;
852 int block0, block1, page, ret, ofs = 0; 852 int block0, block1, page, ret, skip, ofs = 0;
853 u8 *oobbuf = ops->oobbuf; 853 u8 *oobbuf = ops->oobbuf;
854 u8 *buf = ops->datbuf; 854 u8 *buf = ops->datbuf;
855 size_t len, ooblen, nbdata, nboob; 855 size_t len, ooblen, nbdata, nboob;
@@ -869,8 +869,7 @@ static int doc_read_oob(struct mtd_info *mtd, loff_t from,
869 869
870 doc_dbg("doc_read_oob(from=%lld, mode=%d, data=(%p:%zu), oob=(%p:%zu))\n", 870 doc_dbg("doc_read_oob(from=%lld, mode=%d, data=(%p:%zu), oob=(%p:%zu))\n",
871 from, ops->mode, buf, len, oobbuf, ooblen); 871 from, ops->mode, buf, len, oobbuf, ooblen);
872 if ((len % DOC_LAYOUT_PAGE_SIZE) || (ooblen % DOC_LAYOUT_OOB_SIZE) || 872 if (ooblen % DOC_LAYOUT_OOB_SIZE)
873 (from % DOC_LAYOUT_PAGE_SIZE))
874 return -EINVAL; 873 return -EINVAL;
875 874
876 ret = -EINVAL; 875 ret = -EINVAL;
@@ -882,10 +881,11 @@ static int doc_read_oob(struct mtd_info *mtd, loff_t from,
882 ops->oobretlen = 0; 881 ops->oobretlen = 0;
883 ops->retlen = 0; 882 ops->retlen = 0;
884 ret = 0; 883 ret = 0;
884 skip = from % DOC_LAYOUT_PAGE_SIZE;
885 while (!ret && (len > 0 || ooblen > 0)) { 885 while (!ret && (len > 0 || ooblen > 0)) {
886 calc_block_sector(from, &block0, &block1, &page, &ofs, 886 calc_block_sector(from - skip, &block0, &block1, &page, &ofs,
887 docg3->reliable); 887 docg3->reliable);
888 nbdata = min_t(size_t, len, (size_t)DOC_LAYOUT_PAGE_SIZE); 888 nbdata = min_t(size_t, len, DOC_LAYOUT_PAGE_SIZE - skip);
889 nboob = min_t(size_t, ooblen, (size_t)DOC_LAYOUT_OOB_SIZE); 889 nboob = min_t(size_t, ooblen, (size_t)DOC_LAYOUT_OOB_SIZE);
890 ret = doc_read_page_prepare(docg3, block0, block1, page, ofs); 890 ret = doc_read_page_prepare(docg3, block0, block1, page, ofs);
891 if (ret < 0) 891 if (ret < 0)
@@ -893,10 +893,14 @@ static int doc_read_oob(struct mtd_info *mtd, loff_t from,
893 ret = doc_read_page_ecc_init(docg3, DOC_ECC_BCH_TOTAL_BYTES); 893 ret = doc_read_page_ecc_init(docg3, DOC_ECC_BCH_TOTAL_BYTES);
894 if (ret < 0) 894 if (ret < 0)
895 goto err_in_read; 895 goto err_in_read;
896 ret = doc_read_page_getbytes(docg3, nbdata, buf, 1); 896 ret = doc_read_page_getbytes(docg3, skip, NULL, 1);
897 if (ret < skip)
898 goto err_in_read;
899 ret = doc_read_page_getbytes(docg3, nbdata, buf, 0);
897 if (ret < nbdata) 900 if (ret < nbdata)
898 goto err_in_read; 901 goto err_in_read;
899 doc_read_page_getbytes(docg3, DOC_LAYOUT_PAGE_SIZE - nbdata, 902 doc_read_page_getbytes(docg3,
903 DOC_LAYOUT_PAGE_SIZE - nbdata - skip,
900 NULL, 0); 904 NULL, 0);
901 ret = doc_read_page_getbytes(docg3, nboob, oobbuf, 0); 905 ret = doc_read_page_getbytes(docg3, nboob, oobbuf, 0);
902 if (ret < nboob) 906 if (ret < nboob)
@@ -950,6 +954,7 @@ static int doc_read_oob(struct mtd_info *mtd, loff_t from,
950 len -= nbdata; 954 len -= nbdata;
951 ooblen -= nboob; 955 ooblen -= nboob;
952 from += DOC_LAYOUT_PAGE_SIZE; 956 from += DOC_LAYOUT_PAGE_SIZE;
957 skip = 0;
953 } 958 }
954 959
955 return ret; 960 return ret;