diff options
| -rw-r--r-- | conf/distro/openmnci.conf | 2 | ||||
| -rw-r--r-- | packages/busybox/busybox-1.00/ramses/defconfig | 6 | ||||
| -rw-r--r-- | packages/busybox/files/ramses/defconfig | 0 | ||||
| -rw-r--r-- | packages/linux/mnci-ramses-2.4.21-rmk2-pxa1/mnci-combined.patch | 100262 | ||||
| -rw-r--r-- | packages/linux/mnci-ramses_2.4.21-rmk2-pxa1.bb | 2 |
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> ++ </ |
