<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
<HTML>
<HEAD>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=us-ascii">
<META NAME="Generator" CONTENT="MS Exchange Server version 6.5.7654.12">
<TITLE>[PATCH] MTD: Micron SPINAND Driver support</TITLE>
</HEAD>
<BODY>
<!-- Converted from text/rtf format -->
<BR>

<P><FONT SIZE=2 FACE="Courier New">This patch adds support for Micron SPINAND via MTD.</FONT>
</P>
<BR>

<P><FONT SIZE=2 FACE="Courier New">Signed-off-by: Mona Anonuevo (manonuevo@micron.com)</FONT>

<BR><FONT SIZE=2 FACE="Courier New">Signed-off-by: Tuan Nguyen (tqnguyen@micron.com)</FONT>

<BR><FONT SIZE=2 FACE="Courier New">----</FONT>

<BR><FONT SIZE=2 FACE="Courier New">&nbsp;drivers/mtd/Kconfig&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |&nbsp;&nbsp;&nbsp; 2 </FONT>

<BR><FONT SIZE=2 FACE="Courier New">&nbsp;drivers/mtd/Makefile&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |&nbsp;&nbsp;&nbsp; 2 </FONT>

<BR><FONT SIZE=2 FACE="Courier New">&nbsp;drivers/mtd/spinand/Kconfig&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |&nbsp;&nbsp; 25 +</FONT>

<BR><FONT SIZE=2 FACE="Courier New">&nbsp;drivers/mtd/spinand/Makefile&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |&nbsp;&nbsp; 10 </FONT>

<BR><FONT SIZE=2 FACE="Courier New">&nbsp;drivers/mtd/spinand/spinand_lld.c |&nbsp; 760 ++++++++++++++++++++++++++++++++++++++</FONT>

<BR><FONT SIZE=2 FACE="Courier New">&nbsp;drivers/mtd/spinand/spinand_mtd.c |&nbsp; 728 ++++++++++++++++++++++++++++++++++++</FONT>

<BR><FONT SIZE=2 FACE="Courier New">&nbsp;include/linux/mtd/spinand.h&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |&nbsp; 160 ++++++++</FONT>

<BR><FONT SIZE=2 FACE="Courier New">&nbsp;7 files changed, 1687 insertions(+)</FONT>
</P>

<P><FONT SIZE=2 FACE="Courier New">PATCH FOLLOWS</FONT>

<BR><FONT SIZE=2 FACE="Courier New">Kernel Version:&nbsp; Linux 2.6.33.20</FONT>

<BR><FONT SIZE=2 FACE="Courier New">diff -urN linux-2.6.33.20-orig/drivers/mtd/Kconfig linux-2.6.33.20/drivers/mtd/Kconfig</FONT>

<BR><FONT SIZE=2 FACE="Courier New">--- linux-2.6.33.20-orig/drivers/mtd/Kconfig&nbsp;&nbsp;&nbsp; 2010-04-01 16:02:33.000000000 -0700</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+++ linux-2.6.33.20/drivers/mtd/Kconfig 2010-05-19 04:28:06.000000000 -0700</FONT>

<BR><FONT SIZE=2 FACE="Courier New">@@ -325,6 +325,8 @@</FONT>

<BR><FONT SIZE=2 FACE="Courier New">&nbsp;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">&nbsp;source &quot;drivers/mtd/onenand/Kconfig&quot;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">&nbsp;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+source &quot;drivers/mtd/spinand/Kconfig&quot;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">&nbsp;source &quot;drivers/mtd/lpddr/Kconfig&quot;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">&nbsp;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">&nbsp;source &quot;drivers/mtd/ubi/Kconfig&quot;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">diff -urN linux-2.6.33.20-orig/drivers/mtd/Makefile linux-2.6.33.20/drivers/mtd/Makefile</FONT>

<BR><FONT SIZE=2 FACE="Courier New">--- linux-2.6.33.20-orig/drivers/mtd/Makefile&nbsp;&nbsp; 2010-04-01 16:02:33.000000000 -0700</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+++ linux-2.6.33.20/drivers/mtd/Makefile&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2010-05-19 04:28:06.000000000 -0700</FONT>

<BR><FONT SIZE=2 FACE="Courier New">@@ -31,4 +31,6 @@</FONT>

<BR><FONT SIZE=2 FACE="Courier New">&nbsp;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">&nbsp;obj-y&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; += chips/ lpddr/ maps/ devices/ nand/ onenand/ tests/</FONT>

<BR><FONT SIZE=2 FACE="Courier New">&nbsp;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+obj-y&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; += spinand/ </FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">&nbsp;obj-$(CONFIG_MTD_UBI)&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; += ubi/</FONT>

<BR><FONT SIZE=2 FACE="Courier New">diff -urN linux-2.6.33.20-orig/drivers/mtd/spinand/Kconfig linux-2.6.33.20/drivers/mtd/spinand/Kconfig</FONT>

<BR><FONT SIZE=2 FACE="Courier New">--- linux-2.6.33.20-orig/drivers/mtd/spinand/Kconfig&nbsp;&nbsp;&nbsp; 1969-12-31 16:00:00.000000000 -0800</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+++ linux-2.6.33.20/drivers/mtd/spinand/Kconfig 2010-05-19 04:28:06.000000000 -0700</FONT>

<BR><FONT SIZE=2 FACE="Courier New">@@ -0,0 +1,25 @@</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+#</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+# linux/drivers/mtd/spinand/Kconfig</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+#</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+menuconfig MTD_SPINAND</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; tristate &quot;SPINAND Device Support&quot;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; depends on MTD</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; help</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp; This enables support for accessing Micron SPI NAND flash</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp; devices.</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+if MTD_SPINAND</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+config MTD_SPINAND_ONDIEECC</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; bool &quot;Use SPINAND internal ECC&quot;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; help</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Internel ECC</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+config MTD_SPINAND_SWECC</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; bool &quot;Use software ECC&quot;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; depends on MTD_NAND</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; help</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; software ECC</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+endif</FONT>

<BR><FONT SIZE=2 FACE="Courier New">diff -urN linux-2.6.33.20-orig/drivers/mtd/spinand/Makefile linux-2.6.33.20/drivers/mtd/spinand/Makefile</FONT>

<BR><FONT SIZE=2 FACE="Courier New">--- linux-2.6.33.20-orig/drivers/mtd/spinand/Makefile&nbsp;&nbsp; 1969-12-31 16:00:00.000000000 -0800</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+++ linux-2.6.33.20/drivers/mtd/spinand/Makefile&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2010-05-19 04:28:07.000000000 -0700</FONT>

<BR><FONT SIZE=2 FACE="Courier New">@@ -0,0 +1,10 @@</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+#</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+# Makefile for the SPI NAND MTD</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+#</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+# Core functionality.</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+obj-$(CONFIG_MTD_SPINAND)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; += spinand.o</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+spinand-objs := spinand_mtd.o spinand_lld.o</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">diff -urN linux-2.6.33.20-orig/drivers/mtd/spinand/spinand_lld.c linux-2.6.33.20/drivers/mtd/spinand/spinand_lld.c</FONT>

<BR><FONT SIZE=2 FACE="Courier New">--- linux-2.6.33.20-orig/drivers/mtd/spinand/spinand_lld.c&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1969-12-31 16:00:00.000000000 -0800</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+++ linux-2.6.33.20/drivers/mtd/spinand/spinand_lld.c&nbsp;&nbsp; 2010-05-19 03:56:51.000000000 -0700</FONT>

