int eccbytes = chip->ecc.bytes;
        int eccsteps = chip->ecc.steps;
        uint8_t *p = buf;
-       uint8_t *ecc_calc = chip->buffers.ecccalc;
-       uint8_t *ecc_code = chip->buffers.ecccode;
+       uint8_t *ecc_calc = chip->buffers->ecccalc;
+       uint8_t *ecc_code = chip->buffers->ecccode;
        int *eccpos = chip->ecc.layout->eccpos;
 
        nand_read_page_raw(mtd, chip, buf);
        int eccbytes = chip->ecc.bytes;
        int eccsteps = chip->ecc.steps;
        uint8_t *p = buf;
-       uint8_t *ecc_calc = chip->buffers.ecccalc;
-       uint8_t *ecc_code = chip->buffers.ecccode;
+       uint8_t *ecc_calc = chip->buffers->ecccalc;
+       uint8_t *ecc_code = chip->buffers->ecccode;
        int *eccpos = chip->ecc.layout->eccpos;
 
        for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) {
        page = realpage & chip->pagemask;
 
        col = (int)(from & (mtd->writesize - 1));
-       chip->oob_poi = chip->buffers.oobrbuf;
+       chip->oob_poi = chip->buffers->oobrbuf;
 
        buf = ops->datbuf;
        oob = ops->oobbuf;
 
                /* Is the current page in the buffer ? */
                if (realpage != chip->pagebuf || oob) {
-                       bufpoi = aligned ? buf : chip->buffers.databuf;
+                       bufpoi = aligned ? buf : chip->buffers->databuf;
 
                        if (likely(sndcmd)) {
                                chip->cmdfunc(mtd, NAND_CMD_READ0, 0x00, page);
                        /* Transfer not aligned data */
                        if (!aligned) {
                                chip->pagebuf = realpage;
-                               memcpy(buf, chip->buffers.databuf + col, bytes);
+                               memcpy(buf, chip->buffers->databuf + col, bytes);
                        }
 
                        buf += bytes;
                                        nand_wait_ready(mtd);
                        }
                } else {
-                       memcpy(buf, chip->buffers.databuf + col, bytes);
+                       memcpy(buf, chip->buffers->databuf + col, bytes);
                        buf += bytes;
                }
 
        realpage = (int)(from >> chip->page_shift);
        page = realpage & chip->pagemask;
 
-       chip->oob_poi = chip->buffers.oobrbuf;
+       chip->oob_poi = chip->buffers->oobrbuf;
 
        while(1) {
                sndcmd = chip->ecc.read_oob(mtd, chip, page, sndcmd);
        int i, eccsize = chip->ecc.size;
        int eccbytes = chip->ecc.bytes;
        int eccsteps = chip->ecc.steps;
-       uint8_t *ecc_calc = chip->buffers.ecccalc;
+       uint8_t *ecc_calc = chip->buffers->ecccalc;
        const uint8_t *p = buf;
        int *eccpos = chip->ecc.layout->eccpos;
 
        int i, eccsize = chip->ecc.size;
        int eccbytes = chip->ecc.bytes;
        int eccsteps = chip->ecc.steps;
-       uint8_t *ecc_calc = chip->buffers.ecccalc;
+       uint8_t *ecc_calc = chip->buffers->ecccalc;
        const uint8_t *p = buf;
        int *eccpos = chip->ecc.layout->eccpos;
 
            (chip->pagebuf << chip->page_shift) < (to + ops->len))
                chip->pagebuf = -1;
 
-       chip->oob_poi = chip->buffers.oobwbuf;
+       chip->oob_poi = chip->buffers->oobwbuf;
 
        while(1) {
                int cached = writelen > bytes && page != blockmask;
        if (page == chip->pagebuf)
                chip->pagebuf = -1;
 
-       chip->oob_poi = chip->buffers.oobwbuf;
+       chip->oob_poi = chip->buffers->oobwbuf;
        memset(chip->oob_poi, 0xff, mtd->oobsize);
        nand_fill_oob(chip, ops->oobbuf, ops);
        status = chip->ecc.write_oob(mtd, chip, page & chip->pagemask);
        int i;
        struct nand_chip *chip = mtd->priv;
 
+       if (!(chip->options & NAND_OWN_BUFFERS))
+               chip->buffers = kmalloc(sizeof(*chip->buffers), GFP_KERNEL);
+       if (!chip->buffers)
+               return -ENOMEM;
+
        /* Preset the internal oob write buffer */
-       memset(chip->buffers.oobwbuf, 0xff, mtd->oobsize);
+       memset(chip->buffers->oobwbuf, 0xff, mtd->oobsize);
 
        /*
         * If no default placement scheme is given, select an appropriate one
 
        /* Free bad block table memory */
        kfree(chip->bbt);
+       if (!(chip->options & NAND_OWN_BUFFERS))
+               kfree(chip->buffers);
 }
 
 EXPORT_SYMBOL_GPL(nand_scan);