/*
- * 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-2010 Aleph One Ltd.
* for Toby Churchill Ltd and Brightstar Engineering
*
* Created by Charles Manning <charles@aleph1.co.uk>
* 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>
-#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)
typedef struct
{
- __u8 data[PAGE_TOTAL_SIZE]; // Data + spare
+ u8 data[PAGE_TOTAL_SIZE]; // Data + spare
int empty; // is this empty?
} nandemul_Page;
}
-static void nandemul2k_Read(void *buffer, int page, int start, int nBytes)
+static void nandemul2k_Read(void *buffer, int page, int start, int n_bytes)
{
int pg = page%PAGES_PER_BLOCK;
int blk = page/PAGES_PER_BLOCK;
- if(buffer && nBytes > 0)
+ if(buffer && n_bytes > 0)
{
- memcpy(buffer,&ned.block[blk]->page[pg]->data[start],nBytes);
+ memcpy(buffer,&ned.block[blk]->page[pg]->data[start],n_bytes);
}
}
-static void nandemul2k_Program(const void *buffer, int page, int start, int nBytes)
+static void nandemul2k_Program(const void *buffer, int page, int start, int n_bytes)
{
int pg = page%PAGES_PER_BLOCK;
int blk = page/PAGES_PER_BLOCK;
- __u8 *p;
- __u8 *b = (__u8 *)buffer;
+ u8 *p;
+ u8 *b = (u8 *)buffer;
p = &ned.block[blk]->page[pg]->data[start];
- while(buffer && nBytes>0)
+ while(buffer && n_bytes>0)
{
*p = *p & *b;
p++;
b++;
- nBytes--;
+ n_bytes--;
}
}
-int nandemul2k_ReadId(__u8 *vendorId, __u8 *deviceId)
+static int nandemul2k_ReadId(u8 *vendorId, u8 *deviceId)
{
*vendorId = 'Y';
*deviceId = '2';
}
-int nandemul2k_ReadStatus(__u8 *status)
+static int nandemul2k_ReadStatus(u8 *status)
{
*status = 0;
return 1;
*/
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,
- 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))
/* 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);
page = ((int) from) >> NAND_SHIFT;
/* Mask to get column */
- col = from & 0x0f;
+ col = from & (PAGE_SPARE_SIZE-1)
/* Initialize return length value */
*retlen = 0;
/* 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);
page = ((int) to) >> NAND_SHIFT;
/* Mask to get column */
- col = to & 0x0f;
+ col = to & PAGE_SPARE_SIZE;
/* Initialize return length value */
*retlen = 0;
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;
*/
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;
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;
mtd->suspend = NULL;
mtd->resume = NULL;
+ mtd->name = "NANDemul2k";
+
/* Return happy */
return 0;
}
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]);