if (unlikely(oob)) {
 
-                               /* Raw mode does data:oob:data:oob */
-                               if (ops->mode != MTD_OOB_RAW) {
-                                       int toread = min(oobreadlen,
-                                                               max_oobsize);
-                                       if (toread) {
-                                               oob = nand_transfer_oob(chip,
-                                                       oob, ops, toread);
-                                               oobreadlen -= toread;
-                                       }
-                               } else
-                                       buf = nand_transfer_oob(chip,
-                                               buf, ops, mtd->oobsize);
+                               int toread = min(oobreadlen, max_oobsize);
+
+                               if (toread) {
+                                       oob = nand_transfer_oob(chip,
+                                               oob, ops, toread);
+                                       oobreadlen -= toread;
+                               }
                        }
 
                        if (!(chip->options & NAND_NO_READRDY)) {
 
                         size_t len)
 {
        struct mtd_oob_ops ops;
+       int res;
 
        ops.mode = MTD_OOB_RAW;
        ops.ooboffs = 0;
        ops.ooblen = mtd->oobsize;
-       ops.oobbuf = buf;
-       ops.datbuf = buf;
-       ops.len = len;
 
-       return mtd->read_oob(mtd, offs, &ops);
+
+       while (len > 0) {
+               if (len <= mtd->writesize) {
+                       ops.oobbuf = buf + len;
+                       ops.datbuf = buf;
+                       ops.len = len;
+                       return mtd->read_oob(mtd, offs, &ops);
+               } else {
+                       ops.oobbuf = buf + mtd->writesize;
+                       ops.datbuf = buf;
+                       ops.len = mtd->writesize;
+                       res = mtd->read_oob(mtd, offs, &ops);
+
+                       if (res)
+                               return res;
+               }
+
+               buf += mtd->oobsize + mtd->writesize;
+               len -= mtd->writesize;
+       }
+       return 0;
 }
 
 /*
 
  * MTD_OOB_PLACE:      oob data are placed at the given offset
  * MTD_OOB_AUTO:       oob data are automatically placed at the free areas
  *                     which are defined by the ecclayout
- * MTD_OOB_RAW:                mode to read raw data+oob in one chunk. The oob data
- *                     is inserted into the data. Thats a raw image of the
- *                     flash contents.
+ * MTD_OOB_RAW:                mode to read oob and data without doing ECC checking
  */
 typedef enum {
        MTD_OOB_PLACE,