<BR><FONT SIZE=2 FACE="Courier New">@@ -0,0 +1,760 @@</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+/*</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+spinand_lld.c</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+Copyright (c) 2009-2010 Micron Technology, Inc.</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+This program is free software; you can redistribute it and/or</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+modify it under the terms of the GNU General Public License</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+as published by the Free Software Foundation; either version 2</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+of the License, or (at your option) any later version.</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+This program is distributed in the hope that it will be useful,</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+but WITHOUT ANY WARRANTY; without even the implied warranty of</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.&nbsp; See the</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+GNU General Public License for more details.</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+*/</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+#include &lt;linux/init.h&gt;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+#include &lt;linux/module.h&gt;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+#include &lt;linux/device.h&gt;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+#include &lt;linux/interrupt.h&gt;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+#include &lt;linux/mutex.h&gt;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+#include &lt;linux/math64.h&gt;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+#include &lt;linux/mtd/mtd.h&gt;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+#include &lt;linux/mtd/partitions.h&gt;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+#include &lt;linux/mtd/spinand.h&gt;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+#include &lt;linux/spi/spi.h&gt;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+#define mu_spi_nand_driver_version &quot;Beagle-MTD_01.00_Linux2.6.33_20100507&quot;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+#define SPI_NAND_MICRON_DRIVER_KEY 0x1233567</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+/****************************************************************************/</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+/**</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp; OOB area specification layout:&nbsp; Total 32 available free bytes.</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+*/</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+static struct nand_ecclayout spinand_oob_64 = {</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .eccbytes = 24,</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .eccpos = {</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; 1, 2, 3, 4, 5, 6,</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; 17, 18, 19, 20, 21, 22,</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; 33, 34, 35, 36, 37, 38,</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; 49, 50, 51, 52, 53, 54, },</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .oobavail = 32,</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .oobfree = {</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {.offset = 8,</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .length = 8},</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {.offset = 24,</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .length = 8},</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {.offset = 40,</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .length = 8},</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {.offset = 56,</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .length = 8}, }</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+};</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+/**</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ * spinand_cmd - to process a command to send to the SPI Nand</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ * </FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ * Description:</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ *&nbsp;&nbsp;&nbsp; Set up the command buffer to send to the SPI controller.</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ *&nbsp;&nbsp;&nbsp; The command buffer has to initized to 0</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ */</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+int spinand_cmd(struct spi_device *spi, struct spinand_cmd *cmd)</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+{</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ret;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct spi_message&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; message;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct spi_transfer&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; x[4];</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; u8 dummy = 0xff;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; spi_message_init(&amp;message);</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; memset(x, 0, sizeof x);</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; x[0].len = 1;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; x[0].tx_buf = &amp;cmd-&gt;cmd;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; spi_message_add_tail(&amp;x[0], &amp;message);</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (cmd-&gt;n_addr)</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; x[1].len = cmd-&gt;n_addr;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; x[1].tx_buf = cmd-&gt;addr;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; spi_message_add_tail(&amp;x[1], &amp;message);</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (cmd-&gt;n_dummy)</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; x[2].len = cmd-&gt;n_dummy;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; x[2].tx_buf = &amp;dummy;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; spi_message_add_tail(&amp;x[2], &amp;message);&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (cmd-&gt;n_tx)</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; x[3].len = cmd-&gt;n_tx;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; x[3].tx_buf = cmd-&gt;tx_buf;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; spi_message_add_tail(&amp;x[3], &amp;message);&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (cmd-&gt;n_rx)</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; x[3].len = cmd-&gt;n_rx;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; x[3].rx_buf = cmd-&gt;rx_buf;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; spi_message_add_tail(&amp;x[3], &amp;message);&nbsp; </FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ret = spi_sync(spi, &amp;message);</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return ret; </FONT>

