Some cleanups, Linux 2.6.25 handling, fix handing of root permissions
[yaffs2.git] / mtdemul / nandemul2k.c
index 2980f9a..7efa8d4 100644 (file)
@@ -1,7 +1,7 @@
 /*
- * YAFFS: Yet another FFS. A NAND-flash specific file system. 
+ * YAFFS: Yet Another Flash File System. A NAND-flash specific file system.
  *
- * Copyright (C) 2002 Aleph One Ltd.
+ * Copyright (C) 2002-2007 Aleph One Ltd.
  *   for Toby Churchill Ltd and Brightstar Engineering
  *
  * Created by Charles Manning <charles@aleph1.co.uk>
@@ -9,12 +9,13 @@
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
- *
- *
+ */
+
+/*
  *  This version hacked for emulating 2kpage NAND for YAFFS2 testing.
  */
 
-#include <linux/config.h>
+//#include <linux/config.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/version.h>
 #include <linux/mtd/mtd.h>
 #include <linux/interrupt.h>
 #include <linux/string.h>
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
 #include <linux/locks.h>
+#endif
 
 #include <asm/uaccess.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/partitions.h>
 #include <linux/mtd/nand.h>
+#include "../yaffs_nandemul2k.h"
 
-#define T(f,x) printk x
 #define ALLOCATE(x) kmalloc(x,GFP_KERNEL)
 #define FREE(x)     kfree(x)
 
 
 
 
-#define EM_SIZE_IN_MEG 4
-#define PAGE_DATA_SIZE  (2048)
-#define PAGE_SPARE_SIZE (64)
-#define PAGES_PER_BLOCK (64)
 #define NAND_SHIFT      (11)   // Shifter for 2k
+#define PAGE_DATA_SIZE  (1 << NAND_SHIFT)
+#define PAGE_SPARE_SIZE (64)
+#define BLK_SHIFT      6
+#define PAGES_PER_BLOCK (1 << BLK_SHIFT)       // = 64
 
 
+#define EM_SIZE_IN_MEG 4
 #define EM_SIZE_IN_BYTES (EM_SIZE_IN_MEG * (1<<20))
 
 #define PAGE_TOTAL_SIZE (PAGE_DATA_SIZE+PAGE_SPARE_SIZE)
@@ -251,7 +255,7 @@ int nandemul2k_GetNumberOfBlocks(void) {return nandemul2k_CalcNBlocks();}
 
 
 
-int nandemul2k_ReadId(__u8 *vendorId, __u8 *deviceId)
+static int nandemul2k_ReadId(__u8 *vendorId, __u8 *deviceId)
 {
        *vendorId = 'Y'; 
        *deviceId = '2';
@@ -260,7 +264,7 @@ int nandemul2k_ReadId(__u8 *vendorId, __u8 *deviceId)
 }
 
 
-int nandemul2k_ReadStatus(__u8 *status)
+static int nandemul2k_ReadStatus(__u8 *status)
 {
                *status = 0;
                return 1;
@@ -276,19 +280,19 @@ int nandemul2k_ReadStatus(__u8 *status)
  */
 static int nand_read (struct mtd_info *mtd, loff_t from, size_t len,
                        size_t *retlen, u_char *buf);
-static int nand_read_ecc (struct mtd_info *mtd, loff_t from, size_t len,
-                               size_t *retlen, u_char *buf, u_char *oob_buf, struct nand_oobinfo *dummy);
 static int nand_read_oob (struct mtd_info *mtd, loff_t from, size_t len,
                                size_t *retlen, u_char *buf);
 static int nand_write (struct mtd_info *mtd, loff_t to, size_t len,
                        size_t *retlen, const u_char *buf);
-static int nand_write_ecc (struct mtd_info *mtd, loff_t to, size_t len,
-                               size_t *retlen, const u_char *buf,
-                               const u_char *oob_buf, struct nand_oobinfo *dummy);
 static int nand_write_oob (struct mtd_info *mtd, loff_t to, size_t len,
                                size_t *retlen, const u_char *buf);
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,7))
+static int nand_writev (struct mtd_info *mtd, const struct kvec *vecs,
+                               unsigned long count, loff_t to, size_t *retlen);
+#else
 static int nand_writev (struct mtd_info *mtd, const struct iovec *vecs,
                                unsigned long count, loff_t to, size_t *retlen);
