/* FIXME: Use kiovec in 2.5 to lock down the user's buffers
           and pass them directly to the MTD functions */
+
+       if (count > MAX_KMALLOC_SIZE)
+               kbuf=kmalloc(MAX_KMALLOC_SIZE, GFP_KERNEL);
+       else
+               kbuf=kmalloc(count, GFP_KERNEL);
+
+       if (!kbuf)
+               return -ENOMEM;
+
        while (count) {
+
                if (count > MAX_KMALLOC_SIZE)
                        len = MAX_KMALLOC_SIZE;
                else
                        len = count;
 
-               kbuf=kmalloc(len,GFP_KERNEL);
-               if (!kbuf)
-                       return -ENOMEM;
-
                switch (MTD_MODE(file)) {
                case MTD_MODE_OTP_FACT:
                        ret = mtd->read_fact_prot_reg(mtd, *ppos, len, &retlen, kbuf);
                        return ret;
                }
 
-               kfree(kbuf);
        }
 
+       kfree(kbuf);
        return total_retlen;
 } /* mtd_read */
 
        if (!count)
                return 0;
 
+       if (count > MAX_KMALLOC_SIZE)
+               kbuf=kmalloc(MAX_KMALLOC_SIZE, GFP_KERNEL);
+       else
+               kbuf=kmalloc(count, GFP_KERNEL);
+
+       if (!kbuf)
+               return -ENOMEM;
+
        while (count) {
+
                if (count > MAX_KMALLOC_SIZE)
                        len = MAX_KMALLOC_SIZE;
                else
                        len = count;
 
-               kbuf=kmalloc(len,GFP_KERNEL);
-               if (!kbuf) {
-                       printk("kmalloc is null\n");
-                       return -ENOMEM;
-               }
-
                if (copy_from_user(kbuf, buf, len)) {
                        kfree(kbuf);
                        return -EFAULT;
                        kfree(kbuf);
                        return ret;
                }
-
-               kfree(kbuf);
        }
 
+       kfree(kbuf);
        return total_retlen;
 } /* mtd_write */