<BR><FONT SIZE=2 FACE="Courier New">+}</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+/**</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ * spinand_reset- send reset command &quot;0xff&quot; to the Nand device</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ * </FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ * Description:</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ *&nbsp;&nbsp;&nbsp; Reset the SPI Nand with the reset command 0xff</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ */</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+static int spinand_reset(struct spi_device *spi_nand)</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+{</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct spinand_cmd cmd = {0};</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cmd.cmd = CMD_RESET;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return spinand_cmd(spi_nand, &amp;cmd);</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+}</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+/**</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ * spinand_read_id- Read SPI Nand ID</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ * </FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ * Description:</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ *&nbsp;&nbsp;&nbsp; Read ID: read two ID bytes from the SPI Nand device</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ */</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+static int spinand_read_id(struct spi_device *spi_nand, u8 *id)</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+{</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct spinand_cmd cmd = {0};</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ssize_t retval;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cmd.cmd = CMD_READ_ID;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cmd.n_dummy = 1;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cmd.n_rx = 2;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cmd.rx_buf = id;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; retval = spinand_cmd(spi_nand, &amp;cmd);</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (retval != 0) {</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dev_err(&amp;spi_nand-&gt;dev, &quot;error %d reading id\n&quot;,</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (int) retval);</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return retval;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return 0;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </FONT>

<BR><FONT SIZE=2 FACE="Courier New">+}</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+/**</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ * spinand_lock_block- send write register 0x1f command to the Nand device</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ * </FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ * Description:</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ *&nbsp;&nbsp;&nbsp; After power up, all the Nand blocks are locked.&nbsp; This function allows</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ *&nbsp;&nbsp;&nbsp; one to unlock the blocks, and so it can be wriiten or erased.</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ */</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+static int spinand_lock_block(struct spi_device *spi_nand, struct spinand_info *info, u8 lock)</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+{</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct spinand_cmd cmd = {0};</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ssize_t retval;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cmd.cmd = CMD_WRITE_REG;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cmd.n_addr = 1;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cmd.addr[0] = REG_BLOCK_LOCK;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cmd.n_tx = 1;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cmd.tx_buf = &amp;lock;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; retval = spinand_cmd(spi_nand, &amp;cmd);</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (retval != 0) {</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dev_err(&amp;spi_nand-&gt;dev, &quot;error %d lock block\n&quot;,</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (int) retval);</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return retval;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return 0;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </FONT>

<BR><FONT SIZE=2 FACE="Courier New">+}</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+/**</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ * spinand_read_status- send command 0xf to the SPI Nand status register</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ * </FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ * Description:</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ *&nbsp;&nbsp;&nbsp; After read, write, or erase, the Nand device is expected to set the busy status.</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ *&nbsp;&nbsp;&nbsp; This function is to allow reading the status of the command: read, write, and erase.</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ *&nbsp;&nbsp;&nbsp; Once the status turns to be ready, the other status bits also are valid status bits.</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ */</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+static int spinand_read_status(struct spi_device *spi_nand, struct spinand_info *info, u8 *status)</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+{</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct spinand_cmd cmd = {0};</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ssize_t retval;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cmd.cmd = CMD_READ_REG;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cmd.n_addr = 1;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cmd.addr[0] = REG_STATUS;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cmd.n_rx = 1;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cmd.rx_buf = status;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; retval = spinand_cmd(spi_nand, &amp;cmd);</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (retval != 0) {</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dev_err(&amp;spi_nand-&gt;dev, &quot;error %d reading status register\n&quot;,</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (int) retval);</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return retval;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return 0;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+}</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+/**</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ * spinand_get_otp- send command 0xf to read the SPI Nand OTP register</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ * </FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ * Description:</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ *&nbsp;&nbsp; There is one bit( bit 0x10 ) to set or to clear the internal ECC.</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ *&nbsp;&nbsp; Enable chip internal ECC, set the bit to 1</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ *&nbsp;&nbsp; Disable chip internal ECC, clear the bit to 0</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ */</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+static int spinand_get_otp(struct spi_device *spi_nand, struct spinand_info *info, u8* otp)</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+{</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct spinand_cmd cmd = {0};</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ssize_t retval;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cmd.cmd = CMD_READ_REG;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cmd.n_addr = 1;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cmd.addr[0] = REG_OTP;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cmd.n_rx = 1;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cmd.rx_buf = otp;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; retval = spinand_cmd(spi_nand, &amp;cmd);</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (retval != 0) {</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dev_err(&amp;spi_nand-&gt;dev, &quot;error %d get otp\n&quot;,</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (int) retval);</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return retval;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return 0;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </FONT>

<BR><FONT SIZE=2 FACE="Courier New">+}</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+/**</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ * spinand_set_otp- send command 0x1f to write the SPI Nand OTP register</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ * </FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ * Description:</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ *&nbsp;&nbsp; There is one bit( bit 0x10 ) to set or to clear the internal ECC.</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ *&nbsp;&nbsp; Enable chip internal ECC, set the bit to 1</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ *&nbsp;&nbsp; Disable chip internal ECC, clear the bit to 0</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ */</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+static int spinand_set_otp(struct spi_device *spi_nand, struct spinand_info *info, u8* otp)</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+{</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct spinand_cmd cmd = {0};</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ssize_t retval;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cmd.cmd = CMD_WRITE_REG;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cmd.n_addr = 1;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cmd.addr[0] = REG_OTP;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cmd.n_tx = 1;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cmd.tx_buf = otp;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; retval = spinand_cmd(spi_nand, &amp;cmd);</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (retval != 0) {</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dev_err(&amp;spi_nand-&gt;dev, &quot;error %d set otp\n&quot;,</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (int) retval);</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return retval;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return 0;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+}</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+/**</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ * sspinand_enable_ecc- send command 0x1f to write the SPI Nand OTP register</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ * </FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ * Description:</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ *&nbsp;&nbsp; There is one bit( bit 0x10 ) to set or to clear the internal ECC.</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ *&nbsp;&nbsp; Enable chip internal ECC, set the bit to 1</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ *&nbsp;&nbsp; Disable chip internal ECC, clear the bit to 0</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ */</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+static int spinand_enable_ecc(struct spi_device *spi_nand, struct spinand_info *info)</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+{</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ssize_t retval;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; u8 otp = 0;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; retval = spinand_get_otp(spi_nand, info, &amp;otp);</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if ((otp &amp; OTP_ECC_MASK) == OTP_ECC_MASK)</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return 0;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; otp |= OTP_ECC_MASK;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; retval = spinand_set_otp(spi_nand, info, &amp;otp);</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; retval = spinand_get_otp(spi_nand, info, &amp;otp);</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return retval;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+}</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+static int spinand_disable_ecc(struct spi_device *spi_nand, struct spinand_info *info)</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+{</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ssize_t retval;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; u8 otp = 0;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; retval = spinand_get_otp(spi_nand, info, &amp;otp);</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if ((otp &amp; OTP_ECC_MASK) == OTP_ECC_MASK)</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; otp &amp;= ~OTP_ECC_MASK;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; retval = spinand_set_otp(spi_nand, info, &amp;otp);</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; retval = spinand_get_otp(spi_nand, info, &amp;otp);</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return retval;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return 0;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+}</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+/**</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ * sspinand_write_enable- send command 0x06 to enable write or erase the Nand cells</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ * </FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ * Description:</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ *&nbsp;&nbsp; Before write and erase the Nand cells, the write enable has to be set.</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ *&nbsp;&nbsp; After the write or erase, the write enable bit is automatically cleared( status register bit 2 )</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ *&nbsp;&nbsp; Set the bit 2 of the status register has the same effect</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ */</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+static int spinand_write_enable(struct spi_device *spi_nand, struct spinand_info *info)</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+{</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct spinand_cmd cmd = {0};</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cmd.cmd = CMD_WR_ENABLE;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return spinand_cmd(spi_nand, &amp;cmd);</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+}</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+static int spinand_read_page_to_cache(struct spi_device *spi_nand, struct spinand_info *info, u16 page_id)</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+{</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct spinand_cmd cmd = {0};</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; u16 row;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; row = page_id;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cmd.cmd = CMD_READ;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cmd.n_addr = 3;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cmd.addr[1] = (u8)((row&amp;0xff00)&gt;&gt;8);</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cmd.addr[2] = (u8)(row&amp;0x00ff);</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return spinand_cmd(spi_nand, &amp;cmd);</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+}</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+/**</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ * spinand_read_from_cache- send command 0x03 to read out the data from the cache register( 2112 bytes max )</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ * </FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ * Description:</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ *&nbsp;&nbsp; The read can specify 1 to 2112 bytes of data read at the coresponded locations.</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ *&nbsp;&nbsp; No tRd delay.</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ */</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+static int spinand_read_from_cache(struct spi_device *spi_nand, struct spinand_info *info, u16 byte_id, u16 len, u8* rbuf)</FONT></P>

<P><FONT SIZE=2 FACE="Courier New">+{</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct spinand_cmd cmd = {0};</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; u16 column;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; column = byte_id;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cmd.cmd = CMD_READ_RDM;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cmd.n_addr = 2;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cmd.addr[0] = (u8)((column&amp;0xff00)&gt;&gt;8);</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cmd.addr[1] = (u8)(column&amp;0x00ff);</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cmd.n_dummy = 1;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cmd.n_rx = len;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cmd.rx_buf = rbuf;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return spinand_cmd(spi_nand, &amp;cmd);&nbsp;&nbsp;&nbsp;&nbsp; </FONT>

<BR><FONT SIZE=2 FACE="Courier New">+}</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+/**</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ * spinand_read_page-to read a page with:</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ * @page_id: the physical page number</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ * @offset:&nbsp; the location from 0 to 2111</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ * @len:&nbsp;&nbsp;&nbsp;&nbsp; number of bytes to read</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ * @rbuf:&nbsp;&nbsp;&nbsp; read buffer to hold @len bytes</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ *</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ * Description:</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ *&nbsp;&nbsp; The read icludes two commands to the Nand: 0x13 and 0x03 commands</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ *&nbsp;&nbsp; Poll to read status to wait for tRD time.</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ */</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+static int spinand_read_page(struct spi_device *spi_nand, struct spinand_info *info, u16 page_id, u16 offset, u16 len, u8* rbuf)</FONT></P>

<P><FONT SIZE=2 FACE="Courier New">+{</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ssize_t retval;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; u8 status = 0;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; retval = spinand_read_page_to_cache(spi_nand, info, page_id);</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while (1)</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; retval = spinand_read_status(spi_nand, info, &amp;status);</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (retval&lt;0) {</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dev_err(&amp;spi_nand-&gt;dev, &quot;error %d reading status register\n&quot;,</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (int) retval);</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return retval;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if ((status &amp; STATUS_OIP_MASK) == STATUS_READY)</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if ((status &amp; STATUS_ECC_MASK) == STATUS_ECC_ERROR)</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dev_err(&amp;spi_nand-&gt;dev, &quot;ecc error, page=%d\n&quot;, page_id);</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (spi_nand == SPI_NAND_MICRON_DRIVER_KEY)</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printk(KERN_INFO &quot;Error: reformat or erase your device. \n&quot;); </FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return -1;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; retval = spinand_read_from_cache(spi_nand, info, offset, len, rbuf);</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return 0;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </FONT>

<BR><FONT SIZE=2 FACE="Courier New">+}</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+/**</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ * spinand_program_data_to_cache--to write a page to cache with:</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ * @byte_id: the location to write to the cache</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ * @len:&nbsp;&nbsp;&nbsp;&nbsp; number of bytes to write</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ * @rbuf:&nbsp;&nbsp;&nbsp; read buffer to hold @len bytes</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ *</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ * Description:</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ *&nbsp;&nbsp; The write command used here is 0x84--indicating that the cache is not cleared first.</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ *&nbsp;&nbsp; Since it is writing the data to cache, there is no tPROG time.</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ */</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+static int spinand_program_data_to_cache(struct spi_device *spi_nand, struct spinand_info *info, u16 byte_id, u16 len, u8* wbuf)</FONT></P>

<P><FONT SIZE=2 FACE="Courier New">+{</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct spinand_cmd cmd = {0};</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; u16 column;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; column = byte_id;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cmd.cmd = CMD_PROG_PAGE_CLRCACHE;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cmd.n_addr = 2;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cmd.addr[0] = (u8)((column&amp;0xff00)&gt;&gt;8);</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cmd.addr[1] = (u8)(column&amp;0x00ff);</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cmd.n_tx = len;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cmd.tx_buf = wbuf;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return spinand_cmd(spi_nand, &amp;cmd);</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+}</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+/**</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ * spinand_program_execute--to write a page from cache to the Nand array with:</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ * @page_id: the physical page location to write the page.</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ *</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ * Description:</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ *&nbsp;&nbsp; The write command used here is 0x10--indicating the cache is writing to the Nand array.</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ *&nbsp;&nbsp; Need to wait for tPROG time to finish the transaction.</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ */</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+static int spinand_program_execute(struct spi_device *spi_nand, struct spinand_info *info, u16 page_id)</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+{</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct spinand_cmd cmd = {0};</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; u16 row;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; row = page_id;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cmd.cmd = CMD_PROG_PAGE_EXC;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cmd.n_addr = 3;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cmd.addr[1] = (u8)((row&amp;0xff00)&gt;&gt;8);</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cmd.addr[2] = (u8)(row&amp;0x00ff);</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return spinand_cmd(spi_nand, &amp;cmd);</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+}</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+/**</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ * spinand_program_page--to write a page with:</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ * @page_id: the physical page location to write the page.</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ * @offset:&nbsp; the location from the cache starting from 0 to 2111</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ * @len:&nbsp;&nbsp;&nbsp;&nbsp; the number of bytes to write </FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ * @wbuf:&nbsp;&nbsp;&nbsp; the buffer to hold the number of bytes</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ *</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ * Description:</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ *&nbsp;&nbsp; The commands used here are 0x06, 0x84, and 0x10--indicating that the write enable is first</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ *&nbsp;&nbsp; sent, the write cache command, and the write execute command</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ *&nbsp;&nbsp; Poll to wait for the tPROG time to finish the transaction.</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ */</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+static int spinand_program_page(struct spi_device *spi_nand, struct spinand_info *info, u16 page_id, u16 offset, u16 len, u8* wbuf)</FONT></P>

<P><FONT SIZE=2 FACE="Courier New">+{</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ssize_t retval;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; u8 status = 0;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; retval = spinand_write_enable(spi_nand, info);</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; retval = spinand_program_data_to_cache(spi_nand, info, offset, len, wbuf);</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; retval = spinand_program_execute(spi_nand, info, page_id);</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while (1)</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; retval = spinand_read_status(spi_nand, info, &amp;status);</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (retval&lt;0) {</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dev_err(&amp;spi_nand-&gt;dev, &quot;error %d reading status register\n&quot;,</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (int) retval);</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return retval;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if ((status &amp; STATUS_OIP_MASK) == STATUS_READY)</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if ((status &amp; STATUS_P_FAIL_MASK) == STATUS_P_FAIL)</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dev_err(&amp;spi_nand-&gt;dev, &quot;program error, page=%d\n&quot;, page_id);</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return -1;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return 0;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+}</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+/**</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ * spinand_erase_block_erase--to erase a page with:</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ * @block_id: the physical block location to erase.</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ *</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ * Description:</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ *&nbsp;&nbsp; The command used here is 0xd8--indicating an erase command to erase one block--64 pages</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ *&nbsp;&nbsp; Need to wait for tERS.</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ */</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+static int spinand_erase_block_erase(struct spi_device *spi_nand, struct spinand_info *info, u16 block_id)</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+{</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct spinand_cmd cmd = {0};</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; u16 row;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; row = block_id &lt;&lt; 6;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cmd.cmd = CMD_ERASE_BLK;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cmd.n_addr = 3;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cmd.addr[1] = (u8)((row&amp;0xff00)&gt;&gt;8);</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cmd.addr[2] = (u8)(row&amp;0x00ff);</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return spinand_cmd(spi_nand, &amp;cmd);&nbsp;&nbsp;&nbsp;&nbsp; </FONT>

<BR><FONT SIZE=2 FACE="Courier New">+}</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+/**</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ * spinand_erase_block--to erase a page with:</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ * @block_id: the physical block location to erase.</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ *</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ * Description:</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ *&nbsp;&nbsp; The commands used here are 0x06 and 0xd8--indicating an erase command to erase one block--64 pages</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ *&nbsp;&nbsp; It will first to enable the write enable bit ( 0x06 command ), and then send the 0xd8 erase command</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ *&nbsp;&nbsp; Poll to wait for the tERS time to complete the tranaction.</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ */</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+static int spinand_erase_block(struct spi_device *spi_nand, struct spinand_info *info, u16 block_id)</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+{</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ssize_t retval;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; u8 status= 0;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; retval = spinand_write_enable(spi_nand, info);</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; retval = spinand_erase_block_erase(spi_nand, info, block_id);</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while (1)</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; retval = spinand_read_status(spi_nand, info, &amp;status);</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (retval&lt;0) {</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dev_err(&amp;spi_nand-&gt;dev, &quot;error %d reading status register\n&quot;,</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (int) retval);</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return retval;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if ((status &amp; STATUS_OIP_MASK) == STATUS_READY)</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if ((status &amp; STATUS_E_FAIL_MASK) == STATUS_E_FAIL)</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dev_err(&amp;spi_nand-&gt;dev, &quot;erase error, block=%d\n&quot;, block_id);</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return -1;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return 0;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+}</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+/*</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+* spinand_get_info: get NAND info, from read id or const value </FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ * Description:</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ *&nbsp;&nbsp; To set up the device parameters.</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ */</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+static int spinand_get_info(struct spi_device *spi_nand, struct spinand_info *info, u8* id)</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+{</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (id[0]==0x2C &amp;&amp; (id[1]==0x11 || id[1]==0x12 || id[1]==0x13))</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; info-&gt;mid = id[0];</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; info-&gt;did = id[1];</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; info-&gt;name = &quot;MT29F1G01ZAC&quot;;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; info-&gt;nand_size = (1024 * 64 * 2112);</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; info-&gt;usable_size = (1024 * 64 * 2048);</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; info-&gt;block_size = (2112*64);</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; info-&gt;block_main_size = (2048*64);</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; info-&gt;block_num_per_chip = 1024;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; info-&gt;page_size = 2112;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; info-&gt;page_main_size = 2048;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; info-&gt;page_spare_size = 64;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; info-&gt;page_num_per_block = 64;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; info-&gt;block_shift = 17;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; info-&gt;block_mask = 0x1ffff;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; info-&gt;page_shift = 11;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; info-&gt;page_mask = 0x7ff;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; info-&gt;ecclayout = &amp;spinand_oob_64;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return 0;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+}</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+/**</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ * spinand_probe - [spinand Interface] </FONT>

<BR><FONT SIZE=2 FACE="Courier New">+* @spi_nand: registered device driver.</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ *</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ * Description:</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ *&nbsp;&nbsp; To set up the device driver parameters to make the device available.</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ */</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+static int __devinit spinand_probe(struct spi_device *spi_nand)</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+{</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ssize_t retval;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct mtd_info *mtd;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct spinand_chip *chip; </FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct spinand_info *info;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; u8 id[2]= {0};</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; retval = spinand_reset(spi_nand);</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; retval = spinand_reset(spi_nand);</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; retval = spinand_read_id(spi_nand, (u8*)&amp;id);</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (id[0]==0 &amp;&amp; id[1]==0)</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printk(KERN_INFO &quot;SPINAND: read id error! 0x%02x, 0x%02x!\n&quot;, id[0], id[1]); </FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return 0;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; info&nbsp; = kzalloc(sizeof(struct spinand_info), GFP_KERNEL);</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (!info)</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return -ENOMEM;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; retval = spinand_get_info(spi_nand, info, (u8*)&amp;id);</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printk(KERN_INFO &quot;SPINAND: 0x%02x, 0x%02x, %s\n&quot;, id[0], id[1], info-&gt;name); </FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printk(KERN_INFO &quot;%s\n&quot;, mu_spi_nand_driver_version);</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; retval = spinand_lock_block(spi_nand, info, BL_ALL_UNLOCKED);</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+#ifdef CONFIG_MTD_SPINAND_ONDIEECC</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; retval = spinand_enable_ecc(spi_nand, info);</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+#else</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; retval = spinand_disable_ecc(spi_nand, info);</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+#endif</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; chip&nbsp; = kzalloc(sizeof(struct spinand_chip), GFP_KERNEL);</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (!chip)</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return -ENOMEM;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; chip-&gt;spi_nand = spi_nand;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; chip-&gt;info = info;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; chip-&gt;reset = spinand_reset;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; chip-&gt;read_id = spinand_read_id;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; chip-&gt;read_page = spinand_read_page;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; chip-&gt;program_page = spinand_program_page;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; chip-&gt;erase_block = spinand_erase_block;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; chip-&gt;buf = kzalloc(info-&gt;page_size, GFP_KERNEL);</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (!chip-&gt;buf)</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return -ENOMEM;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; chip-&gt;oobbuf = kzalloc(info-&gt;ecclayout-&gt;oobavail, GFP_KERNEL);</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (!chip-&gt;oobbuf)</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return -ENOMEM;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mtd = kzalloc(sizeof(struct mtd_info), GFP_KERNEL);</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (!mtd)</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return -ENOMEM;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dev_set_drvdata(&amp;spi_nand-&gt;dev, mtd);</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mtd-&gt;priv = chip;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; retval = spinand_mtd(mtd);</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return retval;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+}</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+/**</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ * __devexit spinand_remove--Remove the device driver</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ * @spi: the spi device.</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ *</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ * Description:</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ *&nbsp;&nbsp; To remove the device driver parameters and free up allocated memories.</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ */</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+static int __devexit spinand_remove(struct spi_device *spi)</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+{</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct mtd_info *mtd;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct spinand_chip *chip; </FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DEBUG(MTD_DEBUG_LEVEL1, &quot;%s: remove\n&quot;, dev_name(&amp;spi-&gt;dev));</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mtd = dev_get_drvdata(&amp;spi-&gt;dev);</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; spinand_mtd_release(mtd);</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; chip = mtd-&gt;priv;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; kfree(chip-&gt;info);</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; kfree(chip-&gt;buf);</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; kfree(chip-&gt;oobbuf);</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; kfree(chip);</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; kfree(mtd);</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return 0;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+}</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+/**</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ * Device name structure description</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+*/</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+static struct spi_driver spinand_driver = {</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .driver = {</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .name&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; = &quot;spi_nand&quot;,</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .bus&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; = &amp;spi_bus_type,</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .owner&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; = THIS_MODULE,</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; },</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .probe&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; = spinand_probe,</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .remove &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; = __devexit_p(spinand_remove),</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+};</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+/**</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ * Device driver registration</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+*/</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+static int __init spinand_init(void)</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+{</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return spi_register_driver(&amp;spinand_driver);</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+}</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+/**</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ * unregister Device driver.</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+*/</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+static void __exit spinand_exit(void)</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+{</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; spi_unregister_driver(&amp;spinand_driver);</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+}</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+module_init(spinand_init);</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+module_exit(spinand_exit);</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+MODULE_LICENSE(&quot;GPL&quot;);</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+MODULE_AUTHOR(&quot;Henry Pan &lt;hspan@micron.com&gt;&quot;);</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+MODULE_DESCRIPTION(&quot;SPI NAND driver code&quot;);</FONT>

<BR><FONT SIZE=2 FACE="Courier New">diff -urN linux-2.6.33.20-orig/drivers/mtd/spinand/spinand_mtd.c linux-2.6.33.20/drivers/mtd/spinand/spinand_mtd.c</FONT>

<BR><FONT SIZE=2 FACE="Courier New">--- linux-2.6.33.20-orig/drivers/mtd/spinand/spinand_mtd.c&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1969-12-31 16:00:00.000000000 -0800</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+++ linux-2.6.33.20/drivers/mtd/spinand/spinand_mtd.c&nbsp;&nbsp; 2010-05-19 04:28:07.000000000 -0700</FONT>

<BR><FONT SIZE=2 FACE="Courier New">@@ -0,0 +1,728 @@</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+/*</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+spinand_mtd.c</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+Copyright (c) 2009-2010 Micron Technology, Inc.</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+This program is free software; you can redistribute it and/or</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+modify it under the terms of the GNU General Public License</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+as published by the Free Software Foundation; either version 2</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+of the License, or (at your option) any later version.</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+This program is distributed in the hope that it will be useful,</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+but WITHOUT ANY WARRANTY; without even the implied warranty of</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.&nbsp; See the</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+GNU General Public License for more details.</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+*/</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+#include &lt;linux/kernel.h&gt;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+#include &lt;linux/module.h&gt;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+#include &lt;linux/init.h&gt;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+#include &lt;linux/sched.h&gt;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+#include &lt;linux/delay.h&gt;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+#include &lt;linux/interrupt.h&gt;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+#include &lt;linux/jiffies.h&gt;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+#include &lt;linux/mtd/mtd.h&gt;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+#include &lt;linux/mtd/partitions.h&gt;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+#include &lt;linux/mtd/spinand.h&gt;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+#include &lt;linux/mtd/nand_ecc.h&gt;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+/**</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ * spinand_get_device - [GENERIC] Get chip for selected access</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ * @param mtd&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; MTD device structure</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ * @param new_state&nbsp;&nbsp;&nbsp; the state which is requested</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ *</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ * Get the device and lock it for exclusive access</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ */</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+#define mu_spi_nand_driver_version &quot;Beagle-MTD_01.00_Linux2.6.33_20100507&quot;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+static int spinand_get_device(struct mtd_info *mtd, int new_state)</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+{</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct spinand_chip *this = mtd-&gt;priv;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DECLARE_WAITQUEUE(wait, current);</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /*</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * Grab the lock and see if the device is available</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while (1) {</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; spin_lock(&amp;this-&gt;chip_lock);</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (this-&gt;state == FL_READY) {</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this-&gt;state = new_state;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; spin_unlock(&amp;this-&gt;chip_lock);</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (new_state == FL_PM_SUSPENDED) {</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; spin_unlock(&amp;this-&gt;chip_lock);</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return (this-&gt;state == FL_PM_SUSPENDED) ? 0 : -EAGAIN;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; set_current_state(TASK_UNINTERRUPTIBLE);</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; add_wait_queue(&amp;this-&gt;wq, &amp;wait);</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; spin_unlock(&amp;this-&gt;chip_lock);</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; schedule();</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; remove_wait_queue(&amp;this-&gt;wq, &amp;wait);</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return 0;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+}</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+/**</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ * spinand_release_device - [GENERIC] release chip</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ * @param mtd&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; MTD device structure</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ *</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ * Deselect, release chip lock and wake up anyone waiting on the device</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ */</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+static void spinand_release_device(struct mtd_info *mtd)</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+{</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct spinand_chip *this = mtd-&gt;priv;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* Release the chip */</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; spin_lock(&amp;this-&gt;chip_lock);</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this-&gt;state = FL_READY;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; wake_up(&amp;this-&gt;wq);</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; spin_unlock(&amp;this-&gt;chip_lock);</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+}</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+#ifdef CONFIG_MTD_SPINAND_SWECC </FONT>

<BR><FONT SIZE=2 FACE="Courier New">+static void spinand_calculate_ecc(struct mtd_info *mtd)</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+{</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int i; </FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int eccsize = 512;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int eccbytes = 3;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int eccsteps = 4;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int ecctotal = 12;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct spinand_chip *chip = mtd-&gt;priv;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct spinand_info *info = chip-&gt;info;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; unsigned char *p = chip-&gt;buf;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize)</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; __nand_calculate_ecc(p, eccsize, &amp;chip-&gt;ecc_calc[i]);</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (i = 0; i &lt; ecctotal; i++)</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; chip-&gt;buf[info-&gt;page_main_size + info-&gt;ecclayout-&gt;eccpos[i]] = chip-&gt;ecc_calc[i];</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+}</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+static int spinand_correct_data(struct mtd_info *mtd)</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+{</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int i; </FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int eccsize = 512;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int eccbytes = 3;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int eccsteps = 4;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int ecctotal = 12;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct spinand_chip *chip = mtd-&gt;priv;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct spinand_info *info = chip-&gt;info;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; unsigned char *p = chip-&gt;buf;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int errcode = 0;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize)</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; __nand_calculate_ecc(p, eccsize, &amp;chip-&gt;ecc_calc[i]);</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (i = 0; i &lt; ecctotal; i++)</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; chip-&gt;ecc_code[i] = chip-&gt;buf[info-&gt;page_main_size + info-&gt;ecclayout-&gt;eccpos[i]];</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize)</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int stat;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; stat = __nand_correct_data(p, &amp;chip-&gt;ecc_code[i], &amp;chip-&gt;ecc_calc[i], eccsize);</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (stat &lt; 0)</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; errcode = -1;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else if (stat == 1)</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; errcode = 1;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return errcode;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+}</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+#endif</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+static int spinand_read_ops(struct mtd_info *mtd, loff_t from,</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp; struct mtd_oob_ops *ops)</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+{</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct spinand_chip *chip = mtd-&gt;priv;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct spi_device *spi_nand = chip-&gt;spi_nand;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct spinand_info *info = chip-&gt;info;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int page_id, page_offset, page_num, oob_num;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int count;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int main_ok, main_left, main_offset;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int oob_ok, oob_left;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; signed int retval;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; signed int errcode=0;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (!chip-&gt;buf)</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return -1;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; page_id = from &gt;&gt; info-&gt;page_shift;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* for main data */</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; page_offset = from &amp; info-&gt;page_mask;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; page_num = (page_offset + ops-&gt;len + info-&gt;page_main_size -1 ) / info-&gt;page_main_size;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* for oob */</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; oob_num = (ops-&gt;ooblen + info-&gt;ecclayout-&gt;oobavail -1) / info-&gt;ecclayout-&gt;oobavail;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; count = 0;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; main_left = ops-&gt;len;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; main_ok = 0;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; main_offset = page_offset;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; oob_left = ops-&gt;ooblen;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; oob_ok = 0;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while (1)</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (count &lt; page_num || count &lt; oob_num) </FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; memset(chip-&gt;buf, 0, info-&gt;page_size); </FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; retval = chip-&gt;read_page(spi_nand, info, page_id + count, 0, info-&gt;page_size, chip-&gt;buf);</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (retval != 0)</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; errcode = -1;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printk(KERN_INFO &quot;spinand_read_ops: fail, page=%d!\n&quot;, page_id);</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return errcode;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (count &lt; page_num &amp;&amp; ops-&gt;datbuf) </FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int size;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </FONT>

<BR><FONT SIZE=2 FACE="Courier New">+#ifdef CONFIG_MTD_SPINAND_SWECC</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; retval = spinand_correct_data(mtd);</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (retval == -1)</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printk(KERN_INFO &quot;SWECC uncorrectable error! page=%x\n&quot;, page_id+count); </FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else if (retval == 1)</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printk(KERN_INFO &quot;SWECC 1 bit error, corrected! page=%x\n&quot;, page_id+count); </FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+#endif</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if ((main_offset + main_left) &lt; info-&gt;page_main_size)</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; size = main_left;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; size = info-&gt;page_main_size - main_offset;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; memcpy (ops-&gt;datbuf + main_ok, chip-&gt;buf, size);</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; main_ok += size;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; main_left -= size;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; main_offset = 0;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ops-&gt;retlen = main_ok;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (count &lt; oob_num &amp;&amp; ops-&gt;oobbuf &amp;&amp; chip-&gt;oobbuf)</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int size;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int offset, len, temp;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* repack spare to oob */</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; memset(chip-&gt;oobbuf, 0, info-&gt;ecclayout-&gt;oobavail);</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; temp = 0;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; offset = info-&gt;ecclayout-&gt;oobfree[0].offset;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; len = info-&gt;ecclayout-&gt;oobfree[0].length;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; memcpy (chip-&gt;oobbuf + temp, chip-&gt;buf + info-&gt;page_main_size + offset, len);</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; temp += len;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; offset = info-&gt;ecclayout-&gt;oobfree[1].offset;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; len = info-&gt;ecclayout-&gt;oobfree[1].length;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; memcpy (chip-&gt;oobbuf + temp, chip-&gt;buf + info-&gt;page_main_size + offset, len);</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; temp += len;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; offset = info-&gt;ecclayout-&gt;oobfree[2].offset;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; len = info-&gt;ecclayout-&gt;oobfree[2].length;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; memcpy (chip-&gt;oobbuf + temp, chip-&gt;buf + info-&gt;page_main_size + offset, len);</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; temp += len;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; offset = info-&gt;ecclayout-&gt;oobfree[3].offset;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; len = info-&gt;ecclayout-&gt;oobfree[3].length;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; memcpy (chip-&gt;oobbuf + temp, chip-&gt;buf + info-&gt;page_main_size + offset, len);</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* copy oobbuf to ops oobbuf */</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (oob_left &lt; info-&gt;ecclayout-&gt;oobavail) </FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; size = oob_left;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; size = info-&gt;ecclayout-&gt;oobavail;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; memcpy (ops-&gt;oobbuf + oob_ok, chip-&gt;oobbuf, size);</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; oob_ok += size;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; oob_left -= size;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ops-&gt;oobretlen = oob_ok;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; count++;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return errcode;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+}</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+static int spinand_write_ops(struct mtd_info *mtd, loff_t to,</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp; struct mtd_oob_ops *ops)</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+{</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct spinand_chip *chip = mtd-&gt;priv;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct spi_device *spi_nand = chip-&gt;spi_nand;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct spinand_info *info = chip-&gt;info;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int page_id, page_offset, page_num, oob_num;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int count;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int main_ok, main_left, main_offset;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int oob_ok, oob_left;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; signed int retval;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; signed int errcode=0;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (!chip-&gt;buf)</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return -1;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; page_id = to &gt;&gt; info-&gt;page_shift;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* for main data */</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; page_offset = to &amp; info-&gt;page_mask;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; page_num = (page_offset + ops-&gt;len + info-&gt;page_main_size -1 ) / info-&gt;page_main_size;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* for oob */</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; oob_num = (ops-&gt;ooblen + info-&gt;ecclayout-&gt;oobavail -1) / info-&gt;ecclayout-&gt;oobavail;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; count = 0;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; main_left = ops-&gt;len;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; main_ok = 0;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; main_offset = page_offset;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; oob_left = ops-&gt;ooblen;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; oob_ok = 0;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while (1)</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (count &lt; page_num || count &lt; oob_num) </FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; memset(chip-&gt;buf, 0xFF, info-&gt;page_size); </FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break; </FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (count &lt; page_num &amp;&amp; ops-&gt;datbuf) </FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int size;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if ((main_offset + main_left) &lt; info-&gt;page_main_size)</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; size = main_left;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; size = info-&gt;page_main_size - main_offset;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; memcpy (chip-&gt;buf, ops-&gt;datbuf + main_ok, size);</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; main_ok += size;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; main_left -= size;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; main_offset = 0;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </FONT>

<BR><FONT SIZE=2 FACE="Courier New">+#ifdef CONFIG_MTD_SPINAND_SWECC </FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; spinand_calculate_ecc(mtd);</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+#endif</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (count &lt; oob_num &amp;&amp; ops-&gt;oobbuf &amp;&amp; chip-&gt;oobbuf)</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int size;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int offset, len, temp;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; memset(chip-&gt;oobbuf, 0xFF, info-&gt;ecclayout-&gt;oobavail);</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (oob_left &lt; info-&gt;ecclayout-&gt;oobavail) </FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; size = oob_left;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; size = info-&gt;ecclayout-&gt;oobavail;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; memcpy (chip-&gt;oobbuf, ops-&gt;oobbuf + oob_ok, size);</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; oob_ok += size;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; oob_left -= size;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* repack oob to spare */</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; temp = 0;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; offset = info-&gt;ecclayout-&gt;oobfree[0].offset;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; len = info-&gt;ecclayout-&gt;oobfree[0].length;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; memcpy (chip-&gt;buf + info-&gt;page_main_size + offset, chip-&gt;oobbuf + temp, len);</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; temp += len;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; offset = info-&gt;ecclayout-&gt;oobfree[1].offset;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; len = info-&gt;ecclayout-&gt;oobfree[1].length;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; memcpy (chip-&gt;buf + info-&gt;page_main_size + offset, chip-&gt;oobbuf + temp, len);</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; temp += len;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; offset = info-&gt;ecclayout-&gt;oobfree[2].offset;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; len = info-&gt;ecclayout-&gt;oobfree[2].length;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; memcpy (chip-&gt;buf + info-&gt;page_main_size + offset, chip-&gt;oobbuf + temp, len);</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; temp += len;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; offset = info-&gt;ecclayout-&gt;oobfree[3].offset;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; len = info-&gt;ecclayout-&gt;oobfree[3].length;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; memcpy (chip-&gt;buf + info-&gt;page_main_size + offset, chip-&gt;oobbuf + temp, len);</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (count &lt; page_num || count &lt; oob_num) </FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; retval = chip-&gt;program_page(spi_nand, info, page_id + count, 0, info-&gt;page_size, chip-&gt;buf);</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (retval != 0)</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; errcode = -1;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printk(KERN_INFO &quot;spinand_write_ops: fail, page=%d!\n&quot;, page_id);</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return errcode;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (count &lt; page_num &amp;&amp; ops-&gt;datbuf) </FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ops-&gt;retlen = main_ok;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (count &lt; oob_num &amp;&amp; ops-&gt;oobbuf &amp;&amp; chip-&gt;oobbuf)</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ops-&gt;oobretlen = oob_ok;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; count++;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return errcode;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+}</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+static int spinand_read(struct mtd_info *mtd, loff_t from, size_t len,</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; size_t *retlen, u_char *buf)</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+{</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct mtd_oob_ops ops = {0};</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int ret;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* Do not allow reads past end of device */</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if ((from + len) &gt; mtd-&gt;size)</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return -EINVAL;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (!len)</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return 0;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; spinand_get_device(mtd, FL_READING);</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ops.len = len;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ops.datbuf = buf;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ret = spinand_read_ops(mtd, from, &amp;ops);</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ </FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *retlen = ops.retlen;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; spinand_release_device(mtd);</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return ret;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+}</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+static int spinand_write(struct mtd_info *mtd, loff_t to, size_t len,</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; size_t *retlen, const u_char *buf)</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+{</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct mtd_oob_ops ops = {0};</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int ret;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* Do not allow reads past end of device */</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if ((to + len) &gt; mtd-&gt;size)</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return -EINVAL;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (!len)</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return 0;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; spinand_get_device(mtd, FL_WRITING);</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ops.len = len;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ops.datbuf = (uint8_t *)buf;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ret =&nbsp; spinand_write_ops(mtd, to, &amp;ops);</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *retlen = ops.retlen;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; spinand_release_device(mtd);</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return ret;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+}</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+static int spinand_read_oob(struct mtd_info *mtd, loff_t from,</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp; struct mtd_oob_ops *ops)</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+{</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int ret;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; spinand_get_device(mtd, FL_READING);</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ret = spinand_read_ops(mtd, from, ops);</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; spinand_release_device(mtd);</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return ret;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+}</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+static int spinand_write_oob(struct mtd_info *mtd, loff_t to,</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp; struct mtd_oob_ops *ops)</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+{</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int ret;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; spinand_get_device(mtd, FL_WRITING);</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ret = spinand_write_ops(mtd, to, ops);</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; spinand_release_device(mtd);</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return ret;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+}</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+/**</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ * spinand_erase - [MTD Interface] erase block(s)</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ * @param mtd&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; MTD device structure</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ * @param instr&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; erase instruction</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ *</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ * Erase one ore more blocks</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ */</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+static int spinand_erase(struct mtd_info *mtd, struct erase_info *instr)</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+{</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct spinand_chip *chip = mtd-&gt;priv;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct spi_device *spi_nand = chip-&gt;spi_nand;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct spinand_info *info = chip-&gt;info;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; u16 block_id, block_num, count;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; signed int retval=0;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; signed int errcode=0;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DEBUG(MTD_DEBUG_LEVEL3, &quot;spinand_erase: start = 0x%012llx, len = %llu\n&quot;,</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (unsigned long long)instr-&gt;addr, (unsigned long long)instr-&gt;len);</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* check address align on block boundary */</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (instr-&gt;addr &amp; (info-&gt;block_main_size - 1)) {</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DEBUG(MTD_DEBUG_LEVEL0, &quot;spinand_erase: Unaligned address\n&quot;);</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return -EINVAL;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (instr-&gt;len &amp; (info-&gt;block_main_size - 1)) {</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DEBUG(MTD_DEBUG_LEVEL0, &quot;spinand_erase: &quot;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &quot;Length not block aligned\n&quot;);</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return -EINVAL;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* Do not allow erase past end of device */</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if ((instr-&gt;len + instr-&gt;addr) &gt; info-&gt;usable_size) {</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DEBUG(MTD_DEBUG_LEVEL0, &quot;spinand_erase: &quot;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &quot;Erase past end of device\n&quot;);</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return -EINVAL;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; instr-&gt;fail_addr = MTD_FAIL_ADDR_UNKNOWN;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* Grab the lock and see if the device is available */</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; spinand_get_device(mtd, FL_ERASING);</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; block_id = instr-&gt;addr &gt;&gt; info-&gt;block_shift;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; block_num = instr-&gt;len &gt;&gt; info-&gt;block_shift; </FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; count = 0;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while (count &lt; block_num )</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; retval = chip-&gt;erase_block(spi_nand, info, block_id+count);</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (retval!=0)</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; retval = chip-&gt;erase_block(spi_nand, info, block_id+count);</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (retval!=0)</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printk(KERN_INFO &quot;spinand_erase: fail, block=%d!\n&quot;, block_id+count);</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; errcode = -1;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; count++;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (errcode == 0)</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; instr-&gt;state = MTD_ERASE_DONE;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* Deselect and wake up anyone waiting on the device */</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; spinand_release_device(mtd);</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* Do call back function */</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(instr-&gt;callback)</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; instr-&gt;callback(instr);</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return errcode;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+}</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+/**</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ * spinand_sync - [MTD Interface] sync</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ * @param mtd&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; MTD device structure</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ *</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ * Sync is actually a wait for chip ready function</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ */</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+static void spinand_sync(struct mtd_info *mtd)</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+{</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DEBUG(MTD_DEBUG_LEVEL3, &quot;spinand_sync: called\n&quot;);</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* Grab the lock and see if the device is available */</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; spinand_get_device(mtd, FL_SYNCING);</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* Release it and go back */</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; spinand_release_device(mtd);</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+}</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+static int spinand_block_isbad(struct mtd_info *mtd, loff_t ofs)</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+{</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct spinand_chip *chip = mtd-&gt;priv;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct spi_device *spi_nand = chip-&gt;spi_nand;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct spinand_info *info = chip-&gt;info;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; u16 block_id;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; u8 is_bad = 0x00;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; u8 ret = 0;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; spinand_get_device(mtd, FL_READING);</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; block_id = ofs &gt;&gt; info-&gt;block_shift;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; chip-&gt;read_page(spi_nand, info, block_id*info-&gt;page_num_per_block, info-&gt;page_main_size, 1, &amp;is_bad);</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (is_bad != 0xFF)</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ret =&nbsp; 1;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; spinand_release_device(mtd);</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return ret; </FONT>

<BR><FONT SIZE=2 FACE="Courier New">+}</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+/**</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ * spinand_block_markbad - [MTD Interface] Mark bad block</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ * @param mtd&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; MTD device structure</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ * @param ofs&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Bad block number</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ */</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+static int spinand_block_markbad(struct mtd_info *mtd, loff_t ofs)</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+{</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct spinand_chip *chip = mtd-&gt;priv;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct spi_device *spi_nand = chip-&gt;spi_nand;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct spinand_info *info = chip-&gt;info;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; u16 block_id;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; u8 is_bad = 0x00; </FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; u8 ret = 0;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; spinand_get_device(mtd, FL_WRITING);</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; block_id = ofs &gt;&gt; info-&gt;block_shift;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; chip-&gt;program_page(spi_nand, info, block_id*info-&gt;page_num_per_block, info-&gt;page_main_size, 1, &amp;is_bad);</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; spinand_release_device(mtd);</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return ret;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+}</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+/**</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ * spinand_suspend - [MTD Interface] Suspend the spinand flash</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ * @param mtd&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; MTD device structure</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ */</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+static int spinand_suspend(struct mtd_info *mtd)</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+{</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return spinand_get_device(mtd, FL_PM_SUSPENDED);</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+}</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+/**</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ * spinand_resume - [MTD Interface] Resume the spinand flash</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ * @param mtd&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; MTD device structure</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ */</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+static void spinand_resume(struct mtd_info *mtd)</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+{</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct spinand_chip *this = mtd-&gt;priv;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (this-&gt;state == FL_PM_SUSPENDED)</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; spinand_release_device(mtd);</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printk(KERN_ERR &quot;resume() called for the chip which is not&quot;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &quot;in suspended state\n&quot;);</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+}</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+/**</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ * spinand_mtd - add MTD device with parameters</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ * @param mtd&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; MTD device structure</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ *</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ * Add MTD device with parameters.</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ */</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+int spinand_mtd(struct mtd_info *mtd)</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+{</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct spinand_chip *chip = mtd-&gt;priv;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct spinand_info *info = chip-&gt;info;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; chip-&gt;state = FL_READY;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; init_waitqueue_head(&amp;chip-&gt;wq);</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; spin_lock_init(&amp;chip-&gt;chip_lock);</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mtd-&gt;name = info-&gt;name;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mtd-&gt;size = info-&gt;usable_size;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mtd-&gt;erasesize = info-&gt;block_main_size;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mtd-&gt;writesize = info-&gt;page_main_size;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mtd-&gt;oobsize = info-&gt;ecclayout-&gt;oobavail;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mtd-&gt;owner = THIS_MODULE;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mtd-&gt;type = MTD_NANDFLASH;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mtd-&gt;flags = MTD_CAP_NANDFLASH;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mtd-&gt;ecclayout = info-&gt;ecclayout;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mtd-&gt;erase = spinand_erase;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mtd-&gt;point = NULL;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mtd-&gt;unpoint = NULL;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mtd-&gt;read = spinand_read;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mtd-&gt;write = spinand_write;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mtd-&gt;read_oob = spinand_read_oob;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mtd-&gt;write_oob = spinand_write_oob;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mtd-&gt;sync = spinand_sync;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mtd-&gt;lock = NULL;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mtd-&gt;unlock = NULL;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mtd-&gt;suspend = spinand_suspend;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mtd-&gt;resume = spinand_resume;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mtd-&gt;block_isbad = spinand_block_isbad;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mtd-&gt;block_markbad = spinand_block_markbad;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return add_mtd_device(mtd) == 1 ? -ENODEV : 0;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+}</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+void spinand_mtd_release(struct mtd_info *mtd)</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+{</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; del_mtd_device(mtd);</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+}</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+EXPORT_SYMBOL_GPL(spinand_mtd);</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+MODULE_LICENSE(&quot;GPL&quot;);</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+MODULE_AUTHOR(&quot;Henry Pan &lt;hspan@micron.com&gt;&quot;);</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+MODULE_DESCRIPTION(&quot;SPI NAND driver code&quot;);</FONT>

<BR><FONT SIZE=2 FACE="Courier New">diff -urN linux-2.6.33.20-orig/include/linux/mtd/spinand.h linux-2.6.33.20/include/linux/mtd/spinand.h</FONT>

<BR><FONT SIZE=2 FACE="Courier New">--- linux-2.6.33.20-orig/include/linux/mtd/spinand.h&nbsp;&nbsp;&nbsp; 1969-12-31 16:00:00.000000000 -0800</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+++ linux-2.6.33.20/include/linux/mtd/spinand.h 2010-05-19 04:28:07.000000000 -0700</FONT>

<BR><FONT SIZE=2 FACE="Courier New">@@ -0,0 +1,160 @@</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+/*</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ *&nbsp; linux/include/linux/mtd/spinand.h</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ *</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ Copyright (c) 2009-2010 Micron Technology, Inc.</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+This software is licensed under the terms of the GNU General Public</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+License version 2, as published by the Free Software Foundation, and</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+may be copied, distributed, and modified under those terms.</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+This program is distributed in the hope that it will be useful,</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+but WITHOUT ANY WARRANTY; without even the implied warranty of</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.&nbsp; See the</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+GNU General Public License for more details.</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ *&nbsp; Henry Pan &lt;hspan@micron.com&gt;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ *</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ *&nbsp; based on nand.h</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+ */</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+#ifndef __LINUX_MTD_SPI_NAND_H</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+#define __LINUX_MTD_SPI_NAND_H</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+#include &lt;linux/wait.h&gt;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+#include &lt;linux/spinlock.h&gt;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+#include &lt;linux/mtd/mtd.h&gt;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+/* cmd */</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+#define CMD_READ&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0x13</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+#define CMD_READ_RDM&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0x03</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+#define CMD_PROG_PAGE_CLRCACHE 0x02</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+#define CMD_PROG_PAGE&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0x84</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+#define CMD_PROG_PAGE_EXC&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0x10</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+#define CMD_ERASE_BLK&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0xd8</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+#define CMD_WR_ENABLE&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0x06</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+#define CMD_WR_DISABLE &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0x04</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+#define CMD_READ_ID&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0x9f</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+#define CMD_RESET&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0xff</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+#define CMD_READ_REG&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0x0f</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+#define CMD_WRITE_REG&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0x1f</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+/* feature/ status reg */</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+#define REG_BLOCK_LOCK &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0xa0</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+#define REG_OTP&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0xb0</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+#define REG_STATUS&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0xc0/* timing */</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+/* status */</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+#define STATUS_OIP_MASK&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0x01</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+#define STATUS_READY&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0 &lt;&lt; 0</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+#define STATUS_BUSY&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1 &lt;&lt; 0</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+#define STATUS_E_FAIL_MASK&nbsp;&nbsp;&nbsp;&nbsp; 0x04</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+#define STATUS_E_FAIL&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1 &lt;&lt; 2</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+#define STATUS_P_FAIL_MASK &nbsp;&nbsp;&nbsp; 0x08</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+#define STATUS_P_FAIL&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1 &lt;&lt; 3</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+#define STATUS_ECC_MASK &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0x30</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+#define STATUS_ECC_1BIT_CORRECTED&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1 &lt;&lt; 4</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+#define STATUS_ECC_ERROR&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2 &lt;&lt; 4</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+#define STATUS_ECC_RESERVED&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3 &lt;&lt; 4</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+/*ECC enable defines*/</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+#define OTP_ECC_MASK&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0x10</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+#define OTP_ECC_OFF&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+#define OTP_ECC_ON&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+#define ECC_DISABLED</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+#define ECC_IN_NAND&nbsp;&nbsp; </FONT>

<BR><FONT SIZE=2 FACE="Courier New">+#define ECC_SOFT</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+/* block lock */</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+#define BL_ALL_LOCKED&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0x38 </FONT>

<BR><FONT SIZE=2 FACE="Courier New">+#define BL_1_2_LOCKED&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0x30</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+#define BL_1_4_LOCKED&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0x28</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+#define BL_1_8_LOCKED&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0x20</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+#define BL_1_16_LOCKED&nbsp;&nbsp;&nbsp;&nbsp; 0x18</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+#define BL_1_32_LOCKED&nbsp;&nbsp;&nbsp;&nbsp; 0x10</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+#define BL_1_64_LOCKED&nbsp;&nbsp;&nbsp;&nbsp; 0x08</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+#define BL_ALL_UNLOCKED&nbsp;&nbsp;&nbsp; 0</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+/****************************************************************************/</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+struct spinand_info {</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; u8&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mid;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; u8&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; did;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; char&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *name;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; u64&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; nand_size;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; u64&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; usable_size;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; u32&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; block_size;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; u32&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; block_main_size;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /*u32&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; block_spare_size; */</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; u16&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; block_num_per_chip;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; u16&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; page_size;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; u16&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; page_main_size;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; u16&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; page_spare_size;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; u16&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; page_num_per_block;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; u8&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; block_shift;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; u32&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; block_mask;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; u8&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; page_shift;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; u16&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; page_mask;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct nand_ecclayout *ecclayout;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+};</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+typedef enum {</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; FL_READY,</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; FL_READING,</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; FL_WRITING,</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; FL_ERASING,</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; FL_SYNCING,</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; FL_LOCKING,</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; FL_RESETING,</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; FL_OTPING,</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; FL_PM_SUSPENDED,</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+} spinand_state_t;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </FONT>

<BR><FONT SIZE=2 FACE="Courier New">+struct spinand_chip { /* used for multi chip */</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; spinlock_t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; chip_lock;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; wait_queue_head_t wq;&nbsp;&nbsp; </FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; spinand_state_t state;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct spi_device&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *spi_nand;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct spinand_info *info;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /*struct mtd_info&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *mtd; */</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int (*reset) (struct spi_device *spi_nand);</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int (*read_id) (struct spi_device *spi_nand, u8* id);</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int (*read_page) (struct spi_device *spi_nand, struct spinand_info *info, u16 page_id, u16 offset, u16 len, u8* rbuf);</FONT></P>

<P><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int (*program_page) (struct spi_device *spi_nand, struct spinand_info *info, u16 page_id, u16 offset, u16 len, u8* wbuf);</FONT></P>

<P><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int (*erase_block) (struct spi_device *spi_nand, struct spinand_info *info, u16 block_id);</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; u8 *buf;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; u8 *oobbuf; /* temp buffer */</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+#ifdef CONFIG_MTD_SPINAND_SWECC</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; u8 ecc_calc[12];</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; u8 ecc_code[12];</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+#endif</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+};</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+struct spinand_cmd {</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; u8 cmd;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; unsigned n_addr;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; u8 addr[3];</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; unsigned n_dummy;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; unsigned n_tx;&nbsp; </FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; u8 *tx_buf;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; unsigned n_rx;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; u8 *rx_buf;</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+};</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+extern int spinand_mtd(struct mtd_info *mtd);</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+extern void spinand_mtd_release(struct mtd_info *mtd);</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+</FONT>

<BR><FONT SIZE=2 FACE="Courier New">+#endif /* __LINUX_MTD_SPI_NAND_H */</FONT>
</P>

</BODY>
</HTML>