+#endif
 static int nand_erase (struct mtd_info *mtd, struct erase_info *instr);
 static void nand_sync (struct mtd_info *mtd);
 
@@ -334,17 +338,17 @@ static int nand_read_ecc (struct mtd_info *mtd, loff_t from, size_t len,
 
                /* Get raw starting column */
 
-               start = from & (mtd->oobblock-1);
+               start = from & (PAGE_DATA_SIZE - 1);
 
                // OK now check for the curveball where the start and end are in
                // the same page
-               if((start + n) < mtd->oobblock)
+               if((start + n) < PAGE_DATA_SIZE)
                {
                        nToCopy = n;
                }
                else
                {
-                       nToCopy =  mtd->oobblock - start;
+                       nToCopy =  PAGE_DATA_SIZE - start;
                }
 
                nandemul2k_Read(buf, page, start, nToCopy);
@@ -377,7 +381,7 @@ static int nand_read_oob (struct mtd_info *mtd, loff_t from, size_t len,
        page = ((int) from) >> NAND_SHIFT;
 
        /* Mask to get column */
-       col = from & 0x0f;
+       col = from & (PAGE_SPARE_SIZE-1)
 
        /* Initialize return length value */
        *retlen = 0;
@@ -411,7 +415,7 @@ static int nand_write (struct mtd_info *mtd, loff_t to, size_t len,
  */
 static int nand_write_ecc (struct mtd_info *mtd, loff_t to, size_t len,
                                size_t *retlen, const u_char *buf,
-                               const u_char *oob_buf, struct nand_oobinfo *dummy)
+                               u_char *oob_buf, struct nand_oobinfo *dummy)
 {
 
        int     start, page;
@@ -438,17 +442,17 @@ static int nand_write_ecc (struct mtd_info *mtd, loff_t to, size_t len,
 
                /* Get raw starting column */
 
-               start = to & (mtd->oobblock - 1);
+               start = to & (PAGE_DATA_SIZE - 1);
 
                // OK now check for the curveball where the start and end are in
                // the same page
-               if((start + n) < mtd->oobblock)
+               if((start + n) < PAGE_DATA_SIZE)
                {
                        nToCopy = n;
                }
                else
                {
-                       nToCopy =  mtd->oobblock - start;
+                       nToCopy =  PAGE_DATA_SIZE - start;
                }
 
                nandemul2k_Program(buf, page, start, nToCopy);
@@ -483,7 +487,7 @@ static int nand_write_oob (struct mtd_info *mtd, loff_t to, size_t len,
        page = ((int) to) >> NAND_SHIFT;
 
        /* Mask to get column */
-       col = to & 0x0f;
+       col = to & PAGE_SPARE_SIZE;
 
        /* Initialize return length value */
        *retlen = 0;
@@ -507,8 +511,13 @@ static int nand_write_oob (struct mtd_info *mtd, loff_t to, size_t len,
 /*
  * NAND write with iovec
  */
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,7))
+static int nand_writev (struct mtd_info *mtd, const struct kvec *vecs,
+                               unsigned long count, loff_t to, size_t *retlen)
+#else
 static int nand_writev (struct mtd_info *mtd, const struct iovec *vecs,
                                unsigned long count, loff_t to, size_t *retlen)
+#endif
 {
        return -EINVAL;
 }
@@ -545,16 +554,17 @@ static int nand_erase (struct mtd_info *mtd, struct erase_info *instr)
                return -EINVAL;
        }
 
-       nBlocks = instr->len >> (NAND_SHIFT + 5);
-       block = instr->addr >> (NAND_SHIFT + 5);
+       nBlocks = instr->len >> (NAND_SHIFT + BLK_SHIFT);
+       block = instr->addr >> (NAND_SHIFT + BLK_SHIFT);
 
        for(i = 0; i < nBlocks; i++)
        {
                nandemul2k_DoErase(block);
                block++;
        }
-
-
+       
+       instr->state = MTD_ERASE_DONE; /* Changed state to done */
+       instr->callback(instr);        /* ... and wake up */
 
        return 0;
 
@@ -562,12 +572,12 @@ static int nand_erase (struct mtd_info *mtd, struct erase_info *instr)
 }
 
 
-int nand_block_isbad(struct mtd_info *mtd,int blockNo)
+static int nand_block_isbad(struct mtd_info *mtd, loff_t ofs)
 {
        return 0;
 }
 
-int nand_block_markbad(struct mtd_info *mtd, int blockNo)
+static int nand_block_markbad(struct mtd_info *mtd, loff_t ofs)
 {
        return 0;
 }
@@ -585,10 +595,11 @@ static void nand_sync (struct mtd_info *mtd)
 /*
  * Scan for the NAND device
  */
-int nand_scan (struct mtd_info *mtd,int nchips)
+static int nandemul2k_scan (struct mtd_info *mtd,int nchips)
 {
-       mtd->oobblock = PAGE_DATA_SIZE;
-       mtd->oobsize =  PAGE_SPARE_SIZE;
+       mtd->writesize = PAGE_DATA_SIZE;
+       mtd->oobsize   = PAGE_SPARE_SIZE;
+       mtd->oobavail  = PAGE_SPARE_SIZE/2; /* Simulate using up some for other uses */
        mtd->erasesize = PAGE_DATA_SIZE * PAGES_PER_BLOCK;
        mtd->size = sizeInMB * 1024*1024;
 
@@ -598,14 +609,13 @@ int nand_scan (struct mtd_info *mtd,int nchips)
        mtd->type = MTD_NANDFLASH;
        mtd->flags = MTD_CAP_NANDFLASH;
        mtd->owner = THIS_MODULE;
-       mtd->ecctype = MTD_ECC_NONE;
        mtd->erase = nand_erase;
        mtd->point = NULL;
        mtd->unpoint = NULL;
        mtd->read = nand_read;
        mtd->write = nand_write;
-       mtd->read_ecc = nand_read_ecc;
-       mtd->write_ecc = nand_write_ecc;
+       mtd->read_oob = nand_read_oob;
+       mtd->write_oob = nand_write_oob;
        mtd->read_oob = nand_read_oob;
        mtd->write_oob = nand_write_oob;
        mtd->block_isbad = nand_block_isbad;
@@ -618,6 +628,8 @@ int nand_scan (struct mtd_info *mtd,int nchips)
        mtd->suspend = NULL;
        mtd->resume = NULL;
 
+       mtd->name = "NANDemul2k";
+
        /* Return happy */
        return 0;
 }
@@ -636,9 +648,9 @@ __setup("sizeInMB=",sizeInMB);
 
 static struct mtd_partition nandemul2k_partition[] =
 {
-       { name: "NANDemul partition 1",
-         offset:  0,
-         size: 0 },
+       { .name         = "NANDemul partition 1",
+         .offset       = 0,
+         .size         = 0 },
 };
 
 static int nPartitions = sizeof(nandemul2k_partition)/sizeof(nandemul2k_partition[0]);
@@ -653,7 +665,7 @@ int __init nandemul2k_init (void)
        
        CheckInit();
 
-       nand_scan(&nandemul2k_mtd,1);
+       nandemul2k_scan(&nandemul2k_mtd,1);
 
        // Build the partition table