diff options
-rw-r--r-- | drivers/mtd/devices/docg3.c | 21 |
1 files changed, 13 insertions, 8 deletions
diff --git a/drivers/mtd/devices/docg3.c b/drivers/mtd/devices/docg3.c index 3eafef383a39..2c1d0fca6757 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; |