summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--conf/distro/openmnci.conf2
-rw-r--r--packages/busybox/busybox-1.00/ramses/defconfig6
-rw-r--r--packages/busybox/files/ramses/defconfig0
-rw-r--r--packages/linux/mnci-ramses-2.4.21-rmk2-pxa1/mnci-combined.patch100262
-rw-r--r--packages/linux/mnci-ramses_2.4.21-rmk2-pxa1.bb2
5 files changed, 100267 insertions, 5 deletions
diff --git a/conf/distro/openmnci.conf b/conf/distro/openmnci.conf
index fb46dc203f..64423093d7 100644
--- a/conf/distro/openmnci.conf
+++ b/conf/distro/openmnci.conf
@@ -3,7 +3,7 @@ INHERIT += "debian"
#CVSDATE = 20050107
-CVSDATE = 20050216
+#CVSDATE = 20050216
CVSDATE_ipkg-utils = 20050110
#ASSUME_PROVIDED = "virtual/arm-linux-gcc-2.95"
diff --git a/packages/busybox/busybox-1.00/ramses/defconfig b/packages/busybox/busybox-1.00/ramses/defconfig
index 94f175b5a3..f98af91853 100644
--- a/packages/busybox/busybox-1.00/ramses/defconfig
+++ b/packages/busybox/busybox-1.00/ramses/defconfig
@@ -111,7 +111,7 @@ CONFIG_FEATURE_LS_RECURSIVE=y
CONFIG_FEATURE_LS_SORTFILES=y
CONFIG_FEATURE_LS_TIMESTAMPS=y
CONFIG_FEATURE_LS_USERNAME=y
-CONFIG_FEATURE_LS_COLOR=y
+# CONFIG_FEATURE_LS_COLOR is not set
CONFIG_MD5SUM=y
CONFIG_MKDIR=y
CONFIG_MKFIFO=y
@@ -284,7 +284,7 @@ CONFIG_DC=y
# CONFIG_MT is not set
# CONFIG_RX is not set
CONFIG_STRINGS=y
-# CONFIG_TIME is not set
+CONFIG_TIME=y
# CONFIG_WATCHDOG is not set
#
@@ -301,7 +301,7 @@ CONFIG_FEATURE_INSMOD_LOAD_MAP_FULL=y
CONFIG_LSMOD=y
CONFIG_MODPROBE=y
CONFIG_RMMOD=y
-CONFIG_FEATURE_CHECK_TAINTED_MODULE=y
+# CONFIG_FEATURE_CHECK_TAINTED_MODULE is not set
#
# Networking Utilities
diff --git a/packages/busybox/files/ramses/defconfig b/packages/busybox/files/ramses/defconfig
deleted file mode 100644
index e69de29bb2..0000000000
--- a/packages/busybox/files/ramses/defconfig
+++ /dev/null
diff --git a/packages/linux/mnci-ramses-2.4.21-rmk2-pxa1/mnci-combined.patch b/packages/linux/mnci-ramses-2.4.21-rmk2-pxa1/mnci-combined.patch
index e69de29bb2..fd1ba4db48 100644
--- a/packages/linux/mnci-ramses-2.4.21-rmk2-pxa1/mnci-combined.patch
+++ b/packages/linux/mnci-ramses-2.4.21-rmk2-pxa1/mnci-combined.patch
@@ -0,0 +1,100262 @@
+
+# This is a cumulative patch consisting of:
+#
+# mtd-cvs.patch
+# linux-vtcomparison.patch
+# linux-mkdep.patch
+# linux-iw241_we16-6.patch
+# arm-noshortloads.patch
+# pxa-pcmcia.patch
+# pxa-smc91x.patch
+# pxa-usb.patch
+# pxa-usbeth.patch
+# pxa-irda.patch
+# pxa-ac97.patch
+# pxa-timerint.patch
+# fb-buffered.patch
+# fb-turn180.patch
+# i2c-ds1337.patch
+# keyb-input.patch
+# keyb-module.patch
+# logo-noscrollregion.patch
+# net-dhcp-timeout.patch
+# pm.patch
+# swap-performance.patch
+# small-nocramdisk.patch
+# smc91x-ethtool.patch
+# ucb1x00.patch
+# vmalloc.patch
+# usb-sl811.patch
+# orinoco013e.patch
+# ramses.patch
+# ramses-ac97.patch
+# ramses-keyb.patch
+# ramses-mtd.patch
+# ramses-orinoco-ignorecis.patch
+# ramses-pcmcia.patch
+# ramses-serial.patch
+# ramses-smc91x.patch
+# ramses-sysctl.patch
+# ramses-ucb1x00-dejitter.patch
+# ramses-lcd.patch
+# ramses-usb.patch
+# ramses-corevolt.patch
+# wedge.patch
+# usb-sonycamera.patch
+# ramses-ucb1x00-rotate.patch
+# vt-noblank.patch
+#
+# Patch managed by http://www.holgerschurig.de/patcher.html
+#
+
+--- /dev/null
++++ linux-2.4.21/Documentation/DocBook/librs.tmpl
+@@ -0,0 +1,287 @@
++<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook V3.1//EN"[]>
++
++<book id="Reed-Solomon-Library-Guide">
++ <bookinfo>
++ <title>Reed-Solomon Library Programming Interface</title>
++
++ <authorgroup>
++ <author>
++ <firstname>Thomas</firstname>
++ <surname>Gleixner</surname>
++ <affiliation>
++ <address>
++ <email>tglx@linutronix.de</email>
++ </address>
++ </affiliation>
++ </author>
++ </authorgroup>
++
++ <copyright>
++ <year>2004</year>
++ <holder>Thomas Gleixner</holder>
++ </copyright>
++
++ <legalnotice>
++ <para>
++ This documentation is free software; you can redistribute
++ it and/or modify it under the terms of the GNU General Public
++ License version 2 as published by the Free Software Foundation.
++ </para>
++
++ <para>
++ This program is distributed in the hope that it will be
++ useful, but WITHOUT ANY WARRANTY; without even the implied
++ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
++ See the GNU General Public License for more details.
++ </para>
++
++ <para>
++ You should have received a copy of the GNU General Public
++ License along with this program; if not, write to the Free
++ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
++ MA 02111-1307 USA
++ </para>
++
++ <para>
++ For more details see the file COPYING in the source
++ distribution of Linux.
++ </para>
++ </legalnotice>
++ </bookinfo>
++
++<toc></toc>
++
++ <chapter id="intro">
++ <title>Introduction</title>
++ <para>
++ The generic Reed-Solomon Library provides encoding, decoding
++ and error correction functions.
++ </para>
++ <para>
++ Reed-Solomon codes are used in communication and storage
++ applications to ensure data integrity.
++ </para>
++ <para>
++ This documentation is provided for developers who want to utilize
++ the functions provided by the library.
++ </para>
++ </chapter>
++
++ <chapter id="bugs">
++ <title>Known Bugs And Assumptions</title>
++ <para>
++ None.
++ </para>
++ </chapter>
++
++ <chapter id="usage">
++ <title>Usage</title>
++ <para>
++ This chapter provides examples how to use the library.
++ </para>
++ <sect1>
++ <title>Initializing</title>
++ <para>
++ The init function init_rs returns a pointer to a
++ rs decoder structure, which holds the necessary
++ information for encoding, decoding and error correction
++ with the given polynomial. It either uses an existing
++ matching decoder or creates a new one. On creation all
++ the lookup tables for fast en/decoding are created.
++ The function may take a while, so make sure not to
++ call it in critical code paths.
++ </para>
++ <programlisting>
++/* the Reed Solomon control structure */
++static struct rs_control *rs_decoder;
++
++/* Symbolsize is 10 (bits)
++ * Primitve polynomial is x^10+x^3+1
++ * first consecutive root is 0
++ * primitve element to generate roots = 1
++ * generator polinomial degree (number of roots) = 6
++ */
++rs_decoder = init_rs (10, 0x409, 0, 1, 6);
++ </programlisting>
++ </sect1>
++ <sect1>
++ <title>Encoding</title>
++ <para>
++ The encoder calculates the Reed-Solomon code over
++ the given data length and stores the result in
++ the parity buffer. Note that the parity buffer must
++ be initialized before calling the encoder.
++ </para>
++ <para>
++ The expanded data can be inverted on the fly by
++ providing a non zero inversion mask. The expanded data is
++ XOR'ed with the mask. This is used e.g. for FLASH
++ ECC, where the all 0xFF is inverted to an all 0x00.
++ The Reed-Solomon code for all 0x00 is all 0x00. The
++ code is inverted before storing to FLASH so it is 0xFF
++ too. This prevent's that reading from an erased FLASH
++ results in ECC errors.
++ </para>
++ <para>
++ The databytes are expanded to the given symbol size
++ on the fly. There is no support for encoding continuous
++ bitstreams with a symbol size != 8 at the moment. If
++ it is necessary it should be not a big deal to implement
++ such functionality.
++ </para>
++ <programlisting>
++/* Parity buffer. Size = number of roots */
++uint16_t par[6];
++/* Initialize the parity buffer */
++memset(par, 0, sizeof(par));
++/* Encode 512 byte in data8. Store parity in buffer par */
++encode_rs8 (rs_decoder, data8, 512, par, 0);
++ </programlisting>
++ </sect1>
++ <sect1>
++ <title>Decoding</title>
++ <para>
++ The decoder calculates the syndrome over
++ the given data length and the received parity symbols
++ and corrects errors in the data.
++ </para>
++ <para>
++ If a syndrome is available from a hardware decoder
++ then the syndrome calculation is skipped.
++ </para>
++ <para>
++ The correction of the data buffer can be suppressed
++ by providing a correction pattern buffer and an error
++ location buffer to the decoder. The decoder stores the
++ calculated error location and the correction bitmask
++ in the given buffers. This is useful for hardware
++ decoders which use a weird bit ordering scheme.
++ </para>
++ <para>
++ The databytes are expanded to the given symbol size
++ on the fly. There is no support for decoding continuous
++ bitstreams with a symbolsize != 8 at the moment. If
++ it is necessary it should be not a big deal to implement
++ such functionality.
++ </para>
++
++ <sect2>
++ <title>
++ Decoding with syndrome calculation, direct data correction
++ </title>
++ <programlisting>
++/* Parity buffer. Size = number of roots */
++uint16_t par[6];
++uint8_t data[512];
++int numerr;
++/* Receive data */
++.....
++/* Receive parity */
++.....
++/* Decode 512 byte in data8.*/
++numerr = decode_rs8 (rs_decoder, data8, par, 512, NULL, 0, NULL, 0, NULL);
++ </programlisting>
++ </sect2>
++
++ <sect2>
++ <title>
++ Decoding with syndrome given by hardware decoder, direct data correction
++ </title>
++ <programlisting>
++/* Parity buffer. Size = number of roots */
++uint16_t par[6], syn[6];
++uint8_t data[512];
++int numerr;
++/* Receive data */
++.....
++/* Receive parity */
++.....
++/* Get syndrome from hardware decoder */
++.....
++/* Decode 512 byte in data8.*/
++numerr = decode_rs8 (rs_decoder, data8, par, 512, syn, 0, NULL, 0, NULL);
++ </programlisting>
++ </sect2>
++
++ <sect2>
++ <title>
++ Decoding with syndrome given by hardware decoder, no direct data correction.
++ </title>
++ <para>
++ Note: It's not necessary to give data and received parity to the decoder.
++ </para>
++ <programlisting>
++/* Parity buffer. Size = number of roots */
++uint16_t par[6], syn[6], corr[8];
++uint8_t data[512];
++int numerr, errpos[8];
++/* Receive data */
++.....
++/* Receive parity */
++.....
++/* Get syndrome from hardware decoder */
++.....
++/* Decode 512 byte in data8.*/
++numerr = decode_rs8 (rs_decoder, NULL, NULL, 512, syn, 0, errpos, 0, corr);
++for (i = 0; i < numerr; i++) {
++ do_error_correction_in_your_buffer(errpos[i], corr[i]);
++}
++ </programlisting>
++ </sect2>
++ </sect1>
++ <sect1>
++ <title>Cleanup</title>
++ <para>
++ The function free_rs frees the allocated resources,
++ if the caller is the last user of the decoder.
++ </para>
++ <programlisting>
++/* Release resources */
++free_rs(rs_decoder);
++ </programlisting>
++ </sect1>
++
++ </chapter>
++
++ <chapter id="structs">
++ <title>Structures</title>
++ <para>
++ This chapter contains the autogenerated documentation of the structures which are
++ used in the Reed-Solomon Library and are relevant for a developer.
++ </para>
++!Iinclude/linux/rslib.h
++ </chapter>
++
++ <chapter id="pubfunctions">
++ <title>Public Functions Provided</title>
++ <para>
++ This chapter contains the autogenerated documentation of the Reed-Solomon functions
++ which are exported.
++ </para>
++!Elib/reed_solomon/reed_solomon.c
++ </chapter>
++
++ <chapter id="credits">
++ <title>Credits</title>
++ <para>
++ The library code for encoding and decoding was written by Phil Karn.
++ </para>
++ <programlisting>
++ Copyright 2002, Phil Karn, KA9Q
++ May be used under the terms of the GNU General Public License (GPL)
++ </programlisting>
++ <para>
++ The wrapper functions and interfaces are written by Thomas Gleixner
++ </para>
++ <para>
++ Many users have provided bugfixes, improvements and helping hands for testing.
++ Thanks a lot.
++ </para>
++ <para>
++ The following people have contributed to this document:
++ </para>
++ <para>
++ Thomas Gleixner<email>tglx@linutronix.de</email>
++ </para>
++ </chapter>
++</book>
+--- /dev/null
++++ linux-2.4.21/Documentation/DocBook/mtdnand.tmpl
+@@ -0,0 +1,1318 @@
++<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook V3.1//EN"[]>
++
++<book id="MTD-NAND-Guide">
++ <bookinfo>
++ <title>MTD NAND Driver Programming Interface</title>
++
++ <authorgroup>
++ <author>
++ <firstname>Thomas</firstname>
++ <surname>Gleixner</surname>
++ <affiliation>
++ <address>
++ <email>tglx@linutronix.de</email>
++ </address>
++ </affiliation>
++ </author>
++ </authorgroup>
++
++ <copyright>
++ <year>2004</year>
++ <holder>Thomas Gleixner</holder>
++ </copyright>
++
++ <legalnotice>
++ <para>
++ This documentation is free software; you can redistribute
++ it and/or modify it under the terms of the GNU General Public
++ License version 2 as published by the Free Software Foundation.
++ </para>
++
++ <para>
++ This program is distributed in the hope that it will be
++ useful, but WITHOUT ANY WARRANTY; without even the implied
++ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
++ See the GNU General Public License for more details.
++ </para>
++
++ <para>
++ You should have received a copy of the GNU General Public
++ License along with this program; if not, write to the Free
++ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
++ MA 02111-1307 USA
++ </para>
++
++ <para>
++ For more details see the file COPYING in the source
++ distribution of Linux.
++ </para>
++ </legalnotice>
++ </bookinfo>
++
++<toc></toc>
++
++ <chapter id="intro">
++ <title>Introduction</title>
++ <para>
++ The generic NAND driver supports almost all NAND and AG-AND based
++ chips and connects them to the Memory Technology Devices (MTD)
++ subsystem of the Linux Kernel.
++ </para>
++ <para>
++ This documentation is provided for developers who want to implement
++ board drivers or filesystem drivers suitable for NAND devices.
++ </para>
++ </chapter>
++
++ <chapter id="bugs">
++ <title>Known Bugs And Assumptions</title>
++ <para>
++ None.
++ </para>
++ </chapter>
++
++ <chapter id="dochints">
++ <title>Documentation hints</title>
++ <para>
++ The function and structure docs are autogenerated. Each function and
++ struct member has a short description which is marked with an [XXX] identifier.
++ The following chapters explain the meaning of those identifiers.
++ </para>
++ <sect1>
++ <title>Function identifiers [XXX]</title>
++ <para>
++ The functions are marked with [XXX] identifiers in the short
++ comment. The identifiers explain the usage and scope of the
++ functions. Following identifiers are used:
++ </para>
++ <itemizedlist>
++ <listitem><para>
++ [MTD Interface]</para><para>
++ These functions provide the interface to the MTD kernel API.
++ They are not replacable and provide functionality
++ which is complete hardware independent.
++ </para></listitem>
++ <listitem><para>
++ [NAND Interface]</para><para>
++ These functions are exported and provide the interface to the NAND kernel API.
++ </para></listitem>
++ <listitem><para>
++ [GENERIC]</para><para>
++ Generic functions are not replacable and provide functionality
++ which is complete hardware independent.
++ </para></listitem>
++ <listitem><para>
++ [DEFAULT]</para><para>
++ Default functions provide hardware related functionality which is suitable
++ for most of the implementations. These functions can be replaced by the
++ board driver if neccecary. Those functions are called via pointers in the
++ NAND chip description structure. The board driver can set the functions which
++ should be replaced by board dependend functions before calling nand_scan().
++ If the function pointer is NULL on entry to nand_scan() then the pointer
++ is set to the default function which is suitable for the detected chip type.
++ </para></listitem>
++ </itemizedlist>
++ </sect1>
++ <sect1>
++ <title>Struct member identifiers [XXX]</title>
++ <para>
++ The struct members are marked with [XXX] identifiers in the
++ comment. The identifiers explain the usage and scope of the
++ members. Following identifiers are used:
++ </para>
++ <itemizedlist>
++ <listitem><para>
++ [INTERN]</para><para>
++ These members are for NAND driver internal use only and must not be
++ modified. Most of these values are calculated from the chip geometry
++ information which is evaluated during nand_scan().
++ </para></listitem>
++ <listitem><para>
++ [REPLACEABLE]</para><para>
++ Replaceable members hold hardware related functions which can be
++ provided by the board driver. The board driver can set the functions which
++ should be replaced by board dependend functions before calling nand_scan().
++ If the function pointer is NULL on entry to nand_scan() then the pointer
++ is set to the default function which is suitable for the detected chip type.
++ </para></listitem>
++ <listitem><para>
++ [BOARDSPECIFIC]</para><para>
++ Board specific members hold hardware related information which must
++ be provided by the board driver. The board driver must set the function
++ pointers and datafields before calling nand_scan().
++ </para></listitem>
++ <listitem><para>
++ [OPTIONAL]</para><para>
++ Optional members can hold information relevant for the board driver. The
++ generic NAND driver code does not use this information.
++ </para></listitem>
++ </itemizedlist>
++ </sect1>
++ </chapter>
++
++ <chapter id="basicboarddriver">
++ <title>Basic board driver</title>
++ <para>
++ For most boards it will be sufficient to provide just the
++ basic functions and fill out some really board dependend
++ members in the nand chip description structure.
++ See drivers/mtd/nand/skeleton for reference.
++ </para>
++ <sect1>
++ <title>Basic defines</title>
++ <para>
++ At least you have to provide a mtd structure and
++ a storage for the ioremap'ed chip address.
++ You can allocate the mtd structure using kmalloc
++ or you can allocate it statically.
++ In case of static allocation you have to allocate
++ a nand_chip structure too.
++ </para>
++ <para>
++ Kmalloc based example
++ </para>
++ <programlisting>
++static struct mtd_info *board_mtd;
++static unsigned long baseaddr;
++ </programlisting>
++ <para>
++ Static example
++ </para>
++ <programlisting>
++static struct mtd_info board_mtd;
++static struct nand_chip board_chip;
++static unsigned long baseaddr;
++ </programlisting>
++ </sect1>
++ <sect1>
++ <title>Partition defines</title>
++ <para>
++ If you want to divide your device into parititions, then
++ enable the configuration switch CONFIG_MTD_PARITIONS and define
++ a paritioning scheme suitable to your board.
++ </para>
++ <programlisting>
++#define NUM_PARTITIONS 2
++static struct mtd_partition partition_info[] = {
++ { .name = "Flash partition 1",
++ .offset = 0,
++ .size = 8 * 1024 * 1024 },
++ { .name = "Flash partition 2",
++ .offset = MTDPART_OFS_NEXT,
++ .size = MTDPART_SIZ_FULL },
++};
++ </programlisting>
++ </sect1>
++ <sect1>
++ <title>Hardware control function</title>
++ <para>
++ The hardware control function provides access to the
++ control pins of the NAND chip(s).
++ The access can be done by GPIO pins or by address lines.
++ If you use address lines, make sure that the timing
++ requirements are met.
++ </para>
++ <para>
++ <emphasis>GPIO based example</emphasis>
++ </para>
++ <programlisting>
++static void board_hwcontrol(struct mtd_info *mtd, int cmd)
++{
++ switch(cmd){
++ case NAND_CTL_SETCLE: /* Set CLE pin high */ break;
++ case NAND_CTL_CLRCLE: /* Set CLE pin low */ break;
++ case NAND_CTL_SETALE: /* Set ALE pin high */ break;
++ case NAND_CTL_CLRALE: /* Set ALE pin low */ break;
++ case NAND_CTL_SETNCE: /* Set nCE pin low */ break;
++ case NAND_CTL_CLRNCE: /* Set nCE pin high */ break;
++ }
++}
++ </programlisting>
++ <para>
++ <emphasis>Address lines based example.</emphasis> It's assumed that the
++ nCE pin is driven by a chip select decoder.
++ </para>
++ <programlisting>
++static void board_hwcontrol(struct mtd_info *mtd, int cmd)
++{
++ struct nand_chip *this = (struct nand_chip *) mtd->priv;
++ switch(cmd){
++ case NAND_CTL_SETCLE: this->IO_ADDR_W |= CLE_ADRR_BIT; break;
++ case NAND_CTL_CLRCLE: this->IO_ADDR_W &= ~CLE_ADRR_BIT; break;
++ case NAND_CTL_SETALE: this->IO_ADDR_W |= ALE_ADRR_BIT; break;
++ case NAND_CTL_CLRALE: this->IO_ADDR_W &= ~ALE_ADRR_BIT; break;
++ }
++}
++ </programlisting>
++ </sect1>
++ <sect1>
++ <title>Device ready function</title>
++ <para>
++ If the hardware interface has the ready busy pin of the NAND chip connected to a
++ GPIO or other accesible I/O pin, this function is used to read back the state of the
++ pin. The function has no arguments and should return 0, if the device is busy (R/B pin
++ is low) and 1, if the device is ready (R/B pin is high).
++ If the hardware interface does not give access to the ready busy pin, then
++ the function must not be defined and the function pointer this->dev_ready is set to NULL.
++ </para>
++ </sect1>
++ <sect1>
++ <title>Init function</title>
++ <para>
++ The init function allocates memory and sets up all the board
++ specific parameters and function pointers. When everything
++ is set up nand_scan() is called. This function tries to
++ detect and identify then chip. If a chip is found all the
++ internal data fields are initialized accordingly.
++ The structure(s) have to be zeroed out first and then filled with the neccecary
++ information about the device.
++ </para>
++ <programlisting>
++int __init board_init (void)
++{
++ struct nand_chip *this;
++ int err = 0;
++
++ /* Allocate memory for MTD device structure and private data */
++ board_mtd = kmalloc (sizeof(struct mtd_info) + sizeof (struct nand_chip), GFP_KERNEL);
++ if (!board_mtd) {
++ printk ("Unable to allocate NAND MTD device structure.\n");
++ err = -ENOMEM;
++ goto out;
++ }
++
++ /* Initialize structures */
++ memset ((char *) board_mtd, 0, sizeof(struct mtd_info) + sizeof(struct nand_chip));
++
++ /* map physical adress */
++ baseaddr = (unsigned long)ioremap(CHIP_PHYSICAL_ADDRESS, 1024);
++ if(!baseaddr){
++ printk("Ioremap to access NAND chip failed\n");
++ err = -EIO;
++ goto out_mtd;
++ }
++
++ /* Get pointer to private data */
++ this = (struct nand_chip *) ();
++ /* Link the private data with the MTD structure */
++ board_mtd->priv = this;
++
++ /* Set address of NAND IO lines */
++ this->IO_ADDR_R = baseaddr;
++ this->IO_ADDR_W = baseaddr;
++ /* Reference hardware control function */
++ this->hwcontrol = board_hwcontrol;
++ /* Set command delay time, see datasheet for correct value */
++ this->chip_delay = CHIP_DEPENDEND_COMMAND_DELAY;
++ /* Assign the device ready function, if available */
++ this->dev_ready = board_dev_ready;
++ this->eccmode = NAND_ECC_SOFT;
++
++ /* Scan to find existance of the device */
++ if (nand_scan (board_mtd, 1)) {
++ err = -ENXIO;
++ goto out_ior;
++ }
++
++ add_mtd_partitions(board_mtd, partition_info, NUM_PARTITIONS);
++ goto out;
++
++out_ior:
++ iounmap((void *)baseaddr);
++out_mtd:
++ kfree (board_mtd);
++out:
++ return err;
++}
++module_init(board_init);
++ </programlisting>
++ </sect1>
++ <sect1>
++ <title>Exit function</title>
++ <para>
++ The exit function is only neccecary if the driver is
++ compiled as a module. It releases all resources which
++ are held by the chip driver and unregisters the partitions
++ in the MTD layer.
++ </para>
++ <programlisting>
++#ifdef MODULE
++static void __exit board_cleanup (void)
++{
++ /* Release resources, unregister device */
++ nand_release (board_mtd);
++
++ /* unmap physical adress */
++ iounmap((void *)baseaddr);
++
++ /* Free the MTD device structure */
++ kfree (board_mtd);
++}
++module_exit(board_cleanup);
++#endif
++ </programlisting>
++ </sect1>
++ </chapter>
++
++ <chapter id="boarddriversadvanced">
++ <title>Advanced board driver functions</title>
++ <para>
++ This chapter describes the advanced functionality of the NAND
++ driver. For a list of functions which can be overridden by the board
++ driver see the documentation of the nand_chip structure.
++ </para>
++ <sect1>
++ <title>Multiple chip control</title>
++ <para>
++ The nand driver can control chip arrays. Therefor the
++ board driver must provide an own select_chip function. This
++ function must (de)select the requested chip.
++ The function pointer in the nand_chip structure must
++ be set before calling nand_scan(). The maxchip parameter
++ of nand_scan() defines the maximum number of chips to
++ scan for. Make sure that the select_chip function can
++ handle the requested number of chips.
++ </para>
++ <para>
++ The nand driver concatenates the chips to one virtual
++ chip and provides this virtual chip to the MTD layer.
++ </para>
++ <para>
++ <emphasis>Note: The driver can only handle linear chip arrays
++ of equally sized chips. There is no support for
++ parallel arrays which extend the buswidth.</emphasis>
++ </para>
++ <para>
++ <emphasis>GPIO based example</emphasis>
++ </para>
++ <programlisting>
++static void board_select_chip (struct mtd_info *mtd, int chip)
++{
++ /* Deselect all chips, set all nCE pins high */
++ GPIO(BOARD_NAND_NCE) |= 0xff;
++ if (chip >= 0)
++ GPIO(BOARD_NAND_NCE) &= ~ (1 << chip);
++}
++ </programlisting>
++ <para>
++ <emphasis>Address lines based example.</emphasis>
++ Its assumed that the nCE pins are connected to an
++ address decoder.
++ </para>
++ <programlisting>
++static void board_select_chip (struct mtd_info *mtd, int chip)
++{
++ struct nand_chip *this = (struct nand_chip *) mtd->priv;
++
++ /* Deselect all chips */
++ this->IO_ADDR_R &= ~BOARD_NAND_ADDR_MASK;
++ this->IO_ADDR_W &= ~BOARD_NAND_ADDR_MASK;
++ switch (chip) {
++ case 0:
++ this->IO_ADDR_R |= BOARD_NAND_ADDR_CHIP0;
++ this->IO_ADDR_W |= BOARD_NAND_ADDR_CHIP0;
++ break;
++ ....
++ case n:
++ this->IO_ADDR_R |= BOARD_NAND_ADDR_CHIPn;
++ this->IO_ADDR_W |= BOARD_NAND_ADDR_CHIPn;
++ break;
++ }
++}
++ </programlisting>
++ </sect1>
++ <sect1>
++ <title>Hardware ECC support</title>
++ <sect2>
++ <title>Functions and constants</title>
++ <para>
++ The nand driver supports three different types of
++ hardware ECC.
++ <itemizedlist>
++ <listitem><para>NAND_ECC_HW3_256</para><para>
++ Hardware ECC generator providing 3 bytes ECC per
++ 256 byte.
++ </para> </listitem>
++ <listitem><para>NAND_ECC_HW3_512</para><para>
++ Hardware ECC generator providing 3 bytes ECC per
++ 512 byte.
++ </para> </listitem>
++ <listitem><para>NAND_ECC_HW6_512</para><para>
++ Hardware ECC generator providing 6 bytes ECC per
++ 512 byte.
++ </para> </listitem>
++ <listitem><para>NAND_ECC_HW8_512</para><para>
++ Hardware ECC generator providing 6 bytes ECC per
++ 512 byte.
++ </para> </listitem>
++ </itemizedlist>
++ If your hardware generator has a different functionality
++ add it at the appropriate place in nand_base.c
++ </para>
++ <para>
++ The board driver must provide following functions:
++ <itemizedlist>
++ <listitem><para>enable_hwecc</para><para>
++ This function is called before reading / writing to
++ the chip. Reset or initialize the hardware generator
++ in this function. The function is called with an
++ argument which let you distinguish between read
++ and write operations.
++ </para> </listitem>
++ <listitem><para>calculate_ecc</para><para>
++ This function is called after read / write from / to
++ the chip. Transfer the ECC from the hardware to
++ the buffer. If the option NAND_HWECC_SYNDROME is set
++ then the function is only called on write. See below.
++ </para> </listitem>
++ <listitem><para>correct_data</para><para>
++ In case of an ECC error this function is called for
++ error detection and correction. Return 1 respectively 2
++ in case the error can be corrected. If the error is
++ not correctable return -1. If your hardware generator
++ matches the default algorithm of the nand_ecc software
++ generator then use the correction function provided
++ by nand_ecc instead of implementing duplicated code.
++ </para> </listitem>
++ </itemizedlist>
++ </para>
++ </sect2>
++ <sect2>
++ <title>Hardware ECC with syndrome calculation</title>
++ <para>
++ Many hardware ECC implementations provide Reed-Solomon
++ codes and calculate an error syndrome on read. The syndrome
++ must be converted to a standard Reed-Solomon syndrome
++ before calling the error correction code in the generic
++ Reed-Solomon library.
++ </para>
++ <para>
++ The ECC bytes must be placed immidiately after the data
++ bytes in order to make the syndrome generator work. This
++ is contrary to the usual layout used by software ECC. The
++ seperation of data and out of band area is not longer
++ possible. The nand driver code handles this layout and
++ the remaining free bytes in the oob area are managed by
++ the autoplacement code. Provide a matching oob-layout
++ in this case. See rts_from4.c and diskonchip.c for
++ implementation reference. In those cases we must also
++ use bad block tables on FLASH, because the ECC layout is
++ interferring with the bad block marker positions.
++ See bad block table support for details.
++ </para>
++ </sect2>
++ </sect1>
++ <sect1>
++ <title>Bad block table support</title>
++ <para>
++ Most NAND chips mark the bad blocks at a defined
++ position in the spare area. Those blocks must
++ not be erased under any circumstances as the bad
++ block information would be lost.
++ It is possible to check the bad block mark each
++ time when the blocks are accessed by reading the
++ spare area of the first page in the block. This
++ is time consuming so a bad block table is used.
++ </para>
++ <para>
++ The nand driver supports various types of bad block
++ tables.
++ <itemizedlist>
++ <listitem><para>Per device</para><para>
++ The bad block table contains all bad block information
++ of the device which can consist of multiple chips.
++ </para> </listitem>
++ <listitem><para>Per chip</para><para>
++ A bad block table is used per chip and contains the
++ bad block information for this particular chip.
++ </para> </listitem>
++ <listitem><para>Fixed offset</para><para>
++ The bad block table is located at a fixed offset
++ in the chip (device). This applies to various
++ DiskOnChip devices.
++ </para> </listitem>
++ <listitem><para>Automatic placed</para><para>
++ The bad block table is automatically placed and
++ detected either at the end or at the beginning
++ of a chip (device)
++ </para> </listitem>
++ <listitem><para>Mirrored tables</para><para>
++ The bad block table is mirrored on the chip (device) to
++ allow updates of the bad block table without data loss.
++ </para> </listitem>
++ </itemizedlist>
++ </para>
++ <para>
++ nand_scan() calls the function nand_default_bbt().
++ nand_default_bbt() selects appropriate default
++ bad block table desriptors depending on the chip information
++ which was retrieved by nand_scan().
++ </para>
++ <para>
++ The standard policy is scanning the device for bad
++ blocks and build a ram based bad block table which
++ allows faster access than always checking the
++ bad block information on the flash chip itself.
++ </para>
++ <sect2>
++ <title>Flash based tables</title>
++ <para>
++ It may be desired or neccecary to keep a bad block table in FLASH.
++ For AG-AND chips this is mandatory, as they have no factory marked
++ bad blocks. They have factory marked good blocks. The marker pattern
++ is erased when the block is erased to be reused. So in case of
++ powerloss before writing the pattern back to the chip this block
++ would be lost and added to the bad blocks. Therefor we scan the
++ chip(s) when we detect them the first time for good blocks and
++ store this information in a bad block table before erasing any
++ of the blocks.
++ </para>
++ <para>
++ The blocks in which the tables are stored are procteted against
++ accidental access by marking them bad in the memory bad block
++ table. The bad block table managment functions are allowed
++ to circumvernt this protection.
++ </para>
++ <para>
++ The simplest way to activate the FLASH based bad block table support
++ is to set the option NAND_USE_FLASH_BBT in the option field of
++ the nand chip structure before calling nand_scan(). For AG-AND
++ chips is this done by default.
++ This activates the default FLASH based bad block table functionality
++ of the NAND driver. The default bad block table options are
++ <itemizedlist>
++ <listitem><para>Store bad block table per chip</para></listitem>
++ <listitem><para>Use 2 bits per block</para></listitem>
++ <listitem><para>Automatic placement at the end of the chip</para></listitem>
++ <listitem><para>Use mirrored tables with version numbers</para></listitem>
++ <listitem><para>Reserve 4 blocks at the end of the chip</para></listitem>
++ </