Hi all,
Looks like a real rush since -rc7 ...
Changes since 20090602:
This tree fails to build for powerpc allyesconfig.
Moved tree: device-mapper (it now assumes some of the commits in the
block tree have been applied)
The x86 tree lost its conflict.
The kvm tree gained a conflict against the x86 tree.
The net tree gained a conflict against Linus' tree.
The wireless tree gained conflicts against the x86 (1) and acpi (2) trees.
It also gained a build failure due to an interaction with the acpi tree
for which I reverted 2 commits from the acpi tree.
The block tree lost its build failure due to updates in the device-mapper
tree.
The genirq tree lost its 2 conflicts.
The trivial tree gained a conflict against the wireless tree.
The driver-core tree gained conflicts against the trivial (1), x86 (1),
firmware (1) and ttydev (3) trees.
The ubi tree gained a build failure for which I reverted 2 commits.
----------------------------------------------------------------------------
I have created today's linux-next tree at
git://git.kernel.org/pub/scm/linux/kernel/git/sfr/linux-next.git
(patches at
http://www.kernel.org/pub/linux/kernel/people/sfr/linux-next/). If you
are tracking the linux-next tree using git, you should not use "git pull"
to do so as that will try to merge the new linux-next release with the
old one. You should use "git fetch" as mentioned in the FAQ on the wiki
(see below).
You can see which trees have been included by looking in the Next/Trees
file in the source. There are also quilt-import.log and merge.log files
in the Next directory. Between each merge, the tree was built with
a ppc64_defconfig for powerpc and an allmodconfig for x86_64. After the
final fixups (if any), it is also built with powerpc allnoconfig (32 and
64 bit), ppc44x_defconfig and allyesconfig (minus
CONFIG_PROFILE_ALL_BRANCHES) and i386, sparc and sparc64 defconfig.
These builds also have CONFIG_ENABLE_WARN_DEPRECATED,
CONFIG_ENABLE_MUST_CHECK and CONFIG_DEBUG_INFO disabled when necessary.
Below is a summary of the state of the merge.
We are up to 142 trees (counting Linus' and 19 trees of patches pending for
Linus' tree), more are welcome (even if they are currently empty).
Thanks to those who have contributed, and to those who haven't, please do.
Status of my local build tests will be at
http://kisskb.ellerman.id.au/linux-next . If maintainers want to give
advice about cross compilers/configs that work, we are always open to add
more builds.
Thanks to Jan Dittmer for adding the linux-next tree to his build tests
at http://l4x.org/k/ , the guys at http://test.kernel.org/ and Randy
Dunlap for doing many randconfig builds.
There is a wiki covering stuff to do with linux-next at
http://linux.f-seidel.de/linux-next/pmwiki/ . Thanks to Frank Seidel.
--
Cheers,
Stephen Rothwell [email protected]
$ git checkout master
$ git reset --hard stable
Merging origin/master
Merging fixes/fixes
Merging arm-current/master
Merging m68k-current/for-linus
Merging powerpc-merge/merge
Merging sparc-current/master
Merging scsi-rc-fixes/master
Merging net-current/master
Merging sound-current/for-linus
Merging pci-current/for-linus
Merging wireless-current/master
Merging kbuild-current/master
Merging quilt/driver-core.current
Merging quilt/usb.current
Merging cpufreq-current/fixes
Merging input-current/for-linus
Merging md-current/for-linus
Merging audit-current/for-linus
Merging crypto-current/master
Merging dwmw2/master
Merging arm/devel
Merging avr32/avr32-arch
Merging blackfin/for-linus
Merging cris/for-next
Merging ia64/test
Merging m68k/for-next
Merging m68knommu/for-next
Merging microblaze/next
Merging mips/mips-for-linux-next
Merging parisc/master
Merging powerpc/next
Merging 4xx/next
Merging galak/next
Merging pxa/for-next
CONFLICT (content): Merge conflict in arch/arm/mach-pxa/viper.c
Merging s390/features
Merging sh/master
Merging sparc/master
Merging x86/auto-x86-next
Merging xtensa/master
Merging configfs/linux-next
Merging ext4/next
Merging fatfs/master
Merging fuse/for-next
Merging gfs2/master
Merging jfs/next
Merging nfs/linux-next
Merging nfsd/nfsd-next
Merging nilfs2/for-next
Merging ocfs2/linux-next
Merging squashfs/master
Merging v9fs/for-next
CONFLICT (content): Merge conflict in net/9p/protocol.c
Merging ubifs/linux-next
Merging xfs/master
Merging reiserfs-bkl/reiserfs/kill-bkl-rc6
Merging vfs/for-next
CONFLICT (content): Merge conflict in fs/ext4/super.c
CONFLICT (content): Merge conflict in fs/fuse/inode.c
CONFLICT (delete/modify): fs/gfs2/ops_super.c deleted in HEAD and modified in vfs/for-next. Version vfs/for-next of fs/gfs2/ops_super.c left in tree.
CONFLICT (content): Merge conflict in fs/reiserfs/super.c
$ git rm -f fs/gfs2/ops_super.c
Applying: vfs/gfs2: fixup merge for file removal
Applying: vfs: fix mismerge of fs/reiserfs/xattr.c
Merging pci/linux-next
Merging hid/for-next
Merging quilt/i2c
Merging quilt/jdelvare-hwmon
Merging quilt/kernel-doc
Merging v4l-dvb/master
Merging quota/for_next
Merging kbuild/master
Merging ide/for-next
Merging libata/NEXT
Merging infiniband/for-next
Merging acpi/test
Merging ieee1394/for-next
Merging ubi/linux-next
Merging kvm/master
CONFLICT (content): Merge conflict in arch/x86/include/asm/mce.h
Merging dlm/next
Merging scsi/master
Merging async_tx/next
Merging udf/for_next
Merging net/master
CONFLICT (content): Merge conflict in drivers/net/forcedeth.c
CONFLICT (content): Merge conflict in include/linux/mmc/sdio_ids.h
Merging wireless/master
CONFLICT (content): Merge conflict in Documentation/feature-removal-schedule.txt
CONFLICT (content): Merge conflict in drivers/platform/x86/Kconfig
CONFLICT (content): Merge conflict in drivers/platform/x86/toshiba_acpi.c
[master f168b47] Revert "oqo: dev_set_name()"
[master e52d8f8] Revert "platform/x86: Add oqo-wmi driver for model 2 OQO backlight and rfkill control"
Merging mtd/master
CONFLICT (content): Merge conflict in drivers/mtd/nand/mxc_nand.c
Merging crypto/master
Merging sound/for-next
Merging cpufreq/next
Merging quilt/rr
CONFLICT (content): Merge conflict in arch/x86/kernel/cpu/cpufreq/powernow-k8.c
Merging cifs/master
Merging mmc/next
Merging input/next
Merging bkl-removal/bkl-removal
Merging lsm/for-next
Merging block/for-next
CONFLICT (content): Merge conflict in drivers/ide/ide-atapi.c
CONFLICT (content): Merge conflict in drivers/ide/ide-cd.c
CONFLICT (content): Merge conflict in drivers/ide/ide-floppy.c
CONFLICT (content): Merge conflict in drivers/ide/ide-tape.c
Merging quilt/device-mapper
Merging embedded/master
Merging firmware/master
Merging pcmcia/master
Merging battery/master
Merging leds/for-mm
Merging backlight/for-mm
Merging kgdb/kgdb-next
Merging slab/for-next
Merging uclinux/for-next
Merging md/for-next
Applying: md: fix fallout from block tree API change
Merging mfd/for-next
Merging hdlc/hdlc-next
Merging drm/drm-next
Merging voltage/for-next
Merging security-testing/next
Merging lblnet/master
Merging quilt/ttydev
Merging agp/agp-next
Merging tip-core/auto-core-next
Merging cpus4096/auto-cpus4096-next
Merging tracing/auto-tracing-next
CONFLICT (content): Merge conflict in block/blk-sysfs.c
CONFLICT (content): Merge conflict in net/core/drop_monitor.c
CONFLICT (content): Merge conflict in net/core/net-traces.c
Merging genirq/auto-genirq-next
Merging safe-poison-pointers/auto-safe-poison-pointers-next
Merging sched/auto-sched-next
Merging stackprotector/auto-stackprotector-next
Merging timers/auto-timers-next
CONFLICT (content): Merge conflict in kernel/sched.c
Merging generic-ipi/auto-generic-ipi-next
Merging oprofile/auto-oprofile-next
Merging fastboot/auto-fastboot-next
Merging sparseirq/auto-sparseirq-next
Merging iommu/auto-iommu-next
Merging uwb/for-upstream
Merging watchdog/master
Merging bdev/master
Merging dwmw2-iommu/master
CONFLICT (content): Merge conflict in drivers/pci/intel-iommu.c
CONFLICT (content): Merge conflict in drivers/pci/intr_remapping.c
Merging cputime/cputime
Merging osd/linux-next
Merging jc_docs/docs-next
Merging nommu/master
Merging trivial/for-next
CONFLICT (content): Merge conflict in Documentation/rfkill.txt
Merging audit/for-next
Merging omap/for-next
Merging quilt/aoe
Merging kmemleak/kmemleak
CONFLICT (delete/modify): arch/x86/kernel/vmlinux_32.lds.S deleted in HEAD and modified in kmemleak/kmemleak. Version kmemleak/kmemleak of arch/x86/kernel/vmlinux_32.lds.S left in tree.
CONFLICT (delete/modify): arch/x86/kernel/vmlinux_64.lds.S deleted in HEAD and modified in kmemleak/kmemleak. Version kmemleak/kmemleak of arch/x86/kernel/vmlinux_64.lds.S left in tree.
CONFLICT (content): Merge conflict in lib/Kconfig.debug
CONFLICT (content): Merge conflict in mm/slob.c
$ git rm -f arch/x86/kernel/vmlinux_32.lds.S arch/x86/kernel/vmlinux_64.lds.S
Merging kmemcheck/auto-kmemcheck-next
CONFLICT (content): Merge conflict in arch/x86/mm/fault.c
CONFLICT (content): Merge conflict in include/linux/ring_buffer.h
CONFLICT (content): Merge conflict in include/linux/slab.h
CONFLICT (content): Merge conflict in kernel/trace/ring_buffer.c
CONFLICT (content): Merge conflict in mm/Makefile
CONFLICT (content): Merge conflict in mm/slab.c
CONFLICT (content): Merge conflict in mm/slub.c
Merging suspend/linux-next
Merging bluetooth/master
Merging edac-amd/for-next
Merging fsnotify/for-next
Merging asm-generic/next
CONFLICT (content): Merge conflict in arch/arm/include/asm/page.h
Merging quilt/driver-core
CONFLICT (content): Merge conflict in Documentation/trace/ftrace.txt
CONFLICT (content): Merge conflict in arch/x86/kernel/microcode_core.c
CONFLICT (content): Merge conflict in drivers/base/firmware_class.c
CONFLICT (content): Merge conflict in init/main.c
Merging quilt/usb
CONFLICT (content): Merge conflict in drivers/usb/class/cdc-acm.c
CONFLICT (content): Merge conflict in drivers/usb/serial/cp210x.c
CONFLICT (content): Merge conflict in drivers/usb/serial/ftdi_sio.c
CONFLICT (content): Merge conflict in drivers/usb/serial/sierra.c
Merging quilt/staging
CONFLICT (content): Merge conflict in drivers/staging/rt2860/common/mlme.c
CONFLICT (content): Merge conflict in drivers/staging/rt2870/common/mlme.c
CONFLICT (content): Merge conflict in drivers/staging/rt3070/common/mlme.c
Merging scsi-post-merge/master
CONFLICT (content): Merge conflict in include/Kbuild
[master 10346ca] Revert "UBI: make gluebi a separate module"
[master b6f540e] Revert "UBI: remove built-in gluebi"
Stephen Rothwell wrote:
> Hi all,
>
> Looks like a real rush since -rc7 ...
CFG80211=y
MAC80211=y
RFKILL=m
net/built-in.o: In function `cfg80211_netdev_notifier_call':
core.c:(.text+0xa678b): undefined reference to `rfkill_blocked'
net/built-in.o: In function `cfg80211_dev_free':
(.text+0xa67e2): undefined reference to `rfkill_destroy'
net/built-in.o: In function `cfg80211_rfkill_sync_work':
core.c:(.text+0xa686e): undefined reference to `rfkill_blocked'
net/built-in.o: In function `wiphy_new':
(.text+0xa69f2): undefined reference to `rfkill_alloc'
net/built-in.o: In function `wiphy_rfkill_start_polling':
(.text+0xa6bd2): undefined reference to `rfkill_resume_polling'
net/built-in.o: In function `wiphy_rfkill_stop_polling':
(.text+0xa6bdf): undefined reference to `rfkill_pause_polling'
net/built-in.o: In function `wiphy_unregister':
(.text+0xa6bf4): undefined reference to `rfkill_unregister'
net/built-in.o: In function `wiphy_rfkill_set_hw_state':
(.text+0xa6c64): undefined reference to `rfkill_set_hw_state'
net/built-in.o: In function `wiphy_register':
(.text+0xa6db4): undefined reference to `rfkill_register'
net/built-in.o: In function `cfg80211_wext_giwtxpower':
(.text+0xb01e9): undefined reference to `rfkill_blocked'
net/built-in.o: In function `cfg80211_wext_siwtxpower':
(.text+0xb0cf3): undefined reference to `rfkill_set_sw_state'
net/built-in.o: In function `cfg80211_wext_siwtxpower':
(.text+0xb0d1f): undefined reference to `rfkill_set_sw_state'
--
~Randy
LPC 2009, Sept. 23-25, Portland, Oregon
http://linuxplumbersconf.org/2009/
Stephen Rothwell wrote:
> Hi all,
>
> Looks like a real rush since -rc7 ...
drivers/staging/comedi/drivers/adq12b.c:328: error: implicit declaration of function 'udelay'
drivers/staging/mrst_nand/ffsport.c:360:error: 'struct request' has no member named 'sector'
drivers/staging/mrst_nand/ffsport.c:376:error: 'struct request' has no member named 'sector'
drivers/staging/mrst_nand/ffsport.c:376:error: 'struct request' has no member named 'current_nr_sectors'
drivers/staging/mrst_nand/ffsport.c:380:error: 'struct request' has no member named 'sector'
drivers/staging/mrst_nand/ffsport.c:381:error: 'struct request' has no member named 'current_nr_sectors'
drivers/staging/mrst_nand/ffsport.c:392:error: 'struct request' has no member named 'current_nr_sectors'
drivers/staging/mrst_nand/ffsport.c:499:error: implicit declaration of function 'elv_next_request'
drivers/staging/mrst_nand/ffsport.c:517:error: implicit declaration of function 'end_request'
drivers/staging/mrst_nand/ffsport.c:738:error: implicit declaration of function 'blk_queue_hardsect_size'
--
~Randy
LPC 2009, Sept. 23-25, Portland, Oregon
http://linuxplumbersconf.org/2009/
On Wed, 2009-06-03 at 08:22 -0700, Randy Dunlap wrote:
> Stephen Rothwell wrote:
> CFG80211=y
> MAC80211=y
> RFKILL=m
>
> net/built-in.o: In function `cfg80211_netdev_notifier_call':
> core.c:(.text+0xa678b): undefined reference to `rfkill_blocked'
> net/built-in.o: In function `cfg80211_dev_free':
Hrm. I thought
config CFG80211
tristate "Improved wireless configuration API"
depends on RFKILL || !RFKILL
would avoid that. Why doesn't it?
johannes
On Wed, Jun 03, 2009 at 08:24:49AM -0700, Randy Dunlap wrote:
> Stephen Rothwell wrote:
> > Hi all,
> >
> > Looks like a real rush since -rc7 ...
>
>
> drivers/staging/comedi/drivers/adq12b.c:328: error: implicit declaration of function 'udelay'
>
>
> drivers/staging/mrst_nand/ffsport.c:360:error: 'struct request' has no member named 'sector'
> drivers/staging/mrst_nand/ffsport.c:376:error: 'struct request' has no member named 'sector'
> drivers/staging/mrst_nand/ffsport.c:376:error: 'struct request' has no member named 'current_nr_sectors'
> drivers/staging/mrst_nand/ffsport.c:380:error: 'struct request' has no member named 'sector'
> drivers/staging/mrst_nand/ffsport.c:381:error: 'struct request' has no member named 'current_nr_sectors'
> drivers/staging/mrst_nand/ffsport.c:392:error: 'struct request' has no member named 'current_nr_sectors'
> drivers/staging/mrst_nand/ffsport.c:499:error: implicit declaration of function 'elv_next_request'
> drivers/staging/mrst_nand/ffsport.c:517:error: implicit declaration of function 'end_request'
> drivers/staging/mrst_nand/ffsport.c:738:error: implicit declaration of function 'blk_queue_hardsect_size'
Can I get your .config for this? It works here with a "default" one.
thanks,
greg k-h
#
# Automatically generated make config: don't edit
# Linux kernel version: 2.6.30-rc7
# Wed Jun 3 02:15:38 2009
#
# CONFIG_64BIT is not set
CONFIG_X86_32=y
# CONFIG_X86_64 is not set
CONFIG_X86=y
CONFIG_OUTPUT_FORMAT="elf32-i386"
CONFIG_ARCH_DEFCONFIG="arch/x86/configs/i386_defconfig"
CONFIG_GENERIC_TIME=y
CONFIG_GENERIC_CMOS_UPDATE=y
CONFIG_CLOCKSOURCE_WATCHDOG=y
CONFIG_GENERIC_CLOCKEVENTS=y
CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y
CONFIG_LOCKDEP_SUPPORT=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_HAVE_LATENCYTOP_SUPPORT=y
CONFIG_FAST_CMPXCHG_LOCAL=y
CONFIG_MMU=y
CONFIG_ZONE_DMA=y
CONFIG_GENERIC_ISA_DMA=y
CONFIG_GENERIC_IOMAP=y
CONFIG_GENERIC_HWEIGHT=y
CONFIG_GENERIC_GPIO=y
CONFIG_ARCH_MAY_HAVE_PC_FDC=y
# CONFIG_RWSEM_GENERIC_SPINLOCK is not set
CONFIG_RWSEM_XCHGADD_ALGORITHM=y
CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
# CONFIG_GENERIC_TIME_VSYSCALL is not set
CONFIG_ARCH_HAS_CPU_RELAX=y
CONFIG_ARCH_HAS_DEFAULT_IDLE=y
CONFIG_ARCH_HAS_CACHE_LINE_SIZE=y
CONFIG_HAVE_SETUP_PER_CPU_AREA=y
CONFIG_HAVE_DYNAMIC_PER_CPU_AREA=y
# CONFIG_HAVE_CPUMASK_OF_CPU_MAP is not set
CONFIG_ARCH_HIBERNATION_POSSIBLE=y
CONFIG_ARCH_SUSPEND_POSSIBLE=y
# CONFIG_ZONE_DMA32 is not set
CONFIG_ARCH_POPULATES_NODE_MAP=y
# CONFIG_AUDIT_ARCH is not set
CONFIG_ARCH_SUPPORTS_OPTIMIZED_INLINING=y
CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y
CONFIG_GENERIC_HARDIRQS=y
CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
CONFIG_GENERIC_IRQ_PROBE=y
CONFIG_GENERIC_PENDING_IRQ=y
CONFIG_USE_GENERIC_SMP_HELPERS=y
CONFIG_X86_32_SMP=y
CONFIG_X86_HT=y
CONFIG_X86_TRAMPOLINE=y
CONFIG_KTIME_SCALAR=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
#
# General setup
#
CONFIG_EXPERIMENTAL=y
CONFIG_LOCK_KERNEL=y
CONFIG_INIT_ENV_ARG_LIMIT=32
CONFIG_LOCALVERSION=""
CONFIG_LOCALVERSION_AUTO=y
CONFIG_HAVE_KERNEL_GZIP=y
CONFIG_HAVE_KERNEL_BZIP2=y
CONFIG_HAVE_KERNEL_LZMA=y
# CONFIG_KERNEL_GZIP is not set
CONFIG_KERNEL_BZIP2=y
# CONFIG_KERNEL_LZMA is not set
CONFIG_SWAP=y
CONFIG_SYSVIPC=y
CONFIG_SYSVIPC_SYSCTL=y
CONFIG_BSD_PROCESS_ACCT=y
# CONFIG_BSD_PROCESS_ACCT_V3 is not set
#
# RCU Subsystem
#
CONFIG_CLASSIC_RCU=y
# CONFIG_TREE_RCU is not set
# CONFIG_PREEMPT_RCU is not set
# CONFIG_TREE_RCU_TRACE is not set
# CONFIG_PREEMPT_RCU_TRACE is not set
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_LOG_BUF_SHIFT=17
CONFIG_HAVE_UNSTABLE_SCHED_CLOCK=y
CONFIG_GROUP_SCHED=y
CONFIG_FAIR_GROUP_SCHED=y
CONFIG_RT_GROUP_SCHED=y
CONFIG_USER_SCHED=y
# CONFIG_CGROUP_SCHED is not set
# CONFIG_CGROUPS is not set
# CONFIG_SYSFS_DEPRECATED_V2 is not set
CONFIG_RELAY=y
# CONFIG_NAMESPACES is not set
# CONFIG_BLK_DEV_INITRD is not set
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
CONFIG_SYSCTL=y
CONFIG_ANON_INODES=y
CONFIG_EMBEDDED=y
# CONFIG_UID16 is not set
CONFIG_SYSCTL_SYSCALL=y
CONFIG_KALLSYMS=y
CONFIG_KALLSYMS_ALL=y
CONFIG_KALLSYMS_EXTRA_PASS=y
CONFIG_STRIP_ASM_SYMS=y
# CONFIG_HOTPLUG is not set
# CONFIG_PRINTK is not set
# CONFIG_BUG is not set
CONFIG_ELF_CORE=y
CONFIG_PCSPKR_PLATFORM=y
CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
# CONFIG_EPOLL is not set
CONFIG_SIGNALFD=y
CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_AIO=y
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_COMPAT_BRK=y
# CONFIG_SLAB_ALLOCATOR is not set
# CONFIG_SLUB_ALLOCATOR is not set
CONFIG_SLQB_ALLOCATOR=y
CONFIG_SLQB=y
# CONFIG_SLOB is not set
CONFIG_PROFILING=y
CONFIG_TRACEPOINTS=y
CONFIG_MARKERS=y
CONFIG_OPROFILE=y
CONFIG_OPROFILE_IBS=y
CONFIG_HAVE_OPROFILE=y
CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
CONFIG_HAVE_IOREMAP_PROT=y
CONFIG_HAVE_KPROBES=y
CONFIG_HAVE_KRETPROBES=y
CONFIG_HAVE_ARCH_TRACEHOOK=y
CONFIG_HAVE_DMA_API_DEBUG=y
CONFIG_SLOW_WORK=y
CONFIG_HAVE_GENERIC_DMA_COHERENT=y
CONFIG_SLABINFO=y
CONFIG_RT_MUTEXES=y
CONFIG_BASE_SMALL=0
# CONFIG_MODULES is not set
CONFIG_BLOCK=y
CONFIG_LBD=y
CONFIG_BLK_DEV_BSG=y
CONFIG_BLK_DEV_INTEGRITY=y
#
# IO Schedulers
#
CONFIG_IOSCHED_NOOP=y
# CONFIG_IOSCHED_AS is not set
CONFIG_IOSCHED_DEADLINE=y
CONFIG_IOSCHED_CFQ=y
# CONFIG_DEFAULT_AS is not set
CONFIG_DEFAULT_DEADLINE=y
# CONFIG_DEFAULT_CFQ is not set
# CONFIG_DEFAULT_NOOP is not set
CONFIG_DEFAULT_IOSCHED="deadline"
# CONFIG_FREEZER is not set
#
# Processor type and features
#
# CONFIG_NO_HZ is not set
# CONFIG_HIGH_RES_TIMERS is not set
CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
CONFIG_SMP=y
CONFIG_X86_MPPARSE=y
CONFIG_X86_BIGSMP=y
CONFIG_X86_EXTENDED_PLATFORM=y
# CONFIG_X86_ELAN is not set
CONFIG_X86_RDC321X=y
CONFIG_X86_32_NON_STANDARD=y
# CONFIG_X86_NUMAQ is not set
CONFIG_X86_SUMMIT=y
CONFIG_X86_ES7000=y
CONFIG_SCHED_OMIT_FRAME_POINTER=y
CONFIG_PARAVIRT_GUEST=y
CONFIG_XEN=y
CONFIG_XEN_MAX_DOMAIN_MEMORY=8
CONFIG_XEN_DEBUG_FS=y
CONFIG_VMI=y
CONFIG_KVM_CLOCK=y
# CONFIG_KVM_GUEST is not set
CONFIG_PARAVIRT=y
CONFIG_PARAVIRT_SPINLOCKS=y
CONFIG_PARAVIRT_CLOCK=y
CONFIG_PARAVIRT_DEBUG=y
CONFIG_MEMTEST=y
CONFIG_X86_CYCLONE_TIMER=y
# CONFIG_M386 is not set
# CONFIG_M486 is not set
# CONFIG_M586 is not set
# CONFIG_M586TSC is not set
# CONFIG_M586MMX is not set
# CONFIG_M686 is not set
# CONFIG_MPENTIUMII is not set
# CONFIG_MPENTIUMIII is not set
# CONFIG_MPENTIUMM is not set
# CONFIG_MPENTIUM4 is not set
# CONFIG_MK6 is not set
# CONFIG_MK7 is not set
# CONFIG_MK8 is not set
# CONFIG_MCRUSOE is not set
# CONFIG_MEFFICEON is not set
# CONFIG_MWINCHIPC6 is not set
# CONFIG_MWINCHIP3D is not set
CONFIG_MGEODEGX1=y
# CONFIG_MGEODE_LX is not set
# CONFIG_MCYRIXIII is not set
# CONFIG_MVIAC3_2 is not set
# CONFIG_MVIAC7 is not set
# CONFIG_MPSC is not set
# CONFIG_MCORE2 is not set
# CONFIG_GENERIC_CPU is not set
CONFIG_X86_GENERIC=y
CONFIG_X86_CPU=y
CONFIG_X86_L1_CACHE_BYTES=64
CONFIG_X86_INTERNODE_CACHE_BYTES=64
CONFIG_X86_CMPXCHG=y
CONFIG_X86_L1_CACHE_SHIFT=4
CONFIG_X86_XADD=y
# CONFIG_X86_PPRO_FENCE is not set
CONFIG_X86_WP_WORKS_OK=y
CONFIG_X86_INVLPG=y
CONFIG_X86_BSWAP=y
CONFIG_X86_POPAD_OK=y
CONFIG_X86_ALIGNMENT_16=y
CONFIG_X86_INTEL_USERCOPY=y
CONFIG_X86_TSC=y
CONFIG_X86_CMPXCHG64=y
CONFIG_X86_MINIMUM_CPU_FAMILY=4
CONFIG_X86_DEBUGCTLMSR=y
# CONFIG_PROCESSOR_SELECT is not set
CONFIG_CPU_SUP_INTEL=y
CONFIG_CPU_SUP_CYRIX_32=y
CONFIG_CPU_SUP_AMD=y
CONFIG_CPU_SUP_CENTAUR=y
CONFIG_CPU_SUP_TRANSMETA_32=y
CONFIG_CPU_SUP_UMC_32=y
CONFIG_X86_DS=y
CONFIG_X86_PTRACE_BTS=y
CONFIG_HPET_TIMER=y
CONFIG_HPET_EMULATE_RTC=y
CONFIG_DMI=y
# CONFIG_IOMMU_HELPER is not set
# CONFIG_IOMMU_API is not set
CONFIG_NR_CPUS=32
# CONFIG_SCHED_SMT is not set
# CONFIG_SCHED_MC is not set
# CONFIG_PREEMPT_NONE is not set
CONFIG_PREEMPT_VOLUNTARY=y
# CONFIG_PREEMPT is not set
CONFIG_X86_LOCAL_APIC=y
CONFIG_X86_IO_APIC=y
# CONFIG_X86_REROUTE_FOR_BROKEN_BOOT_IRQS is not set
CONFIG_X86_MCE=y
# CONFIG_X86_OLD_MCE is not set
CONFIG_X86_NEW_MCE=y
CONFIG_X86_MCE_INTEL=y
CONFIG_X86_MCE_AMD=y
# CONFIG_X86_ANCIENT_MCE is not set
CONFIG_X86_MCE_THRESHOLD=y
CONFIG_X86_MCE_INJECT=y
CONFIG_X86_THERMAL_VECTOR=y
# CONFIG_VM86 is not set
CONFIG_TOSHIBA=y
CONFIG_I8K=y
CONFIG_X86_REBOOTFIXUPS=y
# CONFIG_MICROCODE is not set
CONFIG_X86_MSR=y
CONFIG_X86_CPUID=y
CONFIG_X86_CPU_DEBUG=y
CONFIG_NOHIGHMEM=y
# CONFIG_HIGHMEM4G is not set
# CONFIG_HIGHMEM64G is not set
CONFIG_VMSPLIT_3G=y
# CONFIG_VMSPLIT_3G_OPT is not set
# CONFIG_VMSPLIT_2G is not set
# CONFIG_VMSPLIT_2G_OPT is not set
# CONFIG_VMSPLIT_1G is not set
CONFIG_PAGE_OFFSET=0xC0000000
CONFIG_X86_PAE=y
CONFIG_ARCH_PHYS_ADDR_T_64BIT=y
#
# NUMA (Summit) requires SMP, 64GB highmem support, ACPI
#
CONFIG_NEED_NODE_MEMMAP_SIZE=y
CONFIG_ARCH_FLATMEM_ENABLE=y
CONFIG_ARCH_SPARSEMEM_ENABLE=y
CONFIG_ARCH_SELECT_MEMORY_MODEL=y
CONFIG_ILLEGAL_POINTER_VALUE=0
CONFIG_SELECT_MEMORY_MODEL=y
# CONFIG_FLATMEM_MANUAL is not set
# CONFIG_DISCONTIGMEM_MANUAL is not set
CONFIG_SPARSEMEM_MANUAL=y
CONFIG_SPARSEMEM=y
CONFIG_HAVE_MEMORY_PRESENT=y
CONFIG_SPARSEMEM_STATIC=y
CONFIG_PAGEFLAGS_EXTENDED=y
CONFIG_SPLIT_PTLOCK_CPUS=4
CONFIG_PHYS_ADDR_T_64BIT=y
CONFIG_ZONE_DMA_FLAG=1
CONFIG_BOUNCE=y
CONFIG_VIRT_TO_BUS=y
CONFIG_UNEVICTABLE_LRU=y
CONFIG_HAVE_MLOCK=y
CONFIG_HAVE_MLOCKED_PAGE_BIT=y
# CONFIG_X86_CHECK_BIOS_CORRUPTION is not set
CONFIG_X86_RESERVE_LOW_64K=y
CONFIG_MATH_EMULATION=y
# CONFIG_MTRR is not set
CONFIG_SECCOMP=y
CONFIG_CC_STACKPROTECTOR_ALL=y
CONFIG_CC_STACKPROTECTOR=y
# CONFIG_HZ_100 is not set
CONFIG_HZ_250=y
# CONFIG_HZ_300 is not set
# CONFIG_HZ_1000 is not set
CONFIG_HZ=250
# CONFIG_SCHED_HRTICK is not set
CONFIG_KEXEC=y
CONFIG_PHYSICAL_START=0x1000000
# CONFIG_RELOCATABLE is not set
CONFIG_PHYSICAL_ALIGN=0x1000000
# CONFIG_COMPAT_VDSO is not set
CONFIG_CMDLINE_BOOL=y
CONFIG_CMDLINE=""
CONFIG_CMDLINE_OVERRIDE=y
#
# Power management and ACPI options
#
# CONFIG_PM is not set
#
# CPU Frequency scaling
#
CONFIG_CPU_FREQ=y
CONFIG_CPU_FREQ_TABLE=y
CONFIG_CPU_FREQ_DEBUG=y
CONFIG_CPU_FREQ_STAT=y
CONFIG_CPU_FREQ_STAT_DETAILS=y
# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set
# CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE is not set
CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE=y
# CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND is not set
# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set
CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
# CONFIG_CPU_FREQ_GOV_POWERSAVE is not set
CONFIG_CPU_FREQ_GOV_USERSPACE=y
# CONFIG_CPU_FREQ_GOV_ONDEMAND is not set
CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y
#
# CPUFreq processor drivers
#
# CONFIG_X86_POWERNOW_K6 is not set
CONFIG_X86_POWERNOW_K7=y
CONFIG_X86_SPEEDSTEP_CENTRINO=y
CONFIG_X86_SPEEDSTEP_CENTRINO_TABLE=y
CONFIG_X86_SPEEDSTEP_ICH=y
# CONFIG_X86_SPEEDSTEP_SMI is not set
# CONFIG_X86_P4_CLOCKMOD is not set
CONFIG_X86_CPUFREQ_NFORCE2=y
CONFIG_X86_LONGRUN=y
# CONFIG_X86_E_POWERSAVER is not set
#
# shared options
#
CONFIG_X86_SPEEDSTEP_LIB=y
CONFIG_X86_SPEEDSTEP_RELAXED_CAP_CHECK=y
CONFIG_CPU_IDLE=y
CONFIG_CPU_IDLE_GOV_LADDER=y
#
# Bus options (PCI etc.)
#
# CONFIG_PCI is not set
# CONFIG_ARCH_SUPPORTS_MSI is not set
CONFIG_ISA_DMA_API=y
CONFIG_ISA=y
# CONFIG_EISA is not set
CONFIG_MCA=y
CONFIG_MCA_LEGACY=y
# CONFIG_MCA_PROC_FS is not set
CONFIG_SCx200=y
CONFIG_SCx200HR_TIMER=y
# CONFIG_OLPC is not set
#
# Executable file formats / Emulations
#
CONFIG_BINFMT_ELF=y
CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS=y
CONFIG_HAVE_AOUT=y
# CONFIG_BINFMT_AOUT is not set
CONFIG_BINFMT_MISC=y
CONFIG_HAVE_ATOMIC_IOMAP=y
# CONFIG_NET is not set
#
# Device Drivers
#
#
# Generic Driver Options
#
CONFIG_STANDALONE=y
CONFIG_PREVENT_FIRMWARE_BUILD=y
CONFIG_FW_LOADER=y
# CONFIG_FIRMWARE_IN_KERNEL is not set
CONFIG_EXTRA_FIRMWARE=""
CONFIG_DEBUG_DRIVER=y
# CONFIG_DEBUG_DEVRES is not set
CONFIG_SYS_HYPERVISOR=y
CONFIG_MTD=y
CONFIG_MTD_DEBUG=y
CONFIG_MTD_DEBUG_VERBOSE=0
# CONFIG_MTD_CONCAT is not set
# CONFIG_MTD_PARTITIONS is not set
#
# User Modules And Translation Layers
#
CONFIG_MTD_CHAR=y
CONFIG_HAVE_MTD_OTP=y
CONFIG_MTD_BLKDEVS=y
# CONFIG_MTD_BLOCK is not set
CONFIG_MTD_BLOCK_RO=y
CONFIG_FTL=y
# CONFIG_NFTL is not set
CONFIG_INFTL=y
CONFIG_RFD_FTL=y
# CONFIG_SSFDC is not set
# CONFIG_MTD_OOPS is not set
#
# RAM/ROM/Flash chip drivers
#
# CONFIG_MTD_CFI is not set
CONFIG_MTD_JEDECPROBE=y
CONFIG_MTD_GEN_PROBE=y
CONFIG_MTD_CFI_ADV_OPTIONS=y
# CONFIG_MTD_CFI_NOSWAP is not set
# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set
CONFIG_MTD_CFI_LE_BYTE_SWAP=y
# CONFIG_MTD_CFI_GEOMETRY is not set
CONFIG_MTD_MAP_BANK_WIDTH_1=y
CONFIG_MTD_MAP_BANK_WIDTH_2=y
CONFIG_MTD_MAP_BANK_WIDTH_4=y
# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
CONFIG_MTD_CFI_I1=y
CONFIG_MTD_CFI_I2=y
# CONFIG_MTD_CFI_I4 is not set
# CONFIG_MTD_CFI_I8 is not set
CONFIG_MTD_OTP=y
# CONFIG_MTD_CFI_INTELEXT is not set
CONFIG_MTD_CFI_AMDSTD=y
# CONFIG_MTD_CFI_STAA is not set
CONFIG_MTD_CFI_UTIL=y
CONFIG_MTD_RAM=y
CONFIG_MTD_ROM=y
CONFIG_MTD_ABSENT=y
#
# Mapping drivers for chip access
#
# CONFIG_MTD_COMPLEX_MAPPINGS is not set
CONFIG_MTD_PHYSMAP=y
CONFIG_MTD_PHYSMAP_COMPAT=y
CONFIG_MTD_PHYSMAP_START=0x8000000
CONFIG_MTD_PHYSMAP_LEN=0
CONFIG_MTD_PHYSMAP_BANKWIDTH=2
# CONFIG_MTD_TS5500 is not set
CONFIG_MTD_AMD76XROM=y
CONFIG_MTD_ICHXROM=y
# CONFIG_MTD_SCB2_FLASH is not set
CONFIG_MTD_L440GX=y
CONFIG_MTD_PLATRAM=y
#
# Self-contained MTD device drivers
#
CONFIG_MTD_SLRAM=y
CONFIG_MTD_PHRAM=y
# CONFIG_MTD_MTDRAM is not set
CONFIG_MTD_BLOCK2MTD=y
#
# Disk-On-Chip Device Drivers
#
CONFIG_MTD_DOC2000=y
CONFIG_MTD_DOC2001=y
CONFIG_MTD_DOC2001PLUS=y
CONFIG_MTD_DOCPROBE=y
CONFIG_MTD_DOCECC=y
CONFIG_MTD_DOCPROBE_ADVANCED=y
CONFIG_MTD_DOCPROBE_ADDRESS=0x0000
CONFIG_MTD_DOCPROBE_HIGH=y
# CONFIG_MTD_DOCPROBE_55AA is not set
CONFIG_MTD_NAND=y
CONFIG_MTD_NAND_VERIFY_WRITE=y
# CONFIG_MTD_NAND_ECC_SMC is not set
CONFIG_MTD_NAND_MUSEUM_IDS=y
CONFIG_MTD_NAND_IDS=y
CONFIG_MTD_NAND_DISKONCHIP=y
CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADVANCED=y
CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADDRESS=0
CONFIG_MTD_NAND_DISKONCHIP_PROBE_HIGH=y
# CONFIG_MTD_NAND_DISKONCHIP_BBTWRITE is not set
CONFIG_MTD_NAND_CS553X=y
CONFIG_MTD_NAND_PLATFORM=y
CONFIG_MTD_ONENAND=y
# CONFIG_MTD_ONENAND_VERIFY_WRITE is not set
CONFIG_MTD_ONENAND_OTP=y
# CONFIG_MTD_ONENAND_2X_PROGRAM is not set
#
# LPDDR flash memory drivers
#
CONFIG_MTD_LPDDR=y
CONFIG_MTD_QINFO_PROBE=y
#
# UBI - Unsorted block images
#
CONFIG_MTD_UBI=y
CONFIG_MTD_UBI_WL_THRESHOLD=4096
CONFIG_MTD_UBI_BEB_RESERVE=1
CONFIG_MTD_UBI_GLUEBI=y
#
# UBI debugging options
#
CONFIG_MTD_UBI_DEBUG=y
CONFIG_MTD_UBI_DEBUG_MSG=y
CONFIG_MTD_UBI_DEBUG_PARANOID=y
CONFIG_MTD_UBI_DEBUG_DISABLE_BGT=y
# CONFIG_MTD_UBI_DEBUG_EMULATE_BITFLIPS is not set
CONFIG_MTD_UBI_DEBUG_EMULATE_WRITE_FAILURES=y
# CONFIG_MTD_UBI_DEBUG_EMULATE_ERASE_FAILURES is not set
#
# Additional UBI debugging messages
#
CONFIG_MTD_UBI_DEBUG_MSG_BLD=y
CONFIG_MTD_UBI_DEBUG_MSG_EBA=y
CONFIG_MTD_UBI_DEBUG_MSG_WL=y
# CONFIG_MTD_UBI_DEBUG_MSG_IO is not set
CONFIG_PARPORT=y
CONFIG_PARPORT_PC=y
CONFIG_PARPORT_PC_FIFO=y
# CONFIG_PARPORT_PC_SUPERIO is not set
# CONFIG_PARPORT_GSC is not set
CONFIG_PARPORT_AX88796=y
CONFIG_PARPORT_1284=y
CONFIG_PARPORT_NOT_PC=y
CONFIG_PNP=y
CONFIG_PNP_DEBUG_MESSAGES=y
#
# Protocols
#
# CONFIG_ISAPNP is not set
# CONFIG_PNPBIOS is not set
# CONFIG_PNPACPI is not set
CONFIG_BLK_DEV=y
CONFIG_BLK_DEV_FD=y
# CONFIG_BLK_DEV_XD is not set
CONFIG_PARIDE=y
#
# Parallel IDE high-level drivers
#
CONFIG_PARIDE_PD=y
CONFIG_PARIDE_PCD=y
# CONFIG_PARIDE_PF is not set
CONFIG_PARIDE_PT=y
# CONFIG_PARIDE_PG is not set
#
# Parallel IDE protocol modules
#
CONFIG_PARIDE_ATEN=y
CONFIG_PARIDE_BPCK=y
CONFIG_PARIDE_BPCK6=y
CONFIG_PARIDE_COMM=y
CONFIG_PARIDE_DSTR=y
CONFIG_PARIDE_FIT2=y
# CONFIG_PARIDE_FIT3 is not set
CONFIG_PARIDE_EPAT=y
# CONFIG_PARIDE_EPATC8 is not set
CONFIG_PARIDE_EPIA=y
CONFIG_PARIDE_FRIQ=y
CONFIG_PARIDE_FRPW=y
# CONFIG_PARIDE_KBIC is not set
# CONFIG_PARIDE_KTTI is not set
# CONFIG_PARIDE_ON20 is not set
CONFIG_PARIDE_ON26=y
# CONFIG_BLK_DEV_COW_COMMON is not set
CONFIG_BLK_DEV_LOOP=y
CONFIG_BLK_DEV_CRYPTOLOOP=y
# CONFIG_BLK_DEV_RAM is not set
# CONFIG_CDROM_PKTCDVD is not set
CONFIG_XEN_BLKDEV_FRONTEND=y
# CONFIG_VIRTIO_BLK is not set
CONFIG_BLK_DEV_HD=y
# CONFIG_MISC_DEVICES is not set
CONFIG_HAVE_IDE=y
CONFIG_IDE=y
#
# Please see Documentation/ide/ide.txt for help/info on IDE drives
#
CONFIG_IDE_XFER_MODE=y
CONFIG_IDE_TIMINGS=y
CONFIG_IDE_ATAPI=y
CONFIG_IDE_LEGACY=y
CONFIG_BLK_DEV_IDE_SATA=y
CONFIG_IDE_GD=y
CONFIG_IDE_GD_ATA=y
CONFIG_IDE_GD_ATAPI=y
# CONFIG_BLK_DEV_IDECD is not set
CONFIG_BLK_DEV_IDETAPE=y
CONFIG_IDE_TASK_IOCTL=y
CONFIG_IDE_PROC_FS=y
#
# IDE chipset support/bugfixes
#
# CONFIG_IDE_GENERIC is not set
CONFIG_BLK_DEV_PLATFORM=y
CONFIG_BLK_DEV_CMD640=y
CONFIG_BLK_DEV_CMD640_ENHANCED=y
CONFIG_BLK_DEV_IDEPNP=y
#
# Other IDE chipsets support
#
#
# Note: most of these also require special kernel boot parameters
#
CONFIG_BLK_DEV_4DRIVES=y
CONFIG_BLK_DEV_ALI14XX=y
CONFIG_BLK_DEV_DTC2278=y
CONFIG_BLK_DEV_HT6560B=y
CONFIG_BLK_DEV_QD65XX=y
CONFIG_BLK_DEV_UMC8672=y
# CONFIG_BLK_DEV_IDEDMA is not set
#
# SCSI device support
#
# CONFIG_RAID_ATTRS is not set
# CONFIG_SCSI is not set
# CONFIG_SCSI_DMA is not set
# CONFIG_SCSI_NETLINK is not set
# CONFIG_ATA is not set
CONFIG_MD=y
# CONFIG_BLK_DEV_MD is not set
CONFIG_BLK_DEV_DM=y
# CONFIG_DM_DEBUG is not set
CONFIG_DM_CRYPT=y
CONFIG_DM_SNAPSHOT=y
CONFIG_DM_MIRROR=y
CONFIG_DM_ZERO=y
CONFIG_DM_MULTIPATH=y
CONFIG_DM_MULTIPATH_QL=y
CONFIG_DM_DELAY=y
CONFIG_DM_UEVENT=y
CONFIG_MACINTOSH_DRIVERS=y
# CONFIG_MAC_EMUMOUSEBTN is not set
CONFIG_PHONE=y
CONFIG_PHONE_IXJ=y
#
# Input device support
#
CONFIG_INPUT=y
# CONFIG_INPUT_FF_MEMLESS is not set
CONFIG_INPUT_POLLDEV=y
#
# Userland interfaces
#
CONFIG_INPUT_MOUSEDEV=y
CONFIG_INPUT_MOUSEDEV_PSAUX=y
CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
# CONFIG_INPUT_JOYDEV is not set
# CONFIG_INPUT_EVDEV is not set
# CONFIG_INPUT_EVBUG is not set
# CONFIG_XEN_KBDDEV_FRONTEND is not set
#
# Input Device Drivers
#
CONFIG_INPUT_KEYBOARD=y
# CONFIG_KEYBOARD_ATKBD is not set
CONFIG_KEYBOARD_SUNKBD=y
CONFIG_KEYBOARD_LKKBD=y
CONFIG_KEYBOARD_XTKBD=y
CONFIG_KEYBOARD_NEWTON=y
# CONFIG_KEYBOARD_STOWAWAY is not set
CONFIG_KEYBOARD_LM8323=y
CONFIG_KEYBOARD_GPIO=y
# CONFIG_INPUT_MOUSE is not set
CONFIG_INPUT_JOYSTICK=y
# CONFIG_JOYSTICK_ANALOG is not set
CONFIG_JOYSTICK_A3D=y
CONFIG_JOYSTICK_ADI=y
CONFIG_JOYSTICK_COBRA=y
CONFIG_JOYSTICK_GF2K=y
# CONFIG_JOYSTICK_GRIP is not set
CONFIG_JOYSTICK_GRIP_MP=y
CONFIG_JOYSTICK_GUILLEMOT=y
# CONFIG_JOYSTICK_INTERACT is not set
# CONFIG_JOYSTICK_SIDEWINDER is not set
CONFIG_JOYSTICK_TMDC=y
# CONFIG_JOYSTICK_IFORCE is not set
# CONFIG_JOYSTICK_WARRIOR is not set
# CONFIG_JOYSTICK_MAGELLAN is not set
CONFIG_JOYSTICK_SPACEORB=y
CONFIG_JOYSTICK_SPACEBALL=y
# CONFIG_JOYSTICK_STINGER is not set
CONFIG_JOYSTICK_TWIDJOY=y
# CONFIG_JOYSTICK_ZHENHUA is not set
CONFIG_JOYSTICK_DB9=y
# CONFIG_JOYSTICK_GAMECON is not set
CONFIG_JOYSTICK_TURBOGRAFX=y
CONFIG_JOYSTICK_JOYDUMP=y
CONFIG_INPUT_TABLET=y
CONFIG_INPUT_TOUCHSCREEN=y
# CONFIG_TOUCHSCREEN_AD7879_I2C is not set
# CONFIG_TOUCHSCREEN_AD7879 is not set
CONFIG_TOUCHSCREEN_DA9034=y
# CONFIG_TOUCHSCREEN_EETI is not set
CONFIG_TOUCHSCREEN_FUJITSU=y
CONFIG_TOUCHSCREEN_GUNZE=y
CONFIG_TOUCHSCREEN_ELO=y
CONFIG_TOUCHSCREEN_WACOM_W8001=y
CONFIG_TOUCHSCREEN_MTOUCH=y
# CONFIG_TOUCHSCREEN_INEXIO is not set
CONFIG_TOUCHSCREEN_MK712=y
CONFIG_TOUCHSCREEN_HTCPEN=y
CONFIG_TOUCHSCREEN_PENMOUNT=y
# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set
CONFIG_TOUCHSCREEN_TOUCHWIN=y
CONFIG_TOUCHSCREEN_TOUCHIT213=y
# CONFIG_TOUCHSCREEN_TSC2007 is not set
CONFIG_INPUT_MISC=y
CONFIG_INPUT_PCSPKR=y
CONFIG_INPUT_APANEL=y
CONFIG_INPUT_WISTRON_BTNS=y
CONFIG_INPUT_UINPUT=y
CONFIG_INPUT_PCF50633_PMU=y
CONFIG_INPUT_GPIO_ROTARY_ENCODER=y
#
# Hardware I/O ports
#
CONFIG_SERIO=y
CONFIG_SERIO_I8042=y
CONFIG_SERIO_SERPORT=y
CONFIG_SERIO_CT82C710=y
CONFIG_SERIO_PARKBD=y
# CONFIG_SERIO_LIBPS2 is not set
CONFIG_SERIO_RAW=y
CONFIG_GAMEPORT=y
CONFIG_GAMEPORT_NS558=y
# CONFIG_GAMEPORT_L4 is not set
#
# Character devices
#
CONFIG_VT=y
# CONFIG_CONSOLE_TRANSLATIONS is not set
# CONFIG_VT_CONSOLE is not set
CONFIG_HW_CONSOLE=y
CONFIG_VT_HW_CONSOLE_BINDING=y
CONFIG_DEVKMEM=y
# CONFIG_SERIAL_NONSTANDARD is not set
#
# Serial drivers
#
# CONFIG_SERIAL_8250 is not set
CONFIG_FIX_EARLYCON_MEM=y
#
# Non-8250 serial port support
#
CONFIG_CONSOLE_POLL=y
# CONFIG_UNIX98_PTYS is not set
CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=256
# CONFIG_PRINTER is not set
# CONFIG_PPDEV is not set
CONFIG_HVC_DRIVER=y
CONFIG_HVC_IRQ=y
CONFIG_HVC_XEN=y
CONFIG_VIRTIO_CONSOLE=y
# CONFIG_IPMI_HANDLER is not set
CONFIG_HW_RANDOM=y
CONFIG_HW_RANDOM_TIMERIOMEM=y
CONFIG_HW_RANDOM_VIA=y
CONFIG_HW_RANDOM_VIRTIO=y
CONFIG_NVRAM=y
CONFIG_DTLK=y
# CONFIG_R3964 is not set
# CONFIG_MWAVE is not set
CONFIG_SCx200_GPIO=y
# CONFIG_PC8736x_GPIO is not set
CONFIG_NSC_GPIO=y
CONFIG_CS5535_GPIO=y
# CONFIG_RAW_DRIVER is not set
# CONFIG_HANGCHECK_TIMER is not set
CONFIG_TCG_TPM=y
# CONFIG_TCG_TIS is not set
# CONFIG_TCG_NSC is not set
# CONFIG_TCG_ATMEL is not set
CONFIG_TCG_INFINEON=y
# CONFIG_TELCLOCK is not set
CONFIG_DEVPORT=y
CONFIG_I2C=y
CONFIG_I2C_BOARDINFO=y
# CONFIG_I2C_CHARDEV is not set
CONFIG_I2C_HELPER_AUTO=y
CONFIG_I2C_ALGOBIT=y
CONFIG_I2C_ALGOPCA=y
#
# I2C Hardware Bus support
#
#
# I2C system bus drivers (mostly embedded / system-on-chip)
#
# CONFIG_I2C_GPIO is not set
# CONFIG_I2C_OCORES is not set
# CONFIG_I2C_SIMTEC is not set
#
# External I2C/SMBus adapter drivers
#
CONFIG_I2C_PARPORT=y
CONFIG_I2C_PARPORT_LIGHT=y
# CONFIG_I2C_TAOS_EVM is not set
#
# Other I2C/SMBus bus drivers
#
CONFIG_I2C_PCA_ISA=y
CONFIG_I2C_PCA_PLATFORM=y
CONFIG_SCx200_I2C=y
CONFIG_SCx200_I2C_SCL=12
CONFIG_SCx200_I2C_SDA=13
#
# Miscellaneous I2C Chip support
#
# CONFIG_DS1682 is not set
CONFIG_SENSORS_PCA9539=y
CONFIG_SENSORS_TSL2550=y
CONFIG_I2C_DEBUG_CORE=y
CONFIG_I2C_DEBUG_ALGO=y
CONFIG_I2C_DEBUG_BUS=y
CONFIG_I2C_DEBUG_CHIP=y
# CONFIG_SPI is not set
CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
CONFIG_GPIOLIB=y
CONFIG_DEBUG_GPIO=y
CONFIG_GPIO_SYSFS=y
#
# Memory mapped GPIO expanders:
#
#
# I2C GPIO expanders:
#
CONFIG_GPIO_MAX732X=y
# CONFIG_GPIO_PCA953X is not set
CONFIG_GPIO_PCF857X=y
#
# PCI GPIO expanders:
#
#
# SPI GPIO expanders:
#
CONFIG_W1=y
#
# 1-wire Bus Masters
#
# CONFIG_W1_MASTER_DS2482 is not set
CONFIG_W1_MASTER_GPIO=y
#
# 1-wire Slaves
#
# CONFIG_W1_SLAVE_THERM is not set
# CONFIG_W1_SLAVE_SMEM is not set
CONFIG_W1_SLAVE_DS2431=y
CONFIG_W1_SLAVE_DS2433=y
CONFIG_W1_SLAVE_DS2433_CRC=y
# CONFIG_W1_SLAVE_DS2760 is not set
CONFIG_W1_SLAVE_BQ27000=y
CONFIG_POWER_SUPPLY=y
CONFIG_POWER_SUPPLY_DEBUG=y
CONFIG_PDA_POWER=y
# CONFIG_BATTERY_DS2760 is not set
# CONFIG_BATTERY_BQ27x00 is not set
CONFIG_BATTERY_DA9030=y
CONFIG_CHARGER_PCF50633=y
# CONFIG_HWMON is not set
# CONFIG_THERMAL is not set
# CONFIG_THERMAL_HWMON is not set
# CONFIG_WATCHDOG is not set
CONFIG_SSB_POSSIBLE=y
#
# Sonics Silicon Backplane
#
CONFIG_SSB=y
CONFIG_SSB_SILENT=y
#
# Multifunction device drivers
#
CONFIG_MFD_CORE=y
CONFIG_MFD_SM501=y
CONFIG_MFD_SM501_GPIO=y
CONFIG_HTC_PASIC3=y
# CONFIG_TPS65010 is not set
# CONFIG_TWL4030_CORE is not set
# CONFIG_MFD_TMIO is not set
CONFIG_PMIC_DA903X=y
CONFIG_MFD_WM8400=y
# CONFIG_MFD_WM8350_I2C is not set
CONFIG_MFD_PCF50633=y
CONFIG_PCF50633_ADC=y
CONFIG_PCF50633_GPIO=y
CONFIG_AB3100_CORE=y
CONFIG_REGULATOR=y
CONFIG_REGULATOR_DEBUG=y
# CONFIG_REGULATOR_FIXED_VOLTAGE is not set
CONFIG_REGULATOR_VIRTUAL_CONSUMER=y
CONFIG_REGULATOR_USERSPACE_CONSUMER=y
CONFIG_REGULATOR_BQ24022=y
CONFIG_REGULATOR_MAX1586=y
CONFIG_REGULATOR_WM8400=y
CONFIG_REGULATOR_DA903X=y
CONFIG_REGULATOR_PCF50633=y
CONFIG_REGULATOR_LP3971=y
#
# Multimedia devices
#
#
# Multimedia core support
#
CONFIG_VIDEO_DEV=y
CONFIG_VIDEO_V4L2_COMMON=y
# CONFIG_VIDEO_ALLOW_V4L1 is not set
# CONFIG_VIDEO_V4L1_COMPAT is not set
CONFIG_VIDEO_MEDIA=y
#
# Multimedia drivers
#
CONFIG_MEDIA_TUNER=y
CONFIG_MEDIA_TUNER_CUSTOMISE=y
# CONFIG_MEDIA_TUNER_SIMPLE is not set
# CONFIG_MEDIA_TUNER_TDA8290 is not set
CONFIG_MEDIA_TUNER_TDA827X=y
CONFIG_MEDIA_TUNER_TDA18271=y
CONFIG_MEDIA_TUNER_TDA9887=y
# CONFIG_MEDIA_TUNER_TEA5761 is not set
CONFIG_MEDIA_TUNER_TEA5767=y
CONFIG_MEDIA_TUNER_MT20XX=y
# CONFIG_MEDIA_TUNER_MT2060 is not set
# CONFIG_MEDIA_TUNER_MT2266 is not set
CONFIG_MEDIA_TUNER_MT2131=y
CONFIG_MEDIA_TUNER_QT1010=y
CONFIG_MEDIA_TUNER_XC2028=y
# CONFIG_MEDIA_TUNER_XC5000 is not set
CONFIG_MEDIA_TUNER_MXL5005S=y
# CONFIG_MEDIA_TUNER_MXL5007T is not set
CONFIG_MEDIA_TUNER_MC44S803=y
CONFIG_VIDEO_V4L2=y
CONFIG_VIDEOBUF_GEN=y
CONFIG_VIDEOBUF_VMALLOC=y
CONFIG_VIDEO_CAPTURE_DRIVERS=y
CONFIG_VIDEO_ADV_DEBUG=y
CONFIG_VIDEO_FIXED_MINOR_RANGES=y
CONFIG_VIDEO_HELPER_CHIPS_AUTO=y
CONFIG_VIDEO_VIVI=y
CONFIG_VIDEO_SAA5246A=y
CONFIG_VIDEO_SAA5249=y
CONFIG_SOC_CAMERA=y
# CONFIG_SOC_CAMERA_MT9M001 is not set
CONFIG_SOC_CAMERA_MT9M111=y
CONFIG_SOC_CAMERA_MT9T031=y
CONFIG_SOC_CAMERA_MT9V022=y
CONFIG_SOC_CAMERA_TW9910=y
# CONFIG_SOC_CAMERA_PLATFORM is not set
# CONFIG_SOC_CAMERA_OV772X is not set
CONFIG_RADIO_ADAPTERS=y
CONFIG_RADIO_CADET=y
CONFIG_RADIO_RTRACK=y
CONFIG_RADIO_RTRACK_PORT=20f
CONFIG_RADIO_RTRACK2=y
CONFIG_RADIO_RTRACK2_PORT=30c
CONFIG_RADIO_AZTECH=y
CONFIG_RADIO_AZTECH_PORT=350
CONFIG_RADIO_GEMTEK=y
CONFIG_RADIO_GEMTEK_PORT=34c
CONFIG_RADIO_GEMTEK_PROBE=y
CONFIG_RADIO_SF16FMI=y
CONFIG_RADIO_SF16FMR2=y
CONFIG_RADIO_TERRATEC=y
CONFIG_RADIO_TERRATEC_PORT=590
# CONFIG_RADIO_TRUST is not set
CONFIG_RADIO_TYPHOON=y
CONFIG_RADIO_TYPHOON_PROC_FS=y
CONFIG_RADIO_TYPHOON_PORT=316
CONFIG_RADIO_TYPHOON_MUTEFREQ=87500
CONFIG_RADIO_ZOLTRIX=y
CONFIG_RADIO_ZOLTRIX_PORT=20c
CONFIG_RADIO_TEA5764=y
# CONFIG_RADIO_TEA5764_XTAL is not set
# CONFIG_DAB is not set
#
# Graphics support
#
# CONFIG_VGASTATE is not set
CONFIG_VIDEO_OUTPUT_CONTROL=y
CONFIG_FB=y
CONFIG_FIRMWARE_EDID=y
# CONFIG_FB_DDC is not set
# CONFIG_FB_BOOT_VESA_SUPPORT is not set
CONFIG_FB_CFB_FILLRECT=y
CONFIG_FB_CFB_COPYAREA=y
CONFIG_FB_CFB_IMAGEBLIT=y
# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
CONFIG_FB_SYS_FILLRECT=y
CONFIG_FB_SYS_COPYAREA=y
CONFIG_FB_SYS_IMAGEBLIT=y
# CONFIG_FB_FOREIGN_ENDIAN is not set
CONFIG_FB_SYS_FOPS=y
CONFIG_FB_DEFERRED_IO=y
# CONFIG_FB_SVGALIB is not set
# CONFIG_FB_MACMODES is not set
# CONFIG_FB_BACKLIGHT is not set
CONFIG_FB_MODE_HELPERS=y
# CONFIG_FB_TILEBLITTING is not set
#
# Frame buffer hardware drivers
#
CONFIG_FB_ARC=y
# CONFIG_FB_VGA16 is not set
# CONFIG_FB_VESA is not set
# CONFIG_FB_N411 is not set
CONFIG_FB_HGA=y
# CONFIG_FB_HGA_ACCEL is not set
CONFIG_FB_S1D13XXX=y
CONFIG_FB_TMIO=y
CONFIG_FB_TMIO_ACCELL=y
# CONFIG_FB_SM501 is not set
# CONFIG_FB_VIRTUAL is not set
CONFIG_XEN_FBDEV_FRONTEND=y
CONFIG_FB_METRONOME=y
CONFIG_FB_MB862XX=y
CONFIG_FB_BROADSHEET=y
CONFIG_BACKLIGHT_LCD_SUPPORT=y
# CONFIG_LCD_CLASS_DEVICE is not set
CONFIG_BACKLIGHT_CLASS_DEVICE=y
# CONFIG_BACKLIGHT_GENERIC is not set
CONFIG_BACKLIGHT_DA903X=y
CONFIG_BACKLIGHT_MBP_NVIDIA=y
CONFIG_BACKLIGHT_SAHARA=y
#
# Display device support
#
# CONFIG_DISPLAY_SUPPORT is not set
#
# Console display driver support
#
CONFIG_VGA_CONSOLE=y
CONFIG_VGACON_SOFT_SCROLLBACK=y
CONFIG_VGACON_SOFT_SCROLLBACK_SIZE=64
CONFIG_MDA_CONSOLE=y
CONFIG_DUMMY_CONSOLE=y
CONFIG_FRAMEBUFFER_CONSOLE=y
CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y
# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
CONFIG_FONTS=y
CONFIG_FONT_8x8=y
CONFIG_FONT_8x16=y
CONFIG_FONT_6x11=y
# CONFIG_FONT_7x14 is not set
CONFIG_FONT_PEARL_8x8=y
CONFIG_FONT_ACORN_8x8=y
CONFIG_FONT_MINI_4x6=y
CONFIG_FONT_SUN8x16=y
# CONFIG_FONT_SUN12x22 is not set
CONFIG_FONT_10x18=y
CONFIG_LOGO=y
CONFIG_LOGO_LINUX_MONO=y
CONFIG_LOGO_LINUX_VGA16=y
# CONFIG_LOGO_LINUX_CLUT224 is not set
# CONFIG_SOUND is not set
# CONFIG_HID_SUPPORT is not set
# CONFIG_USB_SUPPORT is not set
# CONFIG_MMC is not set
CONFIG_MEMSTICK=y
CONFIG_MEMSTICK_DEBUG=y
#
# MemoryStick drivers
#
# CONFIG_MEMSTICK_UNSAFE_RESUME is not set
CONFIG_MSPRO_BLOCK=y
#
# MemoryStick Host Controller Drivers
#
CONFIG_NEW_LEDS=y
CONFIG_LEDS_CLASS=y
#
# LED drivers
#
CONFIG_LEDS_NET48XX=y
CONFIG_LEDS_WRAP=y
CONFIG_LEDS_ALIX2=y
# CONFIG_LEDS_PCA9532 is not set
CONFIG_LEDS_GPIO=y
# CONFIG_LEDS_GPIO_PLATFORM is not set
CONFIG_LEDS_LP5521=y
CONFIG_LEDS_CLEVO_MAIL=y
CONFIG_LEDS_PCA955X=y
# CONFIG_LEDS_DA903X is not set
# CONFIG_LEDS_BD2802 is not set
#
# LED Triggers
#
CONFIG_LEDS_TRIGGERS=y
CONFIG_LEDS_TRIGGER_TIMER=y
CONFIG_LEDS_TRIGGER_IDE_DISK=y
# CONFIG_LEDS_TRIGGER_HEARTBEAT is not set
# CONFIG_LEDS_TRIGGER_BACKLIGHT is not set
CONFIG_LEDS_TRIGGER_GPIO=y
CONFIG_LEDS_TRIGGER_DEFAULT_ON=y
#
# iptables trigger is under Netfilter config (LED target)
#
CONFIG_ACCESSIBILITY=y
CONFIG_EDAC=y
#
# Reporting subsystems
#
CONFIG_EDAC_DEBUG=y
CONFIG_EDAC_DEBUG_VERBOSE=y
CONFIG_EDAC_MM_EDAC=y
CONFIG_RTC_LIB=y
CONFIG_RTC_CLASS=y
# CONFIG_RTC_HCTOSYS is not set
CONFIG_RTC_DEBUG=y
#
# RTC interfaces
#
CONFIG_RTC_INTF_SYSFS=y
CONFIG_RTC_INTF_PROC=y
CONFIG_RTC_INTF_DEV=y
CONFIG_RTC_INTF_DEV_UIE_EMUL=y
CONFIG_RTC_DRV_TEST=y
#
# I2C RTC drivers
#
CONFIG_RTC_DRV_DS1307=y
CONFIG_RTC_DRV_DS1374=y
CONFIG_RTC_DRV_DS1672=y
CONFIG_RTC_DRV_MAX6900=y
# CONFIG_RTC_DRV_RS5C372 is not set
CONFIG_RTC_DRV_ISL1208=y
CONFIG_RTC_DRV_X1205=y
# CONFIG_RTC_DRV_PCF8563 is not set
CONFIG_RTC_DRV_PCF8583=y
CONFIG_RTC_DRV_M41T80=y
# CONFIG_RTC_DRV_M41T80_WDT is not set
CONFIG_RTC_DRV_S35390A=y
CONFIG_RTC_DRV_FM3130=y
CONFIG_RTC_DRV_RX8581=y
#
# SPI RTC drivers
#
#
# Platform RTC drivers
#
CONFIG_RTC_DRV_CMOS=y
CONFIG_RTC_DRV_DS1286=y
CONFIG_RTC_DRV_DS1511=y
# CONFIG_RTC_DRV_DS1553 is not set
# CONFIG_RTC_DRV_DS1742 is not set
CONFIG_RTC_DRV_STK17TA8=y
CONFIG_RTC_DRV_M48T86=y
CONFIG_RTC_DRV_M48T35=y
CONFIG_RTC_DRV_M48T59=y
# CONFIG_RTC_DRV_MSM6242 is not set
CONFIG_RTC_DRV_BQ4802=y
CONFIG_RTC_DRV_RP5C01=y
# CONFIG_RTC_DRV_V3020 is not set
CONFIG_RTC_DRV_PCF50633=y
#
# on-CPU RTC drivers
#
# CONFIG_DMADEVICES is not set
CONFIG_AUXDISPLAY=y
CONFIG_KS0108=y
CONFIG_KS0108_PORT=0x378
CONFIG_KS0108_DELAY=2
# CONFIG_CFAG12864B is not set
# CONFIG_UIO is not set
# CONFIG_XEN_BALLOON is not set
CONFIG_XEN_DEV_EVTCHN=y
CONFIG_XENFS=y
CONFIG_XEN_COMPAT_XENFS=y
CONFIG_XEN_SYS_HYPERVISOR=y
CONFIG_STAGING=y
# CONFIG_STAGING_EXCLUDE_BUILD is not set
CONFIG_ECHO=y
CONFIG_PANEL=y
CONFIG_PANEL_PARPORT=0
CONFIG_PANEL_PROFILE=5
CONFIG_PANEL_CHANGE_MESSAGE=y
CONFIG_PANEL_BOOT_MESSAGE=""
#
# Android
#
# CONFIG_ANDROID is not set
CONFIG_ANDROID_BINDER_IPC=y
CONFIG_ANDROID_LOGGER=y
CONFIG_ANDROID_RAM_CONSOLE=y
CONFIG_ANDROID_RAM_CONSOLE_ENABLE_VERBOSE=y
CONFIG_ANDROID_RAM_CONSOLE_EARLY_INIT=y
CONFIG_ANDROID_RAM_CONSOLE_EARLY_ADDR=0
CONFIG_ANDROID_RAM_CONSOLE_EARLY_SIZE=0
# CONFIG_ANDROID_TIMED_OUTPUT is not set
CONFIG_ANDROID_LOW_MEMORY_KILLER=y
CONFIG_B3DFG=y
CONFIG_PLAN9AUTH=y
CONFIG_HECI=y
CONFIG_VT6655=y
CONFIG_MRST_NAND=y
CONFIG_MRST_NAND_HW=y
# CONFIG_MRST_NAND_EMU is not set
# CONFIG_X86_PLATFORM_DEVICES is not set
#
# Firmware Drivers
#
CONFIG_EDD=y
CONFIG_EDD_OFF=y
CONFIG_FIRMWARE_MEMMAP=y
CONFIG_DELL_RBU=y
CONFIG_DCDBAS=y
# CONFIG_DMIID is not set
CONFIG_ISCSI_IBFT_FIND=y
CONFIG_ISCSI_IBFT=y
#
# File systems
#
CONFIG_EXT2_FS=y
CONFIG_EXT2_FS_XATTR=y
# CONFIG_EXT2_FS_POSIX_ACL is not set
CONFIG_EXT2_FS_SECURITY=y
# CONFIG_EXT2_FS_XIP is not set
CONFIG_EXT3_FS=y
CONFIG_EXT3_DEFAULTS_TO_ORDERED=y
CONFIG_EXT3_FS_XATTR=y
CONFIG_EXT3_FS_POSIX_ACL=y
# CONFIG_EXT3_FS_SECURITY is not set
CONFIG_EXT4_FS=y
CONFIG_EXT4DEV_COMPAT=y
CONFIG_EXT4_FS_XATTR=y
CONFIG_EXT4_FS_POSIX_ACL=y
# CONFIG_EXT4_FS_SECURITY is not set
CONFIG_JBD=y
CONFIG_JBD_DEBUG=y
CONFIG_JBD2=y
CONFIG_JBD2_DEBUG=y
CONFIG_FS_MBCACHE=y
CONFIG_REISERFS_FS=y
CONFIG_REISERFS_CHECK=y
CONFIG_REISERFS_PROC_INFO=y
# CONFIG_REISERFS_FS_XATTR is not set
# CONFIG_JFS_FS is not set
CONFIG_FS_POSIX_ACL=y
# CONFIG_FILE_LOCKING is not set
CONFIG_XFS_FS=y
CONFIG_XFS_QUOTA=y
# CONFIG_XFS_POSIX_ACL is not set
CONFIG_XFS_RT=y
# CONFIG_XFS_DEBUG is not set
# CONFIG_GFS2_FS is not set
# CONFIG_BTRFS_FS is not set
# CONFIG_FSNOTIFY is not set
# CONFIG_INOTIFY is not set
CONFIG_QUOTA=y
# CONFIG_PRINT_QUOTA_WARNING is not set
CONFIG_QUOTA_TREE=y
CONFIG_QFMT_V1=y
CONFIG_QFMT_V2=y
CONFIG_QUOTACTL=y
CONFIG_AUTOFS_FS=y
# CONFIG_AUTOFS4_FS is not set
CONFIG_FUSE_FS=y
# CONFIG_CUSE is not set
#
# Caches
#
CONFIG_FSCACHE=y
CONFIG_FSCACHE_STATS=y
CONFIG_FSCACHE_HISTOGRAM=y
# CONFIG_FSCACHE_DEBUG is not set
CONFIG_CACHEFILES=y
CONFIG_CACHEFILES_DEBUG=y
CONFIG_CACHEFILES_HISTOGRAM=y
#
# CD-ROM/DVD Filesystems
#
CONFIG_ISO9660_FS=y
CONFIG_JOLIET=y
# CONFIG_ZISOFS is not set
# CONFIG_UDF_FS is not set
#
# DOS/FAT/NT Filesystems
#
CONFIG_FAT_FS=y
CONFIG_MSDOS_FS=y
CONFIG_VFAT_FS=y
CONFIG_FAT_DEFAULT_CODEPAGE=437
CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
CONFIG_NTFS_FS=y
CONFIG_NTFS_DEBUG=y
CONFIG_NTFS_RW=y
#
# Pseudo filesystems
#
CONFIG_PROC_FS=y
CONFIG_PROC_KCORE=y
CONFIG_PROC_SYSCTL=y
CONFIG_PROC_PAGE_MONITOR=y
CONFIG_SYSFS=y
# CONFIG_TMPFS is not set
CONFIG_HUGETLBFS=y
CONFIG_HUGETLB_PAGE=y
CONFIG_CONFIGFS_FS=y
CONFIG_MISC_FILESYSTEMS=y
CONFIG_ADFS_FS=y
# CONFIG_ADFS_FS_RW is not set
CONFIG_AFFS_FS=y
# CONFIG_HFS_FS is not set
CONFIG_HFSPLUS_FS=y
CONFIG_BEFS_FS=y
CONFIG_BEFS_DEBUG=y
# CONFIG_BFS_FS is not set
CONFIG_EFS_FS=y
# CONFIG_JFFS2_FS is not set
# CONFIG_UBIFS_FS is not set
CONFIG_CRAMFS=y
# CONFIG_SQUASHFS is not set
# CONFIG_VXFS_FS is not set
CONFIG_MINIX_FS=y
CONFIG_OMFS_FS=y
CONFIG_HPFS_FS=y
# CONFIG_QNX4FS_FS is not set
# CONFIG_ROMFS_FS is not set
CONFIG_SYSV_FS=y
CONFIG_UFS_FS=y
CONFIG_UFS_FS_WRITE=y
CONFIG_UFS_DEBUG=y
# CONFIG_NILFS2_FS is not set
CONFIG_EXPORTFS=y
#
# Partition Types
#
CONFIG_PARTITION_ADVANCED=y
CONFIG_ACORN_PARTITION=y
CONFIG_ACORN_PARTITION_CUMANA=y
CONFIG_ACORN_PARTITION_EESOX=y
# CONFIG_ACORN_PARTITION_ICS is not set
CONFIG_ACORN_PARTITION_ADFS=y
# CONFIG_ACORN_PARTITION_POWERTEC is not set
CONFIG_ACORN_PARTITION_RISCIX=y
CONFIG_OSF_PARTITION=y
CONFIG_AMIGA_PARTITION=y
# CONFIG_ATARI_PARTITION is not set
CONFIG_MAC_PARTITION=y
CONFIG_MSDOS_PARTITION=y
CONFIG_BSD_DISKLABEL=y
# CONFIG_MINIX_SUBPARTITION is not set
# CONFIG_SOLARIS_X86_PARTITION is not set
CONFIG_UNIXWARE_DISKLABEL=y
# CONFIG_LDM_PARTITION is not set
CONFIG_SGI_PARTITION=y
# CONFIG_ULTRIX_PARTITION is not set
# CONFIG_SUN_PARTITION is not set
# CONFIG_KARMA_PARTITION is not set
# CONFIG_EFI_PARTITION is not set
# CONFIG_SYSV68_PARTITION is not set
CONFIG_NLS=y
CONFIG_NLS_DEFAULT="iso8859-1"
CONFIG_NLS_CODEPAGE_437=y
# CONFIG_NLS_CODEPAGE_737 is not set
CONFIG_NLS_CODEPAGE_775=y
CONFIG_NLS_CODEPAGE_850=y
# CONFIG_NLS_CODEPAGE_852 is not set
# CONFIG_NLS_CODEPAGE_855 is not set
CONFIG_NLS_CODEPAGE_857=y
# CONFIG_NLS_CODEPAGE_860 is not set
CONFIG_NLS_CODEPAGE_861=y
CONFIG_NLS_CODEPAGE_862=y
CONFIG_NLS_CODEPAGE_863=y
CONFIG_NLS_CODEPAGE_864=y
# CONFIG_NLS_CODEPAGE_865 is not set
CONFIG_NLS_CODEPAGE_866=y
CONFIG_NLS_CODEPAGE_869=y
CONFIG_NLS_CODEPAGE_936=y
# CONFIG_NLS_CODEPAGE_950 is not set
CONFIG_NLS_CODEPAGE_932=y
# CONFIG_NLS_CODEPAGE_949 is not set
CONFIG_NLS_CODEPAGE_874=y
# CONFIG_NLS_ISO8859_8 is not set
CONFIG_NLS_CODEPAGE_1250=y
# CONFIG_NLS_CODEPAGE_1251 is not set
CONFIG_NLS_ASCII=y
CONFIG_NLS_ISO8859_1=y
# CONFIG_NLS_ISO8859_2 is not set
CONFIG_NLS_ISO8859_3=y
CONFIG_NLS_ISO8859_4=y
CONFIG_NLS_ISO8859_5=y
CONFIG_NLS_ISO8859_6=y
CONFIG_NLS_ISO8859_7=y
CONFIG_NLS_ISO8859_9=y
# CONFIG_NLS_ISO8859_13 is not set
CONFIG_NLS_ISO8859_14=y
CONFIG_NLS_ISO8859_15=y
CONFIG_NLS_KOI8_R=y
CONFIG_NLS_KOI8_U=y
CONFIG_NLS_UTF8=y
#
# Kernel hacking
#
CONFIG_TRACE_IRQFLAGS_SUPPORT=y
# CONFIG_ENABLE_WARN_DEPRECATED is not set
CONFIG_ENABLE_MUST_CHECK=y
CONFIG_FRAME_WARN=1024
CONFIG_MAGIC_SYSRQ=y
CONFIG_UNUSED_SYMBOLS=y
CONFIG_DEBUG_FS=y
# CONFIG_HEADERS_CHECK is not set
CONFIG_DEBUG_KERNEL=y
# CONFIG_DEBUG_SHIRQ is not set
CONFIG_DETECT_SOFTLOCKUP=y
# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
# CONFIG_DETECT_HUNG_TASK is not set
CONFIG_SCHED_DEBUG=y
CONFIG_SCHEDSTATS=y
# CONFIG_TIMER_STATS is not set
CONFIG_DEBUG_OBJECTS=y
CONFIG_DEBUG_OBJECTS_SELFTEST=y
CONFIG_DEBUG_OBJECTS_FREE=y
# CONFIG_DEBUG_OBJECTS_TIMERS is not set
CONFIG_DEBUG_OBJECTS_ENABLE_DEFAULT=1
CONFIG_SLQB_DEBUG=y
# CONFIG_SLQB_DEBUG_ON is not set
# CONFIG_SLQB_SYSFS is not set
CONFIG_DEBUG_KMEMLEAK=y
CONFIG_DEBUG_KMEMLEAK_TEST=y
CONFIG_DEBUG_RT_MUTEXES=y
CONFIG_DEBUG_PI_LIST=y
# CONFIG_RT_MUTEX_TESTER is not set
CONFIG_DEBUG_SPINLOCK=y
CONFIG_DEBUG_MUTEXES=y
CONFIG_DEBUG_LOCK_ALLOC=y
CONFIG_PROVE_LOCKING=y
CONFIG_LOCKDEP=y
# CONFIG_LOCK_STAT is not set
CONFIG_DEBUG_LOCKDEP=y
CONFIG_TRACE_IRQFLAGS=y
# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
CONFIG_DEBUG_LOCKING_API_SELFTESTS=y
CONFIG_STACKTRACE=y
CONFIG_DEBUG_KOBJECT=y
# CONFIG_DEBUG_INFO is not set
# CONFIG_DEBUG_VM is not set
CONFIG_DEBUG_VIRTUAL=y
CONFIG_DEBUG_WRITECOUNT=y
CONFIG_DEBUG_MEMORY_INIT=y
CONFIG_DEBUG_LIST=y
CONFIG_DEBUG_SG=y
CONFIG_DEBUG_NOTIFIERS=y
CONFIG_ARCH_WANT_FRAME_POINTERS=y
CONFIG_FRAME_POINTER=y
CONFIG_RCU_TORTURE_TEST=y
CONFIG_RCU_TORTURE_TEST_RUNNABLE=y
# CONFIG_RCU_CPU_STALL_DETECTOR is not set
# CONFIG_BACKTRACE_SELF_TEST is not set
# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
# CONFIG_FAULT_INJECTION is not set
CONFIG_LATENCYTOP=y
# CONFIG_SYSCTL_SYSCALL_CHECK is not set
CONFIG_DEBUG_PAGEALLOC=y
CONFIG_USER_STACKTRACE_SUPPORT=y
CONFIG_NOP_TRACER=y
CONFIG_HAVE_FUNCTION_TRACER=y
CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y
CONFIG_HAVE_DYNAMIC_FTRACE=y
CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
CONFIG_HAVE_HW_BRANCH_TRACER=y
CONFIG_HAVE_FTRACE_SYSCALLS=y
CONFIG_RING_BUFFER=y
CONFIG_EVENT_TRACING=y
CONFIG_CONTEXT_SWITCH_TRACER=y
CONFIG_TRACING=y
CONFIG_TRACING_SUPPORT=y
# CONFIG_FTRACE is not set
# CONFIG_DMA_API_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
CONFIG_KGDB=y
CONFIG_KGDB_SERIAL_CONSOLE=y
# CONFIG_KGDB_TESTS is not set
CONFIG_HAVE_ARCH_KMEMCHECK=y
CONFIG_STRICT_DEVMEM=y
# CONFIG_X86_VERBOSE_BOOTUP is not set
CONFIG_EARLY_PRINTK=y
CONFIG_DEBUG_STACKOVERFLOW=y
# CONFIG_DEBUG_STACK_USAGE is not set
CONFIG_DEBUG_PER_CPU_MAPS=y
CONFIG_X86_PTDUMP=y
# CONFIG_DEBUG_RODATA is not set
# CONFIG_4KSTACKS is not set
# CONFIG_DOUBLEFAULT is not set
CONFIG_IOMMU_STRESS=y
CONFIG_X86_DS_SELFTEST=y
CONFIG_HAVE_MMIOTRACE_SUPPORT=y
CONFIG_IO_DELAY_TYPE_0X80=0
CONFIG_IO_DELAY_TYPE_0XED=1
CONFIG_IO_DELAY_TYPE_UDELAY=2
CONFIG_IO_DELAY_TYPE_NONE=3
# CONFIG_IO_DELAY_0X80 is not set
# CONFIG_IO_DELAY_0XED is not set
CONFIG_IO_DELAY_UDELAY=y
# CONFIG_IO_DELAY_NONE is not set
CONFIG_DEFAULT_IO_DELAY_TYPE=2
# CONFIG_DEBUG_BOOT_PARAMS is not set
CONFIG_CPA_DEBUG=y
# CONFIG_OPTIMIZE_INLINING is not set
#
# Security options
#
CONFIG_KEYS=y
CONFIG_KEYS_DEBUG_PROC_KEYS=y
CONFIG_SECURITY=y
CONFIG_SECURITYFS=y
# CONFIG_SECURITY_NETWORK is not set
CONFIG_SECURITY_PATH=y
CONFIG_SECURITY_FILE_CAPABILITIES=y
CONFIG_SECURITY_DEFAULT_MMAP_MIN_ADDR=0
# CONFIG_SECURITY_TOMOYO is not set
CONFIG_CRYPTO=y
#
# Crypto core or helper
#
CONFIG_CRYPTO_FIPS=y
CONFIG_CRYPTO_ALGAPI=y
CONFIG_CRYPTO_ALGAPI2=y
CONFIG_CRYPTO_AEAD=y
CONFIG_CRYPTO_AEAD2=y
CONFIG_CRYPTO_BLKCIPHER=y
CONFIG_CRYPTO_BLKCIPHER2=y
CONFIG_CRYPTO_HASH=y
CONFIG_CRYPTO_HASH2=y
CONFIG_CRYPTO_RNG=y
CONFIG_CRYPTO_RNG2=y
CONFIG_CRYPTO_PCOMP=y
CONFIG_CRYPTO_MANAGER=y
CONFIG_CRYPTO_MANAGER2=y
CONFIG_CRYPTO_GF128MUL=y
CONFIG_CRYPTO_NULL=y
CONFIG_CRYPTO_WORKQUEUE=y
CONFIG_CRYPTO_CRYPTD=y
CONFIG_CRYPTO_AUTHENC=y
#
# Authenticated Encryption with Associated Data
#
CONFIG_CRYPTO_CCM=y
# CONFIG_CRYPTO_GCM is not set
CONFIG_CRYPTO_SEQIV=y
#
# Block modes
#
CONFIG_CRYPTO_CBC=y
CONFIG_CRYPTO_CTR=y
CONFIG_CRYPTO_CTS=y
CONFIG_CRYPTO_ECB=y
CONFIG_CRYPTO_LRW=y
CONFIG_CRYPTO_PCBC=y
CONFIG_CRYPTO_XTS=y
#
# Hash modes
#
CONFIG_CRYPTO_HMAC=y
CONFIG_CRYPTO_XCBC=y
#
# Digest
#
CONFIG_CRYPTO_CRC32C=y
# CONFIG_CRYPTO_CRC32C_INTEL is not set
CONFIG_CRYPTO_MD4=y
# CONFIG_CRYPTO_MD5 is not set
# CONFIG_CRYPTO_MICHAEL_MIC is not set
CONFIG_CRYPTO_RMD128=y
# CONFIG_CRYPTO_RMD160 is not set
CONFIG_CRYPTO_RMD256=y
CONFIG_CRYPTO_RMD320=y
CONFIG_CRYPTO_SHA1=y
# CONFIG_CRYPTO_SHA256 is not set
# CONFIG_CRYPTO_SHA512 is not set
# CONFIG_CRYPTO_TGR192 is not set
# CONFIG_CRYPTO_WP512 is not set
#
# Ciphers
#
CONFIG_CRYPTO_AES=y
CONFIG_CRYPTO_AES_586=y
CONFIG_CRYPTO_ANUBIS=y
CONFIG_CRYPTO_ARC4=y
CONFIG_CRYPTO_BLOWFISH=y
CONFIG_CRYPTO_CAMELLIA=y
CONFIG_CRYPTO_CAST5=y
# CONFIG_CRYPTO_CAST6 is not set
CONFIG_CRYPTO_DES=y
# CONFIG_CRYPTO_FCRYPT is not set
CONFIG_CRYPTO_KHAZAD=y
# CONFIG_CRYPTO_SALSA20 is not set
CONFIG_CRYPTO_SALSA20_586=y
CONFIG_CRYPTO_SEED=y
CONFIG_CRYPTO_SERPENT=y
# CONFIG_CRYPTO_TEA is not set
# CONFIG_CRYPTO_TWOFISH is not set
CONFIG_CRYPTO_TWOFISH_COMMON=y
CONFIG_CRYPTO_TWOFISH_586=y
#
# Compression
#
CONFIG_CRYPTO_DEFLATE=y
# CONFIG_CRYPTO_ZLIB is not set
CONFIG_CRYPTO_LZO=y
#
# Random Number Generation
#
CONFIG_CRYPTO_ANSI_CPRNG=y
CONFIG_CRYPTO_HW=y
CONFIG_CRYPTO_DEV_PADLOCK=y
CONFIG_CRYPTO_DEV_PADLOCK_AES=y
# CONFIG_CRYPTO_DEV_PADLOCK_SHA is not set
CONFIG_HAVE_KVM=y
CONFIG_VIRTUALIZATION=y
CONFIG_VIRTIO=y
CONFIG_VIRTIO_RING=y
CONFIG_VIRTIO_BALLOON=y
CONFIG_BINARY_PRINTF=y
#
# Library routines
#
CONFIG_BITREVERSE=y
CONFIG_GENERIC_FIND_FIRST_BIT=y
CONFIG_GENERIC_FIND_NEXT_BIT=y
CONFIG_GENERIC_FIND_LAST_BIT=y
CONFIG_CRC_CCITT=y
CONFIG_CRC16=y
CONFIG_CRC_T10DIF=y
CONFIG_CRC_ITU_T=y
CONFIG_CRC32=y
CONFIG_CRC7=y
CONFIG_LIBCRC32C=y
CONFIG_ZLIB_INFLATE=y
CONFIG_ZLIB_DEFLATE=y
CONFIG_LZO_COMPRESS=y
CONFIG_LZO_DECOMPRESS=y
CONFIG_REED_SOLOMON=y
CONFIG_REED_SOLOMON_DEC16=y
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT=y
CONFIG_HAS_DMA=y
CONFIG_CHECK_SIGNATURE=y
# CONFIG_CPUMASK_OFFSTACK is not set
#
# Automatically generated make config: don't edit
# Linux kernel version: 2.6.30-rc7
# Wed Jun 3 04:39:35 2009
#
CONFIG_64BIT=y
# CONFIG_X86_32 is not set
CONFIG_X86_64=y
CONFIG_X86=y
CONFIG_OUTPUT_FORMAT="elf64-x86-64"
CONFIG_ARCH_DEFCONFIG="arch/x86/configs/x86_64_defconfig"
CONFIG_GENERIC_TIME=y
CONFIG_GENERIC_CMOS_UPDATE=y
CONFIG_CLOCKSOURCE_WATCHDOG=y
CONFIG_GENERIC_CLOCKEVENTS=y
CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y
CONFIG_LOCKDEP_SUPPORT=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_HAVE_LATENCYTOP_SUPPORT=y
CONFIG_FAST_CMPXCHG_LOCAL=y
CONFIG_MMU=y
CONFIG_ZONE_DMA=y
CONFIG_GENERIC_ISA_DMA=y
CONFIG_GENERIC_IOMAP=y
CONFIG_GENERIC_BUG=y
CONFIG_GENERIC_BUG_RELATIVE_POINTERS=y
CONFIG_GENERIC_HWEIGHT=y
CONFIG_ARCH_MAY_HAVE_PC_FDC=y
CONFIG_RWSEM_GENERIC_SPINLOCK=y
# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
CONFIG_GENERIC_TIME_VSYSCALL=y
CONFIG_ARCH_HAS_CPU_RELAX=y
CONFIG_ARCH_HAS_DEFAULT_IDLE=y
CONFIG_ARCH_HAS_CACHE_LINE_SIZE=y
CONFIG_HAVE_SETUP_PER_CPU_AREA=y
CONFIG_HAVE_DYNAMIC_PER_CPU_AREA=y
CONFIG_HAVE_CPUMASK_OF_CPU_MAP=y
CONFIG_ARCH_HIBERNATION_POSSIBLE=y
CONFIG_ARCH_SUSPEND_POSSIBLE=y
CONFIG_ZONE_DMA32=y
CONFIG_ARCH_POPULATES_NODE_MAP=y
CONFIG_AUDIT_ARCH=y
CONFIG_ARCH_SUPPORTS_OPTIMIZED_INLINING=y
CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y
CONFIG_GENERIC_HARDIRQS=y
CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
CONFIG_GENERIC_IRQ_PROBE=y
CONFIG_GENERIC_PENDING_IRQ=y
CONFIG_USE_GENERIC_SMP_HELPERS=y
CONFIG_X86_64_SMP=y
CONFIG_X86_HT=y
CONFIG_X86_TRAMPOLINE=y
# CONFIG_KTIME_SCALAR is not set
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
#
# General setup
#
CONFIG_EXPERIMENTAL=y
CONFIG_LOCK_KERNEL=y
CONFIG_INIT_ENV_ARG_LIMIT=32
CONFIG_LOCALVERSION=""
CONFIG_LOCALVERSION_AUTO=y
CONFIG_HAVE_KERNEL_GZIP=y
CONFIG_HAVE_KERNEL_BZIP2=y
CONFIG_HAVE_KERNEL_LZMA=y
CONFIG_KERNEL_GZIP=y
# CONFIG_KERNEL_BZIP2 is not set
# CONFIG_KERNEL_LZMA is not set
CONFIG_SWAP=y
# CONFIG_SYSVIPC is not set
CONFIG_POSIX_MQUEUE=y
CONFIG_POSIX_MQUEUE_SYSCTL=y
CONFIG_BSD_PROCESS_ACCT=y
# CONFIG_BSD_PROCESS_ACCT_V3 is not set
CONFIG_TASKSTATS=y
CONFIG_TASK_DELAY_ACCT=y
CONFIG_TASK_XACCT=y
CONFIG_TASK_IO_ACCOUNTING=y
CONFIG_AUDIT=y
CONFIG_AUDITSYSCALL=y
CONFIG_AUDIT_TREE=y
#
# RCU Subsystem
#
# CONFIG_CLASSIC_RCU is not set
CONFIG_TREE_RCU=y
# CONFIG_PREEMPT_RCU is not set
CONFIG_RCU_TRACE=y
CONFIG_RCU_FANOUT=64
# CONFIG_RCU_FANOUT_EXACT is not set
CONFIG_TREE_RCU_TRACE=y
# CONFIG_PREEMPT_RCU_TRACE is not set
CONFIG_IKCONFIG=m
CONFIG_IKCONFIG_PROC=y
CONFIG_LOG_BUF_SHIFT=17
CONFIG_HAVE_UNSTABLE_SCHED_CLOCK=y
CONFIG_GROUP_SCHED=y
CONFIG_FAIR_GROUP_SCHED=y
CONFIG_RT_GROUP_SCHED=y
# CONFIG_USER_SCHED is not set
CONFIG_CGROUP_SCHED=y
CONFIG_CGROUPS=y
# CONFIG_CGROUP_DEBUG is not set
# CONFIG_CGROUP_NS is not set
# CONFIG_CGROUP_FREEZER is not set
CONFIG_CGROUP_DEVICE=y
CONFIG_CPUSETS=y
# CONFIG_PROC_PID_CPUSET is not set
CONFIG_CGROUP_CPUACCT=y
CONFIG_RESOURCE_COUNTERS=y
# CONFIG_CGROUP_MEM_RES_CTLR is not set
# CONFIG_SYSFS_DEPRECATED_V2 is not set
CONFIG_RELAY=y
CONFIG_NAMESPACES=y
CONFIG_UTS_NS=y
CONFIG_IPC_NS=y
CONFIG_USER_NS=y
# CONFIG_PID_NS is not set
CONFIG_NET_NS=y
# CONFIG_BLK_DEV_INITRD is not set
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
CONFIG_SYSCTL=y
CONFIG_ANON_INODES=y
# CONFIG_EMBEDDED is not set
CONFIG_SYSCTL_SYSCALL=y
CONFIG_KALLSYMS=y
CONFIG_KALLSYMS_ALL=y
CONFIG_KALLSYMS_EXTRA_PASS=y
# CONFIG_STRIP_ASM_SYMS is not set
CONFIG_HOTPLUG=y
CONFIG_PRINTK=y
CONFIG_BUG=y
CONFIG_ELF_CORE=y
CONFIG_PCSPKR_PLATFORM=y
CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
CONFIG_EPOLL=y
CONFIG_SIGNALFD=y
CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_AIO=y
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_PCI_QUIRKS=y
CONFIG_COMPAT_BRK=y
# CONFIG_SLAB_ALLOCATOR is not set
# CONFIG_SLUB_ALLOCATOR is not set
CONFIG_SLQB_ALLOCATOR=y
CONFIG_SLQB=y
# CONFIG_SLOB is not set
CONFIG_PROFILING=y
CONFIG_TRACEPOINTS=y
CONFIG_MARKERS=y
# CONFIG_OPROFILE is not set
CONFIG_HAVE_OPROFILE=y
CONFIG_KPROBES=y
CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
CONFIG_KRETPROBES=y
CONFIG_HAVE_IOREMAP_PROT=y
CONFIG_HAVE_KPROBES=y
CONFIG_HAVE_KRETPROBES=y
CONFIG_HAVE_ARCH_TRACEHOOK=y
CONFIG_HAVE_DMA_API_DEBUG=y
CONFIG_SLOW_WORK=y
# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
CONFIG_SLABINFO=y
CONFIG_RT_MUTEXES=y
CONFIG_BASE_SMALL=0
CONFIG_MODULES=y
# CONFIG_MODULE_FORCE_LOAD is not set
CONFIG_MODULE_UNLOAD=y
# CONFIG_MODULE_FORCE_UNLOAD is not set
CONFIG_MODVERSIONS=y
# CONFIG_MODULE_SRCVERSION_ALL is not set
CONFIG_STOP_MACHINE=y
CONFIG_BLOCK=y
# CONFIG_BLK_DEV_BSG is not set
CONFIG_BLK_DEV_INTEGRITY=y
#
# IO Schedulers
#
CONFIG_IOSCHED_NOOP=y
CONFIG_IOSCHED_AS=m
# CONFIG_IOSCHED_DEADLINE is not set
# CONFIG_IOSCHED_CFQ is not set
# CONFIG_DEFAULT_AS is not set
# CONFIG_DEFAULT_DEADLINE is not set
# CONFIG_DEFAULT_CFQ is not set
CONFIG_DEFAULT_NOOP=y
CONFIG_DEFAULT_IOSCHED="noop"
CONFIG_PREEMPT_NOTIFIERS=y
CONFIG_FREEZER=y
#
# Processor type and features
#
CONFIG_TICK_ONESHOT=y
CONFIG_NO_HZ=y
CONFIG_HIGH_RES_TIMERS=y
CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
CONFIG_SMP=y
CONFIG_X86_X2APIC=y
CONFIG_SPARSE_IRQ=y
CONFIG_NUMA_IRQ_DESC=y
CONFIG_X86_MPPARSE=y
CONFIG_X86_EXTENDED_PLATFORM=y
CONFIG_X86_VSMP=y
CONFIG_X86_UV=y
# CONFIG_SCHED_OMIT_FRAME_POINTER is not set
# CONFIG_PARAVIRT_GUEST is not set
CONFIG_PARAVIRT=y
CONFIG_PARAVIRT_DEBUG=y
# CONFIG_MEMTEST is not set
# CONFIG_M386 is not set
# CONFIG_M486 is not set
# CONFIG_M586 is not set
# CONFIG_M586TSC is not set
# CONFIG_M586MMX is not set
# CONFIG_M686 is not set
# CONFIG_MPENTIUMII is not set
# CONFIG_MPENTIUMIII is not set
# CONFIG_MPENTIUMM is not set
# CONFIG_MPENTIUM4 is not set
# CONFIG_MK6 is not set
# CONFIG_MK7 is not set
# CONFIG_MK8 is not set
# CONFIG_MCRUSOE is not set
# CONFIG_MEFFICEON is not set
# CONFIG_MWINCHIPC6 is not set
# CONFIG_MWINCHIP3D is not set
# CONFIG_MGEODEGX1 is not set
# CONFIG_MGEODE_LX is not set
# CONFIG_MCYRIXIII is not set
# CONFIG_MVIAC3_2 is not set
# CONFIG_MVIAC7 is not set
# CONFIG_MPSC is not set
# CONFIG_MCORE2 is not set
CONFIG_GENERIC_CPU=y
CONFIG_X86_CPU=y
CONFIG_X86_L1_CACHE_BYTES=64
CONFIG_X86_INTERNODE_CACHE_BYTES=4096
CONFIG_X86_CMPXCHG=y
CONFIG_X86_L1_CACHE_SHIFT=6
CONFIG_X86_WP_WORKS_OK=y
CONFIG_X86_TSC=y
CONFIG_X86_CMPXCHG64=y
CONFIG_X86_CMOV=y
CONFIG_X86_MINIMUM_CPU_FAMILY=64
CONFIG_X86_DEBUGCTLMSR=y
CONFIG_CPU_SUP_INTEL=y
CONFIG_CPU_SUP_AMD=y
CONFIG_CPU_SUP_CENTAUR=y
CONFIG_X86_DS=y
CONFIG_X86_PTRACE_BTS=y
CONFIG_HPET_TIMER=y
CONFIG_DMI=y
CONFIG_GART_IOMMU=y
CONFIG_CALGARY_IOMMU=y
# CONFIG_CALGARY_IOMMU_ENABLED_BY_DEFAULT is not set
# CONFIG_AMD_IOMMU is not set
CONFIG_SWIOTLB=y
CONFIG_IOMMU_HELPER=y
CONFIG_IOMMU_API=y
CONFIG_MAXSMP=y
CONFIG_NR_CPUS=4096
# CONFIG_SCHED_SMT is not set
CONFIG_SCHED_MC=y
# CONFIG_PREEMPT_NONE is not set
CONFIG_PREEMPT_VOLUNTARY=y
# CONFIG_PREEMPT is not set
CONFIG_X86_LOCAL_APIC=y
CONFIG_X86_IO_APIC=y
CONFIG_X86_REROUTE_FOR_BROKEN_BOOT_IRQS=y
CONFIG_X86_MCE=y
CONFIG_X86_NEW_MCE=y
CONFIG_X86_MCE_INTEL=y
CONFIG_X86_MCE_AMD=y
CONFIG_X86_MCE_THRESHOLD=y
CONFIG_X86_MCE_INJECT=m
CONFIG_X86_THERMAL_VECTOR=y
# CONFIG_I8K is not set
CONFIG_MICROCODE=m
# CONFIG_MICROCODE_INTEL is not set
CONFIG_MICROCODE_AMD=y
CONFIG_MICROCODE_OLD_INTERFACE=y
CONFIG_X86_MSR=m
CONFIG_X86_CPUID=m
CONFIG_X86_CPU_DEBUG=y
CONFIG_ARCH_PHYS_ADDR_T_64BIT=y
CONFIG_DIRECT_GBPAGES=y
CONFIG_NUMA=y
# CONFIG_K8_NUMA is not set
CONFIG_X86_64_ACPI_NUMA=y
CONFIG_NODES_SPAN_OTHER_NODES=y
CONFIG_NUMA_EMU=y
CONFIG_NODES_SHIFT=9
CONFIG_ARCH_SPARSEMEM_DEFAULT=y
CONFIG_ARCH_SPARSEMEM_ENABLE=y
CONFIG_ARCH_SELECT_MEMORY_MODEL=y
CONFIG_ILLEGAL_POINTER_VALUE=0xdead000000000000
CONFIG_SELECT_MEMORY_MODEL=y
# CONFIG_FLATMEM_MANUAL is not set
# CONFIG_DISCONTIGMEM_MANUAL is not set
CONFIG_SPARSEMEM_MANUAL=y
CONFIG_SPARSEMEM=y
CONFIG_NEED_MULTIPLE_NODES=y
CONFIG_HAVE_MEMORY_PRESENT=y
CONFIG_SPARSEMEM_EXTREME=y
CONFIG_SPARSEMEM_VMEMMAP_ENABLE=y
# CONFIG_SPARSEMEM_VMEMMAP is not set
#
# Memory hotplug is currently incompatible with Software Suspend
#
CONFIG_PAGEFLAGS_EXTENDED=y
CONFIG_SPLIT_PTLOCK_CPUS=4
# CONFIG_MIGRATION is not set
CONFIG_PHYS_ADDR_T_64BIT=y
CONFIG_ZONE_DMA_FLAG=1
CONFIG_BOUNCE=y
CONFIG_VIRT_TO_BUS=y
CONFIG_UNEVICTABLE_LRU=y
CONFIG_HAVE_MLOCK=y
CONFIG_HAVE_MLOCKED_PAGE_BIT=y
CONFIG_MMU_NOTIFIER=y
# CONFIG_X86_CHECK_BIOS_CORRUPTION is not set
# CONFIG_X86_RESERVE_LOW_64K is not set
CONFIG_MTRR=y
# CONFIG_MTRR_SANITIZER is not set
CONFIG_X86_PAT=y
CONFIG_EFI=y
# CONFIG_SECCOMP is not set
CONFIG_CC_STACKPROTECTOR_ALL=y
CONFIG_CC_STACKPROTECTOR=y
CONFIG_HZ_100=y
# CONFIG_HZ_250 is not set
# CONFIG_HZ_300 is not set
# CONFIG_HZ_1000 is not set
CONFIG_HZ=100
CONFIG_SCHED_HRTICK=y
# CONFIG_KEXEC is not set
# CONFIG_CRASH_DUMP is not set
CONFIG_PHYSICAL_START=0x1000000
# CONFIG_RELOCATABLE is not set
CONFIG_PHYSICAL_ALIGN=0x1000000
CONFIG_HOTPLUG_CPU=y
CONFIG_CMDLINE_BOOL=y
CONFIG_CMDLINE=""
CONFIG_CMDLINE_OVERRIDE=y
CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
CONFIG_HAVE_ARCH_EARLY_PFN_TO_NID=y
#
# Power management and ACPI options
#
CONFIG_ARCH_HIBERNATION_HEADER=y
CONFIG_PM=y
CONFIG_PM_DEBUG=y
CONFIG_PM_VERBOSE=y
CONFIG_CAN_PM_TRACE=y
# CONFIG_PM_TRACE_RTC is not set
CONFIG_PM_SLEEP_SMP=y
CONFIG_PM_SLEEP=y
CONFIG_SUSPEND=y
# CONFIG_PM_TEST_SUSPEND is not set
CONFIG_SUSPEND_FREEZER=y
CONFIG_HIBERNATION=y
CONFIG_PM_STD_PARTITION=""
CONFIG_ACPI=y
CONFIG_ACPI_SLEEP=y
CONFIG_ACPI_PROCFS=y
CONFIG_ACPI_PROCFS_POWER=y
CONFIG_ACPI_SYSFS_POWER=y
CONFIG_ACPI_PROC_EVENT=y
CONFIG_ACPI_AC=y
# CONFIG_ACPI_BATTERY is not set
# CONFIG_ACPI_BUTTON is not set
CONFIG_ACPI_VIDEO=y
CONFIG_ACPI_FAN=m
CONFIG_ACPI_DOCK=y
CONFIG_ACPI_PROCESSOR=m
CONFIG_ACPI_HOTPLUG_CPU=y
CONFIG_ACPI_THERMAL=m
CONFIG_ACPI_NUMA=y
# CONFIG_ACPI_CUSTOM_DSDT is not set
CONFIG_ACPI_BLACKLIST_YEAR=0
# CONFIG_ACPI_DEBUG is not set
# CONFIG_ACPI_PCI_SLOT is not set
CONFIG_X86_PM_TIMER=y
CONFIG_ACPI_CONTAINER=m
CONFIG_ACPI_SBS=y
#
# CPU Frequency scaling
#
CONFIG_CPU_FREQ=y
CONFIG_CPU_FREQ_TABLE=y
# CONFIG_CPU_FREQ_DEBUG is not set
# CONFIG_CPU_FREQ_STAT is not set
CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y
# CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE is not set
# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set
# CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND is not set
# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set
CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
# CONFIG_CPU_FREQ_GOV_POWERSAVE is not set
# CONFIG_CPU_FREQ_GOV_USERSPACE is not set
CONFIG_CPU_FREQ_GOV_ONDEMAND=y
# CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set
#
# CPUFreq processor drivers
#
# CONFIG_X86_ACPI_CPUFREQ is not set
# CONFIG_X86_POWERNOW_K8 is not set
CONFIG_X86_SPEEDSTEP_CENTRINO=m
CONFIG_X86_P4_CLOCKMOD=m
#
# shared options
#
CONFIG_X86_SPEEDSTEP_LIB=m
CONFIG_CPU_IDLE=y
CONFIG_CPU_IDLE_GOV_LADDER=y
CONFIG_CPU_IDLE_GOV_MENU=y
#
# Memory power savings
#
# CONFIG_I7300_IDLE is not set
#
# Bus options (PCI etc.)
#
CONFIG_PCI=y
CONFIG_PCI_DIRECT=y
CONFIG_PCI_MMCONFIG=y
CONFIG_PCI_DOMAINS=y
CONFIG_DMAR=y
# CONFIG_DMAR_DEFAULT_ON is not set
CONFIG_DMAR_GFX_WA=y
CONFIG_DMAR_FLOPPY_WA=y
CONFIG_INTR_REMAP=y
CONFIG_PCIEPORTBUS=y
CONFIG_PCIEAER=y
# CONFIG_PCIEASPM is not set
CONFIG_ARCH_SUPPORTS_MSI=y
CONFIG_PCI_MSI=y
# CONFIG_PCI_LEGACY is not set
CONFIG_PCI_DEBUG=y
CONFIG_PCI_STUB=m
CONFIG_HT_IRQ=y
# CONFIG_PCI_IOV is not set
CONFIG_ISA_DMA_API=y
CONFIG_K8_NB=y
# CONFIG_PCCARD is not set
# CONFIG_HOTPLUG_PCI is not set
#
# Executable file formats / Emulations
#
CONFIG_BINFMT_ELF=y
# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
# CONFIG_HAVE_AOUT is not set
CONFIG_BINFMT_MISC=m
# CONFIG_IA32_EMULATION is not set
# CONFIG_COMPAT_FOR_U64_ALIGNMENT is not set
CONFIG_NET=y
#
# Networking options
#
CONFIG_PACKET=y
CONFIG_PACKET_MMAP=y
# CONFIG_UNIX is not set
CONFIG_XFRM=y
CONFIG_XFRM_USER=m
CONFIG_XFRM_SUB_POLICY=y
CONFIG_XFRM_MIGRATE=y
# CONFIG_XFRM_STATISTICS is not set
CONFIG_XFRM_IPCOMP=m
CONFIG_NET_KEY=m
# CONFIG_NET_KEY_MIGRATE is not set
CONFIG_INET=y
CONFIG_IP_MULTICAST=y
CONFIG_IP_ADVANCED_ROUTER=y
# CONFIG_ASK_IP_FIB_HASH is not set
CONFIG_IP_FIB_TRIE=y
# CONFIG_IP_FIB_HASH is not set
CONFIG_IP_FIB_TRIE_STATS=y
CONFIG_IP_MULTIPLE_TABLES=y
CONFIG_IP_ROUTE_MULTIPATH=y
# CONFIG_IP_ROUTE_VERBOSE is not set
CONFIG_IP_PNP=y
# CONFIG_IP_PNP_DHCP is not set
CONFIG_IP_PNP_BOOTP=y
# CONFIG_IP_PNP_RARP is not set
# CONFIG_NET_IPIP is not set
CONFIG_NET_IPGRE=m
# CONFIG_NET_IPGRE_BROADCAST is not set
CONFIG_IP_MROUTE=y
CONFIG_IP_PIMSM_V1=y
CONFIG_IP_PIMSM_V2=y
CONFIG_ARPD=y
# CONFIG_SYN_COOKIES is not set
CONFIG_INET_AH=y
CONFIG_INET_ESP=m
CONFIG_INET_IPCOMP=m
CONFIG_INET_XFRM_TUNNEL=m
CONFIG_INET_TUNNEL=m
# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
CONFIG_INET_XFRM_MODE_TUNNEL=m
# CONFIG_INET_XFRM_MODE_BEET is not set
CONFIG_INET_LRO=y
CONFIG_INET_DIAG=m
CONFIG_INET_TCP_DIAG=m
CONFIG_TCP_CONG_ADVANCED=y
CONFIG_TCP_CONG_BIC=y
CONFIG_TCP_CONG_CUBIC=y
CONFIG_TCP_CONG_WESTWOOD=m
# CONFIG_TCP_CONG_HTCP is not set
CONFIG_TCP_CONG_HSTCP=y
CONFIG_TCP_CONG_HYBLA=m
CONFIG_TCP_CONG_VEGAS=m
CONFIG_TCP_CONG_SCALABLE=m
CONFIG_TCP_CONG_LP=y
CONFIG_TCP_CONG_VENO=m
CONFIG_TCP_CONG_YEAH=m
# CONFIG_TCP_CONG_ILLINOIS is not set
# CONFIG_DEFAULT_BIC is not set
CONFIG_DEFAULT_CUBIC=y
# CONFIG_DEFAULT_HTCP is not set
# CONFIG_DEFAULT_VEGAS is not set
# CONFIG_DEFAULT_WESTWOOD is not set
# CONFIG_DEFAULT_RENO is not set
CONFIG_DEFAULT_TCP_CONG="cubic"
CONFIG_TCP_MD5SIG=y
CONFIG_IPV6=y
CONFIG_IPV6_PRIVACY=y
CONFIG_IPV6_ROUTER_PREF=y
CONFIG_IPV6_ROUTE_INFO=y
CONFIG_IPV6_OPTIMISTIC_DAD=y
CONFIG_INET6_AH=m
CONFIG_INET6_ESP=m
# CONFIG_INET6_IPCOMP is not set
# CONFIG_IPV6_MIP6 is not set
# CONFIG_INET6_XFRM_TUNNEL is not set
# CONFIG_INET6_TUNNEL is not set
# CONFIG_INET6_XFRM_MODE_TRANSPORT is not set
CONFIG_INET6_XFRM_MODE_TUNNEL=m
# CONFIG_INET6_XFRM_MODE_BEET is not set
CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m
CONFIG_IPV6_SIT=m
CONFIG_IPV6_NDISC_NODETYPE=y
# CONFIG_IPV6_TUNNEL is not set
CONFIG_IPV6_MULTIPLE_TABLES=y
CONFIG_IPV6_SUBTREES=y
CONFIG_IPV6_MROUTE=y
CONFIG_IPV6_PIMSM_V2=y
CONFIG_NETLABEL=y
CONFIG_NETWORK_SECMARK=y
CONFIG_NETFILTER=y
CONFIG_NETFILTER_DEBUG=y
CONFIG_NETFILTER_ADVANCED=y
CONFIG_BRIDGE_NETFILTER=y
#
# Core Netfilter Configuration
#
CONFIG_NETFILTER_NETLINK=y
# CONFIG_NETFILTER_NETLINK_QUEUE is not set
CONFIG_NETFILTER_NETLINK_LOG=y
# CONFIG_NF_CONNTRACK is not set
CONFIG_NETFILTER_TPROXY=m
CONFIG_NETFILTER_XTABLES=y
# CONFIG_NETFILTER_XT_TARGET_CLASSIFY is not set
CONFIG_NETFILTER_XT_TARGET_DSCP=m
CONFIG_NETFILTER_XT_TARGET_HL=y
CONFIG_NETFILTER_XT_TARGET_MARK=y
CONFIG_NETFILTER_XT_TARGET_NFLOG=m
CONFIG_NETFILTER_XT_TARGET_NFQUEUE=y
CONFIG_NETFILTER_XT_TARGET_RATEEST=y
# CONFIG_NETFILTER_XT_TARGET_TPROXY is not set
CONFIG_NETFILTER_XT_TARGET_TRACE=m
# CONFIG_NETFILTER_XT_TARGET_SECMARK is not set
CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m
CONFIG_NETFILTER_XT_MATCH_COMMENT=m
# CONFIG_NETFILTER_XT_MATCH_DCCP is not set
CONFIG_NETFILTER_XT_MATCH_DSCP=m
CONFIG_NETFILTER_XT_MATCH_ESP=m
CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=y
CONFIG_NETFILTER_XT_MATCH_HL=y
# CONFIG_NETFILTER_XT_MATCH_IPRANGE is not set
CONFIG_NETFILTER_XT_MATCH_LENGTH=m
CONFIG_NETFILTER_XT_MATCH_LIMIT=m
CONFIG_NETFILTER_XT_MATCH_MAC=m
CONFIG_NETFILTER_XT_MATCH_MARK=y
# CONFIG_NETFILTER_XT_MATCH_MULTIPORT is not set
CONFIG_NETFILTER_XT_MATCH_OWNER=m
CONFIG_NETFILTER_XT_MATCH_POLICY=y
CONFIG_NETFILTER_XT_MATCH_PHYSDEV=m
CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m
CONFIG_NETFILTER_XT_MATCH_QUOTA=m
CONFIG_NETFILTER_XT_MATCH_RATEEST=m
# CONFIG_NETFILTER_XT_MATCH_REALM is not set
CONFIG_NETFILTER_XT_MATCH_RECENT=y
CONFIG_NETFILTER_XT_MATCH_RECENT_PROC_COMPAT=y
CONFIG_NETFILTER_XT_MATCH_SCTP=y
# CONFIG_NETFILTER_XT_MATCH_SOCKET is not set
CONFIG_NETFILTER_XT_MATCH_STATISTIC=m
CONFIG_NETFILTER_XT_MATCH_STRING=m
# CONFIG_NETFILTER_XT_MATCH_TCPMSS is not set
CONFIG_NETFILTER_XT_MATCH_TIME=m
CONFIG_NETFILTER_XT_MATCH_U32=y
CONFIG_IP_VS=m
# CONFIG_IP_VS_IPV6 is not set
# CONFIG_IP_VS_DEBUG is not set
CONFIG_IP_VS_TAB_BITS=12
#
# IPVS transport protocol load balancing support
#
# CONFIG_IP_VS_PROTO_TCP is not set
# CONFIG_IP_VS_PROTO_UDP is not set
CONFIG_IP_VS_PROTO_AH_ESP=y
# CONFIG_IP_VS_PROTO_ESP is not set
CONFIG_IP_VS_PROTO_AH=y
#
# IPVS scheduler
#
# CONFIG_IP_VS_RR is not set
CONFIG_IP_VS_WRR=m
# CONFIG_IP_VS_LC is not set
CONFIG_IP_VS_WLC=m
# CONFIG_IP_VS_LBLC is not set
CONFIG_IP_VS_LBLCR=m
CONFIG_IP_VS_DH=m
CONFIG_IP_VS_SH=m
CONFIG_IP_VS_SED=m
CONFIG_IP_VS_NQ=m
#
# IPVS application helper
#
#
# IP: Netfilter Configuration
#
# CONFIG_NF_DEFRAG_IPV4 is not set
# CONFIG_IP_NF_QUEUE is not set
CONFIG_IP_NF_IPTABLES=y
# CONFIG_IP_NF_MATCH_ADDRTYPE is not set
CONFIG_IP_NF_MATCH_AH=m
CONFIG_IP_NF_MATCH_ECN=y
CONFIG_IP_NF_MATCH_TTL=m
# CONFIG_IP_NF_FILTER is not set
CONFIG_IP_NF_TARGET_LOG=y
# CONFIG_IP_NF_TARGET_ULOG is not set
CONFIG_IP_NF_MANGLE=m
CONFIG_IP_NF_TARGET_ECN=m
CONFIG_IP_NF_TARGET_TTL=y
CONFIG_IP_NF_RAW=m
CONFIG_IP_NF_SECURITY=m
# CONFIG_IP_NF_ARPTABLES is not set
#
# IPv6: Netfilter Configuration
#
# CONFIG_IP6_NF_QUEUE is not set
# CONFIG_IP6_NF_IPTABLES is not set
#
# DECnet: Netfilter Configuration
#
CONFIG_DECNET_NF_GRABULATOR=y
CONFIG_BRIDGE_NF_EBTABLES=m
CONFIG_BRIDGE_EBT_BROUTE=m
CONFIG_BRIDGE_EBT_T_FILTER=m
CONFIG_BRIDGE_EBT_T_NAT=m
CONFIG_BRIDGE_EBT_802_3=m
CONFIG_BRIDGE_EBT_AMONG=m
# CONFIG_BRIDGE_EBT_ARP is not set
CONFIG_BRIDGE_EBT_IP=m
CONFIG_BRIDGE_EBT_IP6=m
CONFIG_BRIDGE_EBT_LIMIT=m
CONFIG_BRIDGE_EBT_MARK=m
CONFIG_BRIDGE_EBT_PKTTYPE=m
CONFIG_BRIDGE_EBT_STP=m
# CONFIG_BRIDGE_EBT_VLAN is not set
# CONFIG_BRIDGE_EBT_ARPREPLY is not set
CONFIG_BRIDGE_EBT_DNAT=m
CONFIG_BRIDGE_EBT_MARK_T=m
CONFIG_BRIDGE_EBT_REDIRECT=m
CONFIG_BRIDGE_EBT_SNAT=m
# CONFIG_BRIDGE_EBT_LOG is not set
# CONFIG_BRIDGE_EBT_ULOG is not set
CONFIG_BRIDGE_EBT_NFLOG=m
CONFIG_IP_DCCP=m
CONFIG_INET_DCCP_DIAG=m
#
# DCCP CCIDs Configuration (EXPERIMENTAL)
#
# CONFIG_IP_DCCP_CCID2_DEBUG is not set
CONFIG_IP_DCCP_CCID3=y
# CONFIG_IP_DCCP_CCID3_DEBUG is not set
CONFIG_IP_DCCP_CCID3_RTO=100
CONFIG_IP_DCCP_TFRC_LIB=y
#
# DCCP Kernel Hacking
#
CONFIG_IP_DCCP_DEBUG=y
CONFIG_NET_DCCPPROBE=m
CONFIG_IP_SCTP=y
CONFIG_SCTP_DBG_MSG=y
CONFIG_SCTP_DBG_OBJCNT=y
# CONFIG_SCTP_HMAC_NONE is not set
# CONFIG_SCTP_HMAC_SHA1 is not set
CONFIG_SCTP_HMAC_MD5=y
CONFIG_TIPC=y
CONFIG_TIPC_ADVANCED=y
CONFIG_TIPC_ZONES=3
CONFIG_TIPC_CLUSTERS=1
CONFIG_TIPC_NODES=255
CONFIG_TIPC_SLAVE_NODES=0
CONFIG_TIPC_PORTS=8191
CONFIG_TIPC_LOG=0
# CONFIG_TIPC_DEBUG is not set
# CONFIG_ATM is not set
CONFIG_STP=m
CONFIG_GARP=m
CONFIG_BRIDGE=m
CONFIG_NET_DSA=y
CONFIG_NET_DSA_TAG_DSA=y
CONFIG_NET_DSA_TAG_EDSA=y
# CONFIG_NET_DSA_TAG_TRAILER is not set
CONFIG_NET_DSA_MV88E6XXX=y
# CONFIG_NET_DSA_MV88E6060 is not set
CONFIG_NET_DSA_MV88E6XXX_NEED_PPU=y
CONFIG_NET_DSA_MV88E6131=y
CONFIG_NET_DSA_MV88E6123_61_65=y
CONFIG_VLAN_8021Q=m
CONFIG_VLAN_8021Q_GVRP=y
CONFIG_DECNET=y
# CONFIG_DECNET_ROUTER is not set
CONFIG_LLC=y
CONFIG_LLC2=m
CONFIG_IPX=y
# CONFIG_IPX_INTERN is not set
CONFIG_ATALK=m
CONFIG_DEV_APPLETALK=m
CONFIG_IPDDP=m
CONFIG_IPDDP_ENCAP=y
CONFIG_IPDDP_DECAP=y
# CONFIG_X25 is not set
# CONFIG_LAPB is not set
CONFIG_ECONET=m
CONFIG_ECONET_AUNUDP=y
CONFIG_ECONET_NATIVE=y
CONFIG_WAN_ROUTER=m
# CONFIG_PHONET is not set
CONFIG_NET_SCHED=y
#
# Queueing/Scheduling
#
CONFIG_NET_SCH_CBQ=m
CONFIG_NET_SCH_HTB=y
CONFIG_NET_SCH_HFSC=m
CONFIG_NET_SCH_PRIO=y
CONFIG_NET_SCH_MULTIQ=m
CONFIG_NET_SCH_RED=m
# CONFIG_NET_SCH_SFQ is not set
CONFIG_NET_SCH_TEQL=m
CONFIG_NET_SCH_TBF=m
CONFIG_NET_SCH_GRED=y
CONFIG_NET_SCH_DSMARK=y
CONFIG_NET_SCH_NETEM=y
CONFIG_NET_SCH_DRR=m
#
# Classification
#
CONFIG_NET_CLS=y
CONFIG_NET_CLS_BASIC=y
CONFIG_NET_CLS_TCINDEX=m
# CONFIG_NET_CLS_ROUTE4 is not set
CONFIG_NET_CLS_FW=m
# CONFIG_NET_CLS_U32 is not set
# CONFIG_NET_CLS_RSVP is not set
# CONFIG_NET_CLS_RSVP6 is not set
CONFIG_NET_CLS_FLOW=m
CONFIG_NET_CLS_CGROUP=y
CONFIG_NET_EMATCH=y
CONFIG_NET_EMATCH_STACK=32
# CONFIG_NET_EMATCH_CMP is not set
CONFIG_NET_EMATCH_NBYTE=m
CONFIG_NET_EMATCH_U32=m
CONFIG_NET_EMATCH_META=y
CONFIG_NET_EMATCH_TEXT=m
# CONFIG_NET_CLS_ACT is not set
# CONFIG_NET_CLS_IND is not set
CONFIG_NET_SCH_FIFO=y
CONFIG_DCB=y
#
# Network testing
#
# CONFIG_NET_PKTGEN is not set
CONFIG_NET_TCPPROBE=m
CONFIG_NET_DROP_MONITOR=y
CONFIG_HAMRADIO=y
#
# Packet Radio protocols
#
CONFIG_AX25=m
# CONFIG_AX25_DAMA_SLAVE is not set
CONFIG_NETROM=m
CONFIG_ROSE=m
#
# AX.25 network device drivers
#
CONFIG_MKISS=m
CONFIG_6PACK=m
CONFIG_BPQETHER=m
CONFIG_BAYCOM_SER_FDX=m
CONFIG_BAYCOM_SER_HDX=m
CONFIG_BAYCOM_PAR=m
CONFIG_YAM=m
CONFIG_CAN=y
CONFIG_CAN_RAW=m
CONFIG_CAN_BCM=m
#
# CAN Device Drivers
#
CONFIG_CAN_VCAN=y
CONFIG_CAN_DEV=y
CONFIG_CAN_CALC_BITTIMING=y
CONFIG_CAN_SJA1000=m
CONFIG_CAN_SJA1000_PLATFORM=m
CONFIG_CAN_EMS_PCI=m
CONFIG_CAN_KVASER_PCI=m
# CONFIG_CAN_DEBUG_DEVICES is not set
CONFIG_IRDA=m
#
# IrDA protocols
#
CONFIG_IRLAN=m
CONFIG_IRNET=m
# CONFIG_IRCOMM is not set
CONFIG_IRDA_ULTRA=y
#
# IrDA options
#
CONFIG_IRDA_CACHE_LAST_LSAP=y
CONFIG_IRDA_FAST_RR=y
# CONFIG_IRDA_DEBUG is not set
#
# Infrared-port device drivers
#
#
# SIR device drivers
#
# CONFIG_IRTTY_SIR is not set
#
# Dongle support
#
CONFIG_KINGSUN_DONGLE=m
# CONFIG_KSDAZZLE_DONGLE is not set
CONFIG_KS959_DONGLE=m
#
# FIR device drivers
#
# CONFIG_USB_IRDA is not set
CONFIG_SIGMATEL_FIR=m
CONFIG_NSC_FIR=m
# CONFIG_WINBOND_FIR is not set
CONFIG_SMC_IRCC_FIR=m
CONFIG_ALI_FIR=m
CONFIG_VLSI_FIR=m
CONFIG_VIA_FIR=m
# CONFIG_MCS_FIR is not set
# CONFIG_BT is not set
# CONFIG_AF_RXRPC is not set
CONFIG_FIB_RULES=y
CONFIG_WIRELESS=y
CONFIG_CFG80211=y
# CONFIG_CFG80211_REG_DEBUG is not set
# CONFIG_CFG80211_DEBUGFS is not set
CONFIG_WIRELESS_OLD_REGULATORY=y
# CONFIG_WIRELESS_EXT is not set
CONFIG_LIB80211=y
# CONFIG_LIB80211_DEBUG is not set
# CONFIG_MAC80211 is not set
CONFIG_MAC80211_DEFAULT_PS_VALUE=0
CONFIG_WIMAX=y
CONFIG_WIMAX_DEBUG_LEVEL=8
# CONFIG_RFKILL is not set
CONFIG_NET_9P=y
# CONFIG_NET_9P_VIRTIO is not set
# CONFIG_NET_9P_DEBUG is not set
#
# Device Drivers
#
#
# Generic Driver Options
#
CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
CONFIG_DEVTMPFS=y
# CONFIG_DEVTMPFS_MOUNT is not set
CONFIG_STANDALONE=y
CONFIG_PREVENT_FIRMWARE_BUILD=y
CONFIG_FW_LOADER=y
CONFIG_FIRMWARE_IN_KERNEL=y
CONFIG_EXTRA_FIRMWARE=""
CONFIG_DEBUG_DRIVER=y
# CONFIG_DEBUG_DEVRES is not set
# CONFIG_SYS_HYPERVISOR is not set
CONFIG_CONNECTOR=y
CONFIG_PROC_EVENTS=y
CONFIG_MTD=y
# CONFIG_MTD_DEBUG is not set
CONFIG_MTD_CONCAT=m
CONFIG_MTD_PARTITIONS=y
CONFIG_MTD_TESTS=m
# CONFIG_MTD_REDBOOT_PARTS is not set
CONFIG_MTD_CMDLINE_PARTS=y
CONFIG_MTD_AR7_PARTS=y
#
# User Modules And Translation Layers
#
CONFIG_MTD_CHAR=y
CONFIG_HAVE_MTD_OTP=y
CONFIG_MTD_BLKDEVS=y
# CONFIG_MTD_BLOCK is not set
CONFIG_MTD_BLOCK_RO=y
# CONFIG_FTL is not set
CONFIG_NFTL=m
# CONFIG_NFTL_RW is not set
CONFIG_INFTL=y
CONFIG_RFD_FTL=y
# CONFIG_SSFDC is not set
# CONFIG_MTD_OOPS is not set
#
# RAM/ROM/Flash chip drivers
#
CONFIG_MTD_CFI=y
CONFIG_MTD_JEDECPROBE=m
CONFIG_MTD_GEN_PROBE=y
CONFIG_MTD_CFI_ADV_OPTIONS=y
# CONFIG_MTD_CFI_NOSWAP is not set
CONFIG_MTD_CFI_BE_BYTE_SWAP=y
# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set
# CONFIG_MTD_CFI_GEOMETRY is not set
CONFIG_MTD_MAP_BANK_WIDTH_1=y
CONFIG_MTD_MAP_BANK_WIDTH_2=y
CONFIG_MTD_MAP_BANK_WIDTH_4=y
# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
CONFIG_MTD_CFI_I1=y
CONFIG_MTD_CFI_I2=y
# CONFIG_MTD_CFI_I4 is not set
# CONFIG_MTD_CFI_I8 is not set
CONFIG_MTD_OTP=y
CONFIG_MTD_CFI_INTELEXT=m
CONFIG_MTD_CFI_AMDSTD=m
CONFIG_MTD_CFI_STAA=m
CONFIG_MTD_CFI_UTIL=y
CONFIG_MTD_RAM=m
CONFIG_MTD_ROM=y
CONFIG_MTD_ABSENT=m
#
# Mapping drivers for chip access
#
# CONFIG_MTD_COMPLEX_MAPPINGS is not set
CONFIG_MTD_PHYSMAP=y
CONFIG_MTD_PHYSMAP_COMPAT=y
CONFIG_MTD_PHYSMAP_START=0x8000000
CONFIG_MTD_PHYSMAP_LEN=0
CONFIG_MTD_PHYSMAP_BANKWIDTH=2
# CONFIG_MTD_SC520CDP is not set
# CONFIG_MTD_NETSC520 is not set
# CONFIG_MTD_TS5500 is not set
CONFIG_MTD_AMD76XROM=m
CONFIG_MTD_ICHXROM=m
# CONFIG_MTD_ESB2ROM is not set
CONFIG_MTD_CK804XROM=m
# CONFIG_MTD_SCB2_FLASH is not set
CONFIG_MTD_NETtel=m
CONFIG_MTD_L440GX=m
# CONFIG_MTD_INTEL_VR_NOR is not set
CONFIG_MTD_PLATRAM=m
#
# Self-contained MTD device drivers
#
# CONFIG_MTD_PMC551 is not set
CONFIG_MTD_SLRAM=y
# CONFIG_MTD_PHRAM is not set
CONFIG_MTD_MTDRAM=m
CONFIG_MTDRAM_TOTAL_SIZE=4096
CONFIG_MTDRAM_ERASE_SIZE=128
CONFIG_MTD_BLOCK2MTD=y
#
# Disk-On-Chip Device Drivers
#
# CONFIG_MTD_DOC2000 is not set
# CONFIG_MTD_DOC2001 is not set
CONFIG_MTD_DOC2001PLUS=y
CONFIG_MTD_DOCPROBE=y
CONFIG_MTD_DOCECC=y
# CONFIG_MTD_DOCPROBE_ADVANCED is not set
CONFIG_MTD_DOCPROBE_ADDRESS=0
CONFIG_MTD_NAND=y
# CONFIG_MTD_NAND_VERIFY_WRITE is not set
CONFIG_MTD_NAND_ECC_SMC=y
CONFIG_MTD_NAND_MUSEUM_IDS=y
CONFIG_MTD_NAND_IDS=y
# CONFIG_MTD_NAND_DISKONCHIP is not set
CONFIG_MTD_NAND_CAFE=y
CONFIG_MTD_NAND_NANDSIM=y
# CONFIG_MTD_NAND_PLATFORM is not set
CONFIG_MTD_ALAUDA=m
CONFIG_MTD_ONENAND=m
# CONFIG_MTD_ONENAND_VERIFY_WRITE is not set
CONFIG_MTD_ONENAND_OTP=y
CONFIG_MTD_ONENAND_2X_PROGRAM=y
CONFIG_MTD_ONENAND_SIM=m
#
# LPDDR flash memory drivers
#
# CONFIG_MTD_LPDDR is not set
#
# UBI - Unsorted block images
#
CONFIG_MTD_UBI=m
CONFIG_MTD_UBI_WL_THRESHOLD=4096
CONFIG_MTD_UBI_BEB_RESERVE=1
CONFIG_MTD_UBI_GLUEBI=y
#
# UBI debugging options
#
# CONFIG_MTD_UBI_DEBUG is not set
CONFIG_PARPORT=m
CONFIG_PARPORT_PC=m
CONFIG_PARPORT_PC_FIFO=y
# CONFIG_PARPORT_PC_SUPERIO is not set
# CONFIG_PARPORT_GSC is not set
CONFIG_PARPORT_AX88796=m
# CONFIG_PARPORT_1284 is not set
CONFIG_PARPORT_NOT_PC=y
CONFIG_PNP=y
CONFIG_PNP_DEBUG_MESSAGES=y
#
# Protocols
#
CONFIG_PNPACPI=y
CONFIG_BLK_DEV=y
CONFIG_BLK_DEV_FD=y
CONFIG_PARIDE=m
#
# Parallel IDE high-level drivers
#
# CONFIG_PARIDE_PD is not set
# CONFIG_PARIDE_PCD is not set
# CONFIG_PARIDE_PF is not set
# CONFIG_PARIDE_PT is not set
CONFIG_PARIDE_PG=m
#
# Parallel IDE protocol modules
#
CONFIG_PARIDE_ATEN=m
CONFIG_PARIDE_BPCK=m
CONFIG_PARIDE_COMM=m
CONFIG_PARIDE_DSTR=m
# CONFIG_PARIDE_FIT2 is not set
CONFIG_PARIDE_FIT3=m
# CONFIG_PARIDE_EPAT is not set
# CONFIG_PARIDE_EPIA is not set
# CONFIG_PARIDE_FRIQ is not set
# CONFIG_PARIDE_FRPW is not set
CONFIG_PARIDE_KBIC=m
# CONFIG_PARIDE_KTTI is not set
CONFIG_PARIDE_ON20=m
CONFIG_PARIDE_ON26=m
CONFIG_BLK_CPQ_DA=y
CONFIG_BLK_CPQ_CISS_DA=m
CONFIG_CISS_SCSI_TAPE=y
CONFIG_BLK_DEV_DAC960=m
# CONFIG_BLK_DEV_UMEM is not set
# CONFIG_BLK_DEV_COW_COMMON is not set
CONFIG_BLK_DEV_LOOP=y
# CONFIG_BLK_DEV_CRYPTOLOOP is not set
CONFIG_BLK_DEV_NBD=y
CONFIG_BLK_DEV_SX8=m
# CONFIG_BLK_DEV_UB is not set
# CONFIG_BLK_DEV_RAM is not set
CONFIG_CDROM_PKTCDVD=m
CONFIG_CDROM_PKTCDVD_BUFFERS=8
# CONFIG_CDROM_PKTCDVD_WCACHE is not set
CONFIG_ATA_OVER_ETH=y
CONFIG_VIRTIO_BLK=m
CONFIG_BLK_DEV_HD=y
CONFIG_MISC_DEVICES=y
# CONFIG_IBM_ASM is not set
# CONFIG_PHANTOM is not set
CONFIG_SGI_IOC4=y
CONFIG_TIFM_CORE=m
CONFIG_TIFM_7XX1=m
# CONFIG_ICS932S401 is not set
CONFIG_ENCLOSURE_SERVICES=m
CONFIG_SGI_XP=m
CONFIG_HP_ILO=y
CONFIG_SGI_GRU=m
CONFIG_SGI_GRU_DEBUG=y
# CONFIG_ISL29003 is not set
CONFIG_C2PORT=m
# CONFIG_C2PORT_DURAMAR_2150 is not set
#
# EEPROM support
#
CONFIG_EEPROM_AT24=m
CONFIG_EEPROM_LEGACY=y
CONFIG_EEPROM_MAX6875=y
CONFIG_EEPROM_93CX6=y
CONFIG_HAVE_IDE=y
CONFIG_IDE=y
#
# Please see Documentation/ide/ide.txt for help/info on IDE drives
#
CONFIG_IDE_XFER_MODE=y
CONFIG_IDE_TIMINGS=y
CONFIG_IDE_ATAPI=y
CONFIG_BLK_DEV_IDE_SATA=y
CONFIG_IDE_GD=y
# CONFIG_IDE_GD_ATA is not set
CONFIG_IDE_GD_ATAPI=y
CONFIG_BLK_DEV_IDECD=y
CONFIG_BLK_DEV_IDECD_VERBOSE_ERRORS=y
# CONFIG_BLK_DEV_IDETAPE is not set
CONFIG_BLK_DEV_IDEACPI=y
CONFIG_IDE_TASK_IOCTL=y
# CONFIG_IDE_PROC_FS is not set
#
# IDE chipset support/bugfixes
#
# CONFIG_IDE_GENERIC is not set
CONFIG_BLK_DEV_PLATFORM=m
CONFIG_BLK_DEV_CMD640=y
# CONFIG_BLK_DEV_CMD640_ENHANCED is not set
# CONFIG_BLK_DEV_IDEPNP is not set
CONFIG_BLK_DEV_IDEDMA_SFF=y
#
# PCI IDE chipsets support
#
CONFIG_BLK_DEV_IDEPCI=y
CONFIG_IDEPCI_PCIBUS_ORDER=y
# CONFIG_BLK_DEV_OFFBOARD is not set
CONFIG_BLK_DEV_GENERIC=m
CONFIG_BLK_DEV_OPTI621=y
CONFIG_BLK_DEV_RZ1000=m
CONFIG_BLK_DEV_IDEDMA_PCI=y
CONFIG_BLK_DEV_AEC62XX=m
CONFIG_BLK_DEV_ALI15X3=m
CONFIG_BLK_DEV_AMD74XX=y
# CONFIG_BLK_DEV_ATIIXP is not set
# CONFIG_BLK_DEV_CMD64X is not set
CONFIG_BLK_DEV_TRIFLEX=m
# CONFIG_BLK_DEV_CS5520 is not set
CONFIG_BLK_DEV_CS5530=m
CONFIG_BLK_DEV_HPT366=m
CONFIG_BLK_DEV_JMICRON=m
CONFIG_BLK_DEV_SC1200=m
# CONFIG_BLK_DEV_PIIX is not set
# CONFIG_BLK_DEV_IT8172 is not set
# CONFIG_BLK_DEV_IT8213 is not set
CONFIG_BLK_DEV_IT821X=m
CONFIG_BLK_DEV_NS87415=y
CONFIG_BLK_DEV_PDC202XX_OLD=m
# CONFIG_BLK_DEV_PDC202XX_NEW is not set
CONFIG_BLK_DEV_SVWKS=y
# CONFIG_BLK_DEV_SIIMAGE is not set
# CONFIG_BLK_DEV_SIS5513 is not set
CONFIG_BLK_DEV_SLC90E66=m
CONFIG_BLK_DEV_TRM290=m
# CONFIG_BLK_DEV_VIA82CXXX is not set
# CONFIG_BLK_DEV_TC86C001 is not set
CONFIG_BLK_DEV_IDEDMA=y
#
# SCSI device support
#
# CONFIG_RAID_ATTRS is not set
CONFIG_SCSI=y
CONFIG_SCSI_DMA=y
CONFIG_SCSI_TGT=m
CONFIG_SCSI_NETLINK=y
# CONFIG_SCSI_PROC_FS is not set
#
# SCSI support type (disk, tape, CD-ROM)
#
# CONFIG_BLK_DEV_SD is not set
# CONFIG_CHR_DEV_ST is not set
# CONFIG_CHR_DEV_OSST is not set
# CONFIG_BLK_DEV_SR is not set
CONFIG_CHR_DEV_SG=m
# CONFIG_CHR_DEV_SCH is not set
CONFIG_SCSI_ENCLOSURE=m
CONFIG_SCSI_MULTI_LUN=y
# CONFIG_SCSI_CONSTANTS is not set
CONFIG_SCSI_LOGGING=y
CONFIG_SCSI_SCAN_ASYNC=y
CONFIG_SCSI_WAIT_SCAN=m
#
# SCSI Transports
#
CONFIG_SCSI_SPI_ATTRS=y
CONFIG_SCSI_FC_ATTRS=m
CONFIG_SCSI_FC_TGT_ATTRS=y
CONFIG_SCSI_ISCSI_ATTRS=y
CONFIG_SCSI_SAS_ATTRS=y
CONFIG_SCSI_SAS_LIBSAS=y
CONFIG_SCSI_SAS_HOST_SMP=y
CONFIG_SCSI_SAS_LIBSAS_DEBUG=y
CONFIG_SCSI_SRP_ATTRS=y
CONFIG_SCSI_LOWLEVEL=y
CONFIG_ISCSI_TCP=m
# CONFIG_SCSI_CXGB3_ISCSI is not set
CONFIG_BLK_DEV_3W_XXXX_RAID=y
CONFIG_SCSI_3W_9XXX=m
CONFIG_SCSI_ACARD=y
CONFIG_SCSI_AACRAID=m
CONFIG_SCSI_AIC7XXX=y
CONFIG_AIC7XXX_CMDS_PER_DEVICE=32
CONFIG_AIC7XXX_RESET_DELAY_MS=5000
CONFIG_AIC7XXX_DEBUG_ENABLE=y
CONFIG_AIC7XXX_DEBUG_MASK=0
CONFIG_AIC7XXX_REG_PRETTY_PRINT=y
# CONFIG_SCSI_AIC7XXX_OLD is not set
CONFIG_SCSI_AIC79XX=m
CONFIG_AIC79XX_CMDS_PER_DEVICE=32
CONFIG_AIC79XX_RESET_DELAY_MS=5000
CONFIG_AIC79XX_DEBUG_ENABLE=y
CONFIG_AIC79XX_DEBUG_MASK=0
CONFIG_AIC79XX_REG_PRETTY_PRINT=y
CONFIG_SCSI_AIC94XX=y
# CONFIG_AIC94XX_DEBUG is not set
CONFIG_SCSI_MVSAS=y
# CONFIG_SCSI_MVSAS_DEBUG is not set
CONFIG_SCSI_DPT_I2O=m
# CONFIG_SCSI_ADVANSYS is not set
CONFIG_SCSI_ARCMSR=y
CONFIG_SCSI_ARCMSR_AER=y
CONFIG_MEGARAID_NEWGEN=y
CONFIG_MEGARAID_MM=m
CONFIG_MEGARAID_MAILBOX=m
CONFIG_MEGARAID_LEGACY=m
# CONFIG_MEGARAID_SAS is not set
CONFIG_SCSI_MPT2SAS=m
CONFIG_SCSI_MPT2SAS_MAX_SGE=128
# CONFIG_SCSI_MPT2SAS_LOGGING is not set
CONFIG_SCSI_HPTIOP=y
CONFIG_SCSI_BUSLOGIC=y
CONFIG_LIBFC=m
CONFIG_LIBFCOE=m
# CONFIG_FCOE is not set
# CONFIG_FCOE_FNIC is not set
CONFIG_SCSI_DMX3191D=y
CONFIG_SCSI_EATA=m
# CONFIG_SCSI_EATA_TAGGED_QUEUE is not set
CONFIG_SCSI_EATA_LINKED_COMMANDS=y
CONFIG_SCSI_EATA_MAX_TAGS=16
CONFIG_SCSI_FUTURE_DOMAIN=y
# CONFIG_SCSI_GDTH is not set
CONFIG_SCSI_IPS=m
CONFIG_SCSI_INITIO=m
CONFIG_SCSI_INIA100=y
CONFIG_SCSI_PPA=m
CONFIG_SCSI_IMM=m
# CONFIG_SCSI_IZIP_EPP16 is not set
CONFIG_SCSI_IZIP_SLOW_CTR=y
CONFIG_SCSI_STEX=y
CONFIG_SCSI_SYM53C8XX_2=m
CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=1
CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16
CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64
CONFIG_SCSI_SYM53C8XX_MMIO=y
# CONFIG_SCSI_IPR is not set
CONFIG_SCSI_QLOGIC_1280=y
CONFIG_SCSI_QLA_FC=m
CONFIG_SCSI_QLA_ISCSI=y
# CONFIG_SCSI_LPFC is not set
CONFIG_SCSI_DC395x=y
# CONFIG_SCSI_DC390T is not set
CONFIG_SCSI_DEBUG=m
CONFIG_SCSI_SRP=m
CONFIG_SCSI_DH=y
# CONFIG_SCSI_DH_RDAC is not set
CONFIG_SCSI_DH_HP_SW=m
# CONFIG_SCSI_DH_EMC is not set
CONFIG_SCSI_DH_ALUA=y
CONFIG_SCSI_OSD_INITIATOR=y
# CONFIG_SCSI_OSD_ULD is not set
CONFIG_SCSI_OSD_DPRINT_SENSE=1
CONFIG_SCSI_OSD_DEBUG=y
CONFIG_ATA=m
# CONFIG_ATA_NONSTANDARD is not set
CONFIG_ATA_ACPI=y
CONFIG_SATA_PMP=y
CONFIG_SATA_AHCI=m
# CONFIG_SATA_SIL24 is not set
CONFIG_ATA_SFF=y
CONFIG_SATA_SVW=m
CONFIG_ATA_PIIX=m
# CONFIG_SATA_MV is not set
# CONFIG_SATA_NV is not set
CONFIG_PDC_ADMA=m
CONFIG_SATA_QSTOR=m
# CONFIG_SATA_PROMISE is not set
CONFIG_SATA_SX4=m
CONFIG_SATA_SIL=m
CONFIG_SATA_SIS=m
# CONFIG_SATA_ULI is not set
CONFIG_SATA_VIA=m
CONFIG_SATA_VITESSE=m
CONFIG_SATA_INIC162X=m
CONFIG_PATA_ACPI=m
CONFIG_PATA_ALI=m
# CONFIG_PATA_AMD is not set
# CONFIG_PATA_ARTOP is not set
CONFIG_PATA_ATIIXP=m
CONFIG_PATA_CMD640_PCI=m
CONFIG_PATA_CMD64X=m
CONFIG_PATA_CS5520=m
CONFIG_PATA_CS5530=m
# CONFIG_PATA_CYPRESS is not set
CONFIG_PATA_EFAR=m
# CONFIG_ATA_GENERIC is not set
CONFIG_PATA_HPT366=m
# CONFIG_PATA_HPT37X is not set
CONFIG_PATA_HPT3X2N=m
CONFIG_PATA_HPT3X3=m
# CONFIG_PATA_HPT3X3_DMA is not set
CONFIG_PATA_IT821X=m
CONFIG_PATA_IT8213=m
# CONFIG_PATA_JMICRON is not set
CONFIG_PATA_TRIFLEX=m
# CONFIG_PATA_MARVELL is not set
CONFIG_PATA_MPIIX=m
# CONFIG_PATA_OLDPIIX is not set
CONFIG_PATA_NETCELL=m
# CONFIG_PATA_NINJA32 is not set
CONFIG_PATA_NS87410=m
CONFIG_PATA_NS87415=m
CONFIG_PATA_OPTI=m
# CONFIG_PATA_OPTIDMA is not set
CONFIG_PATA_PDC_OLD=m
# CONFIG_PATA_RADISYS is not set
# CONFIG_PATA_RZ1000 is not set
CONFIG_PATA_SC1200=m
# CONFIG_PATA_SERVERWORKS is not set
CONFIG_PATA_PDC2027X=m
CONFIG_PATA_SIL680=m
CONFIG_PATA_SIS=m
CONFIG_PATA_VIA=m
CONFIG_PATA_WINBOND=m
CONFIG_PATA_SCH=m
# CONFIG_MD is not set
# CONFIG_FUSION is not set
#
# IEEE 1394 (FireWire) support
#
#
# Enable only one of the two stacks, unless you know what you are doing
#
CONFIG_FIREWIRE=m
# CONFIG_FIREWIRE_OHCI is not set
# CONFIG_FIREWIRE_SBP2 is not set
CONFIG_IEEE1394=y
CONFIG_IEEE1394_OHCI1394=y
CONFIG_IEEE1394_PCILYNX=y
# CONFIG_IEEE1394_SBP2 is not set
# CONFIG_IEEE1394_ETH1394_ROM_ENTRY is not set
# CONFIG_IEEE1394_ETH1394 is not set
CONFIG_IEEE1394_RAWIO=m
CONFIG_IEEE1394_VIDEO1394=y
CONFIG_IEEE1394_DV1394=y
# CONFIG_IEEE1394_VERBOSEDEBUG is not set
# CONFIG_I2O is not set
# CONFIG_MACINTOSH_DRIVERS is not set
CONFIG_NETDEVICES=y
# CONFIG_DUMMY is not set
CONFIG_BONDING=m
CONFIG_MACVLAN=m
# CONFIG_EQUALIZER is not set
# CONFIG_TUN is not set
CONFIG_VETH=m
CONFIG_NET_SB1000=m
CONFIG_ARCNET=m
CONFIG_ARCNET_1201=m
CONFIG_ARCNET_1051=m
CONFIG_ARCNET_RAW=m
CONFIG_ARCNET_CAP=m
# CONFIG_ARCNET_COM90xx is not set
CONFIG_ARCNET_COM90xxIO=m
# CONFIG_ARCNET_RIM_I is not set
# CONFIG_ARCNET_COM20020 is not set
CONFIG_PHYLIB=y
#
# MII PHY device drivers
#
# CONFIG_MARVELL_PHY is not set
# CONFIG_DAVICOM_PHY is not set
# CONFIG_QSEMI_PHY is not set
CONFIG_LXT_PHY=y
CONFIG_CICADA_PHY=m
# CONFIG_VITESSE_PHY is not set
CONFIG_SMSC_PHY=y
CONFIG_BROADCOM_PHY=m
# CONFIG_ICPLUS_PHY is not set
CONFIG_REALTEK_PHY=m
CONFIG_NATIONAL_PHY=y
# CONFIG_STE10XP is not set
# CONFIG_LSI_ET1011C_PHY is not set
CONFIG_FIXED_PHY=y
# CONFIG_MDIO_BITBANG is not set
CONFIG_NET_ETHERNET=y
CONFIG_MII=y
# CONFIG_HAPPYMEAL is not set
# CONFIG_SUNGEM is not set
CONFIG_CASSINI=y
CONFIG_NET_VENDOR_3COM=y
# CONFIG_VORTEX is not set
# CONFIG_TYPHOON is not set
CONFIG_ETHOC=y
CONFIG_DNET=y
CONFIG_NET_TULIP=y
# CONFIG_DE2104X is not set
CONFIG_TULIP=m
CONFIG_TULIP_MWI=y
CONFIG_TULIP_MMIO=y
CONFIG_TULIP_NAPI=y
CONFIG_TULIP_NAPI_HW_MITIGATION=y
CONFIG_DE4X5=m
CONFIG_WINBOND_840=y
CONFIG_DM9102=y
CONFIG_ULI526X=y
CONFIG_HP100=m
# CONFIG_IBM_NEW_EMAC_ZMII is not set
# CONFIG_IBM_NEW_EMAC_RGMII is not set
# CONFIG_IBM_NEW_EMAC_TAH is not set
# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
CONFIG_NET_PCI=y
# CONFIG_PCNET32 is not set
CONFIG_AMD8111_ETH=y
CONFIG_ADAPTEC_STARFIRE=y
CONFIG_B44=m
CONFIG_B44_PCI_AUTOSELECT=y
CONFIG_B44_PCICORE_AUTOSELECT=y
CONFIG_B44_PCI=y
CONFIG_FORCEDETH=y
CONFIG_FORCEDETH_NAPI=y
# CONFIG_E100 is not set
# CONFIG_FEALNX is not set
CONFIG_NATSEMI=m
# CONFIG_NE2K_PCI is not set
# CONFIG_8139CP is not set
CONFIG_8139TOO=m
# CONFIG_8139TOO_PIO is not set
# CONFIG_8139TOO_TUNE_TWISTER is not set
# CONFIG_8139TOO_8129 is not set
# CONFIG_8139_OLD_RX_RESET is not set
CONFIG_R6040=y
CONFIG_SIS900=m
CONFIG_EPIC100=y
# CONFIG_SMSC9420 is not set
CONFIG_SUNDANCE=y
# CONFIG_SUNDANCE_MMIO is not set
# CONFIG_TLAN is not set
CONFIG_VIA_RHINE=m
# CONFIG_VIA_RHINE_MMIO is not set
# CONFIG_SC92031 is not set
CONFIG_NET_POCKET=y
CONFIG_ATP=m
# CONFIG_DE600 is not set
CONFIG_DE620=m
CONFIG_ATL2=m
CONFIG_NETDEV_1000=y
CONFIG_ACENIC=m
CONFIG_ACENIC_OMIT_TIGON_I=y
CONFIG_DL2K=y
# CONFIG_E1000 is not set
# CONFIG_E1000E is not set
# CONFIG_IP1000 is not set
# CONFIG_IGB is not set
CONFIG_IGBVF=y
CONFIG_NS83820=m
CONFIG_HAMACHI=m
CONFIG_YELLOWFIN=y
# CONFIG_R8169 is not set
CONFIG_SIS190=y
# CONFIG_SKGE is not set
CONFIG_SKY2=m
CONFIG_SKY2_DEBUG=y
CONFIG_VIA_VELOCITY=m
# CONFIG_TIGON3 is not set
CONFIG_BNX2=y
CONFIG_QLA3XXX=y
CONFIG_ATL1=y
# CONFIG_ATL1E is not set
CONFIG_ATL1C=y
# CONFIG_JME is not set
CONFIG_NETDEV_10000=y
CONFIG_MDIO=y
CONFIG_CHELSIO_T1=y
# CONFIG_CHELSIO_T1_1G is not set
CONFIG_CHELSIO_T3_DEPENDS=y
CONFIG_CHELSIO_T3=y
CONFIG_ENIC=y
# CONFIG_IXGBE is not set
CONFIG_IXGB=y
# CONFIG_S2IO is not set
CONFIG_VXGE=m
# CONFIG_VXGE_DEBUG_TRACE_ALL is not set
CONFIG_MYRI10GE=y
# CONFIG_NETXEN_NIC is not set
CONFIG_NIU=y
CONFIG_MLX4_EN=m
CONFIG_MLX4_CORE=m
CONFIG_MLX4_DEBUG=y
CONFIG_TEHUTI=y
# CONFIG_BNX2X is not set
# CONFIG_QLGE is not set
CONFIG_SFC=y
CONFIG_SFC_MTD=y
CONFIG_BE2NET=m
# CONFIG_TR is not set
#
# Wireless LAN
#
# CONFIG_WLAN_PRE80211 is not set
# CONFIG_WLAN_80211 is not set
#
# WiMAX Wireless Broadband devices
#
CONFIG_WIMAX_I2400M=y
CONFIG_WIMAX_I2400M_USB=m
CONFIG_WIMAX_I2400M_SDIO=y
CONFIG_WIMAX_I2400M_DEBUG_LEVEL=8
#
# USB Network Adapters
#
# CONFIG_USB_CATC is not set
CONFIG_USB_KAWETH=y
CONFIG_USB_PEGASUS=m
CONFIG_USB_RTL8150=y
CONFIG_USB_USBNET=m
CONFIG_USB_NET_AX8817X=m
CONFIG_USB_NET_CDCETHER=m
CONFIG_USB_NET_CDC_EEM=m
# CONFIG_USB_NET_DM9601 is not set
CONFIG_USB_NET_SMSC95XX=m
CONFIG_USB_NET_GL620A=m
CONFIG_USB_NET_NET1080=m
CONFIG_USB_NET_PLUSB=m
CONFIG_USB_NET_MCS7830=m
CONFIG_USB_NET_RNDIS_HOST=m
CONFIG_USB_NET_CDC_SUBSET=m
CONFIG_USB_ALI_M5632=y
CONFIG_USB_AN2720=y
# CONFIG_USB_BELKIN is not set
# CONFIG_USB_ARMLINUX is not set
# CONFIG_USB_EPSON2888 is not set
CONFIG_USB_KC2190=y
CONFIG_USB_NET_ZAURUS=m
# CONFIG_USB_NET_INT51X1 is not set
# CONFIG_WAN is not set
CONFIG_FDDI=m
# CONFIG_DEFXX is not set
CONFIG_SKFP=m
CONFIG_HIPPI=y
CONFIG_ROADRUNNER=y
CONFIG_ROADRUNNER_LARGE_RINGS=y
CONFIG_PLIP=m
CONFIG_PPP=m
CONFIG_PPP_MULTILINK=y
CONFIG_PPP_FILTER=y
CONFIG_PPP_ASYNC=m
CONFIG_PPP_SYNC_TTY=m
CONFIG_PPP_DEFLATE=m
CONFIG_PPP_BSDCOMP=m
# CONFIG_PPP_MPPE is not set
# CONFIG_PPPOE is not set
# CONFIG_PPPOL2TP is not set
CONFIG_SLIP=y
CONFIG_SLIP_COMPRESSED=y
CONFIG_SLHC=y
# CONFIG_SLIP_SMART is not set
# CONFIG_SLIP_MODE_SLIP6 is not set
CONFIG_NET_FC=y
CONFIG_NETCONSOLE=y
CONFIG_NETCONSOLE_DYNAMIC=y
CONFIG_NETPOLL=y
# CONFIG_NETPOLL_TRAP is not set
CONFIG_NET_POLL_CONTROLLER=y
CONFIG_VIRTIO_NET=m
CONFIG_ISDN=y
# CONFIG_MISDN is not set
# CONFIG_ISDN_I4L is not set
CONFIG_ISDN_CAPI=y
# CONFIG_ISDN_DRV_AVMB1_VERBOSE_REASON is not set
# CONFIG_CAPI_TRACE is not set
CONFIG_ISDN_CAPI_MIDDLEWARE=y
# CONFIG_ISDN_CAPI_CAPI20 is not set
#
# CAPI hardware drivers
#
# CONFIG_CAPI_AVM is not set
CONFIG_CAPI_EICON=y
CONFIG_ISDN_DIVAS=y
CONFIG_ISDN_DIVAS_BRIPCI=y
CONFIG_ISDN_DIVAS_PRIPCI=y
CONFIG_ISDN_DIVAS_DIVACAPI=y
CONFIG_ISDN_DIVAS_USERIDI=m
# CONFIG_ISDN_DIVAS_MAINT is not set
CONFIG_PHONE=m
CONFIG_PHONE_IXJ=m
#
# Input device support
#
CONFIG_INPUT=y
CONFIG_INPUT_FF_MEMLESS=y
CONFIG_INPUT_POLLDEV=m
#
# Userland interfaces
#
CONFIG_INPUT_MOUSEDEV=y
CONFIG_INPUT_MOUSEDEV_PSAUX=y
CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
CONFIG_INPUT_JOYDEV=y
CONFIG_INPUT_EVDEV=m
CONFIG_INPUT_EVBUG=m
#
# Input Device Drivers
#
CONFIG_INPUT_KEYBOARD=y
CONFIG_KEYBOARD_ATKBD=y
CONFIG_KEYBOARD_SUNKBD=m
CONFIG_KEYBOARD_LKKBD=y
CONFIG_KEYBOARD_XTKBD=m
CONFIG_KEYBOARD_NEWTON=y
# CONFIG_KEYBOARD_STOWAWAY is not set
CONFIG_KEYBOARD_LM8323=m
CONFIG_INPUT_MOUSE=y
CONFIG_MOUSE_PS2=y
CONFIG_MOUSE_PS2_ALPS=y
CONFIG_MOUSE_PS2_LOGIPS2PP=y
CONFIG_MOUSE_PS2_SYNAPTICS=y
CONFIG_MOUSE_PS2_LIFEBOOK=y
CONFIG_MOUSE_PS2_TRACKPOINT=y
# CONFIG_MOUSE_PS2_ELANTECH is not set
CONFIG_MOUSE_PS2_TOUCHKIT=y
CONFIG_MOUSE_SERIAL=y
CONFIG_MOUSE_APPLETOUCH=m
CONFIG_MOUSE_BCM5974=m
# CONFIG_MOUSE_VSXXXAA is not set
CONFIG_INPUT_JOYSTICK=y
# CONFIG_JOYSTICK_ANALOG is not set
CONFIG_JOYSTICK_A3D=y
# CONFIG_JOYSTICK_ADI is not set
CONFIG_JOYSTICK_COBRA=m
# CONFIG_JOYSTICK_GF2K is not set
CONFIG_JOYSTICK_GRIP=m
CONFIG_JOYSTICK_GRIP_MP=m
# CONFIG_JOYSTICK_GUILLEMOT is not set
CONFIG_JOYSTICK_INTERACT=m
CONFIG_JOYSTICK_SIDEWINDER=m
# CONFIG_JOYSTICK_TMDC is not set
# CONFIG_JOYSTICK_IFORCE is not set
CONFIG_JOYSTICK_WARRIOR=y
# CONFIG_JOYSTICK_MAGELLAN is not set
CONFIG_JOYSTICK_SPACEORB=y
CONFIG_JOYSTICK_SPACEBALL=y
# CONFIG_JOYSTICK_STINGER is not set
CONFIG_JOYSTICK_TWIDJOY=y
CONFIG_JOYSTICK_ZHENHUA=y
CONFIG_JOYSTICK_DB9=m
CONFIG_JOYSTICK_GAMECON=m
# CONFIG_JOYSTICK_TURBOGRAFX is not set
CONFIG_JOYSTICK_JOYDUMP=m
CONFIG_JOYSTICK_XPAD=m
# CONFIG_JOYSTICK_XPAD_FF is not set
CONFIG_JOYSTICK_XPAD_LEDS=y
CONFIG_JOYSTICK_WALKERA0701=m
CONFIG_INPUT_TABLET=y
# CONFIG_TABLET_USB_ACECAD is not set
CONFIG_TABLET_USB_AIPTEK=y
# CONFIG_TABLET_USB_GTCO is not set
CONFIG_TABLET_USB_KBTAB=m
# CONFIG_TABLET_USB_WACOM is not set
CONFIG_INPUT_TOUCHSCREEN=y
CONFIG_TOUCHSCREEN_AD7879_I2C=m
CONFIG_TOUCHSCREEN_AD7879=m
CONFIG_TOUCHSCREEN_DA9034=y
CONFIG_TOUCHSCREEN_EETI=m
CONFIG_TOUCHSCREEN_FUJITSU=m
CONFIG_TOUCHSCREEN_GUNZE=m
CONFIG_TOUCHSCREEN_ELO=y
CONFIG_TOUCHSCREEN_WACOM_W8001=m
CONFIG_TOUCHSCREEN_MTOUCH=y
CONFIG_TOUCHSCREEN_INEXIO=y
CONFIG_TOUCHSCREEN_MK712=y
CONFIG_TOUCHSCREEN_PENMOUNT=m
# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set
CONFIG_TOUCHSCREEN_TOUCHWIN=y
CONFIG_TOUCHSCREEN_USB_COMPOSITE=y
CONFIG_TOUCHSCREEN_USB_EGALAX=y
CONFIG_TOUCHSCREEN_USB_PANJIT=y
CONFIG_TOUCHSCREEN_USB_3M=y
CONFIG_TOUCHSCREEN_USB_ITM=y
CONFIG_TOUCHSCREEN_USB_ETURBO=y
CONFIG_TOUCHSCREEN_USB_GUNZE=y
CONFIG_TOUCHSCREEN_USB_DMC_TSC10=y
CONFIG_TOUCHSCREEN_USB_IRTOUCH=y
CONFIG_TOUCHSCREEN_USB_IDEALTEK=y
CONFIG_TOUCHSCREEN_USB_GENERAL_TOUCH=y
CONFIG_TOUCHSCREEN_USB_GOTOP=y
CONFIG_TOUCHSCREEN_TOUCHIT213=y
CONFIG_TOUCHSCREEN_TSC2007=y
CONFIG_INPUT_MISC=y
CONFIG_INPUT_PCSPKR=m
CONFIG_INPUT_APANEL=m
CONFIG_INPUT_ATLAS_BTNS=m
CONFIG_INPUT_ATI_REMOTE=m
CONFIG_INPUT_ATI_REMOTE2=m
# CONFIG_INPUT_KEYSPAN_REMOTE is not set
CONFIG_INPUT_POWERMATE=y
CONFIG_INPUT_YEALINK=y
CONFIG_INPUT_CM109=y
CONFIG_INPUT_UINPUT=m
CONFIG_INPUT_PCF50633_PMU=y
#
# Hardware I/O ports
#
CONFIG_SERIO=y
CONFIG_SERIO_I8042=y
CONFIG_SERIO_SERPORT=m
CONFIG_SERIO_CT82C710=m
CONFIG_SERIO_PARKBD=m
CONFIG_SERIO_PCIPS2=y
CONFIG_SERIO_LIBPS2=y
CONFIG_SERIO_RAW=y
CONFIG_GAMEPORT=y
CONFIG_GAMEPORT_NS558=m
CONFIG_GAMEPORT_L4=m
CONFIG_GAMEPORT_EMU10K1=y
CONFIG_GAMEPORT_FM801=m
#
# Character devices
#
CONFIG_VT=y
CONFIG_CONSOLE_TRANSLATIONS=y
CONFIG_VT_CONSOLE=y
CONFIG_HW_CONSOLE=y
# CONFIG_VT_HW_CONSOLE_BINDING is not set
CONFIG_DEVKMEM=y
# CONFIG_SERIAL_NONSTANDARD is not set
CONFIG_NOZOMI=m
#
# Serial drivers
#
# CONFIG_SERIAL_8250 is not set
CONFIG_FIX_EARLYCON_MEM=y
#
# Non-8250 serial port support
#
CONFIG_SERIAL_CORE=m
CONFIG_SERIAL_JSM=m
CONFIG_UNIX98_PTYS=y
CONFIG_DEVPTS_MULTIPLE_INSTANCES=y
# CONFIG_LEGACY_PTYS is not set
# CONFIG_PRINTER is not set
CONFIG_PPDEV=m
# CONFIG_VIRTIO_CONSOLE is not set
# CONFIG_IPMI_HANDLER is not set
# CONFIG_HW_RANDOM is not set
# CONFIG_NVRAM is not set
CONFIG_R3964=y
# CONFIG_APPLICOM is not set
# CONFIG_MWAVE is not set
CONFIG_PC8736x_GPIO=y
CONFIG_NSC_GPIO=y
CONFIG_RAW_DRIVER=y
CONFIG_MAX_RAW_DEVS=256
CONFIG_HPET=y
# CONFIG_HPET_MMAP is not set
CONFIG_HANGCHECK_TIMER=m
CONFIG_TCG_TPM=y
CONFIG_TCG_TIS=y
CONFIG_TCG_NSC=m
CONFIG_TCG_ATMEL=m
CONFIG_TCG_INFINEON=y
# CONFIG_TELCLOCK is not set
CONFIG_DEVPORT=y
CONFIG_I2C=y
CONFIG_I2C_BOARDINFO=y
CONFIG_I2C_CHARDEV=y
CONFIG_I2C_HELPER_AUTO=y
CONFIG_I2C_ALGOBIT=y
CONFIG_I2C_ALGOPCA=m
#
# I2C Hardware Bus support
#
#
# PC SMBus host controller drivers
#
CONFIG_I2C_ALI1535=m
# CONFIG_I2C_ALI1563 is not set
# CONFIG_I2C_ALI15X3 is not set
CONFIG_I2C_AMD756=y
# CONFIG_I2C_AMD756_S4882 is not set
# CONFIG_I2C_AMD8111 is not set
CONFIG_I2C_I801=m
# CONFIG_I2C_ISCH is not set
# CONFIG_I2C_PIIX4 is not set
CONFIG_I2C_NFORCE2=y
CONFIG_I2C_NFORCE2_S4985=y
CONFIG_I2C_SIS5595=m
CONFIG_I2C_SIS630=m
# CONFIG_I2C_SIS96X is not set
CONFIG_I2C_VIA=m
CONFIG_I2C_VIAPRO=y
#
# I2C system bus drivers (mostly embedded / system-on-chip)
#
CONFIG_I2C_OCORES=m
CONFIG_I2C_SIMTEC=m
#
# External I2C/SMBus adapter drivers
#
# CONFIG_I2C_PARPORT is not set
CONFIG_I2C_PARPORT_LIGHT=y
# CONFIG_I2C_TAOS_EVM is not set
# CONFIG_I2C_TINY_USB is not set
#
# Graphics adapter I2C/DDC channel drivers
#
CONFIG_I2C_VOODOO3=m
#
# Other I2C/SMBus bus drivers
#
CONFIG_I2C_PCA_PLATFORM=m
# CONFIG_I2C_STUB is not set
#
# Miscellaneous I2C Chip support
#
CONFIG_DS1682=m
# CONFIG_SENSORS_PCF8574 is not set
CONFIG_PCF8575=y
CONFIG_SENSORS_PCA9539=m
CONFIG_SENSORS_TSL2550=y
CONFIG_I2C_DEBUG_CORE=y
CONFIG_I2C_DEBUG_ALGO=y
CONFIG_I2C_DEBUG_BUS=y
# CONFIG_I2C_DEBUG_CHIP is not set
# CONFIG_SPI is not set
CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
# CONFIG_GPIOLIB is not set
CONFIG_W1=m
# CONFIG_W1_CON is not set
#
# 1-wire Bus Masters
#
CONFIG_W1_MASTER_MATROX=m
CONFIG_W1_MASTER_DS2490=m
CONFIG_W1_MASTER_DS2482=m
#
# 1-wire Slaves
#
CONFIG_W1_SLAVE_THERM=m
CONFIG_W1_SLAVE_SMEM=m
CONFIG_W1_SLAVE_DS2431=m
# CONFIG_W1_SLAVE_DS2433 is not set
CONFIG_W1_SLAVE_DS2760=m
CONFIG_W1_SLAVE_BQ27000=m
CONFIG_POWER_SUPPLY=y
# CONFIG_POWER_SUPPLY_DEBUG is not set
CONFIG_PDA_POWER=y
CONFIG_BATTERY_DS2760=m
# CONFIG_BATTERY_BQ27x00 is not set
CONFIG_BATTERY_DA9030=m
# CONFIG_CHARGER_PCF50633 is not set
CONFIG_HWMON=y
CONFIG_HWMON_VID=y
CONFIG_SENSORS_ABITUGURU=y
# CONFIG_SENSORS_ABITUGURU3 is not set
# CONFIG_SENSORS_AD7414 is not set
CONFIG_SENSORS_AD7418=m
CONFIG_SENSORS_ADM1021=m
# CONFIG_SENSORS_ADM1025 is not set
CONFIG_SENSORS_ADM1026=m
CONFIG_SENSORS_ADM1029=m
CONFIG_SENSORS_ADM1031=m
# CONFIG_SENSORS_ADM9240 is not set
# CONFIG_SENSORS_ADT7462 is not set
# CONFIG_SENSORS_ADT7470 is not set
CONFIG_SENSORS_ADT7473=m
CONFIG_SENSORS_ADT7475=y
CONFIG_SENSORS_K8TEMP=m
# CONFIG_SENSORS_ASB100 is not set
CONFIG_SENSORS_ATK0110=m
CONFIG_SENSORS_ATXP1=m
CONFIG_SENSORS_DS1621=m
CONFIG_SENSORS_I5K_AMB=m
CONFIG_SENSORS_F71805F=m
CONFIG_SENSORS_F71882FG=m
# CONFIG_SENSORS_F75375S is not set
# CONFIG_SENSORS_FSCHER is not set
CONFIG_SENSORS_FSCPOS=m
# CONFIG_SENSORS_FSCHMD is not set
CONFIG_SENSORS_G760A=y
# CONFIG_SENSORS_GL518SM is not set
# CONFIG_SENSORS_GL520SM is not set
# CONFIG_SENSORS_CORETEMP is not set
CONFIG_SENSORS_IT87=m
CONFIG_SENSORS_LM63=m
CONFIG_SENSORS_LM75=m
CONFIG_SENSORS_LM77=y
# CONFIG_SENSORS_LM78 is not set
CONFIG_SENSORS_LM80=y
CONFIG_SENSORS_LM83=y
CONFIG_SENSORS_LM85=m
CONFIG_SENSORS_LM87=m
CONFIG_SENSORS_LM90=m
CONFIG_SENSORS_LM92=m
CONFIG_SENSORS_LM93=m
CONFIG_SENSORS_LTC4215=y
CONFIG_SENSORS_LTC4245=y
# CONFIG_SENSORS_LM95241 is not set
CONFIG_SENSORS_MAX1619=m
CONFIG_SENSORS_MAX6650=y
# CONFIG_SENSORS_PC87360 is not set
# CONFIG_SENSORS_PC87427 is not set
CONFIG_SENSORS_PCF8591=y
# CONFIG_SENSORS_SIS5595 is not set
# CONFIG_SENSORS_DME1737 is not set
CONFIG_SENSORS_SMSC47M1=y
# CONFIG_SENSORS_SMSC47M192 is not set
# CONFIG_SENSORS_SMSC47B397 is not set
CONFIG_SENSORS_ADS7828=m
CONFIG_SENSORS_THMC50=y
CONFIG_SENSORS_TMP401=m
# CONFIG_SENSORS_VIA686A is not set
CONFIG_SENSORS_VT1211=m
CONFIG_SENSORS_VT8231=y
CONFIG_SENSORS_W83781D=m
CONFIG_SENSORS_W83791D=y
CONFIG_SENSORS_W83792D=y
CONFIG_SENSORS_W83793=y
CONFIG_SENSORS_W83L785TS=m
CONFIG_SENSORS_W83L786NG=y
CONFIG_SENSORS_W83627HF=y
# CONFIG_SENSORS_W83627EHF is not set
CONFIG_SENSORS_HDAPS=m
# CONFIG_SENSORS_LIS3LV02D is not set
CONFIG_SENSORS_APPLESMC=m
CONFIG_HWMON_DEBUG_CHIP=y
CONFIG_THERMAL=y
CONFIG_THERMAL_HWMON=y
CONFIG_WATCHDOG=y
CONFIG_WATCHDOG_NOWAYOUT=y
#
# Watchdog Device Drivers
#
CONFIG_SOFT_WATCHDOG=m
# CONFIG_ACQUIRE_WDT is not set
CONFIG_ADVANTECH_WDT=m
# CONFIG_ALIM1535_WDT is not set
# CONFIG_ALIM7101_WDT is not set
# CONFIG_SC520_WDT is not set
CONFIG_EUROTECH_WDT=y
CONFIG_IB700_WDT=m
CONFIG_IBMASR=y
# CONFIG_WAFER_WDT is not set
CONFIG_I6300ESB_WDT=m
CONFIG_ITCO_WDT=y
# CONFIG_ITCO_VENDOR_SUPPORT is not set
CONFIG_IT8712F_WDT=y
# CONFIG_IT87_WDT is not set
# CONFIG_HP_WATCHDOG is not set
CONFIG_SC1200_WDT=y
CONFIG_PC87413_WDT=m
CONFIG_60XX_WDT=m
CONFIG_SBC8360_WDT=y
CONFIG_CPU5_WDT=m
CONFIG_SMSC_SCH311X_WDT=m
# CONFIG_SMSC37B787_WDT is not set
CONFIG_W83627HF_WDT=y
CONFIG_W83697HF_WDT=y
CONFIG_W83697UG_WDT=y
CONFIG_W83877F_WDT=m
CONFIG_W83977F_WDT=y
CONFIG_MACHZ_WDT=y
CONFIG_SBC_EPX_C3_WATCHDOG=y
#
# PCI-based Watchdog Cards
#
CONFIG_PCIPCWATCHDOG=y
# CONFIG_WDTPCI is not set
#
# USB-based Watchdog Cards
#
# CONFIG_USBPCWATCHDOG is not set
CONFIG_SSB_POSSIBLE=y
#
# Sonics Silicon Backplane
#
CONFIG_SSB=y
CONFIG_SSB_SPROM=y
CONFIG_SSB_PCIHOST_POSSIBLE=y
CONFIG_SSB_PCIHOST=y
# CONFIG_SSB_B43_PCI_BRIDGE is not set
# CONFIG_SSB_DEBUG is not set
CONFIG_SSB_DRIVER_PCICORE_POSSIBLE=y
CONFIG_SSB_DRIVER_PCICORE=y
#
# Multifunction device drivers
#
CONFIG_MFD_CORE=m
# CONFIG_MFD_SM501 is not set
# CONFIG_HTC_PASIC3 is not set
# CONFIG_TWL4030_CORE is not set
# CONFIG_MFD_TMIO is not set
CONFIG_PMIC_DA903X=y
CONFIG_MFD_WM8400=m
# CONFIG_MFD_WM8350_I2C is not set
CONFIG_MFD_PCF50633=y
# CONFIG_PCF50633_ADC is not set
CONFIG_PCF50633_GPIO=m
CONFIG_AB3100_CORE=m
# CONFIG_REGULATOR is not set
#
# Multimedia devices
#
#
# Multimedia core support
#
CONFIG_VIDEO_DEV=y
CONFIG_VIDEO_V4L2_COMMON=y
CONFIG_VIDEO_ALLOW_V4L1=y
CONFIG_VIDEO_V4L1_COMPAT=y
CONFIG_DVB_CORE=y
CONFIG_VIDEO_MEDIA=y
#
# Multimedia drivers
#
CONFIG_VIDEO_SAA7146=y
CONFIG_VIDEO_SAA7146_VV=y
CONFIG_MEDIA_ATTACH=y
CONFIG_MEDIA_TUNER=y
CONFIG_MEDIA_TUNER_CUSTOMISE=y
CONFIG_MEDIA_TUNER_SIMPLE=y
# CONFIG_MEDIA_TUNER_TDA8290 is not set
# CONFIG_MEDIA_TUNER_TDA827X is not set
CONFIG_MEDIA_TUNER_TDA18271=y
CONFIG_MEDIA_TUNER_TDA9887=y
CONFIG_MEDIA_TUNER_TEA5761=m
CONFIG_MEDIA_TUNER_TEA5767=m
CONFIG_MEDIA_TUNER_MT20XX=y
CONFIG_MEDIA_TUNER_MT2060=y
# CONFIG_MEDIA_TUNER_MT2266 is not set
# CONFIG_MEDIA_TUNER_MT2131 is not set
CONFIG_MEDIA_TUNER_QT1010=m
# CONFIG_MEDIA_TUNER_XC2028 is not set
CONFIG_MEDIA_TUNER_XC5000=m
CONFIG_MEDIA_TUNER_MXL5005S=m
# CONFIG_MEDIA_TUNER_MXL5007T is not set
CONFIG_MEDIA_TUNER_MC44S803=m
CONFIG_VIDEO_V4L2=y
CONFIG_VIDEO_V4L1=y
CONFIG_VIDEOBUF_GEN=y
CONFIG_VIDEOBUF_DMA_SG=y
CONFIG_VIDEOBUF_VMALLOC=y
CONFIG_VIDEOBUF_DVB=y
CONFIG_VIDEO_BTCX=m
CONFIG_VIDEO_IR=y
CONFIG_VIDEO_TVEEPROM=y
CONFIG_VIDEO_TUNER=y
CONFIG_VIDEO_CAPTURE_DRIVERS=y
# CONFIG_VIDEO_ADV_DEBUG is not set
# CONFIG_VIDEO_FIXED_MINOR_RANGES is not set
CONFIG_VIDEO_HELPER_CHIPS_AUTO=y
CONFIG_VIDEO_IR_I2C=y
CONFIG_VIDEO_TVAUDIO=m
CONFIG_VIDEO_TDA7432=m
CONFIG_VIDEO_MSP3400=y
CONFIG_VIDEO_CS5345=y
CONFIG_VIDEO_CS53L32A=m
CONFIG_VIDEO_M52790=m
CONFIG_VIDEO_WM8775=m
CONFIG_VIDEO_WM8739=m
CONFIG_VIDEO_VP27SMPX=m
CONFIG_VIDEO_SAA6588=y
CONFIG_VIDEO_SAA711X=y
CONFIG_VIDEO_SAA717X=m
CONFIG_VIDEO_TVP5150=y
CONFIG_VIDEO_CX25840=m
CONFIG_VIDEO_CX2341X=y
CONFIG_VIDEO_SAA7127=m
CONFIG_VIDEO_UPD64031A=m
CONFIG_VIDEO_UPD64083=m
CONFIG_VIDEO_VIVI=y
CONFIG_VIDEO_BT848=m
# CONFIG_VIDEO_BT848_DVB is not set
CONFIG_VIDEO_BWQCAM=m
# CONFIG_VIDEO_CQCAM is not set
# CONFIG_VIDEO_CPIA is not set
# CONFIG_VIDEO_CPIA2 is not set
CONFIG_VIDEO_SAA5246A=m
CONFIG_VIDEO_SAA5249=m
# CONFIG_VIDEO_STRADIS is not set
# CONFIG_VIDEO_ZORAN is not set
CONFIG_VIDEO_SAA7134=y
CONFIG_VIDEO_SAA7134_DVB=y
# CONFIG_VIDEO_MXB is not set
CONFIG_VIDEO_HEXIUM_ORION=y
CONFIG_VIDEO_HEXIUM_GEMINI=y
CONFIG_VIDEO_CX88=m
# CONFIG_VIDEO_CX88_BLACKBIRD is not set
CONFIG_VIDEO_CX88_DVB=m
CONFIG_VIDEO_CX88_MPEG=m
CONFIG_VIDEO_CX88_VP3054=m
# CONFIG_VIDEO_CX23885 is not set
CONFIG_VIDEO_AU0828=m
CONFIG_VIDEO_IVTV=m
CONFIG_VIDEO_CX18=y
# CONFIG_VIDEO_CAFE_CCIC is not set
CONFIG_SOC_CAMERA=y
CONFIG_SOC_CAMERA_MT9M001=y
# CONFIG_SOC_CAMERA_MT9M111 is not set
CONFIG_SOC_CAMERA_MT9T031=m
# CONFIG_SOC_CAMERA_MT9V022 is not set
CONFIG_SOC_CAMERA_TW9910=m
CONFIG_SOC_CAMERA_PLATFORM=y
# CONFIG_SOC_CAMERA_OV772X is not set
CONFIG_V4L_USB_DRIVERS=y
# CONFIG_USB_VIDEO_CLASS is not set
# CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV is not set
CONFIG_USB_GSPCA=m
# CONFIG_USB_M5602 is not set
CONFIG_USB_STV06XX=m
CONFIG_USB_GSPCA_CONEX=m
CONFIG_USB_GSPCA_ETOMS=m
CONFIG_USB_GSPCA_FINEPIX=m
CONFIG_USB_GSPCA_MARS=m
# CONFIG_USB_GSPCA_MR97310A is not set
CONFIG_USB_GSPCA_OV519=m
CONFIG_USB_GSPCA_OV534=m
CONFIG_USB_GSPCA_PAC207=m
CONFIG_USB_GSPCA_PAC7311=m
CONFIG_USB_GSPCA_SONIXB=m
CONFIG_USB_GSPCA_SONIXJ=m
CONFIG_USB_GSPCA_SPCA500=m
CONFIG_USB_GSPCA_SPCA501=m
CONFIG_USB_GSPCA_SPCA505=m
CONFIG_USB_GSPCA_SPCA506=m
# CONFIG_USB_GSPCA_SPCA508 is not set
CONFIG_USB_GSPCA_SPCA561=m
# CONFIG_USB_GSPCA_SQ905 is not set
CONFIG_USB_GSPCA_SQ905C=m
CONFIG_USB_GSPCA_STK014=m
# CONFIG_USB_GSPCA_SUNPLUS is not set
CONFIG_USB_GSPCA_T613=m
# CONFIG_USB_GSPCA_TV8532 is not set
# CONFIG_USB_GSPCA_VC032X is not set
# CONFIG_USB_GSPCA_ZC3XX is not set
# CONFIG_VIDEO_PVRUSB2 is not set
CONFIG_VIDEO_HDPVR=y
CONFIG_VIDEO_EM28XX=y
CONFIG_VIDEO_EM28XX_DVB=m
CONFIG_VIDEO_CX231XX=m
CONFIG_VIDEO_CX231XX_DVB=m
CONFIG_VIDEO_USBVISION=m
CONFIG_VIDEO_USBVIDEO=y
CONFIG_USB_VICAM=y
CONFIG_USB_IBMCAM=m
# CONFIG_USB_KONICAWC is not set
CONFIG_USB_QUICKCAM_MESSENGER=y
CONFIG_USB_ET61X251=m
# CONFIG_VIDEO_OVCAMCHIP is not set
CONFIG_USB_OV511=m
CONFIG_USB_SE401=y
# CONFIG_USB_SN9C102 is not set
CONFIG_USB_STV680=y
CONFIG_USB_ZC0301=m
CONFIG_USB_PWC=y
CONFIG_USB_PWC_DEBUG=y
# CONFIG_USB_PWC_INPUT_EVDEV is not set
CONFIG_USB_ZR364XX=y
CONFIG_USB_STKWEBCAM=m
CONFIG_USB_S2255=y
CONFIG_RADIO_ADAPTERS=y
CONFIG_RADIO_GEMTEK_PCI=m
CONFIG_RADIO_MAXIRADIO=y
CONFIG_RADIO_MAESTRO=y
# CONFIG_USB_DSBR is not set
CONFIG_USB_SI470X=y
# CONFIG_USB_MR800 is not set
# CONFIG_RADIO_TEA5764 is not set
# CONFIG_DVB_DYNAMIC_MINORS is not set
CONFIG_DVB_CAPTURE_DRIVERS=y
#
# Supported SAA7146 based PCI Adapters
#
CONFIG_TTPCI_EEPROM=m
# CONFIG_DVB_AV7110 is not set
CONFIG_DVB_BUDGET_CORE=m
# CONFIG_DVB_BUDGET is not set
# CONFIG_DVB_BUDGET_CI is not set
CONFIG_DVB_BUDGET_AV=m
#
# Supported USB Adapters
#
# CONFIG_DVB_USB is not set
CONFIG_DVB_TTUSB_BUDGET=y
CONFIG_DVB_TTUSB_DEC=m
CONFIG_DVB_SIANO_SMS1XXX=y
CONFIG_DVB_SIANO_SMS1XXX_SMS_IDS=y
#
# Supported FlexCopII (B2C2) Adapters
#
CONFIG_DVB_B2C2_FLEXCOP=m
CONFIG_DVB_B2C2_FLEXCOP_PCI=m
CONFIG_DVB_B2C2_FLEXCOP_USB=m
# CONFIG_DVB_B2C2_FLEXCOP_DEBUG is not set
#
# Supported BT878 Adapters
#
# CONFIG_DVB_BT8XX is not set
#
# Supported Pluto2 Adapters
#
CONFIG_DVB_PLUTO2=y
#
# Supported SDMC DM1105 Adapters
#
# CONFIG_DVB_DM1105 is not set
#
# Supported FireWire (IEEE 1394) Adapters
#
CONFIG_DVB_FIREDTV=y
CONFIG_DVB_FIREDTV_IEEE1394=y
CONFIG_DVB_FIREDTV_INPUT=y
#
# Supported DVB Frontends
#
CONFIG_DVB_FE_CUSTOMISE=y
#
# Customise DVB Frontends
#
#
# Multistandard (satellite) frontends
#
CONFIG_DVB_STB0899=m
CONFIG_DVB_STB6100=y
CONFIG_DVB_STV090x=m
CONFIG_DVB_STV6110x=m
#
# DVB-S (satellite) frontends
#
# CONFIG_DVB_CX24110 is not set
# CONFIG_DVB_CX24123 is not set
CONFIG_DVB_MT312=m
# CONFIG_DVB_ZL10036 is not set
CONFIG_DVB_S5H1420=y
CONFIG_DVB_STV0288=y
CONFIG_DVB_STB6000=m
# CONFIG_DVB_STV0299 is not set
CONFIG_DVB_STV6110=m
CONFIG_DVB_STV0900=m
CONFIG_DVB_TDA8083=m
CONFIG_DVB_TDA10086=y
CONFIG_DVB_TDA8261=y
CONFIG_DVB_VES1X93=y
CONFIG_DVB_TUNER_ITD1000=m
CONFIG_DVB_TUNER_CX24113=y
# CONFIG_DVB_TDA826X is not set
# CONFIG_DVB_TUA6100 is not set
# CONFIG_DVB_CX24116 is not set
# CONFIG_DVB_SI21XX is not set
#
# DVB-T (terrestrial) frontends
#
# CONFIG_DVB_SP8870 is not set
CONFIG_DVB_SP887X=y
# CONFIG_DVB_CX22700 is not set
CONFIG_DVB_CX22702=y
CONFIG_DVB_DRX397XD=m
CONFIG_DVB_L64781=m
CONFIG_DVB_TDA1004X=y
CONFIG_DVB_NXT6000=y
CONFIG_DVB_MT352=y
CONFIG_DVB_ZL10353=m
CONFIG_DVB_DIB3000MB=y
# CONFIG_DVB_DIB3000MC is not set
CONFIG_DVB_DIB7000M=m
# CONFIG_DVB_DIB7000P is not set
CONFIG_DVB_TDA10048=m
# CONFIG_DVB_AF9013 is not set
#
# DVB-C (cable) frontends
#
# CONFIG_DVB_VES1820 is not set
# CONFIG_DVB_TDA10021 is not set
CONFIG_DVB_TDA10023=y
CONFIG_DVB_STV0297=m
#
# ATSC (North American/Korean Terrestrial/Cable DTV) frontends
#
CONFIG_DVB_NXT200X=y
# CONFIG_DVB_OR51211 is not set
CONFIG_DVB_OR51132=y
# CONFIG_DVB_BCM3510 is not set
CONFIG_DVB_LGDT330X=y
CONFIG_DVB_LGDT3304=y
# CONFIG_DVB_LGDT3305 is not set
CONFIG_DVB_S5H1409=m
# CONFIG_DVB_AU8522 is not set
CONFIG_DVB_S5H1411=m
#
# ISDB-T (terrestrial) frontends
#
CONFIG_DVB_S921=y
#
# Digital terrestrial only tuners/PLL
#
CONFIG_DVB_PLL=y
# CONFIG_DVB_TUNER_DIB0070 is not set
#
# SEC control devices for DVB-S
#
CONFIG_DVB_LNBP21=y
CONFIG_DVB_ISL6405=y
# CONFIG_DVB_ISL6421 is not set
CONFIG_DVB_ISL6423=y
CONFIG_DVB_LGS8GL5=y
# CONFIG_DVB_LGS8GXX is not set
#
# Tools to develop new frontends
#
CONFIG_DVB_DUMMY_FE=m
CONFIG_DAB=y
CONFIG_USB_DABUSB=m
#
# Graphics support
#
CONFIG_AGP=y
CONFIG_AGP_AMD64=y
CONFIG_AGP_INTEL=y
CONFIG_AGP_SIS=y
CONFIG_AGP_VIA=m
# CONFIG_DRM is not set
# CONFIG_VGASTATE is not set
CONFIG_VIDEO_OUTPUT_CONTROL=y
# CONFIG_FB is not set
CONFIG_BACKLIGHT_LCD_SUPPORT=y
CONFIG_LCD_CLASS_DEVICE=y
# CONFIG_LCD_ILI9320 is not set
# CONFIG_LCD_PLATFORM is not set
CONFIG_BACKLIGHT_CLASS_DEVICE=y
# CONFIG_BACKLIGHT_GENERIC is not set
CONFIG_BACKLIGHT_PROGEAR=m
CONFIG_BACKLIGHT_DA903X=y
CONFIG_BACKLIGHT_MBP_NVIDIA=m
CONFIG_BACKLIGHT_SAHARA=m
#
# Display device support
#
CONFIG_DISPLAY_SUPPORT=y
#
# Display hardware drivers
#
#
# Console display driver support
#
CONFIG_VGA_CONSOLE=y
# CONFIG_VGACON_SOFT_SCROLLBACK is not set
CONFIG_DUMMY_CONSOLE=y
# CONFIG_SOUND is not set
# CONFIG_HID_SUPPORT is not set
CONFIG_USB_SUPPORT=y
CONFIG_USB_ARCH_HAS_HCD=y
CONFIG_USB_ARCH_HAS_OHCI=y
CONFIG_USB_ARCH_HAS_EHCI=y
CONFIG_USB=y
CONFIG_USB_DEBUG=y
CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
#
# Miscellaneous USB options
#
# CONFIG_USB_DEVICE_CLASS is not set
CONFIG_USB_DYNAMIC_MINORS=y
CONFIG_USB_SUSPEND=y
# CONFIG_USB_OTG is not set
# CONFIG_USB_MON is not set
CONFIG_USB_WUSB=y
CONFIG_USB_WUSB_CBAF=y
CONFIG_USB_WUSB_CBAF_DEBUG=y
#
# USB Host Controller Drivers
#
CONFIG_USB_C67X00_HCD=y
CONFIG_USB_XHCI_HCD=y
CONFIG_USB_XHCI_HCD_DEBUGGING=y
# CONFIG_USB_EHCI_HCD is not set
# CONFIG_USB_OXU210HP_HCD is not set
CONFIG_USB_ISP116X_HCD=m
CONFIG_USB_ISP1760_HCD=y
CONFIG_USB_OHCI_HCD=m
CONFIG_USB_OHCI_HCD_SSB=y
# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
CONFIG_USB_OHCI_LITTLE_ENDIAN=y
CONFIG_USB_UHCI_HCD=m
# CONFIG_USB_U132_HCD is not set
CONFIG_USB_SL811_HCD=m
CONFIG_USB_R8A66597_HCD=m
# CONFIG_USB_WHCI_HCD is not set
CONFIG_USB_HWA_HCD=y
# CONFIG_USB_GADGET_MUSB_HDRC is not set
#
# USB Device Class drivers
#
CONFIG_USB_ACM=y
# CONFIG_USB_PRINTER is not set
# CONFIG_USB_WDM is not set
CONFIG_USB_TMC=m
#
# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
#
#
# also be needed; see USB_STORAGE Help for more info
#
# CONFIG_USB_STORAGE is not set
CONFIG_USB_LIBUSUAL=y
#
# USB Imaging devices
#
# CONFIG_USB_MDC800 is not set
CONFIG_USB_MICROTEK=m
#
# USB port drivers
#
CONFIG_USB_USS720=m
CONFIG_USB_SERIAL=y
# CONFIG_USB_SERIAL_CONSOLE is not set
CONFIG_USB_EZUSB=y
CONFIG_USB_SERIAL_GENERIC=y
CONFIG_USB_SERIAL_AIRCABLE=m
CONFIG_USB_SERIAL_ARK3116=y
# CONFIG_USB_SERIAL_BELKIN is not set
CONFIG_USB_SERIAL_CH341=y
CONFIG_USB_SERIAL_WHITEHEAT=m
# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
# CONFIG_USB_SERIAL_CP210X is not set
# CONFIG_USB_SERIAL_CYPRESS_M8 is not set
CONFIG_USB_SERIAL_EMPEG=m
# CONFIG_USB_SERIAL_FTDI_SIO is not set
# CONFIG_USB_SERIAL_FUNSOFT is not set
CONFIG_USB_SERIAL_VISOR=m
# CONFIG_USB_SERIAL_IPAQ is not set
CONFIG_USB_SERIAL_IR=y
# CONFIG_USB_SERIAL_EDGEPORT is not set
CONFIG_USB_SERIAL_EDGEPORT_TI=y
CONFIG_USB_SERIAL_GARMIN=m
# CONFIG_USB_SERIAL_IPW is not set
# CONFIG_USB_SERIAL_IUU is not set
CONFIG_USB_SERIAL_KEYSPAN_PDA=y
CONFIG_USB_SERIAL_KEYSPAN=m
# CONFIG_USB_SERIAL_KEYSPAN_MPR is not set
CONFIG_USB_SERIAL_KEYSPAN_USA28=y
# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set
CONFIG_USB_SERIAL_KEYSPAN_USA28XA=y
CONFIG_USB_SERIAL_KEYSPAN_USA28XB=y
CONFIG_USB_SERIAL_KEYSPAN_USA19=y
CONFIG_USB_SERIAL_KEYSPAN_USA18X=y
CONFIG_USB_SERIAL_KEYSPAN_USA19W=y
CONFIG_USB_SERIAL_KEYSPAN_USA19QW=y
CONFIG_USB_SERIAL_KEYSPAN_USA19QI=y
CONFIG_USB_SERIAL_KEYSPAN_USA49W=y
CONFIG_USB_SERIAL_KEYSPAN_USA49WLC=y
CONFIG_USB_SERIAL_KLSI=m
CONFIG_USB_SERIAL_KOBIL_SCT=m
CONFIG_USB_SERIAL_MCT_U232=y
# CONFIG_USB_SERIAL_MOS7720 is not set
# CONFIG_USB_SERIAL_MOS7840 is not set
CONFIG_USB_SERIAL_MOTOROLA=m
# CONFIG_USB_SERIAL_NAVMAN is not set
CONFIG_USB_SERIAL_PL2303=m
CONFIG_USB_SERIAL_OTI6858=y
CONFIG_USB_SERIAL_QUALCOMM=m
# CONFIG_USB_SERIAL_SPCP8X5 is not set
CONFIG_USB_SERIAL_HP4X=y
CONFIG_USB_SERIAL_SAFE=y
CONFIG_USB_SERIAL_SAFE_PADDED=y
CONFIG_USB_SERIAL_SIEMENS_MPI=y
# CONFIG_USB_SERIAL_SIERRAWIRELESS is not set
CONFIG_USB_SERIAL_SYMBOL=m
CONFIG_USB_SERIAL_TI=m
CONFIG_USB_SERIAL_CYBERJACK=y
CONFIG_USB_SERIAL_XIRCOM=m
CONFIG_USB_SERIAL_OPTION=m
CONFIG_USB_SERIAL_OMNINET=y
# CONFIG_USB_SERIAL_OPTICON is not set
CONFIG_USB_SERIAL_DEBUG=y
#
# USB Miscellaneous drivers
#
CONFIG_USB_EMI62=y
# CONFIG_USB_EMI26 is not set
CONFIG_USB_ADUTUX=y
CONFIG_USB_SEVSEG=m
# CONFIG_USB_RIO500 is not set
CONFIG_USB_LEGOTOWER=y
CONFIG_USB_LCD=m
# CONFIG_USB_BERRY_CHARGE is not set
CONFIG_USB_LED=y
CONFIG_USB_CYPRESS_CY7C63=y
CONFIG_USB_CYTHERM=y
# CONFIG_USB_IDMOUSE is not set
CONFIG_USB_FTDI_ELAN=y
CONFIG_USB_APPLEDISPLAY=y
CONFIG_USB_LD=m
# CONFIG_USB_TRANCEVIBRATOR is not set
CONFIG_USB_IOWARRIOR=y
CONFIG_USB_ISIGHTFW=m
CONFIG_USB_VST=m
CONFIG_USB_GADGET=m
CONFIG_USB_GADGET_DEBUG=y
CONFIG_USB_GADGET_DEBUG_FILES=y
CONFIG_USB_GADGET_DEBUG_FS=y
CONFIG_USB_GADGET_VBUS_DRAW=2
CONFIG_USB_GADGET_SELECTED=y
# CONFIG_USB_GADGET_AT91 is not set
# CONFIG_USB_GADGET_ATMEL_USBA is not set
# CONFIG_USB_GADGET_FSL_USB2 is not set
# CONFIG_USB_GADGET_LH7A40X is not set
# CONFIG_USB_GADGET_OMAP is not set
# CONFIG_USB_GADGET_PXA25X is not set
# CONFIG_USB_GADGET_PXA27X is not set
# CONFIG_USB_GADGET_S3C_HSOTG is not set
# CONFIG_USB_GADGET_S3C2410 is not set
# CONFIG_USB_GADGET_IMX is not set
CONFIG_USB_GADGET_M66592=y
CONFIG_USB_M66592=m
# CONFIG_USB_GADGET_AMD5536UDC is not set
# CONFIG_USB_GADGET_FSL_QE is not set
# CONFIG_USB_GADGET_CI13XXX is not set
# CONFIG_USB_GADGET_NET2280 is not set
# CONFIG_USB_GADGET_GOKU is not set
# CONFIG_USB_GADGET_DUMMY_HCD is not set
CONFIG_USB_GADGET_DUALSPEED=y
# CONFIG_USB_ZERO is not set
CONFIG_USB_ETH=m
CONFIG_USB_ETH_RNDIS=y
CONFIG_USB_GADGETFS=m
CONFIG_USB_FILE_STORAGE=m
CONFIG_USB_FILE_STORAGE_TEST=y
# CONFIG_USB_G_SERIAL is not set
# CONFIG_USB_MIDI_GADGET is not set
CONFIG_USB_G_PRINTER=m
# CONFIG_USB_CDC_COMPOSITE is not set
#
# OTG and related infrastructure
#
CONFIG_USB_OTG_UTILS=y
CONFIG_NOP_USB_XCEIV=m
CONFIG_UWB=y
CONFIG_UWB_HWA=y
CONFIG_UWB_WHCI=y
CONFIG_UWB_WLP=m
# CONFIG_UWB_I1480U is not set
CONFIG_MMC=y
# CONFIG_MMC_DEBUG is not set
CONFIG_MMC_UNSAFE_RESUME=y
#
# MMC/SD/SDIO Card Drivers
#
CONFIG_MMC_BLOCK=m
CONFIG_MMC_BLOCK_BOUNCE=y
CONFIG_SDIO_UART=m
CONFIG_MMC_TEST=m
#
# MMC/SD/SDIO Host Controller Drivers
#
CONFIG_MMC_SDHCI=m
# CONFIG_MMC_SDHCI_PCI is not set
# CONFIG_MMC_WBSD is not set
CONFIG_MMC_TIFM_SD=m
CONFIG_MEMSTICK=m
CONFIG_MEMSTICK_DEBUG=y
#
# MemoryStick drivers
#
CONFIG_MEMSTICK_UNSAFE_RESUME=y
CONFIG_MSPRO_BLOCK=m
#
# MemoryStick Host Controller Drivers
#
CONFIG_MEMSTICK_TIFM_MS=m
# CONFIG_MEMSTICK_JMICRON_38X is not set
CONFIG_NEW_LEDS=y
CONFIG_LEDS_CLASS=m
#
# LED drivers
#
# CONFIG_LEDS_ALIX2 is not set
CONFIG_LEDS_PCA9532=m
CONFIG_LEDS_LP5521=m
CONFIG_LEDS_CLEVO_MAIL=m
CONFIG_LEDS_PCA955X=m
# CONFIG_LEDS_DA903X is not set
CONFIG_LEDS_BD2802=m
#
# LED Triggers
#
# CONFIG_LEDS_TRIGGERS is not set
CONFIG_ACCESSIBILITY=y
# CONFIG_INFINIBAND is not set
# CONFIG_EDAC is not set
CONFIG_RTC_LIB=y
CONFIG_RTC_CLASS=y
CONFIG_RTC_HCTOSYS=y
CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
# CONFIG_RTC_DEBUG is not set
#
# RTC interfaces
#
CONFIG_RTC_INTF_SYSFS=y
CONFIG_RTC_INTF_PROC=y
CONFIG_RTC_INTF_DEV=y
CONFIG_RTC_INTF_DEV_UIE_EMUL=y
CONFIG_RTC_DRV_TEST=y
#
# I2C RTC drivers
#
CONFIG_RTC_DRV_DS1307=y
# CONFIG_RTC_DRV_DS1374 is not set
# CONFIG_RTC_DRV_DS1672 is not set
# CONFIG_RTC_DRV_MAX6900 is not set
CONFIG_RTC_DRV_RS5C372=m
# CONFIG_RTC_DRV_ISL1208 is not set
# CONFIG_RTC_DRV_X1205 is not set
CONFIG_RTC_DRV_PCF8563=y
# CONFIG_RTC_DRV_PCF8583 is not set
CONFIG_RTC_DRV_M41T80=y
# CONFIG_RTC_DRV_M41T80_WDT is not set
CONFIG_RTC_DRV_S35390A=m
CONFIG_RTC_DRV_FM3130=y
# CONFIG_RTC_DRV_RX8581 is not set
#
# SPI RTC drivers
#
#
# Platform RTC drivers
#
# CONFIG_RTC_DRV_CMOS is not set
# CONFIG_RTC_DRV_DS1286 is not set
# CONFIG_RTC_DRV_DS1511 is not set
CONFIG_RTC_DRV_DS1553=m
# CONFIG_RTC_DRV_DS1742 is not set
# CONFIG_RTC_DRV_STK17TA8 is not set
CONFIG_RTC_DRV_M48T86=m
CONFIG_RTC_DRV_M48T35=y
CONFIG_RTC_DRV_M48T59=y
# CONFIG_RTC_DRV_MSM6242 is not set
CONFIG_RTC_DRV_BQ4802=y
CONFIG_RTC_DRV_RP5C01=m
CONFIG_RTC_DRV_V3020=y
CONFIG_RTC_DRV_PCF50633=m
#
# on-CPU RTC drivers
#
CONFIG_DMADEVICES=y
#
# DMA Devices
#
CONFIG_INTEL_IOATDMA=m
CONFIG_DMA_ENGINE=y
#
# DMA Clients
#
CONFIG_NET_DMA=y
CONFIG_ASYNC_TX_DMA=y
# CONFIG_DMATEST is not set
CONFIG_DCA=m
CONFIG_AUXDISPLAY=y
# CONFIG_KS0108 is not set
# CONFIG_UIO is not set
CONFIG_STAGING=y
# CONFIG_STAGING_EXCLUDE_BUILD is not set
# CONFIG_ET131X is not set
# CONFIG_SLICOSS is not set
CONFIG_SXG=y
# CONFIG_ME4000 is not set
CONFIG_MEILHAUS=m
CONFIG_ME0600=m
CONFIG_ME0900=m
CONFIG_ME1000=m
CONFIG_ME1400=m
# CONFIG_ME1600 is not set
CONFIG_ME4600=m
CONFIG_ME6000=m
CONFIG_ME8100=m
# CONFIG_ME8200 is not set
CONFIG_MEDUMMY=m
CONFIG_USB_IP_COMMON=y
# CONFIG_USB_IP_VHCI_HCD is not set
CONFIG_USB_IP_HOST=y
# CONFIG_ECHO is not set
CONFIG_COMEDI=m
CONFIG_COMEDI_DEBUG=y
CONFIG_COMEDI_PCI_DRIVERS=m
CONFIG_COMEDI_USB_DRIVERS=m
CONFIG_ASUS_OLED=y
CONFIG_PANEL=m
CONFIG_PANEL_PARPORT=0
CONFIG_PANEL_PROFILE=5
CONFIG_PANEL_CHANGE_MESSAGE=y
CONFIG_PANEL_BOOT_MESSAGE=""
CONFIG_ALTERA_PCIE_CHDMA=m
CONFIG_INPUT_MIMIO=m
CONFIG_TRANZPORT=m
CONFIG_EPL=y
#
# Android
#
CONFIG_ANDROID=y
# CONFIG_ANDROID_BINDER_IPC is not set
CONFIG_ANDROID_LOGGER=m
CONFIG_ANDROID_RAM_CONSOLE=y
# CONFIG_ANDROID_RAM_CONSOLE_ENABLE_VERBOSE is not set
CONFIG_ANDROID_RAM_CONSOLE_EARLY_INIT=y
CONFIG_ANDROID_RAM_CONSOLE_EARLY_ADDR=0
CONFIG_ANDROID_RAM_CONSOLE_EARLY_SIZE=0
# CONFIG_ANDROID_TIMED_OUTPUT is not set
CONFIG_ANDROID_LOW_MEMORY_KILLER=y
CONFIG_DST=y
CONFIG_DST_DEBUG=y
CONFIG_POHMELFS=m
CONFIG_POHMELFS_DEBUG=y
CONFIG_POHMELFS_CRYPTO=y
# CONFIG_USB_SERIAL_ATEN2011 is not set
CONFIG_B3DFG=m
CONFIG_IDE_PHISON=m
CONFIG_PLAN9AUTH=y
# CONFIG_HECI is not set
CONFIG_USB_SERIAL_QUATECH2=y
CONFIG_VT6655=y
CONFIG_USB_CPC=m
# CONFIG_MRST_NAND is not set
CONFIG_X86_PLATFORM_DEVICES=y
CONFIG_ACER_WMI=m
CONFIG_ASUS_LAPTOP=m
CONFIG_DELL_WMI=m
CONFIG_FUJITSU_LAPTOP=m
CONFIG_FUJITSU_LAPTOP_DEBUG=y
CONFIG_HP_WMI=m
CONFIG_MSI_LAPTOP=y
# CONFIG_PANASONIC_LAPTOP is not set
# CONFIG_COMPAL_LAPTOP is not set
# CONFIG_THINKPAD_ACPI is not set
# CONFIG_INTEL_MENLOW is not set
# CONFIG_EEEPC_LAPTOP is not set
CONFIG_ACPI_WMI=m
CONFIG_ACPI_ASUS=m
CONFIG_ACPI_TOSHIBA=m
#
# Firmware Drivers
#
CONFIG_EDD=y
CONFIG_EDD_OFF=y
CONFIG_FIRMWARE_MEMMAP=y
CONFIG_EFI_VARS=y
CONFIG_DELL_RBU=y
# CONFIG_DCDBAS is not set
CONFIG_DMIID=y
CONFIG_ISCSI_IBFT_FIND=y
CONFIG_ISCSI_IBFT=y
#
# File systems
#
# CONFIG_EXT2_FS is not set
CONFIG_EXT3_FS=m
CONFIG_EXT3_DEFAULTS_TO_ORDERED=y
CONFIG_EXT3_FS_XATTR=y
CONFIG_EXT3_FS_POSIX_ACL=y
CONFIG_EXT3_FS_SECURITY=y
CONFIG_EXT4_FS=m
CONFIG_EXT4DEV_COMPAT=y
CONFIG_EXT4_FS_XATTR=y
CONFIG_EXT4_FS_POSIX_ACL=y
# CONFIG_EXT4_FS_SECURITY is not set
CONFIG_JBD=m
# CONFIG_JBD_DEBUG is not set
CONFIG_JBD2=m
CONFIG_JBD2_DEBUG=y
CONFIG_FS_MBCACHE=m
# CONFIG_REISERFS_FS is not set
CONFIG_JFS_FS=m
CONFIG_JFS_POSIX_ACL=y
CONFIG_JFS_SECURITY=y
CONFIG_JFS_DEBUG=y
CONFIG_JFS_STATISTICS=y
CONFIG_FS_POSIX_ACL=y
CONFIG_FILE_LOCKING=y
CONFIG_XFS_FS=m
# CONFIG_XFS_QUOTA is not set
CONFIG_XFS_POSIX_ACL=y
CONFIG_XFS_RT=y
CONFIG_XFS_DEBUG=y
# CONFIG_GFS2_FS is not set
CONFIG_OCFS2_FS=m
# CONFIG_OCFS2_FS_O2CB is not set
# CONFIG_OCFS2_FS_USERSPACE_CLUSTER is not set
# CONFIG_OCFS2_FS_STATS is not set
CONFIG_OCFS2_DEBUG_MASKLOG=y
CONFIG_OCFS2_DEBUG_FS=y
CONFIG_OCFS2_FS_POSIX_ACL=y
CONFIG_BTRFS_FS=m
# CONFIG_BTRFS_FS_POSIX_ACL is not set
# CONFIG_FSNOTIFY is not set
CONFIG_INOTIFY=y
CONFIG_QUOTA=y
# CONFIG_QUOTA_NETLINK_INTERFACE is not set
CONFIG_PRINT_QUOTA_WARNING=y
CONFIG_QUOTA_TREE=y
CONFIG_QFMT_V1=m
CONFIG_QFMT_V2=y
CONFIG_QUOTACTL=y
# CONFIG_AUTOFS_FS is not set
CONFIG_AUTOFS4_FS=m
# CONFIG_FUSE_FS is not set
CONFIG_GENERIC_ACL=y
#
# Caches
#
CONFIG_FSCACHE=m
CONFIG_FSCACHE_STATS=y
CONFIG_FSCACHE_HISTOGRAM=y
CONFIG_FSCACHE_DEBUG=y
CONFIG_CACHEFILES=m
# CONFIG_CACHEFILES_DEBUG is not set
# CONFIG_CACHEFILES_HISTOGRAM is not set
#
# CD-ROM/DVD Filesystems
#
# CONFIG_ISO9660_FS is not set
CONFIG_UDF_FS=m
CONFIG_UDF_NLS=y
#
# DOS/FAT/NT Filesystems
#
CONFIG_FAT_FS=y
# CONFIG_MSDOS_FS is not set
CONFIG_VFAT_FS=y
CONFIG_FAT_DEFAULT_CODEPAGE=437
CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
# CONFIG_NTFS_FS is not set
#
# Pseudo filesystems
#
CONFIG_PROC_FS=y
CONFIG_PROC_KCORE=y
CONFIG_PROC_SYSCTL=y
CONFIG_PROC_PAGE_MONITOR=y
CONFIG_SYSFS=y
CONFIG_TMPFS=y
CONFIG_TMPFS_POSIX_ACL=y
CONFIG_HUGETLBFS=y
CONFIG_HUGETLB_PAGE=y
CONFIG_CONFIGFS_FS=y
# CONFIG_MISC_FILESYSTEMS is not set
# CONFIG_NETWORK_FILESYSTEMS is not set
CONFIG_EXPORTFS=m
#
# Partition Types
#
CONFIG_PARTITION_ADVANCED=y
CONFIG_ACORN_PARTITION=y
CONFIG_ACORN_PARTITION_CUMANA=y
# CONFIG_ACORN_PARTITION_EESOX is not set
CONFIG_ACORN_PARTITION_ICS=y
CONFIG_ACORN_PARTITION_ADFS=y
CONFIG_ACORN_PARTITION_POWERTEC=y
CONFIG_ACORN_PARTITION_RISCIX=y
CONFIG_OSF_PARTITION=y
# CONFIG_AMIGA_PARTITION is not set
CONFIG_ATARI_PARTITION=y
CONFIG_MAC_PARTITION=y
# CONFIG_MSDOS_PARTITION is not set
# CONFIG_LDM_PARTITION is not set
CONFIG_SGI_PARTITION=y
CONFIG_ULTRIX_PARTITION=y
# CONFIG_SUN_PARTITION is not set
# CONFIG_KARMA_PARTITION is not set
# CONFIG_EFI_PARTITION is not set
# CONFIG_SYSV68_PARTITION is not set
CONFIG_NLS=y
CONFIG_NLS_DEFAULT="iso8859-1"
CONFIG_NLS_CODEPAGE_437=m
# CONFIG_NLS_CODEPAGE_737 is not set
# CONFIG_NLS_CODEPAGE_775 is not set
CONFIG_NLS_CODEPAGE_850=m
CONFIG_NLS_CODEPAGE_852=m
CONFIG_NLS_CODEPAGE_855=y
CONFIG_NLS_CODEPAGE_857=y
# CONFIG_NLS_CODEPAGE_860 is not set
# CONFIG_NLS_CODEPAGE_861 is not set
CONFIG_NLS_CODEPAGE_862=y
CONFIG_NLS_CODEPAGE_863=m
# CONFIG_NLS_CODEPAGE_864 is not set
CONFIG_NLS_CODEPAGE_865=y
CONFIG_NLS_CODEPAGE_866=m
CONFIG_NLS_CODEPAGE_869=m
CONFIG_NLS_CODEPAGE_936=y
# CONFIG_NLS_CODEPAGE_950 is not set
CONFIG_NLS_CODEPAGE_932=m
# CONFIG_NLS_CODEPAGE_949 is not set
CONFIG_NLS_CODEPAGE_874=y
CONFIG_NLS_ISO8859_8=y
CONFIG_NLS_CODEPAGE_1250=m
# CONFIG_NLS_CODEPAGE_1251 is not set
CONFIG_NLS_ASCII=y
# CONFIG_NLS_ISO8859_1 is not set
CONFIG_NLS_ISO8859_2=y
# CONFIG_NLS_ISO8859_3 is not set
CONFIG_NLS_ISO8859_4=y
# CONFIG_NLS_ISO8859_5 is not set
CONFIG_NLS_ISO8859_6=y
CONFIG_NLS_ISO8859_7=y
CONFIG_NLS_ISO8859_9=y
# CONFIG_NLS_ISO8859_13 is not set
# CONFIG_NLS_ISO8859_14 is not set
# CONFIG_NLS_ISO8859_15 is not set
CONFIG_NLS_KOI8_R=y
# CONFIG_NLS_KOI8_U is not set
CONFIG_NLS_UTF8=m
CONFIG_DLM=y
# CONFIG_DLM_DEBUG is not set
#
# Kernel hacking
#
CONFIG_TRACE_IRQFLAGS_SUPPORT=y
CONFIG_PRINTK_TIME=y
CONFIG_ENABLE_WARN_DEPRECATED=y
# CONFIG_ENABLE_MUST_CHECK is not set
CONFIG_FRAME_WARN=2048
CONFIG_MAGIC_SYSRQ=y
CONFIG_UNUSED_SYMBOLS=y
CONFIG_DEBUG_FS=y
# CONFIG_HEADERS_CHECK is not set
CONFIG_DEBUG_KERNEL=y
CONFIG_DEBUG_SHIRQ=y
CONFIG_DETECT_SOFTLOCKUP=y
# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
# CONFIG_DETECT_HUNG_TASK is not set
# CONFIG_SCHED_DEBUG is not set
CONFIG_SCHEDSTATS=y
# CONFIG_TIMER_STATS is not set
CONFIG_DEBUG_OBJECTS=y
CONFIG_DEBUG_OBJECTS_SELFTEST=y
# CONFIG_DEBUG_OBJECTS_FREE is not set
CONFIG_DEBUG_OBJECTS_TIMERS=y
CONFIG_DEBUG_OBJECTS_ENABLE_DEFAULT=1
CONFIG_SLQB_DEBUG=y
# CONFIG_SLQB_DEBUG_ON is not set
# CONFIG_SLQB_SYSFS is not set
CONFIG_DEBUG_KMEMLEAK=y
# CONFIG_DEBUG_KMEMLEAK_TEST is not set
CONFIG_DEBUG_RT_MUTEXES=y
CONFIG_DEBUG_PI_LIST=y
CONFIG_RT_MUTEX_TESTER=y
CONFIG_DEBUG_SPINLOCK=y
CONFIG_DEBUG_MUTEXES=y
CONFIG_DEBUG_LOCK_ALLOC=y
CONFIG_PROVE_LOCKING=y
CONFIG_LOCKDEP=y
CONFIG_LOCK_STAT=y
CONFIG_DEBUG_LOCKDEP=y
CONFIG_TRACE_IRQFLAGS=y
CONFIG_DEBUG_SPINLOCK_SLEEP=y
# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
CONFIG_STACKTRACE=y
CONFIG_DEBUG_KOBJECT=y
CONFIG_DEBUG_BUGVERBOSE=y
# CONFIG_DEBUG_INFO is not set
# CONFIG_DEBUG_VM is not set
CONFIG_DEBUG_VIRTUAL=y
# CONFIG_DEBUG_WRITECOUNT is not set
CONFIG_DEBUG_MEMORY_INIT=y
# CONFIG_DEBUG_LIST is not set
CONFIG_DEBUG_SG=y
# CONFIG_DEBUG_NOTIFIERS is not set
CONFIG_ARCH_WANT_FRAME_POINTERS=y
CONFIG_FRAME_POINTER=y
# CONFIG_BOOT_PRINTK_DELAY is not set
CONFIG_RCU_TORTURE_TEST=m
CONFIG_RCU_CPU_STALL_DETECTOR=y
CONFIG_KPROBES_SANITY_TEST=y
# CONFIG_BACKTRACE_SELF_TEST is not set
CONFIG_DEBUG_BLOCK_EXT_DEVT=y
# CONFIG_LKDTM is not set
# CONFIG_FAULT_INJECTION is not set
# CONFIG_LATENCYTOP is not set
CONFIG_SYSCTL_SYSCALL_CHECK=y
CONFIG_DEBUG_PAGEALLOC=y
CONFIG_USER_STACKTRACE_SUPPORT=y
CONFIG_HAVE_FUNCTION_TRACER=y
CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y
CONFIG_HAVE_DYNAMIC_FTRACE=y
CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
CONFIG_HAVE_HW_BRANCH_TRACER=y
CONFIG_HAVE_FTRACE_SYSCALLS=y
CONFIG_TRACING_SUPPORT=y
# CONFIG_FTRACE is not set
CONFIG_PROVIDE_OHCI1394_DMA_INIT=y
# CONFIG_DYNAMIC_DEBUG is not set
# CONFIG_DMA_API_DEBUG is not set
CONFIG_SAMPLES=y
CONFIG_SAMPLE_MARKERS=m
# CONFIG_SAMPLE_TRACEPOINTS is not set
CONFIG_SAMPLE_KOBJECT=m
# CONFIG_SAMPLE_KPROBES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_KGDB is not set
CONFIG_HAVE_ARCH_KMEMCHECK=y
CONFIG_STRICT_DEVMEM=y
# CONFIG_X86_VERBOSE_BOOTUP is not set
CONFIG_EARLY_PRINTK=y
CONFIG_EARLY_PRINTK_DBGP=y
# CONFIG_DEBUG_STACKOVERFLOW is not set
# CONFIG_DEBUG_STACK_USAGE is not set
CONFIG_DEBUG_PER_CPU_MAPS=y
CONFIG_X86_PTDUMP=y
CONFIG_DEBUG_RODATA=y
CONFIG_DEBUG_RODATA_TEST=y
# CONFIG_DEBUG_NX_TEST is not set
CONFIG_IOMMU_DEBUG=y
# CONFIG_IOMMU_STRESS is not set
CONFIG_X86_DS_SELFTEST=y
CONFIG_HAVE_MMIOTRACE_SUPPORT=y
CONFIG_IO_DELAY_TYPE_0X80=0
CONFIG_IO_DELAY_TYPE_0XED=1
CONFIG_IO_DELAY_TYPE_UDELAY=2
CONFIG_IO_DELAY_TYPE_NONE=3
# CONFIG_IO_DELAY_0X80 is not set
CONFIG_IO_DELAY_0XED=y
# CONFIG_IO_DELAY_UDELAY is not set
# CONFIG_IO_DELAY_NONE is not set
CONFIG_DEFAULT_IO_DELAY_TYPE=1
# CONFIG_DEBUG_BOOT_PARAMS is not set
CONFIG_CPA_DEBUG=y
CONFIG_OPTIMIZE_INLINING=y
#
# Security options
#
# CONFIG_KEYS is not set
CONFIG_SECURITY=y
CONFIG_SECURITYFS=y
CONFIG_SECURITY_NETWORK=y
CONFIG_SECURITY_NETWORK_XFRM=y
CONFIG_SECURITY_PATH=y
CONFIG_SECURITY_FILE_CAPABILITIES=y
CONFIG_SECURITY_ROOTPLUG=y
CONFIG_SECURITY_DEFAULT_MMAP_MIN_ADDR=0
CONFIG_SECURITY_SELINUX=y
CONFIG_SECURITY_SELINUX_BOOTPARAM=y
CONFIG_SECURITY_SELINUX_BOOTPARAM_VALUE=1
# CONFIG_SECURITY_SELINUX_DISABLE is not set
# CONFIG_SECURITY_SELINUX_DEVELOP is not set
# CONFIG_SECURITY_SELINUX_AVC_STATS is not set
CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE=1
CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX=y
CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX_VALUE=19
CONFIG_SECURITY_SMACK=y
CONFIG_SECURITY_TOMOYO=y
CONFIG_IMA=y
CONFIG_IMA_MEASURE_PCR_IDX=10
CONFIG_IMA_AUDIT=y
CONFIG_IMA_LSM_RULES=y
CONFIG_CRYPTO=y
#
# Crypto core or helper
#
CONFIG_CRYPTO_FIPS=y
CONFIG_CRYPTO_ALGAPI=y
CONFIG_CRYPTO_ALGAPI2=y
CONFIG_CRYPTO_AEAD=y
CONFIG_CRYPTO_AEAD2=y
CONFIG_CRYPTO_BLKCIPHER=y
CONFIG_CRYPTO_BLKCIPHER2=y
CONFIG_CRYPTO_HASH=y
CONFIG_CRYPTO_HASH2=y
CONFIG_CRYPTO_RNG=y
CONFIG_CRYPTO_RNG2=y
CONFIG_CRYPTO_PCOMP=y
CONFIG_CRYPTO_MANAGER=y
CONFIG_CRYPTO_MANAGER2=y
CONFIG_CRYPTO_GF128MUL=y
CONFIG_CRYPTO_NULL=y
CONFIG_CRYPTO_WORKQUEUE=y
CONFIG_CRYPTO_CRYPTD=y
CONFIG_CRYPTO_AUTHENC=y
CONFIG_CRYPTO_TEST=m
#
# Authenticated Encryption with Associated Data
#
CONFIG_CRYPTO_CCM=y
CONFIG_CRYPTO_GCM=y
CONFIG_CRYPTO_SEQIV=y
#
# Block modes
#
CONFIG_CRYPTO_CBC=y
CONFIG_CRYPTO_CTR=y
CONFIG_CRYPTO_CTS=y
CONFIG_CRYPTO_ECB=y
CONFIG_CRYPTO_LRW=m
CONFIG_CRYPTO_PCBC=y
CONFIG_CRYPTO_XTS=m
CONFIG_CRYPTO_FPU=m
#
# Hash modes
#
CONFIG_CRYPTO_HMAC=y
# CONFIG_CRYPTO_XCBC is not set
#
# Digest
#
CONFIG_CRYPTO_CRC32C=y
CONFIG_CRYPTO_CRC32C_INTEL=m
# CONFIG_CRYPTO_MD4 is not set
CONFIG_CRYPTO_MD5=y
CONFIG_CRYPTO_MICHAEL_MIC=m
CONFIG_CRYPTO_RMD128=m
# CONFIG_CRYPTO_RMD160 is not set
# CONFIG_CRYPTO_RMD256 is not set
# CONFIG_CRYPTO_RMD320 is not set
CONFIG_CRYPTO_SHA1=y
# CONFIG_CRYPTO_SHA256 is not set
CONFIG_CRYPTO_SHA512=m
# CONFIG_CRYPTO_TGR192 is not set
CONFIG_CRYPTO_WP512=m
#
# Ciphers
#
CONFIG_CRYPTO_AES=y
CONFIG_CRYPTO_AES_X86_64=m
CONFIG_CRYPTO_AES_NI_INTEL=m
CONFIG_CRYPTO_ANUBIS=y
# CONFIG_CRYPTO_ARC4 is not set
CONFIG_CRYPTO_BLOWFISH=y
# CONFIG_CRYPTO_CAMELLIA is not set
CONFIG_CRYPTO_CAST5=y
# CONFIG_CRYPTO_CAST6 is not set
CONFIG_CRYPTO_DES=m
CONFIG_CRYPTO_FCRYPT=m
CONFIG_CRYPTO_KHAZAD=m
CONFIG_CRYPTO_SALSA20=y
CONFIG_CRYPTO_SALSA20_X86_64=y
CONFIG_CRYPTO_SEED=y
CONFIG_CRYPTO_SERPENT=y
CONFIG_CRYPTO_TEA=y
# CONFIG_CRYPTO_TWOFISH is not set
CONFIG_CRYPTO_TWOFISH_COMMON=m
CONFIG_CRYPTO_TWOFISH_X86_64=m
#
# Compression
#
CONFIG_CRYPTO_DEFLATE=m
CONFIG_CRYPTO_ZLIB=m
CONFIG_CRYPTO_LZO=y
#
# Random Number Generation
#
# CONFIG_CRYPTO_ANSI_CPRNG is not set
CONFIG_CRYPTO_HW=y
# CONFIG_CRYPTO_DEV_PADLOCK is not set
# CONFIG_CRYPTO_DEV_HIFN_795X is not set
CONFIG_HAVE_KVM=y
CONFIG_HAVE_KVM_IRQCHIP=y
CONFIG_HAVE_KVM_EVENTFD=y
CONFIG_VIRTUALIZATION=y
CONFIG_KVM=m
CONFIG_KVM_INTEL=m
# CONFIG_KVM_AMD is not set
CONFIG_KVM_TRACE=y
CONFIG_VIRTIO=m
CONFIG_VIRTIO_RING=m
CONFIG_VIRTIO_PCI=m
CONFIG_VIRTIO_BALLOON=m
# CONFIG_BINARY_PRINTF is not set
#
# Library routines
#
CONFIG_BITREVERSE=y
CONFIG_GENERIC_FIND_FIRST_BIT=y
CONFIG_GENERIC_FIND_NEXT_BIT=y
CONFIG_GENERIC_FIND_LAST_BIT=y
CONFIG_CRC_CCITT=m
CONFIG_CRC16=m
CONFIG_CRC_T10DIF=m
CONFIG_CRC_ITU_T=y
CONFIG_CRC32=y
# CONFIG_CRC7 is not set
CONFIG_LIBCRC32C=y
CONFIG_ZLIB_INFLATE=m
CONFIG_ZLIB_DEFLATE=m
CONFIG_LZO_COMPRESS=y
CONFIG_LZO_DECOMPRESS=y
CONFIG_REED_SOLOMON=y
CONFIG_REED_SOLOMON_DEC16=y
CONFIG_TEXTSEARCH=y
CONFIG_TEXTSEARCH_KMP=m
CONFIG_TEXTSEARCH_BM=m
CONFIG_TEXTSEARCH_FSM=m
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT=y
CONFIG_HAS_DMA=y
CONFIG_CHECK_SIGNATURE=y
CONFIG_CPUMASK_OFFSTACK=y
CONFIG_NLATTR=y
Stephen Rothwell wrote:
> Hi all,
>
> Looks like a real rush since -rc7 ...
drivers/built-in.o: In function `register_mem_sect_under_node':
(.text+0x1d305b): undefined reference to `sysfs_create_link_nowarn'
I can't find this function's implementation when CONFIG_SYSFS=y.
--
~Randy
LPC 2009, Sept. 23-25, Portland, Oregon
http://linuxplumbersconf.org/2009/
On Wed, 2009-06-03 at 17:47 +0200, Gábor Stefanik wrote:
> >> CFG80211=y
> >> MAC80211=y
> >> RFKILL=m
> >>
> >> net/built-in.o: In function `cfg80211_netdev_notifier_call':
> >> core.c:(.text+0xa678b): undefined reference to `rfkill_blocked'
> >> net/built-in.o: In function `cfg80211_dev_free':
> >
> > Hrm. I thought
> >
> > config CFG80211
> > tristate "Improved wireless configuration API"
> > depends on RFKILL || !RFKILL
> >
> > would avoid that. Why doesn't it?
> >
> > johannes
> >
>
> Maybe the "y" state of CFG80211 specifically needs to depend on
> RFKILL=y || !RFKILL.
Maybe doesn't help me at all.
> BTW should CFG80211=y really be blocked when RFKILL=m?
Yes.
> Shouldn't we
> just disable CFG80211 RFKILL support in this case (perhaps via a
> separate CONFIG_CFG80211_RFKILL automatically configured depending on
> CONFIG_RFKILL)?
That would be immensely stupid. You might as well just make cfg80211 a
module then.
johannes
On Wed, Jun 3, 2009 at 5:29 PM, Johannes Berg <[email protected]> wrote:
> On Wed, 2009-06-03 at 08:22 -0700, Randy Dunlap wrote:
>> Stephen Rothwell wrote:
>
>> CFG80211=y
>> MAC80211=y
>> RFKILL=m
>>
>> net/built-in.o: In function `cfg80211_netdev_notifier_call':
>> core.c:(.text+0xa678b): undefined reference to `rfkill_blocked'
>> net/built-in.o: In function `cfg80211_dev_free':
>
> Hrm. I thought
>
> config CFG80211
> ? ? ? ?tristate "Improved wireless configuration API"
> ? ? ? ?depends on RFKILL || !RFKILL
>
> would avoid that. Why doesn't it?
>
> johannes
>
Maybe the "y" state of CFG80211 specifically needs to depend on
RFKILL=y || !RFKILL.
BTW should CFG80211=y really be blocked when RFKILL=m? Shouldn't we
just disable CFG80211 RFKILL support in this case (perhaps via a
separate CONFIG_CFG80211_RFKILL automatically configured depending on
CONFIG_RFKILL)?
--
Vista: [V]iruses, [I]ntruders, [S]pyware, [T]rojans and [A]dware. :-)
On Wed, 2009-06-03 at 08:22 -0700, Randy Dunlap wrote:
> Stephen Rothwell wrote:
> > Hi all,
> >
> > Looks like a real rush since -rc7 ...
>
>
> CFG80211=y
> MAC80211=y
> RFKILL=m
Hmm. I see, it's mac80211's broken select CFG80211. I'll fix it.
johannes
Randy Dunlap wrote:
> Stephen Rothwell wrote:
>> Hi all,
>>
>> Looks like a real rush since -rc7 ...
>
>
> CFG80211=y
> MAC80211=y
> RFKILL=m
>
> net/built-in.o: In function `cfg80211_netdev_notifier_call':
> core.c:(.text+0xa678b): undefined reference to `rfkill_blocked'
> net/built-in.o: In function `cfg80211_dev_free':
> (.text+0xa67e2): undefined reference to `rfkill_destroy'
> net/built-in.o: In function `cfg80211_rfkill_sync_work':
> core.c:(.text+0xa686e): undefined reference to `rfkill_blocked'
> net/built-in.o: In function `wiphy_new':
> (.text+0xa69f2): undefined reference to `rfkill_alloc'
> net/built-in.o: In function `wiphy_rfkill_start_polling':
> (.text+0xa6bd2): undefined reference to `rfkill_resume_polling'
> net/built-in.o: In function `wiphy_rfkill_stop_polling':
> (.text+0xa6bdf): undefined reference to `rfkill_pause_polling'
> net/built-in.o: In function `wiphy_unregister':
> (.text+0xa6bf4): undefined reference to `rfkill_unregister'
> net/built-in.o: In function `wiphy_rfkill_set_hw_state':
> (.text+0xa6c64): undefined reference to `rfkill_set_hw_state'
> net/built-in.o: In function `wiphy_register':
> (.text+0xa6db4): undefined reference to `rfkill_register'
> net/built-in.o: In function `cfg80211_wext_giwtxpower':
> (.text+0xb01e9): undefined reference to `rfkill_blocked'
> net/built-in.o: In function `cfg80211_wext_siwtxpower':
> (.text+0xb0cf3): undefined reference to `rfkill_set_sw_state'
> net/built-in.o: In function `cfg80211_wext_siwtxpower':
> (.text+0xb0d1f): undefined reference to `rfkill_set_sw_state'
Ugh, there are similar errors in the wimax area, which doesn't
seem to mention RFKILL in its Kconfig file at all. :(
net/built-in.o: In function `wimax_rfkill':
(.text+0x81996): undefined reference to `rfkill_set_sw_state'
net/built-in.o: In function `wimax_report_rfkill_sw':
(.text+0x81ac0): undefined reference to `rfkill_set_sw_state'
net/built-in.o: In function `wimax_report_rfkill_hw':
(.text+0x81bd3): undefined reference to `rfkill_set_hw_state'
net/built-in.o: In function `wimax_rfkill_rm':
(.text+0x81c8f): undefined reference to `rfkill_unregister'
net/built-in.o: In function `wimax_rfkill_rm':
(.text+0x81c9a): undefined reference to `rfkill_destroy'
net/built-in.o: In function `wimax_rfkill_add':
(.text+0x81d52): undefined reference to `rfkill_alloc'
net/built-in.o: In function `wimax_rfkill_add':
(.text+0x81db3): undefined reference to `rfkill_register'
net/built-in.o: In function `wimax_rfkill_add':
(.text+0x81e2d): undefined reference to `rfkill_destroy'
--
~Randy
LPC 2009, Sept. 23-25, Portland, Oregon
http://linuxplumbersconf.org/2009/
On Wed, 2009-06-03 at 10:20 -0700, Randy Dunlap wrote:
> Ugh, there are similar errors in the wimax area, which doesn't
> seem to mention RFKILL in its Kconfig file at all. :(
Guess it too will have to get a
depends on RFKILL || !RFKILL
I can take care of it after dinner.
johannes
On Wed, Jun 03, 2009 at 08:50:10AM -0700, Randy Dunlap wrote:
> Stephen Rothwell wrote:
> > Hi all,
> >
> > Looks like a real rush since -rc7 ...
>
>
> drivers/built-in.o: In function `register_mem_sect_under_node':
> (.text+0x1d305b): undefined reference to `sysfs_create_link_nowarn'
>
>
> I can't find this function's implementation when CONFIG_SYSFS=y.
Ah, it looks like this shows up when CONFIG_MEMORY_HOTPLUG_SPARSE is
set.
Eric, your patch, "sysfs: Remove now unnecessary error reporting
suppression." caused this. Turns out it is still used in the tree, and
you forgot to remove the function from sysfs.h at the same time.
I'm going to drop it, and the other two patches I took from you for
sysfs, as it doesn't make sense to have them in the tree yet.
Care to rework your series with this fixed?
thanks,
greg k-h
Greg KH <[email protected]> writes:
> On Wed, Jun 03, 2009 at 08:50:10AM -0700, Randy Dunlap wrote:
>> Stephen Rothwell wrote:
>> > Hi all,
>> >
>> > Looks like a real rush since -rc7 ...
>>
>>
>> drivers/built-in.o: In function `register_mem_sect_under_node':
>> (.text+0x1d305b): undefined reference to `sysfs_create_link_nowarn'
>>
>>
>> I can't find this function's implementation when CONFIG_SYSFS=y.
>
> Ah, it looks like this shows up when CONFIG_MEMORY_HOTPLUG_SPARSE is
> set.
>
> Eric, your patch, "sysfs: Remove now unnecessary error reporting
> suppression." caused this. Turns out it is still used in the tree, and
> you forgot to remove the function from sysfs.h at the same time.
>
> I'm going to drop it, and the other two patches I took from you for
> sysfs, as it doesn't make sense to have them in the tree yet.
>
> Care to rework your series with this fixed?
Sure.
My apologies it looks like sysfs_create_link_nowarn grew an extra
user since last time I audited that patch thoroughly.
How I missed the header I don't know.
Eric
On Thursday 04 June 2009, Johannes Berg wrote:
> On Wed, 2009-06-03 at 10:20 -0700, Randy Dunlap wrote:
> > Ugh, there are similar errors in the wimax area, which doesn't
> > seem to mention RFKILL in its Kconfig file at all. :(
>
> Guess it too will have to get a
>
> depends on RFKILL || !RFKILL
>
> I can take care of it after dinner.
Ugh...bitten again by Randy's evil autobuilder. Thanks for fixing
it, Johannes.
--
Inaky
On Wed, Jun 03, 2009 at 08:40:33AM -0700, Randy Dunlap wrote:
> Greg KH wrote:
> > On Wed, Jun 03, 2009 at 08:24:49AM -0700, Randy Dunlap wrote:
> >> Stephen Rothwell wrote:
> >>> Hi all,
> >>>
> >>> Looks like a real rush since -rc7 ...
> >>
> >> drivers/staging/comedi/drivers/adq12b.c:328: error: implicit declaration of function 'udelay'
> >>
> >>
> >> drivers/staging/mrst_nand/ffsport.c:360:error: 'struct request' has no member named 'sector'
> >> drivers/staging/mrst_nand/ffsport.c:376:error: 'struct request' has no member named 'sector'
> >> drivers/staging/mrst_nand/ffsport.c:376:error: 'struct request' has no member named 'current_nr_sectors'
> >> drivers/staging/mrst_nand/ffsport.c:380:error: 'struct request' has no member named 'sector'
> >> drivers/staging/mrst_nand/ffsport.c:381:error: 'struct request' has no member named 'current_nr_sectors'
> >> drivers/staging/mrst_nand/ffsport.c:392:error: 'struct request' has no member named 'current_nr_sectors'
> >> drivers/staging/mrst_nand/ffsport.c:499:error: implicit declaration of function 'elv_next_request'
> >> drivers/staging/mrst_nand/ffsport.c:517:error: implicit declaration of function 'end_request'
> >> drivers/staging/mrst_nand/ffsport.c:738:error: implicit declaration of function 'blk_queue_hardsect_size'
> >
> > Can I get your .config for this? It works here with a "default" one.
>
> attached (for mrst_nand/ffsport.c build errors)
Ah, thanks, figured it out.
Gao, this looks like a problem in your ffsport.c code. It isn't up to
date with the 2.6.30-rc8 kernel tree. Care to send me a follow-on patch
to fix this up?
thanks,
greg k-h
Hi Greg,
Thanks for the reminder. I'll check the code in 2.6.30-rc8 and generate new patch to fix this bug as soon as. Thanks.
Rgds,
Yunpeng
>-----Original Message-----
>From: Greg KH [mailto:[email protected]]
>Sent: 2009??6??4?? 7:12
>To: Randy Dunlap; Gao, Yunpeng
>Cc: Stephen Rothwell; [email protected]; LKML
>Subject: Re: linux-next: Tree for June 3 (staging)
>
>On Wed, Jun 03, 2009 at 08:40:33AM -0700, Randy Dunlap wrote:
>> Greg KH wrote:
>> > On Wed, Jun 03, 2009 at 08:24:49AM -0700, Randy Dunlap wrote:
>> >> Stephen Rothwell wrote:
>> >>> Hi all,
>> >>>
>> >>> Looks like a real rush since -rc7 ...
>> >>
>> >> drivers/staging/comedi/drivers/adq12b.c:328: error: implicit declaration
>of function 'udelay'
>> >>
>> >>
>> >> drivers/staging/mrst_nand/ffsport.c:360:error: 'struct request' has no
>member named 'sector'
>> >> drivers/staging/mrst_nand/ffsport.c:376:error: 'struct request' has no
>member named 'sector'
>> >> drivers/staging/mrst_nand/ffsport.c:376:error: 'struct request' has no
>member named 'current_nr_sectors'
>> >> drivers/staging/mrst_nand/ffsport.c:380:error: 'struct request' has no
>member named 'sector'
>> >> drivers/staging/mrst_nand/ffsport.c:381:error: 'struct request' has no
>member named 'current_nr_sectors'
>> >> drivers/staging/mrst_nand/ffsport.c:392:error: 'struct request' has no
>member named 'current_nr_sectors'
>> >> drivers/staging/mrst_nand/ffsport.c:499:error: implicit declaration of
>function 'elv_next_request'
>> >> drivers/staging/mrst_nand/ffsport.c:517:error: implicit declaration of
>function 'end_request'
>> >> drivers/staging/mrst_nand/ffsport.c:738:error: implicit declaration of
>function 'blk_queue_hardsect_size'
>> >
>> > Can I get your .config for this? It works here with a "default" one.
>>
>> attached (for mrst_nand/ffsport.c build errors)
>
>Ah, thanks, figured it out.
>
>Gao, this looks like a problem in your ffsport.c code. It isn't up to
>date with the 2.6.30-rc8 kernel tree. Care to send me a follow-on patch
>to fix this up?
>
>thanks,
>
>greg k-h
????{.n?+???????+%?????ݶ??w??{.n?+????{??G?????{ay?ʇڙ?,j??f???h?????????z_??(?階?ݢj"???m??????G????????????&???~???iO???z??v?^?m????????????I?
On Thu, Jun 04, 2009 at 07:11:52AM +0800, Greg KH wrote:
> On Wed, Jun 03, 2009 at 08:40:33AM -0700, Randy Dunlap wrote:
> > Greg KH wrote:
> > > On Wed, Jun 03, 2009 at 08:24:49AM -0700, Randy Dunlap wrote:
> > >> Stephen Rothwell wrote:
> > >>> Hi all,
> > >>>
> > >>> Looks like a real rush since -rc7 ...
> > >>
> > >> drivers/staging/comedi/drivers/adq12b.c:328: error: implicit declaration of function 'udelay'
> > >>
> > >>
> > >> drivers/staging/mrst_nand/ffsport.c:360:error: 'struct request' has no member named 'sector'
> > >> drivers/staging/mrst_nand/ffsport.c:376:error: 'struct request' has no member named 'sector'
> > >> drivers/staging/mrst_nand/ffsport.c:376:error: 'struct request' has no member named 'current_nr_sectors'
> > >> drivers/staging/mrst_nand/ffsport.c:380:error: 'struct request' has no member named 'sector'
> > >> drivers/staging/mrst_nand/ffsport.c:381:error: 'struct request' has no member named 'current_nr_sectors'
> > >> drivers/staging/mrst_nand/ffsport.c:392:error: 'struct request' has no member named 'current_nr_sectors'
> > >> drivers/staging/mrst_nand/ffsport.c:499:error: implicit declaration of function 'elv_next_request'
> > >> drivers/staging/mrst_nand/ffsport.c:517:error: implicit declaration of function 'end_request'
> > >> drivers/staging/mrst_nand/ffsport.c:738:error: implicit declaration of function 'blk_queue_hardsect_size'
> > >
> > > Can I get your .config for this? It works here with a "default" one.
> >
> > attached (for mrst_nand/ffsport.c build errors)
>
> Ah, thanks, figured it out.
>
> Gao, this looks like a problem in your ffsport.c code. It isn't up to
> date with the 2.6.30-rc8 kernel tree. Care to send me a follow-on patch
> to fix this up?
>
> thanks,
>
> greg k-h
Hi Greg,
I have fixed these compiling bugs in file ffsport.c.
But just found that my email client (Outlook) will replace
TAB with blanks automatically. So, unfortunately, all the
TABs in my first submission patch have been changed to
blanks by the Outlook.
So I'd like to use the Mutt email client and re-submit
the patch as below (the bug-fix of ffsport.c has been included).
Does it make sense?
Thanks.
Rgds,
Yunpeng
-------------------------------------------------------------------------
>From 99a8d7b9e9fe1c0cf11d72b7ece44fb924417dae Mon Sep 17 00:00:00 2001
From: Gao Yunpeng <[email protected]>
Date: Fri, 5 Jun 2009 06:21:38 +0800
Subject: [PATCH] First submission of Intel Moorestown platform NAND flash driver
This driver is a standalone linux block device driver. It acts as
a normal hard disk. Please reference the README file for the detail.
Signed-off-by: Gao Yunpeng <[email protected]>
---
drivers/staging/Kconfig | 2 +
drivers/staging/Makefile | 1 +
drivers/staging/mrst_nand/Kconfig | 27 +
drivers/staging/mrst_nand/Makefile | 7 +
drivers/staging/mrst_nand/NAND_Regs_4.h | 619 ++++
drivers/staging/mrst_nand/README | 29 +
drivers/staging/mrst_nand/ffsdefs.h | 58 +
drivers/staging/mrst_nand/ffsport.c | 954 ++++++
drivers/staging/mrst_nand/ffsport.h | 89 +
drivers/staging/mrst_nand/flash.c | 4150 +++++++++++++++++++++++++++
drivers/staging/mrst_nand/flash.h | 158 +
drivers/staging/mrst_nand/lld.c | 492 ++++
drivers/staging/mrst_nand/lld.h | 123 +
drivers/staging/mrst_nand/lld_cdma.c | 2736 ++++++++++++++++++
drivers/staging/mrst_nand/lld_cdma.h | 138 +
drivers/staging/mrst_nand/lld_emu.c | 788 +++++
drivers/staging/mrst_nand/lld_emu.h | 51 +
drivers/staging/mrst_nand/lld_nand.c | 3113 ++++++++++++++++++++
drivers/staging/mrst_nand/lld_nand.h | 116 +
drivers/staging/mrst_nand/spectraswconfig.h | 86 +
20 files changed, 13737 insertions(+), 0 deletions(-)
create mode 100644 drivers/staging/mrst_nand/Kconfig
create mode 100644 drivers/staging/mrst_nand/Makefile
create mode 100644 drivers/staging/mrst_nand/NAND_Regs_4.h
create mode 100644 drivers/staging/mrst_nand/README
create mode 100644 drivers/staging/mrst_nand/ffsdefs.h
create mode 100644 drivers/staging/mrst_nand/ffsport.c
create mode 100644 drivers/staging/mrst_nand/ffsport.h
create mode 100644 drivers/staging/mrst_nand/flash.c
create mode 100644 drivers/staging/mrst_nand/flash.h
create mode 100644 drivers/staging/mrst_nand/lld.c
create mode 100644 drivers/staging/mrst_nand/lld.h
create mode 100644 drivers/staging/mrst_nand/lld_cdma.c
create mode 100644 drivers/staging/mrst_nand/lld_cdma.h
create mode 100644 drivers/staging/mrst_nand/lld_emu.c
create mode 100644 drivers/staging/mrst_nand/lld_emu.h
create mode 100644 drivers/staging/mrst_nand/lld_nand.c
create mode 100644 drivers/staging/mrst_nand/lld_nand.h
create mode 100644 drivers/staging/mrst_nand/spectraswconfig.h
diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig
index 0dcf9ca..3fb8b75 100644
--- a/drivers/staging/Kconfig
+++ b/drivers/staging/Kconfig
@@ -115,5 +115,7 @@ source "drivers/staging/line6/Kconfig"
source "drivers/staging/serqt_usb/Kconfig"
+source "drivers/staging/mrst_nand/Kconfig"
+
endif # !STAGING_EXCLUDE_BUILD
endif # STAGING
diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile
index 47dfd5b..4da30fe 100644
--- a/drivers/staging/Makefile
+++ b/drivers/staging/Makefile
@@ -40,3 +40,4 @@ obj-$(CONFIG_PLAN9AUTH) += p9auth/
obj-$(CONFIG_HECI) += heci/
obj-$(CONFIG_LINE6_USB) += line6/
obj-$(CONFIG_USB_SERIAL_QUATECH_ESU100) += serqt_usb/
+obj-$(CONFIG_MRST_NAND) += mrst_nand/
diff --git a/drivers/staging/mrst_nand/Kconfig b/drivers/staging/mrst_nand/Kconfig
new file mode 100644
index 0000000..a2017df
--- /dev/null
+++ b/drivers/staging/mrst_nand/Kconfig
@@ -0,0 +1,27 @@
+
+menuconfig MRST_NAND
+ tristate "Moorestown NAND Flash controller"
+ depends on BLOCK
+ default m
+ ---help---
+ Enable the driver for the NAND Flash controller in Intel Moorestown
+ Platform
+
+choice
+ prompt "Compile for"
+ depends on MRST_NAND
+ default MRST_NAND_HW
+
+config MRST_NAND_HW
+ bool "Actual hardware mode"
+ help
+ Driver communicates with the actual hardware's register interface.
+ in DMA mode.
+
+config MRST_NAND_EMU
+ bool "RAM emulator testing"
+ help
+ Driver emulates Flash on a RAM buffer and / or disk file. Useful to test the behavior of FTL layer.
+
+endchoice
+
diff --git a/drivers/staging/mrst_nand/Makefile b/drivers/staging/mrst_nand/Makefile
new file mode 100644
index 0000000..261891c
--- /dev/null
+++ b/drivers/staging/mrst_nand/Makefile
@@ -0,0 +1,7 @@
+#
+# Makefile of Intel Moorestown NAND controller driver
+#
+
+obj-$(CONFIG_MRST_NAND) += spectra.o
+spectra-objs := ffsport.o flash.o lld.o lld_emu.o lld_nand.o lld_cdma.o
+
diff --git a/drivers/staging/mrst_nand/NAND_Regs_4.h b/drivers/staging/mrst_nand/NAND_Regs_4.h
new file mode 100644
index 0000000..e192e4a
--- /dev/null
+++ b/drivers/staging/mrst_nand/NAND_Regs_4.h
@@ -0,0 +1,619 @@
+/*
+ * NAND Flash Controller Device Driver
+ * Copyright (c) 2009, Intel Corporation and its suppliers.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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.
+ *
+ * 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.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+#define DEVICE_RESET 0x0
+#define DEVICE_RESET__BANK0 0x0001
+#define DEVICE_RESET__BANK1 0x0002
+#define DEVICE_RESET__BANK2 0x0004
+#define DEVICE_RESET__BANK3 0x0008
+
+#define TRANSFER_SPARE_REG 0x10
+#define TRANSFER_SPARE_REG__FLAG 0x0001
+
+#define LOAD_WAIT_CNT 0x20
+#define LOAD_WAIT_CNT__VALUE 0xffff
+
+#define PROGRAM_WAIT_CNT 0x30
+#define PROGRAM_WAIT_CNT__VALUE 0xffff
+
+#define ERASE_WAIT_CNT 0x40
+#define ERASE_WAIT_CNT__VALUE 0xffff
+
+#define INT_MON_CYCCNT 0x50
+#define INT_MON_CYCCNT__VALUE 0xffff
+
+#define RB_PIN_ENABLED 0x60
+#define RB_PIN_ENABLED__BANK0 0x0001
+#define RB_PIN_ENABLED__BANK1 0x0002
+#define RB_PIN_ENABLED__BANK2 0x0004
+#define RB_PIN_ENABLED__BANK3 0x0008
+
+#define MULTIPLANE_OPERATION 0x70
+#define MULTIPLANE_OPERATION__FLAG 0x0001
+
+#define MULTIPLANE_READ_ENABLE 0x80
+#define MULTIPLANE_READ_ENABLE__FLAG 0x0001
+
+#define COPYBACK_DISABLE 0x90
+#define COPYBACK_DISABLE__FLAG 0x0001
+
+#define CACHE_WRITE_ENABLE 0xa0
+#define CACHE_WRITE_ENABLE__FLAG 0x0001
+
+#define CACHE_READ_ENABLE 0xb0
+#define CACHE_READ_ENABLE__FLAG 0x0001
+
+#define PREFETCH_MODE 0xc0
+#define PREFETCH_MODE__PREFETCH_EN 0x0001
+#define PREFETCH_MODE__PREFETCH_BURST_LENGTH 0xfff0
+
+#define CHIP_ENABLE_DONT_CARE 0xd0
+#define CHIP_EN_DONT_CARE__FLAG 0x01
+
+#define ECC_ENABLE 0xe0
+#define ECC_ENABLE__FLAG 0x0001
+
+#define GLOBAL_INT_ENABLE 0xf0
+#define GLOBAL_INT_EN_FLAG 0x01
+
+#define WE_2_RE 0x100
+#define WE_2_RE__VALUE 0x003f
+
+#define ADDR_2_DATA 0x110
+#define ADDR_2_DATA__VALUE 0x003f
+
+#define RE_2_WE 0x120
+#define RE_2_WE__VALUE 0x003f
+
+#define ACC_CLKS 0x130
+#define ACC_CLKS__VALUE 0x000f
+
+#define NUMBER_OF_PLANES 0x140
+#define NUMBER_OF_PLANES__VALUE 0x0007
+
+#define PAGES_PER_BLOCK 0x150
+#define PAGES_PER_BLOCK__VALUE 0xffff
+
+#define DEVICE_WIDTH 0x160
+#define DEVICE_WIDTH__VALUE 0x0003
+
+#define DEVICE_MAIN_AREA_SIZE 0x170
+#define DEVICE_MAIN_AREA_SIZE__VALUE 0xffff
+
+#define DEVICE_SPARE_AREA_SIZE 0x180
+#define DEVICE_SPARE_AREA_SIZE__VALUE 0xffff
+
+#define TWO_ROW_ADDR_CYCLES 0x190
+#define TWO_ROW_ADDR_CYCLES__FLAG 0x0001
+
+#define MULTIPLANE_ADDR_RESTRICT 0x1a0
+#define MULTIPLANE_ADDR_RESTRICT__FLAG 0x0001
+
+#define ECC_CORRECTION 0x1b0
+#define ECC_CORRECTION__VALUE 0x001f
+
+#define READ_MODE 0x1c0
+#define READ_MODE__VALUE 0x000f
+
+#define WRITE_MODE 0x1d0
+#define WRITE_MODE__VALUE 0x000f
+
+#define COPYBACK_MODE 0x1e0
+#define COPYBACK_MODE__VALUE 0x000f
+
+#define RDWR_EN_LO_CNT 0x1f0
+#define RDWR_EN_LO_CNT__VALUE 0x001f
+
+#define RDWR_EN_HI_CNT 0x200
+#define RDWR_EN_HI_CNT__VALUE 0x001f
+
+#define MAX_RD_DELAY 0x210
+#define MAX_RD_DELAY__VALUE 0x000f
+
+#define CS_SETUP_CNT 0x220
+#define CS_SETUP_CNT__VALUE 0x001f
+
+#define SPARE_AREA_SKIP_BYTES 0x230
+#define SPARE_AREA_SKIP_BYTES__VALUE 0x003f
+
+#define SPARE_AREA_MARKER 0x240
+#define SPARE_AREA_MARKER__VALUE 0xffff
+
+#define DEVICES_CONNECTED 0x250
+#define DEVICES_CONNECTED__VALUE 0x0007
+
+#define DIE_MASK 0x260
+#define DIE_MASK__VALUE 0x00ff
+
+#define FIRST_BLOCK_OF_NEXT_PLANE 0x270
+#define FIRST_BLOCK_OF_NEXT_PLANE__VALUE 0xffff
+
+#define WRITE_PROTECT 0x280
+#define WRITE_PROTECT__FLAG 0x0001
+
+#define RE_2_RE 0x290
+#define RE_2_RE__VALUE 0x003f
+
+#define MANUFACTURER_ID 0x300
+#define MANUFACTURER_ID__VALUE 0x00ff
+
+#define DEVICE_ID 0x310
+#define DEVICE_ID__VALUE 0x00ff
+
+#define DEVICE_PARAM_0 0x320
+#define DEVICE_PARAM_0__VALUE 0x00ff
+
+#define DEVICE_PARAM_1 0x330
+#define DEVICE_PARAM_1__VALUE 0x00ff
+
+#define DEVICE_PARAM_2 0x340
+#define DEVICE_PARAM_2__VALUE 0x00ff
+
+#define LOGICAL_PAGE_DATA_SIZE 0x350
+#define LOGICAL_PAGE_DATA_SIZE__VALUE 0xffff
+
+#define LOGICAL_PAGE_SPARE_SIZE 0x360
+#define LOGICAL_PAGE_SPARE_SIZE__VALUE 0xffff
+
+#define REVISION 0x370
+#define REVISION__VALUE 0xffff
+
+#define ONFI_DEVICE_FEATURES 0x380
+#define ONFI_DEVICE_FEATURES__VALUE 0x003f
+
+#define ONFI_OPTIONAL_COMMANDS 0x390
+#define ONFI_OPTIONAL_COMMANDS__VALUE 0x003f
+
+#define ONFI_TIMING_MODE 0x3a0
+#define ONFI_TIMING_MODE__VALUE 0x003f
+
+#define ONFI_PGM_CACHE_TIMING_MODE 0x3b0
+#define ONFI_PGM_CACHE_TIMING_MODE__VALUE 0x003f
+
+#define ONFI_DEVICE_NO_OF_LUNS 0x3c0
+#define ONFI_DEVICE_NO_OF_LUNS__NO_OF_LUNS 0x00ff
+#define ONFI_DEVICE_NO_OF_LUNS__ONFI_DEVICE 0x0100
+
+#define ONFI_DEVICE_NO_OF_BLOCKS_PER_LUN_L 0x3d0
+#define ONFI_DEVICE_NO_OF_BLOCKS_PER_LUN_L__VALUE 0xffff
+
+#define ONFI_DEVICE_NO_OF_BLOCKS_PER_LUN_U 0x3e0
+#define ONFI_DEVICE_NO_OF_BLOCKS_PER_LUN_U__VALUE 0xffff
+
+#define FEATURES 0x3f0
+#define FEATURES__N_BANKS 0x0003
+#define FEATURES__ECC_MAX_ERR 0x003c
+#define FEATURES__DMA 0x0040
+#define FEATURES__CMD_DMA 0x0080
+#define FEATURES__PARTITION 0x0100
+#define FEATURES__XDMA_SIDEBAND 0x0200
+#define FEATURES__GPREG 0x0400
+#define FEATURES__INDEX_ADDR 0x0800
+
+#define TRANSFER_MODE 0x400
+#define TRANSFER_MODE__VALUE 0x0003
+
+#define INTR_STATUS0 0x410
+#define INTR_STATUS0__ECC_TRANSACTION_DONE 0x0001
+#define INTR_STATUS0__ECC_ERR 0x0002
+#define INTR_STATUS0__DMA_CMD_COMP 0x0004
+#define INTR_STATUS0__TIME_OUT 0x0008
+#define INTR_STATUS0__PROGRAM_FAIL 0x0010
+#define INTR_STATUS0__ERASE_FAIL 0x0020
+#define INTR_STATUS0__LOAD_COMP 0x0040
+#define INTR_STATUS0__PROGRAM_COMP 0x0080
+#define INTR_STATUS0__ERASE_COMP 0x0100
+#define INTR_STATUS0__PIPE_CPYBCK_CMD_COMP 0x0200
+#define INTR_STATUS0__LOCKED_BLK 0x0400
+#define INTR_STATUS0__UNSUP_CMD 0x0800
+#define INTR_STATUS0__INT_ACT 0x1000
+#define INTR_STATUS0__RST_COMP 0x2000
+#define INTR_STATUS0__PIPE_CMD_ERR 0x4000
+#define INTR_STATUS0__PAGE_XFER_INC 0x8000
+
+#define INTR_EN0 0x420
+#define INTR_EN0__ECC_TRANSACTION_DONE 0x0001
+#define INTR_EN0__ECC_ERR 0x0002
+#define INTR_EN0__DMA_CMD_COMP 0x0004
+#define INTR_EN0__TIME_OUT 0x0008
+#define INTR_EN0__PROGRAM_FAIL 0x0010
+#define INTR_EN0__ERASE_FAIL 0x0020
+#define INTR_EN0__LOAD_COMP 0x0040
+#define INTR_EN0__PROGRAM_COMP 0x0080
+#define INTR_EN0__ERASE_COMP 0x0100
+#define INTR_EN0__PIPE_CPYBCK_CMD_COMP 0x0200
+#define INTR_EN0__LOCKED_BLK 0x0400
+#define INTR_EN0__UNSUP_CMD 0x0800
+#define INTR_EN0__INT_ACT 0x1000
+#define INTR_EN0__RST_COMP 0x2000
+#define INTR_EN0__PIPE_CMD_ERR 0x4000
+#define INTR_EN0__PAGE_XFER_INC 0x8000
+
+#define PAGE_CNT0 0x430
+#define PAGE_CNT0__VALUE 0x00ff
+
+#define ERR_PAGE_ADDR0 0x440
+#define ERR_PAGE_ADDR0__VALUE 0xffff
+
+#define ERR_BLOCK_ADDR0 0x450
+#define ERR_BLOCK_ADDR0__VALUE 0xffff
+
+#define INTR_STATUS1 0x460
+#define INTR_STATUS1__ECC_TRANSACTION_DONE 0x0001
+#define INTR_STATUS1__ECC_ERR 0x0002
+#define INTR_STATUS1__DMA_CMD_COMP 0x0004
+#define INTR_STATUS1__TIME_OUT 0x0008
+#define INTR_STATUS1__PROGRAM_FAIL 0x0010
+#define INTR_STATUS1__ERASE_FAIL 0x0020
+#define INTR_STATUS1__LOAD_COMP 0x0040
+#define INTR_STATUS1__PROGRAM_COMP 0x0080
+#define INTR_STATUS1__ERASE_COMP 0x0100
+#define INTR_STATUS1__PIPE_CPYBCK_CMD_COMP 0x0200
+#define INTR_STATUS1__LOCKED_BLK 0x0400
+#define INTR_STATUS1__UNSUP_CMD 0x0800
+#define INTR_STATUS1__INT_ACT 0x1000
+#define INTR_STATUS1__RST_COMP 0x2000
+#define INTR_STATUS1__PIPE_CMD_ERR 0x4000
+#define INTR_STATUS1__PAGE_XFER_INC 0x8000
+
+#define INTR_EN1 0x470
+#define INTR_EN1__ECC_TRANSACTION_DONE 0x0001
+#define INTR_EN1__ECC_ERR 0x0002
+#define INTR_EN1__DMA_CMD_COMP 0x0004
+#define INTR_EN1__TIME_OUT 0x0008
+#define INTR_EN1__PROGRAM_FAIL 0x0010
+#define INTR_EN1__ERASE_FAIL 0x0020
+#define INTR_EN1__LOAD_COMP 0x0040
+#define INTR_EN1__PROGRAM_COMP 0x0080
+#define INTR_EN1__ERASE_COMP 0x0100
+#define INTR_EN1__PIPE_CPYBCK_CMD_COMP 0x0200
+#define INTR_EN1__LOCKED_BLK 0x0400
+#define INTR_EN1__UNSUP_CMD 0x0800
+#define INTR_EN1__INT_ACT 0x1000
+#define INTR_EN1__RST_COMP 0x2000
+#define INTR_EN1__PIPE_CMD_ERR 0x4000
+#define INTR_EN1__PAGE_XFER_INC 0x8000
+
+#define PAGE_CNT1 0x480
+#define PAGE_CNT1__VALUE 0x00ff
+
+#define ERR_PAGE_ADDR1 0x490
+#define ERR_PAGE_ADDR1__VALUE 0xffff
+
+#define ERR_BLOCK_ADDR1 0x4a0
+#define ERR_BLOCK_ADDR1__VALUE 0xffff
+
+#define INTR_STATUS2 0x4b0
+#define INTR_STATUS2__ECC_TRANSACTION_DONE 0x0001
+#define INTR_STATUS2__ECC_ERR 0x0002
+#define INTR_STATUS2__DMA_CMD_COMP 0x0004
+#define INTR_STATUS2__TIME_OUT 0x0008
+#define INTR_STATUS2__PROGRAM_FAIL 0x0010
+#define INTR_STATUS2__ERASE_FAIL 0x0020
+#define INTR_STATUS2__LOAD_COMP 0x0040
+#define INTR_STATUS2__PROGRAM_COMP 0x0080
+#define INTR_STATUS2__ERASE_COMP 0x0100
+#define INTR_STATUS2__PIPE_CPYBCK_CMD_COMP 0x0200
+#define INTR_STATUS2__LOCKED_BLK 0x0400
+#define INTR_STATUS2__UNSUP_CMD 0x0800
+#define INTR_STATUS2__INT_ACT 0x1000
+#define INTR_STATUS2__RST_COMP 0x2000
+#define INTR_STATUS2__PIPE_CMD_ERR 0x4000
+#define INTR_STATUS2__PAGE_XFER_INC 0x8000
+
+#define INTR_EN2 0x4c0
+#define INTR_EN2__ECC_TRANSACTION_DONE 0x0001
+#define INTR_EN2__ECC_ERR 0x0002
+#define INTR_EN2__DMA_CMD_COMP 0x0004
+#define INTR_EN2__TIME_OUT 0x0008
+#define INTR_EN2__PROGRAM_FAIL 0x0010
+#define INTR_EN2__ERASE_FAIL 0x0020
+#define INTR_EN2__LOAD_COMP 0x0040
+#define INTR_EN2__PROGRAM_COMP 0x0080
+#define INTR_EN2__ERASE_COMP 0x0100
+#define INTR_EN2__PIPE_CPYBCK_CMD_COMP 0x0200
+#define INTR_EN2__LOCKED_BLK 0x0400
+#define INTR_EN2__UNSUP_CMD 0x0800
+#define INTR_EN2__INT_ACT 0x1000
+#define INTR_EN2__RST_COMP 0x2000
+#define INTR_EN2__PIPE_CMD_ERR 0x4000
+#define INTR_EN2__PAGE_XFER_INC 0x8000
+
+#define PAGE_CNT2 0x4d0
+#define PAGE_CNT2__VALUE 0x00ff
+
+#define ERR_PAGE_ADDR2 0x4e0
+#define ERR_PAGE_ADDR2__VALUE 0xffff
+
+#define ERR_BLOCK_ADDR2 0x4f0
+#define ERR_BLOCK_ADDR2__VALUE 0xffff
+
+#define INTR_STATUS3 0x500
+#define INTR_STATUS3__ECC_TRANSACTION_DONE 0x0001
+#define INTR_STATUS3__ECC_ERR 0x0002
+#define INTR_STATUS3__DMA_CMD_COMP 0x0004
+#define INTR_STATUS3__TIME_OUT 0x0008
+#define INTR_STATUS3__PROGRAM_FAIL 0x0010
+#define INTR_STATUS3__ERASE_FAIL 0x0020
+#define INTR_STATUS3__LOAD_COMP 0x0040
+#define INTR_STATUS3__PROGRAM_COMP 0x0080
+#define INTR_STATUS3__ERASE_COMP 0x0100
+#define INTR_STATUS3__PIPE_CPYBCK_CMD_COMP 0x0200
+#define INTR_STATUS3__LOCKED_BLK 0x0400
+#define INTR_STATUS3__UNSUP_CMD 0x0800
+#define INTR_STATUS3__INT_ACT 0x1000
+#define INTR_STATUS3__RST_COMP 0x2000
+#define INTR_STATUS3__PIPE_CMD_ERR 0x4000
+#define INTR_STATUS3__PAGE_XFER_INC 0x8000
+
+#define INTR_EN3 0x510
+#define INTR_EN3__ECC_TRANSACTION_DONE 0x0001
+#define INTR_EN3__ECC_ERR 0x0002
+#define INTR_EN3__DMA_CMD_COMP 0x0004
+#define INTR_EN3__TIME_OUT 0x0008
+#define INTR_EN3__PROGRAM_FAIL 0x0010
+#define INTR_EN3__ERASE_FAIL 0x0020
+#define INTR_EN3__LOAD_COMP 0x0040
+#define INTR_EN3__PROGRAM_COMP 0x0080
+#define INTR_EN3__ERASE_COMP 0x0100
+#define INTR_EN3__PIPE_CPYBCK_CMD_COMP 0x0200
+#define INTR_EN3__LOCKED_BLK 0x0400
+#define INTR_EN3__UNSUP_CMD 0x0800
+#define INTR_EN3__INT_ACT 0x1000
+#define INTR_EN3__RST_COMP 0x2000
+#define INTR_EN3__PIPE_CMD_ERR 0x4000
+#define INTR_EN3__PAGE_XFER_INC 0x8000
+
+#define PAGE_CNT3 0x520
+#define PAGE_CNT3__VALUE 0x00ff
+
+#define ERR_PAGE_ADDR3 0x530
+#define ERR_PAGE_ADDR3__VALUE 0xffff
+
+#define ERR_BLOCK_ADDR3 0x540
+#define ERR_BLOCK_ADDR3__VALUE 0xffff
+
+#define DATA_INTR 0x550
+#define DATA_INTR__WRITE_SPACE_AV 0x0001
+#define DATA_INTR__READ_DATA_AV 0x0002
+
+#define DATA_INTR_EN 0x560
+#define DATA_INTR_EN__WRITE_SPACE_AV 0x0001
+#define DATA_INTR_EN__READ_DATA_AV 0x0002
+
+#define GPREG_0 0x570
+#define GPREG_0__VALUE 0xffff
+
+#define GPREG_1 0x580
+#define GPREG_1__VALUE 0xffff
+
+#define GPREG_2 0x590
+#define GPREG_2__VALUE 0xffff
+
+#define GPREG_3 0x5a0
+#define GPREG_3__VALUE 0xffff
+
+#define ECC_THRESHOLD 0x600
+#define ECC_THRESHOLD__VALUE 0x03ff
+
+#define ECC_ERROR_BLOCK_ADDRESS 0x610
+#define ECC_ERROR_BLOCK_ADDRESS__VALUE 0xffff
+
+#define ECC_ERROR_PAGE_ADDRESS 0x620
+#define ECC_ERROR_PAGE_ADDRESS__VALUE 0x0fff
+#define ECC_ERROR_PAGE_ADDRESS__BANK 0xf000
+
+#define ECC_ERROR_ADDRESS 0x630
+#define ECC_ERROR_ADDRESS__OFFSET 0x0fff
+#define ECC_ERROR_ADDRESS__SECTOR_NR 0xf000
+
+#define ERR_CORRECTION_INFO 0x640
+#define ERR_CORRECTION_INFO__BYTEMASK 0x00ff
+#define ERR_CORRECTION_INFO__DEVICE_NR 0x0f00
+#define ERR_CORRECTION_INFO__ERROR_TYPE 0x4000
+#define ERR_CORRECTION_INFO__LAST_ERR_INFO 0x8000
+
+#define DMA_ENABLE 0x700
+#define DMA_ENABLE__FLAG 0x0001
+
+#define IGNORE_ECC_DONE 0x710
+#define IGNORE_ECC_DONE__FLAG 0x0001
+
+#define DMA_INTR 0x720
+#define DMA_INTR__TARGET_ERROR 0x0001
+#define DMA_INTR__DESC_COMP_CHANNEL0 0x0002
+#define DMA_INTR__DESC_COMP_CHANNEL1 0x0004
+#define DMA_INTR__DESC_COMP_CHANNEL2 0x0008
+#define DMA_INTR__DESC_COMP_CHANNEL3 0x0010
+#define DMA_INTR__MEMCOPY_DESC_COMP 0x0020
+
+#define DMA_INTR_EN 0x730
+#define DMA_INTR_EN__TARGET_ERROR 0x0001
+#define DMA_INTR_EN__DESC_COMP_CHANNEL0 0x0002
+#define DMA_INTR_EN__DESC_COMP_CHANNEL1 0x0004
+#define DMA_INTR_EN__DESC_COMP_CHANNEL2 0x0008
+#define DMA_INTR_EN__DESC_COMP_CHANNEL3 0x0010
+#define DMA_INTR_EN__MEMCOPY_DESC_COMP 0x0020
+
+#define TARGET_ERR_ADDR_LO 0x740
+#define TARGET_ERR_ADDR_LO__VALUE 0xffff
+
+#define TARGET_ERR_ADDR_HI 0x750
+#define TARGET_ERR_ADDR_HI__VALUE 0xffff
+
+#define CHNL_ACTIVE 0x760
+#define CHNL_ACTIVE__CHANNEL0 0x0001
+#define CHNL_ACTIVE__CHANNEL1 0x0002
+#define CHNL_ACTIVE__CHANNEL2 0x0004
+#define CHNL_ACTIVE__CHANNEL3 0x0008
+
+#define ACTIVE_SRC_ID 0x800
+#define ACTIVE_SRC_ID__VALUE 0x00ff
+
+#define PTN_INTR 0x810
+#define PTN_INTR__CONFIG_ERROR 0x0001
+#define PTN_INTR__ACCESS_ERROR_BANK0 0x0002
+#define PTN_INTR__ACCESS_ERROR_BANK1 0x0004
+#define PTN_INTR__ACCESS_ERROR_BANK2 0x0008
+#define PTN_INTR__ACCESS_ERROR_BANK3 0x0010
+#define PTN_INTR__REG_ACCESS_ERROR 0x0020
+
+#define PTN_INTR_EN 0x820
+#define PTN_INTR_EN__CONFIG_ERROR 0x0001
+#define PTN_INTR_EN__ACCESS_ERROR_BANK0 0x0002
+#define PTN_INTR_EN__ACCESS_ERROR_BANK1 0x0004
+#define PTN_INTR_EN__ACCESS_ERROR_BANK2 0x0008
+#define PTN_INTR_EN__ACCESS_ERROR_BANK3 0x0010
+#define PTN_INTR_EN__REG_ACCESS_ERROR 0x0020
+
+#define PERM_SRC_ID_0 0x830
+#define PERM_SRC_ID_0__SRCID 0x00ff
+#define PERM_SRC_ID_0__DIRECT_ACCESS_ACTIVE 0x0800
+#define PERM_SRC_ID_0__WRITE_ACTIVE 0x2000
+#define PERM_SRC_ID_0__READ_ACTIVE 0x4000
+#define PERM_SRC_ID_0__PARTITION_VALID 0x8000
+
+#define MIN_BLK_ADDR_0 0x840
+#define MIN_BLK_ADDR_0__VALUE 0xffff
+
+#define MAX_BLK_ADDR_0 0x850
+#define MAX_BLK_ADDR_0__VALUE 0xffff
+
+#define MIN_MAX_BANK_0 0x860
+#define MIN_MAX_BANK_0__MIN_VALUE 0x0003
+#define MIN_MAX_BANK_0__MAX_VALUE 0x000c
+
+#define PERM_SRC_ID_1 0x870
+#define PERM_SRC_ID_1__SRCID 0x00ff
+#define PERM_SRC_ID_1__DIRECT_ACCESS_ACTIVE 0x0800
+#define PERM_SRC_ID_1__WRITE_ACTIVE 0x2000
+#define PERM_SRC_ID_1__READ_ACTIVE 0x4000
+#define PERM_SRC_ID_1__PARTITION_VALID 0x8000
+
+#define MIN_BLK_ADDR_1 0x880
+#define MIN_BLK_ADDR_1__VALUE 0xffff
+
+#define MAX_BLK_ADDR_1 0x890
+#define MAX_BLK_ADDR_1__VALUE 0xffff
+
+#define MIN_MAX_BANK_1 0x8a0
+#define MIN_MAX_BANK_1__MIN_VALUE 0x0003
+#define MIN_MAX_BANK_1__MAX_VALUE 0x000c
+
+#define PERM_SRC_ID_2 0x8b0
+#define PERM_SRC_ID_2__SRCID 0x00ff
+#define PERM_SRC_ID_2__DIRECT_ACCESS_ACTIVE 0x0800
+#define PERM_SRC_ID_2__WRITE_ACTIVE 0x2000
+#define PERM_SRC_ID_2__READ_ACTIVE 0x4000
+#define PERM_SRC_ID_2__PARTITION_VALID 0x8000
+
+#define MIN_BLK_ADDR_2 0x8c0
+#define MIN_BLK_ADDR_2__VALUE 0xffff
+
+#define MAX_BLK_ADDR_2 0x8d0
+#define MAX_BLK_ADDR_2__VALUE 0xffff
+
+#define MIN_MAX_BANK_2 0x8e0
+#define MIN_MAX_BANK_2__MIN_VALUE 0x0003
+#define MIN_MAX_BANK_2__MAX_VALUE 0x000c
+
+#define PERM_SRC_ID_3 0x8f0
+#define PERM_SRC_ID_3__SRCID 0x00ff
+#define PERM_SRC_ID_3__DIRECT_ACCESS_ACTIVE 0x0800
+#define PERM_SRC_ID_3__WRITE_ACTIVE 0x2000
+#define PERM_SRC_ID_3__READ_ACTIVE 0x4000
+#define PERM_SRC_ID_3__PARTITION_VALID 0x8000
+
+#define MIN_BLK_ADDR_3 0x900
+#define MIN_BLK_ADDR_3__VALUE 0xffff
+
+#define MAX_BLK_ADDR_3 0x910
+#define MAX_BLK_ADDR_3__VALUE 0xffff
+
+#define MIN_MAX_BANK_3 0x920
+#define MIN_MAX_BANK_3__MIN_VALUE 0x0003
+#define MIN_MAX_BANK_3__MAX_VALUE 0x000c
+
+#define PERM_SRC_ID_4 0x930
+#define PERM_SRC_ID_4__SRCID 0x00ff
+#define PERM_SRC_ID_4__DIRECT_ACCESS_ACTIVE 0x0800
+#define PERM_SRC_ID_4__WRITE_ACTIVE 0x2000
+#define PERM_SRC_ID_4__READ_ACTIVE 0x4000
+#define PERM_SRC_ID_4__PARTITION_VALID 0x8000
+
+#define MIN_BLK_ADDR_4 0x940
+#define MIN_BLK_ADDR_4__VALUE 0xffff
+
+#define MAX_BLK_ADDR_4 0x950
+#define MAX_BLK_ADDR_4__VALUE 0xffff
+
+#define MIN_MAX_BANK_4 0x960
+#define MIN_MAX_BANK_4__MIN_VALUE 0x0003
+#define MIN_MAX_BANK_4__MAX_VALUE 0x000c
+
+#define PERM_SRC_ID_5 0x970
+#define PERM_SRC_ID_5__SRCID 0x00ff
+#define PERM_SRC_ID_5__DIRECT_ACCESS_ACTIVE 0x0800
+#define PERM_SRC_ID_5__WRITE_ACTIVE 0x2000
+#define PERM_SRC_ID_5__READ_ACTIVE 0x4000
+#define PERM_SRC_ID_5__PARTITION_VALID 0x8000
+
+#define MIN_BLK_ADDR_5 0x980
+#define MIN_BLK_ADDR_5__VALUE 0xffff
+
+#define MAX_BLK_ADDR_5 0x990
+#define MAX_BLK_ADDR_5__VALUE 0xffff
+
+#define MIN_MAX_BANK_5 0x9a0
+#define MIN_MAX_BANK_5__MIN_VALUE 0x0003
+#define MIN_MAX_BANK_5__MAX_VALUE 0x000c
+
+#define PERM_SRC_ID_6 0x9b0
+#define PERM_SRC_ID_6__SRCID 0x00ff
+#define PERM_SRC_ID_6__DIRECT_ACCESS_ACTIVE 0x0800
+#define PERM_SRC_ID_6__WRITE_ACTIVE 0x2000
+#define PERM_SRC_ID_6__READ_ACTIVE 0x4000
+#define PERM_SRC_ID_6__PARTITION_VALID 0x8000
+
+#define MIN_BLK_ADDR_6 0x9c0
+#define MIN_BLK_ADDR_6__VALUE 0xffff
+
+#define MAX_BLK_ADDR_6 0x9d0
+#define MAX_BLK_ADDR_6__VALUE 0xffff
+
+#define MIN_MAX_BANK_6 0x9e0
+#define MIN_MAX_BANK_6__MIN_VALUE 0x0003
+#define MIN_MAX_BANK_6__MAX_VALUE 0x000c
+
+#define PERM_SRC_ID_7 0x9f0
+#define PERM_SRC_ID_7__SRCID 0x00ff
+#define PERM_SRC_ID_7__DIRECT_ACCESS_ACTIVE 0x0800
+#define PERM_SRC_ID_7__WRITE_ACTIVE 0x2000
+#define PERM_SRC_ID_7__READ_ACTIVE 0x4000
+#define PERM_SRC_ID_7__PARTITION_VALID 0x8000
+
+#define MIN_BLK_ADDR_7 0xa00
+#define MIN_BLK_ADDR_7__VALUE 0xffff
+
+#define MAX_BLK_ADDR_7 0xa10
+#define MAX_BLK_ADDR_7__VALUE 0xffff
+
+#define MIN_MAX_BANK_7 0xa20
+#define MIN_MAX_BANK_7__MIN_VALUE 0x0003
+#define MIN_MAX_BANK_7__MAX_VALUE 0x000c
diff --git a/drivers/staging/mrst_nand/README b/drivers/staging/mrst_nand/README
new file mode 100644
index 0000000..ecba559
--- /dev/null
+++ b/drivers/staging/mrst_nand/README
@@ -0,0 +1,29 @@
+This is a driver for NAND controller of Intel Moorestown platform.
+
+This driver is a standalone linux block device driver, it acts as if it's a normal hard disk.
+It includes three layer:
+ block layer interface - file ffsport.c
+ Flash Translation Layer (FTL) - file flash.c (implement the NAND flash Translation Layer, includs address mapping, garbage collection, wear-leveling and so on)
+ Low level layer - file lld_nand.c/lld_cdma.c/lld_emu.c (which implements actual controller hardware registers access)
+
+This driver can be build as modules or build-in.
+
+Dependency:
+This driver has dependency on IA Firmware of Intel Moorestown platform.
+It need the IA Firmware to create the block table for the first time.
+And to validate this driver code without IA Firmware, you can change the
+macro AUTO_FORMAT_FLASH from 0 to 1 in file spectraswconfig.h. Thus the
+driver will erase the whole nand flash and create a new block table.
+
+TODO:
+ - Enable Command DMA feature support
+ - lower the memory footprint
+ - Remove most of the unnecessary global variables
+ - Change all the upcase variable / functions name to lowercase
+ - Some other misc bugs
+
+Please send patches to:
+ Greg Kroah-Hartman <[email protected]>
+
+And Cc to: Gao Yunpeng <[email protected]>
+
diff --git a/drivers/staging/mrst_nand/ffsdefs.h b/drivers/staging/mrst_nand/ffsdefs.h
new file mode 100644
index 0000000..a9e9cd2
--- /dev/null
+++ b/drivers/staging/mrst_nand/ffsdefs.h
@@ -0,0 +1,58 @@
+/*
+ * NAND Flash Controller Device Driver
+ * Copyright (c) 2009, Intel Corporation and its suppliers.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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.
+ *
+ * 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.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+#ifndef _FFSDEFS_
+#define _FFSDEFS_
+
+#define CLEAR 0 /*use this to clear a field instead of "fail"*/
+#define SET 1 /*use this to set a field instead of "pass"*/
+#define FAIL 1 /*failed flag*/
+#define PASS 0 /*success flag*/
+#define ERR -1 /*error flag*/
+
+#define ERASE_CMD 10
+#define WRITE_MAIN_CMD 11
+#define READ_MAIN_CMD 12
+#define WRITE_SPARE_CMD 13
+#define READ_SPARE_CMD 14
+#define WRITE_MAIN_SPARE_CMD 15
+#define READ_MAIN_SPARE_CMD 16
+#define MEMCOPY_CMD 17
+#define DUMMY_CMD 99
+
+#define EVENT_PASS 0x00
+#define EVENT_CORRECTABLE_DATA_ERROR_FIXED 0x01
+#define EVENT_UNCORRECTABLE_DATA_ERROR 0x02
+#define EVENT_TIME_OUT 0x03
+#define EVENT_PROGRAM_FAILURE 0x04
+#define EVENT_ERASE_FAILURE 0x05
+#define EVENT_MEMCOPY_FAILURE 0x06
+#define EVENT_FAIL 0x07
+
+#define EVENT_NONE 0x22
+#define EVENT_DMA_CMD_COMP 0x77
+#define EVENT_ECC_TRANSACTION_DONE 0x88
+#define EVENT_DMA_CMD_FAIL 0x99
+
+#define CMD_PASS 0
+#define CMD_FAIL 1
+#define CMD_ABORT 2
+#define CMD_NOT_DONE 3
+
+#endif /* _FFSDEFS_ */
diff --git a/drivers/staging/mrst_nand/ffsport.c b/drivers/staging/mrst_nand/ffsport.c
new file mode 100644
index 0000000..68640bd
--- /dev/null
+++ b/drivers/staging/mrst_nand/ffsport.c
@@ -0,0 +1,954 @@
+/*
+ * NAND Flash Controller Device Driver
+ * Copyright (c) 2009, Intel Corporation and its suppliers.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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.
+ *
+ * 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.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+#define SBDBG 0
+
+#include "ffsport.h"
+#include "flash.h"
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <linux/wait.h>
+#include <linux/mutex.h>
+#include <linux/kthread.h>
+#include <linux/log2.h>
+
+/**** Helper functions used for Div, Remainder operation on u64 ****/
+
+/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+* Function: GLOB_Calc_Used_Bits
+* Inputs: Power of 2 number
+* Outputs: Number of Used Bits
+* 0, if the argument is 0
+* Description: Calculate the number of bits used by a given power of 2 number
+* Number can be upto 32 bit
+*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
+int GLOB_Calc_Used_Bits(u32 n)
+{
+ int tot_bits = 0;
+
+ if (n >= 1 << 16) {
+ n >>= 16;
+ tot_bits += 16;
+ }
+
+ if (n >= 1 << 8) {
+ n >>= 8;
+ tot_bits += 8;
+ }
+
+ if (n >= 1 << 4) {
+ n >>= 4;
+ tot_bits += 4;
+ }
+
+ if (n >= 1 << 2) {
+ n >>= 2;
+ tot_bits += 2;
+ }
+
+ if (n >= 1 << 1)
+ tot_bits += 1;
+
+ return ((n == 0) ? (0) : tot_bits);
+}
+
+/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+* Function: GLOB_u64_Div
+* Inputs: Number of u64
+* A power of 2 number as Division
+* Outputs: Quotient of the Divisor operation
+* Description: It divides the address by divisor by using bit shift operation
+* (essentially without explicitely using "/").
+* Divisor is a power of 2 number and Divided is of u64
+*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
+u64 GLOB_u64_Div(u64 addr, u32 divisor)
+{
+ return (u64)(addr >> GLOB_Calc_Used_Bits(divisor));
+}
+
+/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+* Function: GLOB_u64_Remainder
+* Inputs: Number of u64
+* Divisor Type (1 -PageAddress, 2- BlockAddress)
+* Outputs: Remainder of the Division operation
+* Description: It calculates the remainder of a number (of u64) by
+* divisor(power of 2 number ) by using bit shifting and multiply
+* operation(essentially without explicitely using "/").
+*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
+u64 GLOB_u64_Remainder(u64 addr, u32 divisor_type)
+{
+ u64 result = 0;
+
+ if (divisor_type == 1) { /* Remainder -- Page */
+ result = (addr >> DeviceInfo.nBitsInPageDataSize);
+ result = result * DeviceInfo.wPageDataSize;
+ } else if (divisor_type == 2) { /* Remainder -- Block */
+ result = (addr >> DeviceInfo.nBitsInBlockDataSize);
+ result = result * DeviceInfo.wBlockDataSize;
+ }
+
+ result = addr - result;
+
+ return result;
+}
+
+
+void glob_udelay(unsigned long usecs)
+{
+ udelay(usecs);
+}
+
+void glob_mdelay(unsigned long msecs)
+{
+ mdelay(msecs);
+}
+
+u32 *GLOB_MEMMAP_NOCACHE(unsigned long addr, unsigned long size)
+{
+#if (FLASH_NAND || FLASH_CDMA)
+ return (u32 *)ioremap_nocache(addr, (size+0xfff)&(~0xfff));
+#else
+ return (u32 *)addr;
+#endif
+}
+
+u32 *GLOB_MEMMAP_TOBUS(u32 *ptr)
+{
+#if (FLASH_NAND || FLASH_CDMA)
+ return (u32 *)virt_to_bus(ptr);
+#else
+ return ptr;
+#endif
+}
+
+
+#define NUM_DEVICES 1
+#define PARTITIONS 4
+#define NUM_OUTSTANDING_FTL_REQUESTS 8
+
+#define GLOB_SBD_NAME "nd"
+#define GLOB_SBD_IRQ_NUM (29)
+#define GLOB_VERSION "driver version 20090312"
+
+#define GLOB_SBD_IOCTL_GC (0x7701)
+#define GLOB_SBD_IOCTL_WL (0x7702)
+#define GLOB_SBD_IOCTL_FORMAT (0x7703)
+#define GLOB_SBD_IOCTL_ERASE_FLASH (0x7704)
+#define GLOB_SBD_IOCTL_FLUSH_CACHE (0x7705)
+#define GLOB_SBD_IOCTL_COPY_BLK_TABLE (0x7706)
+#define GLOB_SBD_IOCTL_COPY_WEAR_LEVELING_TABLE (0x7707)
+#define GLOB_SBD_IOCTL_GET_NAND_INFO (0x7708)
+#define GLOB_SBD_IOCTL_WRITE_DATA (0x7709)
+#define GLOB_SBD_IOCTL_READ_DATA (0x770A)
+
+
+#define RESERVED_MB_FOR_OS_IMAGE 25
+
+int nand_debug_level;
+module_param(nand_debug_level, int, 0644);
+MODULE_PARM_DESC(nand_debug_level, "debug level value: 1-3");
+
+MODULE_LICENSE("GPL");
+
+struct spectra_nand_dev {
+ struct pci_dev *dev;
+ u64 size;
+ u16 users;
+ spinlock_t qlock;
+ void __iomem *ioaddr; /* Mapped address */
+ struct request_queue *queue;
+ struct task_struct *thread;
+ struct gendisk *gd;
+#if CMD_DMA
+ wait_queue_head_t irq_wait_queue;
+ int irq_count;
+#endif
+ u8 *tmp_buf;
+};
+
+
+static int GLOB_SBD_majornum;
+
+static char *GLOB_version = GLOB_VERSION;
+
+static struct spectra_nand_dev nand_device[NUM_DEVICES];
+
+/* Because the driver will allocate a lot of memory and kmalloc can not */
+/* allocat memory more than 4M bytes, here we use static array as */
+/* memory pool. This is simple but ugly. It should only be used during */
+/* development.*/
+#define LOCAL_MEM_POOL_SIZE (1024 * 1024 * 8)
+static u8 local_mem_pool[LOCAL_MEM_POOL_SIZE];
+
+
+/* static int dev_num; */
+
+static struct mutex spectra_lock;
+
+static int res_blks_os = 1;
+
+struct spectra_indentfy_dev_tag IdentifyDeviceData;
+
+#define SBD_SECTOR_SIZE (IdentifyDeviceData.PageDataSize)
+#define SBD_BLOCK_SIZE (IdentifyDeviceData.PageDataSize *\
+ IdentifyDeviceData.PagesPerBlock)
+
+u8 *mem_pool_ptr;
+
+#if CMD_DMA
+struct GLOB_SBD_CMDDMA_Q {
+ struct request *req;
+ int num_sbd_sects;
+} glob_sbd_cmddma_q;
+
+struct GLOB_SBD_CMDDMA_Q cmddma_request_queue[NUM_OUTSTANDING_FTL_REQUESTS];
+unsigned int cmddma_num_requests;
+unsigned int cmddma_num_ftl_requests;
+
+#if SBDBG
+u64 SBDBG_cdma_address[NUM_OUTSTANDING_FTL_REQUESTS];
+#endif
+
+#endif
+
+static int force_flush_cache(void)
+{
+ if (ERR == GLOB_FTL_Flush_Cache()) {
+ printk(KERN_ERR "Fail to Flush FTL Cache!\n");
+ return -EFAULT;
+ }
+
+ return 0;
+}
+
+struct ioctl_rw_page_info {
+ u8 *data;
+ unsigned int page;
+};
+
+static int ioctl_read_page_data(unsigned long arg)
+{
+ u8 *buf;
+ struct ioctl_rw_page_info info;
+ int result = PASS;
+
+ if (copy_from_user(&info, (void __user *)arg, sizeof(info)))
+ return -EFAULT;
+
+ buf = kmalloc(IdentifyDeviceData.PageDataSize, GFP_ATOMIC);
+ if (!buf) {
+ printk(KERN_ERR "ioctl_read_page_data: "
+ "failed to allocate memory\n");
+ return -ENOMEM;
+ }
+
+ mutex_lock(&spectra_lock);
+ result = GLOB_FTL_Page_Read(buf,
+ (u64)info.page * IdentifyDeviceData.PageDataSize);
+ mutex_unlock(&spectra_lock);
+
+ if (copy_to_user((void __user *)info.data, buf,
+ IdentifyDeviceData.PageDataSize)) {
+ printk(KERN_ERR "ioctl_read_page_data: "
+ "failed to copy user data\n");
+ kfree(buf);
+ return -EFAULT;
+ }
+
+
+ kfree(buf);
+ return result;
+}
+
+static int ioctl_write_page_data(unsigned long arg)
+{
+ u8 *buf;
+ struct ioctl_rw_page_info info;
+ int result = PASS;
+
+ if (copy_from_user(&info, (void __user *)arg, sizeof(info)))
+ return -EFAULT;
+
+ buf = kmalloc(IdentifyDeviceData.PageDataSize, GFP_ATOMIC);
+ if (!buf) {
+ printk(KERN_ERR "ioctl_write_page_data: "
+ "failed to allocate memory\n");
+ return -ENOMEM;
+ }
+
+ if (copy_from_user(buf, (void __user *)info.data,
+ IdentifyDeviceData.PageDataSize)) {
+ printk(KERN_ERR "ioctl_write_page_data: "
+ "failed to copy user data\n");
+ kfree(buf);
+ return -EFAULT;
+ }
+
+ mutex_lock(&spectra_lock);
+ result = GLOB_FTL_Page_Write(buf,
+ (u64)info.page * IdentifyDeviceData.PageDataSize);
+ mutex_unlock(&spectra_lock);
+
+ kfree(buf);
+ return result;
+}
+
+
+/* Static Function Declarations */
+static void GLOB_SBD_request(struct request_queue *q);
+
+/* Return how many blocks should be reserved for bad block replacement */
+static int get_res_blk_num_bad_blk(void)
+{
+ return IdentifyDeviceData.wDataBlockNum / 10;
+}
+
+/* Return how many blocks should be reserved for OS image */
+static int get_res_blk_num_os(void)
+{
+ int res_blks, blk_size;
+
+ blk_size = IdentifyDeviceData.PageDataSize *
+ IdentifyDeviceData.PagesPerBlock;
+
+ res_blks = (RESERVED_MB_FOR_OS_IMAGE *
+ 1024 * 1024) / blk_size;
+
+ if (res_blks >= IdentifyDeviceData.wDataBlockNum) {
+ printk(KERN_ERR "Too many reserved blocks (%d) "
+ "for OS image. Will use default value 1\n",
+ res_blks);
+ res_blks = 1; /* Reserved 1 block for block table */
+ }
+
+ return res_blks;
+}
+
+static void SBD_prepare_flush(struct request_queue *q, struct request *rq)
+{
+ rq->cmd_type = REQ_TYPE_LINUX_BLOCK;
+ /* rq->timeout = 5 * HZ; */
+ rq->cmd[0] = REQ_LB_OP_FLUSH;
+}
+
+/* Transfer a full request. */
+static int do_transfer(struct spectra_nand_dev *tr, struct request *req)
+{
+ u64 start_addr, addr;
+ u32 logical_start_sect, hd_start_sect;
+ u32 nsect, hd_sects;
+ u32 rsect, tsect = 0;
+ char *buf;
+ u32 ratio = IdentifyDeviceData.PageDataSize >> 9;
+
+ start_addr = (u64)(blk_rq_pos(req)) << 9;
+ /* Add a big enough offset to prevent the OS Image from
+ * being accessed or damaged by file system */
+ start_addr += (SBD_BLOCK_SIZE * res_blks_os);
+
+ if (req->cmd_type == REQ_TYPE_LINUX_BLOCK &&
+ req->cmd[0] == REQ_LB_OP_FLUSH) {
+ if (force_flush_cache()) /* Fail to flush cache */
+ return -EIO;
+ else
+ return 0;
+ }
+
+ if (!blk_fs_request(req))
+ return -EIO;
+
+ if (blk_rq_pos(req) + blk_rq_cur_sectors(req) > get_capacity(tr->gd)) {
+ printk(KERN_ERR "Spectra error: request over the NAND "
+ "capacity!sector %d, current_nr_sectors %d, "
+ "while capacity is %d\n",
+ (int)blk_rq_pos(req),
+ blk_rq_cur_sectors(req),
+ (int)get_capacity(tr->gd));
+ return -EIO;
+ }
+
+ logical_start_sect = start_addr >> 9;
+ hd_start_sect = logical_start_sect / ratio;
+ rsect = logical_start_sect - hd_start_sect * ratio;
+
+ addr = (u64)hd_start_sect * ratio * 512;
+ buf = req->buffer;
+ nsect = blk_rq_cur_sectors(req);
+
+ if (rsect)
+ tsect = (ratio - rsect) < nsect ? (ratio - rsect) : nsect;
+
+ switch (rq_data_dir(req)) {
+ case READ:
+ /* Read the first NAND page */
+ if (rsect) {
+ if (GLOB_FTL_Page_Read(tr->tmp_buf, addr)) {
+ printk(KERN_ERR "Error in %s, Line %d\n",
+ __FILE__, __LINE__);
+ return -EIO;
+ }
+ memcpy(buf, tr->tmp_buf + (rsect << 9), tsect << 9);
+ addr += IdentifyDeviceData.PageDataSize;
+ buf += tsect << 9;
+ nsect -= tsect;
+ }
+
+ /* Read the other NAND pages */
+ for (hd_sects = nsect / ratio; hd_sects > 0; hd_sects--) {
+ if (GLOB_FTL_Page_Read(buf, addr)) {
+ printk(KERN_ERR "Error in %s, Line %d\n",
+ __FILE__, __LINE__);
+ return -EIO;
+ }
+ addr += IdentifyDeviceData.PageDataSize;
+ buf += IdentifyDeviceData.PageDataSize;
+ }
+
+ /* Read the last NAND pages */
+ if (nsect % ratio) {
+ if (GLOB_FTL_Page_Read(tr->tmp_buf, addr)) {
+ printk(KERN_ERR "Error in %s, Line %d\n",
+ __FILE__, __LINE__);
+ return -EIO;
+ }
+ memcpy(buf, tr->tmp_buf, (nsect % ratio) << 9);
+ }
+ return 0;
+
+ case WRITE:
+ /* Write the first NAND page */
+ if (rsect) {
+ if (GLOB_FTL_Page_Read(tr->tmp_buf, addr)) {
+ printk(KERN_ERR "Error in %s, Line %d\n",
+ __FILE__, __LINE__);
+ return -EIO;
+ }
+ memcpy(tr->tmp_buf + (rsect << 9), buf, tsect << 9);
+ if (GLOB_FTL_Page_Write(tr->tmp_buf, addr)) {
+ printk(KERN_ERR "Error in %s, Line %d\n",
+ __FILE__, __LINE__);
+ return -EIO;
+ }
+ addr += IdentifyDeviceData.PageDataSize;
+ buf += tsect << 9;
+ nsect -= tsect;
+ }
+
+ /* Write the other NAND pages */
+ for (hd_sects = nsect / ratio; hd_sects > 0; hd_sects--) {
+ if (GLOB_FTL_Page_Write(buf, addr)) {
+ printk(KERN_ERR "Error in %s, Line %d\n",
+ __FILE__, __LINE__);
+ return -EIO;
+ }
+ addr += IdentifyDeviceData.PageDataSize;
+ buf += IdentifyDeviceData.PageDataSize;
+ }
+
+ /* Write the last NAND pages */
+ if (nsect % ratio) {
+ if (GLOB_FTL_Page_Read(tr->tmp_buf, addr)) {
+ printk(KERN_ERR "Error in %s, Line %d\n",
+ __FILE__, __LINE__);
+ return -EIO;
+ }
+ memcpy(tr->tmp_buf, buf, (nsect % ratio) << 9);
+ if (GLOB_FTL_Page_Write(tr->tmp_buf, addr)) {
+ printk(KERN_ERR "Error in %s, Line %d\n",
+ __FILE__, __LINE__);
+ return -EIO;
+ }
+ }
+ return 0;
+
+ default:
+ printk(KERN_NOTICE "Unknown request %u\n", rq_data_dir(req));
+ return -EIO;
+ }
+}
+
+static int spectra_trans_thread(void *arg)
+{
+ struct spectra_nand_dev *tr = arg;
+ struct request_queue *rq = tr->queue;
+ struct request *req = NULL;
+
+ /* we might get involved when memory gets low, so use PF_MEMALLOC */
+ current->flags |= PF_MEMALLOC;
+
+ spin_lock_irq(rq->queue_lock);
+ while (!kthread_should_stop()) {
+ int res;
+
+ if (!req && !(req = blk_fetch_request(rq))) {
+ set_current_state(TASK_INTERRUPTIBLE);
+ spin_unlock_irq(rq->queue_lock);
+ schedule();
+ spin_lock_irq(rq->queue_lock);
+ continue;
+ }
+
+ spin_unlock_irq(rq->queue_lock);
+
+ mutex_lock(&spectra_lock);
+ res = do_transfer(tr, req);
+ mutex_unlock(&spectra_lock);
+
+ spin_lock_irq(rq->queue_lock);
+
+ if (!__blk_end_request_cur(req, res))
+ req = NULL;
+ }
+
+ if (req)
+ __blk_end_request_all(req, -EIO);
+
+ spin_unlock_irq(rq->queue_lock);
+
+ return 0;
+}
+
+
+/* Request function that "handles clustering". */
+static void GLOB_SBD_request(struct request_queue *rq)
+{
+ struct spectra_nand_dev *pdev = rq->queuedata;
+ wake_up_process(pdev->thread);
+}
+
+
+static int GLOB_SBD_open(struct block_device *bdev, fmode_t mode)
+
+{
+ nand_dbg_print(NAND_DBG_WARN, "%s, Line %d, Function: %s\n",
+ __FILE__, __LINE__, __func__);
+ return 0;
+}
+
+static int GLOB_SBD_release(struct gendisk *disk, fmode_t mode)
+{
+#if CMD_DMA
+ struct spectra_nand_dev *dev = disk->private_data;
+#endif
+ int ret;
+
+ nand_dbg_print(NAND_DBG_WARN, "%s, Line %d, Function: %s\n",
+ __FILE__, __LINE__, __func__);
+
+#if CMD_DMA
+ if (cmddma_num_requests) {
+ dev->irq_count = 0;
+ if (cmddma_num_requests)
+ wait_event_interruptible(dev->irq_wait_queue,
+ dev->irq_count);
+ else
+ dev->irq_count = 1;
+ }
+ cmddma_num_requests = 0;
+ cmddma_num_ftl_requests = 0;
+#endif
+ mutex_lock(&spectra_lock);
+ ret = force_flush_cache();
+ mutex_unlock(&spectra_lock);
+
+#if CMD_DMA
+ if (ret == 0) {
+ dev->irq_count = 0;
+ GLOB_FTL_Execute_CMDS();
+ if (!dev->irq_count)
+ wait_event_interruptible(dev->irq_wait_queue,
+ dev->irq_count);
+ }
+
+ if (dev->users)
+ free_irq(GLOB_SBD_IRQ_NUM, (void *)dev);
+#endif
+
+ return 0;
+}
+
+static int GLOB_SBD_getgeo(struct block_device *bdev, struct hd_geometry *geo)
+{
+ geo->heads = 4;
+ geo->sectors = 16;
+ geo->cylinders = get_capacity(bdev->bd_disk) / (4 * 16);
+
+ nand_dbg_print(NAND_DBG_DEBUG,
+ "heads: %d, sectors: %d, cylinders: %d\n",
+ geo->heads, geo->sectors, geo->cylinders);
+
+ return 0;
+}
+
+int GLOB_SBD_ioctl(struct block_device *bdev, fmode_t mode,
+ unsigned int cmd, unsigned long arg)
+{
+ int ret;
+#if CMD_DMA
+ struct spectra_nand_dev *dev = bdev->bd_disk->private_data;
+#endif
+
+ nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
+ __FILE__, __LINE__, __func__);
+
+ switch (cmd) {
+ case GLOB_SBD_IOCTL_GC:
+ nand_dbg_print(NAND_DBG_DEBUG,
+ "Spectra IOCTL: Garbage Collection "
+ "being performed\n");
+ if (PASS != GLOB_FTL_Garbage_Collection())
+ return -EFAULT;
+ return 0;
+
+ case GLOB_SBD_IOCTL_WL:
+ nand_dbg_print(NAND_DBG_DEBUG,
+ "Spectra IOCTL: Static Wear Leveling "
+ "being performed\n");
+ if (PASS != GLOB_FTL_Wear_Leveling())
+ return -EFAULT;
+ return 0;
+
+ case GLOB_SBD_IOCTL_FORMAT:
+ nand_dbg_print(NAND_DBG_DEBUG, "Spectra IOCTL: Flash format "
+ "being performed\n");
+ if (PASS != GLOB_FTL_Flash_Format())
+ return -EFAULT;
+ return 0;
+
+ case GLOB_SBD_IOCTL_FLUSH_CACHE:
+ nand_dbg_print(NAND_DBG_DEBUG, "Spectra IOCTL: Cache flush "
+ "being performed\n");
+ mutex_lock(&spectra_lock);
+ ret = force_flush_cache();
+ mutex_unlock(&spectra_lock);
+#if CMD_DMA
+ if (!ret) {
+ dev->irq_count = 0;
+ GLOB_FTL_Execute_CMDS();
+ if (!dev->irq_count)
+ wait_event_interruptible(dev->irq_wait_queue,
+ dev->irq_count);
+ }
+#endif
+ return ret;
+
+ case GLOB_SBD_IOCTL_COPY_BLK_TABLE:
+ nand_dbg_print(NAND_DBG_DEBUG, "Spectra IOCTL: "
+ "Copy block table\n");
+ if (copy_to_user((void __user *)arg,
+ get_blk_table_start_addr(),
+ get_blk_table_len()))
+ return -EFAULT;
+ return 0;
+
+ case GLOB_SBD_IOCTL_COPY_WEAR_LEVELING_TABLE:
+ nand_dbg_print(NAND_DBG_DEBUG, "Spectra IOCTL: "
+ "Copy wear leveling table\n");
+ if (copy_to_user((void __user *)arg,
+ get_wear_leveling_table_start_addr(),
+ get_wear_leveling_table_len()))
+ return -EFAULT;
+ return 0;
+
+ case GLOB_SBD_IOCTL_GET_NAND_INFO:
+ nand_dbg_print(NAND_DBG_DEBUG, "Spectra IOCTL: "
+ "Get NAND info\n");
+ if (copy_to_user((void __user *)arg, &IdentifyDeviceData,
+ sizeof(IdentifyDeviceData)))
+ return -EFAULT;
+ return 0;
+
+ case GLOB_SBD_IOCTL_WRITE_DATA:
+ nand_dbg_print(NAND_DBG_DEBUG, "Spectra IOCTL: "
+ "Write one page data\n");
+ return ioctl_write_page_data(arg);
+
+ case GLOB_SBD_IOCTL_READ_DATA:
+ nand_dbg_print(NAND_DBG_DEBUG, "Spectra IOCTL: "
+ "Read one page data\n");
+ return ioctl_read_page_data(arg);
+ }
+
+ return -ENOTTY;
+}
+
+static struct block_device_operations GLOB_SBD_ops = {
+ .owner = THIS_MODULE,
+ .open = GLOB_SBD_open,
+ .release = GLOB_SBD_release,
+ .locked_ioctl = GLOB_SBD_ioctl,
+ .getgeo = GLOB_SBD_getgeo,
+};
+
+static int SBD_setup_device(struct spectra_nand_dev *dev, int which)
+{
+ int res_blks;
+ u32 sects;
+
+ nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
+ __FILE__, __LINE__, __func__);
+
+ memset(dev, 0, sizeof(struct spectra_nand_dev));
+
+ nand_dbg_print(NAND_DBG_WARN, "Reserved %d blocks "
+ "for OS image, %d blocks for bad block replacement.\n",
+ get_res_blk_num_os(),
+ get_res_blk_num_bad_blk());
+
+ res_blks = get_res_blk_num_bad_blk() + get_res_blk_num_os();
+
+ dev->size = (u64)IdentifyDeviceData.PageDataSize *
+ IdentifyDeviceData.PagesPerBlock *
+ (IdentifyDeviceData.wDataBlockNum - res_blks);
+
+ res_blks_os = get_res_blk_num_os();
+
+ spin_lock_init(&dev->qlock);
+
+ dev->tmp_buf = kmalloc(IdentifyDeviceData.PageDataSize, GFP_ATOMIC);
+ if (!dev->tmp_buf) {
+ printk(KERN_ERR "Failed to kmalloc memory in %s Line %d, exit.\n",
+ __FILE__, __LINE__);
+ goto out_vfree;
+ }
+
+ dev->queue = blk_init_queue(GLOB_SBD_request, &dev->qlock);
+ if (dev->queue == NULL) {
+ printk(KERN_ERR
+ "Spectra: Request queue could not be initialized."
+ " Aborting\n ");
+ goto out_vfree;
+ }
+ dev->queue->queuedata = dev;
+
+ /* blk_queue_logical_block_size(dev->queue, SBD_SECTOR_SIZE); */
+ blk_queue_logical_block_size(dev->queue, 512);
+ blk_queue_ordered(dev->queue, QUEUE_ORDERED_DRAIN_FLUSH,
+ SBD_prepare_flush);
+
+ dev->thread = kthread_run(spectra_trans_thread, dev, "nand_thd");
+ if (IS_ERR(dev->thread)) {
+ blk_cleanup_queue(dev->queue);
+ unregister_blkdev(GLOB_SBD_majornum, GLOB_SBD_NAME);
+ return PTR_ERR(dev->thread);
+ }
+
+ dev->gd = alloc_disk(PARTITIONS);
+ if (!dev->gd) {
+ printk(KERN_ERR
+ "Spectra: Could not allocate disk. Aborting \n ");
+ goto out_vfree;
+ }
+ dev->gd->major = GLOB_SBD_majornum;
+ dev->gd->first_minor = which * PARTITIONS;
+ dev->gd->fops = &GLOB_SBD_ops;
+ dev->gd->queue = dev->queue;
+ dev->gd->private_data = dev;
+ snprintf(dev->gd->disk_name, 32, "%s%c", GLOB_SBD_NAME, which + 'a');
+
+ sects = dev->size >> 9;
+ nand_dbg_print(NAND_DBG_WARN, "Capacity sects: %d\n", sects);
+ set_capacity(dev->gd, sects);
+
+#if CMD_DMA
+ cmddma_request_queue[0].req = NULL;
+ cmddma_num_requests = 0;
+ cmddma_num_ftl_requests = 0;
+ init_waitqueue_head(&dev->irq_wait_queue);
+ dev->irq_count = 1;
+#endif
+ add_disk(dev->gd);
+
+ return 0;
+out_vfree:
+ return -ENOMEM;
+}
+
+/*
+static ssize_t show_nand_block_num(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ return snprintf(buf, PAGE_SIZE, "%d\n",
+ (int)IdentifyDeviceData.wDataBlockNum);
+}
+
+static ssize_t show_nand_pages_per_block(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ return snprintf(buf, PAGE_SIZE, "%d\n",
+ (int)IdentifyDeviceData.PagesPerBlock);
+}
+
+static ssize_t show_nand_page_size(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ return snprintf(buf, PAGE_SIZE, "%d\n",
+ (int)IdentifyDeviceData.PageDataSize);
+}
+
+static DEVICE_ATTR(nand_block_num, 0444, show_nand_block_num, NULL);
+static DEVICE_ATTR(nand_pages_per_block, 0444, show_nand_pages_per_block, NULL);
+static DEVICE_ATTR(nand_page_size, 0444, show_nand_page_size, NULL);
+
+static void create_sysfs_entry(struct device *dev)
+{
+ if (device_create_file(dev, &dev_attr_nand_block_num))
+ printk(KERN_ERR "Spectra: "
+ "failed to create sysfs entry nand_block_num.\n");
+ if (device_create_file(dev, &dev_attr_nand_pages_per_block))
+ printk(KERN_ERR "Spectra: "
+ "failed to create sysfs entry nand_pages_per_block.\n");
+ if (device_create_file(dev, &dev_attr_nand_page_size))
+ printk(KERN_ERR "Spectra: "
+ "failed to create sysfs entry nand_page_size.\n");
+}
+*/
+
+static int GLOB_SBD_init(void)
+{
+ int i;
+
+ nand_debug_level = 0; /* Set level value for debug output */
+
+ printk(KERN_ALERT "Spectra: %s\n", GLOB_version);
+
+ mutex_init(&spectra_lock);
+
+ GLOB_SBD_majornum = register_blkdev(0, GLOB_SBD_NAME);
+ if (GLOB_SBD_majornum <= 0) {
+ printk(KERN_ERR "Unable to get the major %d for Spectra",
+ GLOB_SBD_majornum);
+ return -EBUSY;
+ }
+
+ if (PASS != GLOB_FTL_Flash_Init()) {
+ printk(KERN_ERR "Spectra: Unable to Initialize Flash Device. "
+ "Aborting\n");
+ goto out_flash_register;
+ }
+
+ /* create_sysfs_entry(&dev->dev); */
+
+ if (PASS != GLOB_FTL_IdentifyDevice(&IdentifyDeviceData)) {
+ printk(KERN_ERR "Spectra: Unable to Read Flash Device. "
+ "Aborting\n");
+ goto out_flash_register;
+ } else {
+ nand_dbg_print(NAND_DBG_WARN, "In GLOB_SBD_init: "
+ "Num blocks=%d, pagesperblock=%d, "
+ "pagedatasize=%d, ECCBytesPerSector=%d, "
+ "SizeofGlobalMem=%d\n",
+ (int)IdentifyDeviceData.NumBlocks,
+ (int)IdentifyDeviceData.PagesPerBlock,
+ (int)IdentifyDeviceData.PageDataSize,
+ (int)IdentifyDeviceData.wECCBytesPerSector,
+ (int)IdentifyDeviceData.SizeOfGlobalMem);
+ }
+
+ if (IdentifyDeviceData.SizeOfGlobalMem >= LOCAL_MEM_POOL_SIZE) {
+ printk(KERN_ERR "Spectra: Unable to Initialize Memory Pool. "
+ "Aborting\n");
+ goto out_mempool_flash_register;
+ }
+
+ /* mem_pool_ptr = (u8 *)kmalloc(IdentifyDeviceData.SizeOfGlobalMem,
+ * GFP_KERNEL);
+ if (!mem_pool_ptr) {
+ printk(KERN_ERR "Spectra: Unable to Initialize Memory Pool. "
+ "Aborting\n");
+ goto out_mempool_flash_register;
+ }
+ */
+
+ mem_pool_ptr = local_mem_pool;
+
+ if (PASS != GLOB_FTL_Mem_Config(mem_pool_ptr)) {
+ printk(KERN_ERR "Spectra: Unable to Read Flash Device. "
+ "Aborting\n");
+ goto out_mempool_flash_register;
+ }
+
+ printk(KERN_ALERT "Spectra: searching block table, please wait ...\n");
+ if (GLOB_FTL_Init() != PASS) {
+ printk(KERN_ERR "Spectra: Unable to Initialize FTL Layer. "
+ "Aborting\n");
+ goto out_ftl_flash_register;
+ }
+
+ for (i = 0; i < NUM_DEVICES; i++)
+ if (SBD_setup_device(&nand_device[i], i) == -ENOMEM)
+ goto out_ftl_flash_register;
+
+ nand_dbg_print(NAND_DBG_DEBUG,
+ "Spectra: module loaded with major number %d\n",
+ GLOB_SBD_majornum);
+
+ return 0;
+
+out_ftl_flash_register:
+ GLOB_FTL_Cache_Release();
+out_flash_register:
+ GLOB_FTL_Flash_Release();
+ unregister_blkdev(GLOB_SBD_majornum, GLOB_SBD_NAME);
+ /* pci_unregister_driver(&nand_pci_driver); */
+
+out_mempool_flash_register:
+ /* kfree(mem_pool_ptr); */
+
+ printk(KERN_ERR "Spectra: Module load failed.\n");
+ return -ENOMEM;
+}
+
+static void __exit GLOB_SBD_exit(void)
+{
+ int i;
+
+ nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
+ __FILE__, __LINE__, __func__);
+
+ for (i = 0; i < NUM_DEVICES; i++) {
+ struct spectra_nand_dev *dev = &nand_device[i];
+ if (dev->gd) {
+ del_gendisk(dev->gd);
+ put_disk(dev->gd);
+ }
+ if (dev->queue)
+ blk_cleanup_queue(dev->queue);
+ }
+
+ unregister_blkdev(GLOB_SBD_majornum, GLOB_SBD_NAME);
+
+ mutex_lock(&spectra_lock);
+ force_flush_cache();
+ mutex_unlock(&spectra_lock);
+
+ GLOB_FTL_Cache_Release();
+
+ /* kfree(mem_pool_ptr); */
+
+ GLOB_FTL_Flash_Release();
+ /* pci_unregister_driver(&nand_pci_driver); */
+
+ nand_dbg_print(NAND_DBG_DEBUG,
+ "Spectra FTL module (major number %d) unloaded.\n",
+ GLOB_SBD_majornum);
+}
+
+module_init(GLOB_SBD_init);
+module_exit(GLOB_SBD_exit);
diff --git a/drivers/staging/mrst_nand/ffsport.h b/drivers/staging/mrst_nand/ffsport.h
new file mode 100644
index 0000000..58ede43
--- /dev/null
+++ b/drivers/staging/mrst_nand/ffsport.h
@@ -0,0 +1,89 @@
+/*
+ * NAND Flash Controller Device Driver
+ * Copyright (c) 2009, Intel Corporation and its suppliers.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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.
+ *
+ * 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.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+#ifndef _FFSPORT_
+#define _FFSPORT_
+
+#include "ffsdefs.h"
+
+#if defined __GNUC__
+#define PACKED
+#define PACKED_GNU __attribute__ ((packed))
+#define UNALIGNED
+#endif
+
+#include <linux/semaphore.h>
+#include <linux/string.h> /* for strcpy(), stricmp(), etc */
+#include <linux/mm.h> /* for kmalloc(), kfree() */
+#include <linux/vmalloc.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/init.h>
+
+#include <linux/kernel.h> /* printk() */
+#include <linux/fs.h> /* everything... */
+#include <linux/errno.h> /* error codes */
+#include <linux/types.h> /* size_t */
+#include <linux/genhd.h>
+#include <linux/blkdev.h>
+#include <linux/hdreg.h>
+#include <linux/pci.h>
+#include "flash.h"
+
+#define VERBOSE 1
+
+#define NAND_DBG_WARN 1
+#define NAND_DBG_DEBUG 2
+#define NAND_DBG_TRACE 3
+
+extern int nand_debug_level;
+
+#ifdef VERBOSE
+#define nand_dbg_print(level, args...) \
+ do { \
+ if (level <= nand_debug_level) \
+ printk(KERN_ALERT args); \
+ } while (0)
+#else
+#define nand_dbg_print(level, args...)
+#endif
+
+#ifdef SUPPORT_BIG_ENDIAN
+#define INVERTUINT16(w) ((u16)(((u16)(w)) << 8) | \
+ (u16)((u16)(w) >> 8))
+
+#define INVERTUINT32(dw) (((u32)(dw) << 24) | \
+ (((u32)(dw) << 8) & 0x00ff0000) | \
+ (((u32)(dw) >> 8) & 0x0000ff00) | \
+ ((u32)(dw) >> 24))
+#else
+#define INVERTUINT16(w) w
+#define INVERTUINT32(dw) dw
+#endif
+
+extern int GLOB_Calc_Used_Bits(u32 n);
+extern u64 GLOB_u64_Div(u64 addr, u32 divisor);
+extern u64 GLOB_u64_Remainder(u64 addr, u32 divisor_type);
+
+extern void glob_udelay(unsigned long usecs);
+extern void glob_mdelay(unsigned long msecs);
+extern u32 *GLOB_MEMMAP_NOCACHE(unsigned long addr, unsigned long size);
+extern u32 *GLOB_MEMMAP_TOBUS(u32 *ptr);
+
+#endif /* _FFSPORT_ */
diff --git a/drivers/staging/mrst_nand/flash.c b/drivers/staging/mrst_nand/flash.c
new file mode 100644
index 0000000..a2a8f36
--- /dev/null
+++ b/drivers/staging/mrst_nand/flash.c
@@ -0,0 +1,4150 @@
+/*
+ * NAND Flash Controller Device Driver
+ * Copyright (c) 2009, Intel Corporation and its suppliers.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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.
+ *
+ * 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.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+#include "flash.h"
+#include "ffsdefs.h"
+#include "lld.h"
+#if CMD_DMA
+#include "lld_cdma.h"
+#endif
+
+#define NAND_CACHE_INIT_ADDR 0xffffffffffffffffULL
+
+#define BLK_FROM_ADDR(addr) ((u32)(addr >> DeviceInfo.nBitsInBlockDataSize))
+#define PAGE_FROM_ADDR(addr, Block) ((u16)((addr - (u64)Block * \
+ DeviceInfo.wBlockDataSize) >> DeviceInfo.nBitsInPageDataSize))
+
+#define IS_SPARE_BLOCK(blk) (BAD_BLOCK != (pbt[blk] &\
+ BAD_BLOCK) && SPARE_BLOCK == (pbt[blk] & SPARE_BLOCK))
+
+#define IS_DATA_BLOCK(blk) (0 == (pbt[blk] & BAD_BLOCK))
+
+#define IS_DISCARDED_BLOCK(blk) (BAD_BLOCK != (pbt[blk] &\
+ BAD_BLOCK) && DISCARD_BLOCK == (pbt[blk] & DISCARD_BLOCK))
+
+#define IS_BAD_BLOCK(blk) (BAD_BLOCK == (pbt[blk] & BAD_BLOCK))
+
+#define NUM_MEMPOOL_ALLOCS (22 + CACHE_BLOCK_NUMBER)
+
+#if DEBUG_BNDRY
+void debug_boundary_lineno_error(int chnl, int limit, int no,
+ int lineno, char *filename)
+{
+ if (chnl >= limit)
+ printk(KERN_ERR "Boundary Check Fail value %d >= limit %d, "
+ "at %s:%d. Other info:%d. Aborting...\n",
+ chnl, limit, filename, lineno, no);
+}
+/* static int globalmemsize; */
+#endif
+
+static u8 FTL_Cache_If_Hit(u64 dwPageAddr);
+static int FTL_Cache_Read(u64 dwPageAddr);
+static void FTL_Cache_Read_Page(u8 *pData, u64 dwPageAddr,
+ u8 cache_blk);
+static void FTL_Cache_Write_Page(u8 *pData, u64 dwPageAddr,
+ u8 cache_blk, u16 flag);
+static int FTL_Cache_Write(void);
+static int FTL_Cache_Write_Back(u8 *pData, u64 blk_addr);
+static void FTL_Calculate_LRU(void);
+static u32 FTL_Get_Block_Index(u32 wBlockNum);
+
+static int FTL_Search_Block_Table_IN_Block(u32 BT_Block,
+ u8 BT_Tag, u16 *Page);
+static int FTL_Read_Block_Table(void);
+static int FTL_Write_Block_Table(int wForce);
+static int FTL_Write_Block_Table_Data(void);
+static int FTL_Check_Block_Table(int wOldTable);
+static int FTL_Static_Wear_Leveling(void);
+static u32 FTL_Replace_Block_Table(void);
+static int FTL_Write_IN_Progress_Block_Table_Page(void);
+
+static u32 FTL_Get_Page_Num(u64 length);
+static u64 FTL_Get_Physical_Block_Addr(u64 blk_addr);
+
+static u32 FTL_Replace_OneBlock(u32 wBlockNum,
+ u32 wReplaceNum);
+static u32 FTL_Replace_LWBlock(u32 wBlockNum,
+ int *pGarbageCollect);
+static u32 FTL_Replace_MWBlock(void);
+static int FTL_Replace_Block(u64 blk_addr);
+static int FTL_Adjust_Relative_Erase_Count(u32 Index_of_MAX);
+
+static int FTL_Flash_Error_Handle(u8 *pData,
+ u64 old_page_addr, u64 blk_addr);
+
+struct device_info_tag DeviceInfo;
+static u8 *g_pTempBuf;
+u8 *g_pBlockTable;
+u8 *g_pWearCounter;
+u16 *g_pReadCounter;
+static u16 g_wBlockTableOffset;
+static u32 g_wBlockTableIndex;
+static u8 g_cBlockTableStatus;
+u32 *g_pBTBlocks;
+struct flash_cache_tag Cache;
+
+int g_wNumFreeBlocks;
+#if CMD_DMA
+ u8 g_SBDCmdIndex = 0;
+#endif
+static u8 *g_pIPF;
+static u8 bt_flag = FIRST_BT_ID;
+static u8 bt_block_changed;
+
+#if READBACK_VERIFY
+static u8 *g_pCheckBuf;
+#endif
+
+static u8 cache_block_to_write;
+static u8 last_erased = FIRST_BT_ID;
+
+static u8 *g_pMemPool;
+static u8 *g_pMemPoolFree;
+static u8 *g_temp_buf;
+
+static int globalMemSize;
+
+static u8 GC_Called;
+static u8 BT_GC_Called;
+
+#if CMD_DMA
+static u8 FTLCommandCount; /* Init value is 0 */
+u8 *g_pBTDelta;
+u8 *g_pBTDelta_Free;
+u8 *g_pBTStartingCopy;
+u8 *g_pWearCounterCopy;
+u16 *g_pReadCounterCopy;
+u8 *g_pBlockTableCopies;
+u8 *g_pNextBlockTable;
+u8 *g_pCopyBackBufferCopies;
+u8 *g_pCopyBackBufferStart;
+
+#pragma pack(push, 1)
+#pragma pack(1)
+struct BTableChangesDelta {
+ u8 FTLCommandCount;
+ u8 ValidFields;
+ u16 g_wBlockTableOffset;
+ u32 g_wBlockTableIndex;
+ u32 BT_Index;
+ u32 BT_Entry_Value;
+ u32 WC_Index;
+ u8 WC_Entry_Value;
+ u32 RC_Index;
+ u16 RC_Entry_Value;
+};
+
+#pragma pack(pop)
+
+struct BTableChangesDelta *p_BTableChangesDelta;
+#endif
+
+
+#define MARK_BLOCK_AS_BAD(blocknode) (blocknode |= BAD_BLOCK)
+#define MARK_BLK_AS_DISCARD(blk) (blk = (blk & ~SPARE_BLOCK) | DISCARD_BLOCK)
+
+#define FTL_Get_LBAPBA_Table_Mem_Size_Bytes() (DeviceInfo.wDataBlockNum *\
+ sizeof(u32))
+#define FTL_Get_WearCounter_Table_Mem_Size_Bytes() (DeviceInfo.wDataBlockNum *\
+ sizeof(u8))
+#define FTL_Get_ReadCounter_Table_Mem_Size_Bytes() (DeviceInfo.wDataBlockNum *\
+ sizeof(u16))
+#if SUPPORT_LARGE_BLOCKNUM
+#define FTL_Get_LBAPBA_Table_Flash_Size_Bytes() (DeviceInfo.wDataBlockNum *\
+ sizeof(u8) * 3)
+#else
+#define FTL_Get_LBAPBA_Table_Flash_Size_Bytes() (DeviceInfo.wDataBlockNum *\
+ sizeof(u32))
+#endif
+#define FTL_Get_WearCounter_Table_Flash_Size_Bytes \
+ FTL_Get_WearCounter_Table_Mem_Size_Bytes
+#define FTL_Get_ReadCounter_Table_Flash_Size_Bytes \
+ FTL_Get_ReadCounter_Table_Mem_Size_Bytes
+
+static u32 FTL_Get_Block_Table_Flash_Size_Bytes(void)
+{
+ u32 byte_num;
+
+ if (DeviceInfo.MLCDevice) {
+ byte_num = FTL_Get_LBAPBA_Table_Flash_Size_Bytes() +
+ DeviceInfo.wDataBlockNum * sizeof(u8) +
+ DeviceInfo.wDataBlockNum * sizeof(u16);
+ } else {
+ byte_num = FTL_Get_LBAPBA_Table_Flash_Size_Bytes() +
+ DeviceInfo.wDataBlockNum * sizeof(u8);
+ }
+
+ byte_num += 4 * sizeof(u8);
+
+ return byte_num;
+}
+
+static u16 FTL_Get_Block_Table_Flash_Size_Pages(void)
+{
+ return (u16)FTL_Get_Page_Num(FTL_Get_Block_Table_Flash_Size_Bytes());
+}
+
+static int FTL_Copy_Block_Table_To_Flash(u8 *flashBuf, u32 sizeToTx,
+ u32 sizeTxed)
+{
+ u32 wBytesCopied, blk_tbl_size, wBytes;
+ u32 *pbt = (u32 *)g_pBlockTable;
+
+ blk_tbl_size = FTL_Get_LBAPBA_Table_Flash_Size_Bytes();
+ for (wBytes = 0;
+ (wBytes < sizeToTx) && ((wBytes + sizeTxed) < blk_tbl_size);
+ wBytes++) {
+#if SUPPORT_LARGE_BLOCKNUM
+ flashBuf[wBytes] = (u8)(pbt[(wBytes + sizeTxed) / 3]
+ >> (((wBytes + sizeTxed) % 3) ?
+ ((((wBytes + sizeTxed) % 3) == 2) ? 0 : 8) : 16)) & 0xFF;
+#else
+ flashBuf[wBytes] = (u8)(pbt[(wBytes + sizeTxed) / 2]
+ >> (((wBytes + sizeTxed) % 2) ? 0 : 8)) & 0xFF;
+#endif
+ }
+
+ sizeTxed = (sizeTxed > blk_tbl_size) ? (sizeTxed - blk_tbl_size) : 0;
+ blk_tbl_size = FTL_Get_WearCounter_Table_Flash_Size_Bytes();
+ wBytesCopied = wBytes;
+ wBytes = ((blk_tbl_size - sizeTxed) > (sizeToTx - wBytesCopied)) ?
+ (sizeToTx - wBytesCopied) : (blk_tbl_size - sizeTxed);
+ memcpy(flashBuf + wBytesCopied, g_pWearCounter + sizeTxed, wBytes);
+
+ sizeTxed = (sizeTxed > blk_tbl_size) ? (sizeTxed - blk_tbl_size) : 0;
+
+ if (DeviceInfo.MLCDevice) {
+ blk_tbl_size = FTL_Get_ReadCounter_Table_Flash_Size_Bytes();
+ wBytesCopied += wBytes;
+ for (wBytes = 0; ((wBytes + wBytesCopied) < sizeToTx) &&
+ ((wBytes + sizeTxed) < blk_tbl_size); wBytes++)
+ flashBuf[wBytes + wBytesCopied] =
+ (g_pReadCounter[(wBytes + sizeTxed) / 2] >>
+ (((wBytes + sizeTxed) % 2) ? 0 : 8)) & 0xFF;
+ }
+
+ return wBytesCopied + wBytes;
+}
+
+static int FTL_Copy_Block_Table_From_Flash(u8 *flashBuf,
+ u32 sizeToTx, u32 sizeTxed)
+{
+ u32 wBytesCopied, blk_tbl_size, wBytes;
+ u32 *pbt = (u32 *)g_pBlockTable;
+
+ blk_tbl_size = FTL_Get_LBAPBA_Table_Flash_Size_Bytes();
+ for (wBytes = 0; (wBytes < sizeToTx) &&
+ ((wBytes + sizeTxed) < blk_tbl_size); wBytes++) {
+#if SUPPORT_LARGE_BLOCKNUM
+ if (!((wBytes + sizeTxed) % 3))
+ pbt[(wBytes + sizeTxed) / 3] = 0;
+ pbt[(wBytes + sizeTxed) / 3] |=
+ (flashBuf[wBytes] << (((wBytes + sizeTxed) % 3) ?
+ ((((wBytes + sizeTxed) % 3) == 2) ? 0 : 8) : 16));
+#else
+ if (!((wBytes + sizeTxed) % 2))
+ pbt[(wBytes + sizeTxed) / 2] = 0;
+ pbt[(wBytes + sizeTxed) / 2] |=
+ (flashBuf[wBytes] << (((wBytes + sizeTxed) % 2) ?
+ 0 : 8));
+#endif
+ }
+
+ sizeTxed = (sizeTxed > blk_tbl_size) ? (sizeTxed - blk_tbl_size) : 0;
+ blk_tbl_size = FTL_Get_WearCounter_Table_Flash_Size_Bytes();
+ wBytesCopied = wBytes;
+ wBytes = ((blk_tbl_size - sizeTxed) > (sizeToTx - wBytesCopied)) ?
+ (sizeToTx - wBytesCopied) : (blk_tbl_size - sizeTxed);
+ memcpy(g_pWearCounter + sizeTxed, flashBuf + wBytesCopied, wBytes);
+ sizeTxed = (sizeTxed > blk_tbl_size) ? (sizeTxed - blk_tbl_size) : 0;
+
+ if (DeviceInfo.MLCDevice) {
+ wBytesCopied += wBytes;
+ blk_tbl_size = FTL_Get_ReadCounter_Table_Flash_Size_Bytes();
+ for (wBytes = 0; ((wBytes + wBytesCopied) < sizeToTx) &&
+ ((wBytes + sizeTxed) < blk_tbl_size); wBytes++) {
+ if (((wBytes + sizeTxed) % 2))
+ g_pReadCounter[(wBytes + sizeTxed) / 2] = 0;
+ g_pReadCounter[(wBytes + sizeTxed) / 2] |=
+ (flashBuf[wBytes] <<
+ (((wBytes + sizeTxed) % 2) ? 0 : 8));
+ }
+ }
+
+ return wBytesCopied+wBytes;
+}
+
+static int FTL_Insert_Block_Table_Signature(u8 *buf, u8 tag)
+{
+ int i;
+
+ for (i = 0; i < BTSIG_BYTES; i++)
+ buf[BTSIG_OFFSET + i] =
+ ((tag + (i * BTSIG_DELTA) - FIRST_BT_ID) %
+ (1 + LAST_BT_ID-FIRST_BT_ID)) + FIRST_BT_ID;
+
+ return PASS;
+}
+
+static int FTL_Extract_Block_Table_Tag(u8 *buf, u8 **tagarray)
+{
+ static u8 tag[BTSIG_BYTES >> 1];
+ int i, j, k, tagi, tagtemp, status;
+
+ *tagarray = (u8 *)tag;
+ tagi = 0;
+
+ for (i = 0; i < (BTSIG_BYTES - 1); i++) {
+ for (j = i + 1; (j < BTSIG_BYTES) &&
+ (tagi < (BTSIG_BYTES >> 1)); j++) {
+ tagtemp = buf[BTSIG_OFFSET + j] -
+ buf[BTSIG_OFFSET + i];
+ if (tagtemp && !(tagtemp % BTSIG_DELTA)) {
+ tagtemp = (buf[BTSIG_OFFSET + i] +
+ (1 + LAST_BT_ID - FIRST_BT_ID) -
+ (i * BTSIG_DELTA)) %
+ (1 + LAST_BT_ID - FIRST_BT_ID);
+ status = FAIL;
+ for (k = 0; k < tagi; k++) {
+ if (tagtemp == tag[k])
+ status = PASS;
+ }
+
+ if (status == FAIL) {
+ tag[tagi++] = tagtemp;
+ i = (j == (i + 1)) ? i + 1 : i;
+ j = (j == (i + 1)) ? i + 1 : i;
+ }
+ }
+ }
+ }
+
+ return tagi;
+}
+
+
+static int FTL_Execute_SPL_Recovery(void)
+{
+ u32 j, block, blks;
+ u32 *pbt = (u32 *)g_pBlockTable;
+ int ret;
+
+ nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
+ __FILE__, __LINE__, __func__);
+
+ blks = DeviceInfo.wSpectraEndBlock - DeviceInfo.wSpectraStartBlock;
+ for (j = 0; j <= blks; j++) {
+ block = (pbt[j]);
+ if (((block & BAD_BLOCK) != BAD_BLOCK) &&
+ ((block & SPARE_BLOCK) == SPARE_BLOCK)) {
+#if CMD_DMA
+ ret = GLOB_LLD_Erase_Block(block & ~BAD_BLOCK,
+ FTLCommandCount, LLD_CMD_FLAG_MODE_POLL);
+#else
+ ret = GLOB_LLD_Erase_Block(block & ~BAD_BLOCK);
+#endif
+ if (FAIL == ret) {
+ nand_dbg_print(NAND_DBG_WARN,
+ "NAND Program fail in %s, Line %d, "
+ "Function: %s, new Bad Block %d "
+ "generated!\n",
+ __FILE__, __LINE__, __func__,
+ (int)(block & ~BAD_BLOCK));
+ MARK_BLOCK_AS_BAD(pbt[j]);
+ }
+ }
+ }
+
+ return PASS;
+}
+
+/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+* Function: GLOB_FTL_IdentifyDevice
+* Inputs: pointer to identify data structure
+* Outputs: PASS / FAIL
+* Description: the identify data structure is filled in with
+* information for the block driver.
+*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
+int GLOB_FTL_IdentifyDevice(struct spectra_indentfy_dev_tag *dev_data)
+{
+ int status = PASS;
+ int bufMem;
+
+ nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
+ __FILE__, __LINE__, __func__);
+
+ bufMem = (DeviceInfo.wPageDataSize -
+ ((DeviceInfo.wDataBlockNum *
+ (sizeof(u32) + sizeof(u8)
+ + (DeviceInfo.MLCDevice ? sizeof(u16) : 0))) %
+ DeviceInfo.wPageDataSize)) %
+ DeviceInfo.wPageDataSize;
+
+ dev_data->NumBlocks = DeviceInfo.wTotalBlocks;
+ dev_data->PagesPerBlock = DeviceInfo.wPagesPerBlock;
+ dev_data->PageDataSize = DeviceInfo.wPageDataSize;
+ dev_data->wECCBytesPerSector =
+ DeviceInfo.wECCBytesPerSector;
+ dev_data->wDataBlockNum = DeviceInfo.wDataBlockNum;
+
+ dev_data->SizeOfGlobalMem =
+ (DeviceInfo.wDataBlockNum * sizeof(u32) * 2) +
+ (DeviceInfo.wDataBlockNum * sizeof(u8) + 2) +
+ (DeviceInfo.MLCDevice ?
+ (DeviceInfo.wDataBlockNum * sizeof(u16)
+#if CMD_DMA
+ * (1+1+1)
+#endif
+ ) : 0) + bufMem +
+#if (PAGES_PER_CACHE_BLOCK > 0)
+ ((CACHE_BLOCK_NUMBER + 1) * PAGES_PER_CACHE_BLOCK *
+ DeviceInfo.wPageDataSize * sizeof(u8)) +
+#else
+ ((CACHE_BLOCK_NUMBER+1) * DeviceInfo.wPagesPerBlock *
+ DeviceInfo.wPageDataSize * sizeof(u8)) +
+#endif
+ (DeviceInfo.wPageSize*sizeof(u8)) +
+ (DeviceInfo.wPagesPerBlock * DeviceInfo.wPageDataSize * sizeof(u8))
+ +
+#if CMD_DMA
+ (DeviceInfo.wDataBlockNum * sizeof(u32)) +
+ (DeviceInfo.wDataBlockNum * sizeof(u8)) +
+ (5 * ((DeviceInfo.wDataBlockNum * sizeof(u32)) +
+ (DeviceInfo.wDataBlockNum * sizeof(u8)) +
+ (DeviceInfo.wDataBlockNum * sizeof(u16)))) +
+ (MAX_DESCS * sizeof(struct BTableChangesDelta)) +
+ (10 * DeviceInfo.wPagesPerBlock * DeviceInfo.wPageDataSize) +
+#endif
+ ((1 + LAST_BT_ID - FIRST_BT_ID) * sizeof(u32)) +
+ (DeviceInfo.wDataBlockNum) +
+ (DeviceInfo.wPageDataSize * sizeof(u8) * 2) +
+ (((DeviceInfo.wPageSize - DeviceInfo.wPageDataSize) *
+ sizeof(u8)) * 2) +
+ (DeviceInfo.wDataBlockNum) +
+#if !CMD_DMA
+ (DeviceInfo.wPageDataSize * DeviceInfo.wPagesPerBlock *
+ sizeof(u8) * 2) +
+#endif
+ DeviceInfo.wBlockSize + GLOB_LLD_Memory_Pool_Size() +
+ (NUM_MEMPOOL_ALLOCS * sizeof(u8) * 4);
+
+ globalMemSize = dev_data->SizeOfGlobalMem;
+
+ return status;
+}
+/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+* Function: GLOB_FTL_Mem_Config
+* Inputs: pointer to the memory that is allocated
+* Outputs: PASS / FAIL
+* Description: This allows the Block Driver to do the memory allocation
+* and is used in place of the FTL doing malloc's. The
+* Block Driver assigns the length based on data passed
+* to it in the GLOB_FTL_IdentifyDevice function.
+* There is sanity checking that the pointers are not NULL
+* There is no sanity checking for the length. If this
+* becomes neccessary, an additioanl parameter will
+* be needed.
+*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
+int GLOB_FTL_Mem_Config(u8 *pMem)
+{
+ int status = FAIL;
+
+ nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
+ __FILE__, __LINE__, __func__);
+
+ if (pMem != NULL) {
+ g_pMemPool = pMem;
+ status = GLOB_LLD_Mem_Config(pMem + globalMemSize -
+ GLOB_LLD_Memory_Pool_Size());
+ }
+
+ return status;
+}
+
+/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+* Function: GLOB_FTL_Init
+* Inputs: none
+* Outputs: PASS=0 / FAIL=1
+* Description: allocates the memory for cache array,
+* important data structures
+* clears the cache array
+* reads the block table from flash into array
+*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
+int GLOB_FTL_Init(void)
+{
+ int i;
+ int status = PASS;
+
+ nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
+ __FILE__, __LINE__, __func__);
+
+#if (PAGES_PER_CACHE_BLOCK > 0)
+ Cache.wCachePageNum = PAGES_PER_CACHE_BLOCK;
+#else
+ Cache.wCachePageNum = DeviceInfo.wPagesPerBlock;
+#endif
+ Cache.dwCacheDataSize = (u32)Cache.wCachePageNum *
+ DeviceInfo.wPageDataSize;
+
+ g_pMemPoolFree = (u8 *)g_pMemPool;
+
+ g_pBlockTable = (u8 *)g_pMemPoolFree;
+ memset(g_pBlockTable, 0, DeviceInfo.wDataBlockNum * sizeof(u32));
+ g_pMemPoolFree += DeviceInfo.wDataBlockNum * sizeof(u32);
+ ALIGN_DWORD_FWD(g_pMemPoolFree);
+
+ g_pWearCounter = (u8 *)g_pMemPoolFree;
+ memset(g_pWearCounter, 0, DeviceInfo.wDataBlockNum * sizeof(u8));
+ g_pMemPoolFree += DeviceInfo.wDataBlockNum * sizeof(u8);
+ ALIGN_DWORD_FWD(g_pMemPoolFree);
+
+ if (DeviceInfo.MLCDevice) {
+ g_pReadCounter = (u16 *)g_pMemPoolFree;
+ g_pMemPoolFree += DeviceInfo.wDataBlockNum * sizeof(u16);
+ memset(g_pReadCounter, 0,
+ DeviceInfo.wDataBlockNum * sizeof(u16));
+ ALIGN_DWORD_FWD(g_pMemPoolFree);
+ }
+
+ for (i = 0; i < CACHE_BLOCK_NUMBER; i++) {
+ Cache.ItemArray[i].dwAddress = NAND_CACHE_INIT_ADDR;
+ Cache.ItemArray[i].bLRUCount = 0;
+ Cache.ItemArray[i].bChanged = CLEAR;
+ Cache.ItemArray[i].pContent = (u8 *)g_pMemPoolFree;
+ g_pMemPoolFree += Cache.dwCacheDataSize * sizeof(u8);
+ ALIGN_DWORD_FWD(g_pMemPoolFree);
+ }
+
+ g_pIPF = (u8 *)g_pMemPoolFree;
+ g_pMemPoolFree += DeviceInfo.wPageSize * sizeof(u8);
+ memset(g_pIPF, 0, DeviceInfo.wPageSize);
+ ALIGN_DWORD_FWD(g_pMemPoolFree);
+
+ g_pTempBuf = (u8 *)g_pMemPoolFree;
+ g_pMemPoolFree += Cache.dwCacheDataSize * sizeof(u8);
+ ALIGN_DWORD_FWD(g_pMemPoolFree);
+
+ g_temp_buf = (u8 *)g_pMemPoolFree;
+ g_pMemPoolFree += DeviceInfo.wPagesPerBlock *
+ DeviceInfo.wPageDataSize * sizeof(u8);
+ memset(g_temp_buf, 0xFF,
+ DeviceInfo.wPagesPerBlock * DeviceInfo.wPageDataSize);
+ ALIGN_DWORD_FWD(g_pMemPoolFree);
+
+#if CMD_DMA
+ g_pBTStartingCopy = (u8 *)g_pMemPoolFree;
+ g_pMemPoolFree += (DeviceInfo.wDataBlockNum * sizeof(u32));
+ memset(g_pBTStartingCopy, 0, DeviceInfo.wDataBlockNum * sizeof(u32));
+ ALIGN_DWORD_FWD(g_pMemPoolFree);
+
+ g_pWearCounterCopy = (u8 *)g_pMemPoolFree;
+ memset(g_pWearCounterCopy, 0, DeviceInfo.wDataBlockNum * sizeof(u8));
+ g_pMemPoolFree += DeviceInfo.wDataBlockNum * sizeof(u8);
+ ALIGN_DWORD_FWD(g_pMemPoolFree);
+
+ if (DeviceInfo.MLCDevice) {
+ g_pReadCounterCopy = (u16 *)g_pMemPoolFree;
+ g_pMemPoolFree += DeviceInfo.wDataBlockNum * sizeof(u16);
+ memset(g_pReadCounterCopy, 0,
+ DeviceInfo.wDataBlockNum * sizeof(u16));
+ ALIGN_DWORD_FWD(g_pMemPoolFree);
+ }
+
+ g_pBlockTableCopies = (u8 *)g_pMemPoolFree;
+ g_pNextBlockTable = g_pBlockTableCopies;
+
+ if (DeviceInfo.MLCDevice)
+ g_pMemPoolFree += 5 *
+ (DeviceInfo.wDataBlockNum * sizeof(u32) +
+ DeviceInfo.wDataBlockNum * sizeof(u8) +
+ DeviceInfo.wDataBlockNum * sizeof(u16));
+ else
+ g_pMemPoolFree += 5 *
+ (DeviceInfo.wDataBlockNum * sizeof(u32) +
+ DeviceInfo.wDataBlockNum * sizeof(u8));
+
+ ALIGN_DWORD_FWD(g_pMemPoolFree);
+
+ g_pBTDelta = (u8 *)g_pMemPoolFree;
+ g_pMemPoolFree += (MAX_DESCS * sizeof(struct BTableChangesDelta));
+ ALIGN_DWORD_FWD(g_pMemPoolFree);
+
+ FTLCommandCount = 0;
+ g_pBTDelta_Free = (u8 *)g_pBTDelta;
+ g_pCopyBackBufferCopies = (u8 *)g_pMemPoolFree;
+ g_pMemPoolFree += 10 * DeviceInfo.wPagesPerBlock *
+ DeviceInfo.wPageDataSize;
+ ALIGN_DWORD_FWD(g_pMemPoolFree);
+
+ g_pCopyBackBufferStart = g_pCopyBackBufferCopies;
+#endif
+ g_pBTBlocks = (u32 *)g_pMemPoolFree;
+ g_pMemPoolFree += (1 + LAST_BT_ID - FIRST_BT_ID) * sizeof(u32);
+ ALIGN_DWORD_FWD(g_pMemPoolFree);
+ memset(g_pBTBlocks, 0xFF,
+ (1 + LAST_BT_ID - FIRST_BT_ID) * sizeof(u32));
+ debug_boundary_error(((int)g_pMemPoolFree - (int)g_pMemPool) - 1,
+ globalMemSize, 0);
+
+ status = FTL_Read_Block_Table();
+
+#if CMD_DMA
+ FTLCommandCount = 0;
+#endif
+
+ return status;
+}
+
+#if CMD_DMA
+int GLOB_FTL_cdma_int(void)
+{
+ return GLOB_LLD_is_cdma_int();
+}
+
+static void save_blk_table_changes(u16 idx)
+{
+ u8 ftl_cmd;
+ u32 *pbt = (u32 *)g_pBTStartingCopy;
+
+ ftl_cmd = p_BTableChangesDelta->FTLCommandCount;
+
+ while (ftl_cmd <= PendingCMD[idx].Tag) {
+ if (p_BTableChangesDelta->ValidFields == 0x01) {
+ g_wBlockTableOffset =
+ p_BTableChangesDelta->g_wBlockTableOffset;
+ } else if (p_BTableChangesDelta->ValidFields == 0x0C) {
+ pbt[p_BTableChangesDelta->BT_Index] =
+ p_BTableChangesDelta->BT_Entry_Value;
+ debug_boundary_error(((
+ p_BTableChangesDelta->BT_Index)),
+ DeviceInfo.wDataBlockNum, 0);
+ } else if (p_BTableChangesDelta->ValidFields == 0x03) {
+ g_wBlockTableOffset =
+ p_BTableChangesDelta->g_wBlockTableOffset;
+ g_wBlockTableIndex =
+ p_BTableChangesDelta->g_wBlockTableIndex;
+ } else if (p_BTableChangesDelta->ValidFields == 0x30) {
+ g_pWearCounterCopy[p_BTableChangesDelta->WC_Index] =
+ p_BTableChangesDelta->WC_Entry_Value;
+ } else if ((DeviceInfo.MLCDevice) &&
+ (p_BTableChangesDelta->ValidFields == 0xC0)) {
+ g_pReadCounterCopy[p_BTableChangesDelta->RC_Index] =
+ p_BTableChangesDelta->RC_Entry_Value;
+ nand_dbg_print(NAND_DBG_DEBUG,
+ "In event status setting read counter "
+ "GLOB_FTLCommandCount %u Count %u Index %u\n",
+ ftl_cmd,
+ p_BTableChangesDelta->RC_Entry_Value,
+ (unsigned int)p_BTableChangesDelta->RC_Index);
+ } else {
+ nand_dbg_print(NAND_DBG_DEBUG,
+ "This should never occur \n");
+ }
+ p_BTableChangesDelta += 1;
+ ftl_cmd = p_BTableChangesDelta->FTLCommandCount;
+ }
+}
+
+static void discard_cmds(u16 n)
+{
+ u32 *pbt = (u32 *)g_pBTStartingCopy;
+ u8 ftl_cmd;
+ unsigned long k, cn;
+
+ if ((PendingCMD[n].CMD == WRITE_MAIN_CMD) ||
+ (PendingCMD[n].CMD == WRITE_MAIN_SPARE_CMD)) {
+ for (k = 0; k < DeviceInfo.wDataBlockNum; k++) {
+ if (PendingCMD[n].Block == (pbt[k] & (~BAD_BLOCK)))
+ MARK_BLK_AS_DISCARD(pbt[k]);
+ }
+ }
+
+ ftl_cmd = p_BTableChangesDelta->FTLCommandCount;
+ while (ftl_cmd <= PendingCMD[n].Tag) {
+ p_BTableChangesDelta += 1;
+ ftl_cmd = p_BTableChangesDelta->FTLCommandCount;
+ }
+
+ cn = UNHIT_BLOCK;
+ for (k = 0; k < CACHE_BLOCK_NUMBER; k++) {
+ if (PendingCMD[n].DataAddr == Cache.ItemArray[k].pContent) {
+ cn = k;
+ break;
+ }
+ }
+ if (cn < UNHIT_BLOCK) {
+ Cache.ItemArray[cn].dwAddress = NAND_CACHE_INIT_ADDR;
+ Cache.ItemArray[cn].bLRUCount = 0;
+ Cache.ItemArray[cn].bChanged = CLEAR;
+ }
+}
+
+static void process_cmd_pass(int *first_failed_cmd, u16 idx)
+{
+ int is_rw_cmd;
+
+ is_rw_cmd = (PendingCMD[idx].CMD == WRITE_MAIN_CMD) ||
+ (PendingCMD[idx].CMD == WRITE_MAIN_SPARE_CMD) ||
+ (PendingCMD[idx].CMD == READ_MAIN_CMD) ||
+ (PendingCMD[idx].CMD == READ_MAIN_SPARE_CMD);
+
+ if (0 == *first_failed_cmd)
+ save_blk_table_changes(idx);
+ else if (is_rw_cmd)
+ discard_cmds(idx);
+}
+
+static void process_cmd_fail_abort(int *first_failed_cmd,
+ u16 idx, int event)
+{
+ u32 *pbt = (u32 *)g_pBTStartingCopy;
+ u8 ftl_cmd;
+ unsigned long i, k, cn;
+ int erase_fail, program_fail;
+
+ if (0 == *first_failed_cmd)
+ *first_failed_cmd = PendingCMD[idx].SBDCmdIndex;
+
+ nand_dbg_print(NAND_DBG_DEBUG, "Uncorrectable error has occured "
+ "while executing %u Command %u accesing Block %u\n",
+ (unsigned int)p_BTableChangesDelta->FTLCommandCount,
+ PendingCMD[idx].CMD,
+ (unsigned int)PendingCMD[idx].Block);
+
+ ftl_cmd = p_BTableChangesDelta->FTLCommandCount;
+ while (ftl_cmd <= PendingCMD[idx].Tag) {
+ p_BTableChangesDelta += 1;
+ ftl_cmd = p_BTableChangesDelta->FTLCommandCount;
+ }
+
+ if ((PendingCMD[idx].CMD == READ_MAIN_CMD) ||
+ (PendingCMD[idx].CMD == READ_MAIN_SPARE_CMD)) {
+ for (i = 0; i < CACHE_BLOCK_NUMBER; i++) {
+ Cache.ItemArray[i].dwAddress = NAND_CACHE_INIT_ADDR;
+ Cache.ItemArray[i].bLRUCount = 0;
+ Cache.ItemArray[i].bChanged = CLEAR;
+ }
+ } else if ((PendingCMD[idx].CMD == WRITE_MAIN_CMD) ||
+ (PendingCMD[idx].CMD == WRITE_MAIN_SPARE_CMD)) {
+ cn = 0;
+ for (k = 0; k < DeviceInfo.wDataBlockNum; k++) {
+ if (PendingCMD[idx].Block == (pbt[k] & (~BAD_BLOCK))) {
+ Cache.ItemArray[0].dwAddress = (u64)k *
+ DeviceInfo.wBlockDataSize;
+ Cache.ItemArray[0].bLRUCount = 0;
+ Cache.ItemArray[0].bChanged = SET;
+ break;
+ }
+ }
+
+ if (k == DeviceInfo.wDataBlockNum)
+ cn = 0;
+ else
+ cn = 1;
+
+ for (i = cn; i < CACHE_BLOCK_NUMBER; i++) {
+ Cache.ItemArray[i].dwAddress = NAND_CACHE_INIT_ADDR;
+ Cache.ItemArray[i].bLRUCount = 0;
+ Cache.ItemArray[i].bChanged = CLEAR;
+ }
+ }
+
+ erase_fail = (event == EVENT_ERASE_FAILURE) &&
+ (PendingCMD[idx].CMD == ERASE_CMD);
+
+ program_fail = (event == EVENT_PROGRAM_FAILURE) &&
+ ((PendingCMD[idx].CMD == WRITE_MAIN_CMD) ||
+ (PendingCMD[idx].CMD == WRITE_MAIN_SPARE_CMD));
+
+ if (erase_fail || program_fail) {
+ for (i = 0; i < DeviceInfo.wDataBlockNum; i++) {
+ if (PendingCMD[idx].Block ==
+ (pbt[i] & (~BAD_BLOCK)))
+ MARK_BLOCK_AS_BAD(pbt[i]);
+ }
+ }
+}
+
+static void process_cmd(int *first_failed_cmd, u16 idx, int event)
+{
+ u8 ftl_cmd;
+ int cmd_match = 0;
+
+ if (p_BTableChangesDelta->FTLCommandCount == PendingCMD[idx].Tag)
+ cmd_match = 1;
+
+ if (PendingCMD[idx].Status == CMD_PASS) {
+ process_cmd_pass(first_failed_cmd, idx);
+ } else if ((PendingCMD[idx].Status == CMD_FAIL) ||
+ (PendingCMD[idx].Status == CMD_ABORT)) {
+ process_cmd_fail_abort(first_failed_cmd, idx, event);
+ } else if ((PendingCMD[idx].Status == CMD_NOT_DONE) &&
+ PendingCMD[idx].Tag) {
+ nand_dbg_print(NAND_DBG_DEBUG,
+ " Command no. %hu is not executed\n",
+ (unsigned int)PendingCMD[idx].Tag);
+ ftl_cmd = p_BTableChangesDelta->FTLCommandCount;
+ while (ftl_cmd <= PendingCMD[idx].Tag) {
+ p_BTableChangesDelta += 1;
+ ftl_cmd = p_BTableChangesDelta->FTLCommandCount;
+ }
+ }
+}
+
+/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+* Function: GLOB_FTL_Event_Status
+* Inputs: none
+* Outputs: Event Code
+* Description: It is called by SBD after hardware interrupt signalling
+* completion of commands chain
+* It does following things
+* get event status from LLD
+* analyze command chain status
+* determine last command executed
+* analyze results
+* rebuild the block table in case of uncorrectable error
+* return event code
+*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
+int GLOB_FTL_Event_Status(int *first_failed_cmd)
+{
+ int event_code = PASS;
+ u16 i_P;
+
+ nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
+ __FILE__, __LINE__, __func__);
+
+ *first_failed_cmd = 0;
+
+ event_code = GLOB_LLD_Event_Status();
+ nand_dbg_print(NAND_DBG_DEBUG, "Event Code got from lld %d\n",
+ event_code);
+
+ switch (event_code) {
+ case EVENT_PASS:
+ nand_dbg_print(NAND_DBG_DEBUG, "Handling EVENT_PASS\n");
+ break;
+ case EVENT_CORRECTABLE_DATA_ERROR_FIXED:
+ nand_dbg_print(NAND_DBG_DEBUG, "Handling "
+ "EVENT_CORRECTABLE_DATA_ERROR_FIXED");
+ return event_code;
+ case EVENT_UNCORRECTABLE_DATA_ERROR:
+ case EVENT_PROGRAM_FAILURE:
+ case EVENT_ERASE_FAILURE:
+ nand_dbg_print(NAND_DBG_DEBUG, "Handling Ugly case\n");
+ nand_dbg_print(NAND_DBG_DEBUG, "UNCORRECTABLE "
+ "DATA ERROR HAS HAPPENED\n");
+ p_BTableChangesDelta =
+ (struct BTableChangesDelta *)g_pBTDelta;
+ for (i_P = MAX_CHANS; i_P < (FTLCommandCount + MAX_CHANS);
+ i_P++)
+ process_cmd(first_failed_cmd, i_P, event_code);
+ memcpy(g_pBlockTable, g_pBTStartingCopy,
+ DeviceInfo.wDataBlockNum * sizeof(u32));
+ memcpy(g_pWearCounter, g_pWearCounterCopy,
+ DeviceInfo.wDataBlockNum * sizeof(u8));
+ if (DeviceInfo.MLCDevice)
+ memcpy(g_pReadCounter, g_pReadCounterCopy,
+ DeviceInfo.wDataBlockNum * sizeof(u16));
+ FTL_Write_Block_Table(FAIL);
+ break;
+ default:
+ nand_dbg_print(NAND_DBG_DEBUG, "Handling default case\n");
+ event_code = FAIL;
+ break;
+ }
+
+ memcpy(g_pBTStartingCopy, g_pBlockTable,
+ DeviceInfo.wDataBlockNum * sizeof(u32));
+ memcpy(g_pWearCounterCopy, g_pWearCounter,
+ DeviceInfo.wDataBlockNum * sizeof(u8));
+ if (DeviceInfo.MLCDevice)
+ memcpy(g_pReadCounterCopy, g_pReadCounter,
+ DeviceInfo.wDataBlockNum * sizeof(u16));
+
+ g_pBTDelta_Free = g_pBTDelta;
+ FTLCommandCount = 0;
+ g_pNextBlockTable = g_pBlockTableCopies;
+ g_pCopyBackBufferStart = g_pCopyBackBufferCopies;
+
+ return event_code;
+}
+
+/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+* Function: GLOB_FTL_Enable_Disable_Interrupts
+* Inputs: enable or disable
+* Outputs: none
+* Description: pass thru to LLD
+**************************************************************/
+void GLOB_FTL_Enable_Disable_Interrupts(u16 int_enable)
+{
+ nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
+ __FILE__, __LINE__, __func__);
+
+ GLOB_LLD_Enable_Disable_Interrupts(int_enable);
+}
+
+/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+* Function: GLOB_FTL_Execute_CMDS
+* Inputs: none
+* Outputs: none
+* Description: pass thru to LLD
+***************************************************************/
+void GLOB_FTL_Execute_CMDS(void)
+{
+ nand_dbg_print(NAND_DBG_TRACE,
+ "GLOB_FTL_Execute_CMDS: FTLCommandCount %u\n",
+ (unsigned int)FTLCommandCount);
+ g_SBDCmdIndex = 0;
+ GLOB_LLD_Execute_CMDs(FTLCommandCount);
+}
+
+#endif
+
+#if !CMD_DMA
+/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+* Function: GLOB_FTL_Read Immediate
+* Inputs: pointer to data
+* address of data
+* Outputs: PASS / FAIL
+* Description: Reads one page of data into RAM directly from flash without
+* using or disturbing cache.It is assumed this function is called
+* with CMD-DMA disabled.
+*****************************************************************/
+int GLOB_FTL_Read_Immediate(u8 *read_data, u64 addr)
+{
+ int wResult = FAIL;
+ u32 Block;
+ u16 Page;
+ u32 phy_blk;
+ u32 *pbt = (u32 *)g_pBlockTable;
+
+ nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
+ __FILE__, __LINE__, __func__);
+
+ Block = BLK_FROM_ADDR(addr);
+ Page = PAGE_FROM_ADDR(addr, Block);
+
+ if (!IS_SPARE_BLOCK(Block))
+ return FAIL;
+
+ phy_blk = pbt[Block];
+ wResult = GLOB_LLD_Read_Page_Main(read_data, phy_blk, Page, 1);
+
+ if (DeviceInfo.MLCDevice) {
+ g_pReadCounter[phy_blk - DeviceInfo.wSpectraStartBlock]++;
+ if (g_pReadCounter[phy_blk - DeviceInfo.wSpectraStartBlock]
+ >= MAX_READ_COUNTER)
+ FTL_Read_Disturbance(phy_blk);
+ if (g_cBlockTableStatus != IN_PROGRESS_BLOCK_TABLE) {
+ g_cBlockTableStatus = IN_PROGRESS_BLOCK_TABLE;
+ FTL_Write_IN_Progress_Block_Table_Page();
+ }
+ }
+
+ return wResult;
+}
+#endif
+
+#ifdef SUPPORT_BIG_ENDIAN
+/*********************************************************************
+* Function: FTL_Invert_Block_Table
+* Inputs: none
+* Outputs: none
+* Description: Re-format the block table in ram based on BIG_ENDIAN and
+* LARGE_BLOCKNUM if necessary
+**********************************************************************/
+static void FTL_Invert_Block_Table(void)
+{
+ u32 i;
+ u32 *pbt = (u32 *)g_pBlockTable;
+
+ nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
+ __FILE__, __LINE__, __func__);
+
+#ifdef SUPPORT_LARGE_BLOCKNUM
+ for (i = 0; i < DeviceInfo.wDataBlockNum; i++) {
+ pbt[i] = INVERTUINT32(pbt[i]);
+ g_pWearCounter[i] = INVERTUINT32(g_pWearCounter[i]);
+ }
+#else
+ for (i = 0; i < DeviceInfo.wDataBlockNum; i++) {
+ pbt[i] = INVERTUINT16(pbt[i]);
+ g_pWearCounter[i] = INVERTUINT16(g_pWearCounter[i]);
+ }
+#endif
+}
+#endif
+
+/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+* Function: GLOB_FTL_Flash_Init
+* Inputs: none
+* Outputs: PASS=0 / FAIL=0x01 (based on read ID)
+* Description: The flash controller is initialized
+* The flash device is reset
+* Perform a flash READ ID command to confirm that a
+* valid device is attached and active.
+* The DeviceInfo structure gets filled in
+*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
+int GLOB_FTL_Flash_Init(void)
+{
+ int status = FAIL;
+
+ nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
+ __FILE__, __LINE__, __func__);
+
+#if CMD_DMA
+ GLOB_LLD_Flash_Init(LLD_CMD_FLAG_MODE_POLL);
+#else
+ GLOB_LLD_Flash_Init();
+#endif
+ status = GLOB_LLD_Read_Device_ID();
+
+ return status;
+}
+
+/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+* Inputs: none
+* Outputs: PASS=0 / FAIL=0x01 (based on read ID)
+* Description: The flash controller is released
+*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
+int GLOB_FTL_Flash_Release(void)
+{
+ nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
+ __FILE__, __LINE__, __func__);
+
+ return GLOB_LLD_Flash_Release();
+}
+
+
+/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+* Function: GLOB_FTL_Cache_Release
+* Inputs: none
+* Outputs: none
+* Description: release all allocated memory in GLOB_FTL_Init
+* (allocated in GLOB_FTL_Init)
+*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
+void GLOB_FTL_Cache_Release(void)
+{
+ nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
+ __FILE__, __LINE__, __func__);
+ return;
+}
+
+/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+* Function: FTL_Cache_If_Hit
+* Inputs: Page Address
+* Outputs: Block number/UNHIT BLOCK
+* Description: Determines if the addressed page is in cache
+*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
+static u8 FTL_Cache_If_Hit(u64 page_addr)
+{
+ u8 i, blk;
+ u64 addr;
+
+ nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
+ __FILE__, __LINE__, __func__);
+
+ blk = UNHIT_BLOCK;
+ for (i = 0; i < CACHE_BLOCK_NUMBER; i++) {
+ addr = Cache.ItemArray[i].dwAddress;
+ if ((addr <= page_addr) &&
+ (addr + Cache.dwCacheDataSize > page_addr)) {
+ blk = i;
+ break;
+ }
+ }
+
+ return blk;
+}
+
+/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+* Function: FTL_Calculate_LRU
+* Inputs: None
+* Outputs: None
+* Description: Calculate the least recently block in a cache and record its
+* index in bLRU field.
+*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
+static void FTL_Calculate_LRU(void)
+{
+ u8 i, bCurrentLRU, bTempCount;
+
+ nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
+ __FILE__, __LINE__, __func__);
+
+ bCurrentLRU = 0;
+ bTempCount = MAX_BYTE_VALUE;
+
+ for (i = 0; i < CACHE_BLOCK_NUMBER; i++) {
+ if (Cache.ItemArray[i].bLRUCount < bTempCount) {
+ bCurrentLRU = i;
+ bTempCount = Cache.ItemArray[i].bLRUCount;
+ }
+ }
+
+ Cache.bLRU = bCurrentLRU;
+}
+
+/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+* Function: FTL_Cache_Read_Page
+* Inputs: pointer to read buffer,page address and block number in a cache
+* Outputs: None
+* Description: Read the page from the cached block addressed by blocknumber
+*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
+static void FTL_Cache_Read_Page(u8 *pData, u64 dwPageAddr,
+ u8 cache_blk)
+{
+ u8 *pSrc;
+ u64 addr;
+
+ nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
+ __FILE__, __LINE__, __func__);
+
+ addr = Cache.ItemArray[cache_blk].dwAddress;
+ pSrc = Cache.ItemArray[cache_blk].pContent;
+ pSrc += (unsigned long)(((dwPageAddr - addr) >>
+ DeviceInfo.nBitsInPageDataSize) * DeviceInfo.wPageDataSize);
+
+#if CMD_DMA
+ GLOB_LLD_MemCopy_CMD(FTLCommandCount, pData, pSrc,
+ DeviceInfo.wPageDataSize, 0);
+ FTLCommandCount++;
+#else
+ memcpy(pData, pSrc, DeviceInfo.wPageDataSize);
+#endif
+
+ if (Cache.ItemArray[cache_blk].bLRUCount < MAX_BYTE_VALUE)
+ Cache.ItemArray[cache_blk].bLRUCount++;
+}
+
+/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+* Function: FTL_Cache_Read_All
+* Inputs: pointer to read buffer,block address
+* Outputs: PASS=0 / FAIL =1
+* Description: It reads pages in cache
+*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
+static int FTL_Cache_Read_All(u8 *pData, u64 blk_addr)
+{
+ int wResult;
+ u32 Block;
+ u32 lba = BAD_BLOCK;
+ u16 Page;
+ u16 PageCount;
+ u32 *pbt = (u32 *)g_pBlockTable;
+ u32 i;
+
+ nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
+ __FILE__, __LINE__, __func__);
+
+ wResult = PASS;
+
+ Block = BLK_FROM_ADDR(blk_addr);
+ Page = PAGE_FROM_ADDR(blk_addr, Block);
+
+ PageCount = Cache.wCachePageNum;
+
+ nand_dbg_print(NAND_DBG_DEBUG,
+ "FTL_Cache_Read_All: Reading Block %u\n",
+ (unsigned int)Block);
+
+ for (i = 0; i < DeviceInfo.wDataBlockNum; i++) {
+ if (Block == (pbt[i] & (~BAD_BLOCK))) {
+ lba = i;
+ if (IS_SPARE_BLOCK(i) || IS_BAD_BLOCK(i) ||
+ IS_DISCARDED_BLOCK(i)) {
+ /* Add by yunpeng -2008.12.3 */
+#if CMD_DMA
+ GLOB_LLD_MemCopy_CMD(FTLCommandCount,
+ pData, g_temp_buf,
+ PageCount * DeviceInfo.wPageDataSize, 0);
+ FTLCommandCount++;
+#else
+ memset(pData, 0xFF,
+ PageCount * DeviceInfo.wPageDataSize);
+#endif
+ return wResult;
+ } else {
+ continue;
+ }
+ }
+ }
+
+ if (lba == BAD_BLOCK)
+ printk(KERN_ERR "FTL_Cache_Read_All: Block is not found in BT\n");
+
+#if CMD_DMA
+ wResult = GLOB_LLD_Read_Page_Main(pData, Block, Page, PageCount,
+ FTLCommandCount,
+ LLD_CMD_FLAG_MODE_CDMA);
+ if (DeviceInfo.MLCDevice) {
+ g_pReadCounter[Block - DeviceInfo.wSpectraStartBlock]++;
+ nand_dbg_print(NAND_DBG_DEBUG,
+ "Read Counter modified in FTLCommandCount %u"
+ " Block %u Counter%u\n",
+ FTLCommandCount, (unsigned int)Block,
+ g_pReadCounter[Block -
+ DeviceInfo.wSpectraStartBlock]);
+
+ p_BTableChangesDelta =
+ (struct BTableChangesDelta *)g_pBTDelta_Free;
+ g_pBTDelta_Free += sizeof(struct BTableChangesDelta);
+ p_BTableChangesDelta->FTLCommandCount = FTLCommandCount;
+ p_BTableChangesDelta->RC_Index =
+ Block - DeviceInfo.wSpectraStartBlock;
+ p_BTableChangesDelta->RC_Entry_Value =
+ g_pReadCounter[Block - DeviceInfo.wSpectraStartBlock];
+ p_BTableChangesDelta->ValidFields = 0xC0;
+
+ FTLCommandCount++;
+
+ if (g_pReadCounter[Block - DeviceInfo.wSpectraStartBlock] >=
+ MAX_READ_COUNTER)
+ FTL_Read_Disturbance(Block);
+ if (g_cBlockTableStatus != IN_PROGRESS_BLOCK_TABLE) {
+ g_cBlockTableStatus = IN_PROGRESS_BLOCK_TABLE;
+ FTL_Write_IN_Progress_Block_Table_Page();
+ }
+ } else {
+ FTLCommandCount++;
+ }
+#else
+ wResult = GLOB_LLD_Read_Page_Main(pData, Block, Page, PageCount);
+ if (wResult == FAIL)
+ return wResult;
+
+ if (DeviceInfo.MLCDevice) {
+ g_pReadCounter[Block - DeviceInfo.wSpectraStartBlock]++;
+ if (g_pReadCounter[Block - DeviceInfo.wSpectraStartBlock] >=
+ MAX_READ_COUNTER)
+ FTL_Read_Disturbance(Block);
+ if (g_cBlockTableStatus != IN_PROGRESS_BLOCK_TABLE) {
+ g_cBlockTableStatus = IN_PROGRESS_BLOCK_TABLE;
+ FTL_Write_IN_Progress_Block_Table_Page();
+ }
+ }
+#endif
+ return wResult;
+}
+
+/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+* Function: FTL_Cache_Write_All
+* Inputs: pointer to cache in sys memory
+* address of free block in flash
+* Outputs: PASS=0 / FAIL=1
+* Description: writes all the pages of the block in cache to flash
+*
+* NOTE:need to make sure this works ok when cache is limited
+* to a partial block. This is where copy-back would be
+* activated. This would require knowing which pages in the
+* cached block are clean/dirty.Right now we only know if
+* the whole block is clean/dirty.
+*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
+static int FTL_Cache_Write_All(u8 *pData, u64 blk_addr)
+{
+ u16 wResult = PASS;
+ u32 Block;
+ u16 Page;
+ u16 PageCount;
+
+ nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
+ __FILE__, __LINE__, __func__);
+
+ nand_dbg_print(NAND_DBG_DEBUG, "This block %d going to be written "
+ "on %d\n", cache_block_to_write,
+ (u32)(blk_addr >> DeviceInfo.nBitsInBlockDataSize));
+
+ Block = BLK_FROM_ADDR(blk_addr);
+ Page = PAGE_FROM_ADDR(blk_addr, Block);
+ PageCount = Cache.wCachePageNum;
+
+#if CMD_DMA
+ if (FAIL == GLOB_LLD_Write_Page_Main(pData, Block, Page, PageCount,
+ FTLCommandCount)) {
+ nand_dbg_print(NAND_DBG_WARN,
+ "NAND Program fail in %s, Line %d, "
+ "Function: %s, new Bad Block %d generated! "
+ "Need Bad Block replacing.\n",
+ __FILE__, __LINE__, __func__, Block);
+ wResult = FAIL;
+ }
+ FTLCommandCount++;
+#else
+ if (FAIL == GLOB_LLD_Write_Page_Main(pData, Block, Page, PageCount)) {
+ nand_dbg_print(NAND_DBG_WARN, "NAND Program fail in %s,"
+ " Line %d, Function %s, new Bad Block %d generated!"
+ "Need Bad Block replacing.\n",
+ __FILE__, __LINE__, __func__, Block);
+ wResult = FAIL;
+ }
+#endif
+ return wResult;
+}
+
+/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+* Function: FTL_Cache_Update_Block
+* Inputs: pointer to buffer,page address,block address
+* Outputs: PASS=0 / FAIL=1
+* Description: It updates the cache
+*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
+static int FTL_Cache_Update_Block(u8 *pData,
+ u64 old_page_addr, u64 blk_addr)
+{
+ int i, j;
+ u8 *buf = pData;
+ int wResult = PASS;
+ int wFoundInCache;
+ u64 page_addr;
+ u64 addr;
+ u64 old_blk_addr;
+ u16 page_offset;
+
+ nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
+ __FILE__, __LINE__, __func__);
+
+ old_blk_addr = (u64)(old_page_addr >>
+ DeviceInfo.nBitsInBlockDataSize) * DeviceInfo.wBlockDataSize;
+ page_offset = (u16)(GLOB_u64_Remainder(old_page_addr, 2) >>
+ DeviceInfo.nBitsInPageDataSize);
+
+ for (i = 0; i < DeviceInfo.wPagesPerBlock; i += Cache.wCachePageNum) {
+ page_addr = old_blk_addr + i * DeviceInfo.wPageDataSize;
+ if (i != page_offset) {
+ wFoundInCache = FAIL;
+ for (j = 0; j < CACHE_BLOCK_NUMBER; j++) {
+ addr = Cache.ItemArray[j].dwAddress;
+ addr = FTL_Get_Physical_Block_Addr(addr) +
+ GLOB_u64_Remainder(addr, 2);
+ if ((addr >= page_addr) && addr <
+ (page_addr + Cache.dwCacheDataSize)) {
+ wFoundInCache = PASS;
+ buf = Cache.ItemArray[j].pContent;
+ Cache.ItemArray[j].bChanged = SET;
+ break;
+ }
+ }
+ if (FAIL == wFoundInCache) {
+ if (ERR == FTL_Cache_Read_All(g_pTempBuf,
+ page_addr)) {
+ wResult = FAIL;
+ break;
+ }
+ buf = g_pTempBuf;
+ }
+ } else {
+ buf = pData;
+ }
+
+ if (FAIL == FTL_Cache_Write_All(buf,
+ blk_addr + (page_addr - old_blk_addr))) {
+ wResult = FAIL;
+ break;
+ }
+ }
+
+ return wResult;
+}
+
+/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+* Function: FTL_Copy_Block
+* Inputs: source block address
+* Destination block address
+* Outputs: PASS=0 / FAIL=1
+* Description: used only for static wear leveling to move the block
+* containing static data to new blocks(more worn)
+*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
+int FTL_Copy_Block(u64 old_blk_addr, u64 blk_addr)
+{
+ int i, r1, r2, wResult = PASS;
+
+ nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
+ __FILE__, __LINE__, __func__);
+
+ for (i = 0; i < DeviceInfo.wPagesPerBlock; i += Cache.wCachePageNum) {
+ r1 = FTL_Cache_Read_All(g_pTempBuf, old_blk_addr +
+ i * DeviceInfo.wPageDataSize);
+ r2 = FTL_Cache_Write_All(g_pTempBuf, blk_addr +
+ i * DeviceInfo.wPageDataSize);
+ if ((ERR == r1) || (FAIL == r2)) {
+ wResult = FAIL;
+ break;
+ }
+ }
+
+ return wResult;
+}
+
+/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+* Function: FTL_Cache_Write_Back
+* Inputs: pointer to data cached in sys memory
+* address of free block in flash
+* Outputs: PASS=0 / FAIL=1
+* Description: writes all the pages of Cache Block to flash
+*
+*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
+static int FTL_Cache_Write_Back(u8 *pData, u64 blk_addr)
+{
+ int i, j, iErase;
+ u64 old_page_addr, addr, phy_addr;
+ u32 *pbt = (u32 *)g_pBlockTable;
+ u32 lba;
+
+ nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
+ __FILE__, __LINE__, __func__);
+
+ old_page_addr = FTL_Get_Physical_Block_Addr(blk_addr) +
+ GLOB_u64_Remainder(blk_addr, 2);
+
+ iErase = (FAIL == FTL_Replace_Block(blk_addr)) ? PASS : FAIL;
+
+ pbt[BLK_FROM_ADDR(blk_addr)] &= (~SPARE_BLOCK);
+
+#if CMD_DMA
+ p_BTableChangesDelta = (struct BTableChangesDelta *)g_pBTDelta_Free;
+ g_pBTDelta_Free += sizeof(struct BTableChangesDelta);
+
+ p_BTableChangesDelta->FTLCommandCount = FTLCommandCount;
+ p_BTableChangesDelta->BT_Index = (u32)(blk_addr >>
+ DeviceInfo.nBitsInBlockDataSize);
+ p_BTableChangesDelta->BT_Entry_Value =
+ pbt[(u32)(blk_addr >> DeviceInfo.nBitsInBlockDataSize)];
+ p_BTableChangesDelta->ValidFields = 0x0C;
+#endif
+
+ if (IN_PROGRESS_BLOCK_TABLE != g_cBlockTableStatus) {
+ g_cBlockTableStatus = IN_PROGRESS_BLOCK_TABLE;
+ FTL_Write_IN_Progress_Block_Table_Page();
+ }
+
+ for (i = 0; i < RETRY_TIMES; i++) {
+ if (PASS == iErase) {
+ phy_addr = FTL_Get_Physical_Block_Addr(blk_addr);
+ if (FAIL == GLOB_FTL_Block_Erase(phy_addr)) {
+ lba = BLK_FROM_ADDR(blk_addr);
+ MARK_BLOCK_AS_BAD(pbt[lba]);
+ i = RETRY_TIMES;
+ break;
+ }
+ }
+
+ for (j = 0; j < CACHE_BLOCK_NUMBER; j++) {
+ addr = Cache.ItemArray[j].dwAddress;
+ if ((addr <= blk_addr) &&
+ ((addr + Cache.dwCacheDataSize) > blk_addr))
+ cache_block_to_write = j;
+ }
+
+ phy_addr = FTL_Get_Physical_Block_Addr(blk_addr);
+ if (PASS == FTL_Cache_Update_Block(pData,
+ old_page_addr, phy_addr)) {
+ cache_block_to_write = UNHIT_BLOCK;
+ break;
+ } else {
+ iErase = PASS;
+ }
+ }
+
+ if (i >= RETRY_TIMES) {
+ if (ERR == FTL_Flash_Error_Handle(pData,
+ old_page_addr, blk_addr))
+ return ERR;
+ else
+ return FAIL;
+ }
+
+ return PASS;
+}
+
+/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+* Function: FTL_Cache_Write_Page
+* Inputs: Pointer to buffer, page address, cache block number
+* Outputs: PASS=0 / FAIL=1
+* Description: It writes the data in Cache Block
+*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
+static void FTL_Cache_Write_Page(u8 *pData, u64 page_addr,
+ u8 cache_blk, u16 flag)
+{
+ u8 *pDest;
+ u64 addr;
+
+ nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
+ __FILE__, __LINE__, __func__);
+
+ addr = Cache.ItemArray[cache_blk].dwAddress;
+ pDest = Cache.ItemArray[cache_blk].pContent;
+
+ pDest += (unsigned long)(page_addr - addr);
+ Cache.ItemArray[cache_blk].bChanged = SET;
+#if CMD_DMA
+ GLOB_LLD_MemCopy_CMD(FTLCommandCount, pDest, pData,
+ DeviceInfo.wPageDataSize, flag);
+ FTLCommandCount++;
+#else
+ memcpy(pDest, pData, DeviceInfo.wPageDataSize);
+#endif
+ if (Cache.ItemArray[cache_blk].bLRUCount < MAX_BYTE_VALUE)
+ Cache.ItemArray[cache_blk].bLRUCount++;
+}
+
+/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+* Function: FTL_Cache_Write
+* Inputs: none
+* Outputs: PASS=0 / FAIL=1
+* Description: It writes least frequently used Cache block to flash if it
+* has been changed
+*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
+static int FTL_Cache_Write(void)
+{
+ int i, bResult = PASS;
+ u8 bNO, least_count = 0xFF;
+
+ nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
+ __FILE__, __LINE__, __func__);
+
+ FTL_Calculate_LRU();
+
+ bNO = Cache.bLRU;
+ nand_dbg_print(NAND_DBG_DEBUG, "FTL_Cache_Write: "
+ "Least used cache block is %d\n", bNO);
+
+ if (SET == Cache.ItemArray[bNO].bChanged) {
+ nand_dbg_print(NAND_DBG_DEBUG, "FTL_Cache_Write: Cache"
+ " Block %d containing logical block %d is dirty\n",
+ bNO,
+ (u32)(Cache.ItemArray[bNO].dwAddress >>
+ DeviceInfo.nBitsInBlockDataSize));
+ bResult = FTL_Cache_Write_Back(Cache.ItemArray[bNO].pContent,
+ Cache.ItemArray[bNO].dwAddress);
+ if (bResult != ERR)
+ Cache.ItemArray[bNO].bChanged = CLEAR;
+
+ least_count = Cache.ItemArray[bNO].bLRUCount;
+
+ for (i = 0; i < CACHE_BLOCK_NUMBER; i++) {
+ if (i == bNO)
+ continue;
+ if (Cache.ItemArray[i].bLRUCount > 0)
+ Cache.ItemArray[i].bLRUCount -= least_count;
+ }
+ }
+
+ return bResult;
+}
+
+/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+* Function: FTL_Cache_Read
+* Inputs: Page address
+* Outputs: PASS=0 / FAIL=1
+* Description: It reads the block from device in Cache Bllock
+* Set the LRU count to 1
+* Mark the Cache Block as clean
+*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
+static int FTL_Cache_Read(u64 page_addr)
+{
+ u64 addr;
+ u8 bNO = Cache.bLRU;
+
+ nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
+ __FILE__, __LINE__, __func__);
+
+ addr = (u64)GLOB_u64_Div(page_addr, Cache.dwCacheDataSize)
+ * Cache.dwCacheDataSize;
+ Cache.ItemArray[bNO].bLRUCount = 1;
+ Cache.ItemArray[bNO].dwAddress = addr;
+ Cache.ItemArray[bNO].bChanged = CLEAR;
+
+ nand_dbg_print(NAND_DBG_DEBUG, "FTL_Cache_Read: Logical Block %d "
+ "is read into cache block no. %d\n",
+ (u32)GLOB_u64_Div(Cache.ItemArray[bNO].dwAddress,
+ Cache.dwCacheDataSize),
+ bNO);
+
+ return FTL_Cache_Read_All(Cache.ItemArray[bNO].pContent,
+ FTL_Get_Physical_Block_Addr(addr) +
+ GLOB_u64_Remainder(addr, 2));
+}
+
+/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+* Function: FTL_Check_Block_Table
+* Inputs: ?
+* Outputs: PASS=0 / FAIL=1
+* Description: It checks the correctness of each block table entry
+*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
+static int FTL_Check_Block_Table(int wOldTable)
+{
+ u32 i;
+ int wResult = PASS;
+ u32 blk_idx;
+ u32 *pbt = (u32 *)g_pBlockTable;
+
+ u8 *pFlag = g_pMemPoolFree;
+ g_pMemPoolFree += (DeviceInfo.wDataBlockNum);
+ ALIGN_DWORD_FWD(g_pMemPoolFree);
+ debug_boundary_error(((int)g_pMemPoolFree - (int)g_pMemPool) - 1,
+ globalMemSize, 0);
+
+ nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
+ __FILE__, __LINE__, __func__);
+
+ if (NULL != pFlag) {
+ memset(pFlag, FAIL, DeviceInfo.wDataBlockNum);
+ for (i = 0; i < DeviceInfo.wDataBlockNum; i++) {
+ blk_idx = (u32)(pbt[i] & (~BAD_BLOCK));
+
+ /*
+ * 20081006/KBV - Changed to pFlag[i] reference
+ * to avoid buffer overflow
+ */
+
+ /*
+ * 2008-10-20 Yunpeng Note: This change avoid
+ * buffer overflow, but changed function of
+ * the code, so it should be re-write later
+ */
+ if ((blk_idx > DeviceInfo.wSpectraEndBlock) ||
+ PASS == pFlag[i]) {
+ wResult = FAIL;
+ break;
+ } else {
+ pFlag[i] = PASS;
+ }
+ }
+ g_pMemPoolFree -= (DeviceInfo.wDataBlockNum);
+ ALIGN_DWORD_BWD(g_pMemPoolFree);
+ }
+ return wResult;
+}
+
+
+/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+* Function: FTL_Write_Block_Table
+* Inputs: flasg
+* Outputs: 0=Block Table was updated. No write done. 1=Block write needs to
+* happen. -1 Error
+* Description: It writes the block table
+* Block table always mapped to LBA 0 which inturn mapped
+* to any physical block
+*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
+static int FTL_Write_Block_Table(int wForce)
+{
+ u32 *pbt = (u32 *)g_pBlockTable;
+ int wSuccess = PASS;
+ u32 wTempBlockTableIndex;
+ u16 bt_pages, new_bt_offset;
+ u8 blockchangeoccured = 0;
+
+ nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
+ __FILE__, __LINE__, __func__);
+
+ bt_pages = FTL_Get_Block_Table_Flash_Size_Pages();
+
+ if (IN_PROGRESS_BLOCK_TABLE != g_cBlockTableStatus)
+ return 0;
+
+ if (PASS == wForce) {
+ g_wBlockTableOffset =
+ (u16)(DeviceInfo.wPagesPerBlock - bt_pages);
+#if CMD_DMA
+ p_BTableChangesDelta =
+ (struct BTableChangesDelta *)g_pBTDelta_Free;
+ g_pBTDelta_Free += sizeof(struct BTableChangesDelta);
+
+ p_BTableChangesDelta->FTLCommandCount = FTLCommandCount;
+ p_BTableChangesDelta->g_wBlockTableOffset =
+ g_wBlockTableOffset;
+ p_BTableChangesDelta->ValidFields = 0x01;
+#endif
+ }
+
+ nand_dbg_print(NAND_DBG_DEBUG,
+ "Inside FTL_Write_Block_Table: block %d Page:%d\n",
+ g_wBlockTableIndex, g_wBlockTableOffset);
+
+ do {
+ new_bt_offset = g_wBlockTableOffset + bt_pages + 1;
+ if ((0 == (new_bt_offset % DeviceInfo.wPagesPerBlock)) ||
+ (new_bt_offset > DeviceInfo.wPagesPerBlock) ||
+ (FAIL == wSuccess)) {
+ wTempBlockTableIndex = FTL_Replace_Block_Table();
+ if (BAD_BLOCK == wTempBlockTableIndex)
+ return ERR;
+ if (!blockchangeoccured) {
+ bt_block_changed = 1;
+ blockchangeoccured = 1;
+ }
+
+ g_wBlockTableIndex = wTempBlockTableIndex;
+ g_wBlockTableOffset = 0;
+ pbt[BLOCK_TABLE_INDEX] = g_wBlockTableIndex;
+#if CMD_DMA
+ p_BTableChangesDelta =
+ (struct BTableChangesDelta *)g_pBTDelta_Free;
+ g_pBTDelta_Free += sizeof(struct BTableChangesDelta);
+
+ p_BTableChangesDelta->FTLCommandCount =
+ FTLCommandCount;
+ p_BTableChangesDelta->g_wBlockTableOffset =
+ g_wBlockTableOffset;
+ p_BTableChangesDelta->g_wBlockTableIndex =
+ g_wBlockTableIndex;
+ p_BTableChangesDelta->ValidFields = 0x03;
+
+ p_BTableChangesDelta =
+ (struct BTableChangesDelta *)g_pBTDelta_Free;
+ g_pBTDelta_Free +=
+ sizeof(struct BTableChangesDelta);
+
+ p_BTableChangesDelta->FTLCommandCount =
+ FTLCommandCount;
+ p_BTableChangesDelta->BT_Index =
+ BLOCK_TABLE_INDEX;
+ p_BTableChangesDelta->BT_Entry_Value =
+ pbt[BLOCK_TABLE_INDEX];
+ p_BTableChangesDelta->ValidFields = 0x0C;
+#endif
+ }
+
+ wSuccess = FTL_Write_Block_Table_Data();
+ if (FAIL == wSuccess)
+ MARK_BLOCK_AS_BAD(pbt[BLOCK_TABLE_INDEX]);
+ } while (FAIL == wSuccess);
+
+ g_cBlockTableStatus = CURRENT_BLOCK_TABLE;
+
+ return 1;
+}
+
+/******************************************************************
+* Function: GLOB_FTL_Flash_Format
+* Inputs: none
+* Outputs: PASS
+* Description: The block table stores bad block info, including MDF+
+* blocks gone bad over the ages. Therefore, if we have a
+* block table in place, then use it to scan for bad blocks
+* If not, then scan for MDF.
+* Now, a block table will only be found if spectra was already
+* being used. For a fresh flash, we'll go thru scanning for
+* MDF. If spectra was being used, then there is a chance that
+* the MDF has been corrupted. Spectra avoids writing to the
+* first 2 bytes of the spare area to all pages in a block. This
+* covers all known flash devices. However, since flash
+* manufacturers have no standard of where the MDF is stored,
+* this cannot guarantee that the MDF is protected for future
+* devices too. The initial scanning for the block table assures
+* this. It is ok even if the block table is outdated, as all
+* we're looking for are bad block markers.
+* Use this when mounting a file system or starting a
+* new flash.
+*
+*********************************************************************/
+static int FTL_Format_Flash(u8 valid_block_table)
+{
+ u32 i, j;
+ u32 *pbt = (u32 *)g_pBlockTable;
+ u32 tempNode;
+ int ret;
+
+#if CMD_DMA
+ u32 *pbtStartingCopy = (u32 *)g_pBTStartingCopy;
+ if (FTLCommandCount)
+ return FAIL;
+#endif
+
+ if (FAIL == FTL_Check_Block_Table(FAIL))
+ valid_block_table = 0;
+
+ if (valid_block_table) {
+ u8 switched = 1;
+ u32 block, k;
+
+ k = DeviceInfo.wSpectraStartBlock;
+ while (switched && (k < DeviceInfo.wSpectraEndBlock)) {
+ switched = 0;
+ k++;
+ for (j = DeviceInfo.wSpectraStartBlock, i = 0;
+ j <= DeviceInfo.wSpectraEndBlock;
+ j++, i++) {
+ block = (pbt[i] & ~BAD_BLOCK) -
+ DeviceInfo.wSpectraStartBlock;
+ if (block != i) {
+ switched = 1;
+ tempNode = pbt[i];
+ pbt[i] = pbt[block];
+ pbt[block] = tempNode;
+ }
+ }
+ }
+ if ((k == DeviceInfo.wSpectraEndBlock) && switched)
+ valid_block_table = 0;
+ }
+
+ if (!valid_block_table) {
+ memset(g_pBlockTable, 0,
+ DeviceInfo.wDataBlockNum * sizeof(u32));
+ memset(g_pWearCounter, 0,
+ DeviceInfo.wDataBlockNum * sizeof(u8));
+ if (DeviceInfo.MLCDevice)
+ memset(g_pReadCounter, 0,
+ DeviceInfo.wDataBlockNum * sizeof(u16));
+#if CMD_DMA
+ memset(g_pBTStartingCopy, 0,
+ DeviceInfo.wDataBlockNum * sizeof(u32));
+ memset(g_pWearCounterCopy, 0,
+ DeviceInfo.wDataBlockNum * sizeof(u8));
+ if (DeviceInfo.MLCDevice)
+ memset(g_pReadCounterCopy, 0,
+ DeviceInfo.wDataBlockNum * sizeof(u16));
+#endif
+
+#if READ_BADBLOCK_INFO
+ for (j = DeviceInfo.wSpectraStartBlock, i = 0;
+ j <= DeviceInfo.wSpectraEndBlock;
+ j++, i++) {
+ if (GLOB_LLD_Get_Bad_Block((u32)j))
+ pbt[i] = (u32)(BAD_BLOCK | j);
+ }
+#endif
+ }
+
+ nand_dbg_print(NAND_DBG_WARN, "Erasing all blocks in the NAND\n");
+
+ for (j = DeviceInfo.wSpectraStartBlock, i = 0;
+ j <= DeviceInfo.wSpectraEndBlock;
+ j++, i++) {
+ if ((pbt[i] & BAD_BLOCK) != BAD_BLOCK) {
+#if CMD_DMA
+ ret = GLOB_LLD_Erase_Block(j, FTLCommandCount,
+ LLD_CMD_FLAG_MODE_POLL);
+#else
+ ret = GLOB_LLD_Erase_Block(j);
+#endif
+ if (FAIL == ret) {
+ pbt[i] = (u32)(j);
+ MARK_BLOCK_AS_BAD(pbt[i]);
+ nand_dbg_print(NAND_DBG_WARN,
+ "NAND Program fail in %s, Line %d, "
+ "Function: %s, new Bad Block %d generated!\n",
+ __FILE__, __LINE__, __func__, (int)j);
+ } else {
+ pbt[i] = (u32)(SPARE_BLOCK | j);
+ }
+ }
+#if CMD_DMA
+ pbtStartingCopy[i] = pbt[i];
+#endif
+ }
+
+ g_wBlockTableOffset = 0;
+ for (i = 0; (i <= (DeviceInfo.wSpectraEndBlock -
+ DeviceInfo.wSpectraStartBlock))
+ && ((pbt[i] & BAD_BLOCK) == BAD_BLOCK); i++)
+ ;
+ if (i > (DeviceInfo.wSpectraEndBlock - DeviceInfo.wSpectraStartBlock)) {
+ printk(KERN_ERR "All blocks bad!\n");
+ return FAIL;
+ } else {
+ g_wBlockTableIndex = pbt[i] & ~BAD_BLOCK;
+ if (i != BLOCK_TABLE_INDEX) {
+ tempNode = pbt[i];
+ pbt[i] = pbt[BLOCK_TABLE_INDEX];
+ pbt[BLOCK_TABLE_INDEX] = tempNode;
+ }
+ }
+ pbt[BLOCK_TABLE_INDEX] &= (~SPARE_BLOCK);
+
+#if CMD_DMA
+ pbtStartingCopy[BLOCK_TABLE_INDEX] &= (~SPARE_BLOCK);
+#endif
+
+ g_cBlockTableStatus = IN_PROGRESS_BLOCK_TABLE;
+ memset(g_pBTBlocks, 0xFF,
+ (1 + LAST_BT_ID - FIRST_BT_ID) * sizeof(u32));
+ g_pBTBlocks[FIRST_BT_ID-FIRST_BT_ID] = g_wBlockTableIndex;
+ FTL_Write_Block_Table(FAIL);
+
+ for (i = 0; i < CACHE_BLOCK_NUMBER; i++) {
+ Cache.ItemArray[i].dwAddress = NAND_CACHE_INIT_ADDR;
+ Cache.ItemArray[i].bLRUCount = 0;
+ Cache.ItemArray[i].bChanged = CLEAR;
+ }
+
+ return PASS;
+}
+
+int GLOB_FTL_Flash_Format(void)
+{
+ return FTL_Format_Flash(1);
+}
+
+/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+* Function: FTL_Search_Block_Table_IN_Block
+* Inputs: Block Number
+* Pointer to page
+* Outputs: PASS / FAIL
+* Page contatining the block table
+* Description: It searches the block table in the block
+* passed as an argument.
+*
+*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
+static int FTL_Search_Block_Table_IN_Block(u32 BT_Block,
+ u8 BT_Tag, u16 *Page)
+{
+ u16 i, j, k;
+ u16 Result = PASS;
+ u16 Last_IPF = 0;
+ u8 BT_Found = 0;
+ u8 *tempbuf, *tagarray;
+ u8 *pSpareBuf;
+ u8 *pSpareBufBTLastPage;
+ u8 bt_flag_last_page = 0xFF;
+ u8 search_in_previous_pages = 0;
+ u16 bt_pages;
+
+ nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
+ __FILE__, __LINE__, __func__);
+
+ bt_pages = FTL_Get_Block_Table_Flash_Size_Pages();
+
+ tempbuf = g_pMemPoolFree;
+ g_pMemPoolFree += (DeviceInfo.wPageDataSize*sizeof(u8));
+ ALIGN_DWORD_FWD(g_pMemPoolFree);
+ pSpareBuf = g_pMemPoolFree;
+ g_pMemPoolFree += (DeviceInfo.wPageSize - DeviceInfo.wPageDataSize) *
+ sizeof(u8);
+ ALIGN_DWORD_FWD(g_pMemPoolFree);
+ pSpareBufBTLastPage = g_pMemPoolFree;
+ g_pMemPoolFree += (DeviceInfo.wPageSize - DeviceInfo.wPageDataSize) *
+ sizeof(u8);
+ ALIGN_DWORD_FWD(g_pMemPoolFree);
+ debug_boundary_error(((int)g_pMemPoolFree - (int)g_pMemPool) - 1,
+ globalMemSize, 0);
+
+ nand_dbg_print(NAND_DBG_DEBUG,
+ "FTL_Search_Block_Table_IN_Block: "
+ "Searching block table in %u block\n",
+ (unsigned int)BT_Block);
+
+ for (i = bt_pages; i < DeviceInfo.wPagesPerBlock;
+ i += (bt_pages + 1)) {
+#if CMD_DMA
+ nand_dbg_print(NAND_DBG_DEBUG,
+ "Searching last IPF: %d\n", i);
+ Result = GLOB_LLD_Read_Page_Main(tempbuf,
+ BT_Block, i, 1, FTLCommandCount,
+ LLD_CMD_FLAG_MODE_POLL);
+#else
+ nand_dbg_print(NAND_DBG_DEBUG,
+ "Searching last IPF: %d\n", i);
+ Result = GLOB_LLD_Read_Page_Main_Polling(tempbuf,
+ BT_Block, i, 1);
+#endif
+ if (0 == memcmp(tempbuf, g_pIPF, DeviceInfo.wPageDataSize)) {
+ if ((i + bt_pages + 1) < DeviceInfo.wPagesPerBlock) {
+ continue;
+ } else {
+ search_in_previous_pages = 1;
+ Last_IPF = i;
+ }
+ }
+
+ if (!search_in_previous_pages) {
+ if (i != bt_pages) {
+ i -= (bt_pages + 1);
+ Last_IPF = i;
+ }
+ }
+
+ if (0 == Last_IPF)
+ break;
+
+ if (!search_in_previous_pages) {
+ i = i + 1;
+ nand_dbg_print(NAND_DBG_DEBUG,
+ "Reading the spare area of Block %u Page %u",
+ (unsigned int)BT_Block, i);
+ Result = GLOB_LLD_Read_Page_Spare(pSpareBuf,
+ BT_Block, i, 1);
+ nand_dbg_print(NAND_DBG_DEBUG,
+ "Reading the spare area of Block %u Page %u",
+ (unsigned int)BT_Block, i + bt_pages - 1);
+ Result = GLOB_LLD_Read_Page_Spare(pSpareBufBTLastPage,
+ BT_Block, i + bt_pages - 1, 1);
+
+ k = 0;
+ j = FTL_Extract_Block_Table_Tag(pSpareBuf, &tagarray);
+ if (j) {
+ for (; k < j; k++) {
+ if (tagarray[k] == BT_Tag)
+ break;
+ }
+ }
+
+ if (k < j)
+ bt_flag = tagarray[k];
+ else
+ Result = FAIL;
+
+ if (Result == PASS) {
+ k = 0;
+ j = FTL_Extract_Block_Table_Tag(
+ pSpareBufBTLastPage, &tagarray);
+ if (j) {
+ for (; k < j; k++) {
+ if (tagarray[k] == BT_Tag)
+ break;
+ }
+ }
+
+ if (k < j)
+ bt_flag_last_page = tagarray[k];
+ else
+ Result = FAIL;
+
+ if (Result == PASS) {
+ if (bt_flag == bt_flag_last_page) {
+ nand_dbg_print(NAND_DBG_DEBUG,
+ "Block table is found"
+ " in page after IPF "
+ "at block %d "
+ "page %d\n",
+ (int)BT_Block, i);
+ BT_Found = 1;
+ *Page = i;
+ g_cBlockTableStatus =
+ CURRENT_BLOCK_TABLE;
+ break;
+ } else {
+ Result = FAIL;
+ }
+ }
+ }
+ }
+
+ if (search_in_previous_pages)
+ i = i - bt_pages;
+ else
+ i = i - (bt_pages + 1);
+
+ Result = PASS;
+
+ nand_dbg_print(NAND_DBG_DEBUG,
+ "Reading the spare area of Block %d Page %d",
+ (int)BT_Block, i);
+
+ Result = GLOB_LLD_Read_Page_Spare(pSpareBuf, BT_Block, i, 1);
+ nand_dbg_print(NAND_DBG_DEBUG,
+ "Reading the spare area of Block %u Page %u",
+ (unsigned int)BT_Block, i + bt_pages - 1);
+
+ Result = GLOB_LLD_Read_Page_Spare(pSpareBufBTLastPage,
+ BT_Block, i + bt_pages - 1, 1);
+
+ k = 0;
+ j = FTL_Extract_Block_Table_Tag(pSpareBuf, &tagarray);
+ if (j) {
+ for (; k < j; k++) {
+ if (tagarray[k] == BT_Tag)
+ break;
+ }
+ }
+
+ if (k < j)
+ bt_flag = tagarray[k];
+ else
+ Result = FAIL;
+
+ if (Result == PASS) {
+ k = 0;
+ j = FTL_Extract_Block_Table_Tag(pSpareBufBTLastPage,
+ &tagarray);
+ if (j) {
+ for (; k < j; k++) {
+ if (tagarray[k] == BT_Tag)
+ break;
+ }
+ }
+
+ if (k < j) {
+ bt_flag_last_page = tagarray[k];
+ } else {
+ Result = FAIL;
+ break;
+ }
+
+ if (Result == PASS) {
+ if (bt_flag == bt_flag_last_page) {
+ nand_dbg_print(NAND_DBG_DEBUG,
+ "Block table is found "
+ "in page prior to IPF "
+ "at block %u page %d\n",
+ (unsigned int)BT_Block, i);
+ BT_Found = 1;
+ *Page = i;
+ g_cBlockTableStatus =
+ IN_PROGRESS_BLOCK_TABLE;
+ break;
+ } else {
+ Result = FAIL;
+ break;
+ }
+ }
+ }
+ }
+
+ if (Result == FAIL) {
+ if ((Last_IPF > bt_pages) && (i < Last_IPF) && (!BT_Found)) {
+ BT_Found = 1;
+ *Page = i - (bt_pages + 1);
+ }
+ if ((Last_IPF == bt_pages) && (i < Last_IPF) && (!BT_Found))
+ goto func_return;
+ }
+
+ if (Last_IPF == 0) {
+ i = 0;
+ Result = PASS;
+ nand_dbg_print(NAND_DBG_DEBUG, "Reading the spare area of "
+ "Block %u Page %u", (unsigned int)BT_Block, i);
+
+ Result = GLOB_LLD_Read_Page_Spare(pSpareBuf, BT_Block, i, 1);
+ nand_dbg_print(NAND_DBG_DEBUG,
+ "Reading the spare area of Block %u Page %u",
+ (unsigned int)BT_Block, i + bt_pages - 1);
+ Result = GLOB_LLD_Read_Page_Spare(pSpareBufBTLastPage,
+ BT_Block, i + bt_pages - 1, 1);
+
+ k = 0;
+ j = FTL_Extract_Block_Table_Tag(pSpareBuf, &tagarray);
+ if (j) {
+ for (; k < j; k++) {
+ if (tagarray[k] == BT_Tag)
+ break;
+ }
+ }
+
+ if (k < j)
+ bt_flag = tagarray[k];
+ else
+ Result = FAIL;
+
+ if (Result == PASS) {
+ k = 0;
+ j = FTL_Extract_Block_Table_Tag(pSpareBufBTLastPage,
+ &tagarray);
+ if (j) {
+ for (; k < j; k++) {
+ if (tagarray[k] == BT_Tag)
+ break;
+ }
+ }
+
+ if (k < j)
+ bt_flag_last_page = tagarray[k];
+ else
+ Result = FAIL;
+
+ if (Result == PASS) {
+ if (bt_flag == bt_flag_last_page) {
+ nand_dbg_print(NAND_DBG_DEBUG,
+ "Block table is found "
+ "in page after IPF at "
+ "block %u page %u\n",
+ (unsigned int)BT_Block,
+ (unsigned int)i);
+ BT_Found = 1;
+ *Page = i;
+ g_cBlockTableStatus =
+ CURRENT_BLOCK_TABLE;
+ goto func_return;
+ } else {
+ Result = FAIL;
+ }
+ }
+ }
+
+ if (Result == FAIL)
+ goto func_return;
+ }
+func_return:
+ g_pMemPoolFree -= ((DeviceInfo.wPageSize - DeviceInfo.wPageDataSize) *
+ sizeof(u8));
+ ALIGN_DWORD_BWD(g_pMemPoolFree);
+
+ g_pMemPoolFree -= ((DeviceInfo.wPageSize - DeviceInfo.wPageDataSize) *
+ sizeof(u8));
+ ALIGN_DWORD_BWD(g_pMemPoolFree);
+
+ g_pMemPoolFree -= ((DeviceInfo.wPageDataSize * sizeof(u8)));
+ ALIGN_DWORD_BWD(g_pMemPoolFree);
+
+ return Result;
+}
+
+u8 *get_blk_table_start_addr(void)
+{
+ return g_pBlockTable;
+}
+
+unsigned long get_blk_table_len(void)
+{
+ return DeviceInfo.wDataBlockNum * sizeof(u32);
+}
+
+u8 *get_wear_leveling_table_start_addr(void)
+{
+ return g_pWearCounter;
+}
+
+unsigned long get_wear_leveling_table_len(void)
+{
+ return DeviceInfo.wDataBlockNum * sizeof(u8);
+}
+
+/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+* Function: FTL_Read_Block_Table
+* Inputs: none
+* Outputs: PASS / FAIL
+* Description: read the flash spare area and find a block containing the
+* most recent block table(having largest block_table_counter).
+* Find the last written Block table in this block.
+* Check the correctness of Block Table
+* If CDMA is enabled, this function is called in
+* polling mode.
+* We don't need to store changes in Block table in this
+* function as it is called only at initialization
+*
+* Note: Currently this function is called at initialization
+* before any read/erase/write command issued to flash so,
+* there is no need to wait for CDMA list to complete as of now
+*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
+static int FTL_Read_Block_Table(void)
+{
+ int k;
+ u16 i;
+ int j;
+ u8 *tempBuf, *tagarray;
+ int wResult = FAIL;
+ int status = FAIL;
+ u8 block_table_found = 0;
+ int search_result;
+ u32 Block;
+ u16 Page = 0;
+ u16 PageCount;
+ u16 bt_pages;
+ int wBytesCopied = 0, tempvar;
+
+ nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
+ __FILE__, __LINE__, __func__);
+
+ bt_pages = FTL_Get_Block_Table_Flash_Size_Pages();
+
+ tempBuf = g_pMemPoolFree;
+ g_pMemPoolFree += DeviceInfo.wPageDataSize * sizeof(u8);
+ ALIGN_DWORD_FWD(g_pMemPoolFree);
+ debug_boundary_error(((int)g_pMemPoolFree - (int)g_pMemPool) - 1,
+ globalMemSize, 0);
+
+ for (j = DeviceInfo.wSpectraStartBlock;
+ j <= (int)DeviceInfo.wSpectraEndBlock;
+ j++) {
+ status = GLOB_LLD_Read_Page_Spare(tempBuf, j, 0, 1);
+ k = 0;
+ i = FTL_Extract_Block_Table_Tag(tempBuf, &tagarray);
+ if (i) {
+#if CMD_DMA
+ status = GLOB_LLD_Read_Page_Main(tempBuf, j, 0, 1,
+ FTLCommandCount, LLD_CMD_FLAG_MODE_POLL);
+#else
+ status = GLOB_LLD_Read_Page_Main_Polling(tempBuf,
+ j, 0, 1);
+#endif
+ for (; k < i; k++) {
+ if (tagarray[k] == tempBuf[3])
+ break;
+ }
+ }
+
+ if (k < i)
+ k = tagarray[k];
+ else
+ continue;
+
+ nand_dbg_print(NAND_DBG_DEBUG,
+ "Block table is contained in Block %d %d\n",
+ (unsigned int)j, (unsigned int)k);
+
+ if (g_pBTBlocks[k-FIRST_BT_ID] == BTBLOCK_INVAL) {
+ g_pBTBlocks[k-FIRST_BT_ID] = j;
+ block_table_found = 1;
+ } else {
+ printk(KERN_ERR "FTL_Read_Block_Table -"
+ "This should never happens. "
+ "Two block table have same counter %u!\n", k);
+ }
+ }
+
+ g_pMemPoolFree -= DeviceInfo.wPageDataSize * sizeof(u8);
+ ALIGN_DWORD_BWD(g_pMemPoolFree);
+
+ if (block_table_found) {
+ if (g_pBTBlocks[FIRST_BT_ID - FIRST_BT_ID] != BTBLOCK_INVAL &&
+ g_pBTBlocks[LAST_BT_ID - FIRST_BT_ID] != BTBLOCK_INVAL) {
+ j = LAST_BT_ID;
+ while ((j > FIRST_BT_ID) &&
+ (g_pBTBlocks[j - FIRST_BT_ID] != BTBLOCK_INVAL))
+ j--;
+ if (j == FIRST_BT_ID) {
+ j = LAST_BT_ID;
+ last_erased = LAST_BT_ID;
+ } else {
+ last_erased = (u8)j + 1;
+ while ((j > FIRST_BT_ID) && (BTBLOCK_INVAL ==
+ g_pBTBlocks[j - FIRST_BT_ID]))
+ j--;
+ }
+ } else {
+ j = FIRST_BT_ID;
+ while (g_pBTBlocks[j - FIRST_BT_ID] == BTBLOCK_INVAL)
+ j++;
+ last_erased = (u8)j;
+ while ((j < LAST_BT_ID) && (BTBLOCK_INVAL !=
+ g_pBTBlocks[j - FIRST_BT_ID]))
+ j++;
+ if (g_pBTBlocks[j-FIRST_BT_ID] == BTBLOCK_INVAL)
+ j--;
+ }
+
+ if (last_erased > j)
+ j += (1 + LAST_BT_ID - FIRST_BT_ID);
+
+ for (; (j >= last_erased) && (FAIL == wResult); j--) {
+ i = (j - FIRST_BT_ID) %
+ (1 + LAST_BT_ID - FIRST_BT_ID);
+ search_result =
+ FTL_Search_Block_Table_IN_Block(g_pBTBlocks[i],
+ i + FIRST_BT_ID, &Page);
+ if (g_cBlockTableStatus == IN_PROGRESS_BLOCK_TABLE)
+ block_table_found = 0;
+
+ while ((search_result == PASS) && (FAIL == wResult)) {
+ nand_dbg_print(NAND_DBG_DEBUG,
+ "FTL_Read_Block_Table:"
+ "Block: %u Page: %u "
+ "contains block table\n",
+ (unsigned int)g_pBTBlocks[i],
+ (unsigned int)Page);
+
+ tempBuf = g_pMemPoolFree;
+ g_pMemPoolFree += DeviceInfo.wPageDataSize *
+ sizeof(u8);
+ ALIGN_DWORD_FWD(g_pMemPoolFree);
+ debug_boundary_error(((int)g_pMemPoolFree -
+ (int)g_pMemPool) - 1,
+ globalMemSize, 0);
+
+ for (k = 0; k < bt_pages; k++) {
+ Block = g_pBTBlocks[i];
+ PageCount = 1;
+#if CMD_DMA
+ status = GLOB_LLD_Read_Page_Main(
+ tempBuf, Block, Page, PageCount,
+ FTLCommandCount,
+ LLD_CMD_FLAG_MODE_POLL);
+#else
+ status =
+ GLOB_LLD_Read_Page_Main_Polling(
+ tempBuf, Block, Page, PageCount);
+#endif
+ tempvar = k ? 0 : 4;
+
+ wBytesCopied +=
+ FTL_Copy_Block_Table_From_Flash(
+ tempBuf + tempvar,
+ DeviceInfo.wPageDataSize - tempvar,
+ wBytesCopied);
+
+ Page++;
+ }
+
+ g_pMemPoolFree -= DeviceInfo.wPageDataSize *
+ sizeof(u8);
+ ALIGN_DWORD_BWD(g_pMemPoolFree);
+
+ wResult = FTL_Check_Block_Table(FAIL);
+ if (FAIL == wResult) {
+ block_table_found = 0;
+ if (Page > bt_pages)
+ Page -= ((bt_pages<<1) + 1);
+ else
+ search_result = FAIL;
+ }
+ }
+ }
+ }
+
+ if (PASS == wResult) {
+ if (!block_table_found)
+ FTL_Execute_SPL_Recovery();
+
+ if (g_cBlockTableStatus == IN_PROGRESS_BLOCK_TABLE)
+ g_wBlockTableOffset = (u16)Page + 1;
+ else
+ g_wBlockTableOffset = (u16)Page - bt_pages;
+
+ g_wBlockTableIndex = (u32)g_pBTBlocks[i];
+
+#if CMD_DMA
+ if (DeviceInfo.MLCDevice)
+ memcpy(g_pBTStartingCopy, g_pBlockTable,
+ DeviceInfo.wDataBlockNum * sizeof(u32)
+ + DeviceInfo.wDataBlockNum * sizeof(u8)
+ + DeviceInfo.wDataBlockNum * sizeof(u16));
+ else
+ memcpy(g_pBTStartingCopy, g_pBlockTable,
+ DeviceInfo.wDataBlockNum * sizeof(u32)
+ + DeviceInfo.wDataBlockNum * sizeof(u8));
+#endif
+ }
+
+ if (FAIL == wResult)
+ printk(KERN_ERR "Yunpeng - "
+ "Can not find valid spectra block table!\n");
+
+#if CMD_DMA
+ GLOB_LLD_Flash_Init(LLD_CMD_FLAG_MODE_CDMA);
+#endif
+
+#if AUTO_FORMAT_FLASH
+ if (FAIL == wResult) {
+ nand_dbg_print(NAND_DBG_DEBUG, "doing auto-format\n");
+ wResult = FTL_Format_Flash(0);
+ }
+#endif
+
+ return wResult;
+}
+
+
+/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+* Function: FTL_Flash_Error_Handle
+* Inputs: Pointer to data
+* Page address
+* Block address
+* Outputs: PASS=0 / FAIL=1
+* Description: It handles any error occured during Spectra operation
+*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
+static int FTL_Flash_Error_Handle(u8 *pData, u64 old_page_addr,
+ u64 blk_addr)
+{
+ u32 i;
+ int j;
+ u32 tmp_node, blk_node = BLK_FROM_ADDR(blk_addr);
+ u64 phy_addr;
+ int wErase = FAIL;
+ int wResult = FAIL;
+ u32 *pbt = (u32 *)g_pBlockTable;
+
+ nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
+ __FILE__, __LINE__, __func__);
+
+ if (ERR == GLOB_FTL_Garbage_Collection())
+ return ERR;
+
+ do {
+ for (i = DeviceInfo.wSpectraEndBlock -
+ DeviceInfo.wSpectraStartBlock;
+ i > 0; i--) {
+ if (IS_SPARE_BLOCK(i)) {
+ tmp_node = (u32)(BAD_BLOCK |
+ pbt[blk_node]);
+ pbt[blk_node] = (u32)(pbt[i] &
+ (~SPARE_BLOCK));
+ pbt[i] = tmp_node;
+#if CMD_DMA
+ p_BTableChangesDelta =
+ (struct BTableChangesDelta *)
+ g_pBTDelta_Free;
+ g_pBTDelta_Free +=
+ sizeof(struct BTableChangesDelta);
+
+ p_BTableChangesDelta->FTLCommandCount =
+ FTLCommandCount;
+ p_BTableChangesDelta->BT_Index =
+ blk_node;
+ p_BTableChangesDelta->BT_Entry_Value =
+ pbt[blk_node];
+ p_BTableChangesDelta->ValidFields = 0x0C;
+
+ p_BTableChangesDelta =
+ (struct BTableChangesDelta *)
+ g_pBTDelta_Free;
+ g_pBTDelta_Free +=
+ sizeof(struct BTableChangesDelta);
+
+ p_BTableChangesDelta->FTLCommandCount =
+ FTLCommandCount;
+ p_BTableChangesDelta->BT_Index = i;
+ p_BTableChangesDelta->BT_Entry_Value = pbt[i];
+ p_BTableChangesDelta->ValidFields = 0x0C;
+#endif
+ wResult = PASS;
+ break;
+ }
+ }
+
+ if (FAIL == wResult) {
+ if (FAIL == GLOB_FTL_Garbage_Collection())
+ break;
+ else
+ continue;
+ }
+
+ if (IN_PROGRESS_BLOCK_TABLE != g_cBlockTableStatus) {
+ g_cBlockTableStatus = IN_PROGRESS_BLOCK_TABLE;
+ FTL_Write_IN_Progress_Block_Table_Page();
+ }
+
+ phy_addr = FTL_Get_Physical_Block_Addr(blk_addr);
+
+ for (j = 0; j < RETRY_TIMES; j++) {
+ if (PASS == wErase) {
+ if (FAIL == GLOB_FTL_Block_Erase(phy_addr)) {
+ MARK_BLOCK_AS_BAD(pbt[blk_node]);
+ break;
+ }
+ }
+ if (PASS == FTL_Cache_Update_Block(pData,
+ old_page_addr,
+ phy_addr)) {
+ wResult = PASS;
+ break;
+ } else {
+ wResult = FAIL;
+ wErase = PASS;
+ }
+ }
+ } while (FAIL == wResult);
+
+ FTL_Write_Block_Table(FAIL);
+
+ return wResult;
+}
+
+/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+* Function: FTL_Get_Page_Num
+* Inputs: Size in bytes
+* Outputs: Size in pages
+* Description: It calculates the pages required for the length passed
+*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
+static u32 FTL_Get_Page_Num(u64 length)
+{
+ return (u32)((length >> DeviceInfo.nBitsInPageDataSize) +
+ (GLOB_u64_Remainder(length , 1) > 0 ? 1 : 0));
+}
+
+/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+* Function: FTL_Get_Physical_Block_Addr
+* Inputs: Block Address (byte format)
+* Outputs: Physical address of the block.
+* Description: It translates LBA to PBA by returning address stored
+* at the LBA location in the block table
+*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
+static u64 FTL_Get_Physical_Block_Addr(u64 blk_addr)
+{
+ u32 *pbt;
+ u64 physical_addr;
+
+ nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
+ __FILE__, __LINE__, __func__);
+
+ pbt = (u32 *)g_pBlockTable;
+ physical_addr = (u64) DeviceInfo.wBlockDataSize *
+ (pbt[BLK_FROM_ADDR(blk_addr)] & (~BAD_BLOCK));
+
+ return physical_addr;
+}
+
+/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+* Function: FTL_Get_Block_Index
+* Inputs: Physical Block no.
+* Outputs: Logical block no. /BAD_BLOCK
+* Description: It returns the logical block no. for the PBA passed
+*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
+static u32 FTL_Get_Block_Index(u32 wBlockNum)
+{
+ u32 *pbt = (u32 *)g_pBlockTable;
+ u32 i;
+
+ nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
+ __FILE__, __LINE__, __func__);
+
+ for (i = 0; i < DeviceInfo.wDataBlockNum; i++)
+ if (wBlockNum == (pbt[i] & (~BAD_BLOCK)))
+ return i;
+
+ return BAD_BLOCK;
+}
+
+/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+* Function: GLOB_FTL_Wear_Leveling
+* Inputs: none
+* Outputs: PASS=0
+* Description: This is static wear leveling (done by explicit call)
+* do complete static wear leveling
+* do complete garbage collection
+*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
+int GLOB_FTL_Wear_Leveling(void)
+{
+ nand_dbg_print(NAND_DBG_WARN, "%s, Line %d, Function: %s\n",
+ __FILE__, __LINE__, __func__);
+
+ FTL_Static_Wear_Leveling();
+ GLOB_FTL_Garbage_Collection();
+
+ return PASS;
+}
+
+static void find_least_most_worn(u8 *chg,
+ u32 *least_idx, u8 *least_cnt,
+ u32 *most_idx, u8 *most_cnt)
+{
+ u32 *pbt = (u32 *)g_pBlockTable;
+ u32 idx;
+ u8 cnt;
+ int i;
+
+ for (i = BLOCK_TABLE_INDEX + 1; i < DeviceInfo.wDataBlockNum; i++) {
+ if (IS_BAD_BLOCK(i) || PASS == chg[i])
+ continue;
+
+ idx = (u32) ((~BAD_BLOCK) & pbt[i]);
+ cnt = g_pWearCounter[idx - DeviceInfo.wSpectraStartBlock];
+
+ if (IS_SPARE_BLOCK(i)) {
+ if (cnt > *most_cnt) {
+ *most_cnt = cnt;
+ *most_idx = idx;
+ }
+ }
+
+ if (IS_DATA_BLOCK(i)) {
+ if (cnt < *least_cnt) {
+ *least_cnt = cnt;
+ *least_idx = idx;
+ }
+ }
+
+ if (PASS == chg[*most_idx] || PASS == chg[*least_idx]) {
+ debug_boundary_error(*most_idx,
+ DeviceInfo.wDataBlockNum, 0);
+ debug_boundary_error(*least_idx,
+ DeviceInfo.wDataBlockNum, 0);
+ continue;
+ }
+ }
+}
+
+static int move_blks_for_wear_leveling(u8 *chg,
+ u32 *least_idx, u32 *rep_blk_num, int *result)
+{
+ u32 *pbt = (u32 *)g_pBlockTable;
+ u32 rep_blk;
+ int j, ret_cp_blk, ret_erase;
+ int ret = PASS;
+
+ chg[*least_idx] = PASS;
+ debug_boundary_error(*least_idx, DeviceInfo.wDataBlockNum, 0);
+
+ rep_blk = FTL_Replace_MWBlock();
+ if (rep_blk != BAD_BLOCK) {
+ nand_dbg_print(NAND_DBG_DEBUG,
+ "More than two spare blocks exist so do it\n");
+ nand_dbg_print(NAND_DBG_DEBUG, "Block Replaced is %d\n",
+ rep_blk);
+
+ chg[rep_blk] = PASS;
+
+ if (IN_PROGRESS_BLOCK_TABLE != g_cBlockTableStatus) {
+ g_cBlockTableStatus = IN_PROGRESS_BLOCK_TABLE;
+ FTL_Write_IN_Progress_Block_Table_Page();
+ }
+
+ for (j = 0; j < RETRY_TIMES; j++) {
+ ret_cp_blk = FTL_Copy_Block((u64)(*least_idx) *
+ DeviceInfo.wBlockDataSize,
+ (u64)rep_blk * DeviceInfo.wBlockDataSize);
+ if (FAIL == ret_cp_blk) {
+ ret_erase = GLOB_FTL_Block_Erase((u64)rep_blk
+ * DeviceInfo.wBlockDataSize);
+ if (FAIL == ret_erase)
+ MARK_BLOCK_AS_BAD(pbt[rep_blk]);
+ } else {
+ nand_dbg_print(NAND_DBG_DEBUG,
+ "FTL_Copy_Block == OK\n");
+ break;
+ }
+ }
+
+ if (j < RETRY_TIMES) {
+ u32 tmp;
+ u32 old_idx = FTL_Get_Block_Index(*least_idx);
+ u32 rep_idx = FTL_Get_Block_Index(rep_blk);
+ tmp = (u32)(DISCARD_BLOCK | pbt[old_idx]);
+ pbt[old_idx] = (u32)((~SPARE_BLOCK) &
+ pbt[rep_idx]);
+ pbt[rep_idx] = tmp;
+#if CMD_DMA
+ p_BTableChangesDelta = (struct BTableChangesDelta *)
+ g_pBTDelta_Free;
+ g_pBTDelta_Free += sizeof(struct BTableChangesDelta);
+ p_BTableChangesDelta->FTLCommandCount =
+ FTLCommandCount;
+ p_BTableChangesDelta->BT_Index = old_idx;
+ p_BTableChangesDelta->BT_Entry_Value = pbt[old_idx];
+ p_BTableChangesDelta->ValidFields = 0x0C;
+
+ p_BTableChangesDelta = (struct BTableChangesDelta *)
+ g_pBTDelta_Free;
+ g_pBTDelta_Free += sizeof(struct BTableChangesDelta);
+
+ p_BTableChangesDelta->FTLCommandCount =
+ FTLCommandCount;
+ p_BTableChangesDelta->BT_Index = rep_idx;
+ p_BTableChangesDelta->BT_Entry_Value = pbt[rep_idx];
+ p_BTableChangesDelta->ValidFields = 0x0C;
+#endif
+ } else {
+ pbt[FTL_Get_Block_Index(rep_blk)] |= BAD_BLOCK;
+#if CMD_DMA
+ p_BTableChangesDelta = (struct BTableChangesDelta *)
+ g_pBTDelta_Free;
+ g_pBTDelta_Free += sizeof(struct BTableChangesDelta);
+
+ p_BTableChangesDelta->FTLCommandCount =
+ FTLCommandCount;
+ p_BTableChangesDelta->BT_Index =
+ FTL_Get_Block_Index(rep_blk);
+ p_BTableChangesDelta->BT_Entry_Value =
+ pbt[FTL_Get_Block_Index(rep_blk)];
+ p_BTableChangesDelta->ValidFields = 0x0C;
+#endif
+ *result = FAIL;
+ ret = FAIL;
+ }
+
+ if ((*rep_blk_num++) > WEAR_LEVELING_BLOCK_NUM)
+ ret = FAIL;
+ } else {
+ printk(KERN_ERR "Less than 3 spare blocks exist so quit\n");
+ ret = FAIL;
+ }
+
+ return ret;
+}
+
+/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+* Function: FTL_Static_Wear_Leveling
+* Inputs: none
+* Outputs: PASS=0 / FAIL=1
+* Description: This is static wear leveling (done by explicit call)
+* search for most&least used
+* if difference < GATE:
+* update the block table with exhange
+* mark block table in flash as IN_PROGRESS
+* copy flash block
+* the caller should handle GC clean up after calling this function
+*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
+int FTL_Static_Wear_Leveling(void)
+{
+ u8 most_worn_cnt;
+ u8 least_worn_cnt;
+ u32 most_worn_idx;
+ u32 least_worn_idx;
+ int result = PASS;
+ int go_on = PASS;
+ u32 replaced_blks = 0;
+ u8 *chang_flag;
+
+ nand_dbg_print(NAND_DBG_WARN, "%s, Line %d, Function: %s\n",
+ __FILE__, __LINE__, __func__);
+
+ chang_flag = g_pMemPoolFree;
+ g_pMemPoolFree += (DeviceInfo.wDataBlockNum);
+ ALIGN_DWORD_FWD(g_pMemPoolFree);
+ debug_boundary_error(((int)g_pMemPoolFree - (int)g_pMemPool) - 1,
+ globalMemSize, 0);
+
+ if (!chang_flag)
+ return FAIL;
+
+ memset(chang_flag, FAIL, DeviceInfo.wDataBlockNum);
+ while (go_on == PASS) {
+ nand_dbg_print(NAND_DBG_DEBUG,
+ "starting static wear leveling\n");
+ most_worn_cnt = 0;
+ least_worn_cnt = 0xFF;
+ least_worn_idx = BLOCK_TABLE_INDEX;
+ most_worn_idx = BLOCK_TABLE_INDEX;
+
+ find_least_most_worn(chang_flag, &least_worn_idx,
+ &least_worn_cnt, &most_worn_idx, &most_worn_cnt);
+
+ nand_dbg_print(NAND_DBG_DEBUG,
+ "Used and least worn is block %u, whos count is %u\n",
+ (unsigned int)least_worn_idx,
+ (unsigned int)least_worn_cnt);
+
+ nand_dbg_print(NAND_DBG_DEBUG,
+ "Free and most worn is block %u, whos count is %u\n",
+ (unsigned int)most_worn_idx,
+ (unsigned int)most_worn_cnt);
+
+ if ((most_worn_cnt > least_worn_cnt) &&
+ (most_worn_cnt - least_worn_cnt > WEAR_LEVELING_GATE))
+ go_on = move_blks_for_wear_leveling(chang_flag,
+ &least_worn_idx, &replaced_blks, &result);
+ }
+
+ g_pMemPoolFree -= (DeviceInfo.wDataBlockNum);
+ ALIGN_DWORD_BWD(g_pMemPoolFree);
+
+ return result;
+}
+
+#if CMD_DMA
+static int do_garbage_collection(u32 discard_cnt)
+{
+ u32 *pbt = (u32 *)g_pBlockTable;
+ u32 pba;
+ u8 bt_block_erased = 0;
+ int i, cnt, ret = FAIL;
+ u64 addr;
+
+ i = 0;
+ while ((i < DeviceInfo.wDataBlockNum) && (discard_cnt > 0) &&
+ ((FTLCommandCount + 28) < 256)) {
+ if (((pbt[i] & BAD_BLOCK) != BAD_BLOCK) &&
+ (pbt[i] & DISCARD_BLOCK)) {
+ if (IN_PROGRESS_BLOCK_TABLE != g_cBlockTableStatus) {
+ g_cBlockTableStatus = IN_PROGRESS_BLOCK_TABLE;
+ FTL_Write_IN_Progress_Block_Table_Page();
+ }
+
+ addr = FTL_Get_Physical_Block_Addr((u64)i *
+ DeviceInfo.wBlockDataSize);
+ pba = BLK_FROM_ADDR(addr);
+
+ for (cnt = FIRST_BT_ID; cnt <= LAST_BT_ID; cnt++) {
+ if (pba == g_pBTBlocks[cnt - FIRST_BT_ID]) {
+ nand_dbg_print(NAND_DBG_DEBUG,
+ "GC will erase BT block %u\n",
+ (unsigned int)pba);
+ discard_cnt--;
+ i++;
+ bt_block_erased = 1;
+ break;
+ }
+ }
+
+ if (bt_block_erased) {
+ bt_block_erased = 0;
+ continue;
+ }
+
+ addr = FTL_Get_Physical_Block_Addr((u64)i *
+ DeviceInfo.wBlockDataSize);
+
+ if (PASS == GLOB_FTL_Block_Erase(addr)) {
+ pbt[i] &= (u32)(~DISCARD_BLOCK);
+ pbt[i] |= (u32)(SPARE_BLOCK);
+ p_BTableChangesDelta =
+ (struct BTableChangesDelta *)
+ g_pBTDelta_Free;
+ g_pBTDelta_Free +=
+ sizeof(struct BTableChangesDelta);
+ p_BTableChangesDelta->FTLCommandCount =
+ FTLCommandCount - 1;
+ p_BTableChangesDelta->BT_Index = i;
+ p_BTableChangesDelta->BT_Entry_Value = pbt[i];
+ p_BTableChangesDelta->ValidFields = 0x0C;
+ discard_cnt--;
+ ret = PASS;
+ } else {
+ MARK_BLOCK_AS_BAD(pbt[i]);
+ }
+ }
+
+ i++;
+ }
+
+ return ret;
+}
+
+#else
+static int do_garbage_collection(u32 discard_cnt)
+{
+ u32 *pbt = (u32 *)g_pBlockTable;
+ u32 pba;
+ u8 bt_block_erased = 0;
+ int i, cnt, ret = FAIL;
+ u64 addr;
+
+ i = 0;
+ while ((i < DeviceInfo.wDataBlockNum) && (discard_cnt > 0)) {
+ if (((pbt[i] & BAD_BLOCK) != BAD_BLOCK) &&
+ (pbt[i] & DISCARD_BLOCK)) {
+ if (IN_PROGRESS_BLOCK_TABLE != g_cBlockTableStatus) {
+ g_cBlockTableStatus = IN_PROGRESS_BLOCK_TABLE;
+ FTL_Write_IN_Progress_Block_Table_Page();
+ }
+
+ addr = FTL_Get_Physical_Block_Addr((u64)i *
+ DeviceInfo.wBlockDataSize);
+ pba = BLK_FROM_ADDR(addr);
+
+ for (cnt = FIRST_BT_ID; cnt <= LAST_BT_ID; cnt++) {
+ if (pba == g_pBTBlocks[cnt - FIRST_BT_ID]) {
+ nand_dbg_print(NAND_DBG_DEBUG,
+ "GC will erase BT block %d\n",
+ pba);
+ discard_cnt--;
+ i++;
+ bt_block_erased = 1;
+ break;
+ }
+ }
+
+ if (bt_block_erased) {
+ bt_block_erased = 0;
+ continue;
+ }
+
+ addr = FTL_Get_Physical_Block_Addr((u64)i *
+ DeviceInfo.wBlockDataSize);
+
+ if (PASS == GLOB_FTL_Block_Erase(addr)) {
+ pbt[i] &= (u32)(~DISCARD_BLOCK);
+ pbt[i] |= (u32)(SPARE_BLOCK);
+ discard_cnt--;
+ ret = PASS;
+ } else {
+ MARK_BLOCK_AS_BAD(pbt[i]);
+ }
+ }
+
+ i++;
+ }
+
+ return ret;
+}
+#endif
+
+/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+* Function: GLOB_FTL_Garbage_Collection
+* Inputs: none
+* Outputs: PASS / FAIL (returns the number of un-erased blocks
+* Description: search the block table for all discarded blocks to erase
+* for each discarded block:
+* set the flash block to IN_PROGRESS
+* erase the block
+* update the block table
+* write the block table to flash
+*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
+int GLOB_FTL_Garbage_Collection(void)
+{
+ u32 i;
+ u32 wDiscard = 0;
+ int wResult = FAIL;
+ u32 *pbt = (u32 *)g_pBlockTable;
+
+ nand_dbg_print(NAND_DBG_WARN, "%s, Line %d, Function: %s\n",
+ __FILE__, __LINE__, __func__);
+
+ if (GC_Called) {
+ printk(KERN_ALERT "GLOB_FTL_Garbage_Collection() "
+ "has been re-entered! Exit.\n");
+ return PASS;
+ }
+
+ GC_Called = 1;
+
+ GLOB_FTL_BT_Garbage_Collection();
+
+ for (i = 0; i < DeviceInfo.wDataBlockNum; i++) {
+ if (IS_DISCARDED_BLOCK(i))
+ wDiscard++;
+ }
+
+ if (wDiscard <= 0) {
+ GC_Called = 0;
+ return wResult;
+ }
+
+ nand_dbg_print(NAND_DBG_DEBUG,
+ "Found %d discarded blocks\n", wDiscard);
+
+ FTL_Write_Block_Table(FAIL);
+
+ wResult = do_garbage_collection(wDiscard);
+
+ FTL_Write_Block_Table(FAIL);
+
+ GC_Called = 0;
+
+ return wResult;
+}
+
+
+#if CMD_DMA
+static int do_bt_garbage_collection(void)
+{
+ u32 pba, lba;
+ u32 *pbt = (u32 *)g_pBlockTable;
+ u32 *pBTBlocksNode = (u32 *)g_pBTBlocks;
+ u64 addr;
+ int i, ret = FAIL;
+
+ nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
+ __FILE__, __LINE__, __func__);
+
+ if (BT_GC_Called)
+ return PASS;
+
+ BT_GC_Called = 1;
+
+ for (i = last_erased; (i <= LAST_BT_ID) &&
+ (g_pBTBlocks[((i + 2) % (1 + LAST_BT_ID - FIRST_BT_ID)) +
+ FIRST_BT_ID - FIRST_BT_ID] != BTBLOCK_INVAL) &&
+ ((FTLCommandCount + 28)) < 256; i++) {
+ pba = pBTBlocksNode[i - FIRST_BT_ID];
+ lba = FTL_Get_Block_Index(pba);
+ nand_dbg_print(NAND_DBG_DEBUG,
+ "do_bt_garbage_collection: pba %d, lba %d\n",
+ pba, lba);
+ nand_dbg_print(NAND_DBG_DEBUG,
+ "Block Table Entry: %d", pbt[lba]);
+
+ if (((pbt[lba] & BAD_BLOCK) != BAD_BLOCK) &&
+ (pbt[lba] & DISCARD_BLOCK)) {
+ nand_dbg_print(NAND_DBG_DEBUG,
+ "do_bt_garbage_collection_cdma: "
+ "Erasing Block tables present in block %d\n",
+ pba);
+ addr = FTL_Get_Physical_Block_Addr((u64)lba *
+ DeviceInfo.wBlockDataSize);
+ if (PASS == GLOB_FTL_Block_Erase(addr)) {
+ pbt[lba] &= (u32)(~DISCARD_BLOCK);
+ pbt[lba] |= (u32)(SPARE_BLOCK);
+
+ p_BTableChangesDelta =
+ (struct BTableChangesDelta *)
+ g_pBTDelta_Free;
+ g_pBTDelta_Free +=
+ sizeof(struct BTableChangesDelta);
+
+ p_BTableChangesDelta->FTLCommandCount =
+ FTLCommandCount - 1;
+ p_BTableChangesDelta->BT_Index = lba;
+ p_BTableChangesDelta->BT_Entry_Value =
+ pbt[lba];
+
+ p_BTableChangesDelta->ValidFields = 0x0C;
+
+ ret = PASS;
+ pBTBlocksNode[last_erased - FIRST_BT_ID] =
+ BTBLOCK_INVAL;
+ nand_dbg_print(NAND_DBG_DEBUG,
+ "resetting bt entry at index %d "
+ "value %d\n", i,
+ pBTBlocksNode[i - FIRST_BT_ID]);
+ if (last_erased == LAST_BT_ID)
+ last_erased = FIRST_BT_ID;
+ else
+ last_erased++;
+ } else {
+ MARK_BLOCK_AS_BAD(pbt[lba]);
+ }
+ }
+ }
+
+ BT_GC_Called = 0;
+
+ return ret;
+}
+
+#else
+static int do_bt_garbage_collection(void)
+{
+ u32 pba, lba;
+ u32 *pbt = (u32 *)g_pBlockTable;
+ u32 *pBTBlocksNode = (u32 *)g_pBTBlocks;
+ u64 addr;
+ int i, ret = FAIL;
+
+ nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
+ __FILE__, __LINE__, __func__);
+
+ if (BT_GC_Called)
+ return PASS;
+
+ BT_GC_Called = 1;
+
+ for (i = last_erased; (i <= LAST_BT_ID) &&
+ (g_pBTBlocks[((i + 2) % (1 + LAST_BT_ID - FIRST_BT_ID)) +
+ FIRST_BT_ID - FIRST_BT_ID] != BTBLOCK_INVAL); i++) {
+ pba = pBTBlocksNode[i - FIRST_BT_ID];
+ lba = FTL_Get_Block_Index(pba);
+ nand_dbg_print(NAND_DBG_DEBUG,
+ "do_bt_garbage_collection_cdma: pba %d, lba %d\n",
+ pba, lba);
+ nand_dbg_print(NAND_DBG_DEBUG,
+ "Block Table Entry: %d", pbt[lba]);
+
+ if (((pbt[lba] & BAD_BLOCK) != BAD_BLOCK) &&
+ (pbt[lba] & DISCARD_BLOCK)) {
+ nand_dbg_print(NAND_DBG_DEBUG,
+ "do_bt_garbage_collection: "
+ "Erasing Block tables present in block %d\n",
+ pba);
+ addr = FTL_Get_Physical_Block_Addr((u64)lba *
+ DeviceInfo.wBlockDataSize);
+ if (PASS == GLOB_FTL_Block_Erase(addr)) {
+ pbt[lba] &= (u32)(~DISCARD_BLOCK);
+ pbt[lba] |= (u32)(SPARE_BLOCK);
+ ret = PASS;
+ pBTBlocksNode[last_erased - FIRST_BT_ID] =
+ BTBLOCK_INVAL;
+ nand_dbg_print(NAND_DBG_DEBUG,
+ "resetting bt entry at index %d "
+ "value %d\n", i,
+ pBTBlocksNode[i - FIRST_BT_ID]);
+ if (last_erased == LAST_BT_ID)
+ last_erased = FIRST_BT_ID;
+ else
+ last_erased++;
+ } else {
+ MARK_BLOCK_AS_BAD(pbt[lba]);
+ }
+ }
+ }
+
+ BT_GC_Called = 0;
+
+ return ret;
+}
+
+#endif
+
+/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+* Function: GLOB_FTL_BT_Garbage_Collection
+* Inputs: none
+* Outputs: PASS / FAIL (returns the number of un-erased blocks
+* Description: Erases discarded blocks containing Block table
+*
+*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
+int GLOB_FTL_BT_Garbage_Collection(void)
+{
+ return do_bt_garbage_collection();
+}
+
+/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+* Function: FTL_Replace_OneBlock
+* Inputs: Block number 1
+* Block number 2
+* Outputs: Replaced Block Number
+* Description: Interchange block table entries at wBlockNum and wReplaceNum
+*
+*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
+static u32 FTL_Replace_OneBlock(u32 blk, u32 rep_blk)
+{
+ u32 tmp_blk;
+ u32 replace_node = BAD_BLOCK;
+ u32 *pbt = (u32 *)g_pBlockTable;
+
+ nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
+ __FILE__, __LINE__, __func__);
+
+ if (rep_blk != BAD_BLOCK) {
+ if (IS_BAD_BLOCK(blk))
+ tmp_blk = (u32)(pbt[blk]);
+ else
+ tmp_blk = (u32)(DISCARD_BLOCK |
+ (~SPARE_BLOCK & pbt[blk]));
+ replace_node = (u32) ((~SPARE_BLOCK) & pbt[rep_blk]);
+ pbt[blk] = replace_node;
+ pbt[rep_blk] = tmp_blk;
+
+#if CMD_DMA
+ p_BTableChangesDelta =
+ (struct BTableChangesDelta *)g_pBTDelta_Free;
+ g_pBTDelta_Free += sizeof(struct BTableChangesDelta);
+
+ p_BTableChangesDelta->FTLCommandCount = FTLCommandCount;
+ p_BTableChangesDelta->BT_Index = blk;
+ p_BTableChangesDelta->BT_Entry_Value = pbt[blk];
+
+ p_BTableChangesDelta->ValidFields = 0x0C;
+
+ p_BTableChangesDelta =
+ (struct BTableChangesDelta *)g_pBTDelta_Free;
+ g_pBTDelta_Free += sizeof(struct BTableChangesDelta);
+
+ p_BTableChangesDelta->FTLCommandCount = FTLCommandCount;
+ p_BTableChangesDelta->BT_Index = rep_blk;
+ p_BTableChangesDelta->BT_Entry_Value = pbt[rep_blk];
+ p_BTableChangesDelta->ValidFields = 0x0C;
+#endif
+ }
+
+ return replace_node;
+}
+
+/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+* Function: FTL_Write_Block_Table_Data
+* Inputs: Block table size in pages
+* Outputs: PASS=0 / FAIL=1
+* Description: Write block table data in flash
+* If first page and last page
+* Write data+BT flag
+* else
+* Write data
+* BT flag is a counter. Its value is incremented for block table
+* write in a new Block
+*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
+static int FTL_Write_Block_Table_Data(void)
+{
+ u64 dwBlockTableAddr, pTempAddr;
+ u32 Block;
+ u16 Page, PageCount;
+ u8 *tempBuf;
+ int wBytesCopied;
+ u16 bt_pages;
+
+ nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
+ __FILE__, __LINE__, __func__);
+
+ dwBlockTableAddr =
+ (u64)((u64)g_wBlockTableIndex * DeviceInfo.wBlockDataSize +
+ (u64)g_wBlockTableOffset * DeviceInfo.wPageDataSize);
+ pTempAddr = dwBlockTableAddr;
+
+ bt_pages = FTL_Get_Block_Table_Flash_Size_Pages();
+
+ nand_dbg_print(NAND_DBG_DEBUG, "FTL_Write_Block_Table_Data: "
+ "page= %d BlockTableIndex= %d "
+ "BlockTableOffset=%d\n", bt_pages,
+ g_wBlockTableIndex, g_wBlockTableOffset);
+
+ Block = BLK_FROM_ADDR(pTempAddr);
+ Page = PAGE_FROM_ADDR(pTempAddr, Block);
+ PageCount = 1;
+
+ if (bt_block_changed) {
+ if (bt_flag == LAST_BT_ID) {
+ bt_flag = FIRST_BT_ID;
+ g_pBTBlocks[bt_flag - FIRST_BT_ID] = Block;
+ } else if (bt_flag < LAST_BT_ID) {
+ bt_flag++;
+ g_pBTBlocks[bt_flag - FIRST_BT_ID] = Block;
+ }
+
+ if ((bt_flag > (LAST_BT_ID-4)) &&
+ g_pBTBlocks[FIRST_BT_ID - FIRST_BT_ID] !=
+ BTBLOCK_INVAL) {
+ bt_block_changed = 0;
+ GLOB_FTL_BT_Garbage_Collection();
+ }
+
+ bt_block_changed = 0;
+ nand_dbg_print(NAND_DBG_DEBUG,
+ "Block Table Counter is %u Block %u\n",
+ bt_flag, (unsigned int)Block);
+ }
+
+ tempBuf = g_pMemPoolFree;
+ g_pMemPoolFree += (bt_pages > 3) ?
+ (FTL_Get_Block_Table_Flash_Size_Bytes() -
+ (DeviceInfo.wPageSize << 1)) : DeviceInfo.wPageSize;
+ ALIGN_DWORD_FWD(g_pMemPoolFree);
+ debug_boundary_error(((int)g_pMemPoolFree - (int)g_pMemPool) - 1,
+ globalMemSize, 0);
+
+ memset(tempBuf, 0, 3);
+ tempBuf[3] = bt_flag;
+ wBytesCopied = FTL_Copy_Block_Table_To_Flash(tempBuf + 4,
+ DeviceInfo.wPageDataSize - 4, 0);
+ memset(&tempBuf[wBytesCopied + 4], 0xff,
+ DeviceInfo.wPageSize - (wBytesCopied + 4));
+ FTL_Insert_Block_Table_Signature(&tempBuf[DeviceInfo.wPageDataSize],
+ bt_flag);
+
+#if CMD_DMA
+ memcpy(g_pNextBlockTable, tempBuf,
+ DeviceInfo.wPageSize * sizeof(u8));
+ nand_dbg_print(NAND_DBG_DEBUG, "Writing First Page of Block Table "
+ "Block %u Page %u\n", (unsigned int)Block, Page);
+ if (FAIL == GLOB_LLD_Write_Page_Main_Spare(g_pNextBlockTable,
+ Block, Page, 1, FTLCommandCount,
+ LLD_CMD_FLAG_MODE_CDMA | LLD_CMD_FLAG_ORDER_BEFORE_REST)) {
+ nand_dbg_print(NAND_DBG_WARN, "NAND Program fail in "
+ "%s, Line %d, Function: %s, "
+ "new Bad Block %d generated!\n",
+ __FILE__, __LINE__, __func__, Block);
+ goto func_return;
+ }
+
+ FTLCommandCount++;
+ g_pNextBlockTable += ((DeviceInfo.wPageSize * sizeof(u8)));
+#else
+ if (FAIL == GLOB_LLD_Write_Page_Main_Spare(tempBuf, Block, Page, 1)) {
+ nand_dbg_print(NAND_DBG_WARN,
+ "NAND Program fail in %s, Line %d, Function: %s, "
+ "new Bad Block %d generated!\n",
+ __FILE__, __LINE__, __func__, Block);
+ goto func_return;
+ }
+#endif
+
+ if (bt_pages > 1) {
+ PageCount = bt_pages - 1;
+ if (PageCount > 1) {
+ wBytesCopied += FTL_Copy_Block_Table_To_Flash(tempBuf,
+ DeviceInfo.wPageDataSize * (PageCount - 1),
+ wBytesCopied);
+
+#if CMD_DMA
+ memcpy(g_pNextBlockTable, tempBuf,
+ (PageCount - 1) * DeviceInfo.wPageDataSize);
+ if (FAIL == GLOB_LLD_Write_Page_Main(
+ g_pNextBlockTable, Block, Page + 1,
+ PageCount - 1, FTLCommandCount)) {
+ nand_dbg_print(NAND_DBG_WARN,
+ "NAND Program fail in %s, Line %d, "
+ "Function: %s, "
+ "new Bad Block %d generated!\n",
+ __FILE__, __LINE__, __func__,
+ (int)Block);
+ goto func_return;
+ }
+
+ FTLCommandCount++;
+ g_pNextBlockTable += (PageCount - 1) *
+ DeviceInfo.wPageDataSize * sizeof(u8);
+#else
+ if (FAIL == GLOB_LLD_Write_Page_Main(tempBuf,
+ Block, Page + 1, PageCount - 1)) {
+ nand_dbg_print(NAND_DBG_WARN,
+ "NAND Program fail in %s, Line %d, "
+ "Function: %s, "
+ "new Bad Block %d generated!\n",
+ __FILE__, __LINE__, __func__,
+ (int)Block);
+ goto func_return;
+ }
+#endif
+ }
+
+ wBytesCopied = FTL_Copy_Block_Table_To_Flash(tempBuf,
+ DeviceInfo.wPageDataSize, wBytesCopied);
+ memset(&tempBuf[wBytesCopied], 0xff,
+ DeviceInfo.wPageSize-wBytesCopied);
+ FTL_Insert_Block_Table_Signature(
+ &tempBuf[DeviceInfo.wPageDataSize], bt_flag);
+#if CMD_DMA
+ memcpy(g_pNextBlockTable, tempBuf,
+ DeviceInfo.wPageSize * sizeof(u8));
+ nand_dbg_print(NAND_DBG_DEBUG,
+ "Writing the last Page of Block Table "
+ "Block %u Page %u\n",
+ (unsigned int)Block, Page + bt_pages - 1);
+ if (FAIL == GLOB_LLD_Write_Page_Main_Spare(g_pNextBlockTable,
+ Block, Page + bt_pages - 1, 1, FTLCommandCount,
+ LLD_CMD_FLAG_MODE_CDMA |
+ LLD_CMD_FLAG_ORDER_BEFORE_REST)) {
+ nand_dbg_print(NAND_DBG_WARN,
+ "NAND Program fail in %s, Line %d, "
+ "Function: %s, new Bad Block %d generated!\n",
+ __FILE__, __LINE__, __func__, Block);
+ goto func_return;
+ }
+ FTLCommandCount++;
+#else
+ if (FAIL == GLOB_LLD_Write_Page_Main_Spare(tempBuf,
+ Block, Page+bt_pages - 1, 1)) {
+ nand_dbg_print(NAND_DBG_WARN,
+ "NAND Program fail in %s, Line %d, "
+ "Function: %s, "
+ "new Bad Block %d generated!\n",
+ __FILE__, __LINE__, __func__, Block);
+ goto func_return;
+ }
+#endif
+ }
+
+ nand_dbg_print(NAND_DBG_DEBUG, "FTL_Write_Block_Table_Data: done\n");
+
+func_return:
+ g_pMemPoolFree -= (bt_pages > 3) ?
+ (FTL_Get_Block_Table_Flash_Size_Bytes() -
+ (DeviceInfo.wPageSize << 1)) : DeviceInfo.wPageSize;
+ ALIGN_DWORD_BWD(g_pMemPoolFree);
+
+ return PASS;
+}
+
+/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+* Function: FTL_Replace_Block_Table
+* Inputs: None
+* Outputs: PASS=0 / FAIL=1
+* Description: Get a new block to write block table
+*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
+static u32 FTL_Replace_Block_Table(void)
+{
+ u32 blk;
+ int gc;
+
+ nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
+ __FILE__, __LINE__, __func__);
+
+ blk = FTL_Replace_LWBlock(BLOCK_TABLE_INDEX, &gc);
+
+ if ((BAD_BLOCK == blk) && (PASS == gc)) {
+ GLOB_FTL_Garbage_Collection();
+ blk = FTL_Replace_LWBlock(BLOCK_TABLE_INDEX, &gc);
+ }
+ if (BAD_BLOCK == blk)
+ printk(KERN_ERR "%s, %s: There is no spare block. "
+ "It should never happen\n",
+ __FILE__, __func__);
+
+ nand_dbg_print(NAND_DBG_DEBUG, "New Block table Block is %d\n", blk);
+
+ return blk;
+}
+
+/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+* Function: FTL_Replace_LWBlock
+* Inputs: Block number
+* Pointer to Garbage Collect flag
+* Outputs:
+* Description: Determine the least weared block by traversing
+* block table
+* Set Garbage collection to be called if number of spare
+* block is less than Free Block Gate count
+* Change Block table entry to map least worn block for current
+* operation
+*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
+static u32 FTL_Replace_LWBlock(u32 wBlockNum, int *pGarbageCollect)
+{
+ u32 i;
+ u32 *pbt = (u32 *)g_pBlockTable;
+ u8 wLeastWornCounter = 0xFF;
+ u32 wLeastWornIndex = BAD_BLOCK;
+ u32 wSpareBlockNum = 0;
+ u32 wDiscardBlockNum = 0;
+
+ nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
+ __FILE__, __LINE__, __func__);
+
+ if (IS_SPARE_BLOCK(wBlockNum)) {
+ *pGarbageCollect = FAIL;
+ pbt[wBlockNum] = (u32)(pbt[wBlockNum] & (~SPARE_BLOCK));
+#if CMD_DMA
+ p_BTableChangesDelta =
+ (struct BTableChangesDelta *)g_pBTDelta_Free;
+ g_pBTDelta_Free += sizeof(struct BTableChangesDelta);
+ p_BTableChangesDelta->FTLCommandCount =
+ FTLCommandCount;
+ p_BTableChangesDelta->BT_Index = (u32)(wBlockNum);
+ p_BTableChangesDelta->BT_Entry_Value = pbt[wBlockNum];
+ p_BTableChangesDelta->ValidFields = 0x0C;
+#endif
+ return pbt[wBlockNum];
+ }
+
+ for (i = 0; i < DeviceInfo.wDataBlockNum; i++) {
+ if (IS_DISCARDED_BLOCK(i))
+ wDiscardBlockNum++;
+
+ if (IS_SPARE_BLOCK(i)) {
+ u32 wPhysicalIndex = (u32)((~BAD_BLOCK) & pbt[i]);
+ if (wPhysicalIndex > DeviceInfo.wSpectraEndBlock)
+ printk(KERN_ERR "FTL_Replace_LWBlock: "
+ "This should never occur!\n");
+ if (g_pWearCounter[wPhysicalIndex -
+ DeviceInfo.wSpectraStartBlock] <
+ wLeastWornCounter) {
+ wLeastWornCounter =
+ g_pWearCounter[wPhysicalIndex -
+ DeviceInfo.wSpectraStartBlock];
+ wLeastWornIndex = i;
+ }
+ wSpareBlockNum++;
+ }
+ }
+
+ nand_dbg_print(NAND_DBG_WARN,
+ "FTL_Replace_LWBlock: Least Worn Counter %d\n",
+ (int)wLeastWornCounter);
+
+ if ((wDiscardBlockNum >= NUM_FREE_BLOCKS_GATE) ||
+ (wSpareBlockNum <= NUM_FREE_BLOCKS_GATE))
+ *pGarbageCollect = PASS;
+ else
+ *pGarbageCollect = FAIL;
+
+ nand_dbg_print(NAND_DBG_DEBUG,
+ "FTL_Replace_LWBlock: Discarded Blocks %u Spare"
+ " Blocks %u\n",
+ (unsigned int)wDiscardBlockNum,
+ (unsigned int)wSpareBlockNum);
+
+ return FTL_Replace_OneBlock(wBlockNum, wLeastWornIndex);
+}
+
+/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+* Function: FTL_Replace_MWBlock
+* Inputs: None
+* Outputs: most worn spare block no./BAD_BLOCK
+* Description: It finds most worn spare block.
+*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
+static u32 FTL_Replace_MWBlock(void)
+{
+ u32 i;
+ u32 *pbt = (u32 *)g_pBlockTable;
+ u8 wMostWornCounter = 0;
+ u32 wMostWornIndex = BAD_BLOCK;
+ u32 wSpareBlockNum = 0;
+
+ nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
+ __FILE__, __LINE__, __func__);
+
+ for (i = 0; i < DeviceInfo.wDataBlockNum; i++) {
+ if (IS_SPARE_BLOCK(i)) {
+ u32 wPhysicalIndex = (u32)((~SPARE_BLOCK) & pbt[i]);
+ if (g_pWearCounter[wPhysicalIndex -
+ DeviceInfo.wSpectraStartBlock] >
+ wMostWornCounter) {
+ wMostWornCounter =
+ g_pWearCounter[wPhysicalIndex -
+ DeviceInfo.wSpectraStartBlock];
+ wMostWornIndex = wPhysicalIndex;
+ }
+ wSpareBlockNum++;
+ }
+ }
+
+ if (wSpareBlockNum <= 2)
+ return BAD_BLOCK;
+
+ return wMostWornIndex;
+}
+
+/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+* Function: FTL_Replace_Block
+* Inputs: Block Address
+* Outputs: PASS=0 / FAIL=1
+* Description: If block specified by blk_addr parameter is not free,
+* replace it with the least worn block.
+*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
+static int FTL_Replace_Block(u64 blk_addr)
+{
+ u32 current_blk = BLK_FROM_ADDR(blk_addr);
+ u32 *pbt = (u32 *)g_pBlockTable;
+ int wResult = PASS;
+ int GarbageCollect = FAIL;
+
+ nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
+ __FILE__, __LINE__, __func__);
+
+ if (IS_SPARE_BLOCK(current_blk)) {
+ pbt[current_blk] = (~SPARE_BLOCK) & pbt[current_blk];
+#if CMD_DMA
+ p_BTableChangesDelta =
+ (struct BTableChangesDelta *)g_pBTDelta_Free;
+ g_pBTDelta_Free += sizeof(struct BTableChangesDelta);
+ p_BTableChangesDelta->FTLCommandCount =
+ FTLCommandCount;
+ p_BTableChangesDelta->BT_Index = current_blk;
+ p_BTableChangesDelta->BT_Entry_Value = pbt[current_blk];
+ p_BTableChangesDelta->ValidFields = 0x0C ;
+#endif
+ return wResult;
+ }
+
+ FTL_Replace_LWBlock(current_blk, &GarbageCollect);
+
+ if (PASS == GarbageCollect)
+ wResult = GLOB_FTL_Garbage_Collection();
+
+ return wResult;
+}
+
+/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+* Function: GLOB_FTL_Is_BadBlock
+* Inputs: block number to test
+* Outputs: PASS (block is BAD) / FAIL (block is not bad)
+* Description: test if this block number is flagged as bad
+*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
+int GLOB_FTL_Is_BadBlock(u32 wBlockNum)
+{
+ u32 *pbt = (u32 *)g_pBlockTable;
+
+ nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
+ __FILE__, __LINE__, __func__);
+
+ if (wBlockNum >= DeviceInfo.wSpectraStartBlock
+ && BAD_BLOCK == (pbt[wBlockNum] & BAD_BLOCK))
+ return PASS;
+ else
+ return FAIL;
+}
+
+/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+* Function: GLOB_FTL_Flush_Cache
+* Inputs: none
+* Outputs: PASS=0 / FAIL=1
+* Description: flush all the cache blocks to flash
+* if a cache block is not dirty, don't do anything with it
+* else, write the block and update the block table
+* Note: This function should be called at shutdown/power down.
+* to write important data into device
+*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
+int GLOB_FTL_Flush_Cache(void)
+{
+ int i;
+
+ nand_dbg_print(NAND_DBG_WARN, "%s, Line %d, Function: %s\n",
+ __FILE__, __LINE__, __func__);
+
+ for (i = 0; i < CACHE_BLOCK_NUMBER; i++) {
+ if (SET == Cache.ItemArray[i].bChanged) {
+ if (FTL_Cache_Write_Back(Cache.ItemArray[i].pContent,
+ Cache.ItemArray[i].dwAddress) != ERR)
+ Cache.ItemArray[i].bChanged = CLEAR;
+ else
+ return ERR;
+ }
+ }
+
+ return FTL_Write_Block_Table(FAIL);
+}
+
+/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+* Function: GLOB_FTL_Page_Read
+* Inputs: pointer to data
+* address of data (u64 is LBA * Bytes/Page)
+* Outputs: PASS=0 / FAIL=1
+* Description: reads a page of data into RAM from the cache
+* if the data is not already in cache, read from flash to cache
+*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
+int GLOB_FTL_Page_Read(u8 *pData, u64 dwPageAddr)
+{
+ u8 cache_blk;
+ int wResult = PASS;
+
+ nand_dbg_print(NAND_DBG_DEBUG, "GLOB_FTL_Page_Read - "
+ "dwPageAddr: %llu\n", dwPageAddr);
+
+#if CMD_DMA
+ g_SBDCmdIndex++;
+#endif
+
+ cache_blk = FTL_Cache_If_Hit(dwPageAddr);
+
+ if (UNHIT_BLOCK == cache_blk) {
+ nand_dbg_print(NAND_DBG_DEBUG,
+ "GLOB_FTL_Page_Read: Cache not hit\n");
+ wResult = FTL_Cache_Write();
+ if (ERR == FTL_Cache_Read(dwPageAddr))
+ wResult = ERR;
+ cache_blk = Cache.bLRU;
+ }
+
+ FTL_Cache_Read_Page(pData, dwPageAddr, cache_blk);
+
+ return wResult;
+}
+
+/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+* Function: GLOB_FTL_Page_Write
+* Inputs: pointer to data
+* address of data (ADDRESSTYPE is LBA * Bytes/Page)
+* Outputs: PASS=0 / FAIL=1
+* Description: writes a page of data from RAM to the cache
+* if the data is not already in cache, write back the
+* least recently used block and read the addressed block
+* from flash to cache
+*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
+int GLOB_FTL_Page_Write(u8 *pData, u64 dwPageAddr)
+{
+ u8 cache_blk;
+ int wResult = PASS;
+ u32 *pbt = (u32 *)g_pBlockTable;
+
+ nand_dbg_print(NAND_DBG_DEBUG, "GLOB_FTL_Page_Write - "
+ "dwPageAddr: %llu\n", dwPageAddr);
+
+#if CMD_DMA
+ g_SBDCmdIndex++;
+#endif
+
+ cache_blk = FTL_Cache_If_Hit(dwPageAddr);
+
+ if (UNHIT_BLOCK == cache_blk) {
+ wResult = FTL_Cache_Write();
+ if (IS_BAD_BLOCK(BLK_FROM_ADDR(dwPageAddr))) {
+ if (FAIL == FTL_Replace_Block(dwPageAddr))
+ return FAIL;
+ }
+ if (ERR == FTL_Cache_Read(dwPageAddr))
+ wResult = ERR;
+ cache_blk = Cache.bLRU;
+ FTL_Cache_Write_Page(pData, dwPageAddr, cache_blk, 0);
+ } else {
+#if CMD_DMA
+ FTL_Cache_Write_Page(pData, dwPageAddr, cache_blk,
+ LLD_CMD_FLAG_ORDER_BEFORE_REST);
+#else
+ FTL_Cache_Write_Page(pData, dwPageAddr, cache_blk, 0);
+#endif
+ }
+
+ return wResult;
+}
+
+/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+* Function: GLOB_FTL_Block_Erase
+* Inputs: address of block to erase (now in byte format, should change to
+* block format)
+* Outputs: PASS=0 / FAIL=1
+* Description: erases the specified block
+* increments the erase count
+* If erase count reaches its upper limit,call function to
+* do the ajustment as per the relative erase count values
+*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
+int GLOB_FTL_Block_Erase(u64 blk_addr)
+{
+ int status;
+ u32 BlkIdx;
+
+ nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
+ __FILE__, __LINE__, __func__);
+
+ BlkIdx = (u32)(blk_addr >> DeviceInfo.nBitsInBlockDataSize);
+
+ if (BlkIdx < DeviceInfo.wSpectraStartBlock) {
+ printk(KERN_ERR "GLOB_FTL_Block_Erase: "
+ "This should never occur\n");
+ return FAIL;
+ }
+
+#if CMD_DMA
+ status = GLOB_LLD_Erase_Block(BlkIdx,
+ FTLCommandCount, LLD_CMD_FLAG_MODE_CDMA);
+ if (status == FAIL)
+ nand_dbg_print(NAND_DBG_WARN,
+ "NAND Program fail in %s, Line %d, "
+ "Function: %s, new Bad Block %d generated!\n",
+ __FILE__, __LINE__, __func__, BlkIdx);
+#else
+ status = GLOB_LLD_Erase_Block(BlkIdx);
+ if (status == FAIL) {
+ nand_dbg_print(NAND_DBG_WARN,
+ "NAND Program fail in %s, Line %d, "
+ "Function: %s, new Bad Block %d generated!\n",
+ __FILE__, __LINE__, __func__, BlkIdx);
+ return status;
+ }
+#endif
+
+ if (DeviceInfo.MLCDevice) {
+ g_pReadCounter[BlkIdx - DeviceInfo.wSpectraStartBlock] = 0;
+ if (g_cBlockTableStatus != IN_PROGRESS_BLOCK_TABLE) {
+ g_cBlockTableStatus = IN_PROGRESS_BLOCK_TABLE;
+ FTL_Write_IN_Progress_Block_Table_Page();
+ }
+ }
+
+ g_pWearCounter[BlkIdx - DeviceInfo.wSpectraStartBlock]++;
+
+#if CMD_DMA
+ p_BTableChangesDelta =
+ (struct BTableChangesDelta *)g_pBTDelta_Free;
+ g_pBTDelta_Free += sizeof(struct BTableChangesDelta);
+ p_BTableChangesDelta->FTLCommandCount = FTLCommandCount;
+ p_BTableChangesDelta->WC_Index =
+ BlkIdx - DeviceInfo.wSpectraStartBlock;
+ p_BTableChangesDelta->WC_Entry_Value =
+ g_pWearCounter[BlkIdx - DeviceInfo.wSpectraStartBlock];
+ p_BTableChangesDelta->ValidFields = 0x30;
+
+ if (DeviceInfo.MLCDevice) {
+ p_BTableChangesDelta =
+ (struct BTableChangesDelta *)g_pBTDelta_Free;
+ g_pBTDelta_Free += sizeof(struct BTableChangesDelta);
+ p_BTableChangesDelta->FTLCommandCount =
+ FTLCommandCount;
+ p_BTableChangesDelta->RC_Index =
+ BlkIdx - DeviceInfo.wSpectraStartBlock;
+ p_BTableChangesDelta->RC_Entry_Value =
+ g_pReadCounter[BlkIdx -
+ DeviceInfo.wSpectraStartBlock];
+ p_BTableChangesDelta->ValidFields = 0xC0;
+ }
+
+ FTLCommandCount++;
+#endif
+
+ if (g_pWearCounter[BlkIdx - DeviceInfo.wSpectraStartBlock] == 0xFE)
+ FTL_Adjust_Relative_Erase_Count(BlkIdx);
+
+ return status;
+}
+
+
+/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+* Function: FTL_Adjust_Relative_Erase_Count
+* Inputs: index to block that was just incremented and is at the max
+* Outputs: PASS=0 / FAIL=1
+* Description: If any erase counts at MAX, adjusts erase count of every
+* block by substracting least worn
+* counter from counter value of every entry in wear table
+*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
+static int FTL_Adjust_Relative_Erase_Count(u32 Index_of_MAX)
+{
+ u8 wLeastWornCounter = MAX_BYTE_VALUE;
+ u8 wWearCounter;
+ u32 i, wWearIndex;
+ u32 *pbt = (u32 *)g_pBlockTable;
+ int wResult = PASS;
+
+ nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
+ __FILE__, __LINE__, __func__);
+
+ for (i = 0; i < DeviceInfo.wDataBlockNum; i++) {
+ if (IS_BAD_BLOCK(i))
+ continue;
+ wWearIndex = (u32)(pbt[i] & (~BAD_BLOCK));
+
+ if ((wWearIndex - DeviceInfo.wSpectraStartBlock) < 0)
+ printk(KERN_ERR "FTL_Adjust_Relative_Erase_Count:"
+ "This should never occur\n");
+ wWearCounter = g_pWearCounter[wWearIndex -
+ DeviceInfo.wSpectraStartBlock];
+ if (wWearCounter < wLeastWornCounter)
+ wLeastWornCounter = wWearCounter;
+ }
+
+ if (wLeastWornCounter == 0) {
+ nand_dbg_print(NAND_DBG_WARN,
+ "Adjusting Wear Levelling Counters: Special Case\n");
+ g_pWearCounter[Index_of_MAX -
+ DeviceInfo.wSpectraStartBlock]--;
+#if CMD_DMA
+ p_BTableChangesDelta =
+ (struct BTableChangesDelta *)g_pBTDelta_Free;
+ g_pBTDelta_Free += sizeof(struct BTableChangesDelta);
+ p_BTableChangesDelta->FTLCommandCount = FTLCommandCount;
+ p_BTableChangesDelta->WC_Index =
+ Index_of_MAX - DeviceInfo.wSpectraStartBlock;
+ p_BTableChangesDelta->WC_Entry_Value =
+ g_pWearCounter[Index_of_MAX -
+ DeviceInfo.wSpectraStartBlock];
+ p_BTableChangesDelta->ValidFields = 0x30;
+#endif
+ FTL_Static_Wear_Leveling();
+ } else {
+ for (i = 0; i < DeviceInfo.wDataBlockNum; i++)
+ if (!IS_BAD_BLOCK(i)) {
+ wWearIndex = (u32)(pbt[i] & (~BAD_BLOCK));
+ g_pWearCounter[wWearIndex -
+ DeviceInfo.wSpectraStartBlock] =
+ (u8)(g_pWearCounter
+ [wWearIndex -
+ DeviceInfo.wSpectraStartBlock] -
+ wLeastWornCounter);
+#if CMD_DMA
+ p_BTableChangesDelta =
+ (struct BTableChangesDelta *)g_pBTDelta_Free;
+ g_pBTDelta_Free +=
+ sizeof(struct BTableChangesDelta);
+
+ p_BTableChangesDelta->FTLCommandCount =
+ FTLCommandCount;
+ p_BTableChangesDelta->WC_Index = wWearIndex -
+ DeviceInfo.wSpectraStartBlock;
+ p_BTableChangesDelta->WC_Entry_Value =
+ g_pWearCounter[wWearIndex -
+ DeviceInfo.wSpectraStartBlock];
+ p_BTableChangesDelta->ValidFields = 0x30;
+#endif
+ }
+ }
+
+ return wResult;
+}
+
+/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+* Function: FTL_Write_IN_Progress_Block_Table_Page
+* Inputs: None
+* Outputs: None
+* Description: It writes in-progress flag page to the page next to
+* block table
+***********************************************************************/
+static int FTL_Write_IN_Progress_Block_Table_Page(void)
+{
+ int wResult = PASS;
+ u16 bt_pages;
+ u16 dwIPFPageAddr;
+#if CMD_DMA
+#else
+ u32 *pbt = (u32 *)g_pBlockTable;
+ u32 wTempBlockTableIndex;
+#endif
+
+ nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
+ __FILE__, __LINE__, __func__);
+
+ bt_pages = FTL_Get_Block_Table_Flash_Size_Pages();
+
+ dwIPFPageAddr = g_wBlockTableOffset + bt_pages;
+
+ nand_dbg_print(NAND_DBG_DEBUG, "Writing IPF at "
+ "Block %d Page %d\n",
+ g_wBlockTableIndex, dwIPFPageAddr);
+
+#if CMD_DMA
+ wResult = GLOB_LLD_Write_Page_Main_Spare(g_pIPF,
+ g_wBlockTableIndex, dwIPFPageAddr, 1, FTLCommandCount,
+ LLD_CMD_FLAG_MODE_CDMA | LLD_CMD_FLAG_ORDER_BEFORE_REST);
+
+ if (wResult == FAIL) {
+ nand_dbg_print(NAND_DBG_WARN,
+ "NAND Program fail in %s, Line %d, "
+ "Function: %s, new Bad Block %d generated!\n",
+ __FILE__, __LINE__, __func__,
+ g_wBlockTableIndex);
+ }
+ g_wBlockTableOffset = dwIPFPageAddr + 1;
+ p_BTableChangesDelta = (struct BTableChangesDelta *)g_pBTDelta_Free;
+ g_pBTDelta_Free += sizeof(struct BTableChangesDelta);
+ p_BTableChangesDelta->FTLCommandCount = FTLCommandCount;
+ p_BTableChangesDelta->g_wBlockTableOffset = g_wBlockTableOffset;
+ p_BTableChangesDelta->ValidFields = 0x01;
+ FTLCommandCount++;
+#else
+ wResult = GLOB_LLD_Write_Page_Main_Spare(g_pIPF,
+ g_wBlockTableIndex, dwIPFPageAddr, 1);
+ if (wResult == FAIL) {
+ nand_dbg_print(NAND_DBG_WARN,
+ "NAND Program fail in %s, Line %d, "
+ "Function: %s, new Bad Block %d generated!\n",
+ __FILE__, __LINE__, __func__,
+ (int)g_wBlockTableIndex);
+ MARK_BLOCK_AS_BAD(pbt[BLOCK_TABLE_INDEX]);
+ wTempBlockTableIndex = FTL_Replace_Block_Table();
+ bt_block_changed = 1;
+ if (BAD_BLOCK == wTempBlockTableIndex)
+ return ERR;
+ g_wBlockTableIndex = wTempBlockTableIndex;
+ g_wBlockTableOffset = 0;
+ pbt[BLOCK_TABLE_INDEX] = g_wBlockTableIndex;
+ return FAIL;
+ }
+ g_wBlockTableOffset = dwIPFPageAddr + 1;
+#endif
+ return wResult;
+}
+
+/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+* Function: FTL_Read_Disturbance
+* Inputs: block address
+* Outputs: PASS=0 / FAIL=1
+* Description: used to handle read disturbance. Data in block that
+* reaches its read limit is moved to new block
+*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
+int FTL_Read_Disturbance(u32 blk_addr)
+{
+ int wResult = FAIL;
+ u32 *pbt = (u32 *) g_pBlockTable;
+ u32 dwOldBlockAddr = blk_addr;
+ u32 wBlockNum;
+ u32 i;
+ u32 wLeastReadCounter = 0xFFFF;
+ u32 wLeastReadIndex = BAD_BLOCK;
+ u32 wSpareBlockNum = 0;
+ u32 wTempNode;
+ u32 wReplacedNode;
+ u8 *g_pTempBuf;
+
+ nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
+ __FILE__, __LINE__, __func__);
+
+#if CMD_DMA
+ g_pTempBuf = (u8 *)g_pCopyBackBufferStart;
+ g_pCopyBackBufferStart += DeviceInfo.wPageDataSize *
+ DeviceInfo.wPagesPerBlock * sizeof(u8);
+#else
+ g_pTempBuf = (u8 *)g_pMemPoolFree;
+ g_pMemPoolFree += DeviceInfo.wPageDataSize *
+ DeviceInfo.wPagesPerBlock * sizeof(u8);
+ ALIGN_DWORD_FWD(g_pMemPoolFree);
+ debug_boundary_error(((int)g_pMemPoolFree - (int)g_pMemPool) - 1,
+ globalMemSize, 0);
+#endif
+
+ wBlockNum = FTL_Get_Block_Index(blk_addr);
+
+ do {
+ /* This is a bug.Here 'i' should be logical block number
+ * and start from 1 (0 is reserved for block table).
+ * Have fixed it. - Yunpeng 2008. 12. 19
+ */
+ for (i = 1; i < DeviceInfo.wDataBlockNum; i++) {
+ if (IS_SPARE_BLOCK(i)) {
+ u32 wPhysicalIndex =
+ (u32)((~SPARE_BLOCK) & pbt[i]);
+ if (g_pReadCounter[wPhysicalIndex -
+ DeviceInfo.wSpectraStartBlock] <
+ wLeastReadCounter) {
+ wLeastReadCounter =
+ g_pReadCounter[wPhysicalIndex -
+ DeviceInfo.wSpectraStartBlock];
+ wLeastReadIndex = i;
+ }
+ wSpareBlockNum++;
+ }
+ }
+
+ if (wSpareBlockNum <= NUM_FREE_BLOCKS_GATE) {
+ wResult = GLOB_FTL_Garbage_Collection();
+ if (PASS == wResult)
+ continue;
+ else
+ break;
+ } else {
+ wTempNode = (u32)(DISCARD_BLOCK | pbt[wBlockNum]);
+ wReplacedNode = (u32)((~SPARE_BLOCK) &
+ pbt[wLeastReadIndex]);
+#if CMD_DMA
+ pbt[wBlockNum] = wReplacedNode;
+ pbt[wLeastReadIndex] = wTempNode;
+ p_BTableChangesDelta =
+ (struct BTableChangesDelta *)g_pBTDelta_Free;
+ g_pBTDelta_Free += sizeof(struct BTableChangesDelta);
+
+ p_BTableChangesDelta->FTLCommandCount =
+ FTLCommandCount;
+ p_BTableChangesDelta->BT_Index = wBlockNum;
+ p_BTableChangesDelta->BT_Entry_Value = pbt[wBlockNum];
+ p_BTableChangesDelta->ValidFields = 0x0C;
+
+ p_BTableChangesDelta =
+ (struct BTableChangesDelta *)g_pBTDelta_Free;
+ g_pBTDelta_Free += sizeof(struct BTableChangesDelta);
+
+ p_BTableChangesDelta->FTLCommandCount =
+ FTLCommandCount;
+ p_BTableChangesDelta->BT_Index = wLeastReadIndex;
+ p_BTableChangesDelta->BT_Entry_Value =
+ pbt[wLeastReadIndex];
+ p_BTableChangesDelta->ValidFields = 0x0C;
+
+ wResult = GLOB_LLD_Read_Page_Main(g_pTempBuf,
+ dwOldBlockAddr, 0, DeviceInfo.wPagesPerBlock,
+ FTLCommandCount, LLD_CMD_FLAG_MODE_CDMA);
+ if (wResult == FAIL)
+ return wResult;
+
+ FTLCommandCount++;
+
+ if (wResult != FAIL) {
+ if (FAIL == GLOB_LLD_Write_Page_Main(
+ g_pTempBuf, pbt[wBlockNum], 0,
+ DeviceInfo.wPagesPerBlock,
+ FTLCommandCount)) {
+ nand_dbg_print(NAND_DBG_WARN,
+ "NAND Program fail in "
+ "%s, Line %d, Function: %s, "
+ "new Bad Block %d "
+ "generated!\n",
+ __FILE__, __LINE__, __func__,
+ (int)pbt[wBlockNum]);
+ wResult = FAIL;
+ MARK_BLOCK_AS_BAD(pbt[wBlockNum]);
+ }
+ FTLCommandCount++;
+ }
+#else
+ wResult = GLOB_LLD_Read_Page_Main(g_pTempBuf,
+ dwOldBlockAddr, 0, DeviceInfo.wPagesPerBlock);
+ if (wResult == FAIL) {
+ g_pMemPoolFree -= (DeviceInfo.wPageDataSize *
+ DeviceInfo.wPagesPerBlock *
+ sizeof(u8));
+ ALIGN_DWORD_BWD(g_pMemPoolFree);
+ return wResult;
+ }
+
+ if (wResult != FAIL) {
+ /* This is a bug. At this time, pbt[wBlockNum]
+ is still the physical address of
+ discard block, and should not be write.
+ Have fixed it as below.
+ -- Yunpeng 2008.12.19
+ */
+ wResult = GLOB_LLD_Write_Page_Main(g_pTempBuf,
+ wReplacedNode, 0,
+ DeviceInfo.wPagesPerBlock);
+ if (wResult == FAIL) {
+ nand_dbg_print(NAND_DBG_WARN,
+ "NAND Program fail in "
+ "%s, Line %d, Function: %s, "
+ "new Bad Block %d "
+ "generated!\n",
+ __FILE__, __LINE__, __func__,
+ (int)wReplacedNode);
+ MARK_BLOCK_AS_BAD(wReplacedNode);
+ } else {
+ pbt[wBlockNum] = wReplacedNode;
+ pbt[wLeastReadIndex] = wTempNode;
+ }
+ }
+
+ if ((wResult == PASS) && (g_cBlockTableStatus !=
+ IN_PROGRESS_BLOCK_TABLE)) {
+ g_cBlockTableStatus = IN_PROGRESS_BLOCK_TABLE;
+ FTL_Write_IN_Progress_Block_Table_Page();
+ }
+#endif
+ }
+ } while (wResult != PASS)
+ ;
+
+#if CMD_DMA
+ /* ... */
+#else
+ g_pMemPoolFree -= (DeviceInfo.wPageDataSize *
+ DeviceInfo.wPagesPerBlock * sizeof(u8));
+ ALIGN_DWORD_BWD(g_pMemPoolFree);
+#endif
+
+ return wResult;
+}
+
diff --git a/drivers/staging/mrst_nand/flash.h b/drivers/staging/mrst_nand/flash.h
new file mode 100644
index 0000000..d0adf5c
--- /dev/null
+++ b/drivers/staging/mrst_nand/flash.h
@@ -0,0 +1,158 @@
+/*
+ * NAND Flash Controller Device Driver
+ * Copyright (c) 2009, Intel Corporation and its suppliers.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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.
+ *
+ * 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.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+#ifndef _FLASH_INTERFACE_
+#define _FLASH_INTERFACE_
+
+#include "ffsport.h"
+#include "spectraswconfig.h"
+
+#define MAX_BLOCKNODE_VALUE 0xFFFFFF
+#define DISCARD_BLOCK 0x800000
+#define SPARE_BLOCK 0x400000
+#define BAD_BLOCK 0xC00000
+
+#define MAX_BYTE_VALUE 0xFF
+#define UNHIT_BLOCK 0xFF
+
+#define IN_PROGRESS_BLOCK_TABLE 0x00
+#define CURRENT_BLOCK_TABLE 0x01
+
+
+#define BTSIG_OFFSET (0)
+#define BTSIG_BYTES (5)
+#define BTSIG_DELTA (3)
+
+#define MAX_TWO_BYTE_VALUE 0xFFFF
+#define MAX_READ_COUNTER 0x2710
+
+#define FIRST_BT_ID (1)
+#define LAST_BT_ID (254)
+#define BTBLOCK_INVAL (u32)(0xFFFFFFFF)
+
+#define ALIGN_DWORD_FWD(ptr) (ptr = (u8 *)((unsigned long)(ptr+3) & ~0x3))
+#define ALIGN_DWORD_BWD(ptr) (ptr = (u8 *)((unsigned long)ptr & ~0x3))
+
+struct device_info_tag {
+ u16 wDeviceMaker;
+ u32 wDeviceType;
+ u32 wSpectraStartBlock;
+ u32 wSpectraEndBlock;
+ u32 wTotalBlocks;
+ u16 wPagesPerBlock;
+ u16 wPageSize;
+ u16 wPageDataSize;
+ u16 wPageSpareSize;
+ u16 wNumPageSpareFlag;
+ u16 wECCBytesPerSector;
+ u32 wBlockSize;
+ u32 wBlockDataSize;
+ u32 wDataBlockNum;
+ u8 bPlaneNum;
+ u16 wDeviceMainAreaSize;
+ u16 wDeviceSpareAreaSize;
+ u16 wDevicesConnected;
+ u16 wDeviceWidth;
+ u16 wHWRevision;
+ u16 wHWFeatures;
+
+ u16 wONFIDevFeatures;
+ u16 wONFIOptCommands;
+ u16 wONFITimingMode;
+ u16 wONFIPgmCacheTimingMode;
+
+ u16 MLCDevice;
+ u16 wSpareSkipBytes;
+
+ u8 nBitsInPageNumber;
+ u8 nBitsInPageDataSize;
+ u8 nBitsInBlockDataSize;
+};
+
+extern struct device_info_tag DeviceInfo;
+
+/* Cache item format */
+struct flash_cache_item_tag {
+ u64 dwAddress;
+ u8 bLRUCount;
+ u8 bChanged;
+ u8 *pContent;
+};
+
+struct flash_cache_tag {
+ u8 bLRU;
+ u32 dwCacheDataSize;
+ u16 wCachePageNum;
+ struct flash_cache_item_tag ItemArray[CACHE_BLOCK_NUMBER];
+};
+
+extern struct flash_cache_tag Cache;
+
+/* struture used for IndentfyDevice function */
+struct spectra_indentfy_dev_tag {
+ u32 NumBlocks;
+ u16 PagesPerBlock;
+ u16 PageDataSize;
+ u16 wECCBytesPerSector;
+ u32 wDataBlockNum;
+ u32 SizeOfGlobalMem;
+};
+
+int GLOB_FTL_Flash_Init(void);
+int GLOB_FTL_Flash_Release(void);
+/*void GLOB_FTL_Erase_Flash(void);*/
+int GLOB_FTL_Block_Erase(u64 block_addr);
+int GLOB_FTL_Is_BadBlock(u32 block_num);
+int GLOB_FTL_IdentifyDevice(struct spectra_indentfy_dev_tag *IdentfyDeviceData);
+int GLOB_FTL_Mem_Config(u8 *pMem);
+int GLOB_FTL_cdma_int (void);
+int GLOB_FTL_Event_Status(int *);
+void GLOB_FTL_Enable_Disable_Interrupts(u16 INT_ENABLE);
+#if CMD_DMA
+void GLOB_FTL_Execute_CMDS(void);
+#endif
+
+/*int FTL_Read_Disturbance(ADDRESSTYPE dwBlockAddr);*/
+int FTL_Read_Disturbance(u32 dwBlockAddr);
+
+/*Flash r/w based on cache*/
+int GLOB_FTL_Page_Read(u8 *read_data, u64 page_addr);
+int GLOB_FTL_Page_Write(u8 *write_data, u64 page_addr);
+int GLOB_FTL_Wear_Leveling(void);
+int GLOB_FTL_Flash_Format(void);
+int GLOB_FTL_Init(void);
+int GLOB_FTL_Flush_Cache(void);
+int GLOB_FTL_Garbage_Collection(void);
+int GLOB_FTL_BT_Garbage_Collection(void);
+void GLOB_FTL_Cache_Release(void);
+u8 *get_blk_table_start_addr(void);
+u8 *get_wear_leveling_table_start_addr(void);
+unsigned long get_blk_table_len(void);
+unsigned long get_wear_leveling_table_len(void);
+
+#if DEBUG_BNDRY
+void debug_boundary_lineno_error(int chnl, int limit, int no, int lineno,
+ char *filename);
+#define debug_boundary_error(chnl, limit, no) debug_boundary_lineno_error(chnl,\
+ limit, no, __LINE__, __FILE__)
+#else
+#define debug_boundary_error(chnl, limit, no) ;
+#endif
+
+#endif /*_FLASH_INTERFACE_*/
diff --git a/drivers/staging/mrst_nand/lld.c b/drivers/staging/mrst_nand/lld.c
new file mode 100644
index 0000000..bed1c3c
--- /dev/null
+++ b/drivers/staging/mrst_nand/lld.c
@@ -0,0 +1,492 @@
+/*
+ * NAND Flash Controller Device Driver
+ * Copyright (c) 2009, Intel Corporation and its suppliers.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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.
+ *
+ * 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.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+#ifdef ELDORA
+#include "defs.h"
+#include "lld.h"
+#else
+#include "spectraswconfig.h"
+#include "ffsport.h"
+#include "ffsdefs.h"
+#include "lld.h"
+
+#ifdef NEW_LLD_API
+#include "flash.h"
+#endif
+
+#endif
+
+/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
+#if FLASH_EMU /* vector all the LLD calls to the LLD_EMU code */
+#include "lld_emu.h"
+#include "lld_cdma.h"
+
+/* common functions: */
+u16 GLOB_LLD_Flash_Reset(void)
+{
+ return emu_Flash_Reset();
+}
+
+u16 GLOB_LLD_Read_Device_ID(void)
+{
+ return emu_Read_Device_ID();
+}
+
+u16 GLOB_LLD_Flash_Release(void)
+{
+ return emu_Flash_Release();
+}
+
+#if CMD_DMA /* new APIs with tags */
+u16 GLOB_LLD_Flash_Init(u16 Flags)
+{
+ if (Flags & LLD_CMD_FLAG_MODE_POLL)
+ return emu_Flash_Init();
+ else
+ return emu_CDMA_Flash_Init();
+}
+
+u16 GLOB_LLD_Erase_Block(u32 block, u8 TagCount, u16 Flags)
+{
+ if (Flags & LLD_CMD_FLAG_MODE_POLL)
+ return emu_Erase_Block(block);
+ else
+ return CDMA_Data_CMD(TagCount, ERASE_CMD, 0, block, 0, 0,
+ Flags);
+}
+
+u16 GLOB_LLD_Write_Page_Main(u8 *data, u32 block, u16 page,
+ u16 count, u8 TagCount)
+{
+ return CDMA_Data_CMD(TagCount, WRITE_MAIN_CMD, data, block, page, count,
+ 0);
+}
+
+u16 GLOB_LLD_Read_Page_Main(u8 *data, u32 block, u16 page,
+ u16 count, u8 TagCount, u16 Flags)
+{
+ if (Flags & LLD_CMD_FLAG_MODE_POLL)
+ return emu_Read_Page_Main(data, block, page, count);
+ else
+ return CDMA_Data_CMD(TagCount, READ_MAIN_CMD, data, block, page,
+ count, Flags);
+}
+
+u16 GLOB_LLD_MemCopy_CMD(u8 TagCount, u8 *dest, u8 *src,
+ u16 ByteCount, u16 flag)
+{
+ return CDMA_MemCopy_CMD(TagCount, dest, src, ByteCount, flag);
+}
+
+u16 GLOB_LLD_Execute_CMDs(u16 count)
+{
+ return emu_CDMA_Execute_CMDs(count);
+}
+
+u16 GLOB_LLD_Event_Status(void)
+{
+ return emu_CDMA_Event_Status();
+}
+
+#ifndef ELDORA
+void GLOB_LLD_Enable_Disable_Interrupts(u16 INT_ENABLE)
+{
+ emu_Enable_Disable_Interrupts(INT_ENABLE);
+}
+
+u16 GLOB_LLD_Write_Page_Main_Spare(u8 *write_data, u32 block,
+ u16 Page, u16 PageCount,
+ u8 TagCount, u16 Flags)
+{
+ if (Flags & LLD_CMD_FLAG_MODE_POLL)
+ return emu_Write_Page_Main_Spare(write_data, block, Page,
+ PageCount);
+ else
+ return CDMA_Data_CMD(TagCount, WRITE_MAIN_SPARE_CMD, write_data,
+ block, Page, PageCount, Flags);
+}
+
+u16 GLOB_LLD_Read_Page_Main_Spare(u8 *read_data, u32 Block,
+ u16 Page, u16 PageCount,
+ u8 TagCount)
+{
+ return CDMA_Data_CMD(TagCount, READ_MAIN_SPARE_CMD,
+ read_data, Block, Page, PageCount,
+ LLD_CMD_FLAG_MODE_CDMA);
+}
+
+u16 GLOB_LLD_Write_Page_Spare(u8 *write_data, u32 Block, u16 Page,
+ u16 PageCount)
+{
+ return emu_Write_Page_Spare(write_data, Block, Page, PageCount);
+}
+
+u16 GLOB_LLD_Read_Page_Spare(u8 *read_data, u32 Block, u16 Page,
+ u16 PageCount)
+{
+ return emu_Read_Page_Spare(read_data, Block, Page, PageCount);
+}
+
+u32 GLOB_LLD_Memory_Pool_Size(void)
+{
+ return CDMA_Memory_Pool_Size();
+}
+
+int GLOB_LLD_Mem_Config(u8 *pMem)
+{
+ return CDMA_Mem_Config(pMem);
+}
+#endif /* !ELDORA */
+
+#else /* if not CMD_DMA, use old style parameters without tags */
+u16 GLOB_LLD_Flash_Init(void)
+{
+ return emu_Flash_Init();
+}
+
+u16 GLOB_LLD_Erase_Block(u32 block_add)
+{
+ return emu_Erase_Block(block_add);
+}
+
+u16 GLOB_LLD_Write_Page_Main(u8 *write_data, u32 block, u16 Page,
+ u16 PageCount)
+{
+ return emu_Write_Page_Main(write_data, block, Page, PageCount);
+}
+
+u16 GLOB_LLD_Read_Page_Main(u8 *read_data, u32 block, u16 Page,
+ u16 PageCount)
+{
+ return emu_Read_Page_Main(read_data, block, Page, PageCount);
+}
+
+u16 GLOB_LLD_Read_Page_Main_Polling(u8 *read_data,
+ u32 block, u16 page, u16 page_count)
+{
+ return emu_Read_Page_Main(read_data, block, page, page_count);
+}
+#ifndef ELDORA
+void GLOB_LLD_Enable_Disable_Interrupts(u16 INT_ENABLE)
+{
+ emu_Enable_Disable_Interrupts(INT_ENABLE);
+}
+
+u16 GLOB_LLD_Write_Page_Main_Spare(u8 *write_data, u32 block,
+ u16 Page, u16 PageCount)
+{
+ return emu_Write_Page_Main_Spare(write_data, block, Page, PageCount);
+}
+
+u16 GLOB_LLD_Read_Page_Main_Spare(u8 *read_data, u32 block,
+ u16 Page, u16 PageCount)
+{
+ return emu_Read_Page_Main_Spare(read_data, block, Page, PageCount);
+}
+
+u16 GLOB_LLD_Write_Page_Spare(u8 *write_data, u32 block, u16 Page,
+ u16 PageCount)
+{
+ return emu_Write_Page_Spare(write_data, block, Page, PageCount);
+}
+
+u16 GLOB_LLD_Read_Page_Spare(u8 *read_data, u32 block, u16 Page,
+ u16 PageCount)
+{
+ return emu_Read_Page_Spare(read_data, block, Page, PageCount);
+}
+
+u32 GLOB_LLD_Memory_Pool_Size(void)
+{
+ return 0;
+}
+
+int GLOB_LLD_Mem_Config(u8 *pMem)
+{
+ return 0;
+}
+
+#endif /* !ELDORA */
+#endif /* CMD_DMA or not */
+
+#ifndef ELDORA
+u16 GLOB_LLD_Get_Bad_Block(u32 block)
+{
+ return emu_Get_Bad_Block(block);
+}
+#endif /* !ELDORA */
+
+#endif /* FLASH_EMU */
+/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
+
+
+/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
+#if FLASH_NAND /* vector all the LLD calls to the NAND controller code */
+#include "lld_nand.h"
+#ifndef ELDORA
+#include "flash.h"
+#endif
+
+/* common functions for LLD_NAND */
+void GLOB_LLD_ECC_Control(int enable)
+{
+ NAND_ECC_Ctrl(enable);
+}
+
+/* common functions for LLD_NAND */
+u16 GLOB_LLD_Flash_Reset(void)
+{
+ return NAND_Flash_Reset();
+}
+
+u16 GLOB_LLD_Read_Device_ID(void)
+{
+ return NAND_Read_Device_ID();
+}
+
+u16 GLOB_LLD_UnlockArrayAll(void)
+{
+ return NAND_UnlockArrayAll();
+}
+
+void GLOB_LLD_Enable_Disable_Interrupts(u16 INT_ENABLE)
+{
+ NAND_LLD_Enable_Disable_Interrupts(INT_ENABLE);
+}
+
+u16 GLOB_LLD_Flash_Init(void)
+{
+ return NAND_Flash_Init();
+}
+
+u16 GLOB_LLD_Flash_Release(void)
+{
+ return 0;
+}
+
+u16 GLOB_LLD_Event_Status(void)
+{
+ return NAND_LLD_Event_Status();
+}
+
+u16 GLOB_LLD_Erase_Block(u32 block_add)
+{
+ return NAND_Erase_Block(block_add);
+}
+
+
+u16 GLOB_LLD_Write_Page_Main(u8 *write_data, u32 block, u16 Page,
+ u16 PageCount)
+{
+ return NAND_Write_Page_Main(write_data, block, Page, PageCount);
+}
+
+u16 GLOB_LLD_Read_Page_Main(u8 *read_data, u32 block, u16 page,
+ u16 page_count)
+{
+ return NAND_Read_Page_Main(read_data, block, page, page_count);
+}
+
+u16 GLOB_LLD_Read_Page_Main_Polling(u8 *read_data,
+ u32 block, u16 page, u16 page_count)
+{
+ return NAND_Read_Page_Main_Polling(read_data,
+ block, page, page_count);
+}
+
+#ifndef ELDORA
+u16 GLOB_LLD_Write_Page_Main_Spare(u8 *write_data, u32 block,
+ u16 Page, u16 PageCount)
+{
+ return NAND_Write_Page_Main_Spare(write_data, block, Page, PageCount);
+}
+
+u16 GLOB_LLD_Write_Page_Spare(u8 *write_data, u32 block, u16 Page,
+ u16 PageCount)
+{
+ return NAND_Write_Page_Spare(write_data, block, Page, PageCount);
+}
+
+u16 GLOB_LLD_Read_Page_Main_Spare(u8 *read_data, u32 block,
+ u16 page, u16 page_count)
+{
+ return NAND_Read_Page_Main_Spare(read_data, block, page, page_count);
+}
+
+u16 GLOB_LLD_Read_Page_Spare(u8 *read_data, u32 block, u16 Page,
+ u16 PageCount)
+{
+ return NAND_Read_Page_Spare(read_data, block, Page, PageCount);
+}
+
+u16 GLOB_LLD_Get_Bad_Block(u32 block)
+{
+ return NAND_Get_Bad_Block(block);
+}
+
+u32 GLOB_LLD_Memory_Pool_Size(void)
+{
+ return NAND_Memory_Pool_Size();
+}
+
+int GLOB_LLD_Mem_Config(u8 *pMem)
+{
+ return NAND_Mem_Config(pMem);
+}
+
+#endif /* !ELDORA */
+
+#endif /* FLASH_NAND */
+/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
+
+/* CMD DMA is not applicable for Eldora */
+#ifndef ELDORA
+
+#if FLASH_CDMA /* vector all the LLD data calls to the LLD_CDMA module */
+ /* vector some other LLD calls to the LLD_CDMA module*/
+ /* vector the common LLD calls to the LLD_NAND module*/
+#include "lld_cdma.h"
+#include "lld_nand.h"
+
+u16 GLOB_LLD_Flash_Reset(void)
+{
+ return NAND_Flash_Reset();
+}
+
+u16 GLOB_LLD_Read_Device_ID(void)
+{
+ return NAND_Read_Device_ID();
+}
+
+u16 GLOB_LLD_UnlockArrayAll(void)
+{
+ return NAND_UnlockArrayAll();
+}
+
+void GLOB_LLD_Enable_Disable_Interrupts(u16 INT_ENABLE)
+{
+ NAND_LLD_Enable_Disable_Interrupts(INT_ENABLE);
+}
+
+u16 GLOB_LLD_Flash_Release(void) /* not used; NOP */
+{
+ return 0;
+}
+
+u16 GLOB_LLD_Flash_Init(u16 Flags)
+{
+ if (Flags & LLD_CMD_FLAG_MODE_POLL)
+ return NAND_Flash_Init();
+ else
+ return CDMA_Flash_Init();
+}
+
+int GLOB_LLD_is_cdma_int(void)
+{
+ return is_cdma_interrupt();
+}
+
+u16 GLOB_LLD_Event_Status(void)
+{
+ return CDMA_Event_Status();
+}
+
+u16 GLOB_LLD_MemCopy_CMD(u8 TagCount, u8 *dest, u8 *src,
+ u16 ByteCount, u16 flag)
+{
+ return CDMA_MemCopy_CMD(TagCount, dest, src, ByteCount, flag);
+}
+
+u16 GLOB_LLD_Execute_CMDs(u16 count)
+{
+ return CDMA_Execute_CMDs(count);
+}
+
+u16 GLOB_LLD_Erase_Block(u32 block, u8 TagCount, u16 Flags)
+{
+ if (Flags & LLD_CMD_FLAG_MODE_POLL)
+ return NAND_Erase_Block(block);
+ else
+ return CDMA_Data_CMD(TagCount, ERASE_CMD, 0, block, 0, 0,
+ Flags);
+}
+
+u16 GLOB_LLD_Write_Page_Main(u8 *data, u32 block, u16 page,
+ u16 count, u8 TagCount)
+{
+ return CDMA_Data_CMD(TagCount, WRITE_MAIN_CMD, data, block, page, count,
+ 0);
+}
+
+u16 GLOB_LLD_Read_Page_Main(u8 *data, u32 block, u16 page,
+ u16 count, u8 TagCount, u16 Flags)
+{
+ if (Flags & LLD_CMD_FLAG_MODE_POLL) {
+ return NAND_Read_Page_Main(data, block, page, count);
+ } else
+ return CDMA_Data_CMD(TagCount, READ_MAIN_CMD, data, block, page,
+ count, Flags);
+}
+
+u16 GLOB_LLD_Write_Page_Spare(u8 *data, u32 block, u16 page,
+ u16 count)
+{
+ return NAND_Write_Page_Spare(data, block, page, count);
+}
+
+u16 GLOB_LLD_Read_Page_Spare(u8 *data, u32 block, u16 page,
+ u16 count)
+{
+ return NAND_Read_Page_Spare(data, block, page, count);
+}
+
+u16 GLOB_LLD_Write_Page_Main_Spare(u8 *data, u32 block, u16 page,
+ u16 count, u8 TagCount, u16 Flags)
+{
+ return CDMA_Data_CMD(TagCount, WRITE_MAIN_SPARE_CMD, data, block, page,
+ count, Flags);
+}
+
+u16 GLOB_LLD_Read_Page_Main_Spare(u8 *data, u32 block, u16 page,
+ u16 count, u8 TagCount)
+{
+ return CDMA_Data_CMD(TagCount, READ_MAIN_SPARE_CMD, data, block, page,
+ count, LLD_CMD_FLAG_MODE_CDMA);
+}
+
+u16 GLOB_LLD_Get_Bad_Block(u32 block)
+{
+ return NAND_Get_Bad_Block(block);
+}
+
+u32 GLOB_LLD_Memory_Pool_Size(void)
+{
+ return CDMA_Memory_Pool_Size();
+}
+
+int GLOB_LLD_Mem_Config(u8 *pMem)
+{
+ return CDMA_Mem_Config(pMem);
+}
+#endif /* FLASH_CDMA */
+
+#endif /* !ELDORA */
+/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
+
+/* end of LLD.c */
diff --git a/drivers/staging/mrst_nand/lld.h b/drivers/staging/mrst_nand/lld.h
new file mode 100644
index 0000000..5889c40
--- /dev/null
+++ b/drivers/staging/mrst_nand/lld.h
@@ -0,0 +1,123 @@
+/*
+ * NAND Flash Controller Device Driver
+ * Copyright (c) 2009, Intel Corporation and its suppliers.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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.
+ *
+ * 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.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+
+
+#ifndef _LLD_
+#define _LLD_
+
+#include "ffsport.h"
+#include "spectraswconfig.h"
+#include "flash.h"
+
+#define GOOD_BLOCK 0
+#define DEFECTIVE_BLOCK 1
+#define READ_ERROR 2
+
+#define CLK_X 5
+#define CLK_MULTI 4
+
+/* Max main & spare sizes supported in LLD */
+#define MAX_PAGE_MAIN_AREA 8192
+#define MAX_PAGE_SPARE_AREA 512
+#define MAX_PAGE_MAINSPARE_AREA 8704
+
+/* for GLOB_LLD_Enable_Disable_Interrupts */
+#define ENABLE_INTERRUPTS 0x0001
+#define DISABLE_INTERRUPTS 0x0000
+
+
+
+/* Typedefs */
+
+/* prototypes: API for LLD */
+/* Currently, Write_Page_Main
+ * MemCopy
+ * Read_Page_Main_Spare
+ * do not have flag because they were not implemented prior to this
+ * They are not being added to keep changes to a minimum for now.
+ * Currently, they are not required (only reqd for Wr_P_M_S.)
+ * Later on, these NEED to be changed.
+ */
+ extern void GLOB_LLD_ECC_Control(int enable);
+extern u16 GLOB_LLD_Flash_Release(void);
+extern u16 GLOB_LLD_Flash_Reset(void);
+extern u16 GLOB_LLD_Read_Device_ID(void);
+#if CMD_DMA
+extern u16 GLOB_LLD_Flash_Init(u16 Flags);
+extern u16 GLOB_LLD_Execute_CMDs(u16 count);
+extern u16 GLOB_LLD_Erase_Block(u32 block, u8 TagCount,
+ u16 Flags);
+extern u16 GLOB_LLD_Write_Page_Main(u8 *write_data, u32 block,
+ u16 Page, u16
+ PageCount, u8 CommandCount);
+extern u16 GLOB_LLD_Read_Page_Main(u8 *read_data, u32 block,
+ u16 Page, u16
+ PageCount, u8 CommandCount, u16 Flags);
+extern u16 GLOB_LLD_MemCopy_CMD(u8 tag, u8 *dest, u8 *src,
+ u16 ByteCount, u16 flag);
+#else
+extern u16 GLOB_LLD_Flash_Init(void);
+extern u16 GLOB_LLD_Erase_Block(u32 block_add);
+extern u16 GLOB_LLD_Write_Page_Main(u8 *write_data, u32 block,
+ u16 Page, u16 PageCount);
+extern u16 GLOB_LLD_Read_Page_Main(u8 *read_data, u32 block,
+ u16 Page, u16 PageCount);
+extern u16 GLOB_LLD_Read_Page_Main_Polling(u8 *read_data,
+ u32 block, u16 page, u16 page_count);
+#endif
+
+extern int GLOB_LLD_is_cdma_int(void);
+extern u16 GLOB_LLD_Event_Status(void);
+extern void GLOB_LLD_Enable_Disable_Interrupts(u16 INT_ENABLE);
+
+extern u16 GLOB_LLD_UnlockArrayAll(void);
+extern u16 GLOB_LLD_Read_Page_Spare(u8 *read_data, u32 block,
+ u16 Page, u16 PageCount);
+extern u16 GLOB_LLD_Write_Page_Spare(u8 *write_data, u32 block,
+ u16 Page, u16 PageCount);
+extern u16 GLOB_LLD_Get_Bad_Block(u32 block);
+#if CMD_DMA
+extern u16 GLOB_LLD_Write_Page_Main_Spare(u8 *write_data,
+ u32 block, u16 Page, u16
+ PageCount, u8 CommandCount, u16 Flags);
+extern u16 GLOB_LLD_Read_Page_Main_Spare(u8 *read_data,
+ u32 block, u16 Page, u16
+ PageCount, u8 CommandCount);
+#else
+extern u16 GLOB_LLD_Write_Page_Main_Spare(u8 *write_data,
+ u32 block, u16 Page, u16 PageCount);
+extern u16 GLOB_LLD_Read_Page_Main_Spare(u8 *read_data,
+ u32 block, u16 Page, u16
+ PageCount);
+#endif /* CMD_DMA */
+
+extern u32 GLOB_LLD_Memory_Pool_Size(void);
+extern int GLOB_LLD_Mem_Config(u8 *pMem);
+
+#if CMD_DMA
+#define LLD_CMD_FLAG_ORDER_BEFORE_REST (0x1)
+#define LLD_CMD_FLAG_MODE_POLL (0x4)
+#define LLD_CMD_FLAG_MODE_CDMA (0x8)
+#endif /* CMD_DMA */
+
+
+#endif /*_LLD_ */
+
+
diff --git a/drivers/staging/mrst_nand/lld_cdma.c b/drivers/staging/mrst_nand/lld_cdma.c
new file mode 100644
index 0000000..19650c2
--- /dev/null
+++ b/drivers/staging/mrst_nand/lld_cdma.c
@@ -0,0 +1,2736 @@
+/*
+ * NAND Flash Controller Device Driver
+ * Copyright (c) 2009, Intel Corporation and its suppliers.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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.
+ *
+ * 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.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+
+/* note: compile with LLD_NAND.C as it contains some common functions */
+#include "spectraswconfig.h"
+#include "lld.h"
+#include "lld_nand.h"
+#include "lld_cdma.h"
+#include "lld_emu.h"
+#include "flash.h"
+#include "NAND_Regs_4.h"
+
+#define DBG_SNC_PRINTEVERY 1000000
+
+#if CMD_DMA
+#define MODE_02 (0x2 << 26)
+#define MAX_DESC_PER_CHANNEL (MAX_DESCS + 2)
+
+#if FLASH_CDMA
+static void ResetSyncModule(void);
+#endif
+
+/* command is sent. This is global so FTL can check final cmd results */
+struct pending_cmd PendingCMD[MAX_DESCS + MAX_CHANS];
+
+struct cdma_descriptor (*cdma_desc)[MAX_DESC_PER_CHANNEL];
+struct memcpy_descriptor (*memcp_desc)[MAX_DESCS];
+
+u16 dcount[MAX_CHANS];
+
+
+/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+* Function: CDMA_Data_Cmd
+* Inputs: tag (0-255)
+* cmd code (aligned for hw)
+* data: pointer to source or destination
+* block: block address
+* page: page address
+* count: num pages to transfer
+* Outputs: PASS
+* Description: This function takes the parameters and puts them
+* into the "pending commands" array.
+* It does not parse or validate the parameters.
+* The array index is same as the tag.
+*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
+u16 CDMA_Data_CMD(u8 tag, u8 CMD, u8 *data,
+ u32 block, u16 page, u16 count, u16 flags)
+{
+ int i;
+
+ debug_boundary_error(block, DeviceInfo.wTotalBlocks, tag);
+ debug_boundary_error(count, DeviceInfo.wPagesPerBlock+1, tag);
+ debug_boundary_error(tag, 252, 0);
+
+ tag += MAX_CHANS;
+ PendingCMD[tag].Tag = tag - MAX_CHANS;
+ PendingCMD[tag].CMD = CMD;
+ PendingCMD[tag].DataAddr = data;
+ PendingCMD[tag].Block = block;
+ PendingCMD[tag].Page = page;
+ PendingCMD[tag].PageCount = count;
+ PendingCMD[tag].DataDestAddr = 0;
+ PendingCMD[tag].DataSrcAddr = 0;
+ PendingCMD[tag].MemCopyByteCnt = 0;
+ PendingCMD[tag].Flags = flags;
+ PendingCMD[tag].SBDCmdIndex = g_SBDCmdIndex;
+
+ for (i = 0; i <= MAX_CHANS; i++)
+ PendingCMD[tag].ChanSync[i] = 0;
+
+ PendingCMD[tag].Status = 0xB0B;
+
+#if FLASH_CDMA
+ switch (CMD) {
+ case WRITE_MAIN_SPARE_CMD:
+ NAND_Conv_Main_Spare_Data_Log2Phy_Format(data, count);
+ break;
+ case WRITE_SPARE_CMD:
+ NAND_Conv_Spare_Data_Log2Phy_Format(data);
+ break;
+ default:
+ break;
+ }
+#endif
+ return PASS;
+}
+
+/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+* Function: CDMA_MemCopy_CMD
+* Inputs: tag (0-255)
+* dest: pointer to destination
+* src: pointer to source
+* count: num bytes to transfer
+* Outputs: PASS
+* Description: This function takes the parameters and puts them
+* into the "pending commands" array.
+* It does not parse or validate the parameters.
+* The array index is same as the tag.
+*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
+u16 CDMA_MemCopy_CMD(u8 tag, u8 *dest, u8 *src,
+ u16 ByteCount, u16 flags)
+{
+ int i;
+
+ nand_dbg_print(NAND_DBG_DEBUG,
+ "CDMA MemC Command called tag=%u\n", tag);
+
+ debug_boundary_error(tag, 252, 0);
+
+ tag += MAX_CHANS;
+ PendingCMD[tag].Tag = tag - MAX_CHANS;
+ PendingCMD[tag].CMD = MEMCOPY_CMD;
+ PendingCMD[tag].DataAddr = 0;
+ PendingCMD[tag].Block = 0;
+ PendingCMD[tag].Page = 0;
+ PendingCMD[tag].PageCount = 0;
+ PendingCMD[tag].DataDestAddr = dest;
+ PendingCMD[tag].DataSrcAddr = src;
+ PendingCMD[tag].MemCopyByteCnt = ByteCount;
+ PendingCMD[tag].Flags = flags;
+ PendingCMD[tag].SBDCmdIndex = g_SBDCmdIndex;
+
+ for (i = 0; i <= MAX_CHANS; i++)
+ PendingCMD[tag].ChanSync[i] = 0;
+
+ PendingCMD[tag].Status = 0xB0B;
+
+ return PASS;
+}
+
+
+#if DEBUG_SYNC || VERBOSE
+/* Double check here because CheckSyncPoints also uses it */
+static void pcmd_per_ch(struct pending_cmd (*p)[MAX_CHANS + MAX_DESCS],
+ u16 tag_count, int *chIndexes)
+{
+ u32 i, j, chnl;
+
+ for (i = 0; i < MAX_CHANS; i++)
+ chIndexes[i] = 0;
+
+ for (i = 0; i < (tag_count + MAX_CHANS); i++) {
+ chnl = PendingCMD[i].Block /
+ (DeviceInfo.wTotalBlocks / totalUsedBanks);
+ debug_boundary_error(chnl, totalUsedBanks, i);
+
+ p[chnl][chIndexes[chnl]].Tag = PendingCMD[i].Tag;
+ p[chnl][chIndexes[chnl]].CMD = PendingCMD[i].CMD;
+ p[chnl][chIndexes[chnl]].DataAddr = PendingCMD[i].DataAddr;
+ p[chnl][chIndexes[chnl]].Block = PendingCMD[i].Block;
+ p[chnl][chIndexes[chnl]].Page = PendingCMD[i].Page;
+ p[chnl][chIndexes[chnl]].DataDestAddr =
+ PendingCMD[i].DataDestAddr;
+ p[chnl][chIndexes[chnl]].PageCount = PendingCMD[i].PageCount;
+ p[chnl][chIndexes[chnl]].DataSrcAddr =
+ PendingCMD[i].DataSrcAddr;
+ p[chnl][chIndexes[chnl]].MemCopyByteCnt =
+ PendingCMD[i].MemCopyByteCnt;
+ p[chnl][chIndexes[chnl]].ChanSync[0] =
+ PendingCMD[i].ChanSync[0];
+ p[chnl][chIndexes[chnl]].Status = PendingCMD[i].Status;
+ chIndexes[chnl]++;
+
+ for (j = 1; (j <= MAX_CHANS) && (PendingCMD[i].ChanSync[j]);
+ j++) {
+ p[chnl][chIndexes[chnl]].Tag = 0xFF;
+ p[chnl][chIndexes[chnl]].CMD = DUMMY_CMD;
+ p[chnl][chIndexes[chnl]].Block = PendingCMD[i].Block;
+ p[chnl][chIndexes[chnl]].ChanSync[0] =
+ PendingCMD[i].ChanSync[j];
+ chIndexes[chnl]++;
+ }
+ }
+}
+#endif
+
+#if VERBOSE
+/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+* Function: PrintPendingCMDs
+* Inputs: none
+* Outputs: none
+* Description: prints the PendingCMDs array
+* number of elements to print needs manual control
+* to keep it small
+*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
+void PrintPendingCMDs(u16 tag_count)
+{
+ u16 i;
+ u16 not_print;
+
+ nand_dbg_print(NAND_DBG_DEBUG, "Printing PendingCMDs Table\n");
+ nand_dbg_print(NAND_DBG_DEBUG, "-------------------------------"
+ "------------------------------------------|\n");
+ nand_dbg_print(NAND_DBG_DEBUG, " | Cache | Flash "
+ "| MemCopy | | |\n");
+ nand_dbg_print(NAND_DBG_DEBUG,
+ "Tag Command DataAddr Block Page PgCnt DestAddr SrcAddr "
+ "BCnt ChanSync Stat|\n");
+
+ for (i = 0; i < (tag_count + MAX_CHANS); i++) {
+ not_print = 0;
+
+ switch (PendingCMD[i].CMD) {
+ case ERASE_CMD:
+ nand_dbg_print(NAND_DBG_DEBUG, "%03d",
+ PendingCMD[i].Tag);
+ nand_dbg_print(NAND_DBG_DEBUG, " ERASE ");
+ break;
+ case WRITE_MAIN_CMD:
+ nand_dbg_print(NAND_DBG_DEBUG, "%03d",
+ PendingCMD[i].Tag);
+ nand_dbg_print(NAND_DBG_DEBUG, " WRITE ");
+ break;
+ case WRITE_MAIN_SPARE_CMD:
+ nand_dbg_print(NAND_DBG_DEBUG, "%03d",
+ PendingCMD[i].Tag);
+ nand_dbg_print(NAND_DBG_DEBUG,
+ " WRITE MAIN+SPARE ");
+ break;
+ case READ_MAIN_SPARE_CMD:
+ nand_dbg_print(NAND_DBG_DEBUG, "%03d",
+ PendingCMD[i].Tag);
+ nand_dbg_print(NAND_DBG_DEBUG,
+ " WRITE MAIN+SPARE ");
+ break;
+ case READ_MAIN_CMD:
+ nand_dbg_print(NAND_DBG_DEBUG, "%03d",
+ PendingCMD[i].Tag);
+ nand_dbg_print(NAND_DBG_DEBUG, " READ ");
+ break;
+ case MEMCOPY_CMD:
+ nand_dbg_print(NAND_DBG_DEBUG, "%03d",
+ PendingCMD[i].Tag);
+ nand_dbg_print(NAND_DBG_DEBUG, " MemCpy ");
+ break;
+ case DUMMY_CMD:
+ nand_dbg_print(NAND_DBG_DEBUG, "%03d",
+ PendingCMD[i].Tag);
+ nand_dbg_print(NAND_DBG_DEBUG, " DUMMY ");
+ break;
+ default:
+ if (i)
+ not_print = 1;
+ }
+
+ if (!not_print) {
+ nand_dbg_print(NAND_DBG_DEBUG, " %p",
+ PendingCMD[i].DataAddr);
+ nand_dbg_print(NAND_DBG_DEBUG, " %04X",
+ (unsigned int)PendingCMD[i].Block);
+ nand_dbg_print(NAND_DBG_DEBUG, " %04X",
+ PendingCMD[i].Page);
+ nand_dbg_print(NAND_DBG_DEBUG, " %04X",
+ PendingCMD[i].PageCount);
+ nand_dbg_print(NAND_DBG_DEBUG, " %p",
+ PendingCMD[i].DataDestAddr);
+ nand_dbg_print(NAND_DBG_DEBUG, " %p",
+ PendingCMD[i].DataSrcAddr);
+ nand_dbg_print(NAND_DBG_DEBUG, " %04X",
+ PendingCMD[i].MemCopyByteCnt);
+ nand_dbg_print(NAND_DBG_DEBUG, " %04X",
+ PendingCMD[i].ChanSync[0]);
+ nand_dbg_print(NAND_DBG_DEBUG, " %04X",
+ PendingCMD[i].Status);
+ nand_dbg_print(NAND_DBG_DEBUG, "|\n");
+ }
+ }
+
+ nand_dbg_print(NAND_DBG_DEBUG, " ----------------------------"
+ "---------------------------------------------|\n");
+}
+
+/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+* Function: PrintPendingCMDsPerChannel
+* Inputs: none
+* Outputs: none
+* Description: prints the PendingCMDs array on a per channel basis
+* number of elements to print needs manual control
+* to keep it small
+*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
+void PrintPendingCMDsPerChannel(u16 tag_count)
+{
+ u16 i, chnl;
+ u16 not_print = 0;
+ struct pending_cmd p_cmd_ch[MAX_CHANS][MAX_CHANS + MAX_DESCS];
+ int chIndexes[MAX_CHANS], maxChIndexes;
+
+ pcmd_per_ch(p_cmd_ch, tag_count, chIndexes);
+ nand_dbg_print(NAND_DBG_DEBUG,
+ "Printing PendingCMDsPerChannel Table\n");
+
+ for (i = 0; i < MAX_CHANS; i++)
+ nand_dbg_print(NAND_DBG_DEBUG,
+ " -------------------------------------|");
+ nand_dbg_print(NAND_DBG_DEBUG, "\n");
+
+ for (i = 0; i < MAX_CHANS; i++)
+ nand_dbg_print(NAND_DBG_DEBUG,
+ " Ch%1d |", i);
+ nand_dbg_print(NAND_DBG_DEBUG, "\n");
+
+ maxChIndexes = 0;
+ for (i = 0; i < MAX_CHANS; i++) {
+ nand_dbg_print(NAND_DBG_DEBUG,
+ "Tag Command FromAddr DestAddr Sync|");
+ if (maxChIndexes < chIndexes[i])
+ maxChIndexes = chIndexes[i];
+ }
+ nand_dbg_print(NAND_DBG_DEBUG, "\n");
+
+ for (i = 0; i <= maxChIndexes; i++) {
+ for (chnl = 0; chnl < MAX_CHANS; chnl++) {
+ not_print = 0;
+ if (chIndexes[chnl] > i) {
+ switch (p_cmd_ch[chnl][i].CMD) {
+ case ERASE_CMD:
+ nand_dbg_print(NAND_DBG_DEBUG,
+ "%03d",
+ p_cmd_ch[chnl][i].Tag);
+ nand_dbg_print(NAND_DBG_DEBUG,
+ " ERASE ");
+ nand_dbg_print(NAND_DBG_DEBUG,
+ " ");
+ nand_dbg_print(NAND_DBG_DEBUG,
+ " %04X:0000",
+ (unsigned int)
+ p_cmd_ch[chnl][i].Block);
+ break;
+ case WRITE_MAIN_CMD:
+ nand_dbg_print(NAND_DBG_DEBUG,
+ "%03d",
+ p_cmd_ch[chnl][i].Tag);
+ nand_dbg_print(NAND_DBG_DEBUG,
+ " WR_MN ");
+ nand_dbg_print(NAND_DBG_DEBUG,
+ " %p",
+ p_cmd_ch[chnl][i].DataAddr);
+ nand_dbg_print(NAND_DBG_DEBUG,
+ " %04X",
+ (unsigned int)
+ p_cmd_ch[chnl][i].Block);
+ nand_dbg_print(NAND_DBG_DEBUG,
+ ":%04X",
+ p_cmd_ch[chnl][i].Page);
+ break;
+ case WRITE_MAIN_SPARE_CMD:
+ nand_dbg_print(NAND_DBG_DEBUG,
+ "%03d",
+ p_cmd_ch[chnl][i].Tag);
+ nand_dbg_print(NAND_DBG_DEBUG,
+ " WR_M+S ");
+ nand_dbg_print(NAND_DBG_DEBUG,
+ " %p",
+ p_cmd_ch[chnl][i].DataAddr);
+ nand_dbg_print(NAND_DBG_DEBUG,
+ " %04X",
+ (unsigned int)
+ p_cmd_ch[chnl][i].Block);
+ nand_dbg_print(NAND_DBG_DEBUG,
+ ":%04X",
+ p_cmd_ch[chnl][i].Page);
+ break;
+ case READ_MAIN_SPARE_CMD:
+ nand_dbg_print(NAND_DBG_DEBUG,
+ "%03d",
+ p_cmd_ch[chnl][i].Tag);
+ nand_dbg_print(NAND_DBG_DEBUG,
+ " RD_M+S ");
+ nand_dbg_print(NAND_DBG_DEBUG,
+ " %04X",
+ (unsigned int)
+ p_cmd_ch[chnl][i].Block);
+ nand_dbg_print(NAND_DBG_DEBUG,
+ ":%04X",
+ p_cmd_ch[chnl][i].Page);
+ nand_dbg_print(NAND_DBG_DEBUG,
+ " %p",
+ p_cmd_ch[chnl][i].DataAddr);
+ break;
+ case READ_MAIN_CMD:
+ nand_dbg_print(NAND_DBG_DEBUG,
+ "%03d",
+ p_cmd_ch[chnl][i].Tag);
+ nand_dbg_print(NAND_DBG_DEBUG,
+ " READ ");
+ nand_dbg_print(NAND_DBG_DEBUG,
+ " %04X",
+ (unsigned int)
+ p_cmd_ch[chnl][i].Block);
+ nand_dbg_print(NAND_DBG_DEBUG,
+ ":%04X",
+ p_cmd_ch[chnl][i].Page);
+ nand_dbg_print(NAND_DBG_DEBUG,
+ " %p",
+ p_cmd_ch[chnl][i].DataAddr);
+ break;
+ case MEMCOPY_CMD:
+ nand_dbg_print(NAND_DBG_DEBUG,
+ "%03d",
+ p_cmd_ch[chnl][i].Tag);
+ nand_dbg_print(NAND_DBG_DEBUG,
+ " MemCpy ");
+ nand_dbg_print(NAND_DBG_DEBUG,
+ " %p",
+ p_cmd_ch[chnl][i].DataSrcAddr);
+ nand_dbg_print(NAND_DBG_DEBUG,
+ " %p",
+ p_cmd_ch[chnl][i].DataDestAddr);
+ break;
+ case DUMMY_CMD:
+ nand_dbg_print(NAND_DBG_DEBUG,
+ "%03d", p_cmd_ch[chnl][i].Tag);
+ nand_dbg_print(NAND_DBG_DEBUG,
+ " DUMMY ");
+ nand_dbg_print(NAND_DBG_DEBUG,
+ " %04X:0000",
+ (unsigned int)
+ p_cmd_ch[chnl][i].Block);
+ break;
+ default:
+ not_print = 1;
+ }
+ } else {
+ not_print = 1;
+ }
+
+ if (!not_print)
+ nand_dbg_print(NAND_DBG_DEBUG,
+ " %04X|",
+ p_cmd_ch[chnl][i].ChanSync[0]);
+ else
+ nand_dbg_print(NAND_DBG_DEBUG,
+ " |");
+
+ if (chnl == MAX_CHANS - 1)
+ nand_dbg_print(NAND_DBG_DEBUG, "\n");
+ }
+ }
+
+ nand_dbg_print(NAND_DBG_DEBUG, " ----------------------------"
+ "---------------------------------------------|\n");
+}
+
+/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+* Function: PrintCDMA_Descriptors
+* Inputs: none
+* Outputs: none
+* Description: prints the CDMA_Descriptors array
+* number of elements to print needs manual control
+* to keep it small
+*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
+void PrintCDMA_Descriptors(void)
+{
+ u16 i;
+ struct cdma_descriptor *pch[MAX_CHANS];
+ struct cdma_descriptor *pchTotal = NULL;
+ struct memcpy_descriptor *mcpyPtr;
+
+ char str[MAX_CHANS * 50 + 2];
+ char *strp;
+
+ for (i = 0; i < MAX_CHANS; i++) {
+ pch[i] = &(cdma_desc[i][0]);
+ pchTotal += (u32)pch[i];
+ }
+
+ nand_dbg_print(NAND_DBG_DEBUG,
+ " Printing CDMA_Descriptors Table \n");
+ nand_dbg_print(NAND_DBG_DEBUG,
+ "----------------------------------------------------"
+ "----------------------------------------------------"
+ "----------------------------------------------------"
+ "-----------------\n");
+ nand_dbg_print(NAND_DBG_DEBUG,
+ " CMD | FromAddr | ToAddr | Siz | Channel | CMD | "
+ "FromAddr | ToAddr | Siz | Channel | CMD | FromAddr | "
+ "ToAddr | Siz | Channel | CMD | FromAddr | ToAddr "
+ "| Siz | Channel\n");
+
+ while (pchTotal) {
+ pchTotal = NULL;
+ for (i = 0; i < MAX_CHANS; i++) {
+ strp = &str[i * (5 + 22 + 6 + 11)];
+ if (pch[i]) {
+ switch ((pch[i]->CommandType) >> 8) {
+ case 0x21:
+ sprintf(strp, " FWr ");
+ strp += 5;
+ sprintf(strp, " 0x%04x%04x",
+ (unsigned)pch[i]->MemAddrHi,
+ (u16)pch[i]->MemAddrLo);
+ strp += 11;
+ sprintf(strp, " 0x%04x%04x",
+ (unsigned)
+ pch[i]->FlashPointerHi,
+ (u16)
+ pch[i]->FlashPointerLo);
+ strp += 11;
+ break;
+ case 0x20:
+ if ((pch[i]->CommandFlags >> 10)) {
+ sprintf(strp, " Mcp ");
+ strp += 5;
+ mcpyPtr =
+ (struct memcpy_descriptor *)
+ ((pch[i]->MemCopyPointerHi << 16) |
+ pch[i]->MemCopyPointerLo);
+ sprintf(strp, " 0x%04x%04x",
+ (unsigned)mcpyPtr->SrcAddrHi,
+ (u16)mcpyPtr->SrcAddrLo);
+ strp += 11;
+ sprintf(strp, " 0x%04x%04x",
+ (unsigned)mcpyPtr->DestAddrHi,
+ (u16)mcpyPtr->DestAddrLo);
+ strp += 11;
+ } else {
+ sprintf(strp, " FRd ");
+ strp += 5;
+ sprintf(strp, " 0x%04x%04x",
+ (unsigned)
+ pch[i]->FlashPointerHi,
+ (u16)
+ pch[i]->FlashPointerLo);
+ strp += 11;
+ sprintf(strp, " 0x%04x%04x",
+ (unsigned)pch[i]->MemAddrHi,
+ (u16)pch[i]->MemAddrLo);
+ strp += 11;
+ }
+ break;
+ default:
+ if (pch[i]->CommandType == 1) {
+ sprintf(strp, " Ers ");
+ strp += 5;
+ } else {
+ sprintf(strp, " INV ");
+ strp += 5;
+ }
+ sprintf(strp,
+ " ");
+ strp += 22;
+ break;
+ }
+
+ sprintf(strp, " %3d ",
+ (int)(pch[i]->CommandType & 0xFFF));
+ strp += 6;
+ sprintf(strp, " 0x%04x ||",
+ (unsigned)pch[i]->Channel);
+ strp += 11;
+
+ pch[i] = (struct cdma_descriptor *)
+ ((pch[i]->NxtPointerHi << 16) |
+ pch[i]->NxtPointerLo);
+ pchTotal += (u32)pch[i];
+ } else {
+ sprintf(strp,
+ " |");
+ strp += 44;
+ }
+ }
+
+ sprintf(strp, "\n");
+ nand_dbg_print(NAND_DBG_DEBUG, "%s", str);
+ }
+ nand_dbg_print(NAND_DBG_DEBUG,
+ " ---------------------------------------------------"
+ "----------------------|\n");
+}
+#endif
+
+static u32 calc_next_desc_ptr(u16 c, u16 d)
+{
+ u32 offset, addr;
+
+ offset = sizeof(struct cdma_descriptor) *
+ (c * MAX_DESC_PER_CHANNEL + d + 1);
+ addr = (unsigned long)cdma_desc + offset;
+
+ return (unsigned long)GLOB_MEMMAP_TOBUS((u32 *)addr);
+}
+
+static u32 calc_desc_ptr(u16 c)
+{
+ u32 offset, addr ;
+
+ offset = sizeof(struct cdma_descriptor) * c * MAX_DESC_PER_CHANNEL;
+ addr = (u32)GLOB_MEMMAP_TOBUS((u32 *)cdma_desc) + offset;
+
+ return addr;
+}
+
+/* Reset cdma_desc d in channel c to 0 */
+static void reset_cdma_desc(u16 c, u16 d)
+{
+ cdma_desc[c][d].NxtPointerHi = 0;
+ cdma_desc[c][d].NxtPointerLo = 0;
+ cdma_desc[c][d].FlashPointerHi = 0;
+ cdma_desc[c][d].FlashPointerLo = 0;
+ cdma_desc[c][d].CommandType = 0;
+ cdma_desc[c][d].MemAddrHi = 0;
+ cdma_desc[c][d].MemAddrLo = 0;
+ cdma_desc[c][d].CommandFlags = 0;
+ cdma_desc[c][d].Channel = 0;
+ cdma_desc[c][d].Status = 0;
+ cdma_desc[c][d].MemCopyPointerHi = 0;
+ cdma_desc[c][d].MemCopyPointerLo = 0;
+ cdma_desc[c][d].Tag = 0;
+}
+
+/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+* Function: CDMA_AddDummyDesc
+* Inputs: Channel number
+* Outputs: None
+* Description: This function adds a dummy descriptor at the descriptor
+* location (from dcount structure) in the given channel.
+*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
+static void CDMA_AddDummyDesc(u16 channel)
+{
+ u16 c, d;
+ u32 *ptr;
+ u32 cont;
+ unsigned long next_ptr;
+
+ c = channel;
+ d = dcount[c];
+
+ debug_boundary_error(d, MAX_DESC_PER_CHANNEL, 0);
+
+ reset_cdma_desc(c, d);
+
+ next_ptr = calc_next_desc_ptr(c, d);
+ cdma_desc[c][d].NxtPointerHi = next_ptr >> 16;
+ cdma_desc[c][d].NxtPointerLo = next_ptr;
+
+ ptr = (u32 *)(u32)(MODE_10 | (c << 24));
+ cdma_desc[c][d].FlashPointerHi = (u32)((u32)ptr >> 16);
+ cdma_desc[c][d].FlashPointerLo = (u32)ptr;
+
+ cdma_desc[c][d].CommandType = 0x42;
+
+ cont = 1;
+ cdma_desc[c][d].CommandFlags = (0 << 10) | (cont << 9) |
+ (0 << 8) | 0x40;
+
+ cdma_desc[c][d].Status = 0;
+ cdma_desc[c][d].Tag = 0xFF;
+
+ return;
+}
+
+
+#if FLASH_ESL
+#else
+/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+* Function: CDMA_AddDummyDescAtEnd
+* Inputs: Channel number
+* Outputs: None
+* Description: This function adds a dummy descriptor at the end of the
+* descriptor chain for the given channel.
+* The purpose of these descriptors is to get a single
+* interrupt on cmd dma chain completion using sync.
+*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
+static void CDMA_AddDummyDescAtEnd(u16 channel)
+{
+ u16 c, d;
+ u32 *ptr;
+ u32 cont;
+
+ c = channel;
+ d = dcount[c];
+ debug_boundary_error(d, MAX_DESC_PER_CHANNEL, 0);
+
+ reset_cdma_desc(c, d);
+
+ ptr = (u32 *)(u32)(MODE_10 | (c << 24));
+ cdma_desc[c][d].FlashPointerHi = (u32)((u32)ptr >> 16);
+ cdma_desc[c][d].FlashPointerLo = (u32)ptr;
+
+ cdma_desc[c][d].CommandType = 0xFFFF;
+
+ cont = 0;
+ cdma_desc[c][d].CommandFlags = (0 << 10) | (cont << 9) |
+ (1 << 8) | 0x40;
+
+ cdma_desc[c][d].Channel = ((1 << 15) | (1 << 14) |
+ (c << CHANNEL_ID_OFFSET) |
+ ((GLOB_valid_banks[3] << 7) |
+ (GLOB_valid_banks[2] << 6) |
+ (GLOB_valid_banks[1] << 5) |
+ (GLOB_valid_banks[0] << 4)) | 0);
+
+ cdma_desc[c][d].Status = 0;
+ cdma_desc[c][d].Tag = 0xFF;
+
+ return;
+}
+
+u32 CDMA_Memory_Pool_Size(void)
+{
+ return (sizeof(struct cdma_descriptor) * MAX_CHANS *
+ MAX_DESC_PER_CHANNEL) +
+ (sizeof(struct memcpy_descriptor) * MAX_CHANS *
+ MAX_DESCS) + 6;
+}
+
+int CDMA_Mem_Config(u8 *pMem)
+{
+ ALIGN_DWORD_FWD(pMem);
+ cdma_desc = (struct cdma_descriptor (*)[MAX_DESC_PER_CHANNEL])pMem;
+ pMem += (sizeof(struct cdma_descriptor) * MAX_CHANS *
+ MAX_DESC_PER_CHANNEL);
+ ALIGN_DWORD_FWD(pMem);
+ memcp_desc = (struct memcpy_descriptor (*)[MAX_DESCS])pMem;
+
+ return PASS;
+}
+
+#if FLASH_CDMA
+/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+* Function: CDMA_Flash_Init
+* Inputs: none
+* Outputs: PASS=0 (notice 0=ok here)
+* Description: This should be called at power up.
+* It disables interrupts and clears status bits
+* issues flash reset command
+* configures the controller registers
+* It sets the interrupt mask and enables interrupts
+* It pre-builds special descriptors
+*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
+u16 CDMA_Flash_Init(void)
+{
+ u16 i, j;
+ u16 int_en_mask;
+ u16 cdma_int_en_mask;
+
+ NAND_Flash_Reset();
+
+ /* Set the global Enable masks for only those interrupts
+ * that are supported */
+ cdma_int_en_mask = (DMA_INTR__DESC_COMP_CHANNEL0 |
+ DMA_INTR__DESC_COMP_CHANNEL1 |
+ DMA_INTR__DESC_COMP_CHANNEL2 |
+ DMA_INTR__DESC_COMP_CHANNEL3 |
+ DMA_INTR__MEMCOPY_DESC_COMP);
+
+ int_en_mask = (INTR_STATUS0__ECC_ERR |
+ INTR_STATUS0__PROGRAM_FAIL |
+ INTR_STATUS0__ERASE_FAIL);
+
+ /* Disable all interrupts */
+ iowrite32(0, FlashReg + GLOBAL_INT_ENABLE);
+ iowrite32(0, FlashReg + INTR_EN0);
+ iowrite32(0, FlashReg + INTR_EN1);
+ iowrite32(0, FlashReg + INTR_EN2);
+ iowrite32(0, FlashReg + INTR_EN3);
+
+ /* Clear all status bits */
+ iowrite32(0xFFFF, FlashReg + INTR_STATUS0);
+ iowrite32(0xFFFF, FlashReg + INTR_STATUS1);
+ iowrite32(0xFFFF, FlashReg + INTR_STATUS2);
+ iowrite32(0xFFFF, FlashReg + INTR_STATUS3);
+
+ iowrite32(0, FlashReg + DMA_INTR_EN);
+ iowrite32(0xFFFF, FlashReg + DMA_INTR);
+
+ iowrite32(cdma_int_en_mask, FlashReg + DMA_INTR_EN);
+
+ iowrite32(int_en_mask, FlashReg + INTR_EN0);
+ iowrite32(int_en_mask, FlashReg + INTR_EN1);
+ iowrite32(int_en_mask, FlashReg + INTR_EN2);
+ iowrite32(int_en_mask, FlashReg + INTR_EN3);
+
+ /* Enable global interrupt to host */
+ iowrite32(GLOBAL_INT_EN_FLAG, FlashReg + GLOBAL_INT_ENABLE);
+
+ /* clear the pending CMD array */
+ for (i = 0; i < (MAX_DESCS + MAX_CHANS); i++) {
+ PendingCMD[i].CMD = 0;
+ PendingCMD[i].Tag = 0;
+ PendingCMD[i].DataAddr = 0;
+ PendingCMD[i].Block = 0;
+ PendingCMD[i].Page = 0;
+ PendingCMD[i].PageCount = 0;
+ PendingCMD[i].DataDestAddr = 0;
+ PendingCMD[i].DataSrcAddr = 0;
+ PendingCMD[i].MemCopyByteCnt = 0;
+
+ for (j = 0; j <= MAX_CHANS; j++)
+ PendingCMD[i].ChanSync[j] = 0;
+
+ PendingCMD[i].Status = 0;
+ PendingCMD[i].SBDCmdIndex = 0;
+ }
+
+ return PASS;
+}
+
+static u16 abort_chnl_helper(u16 ch)
+{
+ u16 desc;
+
+ for (desc = 0; desc < dcount[ch]; desc++) {
+ if ((cdma_desc[ch][desc].Status & CMD_DMA_DESC_COMP) !=
+ CMD_DMA_DESC_COMP) {
+ if (cdma_desc[ch][desc].Tag != 0xFF)
+ PendingCMD[cdma_desc[ch][desc].Tag].Status =
+ CMD_PASS;
+ break;
+ } else {
+ if (cdma_desc[ch][desc].Tag != 0xFF)
+ PendingCMD[cdma_desc[ch][desc].Tag].Status =
+ CMD_PASS;
+ }
+ }
+
+ return desc;
+}
+
+/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+* Function: CDMA_AbortChannels
+* Inputs: channel with failed descriptor
+* Outputs: PASS/ FAIL status
+* Description: This function is called to Abort all the other active channels
+* when a channel gets an error.
+*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
+u16 CDMA_AbortChannels(u16 chan)
+{
+ u16 c, d;
+ u16 aborts_comp;
+ u16 DescB4Abort[MAX_CHANS];
+ u16 status = PASS;
+ u32 active_chnl = 0;
+
+ debug_boundary_error(chan, totalUsedBanks, 0);
+
+ /* If status not complete, Abort the channel */
+ for (c = 0; c < MAX_CHANS; c++) {
+ /* Initialize the descriptor to be aborted */
+ DescB4Abort[c] = 0xFF;
+ if ((c != chan) && (1 == GLOB_valid_banks[c])) {
+ d = abort_chnl_helper(c);
+ if ((ioread32(FlashReg + CHNL_ACTIVE) & (1 << c)) ==
+ (1 << c)) {
+ DescB4Abort[c] = d;
+ aborts_comp = 0;
+ iowrite32(MODE_02 | (0 << 4), FlashMem);
+ iowrite32((0xF << 4) | c, FlashMem + 0x10);
+ }
+ }
+ }
+
+ /* Check if aborts (of all active channels) are done */
+ while (1) {
+ aborts_comp = 1;
+ for (c = 0; c < MAX_CHANS; c++) {
+ if ((DescB4Abort[c] != 0xFF) && (c != chan)) {
+ if (0 == c)
+ active_chnl = CHNL_ACTIVE__CHANNEL0;
+ else if (1 == c)
+ active_chnl = CHNL_ACTIVE__CHANNEL1;
+ else if (2 == c)
+ active_chnl = CHNL_ACTIVE__CHANNEL2;
+ else if (3 == c)
+ active_chnl = CHNL_ACTIVE__CHANNEL3;
+
+ if (!(ioread32(FlashReg + CHNL_ACTIVE) &
+ active_chnl))
+ DescB4Abort[c] = 0xFF;
+ else
+ aborts_comp = 0;
+ }
+ }
+
+ if (1 == aborts_comp)
+ break;
+ }
+
+ ResetSyncModule();
+
+ return status;
+}
+
+/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+* Function: CDMA_UpdateEventStatus
+* Inputs: none
+* Outputs: none
+* Description: This function update the event status of all the channels
+* when an error condition is reported.
+*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
+u16 CDMA_UpdateEventStatus(void)
+{
+ u16 i, j, c, d, status = PASS;
+
+ for (c = 0; c < MAX_CHANS; c++) {
+ if (!GLOB_valid_banks[c])
+ continue;
+
+ d = dcount[c];
+ debug_boundary_error(d, MAX_DESC_PER_CHANNEL, 0);
+ for (j = 0; j < d; j++) {
+ /* Check for the descriptor with failure
+ * (not just desc_complete) */
+ if (!(cdma_desc[c][j].Status & CMD_DMA_DESC_FAIL))
+ continue;
+
+ /* All the previous command's status for this channel
+ * must be good (no errors reported) */
+ for (i = 0; i < j; i++) {
+ if (cdma_desc[c][i].Tag != 0xFF)
+ PendingCMD[cdma_desc[c][i].Tag].Status
+ = CMD_PASS;
+ }
+
+ status = CDMA_AbortChannels(c);
+
+ return status;
+ }
+ }
+
+ return status;
+}
+#endif
+
+
+static void cdma_trans(u16 chan)
+{
+ iowrite32(MODE_10 | (chan << 24), FlashMem);
+ iowrite32((1 << 7) | chan, FlashMem + 0x10);
+
+ iowrite32(MODE_10 | (chan << 24) |
+ ((0x0FFFF & ((u32)(calc_desc_ptr(chan)) >> 16)) << 8),
+ FlashMem);
+ iowrite32((1 << 7) | (1 << 4) | 0, FlashMem + 0x10);
+
+ iowrite32(MODE_10 | (chan << 24) |
+ ((0x0FFFF & ((u32)(calc_desc_ptr(chan)))) << 8),
+ FlashMem);
+ iowrite32((1 << 7) | (1 << 5) | 0, FlashMem + 0x10);
+
+ iowrite32(MODE_10 | (chan << 24), FlashMem);
+ iowrite32((1 << 7) | (1 << 5) | (1 << 4) | 0, FlashMem + 0x10);
+}
+
+/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+* Function: CDMA_Execute_CMDs (for use with CMD_DMA)
+* Inputs: tag_count: the number of pending cmds to do
+* Outputs: PASS/FAIL
+* Description: Build the SDMA chain(s) by making one CMD-DMA descriptor
+* for each pending command, start the CDMA engine, and return.
+*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
+u16 CDMA_Execute_CMDs(u16 tag_count)
+{
+ u16 i, j;
+ u8 cont;
+ u64 flash_add;
+ u32 *ptr;
+ u32 mapped_addr;
+ u16 status = PASS;
+ u16 c, d;
+ u16 tmp_c;
+ unsigned long next_ptr;
+
+ if (tag_count >= MAX_DESCS)
+ return FAIL;
+
+ c = 0;
+ d = 0;
+
+ for (c = 0; c < MAX_CHANS; c++)
+ for (d = 0; d < MAX_DESC_PER_CHANNEL; d++)
+ reset_cdma_desc(c, d);
+
+ debug_boundary_error(totalUsedBanks - 1, MAX_CHANS, 0);
+
+ for (c = 0; c < totalUsedBanks; c++) {
+ dcount[c] = 0;
+ PendingCMD[c].CMD = DUMMY_CMD;
+ PendingCMD[c].SBDCmdIndex = 0xFF;
+ PendingCMD[c].Tag = 0xFF;
+ PendingCMD[c].Block = c * (DeviceInfo.wTotalBlocks /
+ totalUsedBanks);
+
+ for (i = 0; i <= MAX_CHANS; i++)
+ PendingCMD[c].ChanSync[i] = 0;
+ }
+
+ c = 0;
+
+ CDMA_AddSyncPoints(tag_count);
+#if DEBUG_SYNC
+ CDMA_CheckSyncPoints(tag_count);
+#endif
+
+ for (i = 0; i < (tag_count + MAX_CHANS); i++) {
+ if ((i >= totalUsedBanks) && (i < MAX_CHANS))
+ continue;
+
+ if (PendingCMD[i].Block >= DeviceInfo.wTotalBlocks) {
+ PendingCMD[i].Status = CMD_NOT_DONE;
+ continue;
+ }
+
+ c = 0;
+ tmp_c = PendingCMD[i].Block /
+ (DeviceInfo.wTotalBlocks / totalUsedBanks);
+
+ debug_boundary_error(tmp_c, totalUsedBanks, 0);
+
+ if (0 == tmp_c) {
+ c = tmp_c;
+ } else {
+ for (j = 1; j < MAX_CHANS; j++) {
+ if (GLOB_valid_banks[j]) {
+ tmp_c--;
+ if (0 == tmp_c) {
+ c = j;
+ break;
+ }
+ }
+ }
+ }
+
+ if (GLOB_valid_banks[c] == 1) {
+ d = dcount[c];
+ dcount[c]++;
+ } else {
+ continue;
+ }
+
+ next_ptr = calc_next_desc_ptr(c, d);
+ cdma_desc[c][d].NxtPointerHi = next_ptr >> 16;
+ cdma_desc[c][d].NxtPointerLo = next_ptr;
+
+ /* Use the Block offset within a bank */
+ tmp_c = PendingCMD[i].Block /
+ (DeviceInfo.wTotalBlocks / totalUsedBanks);
+ debug_boundary_error(tmp_c, totalUsedBanks, i);
+ flash_add = (u64)(PendingCMD[i].Block - tmp_c *
+ (DeviceInfo.wTotalBlocks / totalUsedBanks)) *
+ DeviceInfo.wBlockDataSize +
+ (u64)(PendingCMD[i].Page) * DeviceInfo.wPageDataSize;
+
+#if FLASH_CDMA
+ ptr = (u32 *)(MODE_10 | (c << 24) |
+ (u32)GLOB_u64_Div(flash_add,
+ DeviceInfo.wPageDataSize));
+ cdma_desc[c][d].FlashPointerHi = (u32)ptr >> 16;
+ cdma_desc[c][d].FlashPointerLo = (u32)ptr;
+#endif
+ /* set continue flag except if last cmd-descriptor */
+ cont = 1;
+
+ if ((PendingCMD[i].CMD == WRITE_MAIN_SPARE_CMD) ||
+ (PendingCMD[i].CMD == READ_MAIN_SPARE_CMD)) {
+ /* Descriptor to set Main+Spare Access Mode */
+ cdma_desc[c][d].CommandType = 0x43;
+ cdma_desc[c][d].CommandFlags =
+ (0 << 10) | (cont << 9) | (0 << 8) | 0x40;
+ cdma_desc[c][d].MemAddrHi = 0;
+ cdma_desc[c][d].MemAddrLo = 0;
+
+ cdma_desc[c][d].Channel = 0;
+ cdma_desc[c][d].Status = 0;
+ cdma_desc[c][d].Tag = i;
+
+ dcount[c]++;
+ d++;
+
+ reset_cdma_desc(c, d);
+
+ next_ptr = calc_next_desc_ptr(c, d);
+ cdma_desc[c][d].NxtPointerHi = next_ptr >> 16;
+ cdma_desc[c][d].NxtPointerLo = next_ptr;
+
+#if FLASH_CDMA
+ cdma_desc[c][d].FlashPointerHi = (u32)ptr >> 16;
+ cdma_desc[c][d].FlashPointerLo = (u32)ptr;
+#endif
+ }
+
+ switch (PendingCMD[i].CMD) {
+ case ERASE_CMD:
+ cdma_desc[c][d].CommandType = 1;
+ cdma_desc[c][d].CommandFlags =
+ (0 << 10) | (cont << 9) | (0 << 8) | 0x40;
+ cdma_desc[c][d].MemAddrHi = 0;
+ cdma_desc[c][d].MemAddrLo = 0;
+ break;
+
+ case WRITE_MAIN_CMD:
+ cdma_desc[c][d].CommandType =
+ 0x2100 | PendingCMD[i].PageCount;
+ cdma_desc[c][d].CommandFlags =
+ (0 << 10) | (cont << 9) | (0 << 8) | 0x40;
+ mapped_addr = (u32)GLOB_MEMMAP_TOBUS
+ ((u32 *)PendingCMD[i].DataAddr);
+ cdma_desc[c][d].MemAddrHi = mapped_addr >> 16;
+ cdma_desc[c][d].MemAddrLo = mapped_addr;
+ break;
+
+ case READ_MAIN_CMD:
+ cdma_desc[c][d].CommandType =
+ 0x2000 | (PendingCMD[i].PageCount);
+ cdma_desc[c][d].CommandFlags =
+ (0 << 10) | (cont << 9) | (0 << 8) | 0x40;
+ mapped_addr = (u32)GLOB_MEMMAP_TOBUS
+ ((u32 *)PendingCMD[i].DataAddr);
+ cdma_desc[c][d].MemAddrHi = mapped_addr >> 16;
+ cdma_desc[c][d].MemAddrLo = mapped_addr;
+ break;
+
+ case WRITE_MAIN_SPARE_CMD:
+ cdma_desc[c][d].CommandType =
+ 0x2100 | (PendingCMD[i].PageCount);
+ cdma_desc[c][d].CommandFlags =
+ (0 << 10) | (cont << 9) | (0 << 8) | 0x40;
+ mapped_addr = (u32)GLOB_MEMMAP_TOBUS
+ ((u32 *)PendingCMD[i].DataAddr);
+ cdma_desc[c][d].MemAddrHi = mapped_addr >> 16;
+ cdma_desc[c][d].MemAddrLo = mapped_addr;
+ break;
+
+ case READ_MAIN_SPARE_CMD:
+ cdma_desc[c][d].CommandType =
+ 0x2000 | (PendingCMD[i].PageCount);
+ cdma_desc[c][d].CommandFlags =
+ (0 << 10) | (cont << 9) | (0 << 8) | 0x40;
+ mapped_addr = (u32)GLOB_MEMMAP_TOBUS
+ ((u32 *)PendingCMD[i].DataAddr);
+ cdma_desc[c][d].MemAddrHi = mapped_addr >> 16;
+ cdma_desc[c][d].MemAddrLo = mapped_addr;
+ break;
+
+ case MEMCOPY_CMD:
+ cdma_desc[c][d].CommandType =
+ 0x2000 | (PendingCMD[i].PageCount);
+ cdma_desc[c][d].CommandFlags =
+ (1 << 10) | (cont << 9) | (0 << 8) | 0x40;
+ mapped_addr = (unsigned int)GLOB_MEMMAP_TOBUS
+ ((u32 *)&memcp_desc[c][d]);
+ cdma_desc[c][d].MemCopyPointerHi = mapped_addr >> 16;
+ cdma_desc[c][d].MemCopyPointerLo = mapped_addr;
+
+ memcp_desc[c][d].NxtPointerHi = 0;
+ memcp_desc[c][d].NxtPointerLo = 0;
+
+ mapped_addr = (u32)GLOB_MEMMAP_TOBUS
+ ((u32 *)PendingCMD[i].DataSrcAddr);
+ memcp_desc[c][d].SrcAddrHi = mapped_addr >> 16;
+ memcp_desc[c][d].SrcAddrLo = mapped_addr;
+ mapped_addr = (u32)GLOB_MEMMAP_TOBUS
+ ((u32 *)PendingCMD[i].DataDestAddr);
+ memcp_desc[c][d].DestAddrHi = mapped_addr >> 16;
+ memcp_desc[c][d].DestAddrLo = mapped_addr;
+
+ memcp_desc[c][d].XferSize =
+ PendingCMD[i].MemCopyByteCnt;
+ memcp_desc[c][d].MemCopyFlags =
+ (0 << 15 | 0 << 14 | 27 << 8 | 0x40);
+ memcp_desc[c][d].MemCopyStatus = 0;
+ break;
+
+ case DUMMY_CMD:
+ default:
+ cdma_desc[c][d].CommandType = 0XFFFF;
+ cdma_desc[c][d].CommandFlags =
+ (0 << 10) | (cont << 9) | (0 << 8) | 0x40;
+ cdma_desc[c][d].MemAddrHi = 0;
+ cdma_desc[c][d].MemAddrLo = 0;
+ break;
+ }
+
+ cdma_desc[c][d].Channel = PendingCMD[i].ChanSync[0];
+ cdma_desc[c][d].Status = 0;
+ cdma_desc[c][d].Tag = i;
+
+ for (j = 1; j <= MAX_CHANS; j++) {
+ if (PendingCMD[i].ChanSync[j]) {
+ if (1 == GLOB_valid_banks[c]) {
+ CDMA_AddDummyDesc(c);
+ d = dcount[c]++;
+ cdma_desc[c][d].Channel =
+ PendingCMD[i].ChanSync[j];
+ }
+ }
+ }
+
+ if ((PendingCMD[i].CMD == WRITE_MAIN_SPARE_CMD) ||
+ (PendingCMD[i].CMD == READ_MAIN_SPARE_CMD)) {
+ /* Descriptor to set back Main Area Access Mode */
+ dcount[c]++;
+ d++;
+ debug_boundary_error(d, MAX_DESC_PER_CHANNEL, 0);
+ next_ptr = calc_next_desc_ptr(c, d);
+ cdma_desc[c][d].NxtPointerHi = next_ptr >> 16;
+ cdma_desc[c][d].NxtPointerLo = next_ptr;
+#if FLASH_CDMA
+ cdma_desc[c][d].FlashPointerHi = (u32)ptr >> 16;
+ cdma_desc[c][d].FlashPointerLo = (u32)ptr;
+#endif
+ cdma_desc[c][d].CommandType = 0x42;
+ cdma_desc[c][d].CommandFlags =
+ (0 << 10) | (cont << 9) | (0 << 8) | 0x40;
+ cdma_desc[c][d].MemAddrHi = 0;
+ cdma_desc[c][d].MemAddrLo = 0;
+
+ cdma_desc[c][d].Channel = PendingCMD[i].ChanSync[0];
+ cdma_desc[c][d].Status = 0;
+ cdma_desc[c][d].Tag = i;
+ }
+ }
+
+ for (c = 0; c < MAX_CHANS; c++) {
+ if (GLOB_valid_banks[c])
+ CDMA_AddDummyDescAtEnd(c);
+ }
+
+#if FLASH_CDMA
+ iowrite32(1, FlashReg + DMA_ENABLE);
+ /* Wait for DMA to be enabled before issuing the next command */
+ while (!(ioread32(FlashReg + DMA_ENABLE) & DMA_ENABLE__FLAG))
+ ;
+
+ for (c = 0; c < MAX_CHANS; c++) {
+ if (!GLOB_valid_banks[c])
+ continue;
+ cdma_trans(c);
+ }
+#endif
+
+ return status;
+}
+
+
+#if FLASH_CDMA
+static void ResetSyncModule(void)
+{
+ u16 c, d;
+ u32 *ptr;
+ u32 cont;
+ unsigned long next_ptr;
+
+ /* Disable all interrupts */
+ iowrite32(0, FlashReg + GLOBAL_INT_ENABLE);
+
+ /* Clear all DMA interrupt bits before starting the chains */
+ iowrite32(ioread32(FlashReg + DMA_INTR), FlashReg + DMA_INTR);
+
+ for (c = 0; c < MAX_CHANS; c++) {
+ for (d = 0; d < MAX_SYNC_POINTS; d++) {
+ reset_cdma_desc(c, d);
+
+ next_ptr = calc_next_desc_ptr(c, d);
+ cdma_desc[c][d].NxtPointerHi = next_ptr >> 16;
+ cdma_desc[c][d].NxtPointerLo = next_ptr;
+
+ ptr = (u32 *)(u32)(MODE_10 | (c << 24));
+ cdma_desc[c][d].FlashPointerHi =
+ (u32)((u32)ptr >> 16);
+ cdma_desc[c][d].FlashPointerLo =
+ (u32)ptr;
+
+ cdma_desc[c][d].CommandType = 0xFFFF;
+
+ if (d == (MAX_SYNC_POINTS - 1)) {
+ cont = 0;
+ cdma_desc[c][d].CommandFlags = (0 << 10) |
+ (cont << 9) | (1 << 8) | 0x40;
+ } else {
+ cont = 1;
+ cdma_desc[c][d].CommandFlags = (0 << 10) |
+ (cont << 9) | (0 << 8) | 0x40;
+ }
+
+ cdma_desc[c][d].Channel = ((0 << 15) | (1 << 14) |
+ (c << CHANNEL_ID_OFFSET) |
+ (1 << (4 + c)) | d);
+
+ cdma_desc[c][d].Status = 0;
+ cdma_desc[c][d].Tag = c * MAX_SYNC_POINTS + d;
+ }
+ }
+
+ for (c = 0; c < MAX_CHANS; c++)
+ cdma_trans(c);
+
+ while ((ioread32(FlashReg + DMA_INTR) &
+ (DMA_INTR__DESC_COMP_CHANNEL0 |
+ DMA_INTR__DESC_COMP_CHANNEL1 |
+ DMA_INTR__DESC_COMP_CHANNEL2 |
+ DMA_INTR__DESC_COMP_CHANNEL3)) !=
+ (DMA_INTR__DESC_COMP_CHANNEL0 |
+ DMA_INTR__DESC_COMP_CHANNEL1 |
+ DMA_INTR__DESC_COMP_CHANNEL2 |
+ DMA_INTR__DESC_COMP_CHANNEL3))
+ ;
+
+ iowrite32(ioread32(FlashReg + DMA_INTR), FlashReg + DMA_INTR);
+ iowrite32(GLOBAL_INT_EN_FLAG, FlashReg + GLOBAL_INT_ENABLE);
+}
+
+int is_cdma_interrupt(void)
+{
+ u32 ints_b0, ints_b1, ints_b2, ints_b3, ints_cdma;
+ u32 int_en_mask;
+ u32 cdma_int_en_mask;
+
+ /* Set the global Enable masks for only those interrupts
+ * that are supported */
+ cdma_int_en_mask = (DMA_INTR__DESC_COMP_CHANNEL0 |
+ DMA_INTR__DESC_COMP_CHANNEL1 |
+ DMA_INTR__DESC_COMP_CHANNEL2 |
+ DMA_INTR__DESC_COMP_CHANNEL3 |
+ DMA_INTR__MEMCOPY_DESC_COMP);
+
+ int_en_mask = (INTR_STATUS0__ECC_ERR |
+ INTR_STATUS0__PROGRAM_FAIL |
+ INTR_STATUS0__ERASE_FAIL);
+
+ ints_b0 = ioread32(FlashReg + INTR_STATUS0) & int_en_mask;
+ ints_b1 = ioread32(FlashReg + INTR_STATUS1) & int_en_mask;
+ ints_b2 = ioread32(FlashReg + INTR_STATUS2) & int_en_mask;
+ ints_b3 = ioread32(FlashReg + INTR_STATUS3) & int_en_mask;
+ ints_cdma = ioread32(FlashReg + DMA_INTR) & cdma_int_en_mask;
+
+ if (ints_b0 || ints_b1 || ints_b2 || ints_b3 || ints_cdma) {
+ nand_dbg_print(NAND_DBG_DEBUG, "NAND controller interrupt!\n"
+ "ints_bank0 to ints_bank3: 0x%x, 0x%x, 0x%x, 0x%x\n"
+ "ints_cdma: 0x%x\n",
+ ints_b0, ints_b1, ints_b2, ints_b3, ints_cdma);
+ return 1;
+ } else {
+ nand_dbg_print(NAND_DBG_DEBUG,
+ "Not a NAND controller interrupt!\n");
+ return 0;
+ }
+}
+
+static void update_event_status(void)
+{
+ u16 i, c, d;
+
+ for (c = 0; c < MAX_CHANS; c++) {
+ if (GLOB_valid_banks[c]) {
+ d = dcount[c];
+ debug_boundary_error(d, MAX_DESC_PER_CHANNEL, 0);
+ for (i = 0; i < d; i++) {
+ if (cdma_desc[c][i].Tag != 0xFF)
+ PendingCMD[cdma_desc[c][i].Tag].Status
+ = CMD_PASS;
+#if FLASH_CDMA
+ if ((cdma_desc[c][i].CommandType == 0x41) ||
+ (cdma_desc[c][i].CommandType == 0x42) ||
+ (cdma_desc[c][i].CommandType == 0x43))
+ continue;
+
+ switch (PendingCMD[cdma_desc[c][i].Tag].CMD) {
+ case READ_MAIN_SPARE_CMD:
+ Conv_Main_Spare_Data_Phy2Log_Format(
+ PendingCMD[
+ cdma_desc[c][i].Tag].DataAddr,
+ PendingCMD[
+ cdma_desc[c][i].Tag].
+ PageCount);
+ break;
+ case READ_SPARE_CMD:
+ Conv_Spare_Data_Phy2Log_Format(
+ PendingCMD[
+ cdma_desc[c][i].Tag].
+ DataAddr);
+ break;
+ default:
+ break;
+ }
+#endif
+ }
+ }
+ }
+}
+
+static u16 do_ecc_for_desc(u16 c, u8 *buf,
+ u16 page)
+{
+ u16 event = EVENT_NONE;
+ u16 err_byte;
+ u8 err_sector;
+ u8 err_page = 0;
+ u8 err_device;
+ u16 ecc_correction_info;
+ u16 err_address;
+ u32 eccSectorSize;
+ u8 *err_pos;
+
+ eccSectorSize = ECC_SECTOR_SIZE * (DeviceInfo.wDevicesConnected);
+
+ do {
+ if (0 == c)
+ err_page = ioread32(FlashReg + ERR_PAGE_ADDR0);
+ else if (1 == c)
+ err_page = ioread32(FlashReg + ERR_PAGE_ADDR1);
+ else if (2 == c)
+ err_page = ioread32(FlashReg + ERR_PAGE_ADDR2);
+ else if (3 == c)
+ err_page = ioread32(FlashReg + ERR_PAGE_ADDR3);
+
+ err_address = ioread32(FlashReg + ECC_ERROR_ADDRESS);
+ err_byte = err_address & ECC_ERROR_ADDRESS__OFFSET;
+ err_sector = ((err_address &
+ ECC_ERROR_ADDRESS__SECTOR_NR) >> 12);
+
+ ecc_correction_info = ioread32(FlashReg + ERR_CORRECTION_INFO);
+ err_device = ((ecc_correction_info &
+ ERR_CORRECTION_INFO__DEVICE_NR) >> 8);
+
+ if (ecc_correction_info & ERR_CORRECTION_INFO__ERROR_TYPE) {
+ return EVENT_UNCORRECTABLE_DATA_ERROR;
+ } else {
+ event = EVENT_CORRECTABLE_DATA_ERROR_FIXED;
+ if (err_byte < eccSectorSize) {
+ err_pos = buf +
+ (err_page - page) *
+ DeviceInfo.wPageDataSize +
+ err_sector * eccSectorSize +
+ err_byte *
+ DeviceInfo.wDevicesConnected +
+ err_device;
+ *err_pos ^= ecc_correction_info &
+ ERR_CORRECTION_INFO__BYTEMASK;
+ }
+ }
+ } while (!(ecc_correction_info & ERR_CORRECTION_INFO__LAST_ERR_INFO));
+
+ return event;
+}
+
+static u16 process_ecc_int(u16 c,
+ u16 *fiqs, u16 *i)
+{
+ u16 d, j, event;
+ u16 ints;
+ u16 cdma_int_en_mask;
+
+ event = EVENT_PASS;
+ d = dcount[c];
+
+ for (j = 0; j < d; j++) {
+ if ((cdma_desc[c][j].Status & CMD_DMA_DESC_COMP) !=
+ CMD_DMA_DESC_COMP)
+ break;
+ }
+
+ *i = j; /* Pass the descripter number found here */
+
+ if (j == d)
+ return EVENT_UNCORRECTABLE_DATA_ERROR;
+
+ event = do_ecc_for_desc(c, PendingCMD[cdma_desc[c][j].Tag].DataAddr,
+ PendingCMD[cdma_desc[c][j].Tag].Page);
+
+ if (EVENT_UNCORRECTABLE_DATA_ERROR == event) {
+ if (cdma_desc[c][j].Tag != 0xFF)
+ PendingCMD[cdma_desc[c][j].Tag].Status = CMD_FAIL;
+ CDMA_UpdateEventStatus();
+
+ iowrite32(0, FlashReg + DMA_ENABLE);
+ while ((ioread32(FlashReg + DMA_ENABLE) & DMA_ENABLE__FLAG))
+ ;
+
+ iowrite32(fiqs[0], FlashReg + INTR_STATUS0);
+ iowrite32(fiqs[1], FlashReg + INTR_STATUS1);
+ iowrite32(fiqs[2], FlashReg + INTR_STATUS2);
+ iowrite32(fiqs[3], FlashReg + INTR_STATUS3);
+
+ cdma_int_en_mask = (DMA_INTR__DESC_COMP_CHANNEL0 |
+ DMA_INTR__DESC_COMP_CHANNEL1 |
+ DMA_INTR__DESC_COMP_CHANNEL2 |
+ DMA_INTR__DESC_COMP_CHANNEL3 |
+ DMA_INTR__MEMCOPY_DESC_COMP);
+
+ ints = (ioread32(FlashReg + DMA_INTR) & cdma_int_en_mask);
+ iowrite32(ints, FlashReg + DMA_INTR);
+
+ return event;
+ }
+
+ if (0 == c)
+ iowrite32(INTR_STATUS0__ECC_ERR, FlashReg + INTR_STATUS0);
+ else if (1 == c)
+ iowrite32(INTR_STATUS1__ECC_ERR, FlashReg + INTR_STATUS1);
+ else if (2 == c)
+ iowrite32(INTR_STATUS2__ECC_ERR, FlashReg + INTR_STATUS2);
+ else if (3 == c)
+ iowrite32(INTR_STATUS3__ECC_ERR, FlashReg + INTR_STATUS3);
+
+ return event;
+}
+
+static void process_prog_fail_int(u16 c,
+ u16 *fiqs, u16 *i)
+{
+ u16 ints;
+ u16 cdma_int_en_mask;
+
+ if (cdma_desc[c][*i].Tag != 0xFF)
+ PendingCMD[cdma_desc[c][*i].Tag].Status = CMD_FAIL;
+
+ CDMA_UpdateEventStatus();
+
+ iowrite32(0, FlashReg + DMA_ENABLE);
+ while ((ioread32(FlashReg + DMA_ENABLE) & DMA_ENABLE__FLAG))
+ ;
+
+ iowrite32(fiqs[0], FlashReg + INTR_STATUS0);
+ iowrite32(fiqs[1], FlashReg + INTR_STATUS1);
+ iowrite32(fiqs[2], FlashReg + INTR_STATUS2);
+ iowrite32(fiqs[3], FlashReg + INTR_STATUS3);
+
+ cdma_int_en_mask = (DMA_INTR__DESC_COMP_CHANNEL0 |
+ DMA_INTR__DESC_COMP_CHANNEL1 |
+ DMA_INTR__DESC_COMP_CHANNEL2 |
+ DMA_INTR__DESC_COMP_CHANNEL3 |
+ DMA_INTR__MEMCOPY_DESC_COMP);
+
+ ints = (ioread32(FlashReg + DMA_INTR) & cdma_int_en_mask);
+ iowrite32(ints, FlashReg + DMA_INTR);
+}
+
+static void process_erase_fail_int(u16 c,
+ u16 *fiqs, u16 *i)
+{
+ u16 ints;
+ u16 cdma_int_en_mask;
+
+ if (cdma_desc[c][*i].Tag != 0xFF)
+ PendingCMD[cdma_desc[c][*i].Tag].Status = CMD_FAIL;
+
+ CDMA_UpdateEventStatus();
+
+ iowrite32(0, FlashReg + DMA_ENABLE);
+ while ((ioread32(FlashReg + DMA_ENABLE) & DMA_ENABLE__FLAG))
+ ;
+
+ iowrite32(fiqs[0], FlashReg + INTR_STATUS0);
+ iowrite32(fiqs[1], FlashReg + INTR_STATUS1);
+ iowrite32(fiqs[2], FlashReg + INTR_STATUS2);
+ iowrite32(fiqs[3], FlashReg + INTR_STATUS3);
+
+ cdma_int_en_mask = (DMA_INTR__DESC_COMP_CHANNEL0 |
+ DMA_INTR__DESC_COMP_CHANNEL1 |
+ DMA_INTR__DESC_COMP_CHANNEL2 |
+ DMA_INTR__DESC_COMP_CHANNEL3 |
+ DMA_INTR__MEMCOPY_DESC_COMP);
+
+ ints = (ioread32(FlashReg + DMA_INTR) & cdma_int_en_mask);
+ iowrite32(ints, FlashReg + DMA_INTR);
+}
+
+/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+* Function: CDMA_Event_Status (for use with CMD_DMA)
+* Inputs: none
+* Outputs: Event_Status code
+* Description: This function is called after an interrupt has happened
+* It reads the HW status register and ...tbd
+* It returns the appropriate event status
+*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
+u16 CDMA_Event_Status(void)
+{
+ u16 FIQstatus[MAX_CHANS];
+ u16 int_status, event;
+ u16 c, i = 0;
+ u16 int_en_mask;
+ u16 cdma_int_en_mask;
+
+ event = EVENT_PASS;
+
+ /* Set the global Enable masks for only those interrupts
+ * that are supported */
+ cdma_int_en_mask = (DMA_INTR__DESC_COMP_CHANNEL0 |
+ DMA_INTR__DESC_COMP_CHANNEL1 |
+ DMA_INTR__DESC_COMP_CHANNEL2 |
+ DMA_INTR__DESC_COMP_CHANNEL3 |
+ DMA_INTR__MEMCOPY_DESC_COMP);
+
+ int_en_mask = (INTR_STATUS0__ECC_ERR |
+ INTR_STATUS0__PROGRAM_FAIL |
+ INTR_STATUS0__ERASE_FAIL);
+
+ FIQstatus[0] = (ioread32(FlashReg + INTR_STATUS0) & int_en_mask);
+ FIQstatus[1] = (ioread32(FlashReg + INTR_STATUS1) & int_en_mask);
+ FIQstatus[2] = (ioread32(FlashReg + INTR_STATUS2) & int_en_mask);
+ FIQstatus[3] = (ioread32(FlashReg + INTR_STATUS3) & int_en_mask);
+
+ int_status = ioread32(FlashReg + DMA_INTR) & cdma_int_en_mask;
+
+ if (int_status) {
+ if ((int_status & DMA_INTR__DESC_COMP_CHANNEL0) ||
+ (int_status & DMA_INTR__DESC_COMP_CHANNEL1) ||
+ (int_status & DMA_INTR__DESC_COMP_CHANNEL2) ||
+ (int_status & DMA_INTR__DESC_COMP_CHANNEL3)) {
+
+ event = EVENT_PASS;
+ update_event_status();
+ } else {
+ /* TODO -- What kind of status can be
+ * reported back to FTL in PendindCMD? */
+ event = EVENT_DMA_CMD_FAIL;
+ }
+
+ iowrite32(0, FlashReg + DMA_ENABLE);
+ while ((ioread32(FlashReg + DMA_ENABLE) & DMA_ENABLE__FLAG))
+ ;
+
+ iowrite32(int_status, FlashReg + DMA_INTR);
+ }
+
+ for (c = 0; c < MAX_CHANS; c++) {
+ if (FIQstatus[c]) {
+ if ((FIQstatus[c] & INTR_STATUS0__ECC_ERR) &&
+ ioread32(FlashReg + ECC_ENABLE)) {
+ event = process_ecc_int(c, FIQstatus, &i);
+ if (EVENT_UNCORRECTABLE_DATA_ERROR == event)
+ return event;
+ }
+
+ if (FIQstatus[c] & INTR_STATUS0__PROGRAM_FAIL) {
+ process_prog_fail_int(c, FIQstatus, &i);
+ return EVENT_PROGRAM_FAILURE;
+ }
+
+ if (FIQstatus[c] & INTR_STATUS0__ERASE_FAIL) {
+ process_erase_fail_int(c, FIQstatus, &i);
+ return EVENT_ERASE_FAILURE;
+ } else {
+ if (0 == c)
+ iowrite32(FIQstatus[0],
+ FlashReg + INTR_STATUS0);
+ else if (1 == c)
+ iowrite32(FIQstatus[1],
+ FlashReg + INTR_STATUS1);
+ else if (2 == c)
+ iowrite32(FIQstatus[2],
+ FlashReg + INTR_STATUS2);
+ else if (3 == c)
+ iowrite32(FIQstatus[3],
+ FlashReg + INTR_STATUS3);
+ }
+ }
+ }
+
+ return event;
+}
+#endif
+
+#endif
+
+/****** Sync related functions ********/
+#define MAX_SYNC 14
+#define FORCED_ORDERED_SYNC 15
+#define SNUS_CHAN_OFFSET 24
+#define SNUS_LASTID_MASK 0xFFFFFF
+
+#if DEBUG_SYNC
+u32 debug_sync_cnt = 1;
+#endif
+
+static u32 isFlashReadCMD(u8 CMD)
+{
+ switch (CMD) {
+ case READ_MAIN_CMD:
+ case READ_SPARE_CMD:
+ case READ_MAIN_SPARE_CMD:
+ return 1;
+ default:
+ return 0;
+ }
+}
+
+static u32 isFlashWriteCMD(u8 CMD)
+{
+ switch (CMD) {
+ case WRITE_MAIN_CMD:
+ case WRITE_SPARE_CMD:
+ case WRITE_MAIN_SPARE_CMD:
+ return 1;
+ default:
+ return 0;
+ }
+}
+
+/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+* Function: generateSyncNum
+* Inputs: sync_usage array, a new sync number in case no reusable one
+* was found. The bit vector of channels taking place in current
+* sync operation, and the earliest cmd id for the new sync op.
+* Outputs: The sync number to be used for the current syncing
+* Description:
+* Assumption : A sync point is always used between 2 and only 2 channels.
+*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
+static u32 generateSyncNum(u32 *sync_usage, u32 *newSyncNum,
+ u32 syncedChans, u32 lastid)
+{
+ u32 synci, toUseSyncNum = 0;
+
+ /* We try to reuse syncs as much as possible with this algorithm */
+ for (synci = 1; synci < *newSyncNum; synci++) {
+ if (((sync_usage[synci] >> SNUS_CHAN_OFFSET) == syncedChans)
+ && ((sync_usage[synci] & SNUS_LASTID_MASK)
+ < lastid)) {
+ toUseSyncNum = synci;
+ break;
+ }
+ }
+
+ if (!toUseSyncNum && (*newSyncNum <= MAX_SYNC))
+ toUseSyncNum = (*newSyncNum)++;
+
+/*
+ The rest is to find another sync point which has at least
+ one channel in common, and then add a sync point to
+ the extra channel, and then use it.
+
+ -- This will not result in the sync number being used
+ by 3 channels, since the new use will have just the
+ syncedChans values. So our assumption still holds valid.
+
+ -- However, adding the new channel is not easy.
+ We need to find the id, which is after the last sync number
+ that existed between the common channel, and our new
+ channel, and before the next sync that will exist
+ between the new and common channel!
+*/
+
+ return toUseSyncNum;
+}
+
+
+#define getChannelPendingCMD(idx) (PendingCMD[idx].Block /\
+ (DeviceInfo.wTotalBlocks / totalUsedBanks))
+
+#define isOrderedPendingCMD(idx) ((PendingCMD[idx].Flags &\
+ LLD_CMD_FLAG_ORDER_BEFORE_REST) != 0)
+
+#define getSyncFromChannel(c) ((c & CHANNEL_SYNC_MASK) >>\
+ CHANNEL_SYNC_OFFSET)
+#define getIdFromChannel(c) ((c & CHANNEL_ID_MASK) >>\
+ CHANNEL_ID_OFFSET)
+#define getContFromChannel(c) ((c & CHANNEL_CONT_MASK) >>\
+ CHANNEL_CONT_OFFSET)
+#define getIntrFromChannel(c) ((c & CHANNEL_INTR_MASK) >>\
+ CHANNEL_INTR_OFFSET)
+#define getChanFromChannel(c) ((c & CHANNEL_DMA_MASK) >>\
+ CHANNEL_DMA_OFFSET)
+
+#define putSyncInChannel(c, v) (c |= ((v << CHANNEL_SYNC_OFFSET) &\
+ CHANNEL_SYNC_MASK))
+#define putIdInChannel(c, v) (c |= ((v << CHANNEL_ID_OFFSET) &\
+ CHANNEL_ID_MASK))
+#define putContInChannel(c, v) (c |= ((v << CHANNEL_CONT_OFFSET) &\
+ CHANNEL_CONT_MASK))
+#define putIntrInChannel(c, v) (c |= ((v << CHANNEL_INTR_OFFSET) &\
+ CHANNEL_INTR_MASK))
+#define putChanInChannel(c, v) (c |= ((v << CHANNEL_DMA_OFFSET) &\
+ CHANNEL_DMA_MASK))
+
+#define addChanToChannel(c, v) (c |= ((1 << CHANNEL_DMA_OFFSET) << v))
+
+#define isWithinRange(toChk, Addr, Bytes) ((toChk >= Addr) &&\
+ (toChk < (Addr + Bytes)))
+
+struct add_sync_points_struct {
+ u8 *fromAddr, *toAddr;
+ u8 CMD;
+ u32 idx;
+ u32 numSync, numSyncOther;
+ u32 chnl, chnlOther;
+ u32 newSyncNum, writeOpSyncPlaced;
+ u32 indx_last_cmd[MAX_CHANS];
+ u32 namb[MAX_CHANS][MAX_CHANS];
+ u32 sync_usage[MAX_SYNC + 1];
+};
+
+static void process_memcpy(struct add_sync_points_struct *ptr)
+{
+ int i, stopLoop, within1, within2, condition;
+ u8 *data_addr;
+ unsigned long offset;
+
+ ptr->fromAddr = PendingCMD[ptr->idx].DataSrcAddr;
+ ptr->toAddr = PendingCMD[ptr->idx].DataDestAddr;
+ stopLoop = 0;
+
+ for (i = ptr->idx - 1; (i >= MAX_CHANS) && !stopLoop; i--) {
+ data_addr = PendingCMD[i].DataAddr;
+ offset = PendingCMD[i].PageCount * DeviceInfo.wPageDataSize;
+ within1 = isWithinRange(ptr->toAddr, data_addr, offset);
+ within2 = isWithinRange(ptr->fromAddr, data_addr, offset);
+ condition = (PendingCMD[i].CMD != MEMCOPY_CMD) &&
+ (PendingCMD[i].CMD != ERASE_CMD) &&
+ (within1 || within2);
+ if (condition) {
+ stopLoop = 1;
+ PendingCMD[ptr->idx].Block = PendingCMD[i].Block;
+ ptr->chnl = getChannelPendingCMD(ptr->idx);
+ debug_boundary_error(ptr->chnl, totalUsedBanks,
+ ptr->idx);
+ if (isFlashWriteCMD(PendingCMD[i].CMD) && within1) {
+ ptr->CMD = READ_MAIN_CMD;
+ PendingCMD[ptr->idx].DataAddr = ptr->toAddr;
+ }
+ }
+ }
+}
+
+static void check_synced_helper(struct add_sync_points_struct *ptr,
+ int j, int k)
+{
+ int l;
+ unsigned long m, n;
+
+ m = ptr->chnl;
+ n = ptr->chnlOther;
+
+ for (l = 0; l < totalUsedBanks; l++) {
+ if ((l != m) && (l != n)) {
+ if (ptr->namb[l][n] <= j) {
+ if (ptr->namb[m][l] < ptr->namb[n][l])
+ ptr->namb[m][l] = ptr->namb[n][l];
+ } else {
+ if (ptr->namb[l][m] < ptr->namb[n][m])
+ ptr->namb[l][m] = ptr->namb[n][m];
+ }
+
+ if (ptr->namb[l][m] <= k) {
+ if (ptr->namb[n][l] < ptr->namb[m][l])
+ ptr->namb[n][l] = ptr->namb[m][l];
+ } else {
+ if (ptr->namb[l][n] < ptr->namb[m][n])
+ ptr->namb[l][n] = ptr->namb[m][n];
+ }
+ }
+ }
+}
+
+#if DEBUG_SYNC
+static void check_synced_debug_sync(struct add_sync_points_struct *ptr,
+ unsigned long toUseSyncNum, unsigned long syncedChans, int j, int k)
+{
+ int m, n;
+
+ if (!(debug_sync_cnt % DBG_SNC_PRINTEVERY)) {
+ nand_dbg_print(NAND_DBG_DEBUG,
+ "ADDSYNC: Placed Sync point 0x%x "
+ "with chanvectors 0x%x "
+ "betn tags %d & prev(%d)=%d\n",
+ (unsigned)toUseSyncNum,
+ (unsigned)syncedChans,
+ j - MAX_CHANS,
+ ptr->idx - MAX_CHANS,
+ k - MAX_CHANS);
+ for (m = 0; m < totalUsedBanks; m++) {
+ nand_dbg_print(NAND_DBG_DEBUG,
+ "ADDSYNC: ch:%d ->", m);
+ for (n = 0; n < totalUsedBanks; n++)
+ if (255 == PendingCMD[ptr->namb[m][n]].Tag)
+ nand_dbg_print(NAND_DBG_DEBUG,
+ " (ch:%d tag: -1)", n);
+ else
+ nand_dbg_print(NAND_DBG_DEBUG,
+ " (ch:%d tag:%3d)", n,
+ PendingCMD[ptr->namb[m][n]].Tag);
+ nand_dbg_print(NAND_DBG_DEBUG, "\n");
+ }
+ }
+}
+#endif
+
+static void check_synced(struct add_sync_points_struct *ptr, int j, int k)
+{
+ unsigned long syncedChans, toUseSyncNum;
+
+ for (ptr->numSync = 0;
+ (ptr->numSync <= MAX_CHANS) &&
+ (PendingCMD[k].ChanSync[ptr->numSync] & CHANNEL_DMA_MASK);
+ ptr->numSync++)
+ ;
+
+ for (ptr->numSyncOther = 0;
+ (ptr->numSyncOther <= MAX_CHANS) &&
+ (PendingCMD[j].ChanSync[ptr->numSyncOther] & CHANNEL_DMA_MASK);
+ ptr->numSyncOther++)
+ ;
+
+ if ((ptr->numSync > MAX_CHANS) ||
+ (ptr->numSyncOther > MAX_CHANS)) {
+ nand_dbg_print(NAND_DBG_DEBUG,
+ "LLD_CDMA: Sync Algorithm failed to place a Sync "
+ "between command tags %d and %d\n",
+ ptr->idx - MAX_CHANS,
+ j - MAX_CHANS);
+ } else {
+ ptr->writeOpSyncPlaced |= (1 << ptr->chnlOther);
+ syncedChans = ((1 << ptr->chnl) | (1 << ptr->chnlOther));
+ toUseSyncNum = generateSyncNum(&ptr->sync_usage[0],
+ &ptr->newSyncNum, syncedChans, (j < k ? j : k));
+ if (!toUseSyncNum) {
+ nand_dbg_print(NAND_DBG_DEBUG,
+ "LLD_CDMA: Sync Algorithm ran out of Syncs "
+ "during syncing command tags %d and %d\n",
+ ptr->idx - MAX_CHANS,
+ j - MAX_CHANS);
+ } else {
+ putSyncInChannel(
+ PendingCMD[k].ChanSync[ptr->numSync],
+ toUseSyncNum);
+ putContInChannel(
+ PendingCMD[k].ChanSync[ptr->numSync],
+ 1);
+ putIdInChannel(
+ PendingCMD[k].ChanSync[ptr->numSync],
+ ptr->chnl);
+ putSyncInChannel(
+ PendingCMD[j].ChanSync[ptr->numSyncOther],
+ toUseSyncNum);
+ putContInChannel(
+ PendingCMD[j].ChanSync[ptr->numSyncOther],
+ 1);
+ putIdInChannel(
+ PendingCMD[j].ChanSync[ptr->numSyncOther],
+ ptr->chnlOther);
+ putChanInChannel(
+ PendingCMD[j].ChanSync[ptr->numSyncOther],
+ syncedChans);
+ putChanInChannel(
+ PendingCMD[k].ChanSync[ptr->numSync],
+ syncedChans);
+
+ ptr->sync_usage[toUseSyncNum] =
+ (syncedChans << SNUS_CHAN_OFFSET) |
+ ((j > k ? j : k) & SNUS_LASTID_MASK);
+
+ ptr->namb[ptr->chnl][ptr->chnlOther] = j;
+
+ if (ptr->namb[ptr->chnlOther][ptr->chnl] > k)
+ nand_dbg_print(NAND_DBG_DEBUG,
+ "LLD_CDMA: Sync Algorithm detected "
+ "a possible deadlock in its assignments.\n");
+ else
+ ptr->namb[ptr->chnlOther][ptr->chnl] = k;
+
+ check_synced_helper(ptr, j, k);
+
+#if DEBUG_SYNC
+ check_synced_debug_sync(ptr, toUseSyncNum,
+ syncedChans, j, k);
+#endif
+ }
+ }
+}
+
+static void process_flash_rw(struct add_sync_points_struct *ptr)
+{
+ int j, k, stopLoop, within1, within2, condition;
+ unsigned long offset;
+
+ ptr->fromAddr = PendingCMD[ptr->idx].DataAddr;
+ k = ptr->indx_last_cmd[ptr->chnl];
+ offset = PendingCMD[ptr->idx].PageCount * DeviceInfo.wPageDataSize;
+ stopLoop = 0;
+
+ for (j = ptr->idx - 1; (j >= MAX_CHANS) && !stopLoop; j--) {
+ ptr->chnlOther = getChannelPendingCMD(j);
+ debug_boundary_error(ptr->chnlOther, totalUsedBanks, j);
+ within1 = isWithinRange(PendingCMD[j].DataDestAddr,
+ ptr->fromAddr, offset);
+ within2 = isWithinRange(PendingCMD[j].DataSrcAddr,
+ ptr->fromAddr, offset);
+ condition = (ptr->fromAddr == PendingCMD[j].DataAddr) ||
+ ((PendingCMD[j].CMD == MEMCOPY_CMD) &&
+ (within1 || within2));
+ if (condition) {
+ if (ptr->namb[ptr->chnl][ptr->chnlOther] >= j) {
+ stopLoop = 1;
+ } else if (ptr->chnlOther == ptr->chnl) {
+ condition = isFlashWriteCMD(ptr->CMD) ||
+ isFlashReadCMD(PendingCMD[j].CMD) ||
+ ((PendingCMD[j].CMD == MEMCOPY_CMD)
+ && within1);
+ if (condition)
+ stopLoop = 1;
+ } else {
+ condition = isFlashReadCMD(ptr->CMD) ||
+ isFlashReadCMD(PendingCMD[j].CMD) ||
+ ((PendingCMD[j].CMD == MEMCOPY_CMD)
+ && within1);
+ if (condition) {
+ if (isFlashReadCMD(PendingCMD[j].CMD)
+ || ((PendingCMD[j].CMD ==
+ MEMCOPY_CMD) && within1)) {
+ stopLoop = 1;
+ if (ptr->writeOpSyncPlaced)
+ break;
+ }
+ if (ptr->writeOpSyncPlaced &
+ (1 << ptr->chnlOther))
+ break;
+
+ check_synced(ptr, j, k);
+ }
+ }
+ }
+ }
+}
+
+static void process_force_ordering_helper(struct add_sync_points_struct *ptr,
+ unsigned long *syncNums, int k)
+{
+ unsigned long syncedChans;
+ int l;
+
+ if ((syncNums[ptr->chnlOther] > MAX_CHANS)) {
+ nand_dbg_print(NAND_DBG_DEBUG,
+ "LLD_CDMA: Sync Algorithm failed "
+ "find previously placed Forced Sync "
+ "at command tag %d, chnl %d\n",
+ (int)k - MAX_CHANS,
+ ptr->chnl);
+ } else {
+ syncedChans = getChanFromChannel(
+ PendingCMD[k].ChanSync[syncNums[ptr->chnlOther]]);
+
+ l = getIntrFromChannel(
+ PendingCMD[k].ChanSync[syncNums[ptr->chnlOther]]);
+
+ PendingCMD[k].ChanSync[syncNums[ptr->chnlOther]] = 0;
+
+ putIntrInChannel(
+ PendingCMD[k].ChanSync[syncNums[ptr->chnlOther]], l);
+
+ putSyncInChannel(
+ PendingCMD[ptr->idx].ChanSync[syncNums[ptr->chnl]],
+ FORCED_ORDERED_SYNC);
+
+ putContInChannel(
+ PendingCMD[ptr->idx].ChanSync[syncNums[ptr->chnl]],
+ 1);
+
+ putIdInChannel(
+ PendingCMD[ptr->idx].ChanSync[syncNums[ptr->chnl]],
+ ptr->chnl);
+
+ putChanInChannel(
+ PendingCMD[ptr->idx].ChanSync[syncNums[ptr->chnl]],
+ syncedChans);
+
+ for (l = 0; l < totalUsedBanks; l++) {
+ if (l != ptr->chnl)
+ ptr->namb[l][ptr->chnl] = ptr->idx;
+ }
+#if DEBUG_SYNC
+ if (!(debug_sync_cnt % DBG_SNC_PRINTEVERY))
+ nand_dbg_print(NAND_DBG_DEBUG,
+ "ADDSYNC: Moved Forced Sync point "
+ "in chnl %d from tag %d to %d\n",
+ ptr->chnl,
+ k - MAX_CHANS,
+ ptr->idx - MAX_CHANS);
+#endif
+ }
+}
+
+static void process_force_ordering(struct add_sync_points_struct *ptr)
+{
+ unsigned long syncNums[MAX_CHANS];
+ unsigned long syncedChans;
+ int j, k, l, stopLoop;
+#if DEBUG_SYNC
+ int m;
+#endif
+
+ stopLoop = 0;
+ for (k = ptr->idx - 1; (k >= MAX_CHANS); k--) {
+ if (ptr->chnl != getChannelPendingCMD(k))
+ k = MAX_CHANS - 1;
+ else if (isOrderedPendingCMD(k))
+ break;
+ }
+
+ if (k >= MAX_CHANS) {
+ for (syncNums[ptr->chnl] = 0;
+ (syncNums[ptr->chnl] <= MAX_CHANS)
+ && (PendingCMD[ptr->idx].ChanSync[syncNums[ptr->chnl]]
+ & CHANNEL_DMA_MASK); syncNums[ptr->chnl]++)
+ ;
+
+ if (syncNums[ptr->chnl] > MAX_CHANS) {
+ nand_dbg_print(NAND_DBG_DEBUG,
+ "LLD_CDMA: Sync Algorithm failed to place "
+ "a Forced Sync at command tag %d\n",
+ ptr->idx - MAX_CHANS);
+ } else {
+ ptr->chnlOther = (ptr->chnl+1) % totalUsedBanks;
+ for (syncNums[ptr->chnlOther] = 0;
+ (syncNums[ptr->chnlOther] <= MAX_CHANS)
+ && (getSyncFromChannel(
+ PendingCMD[k].ChanSync[syncNums[ptr->chnlOther]]) !=
+ FORCED_ORDERED_SYNC);
+ syncNums[ptr->chnlOther]++)
+ ;
+
+ process_force_ordering_helper(ptr, syncNums, k);
+ }
+ } else {
+ syncedChans = 0;
+ for (j = 0; j < totalUsedBanks; j++) {
+ k = ptr->indx_last_cmd[j];
+ for (syncNums[j] = 0;
+ (syncNums[j] <= MAX_CHANS) &&
+ (PendingCMD[k].ChanSync[syncNums[j]] &
+ CHANNEL_DMA_MASK); syncNums[j]++)
+ ;
+ if ((syncNums[j] > MAX_CHANS)) {
+ /* This should never happen! */
+ nand_dbg_print(NAND_DBG_DEBUG,
+ "LLD_CDMA: Sync Algorithm failed to place "
+ "a Forced Sync at command tag %d\n",
+ k - MAX_CHANS);
+ syncNums[0] = MAX_CHANS + 1;
+ }
+ syncedChans |= (1 << j);
+ }
+
+ if (syncNums[0] <= MAX_CHANS) {
+ for (j = 0; j < totalUsedBanks; j++) {
+ k = ptr->indx_last_cmd[j];
+ putSyncInChannel(
+ PendingCMD[k].ChanSync[syncNums[j]],
+ FORCED_ORDERED_SYNC);
+ putContInChannel(
+ PendingCMD[k].ChanSync[syncNums[j]],
+ 1);
+ putIdInChannel(
+ PendingCMD[k].ChanSync[syncNums[j]],
+ j);
+ putChanInChannel(
+ PendingCMD[k].ChanSync[syncNums[j]],
+ syncedChans);
+ for (l = 0; l < totalUsedBanks; l++) {
+ if (l != j)
+ ptr->namb[l][j] = k;
+ }
+ }
+#if DEBUG_SYNC
+ if (!(debug_sync_cnt % DBG_SNC_PRINTEVERY)) {
+ nand_dbg_print(NAND_DBG_DEBUG,
+ "ADDSYNC: Placed Forced Sync point "
+ "for tag %d in tags",
+ ptr->idx - MAX_CHANS);
+ for (m = 0; m < totalUsedBanks; m++) {
+ if (m != ptr->chnl)
+ nand_dbg_print(NAND_DBG_DEBUG,
+ " %d",
+ (int)ptr->indx_last_cmd[m] -
+ MAX_CHANS);
+ }
+ nand_dbg_print(NAND_DBG_DEBUG, "\n");
+ }
+#endif
+ }
+ }
+}
+
+/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+* Function: CDMA_AddSyncPoints
+* Inputs: tag_count:- Number of commands in PendingCMD list
+* Outputs: NONE
+* Description: This function takes the PendingCMD list, and adds sync
+* points between each entry on it, and any preceding entry
+* in other channels that have conflicts with the Cache Block
+* pointer.
+* The design also takes care of syncing between memcopy
+* and flash read/write operations. However, this function
+* does not sync between 2 memcopy operations that have a conflict
+* in a RAM pointer other than the cache block one. It is the
+* responsibility of the calling function, probablt the
+* application calling spectra, to take care of that.
+* Assumptions: + This function is before the CDMA_Descriptor list is created.
+* + This function takes care of the fact that memcopy accesses
+* might be just a few bytes within a cache block, and uses a
+* knowledge of the cache block to check for accesses anywhere
+* within it. However, it is assumed that we dont have ranges
+* that overlap one another. Either ranges overlap perfectly, or
+* the memcopy range is a subset of the flash address range.
+*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
+void CDMA_AddSyncPoints(u16 tag_count)
+{
+ struct add_sync_points_struct vars;
+ int i, j;
+
+ vars.newSyncNum = 1;
+ debug_boundary_error(totalUsedBanks - 1, MAX_CHANS, 0);
+ for (i = 0; i < totalUsedBanks; i++) {
+ vars.chnl = getChannelPendingCMD(i);
+ debug_boundary_error(vars.chnl, totalUsedBanks, i);
+ vars.indx_last_cmd[vars.chnl] = i;
+ for (j = 0; j < totalUsedBanks; j++)
+ vars.namb[i][j] = 0;
+ }
+
+ for (i = 0; i <= MAX_SYNC; i++)
+ vars.sync_usage[i] = 0;
+
+ for (vars.idx = MAX_CHANS;
+ vars.idx < (tag_count + MAX_CHANS);
+ vars.idx++) {
+
+ vars.writeOpSyncPlaced = 0;
+ vars.CMD = PendingCMD[vars.idx].CMD;
+ vars.chnl = getChannelPendingCMD(vars.idx);
+ debug_boundary_error(vars.chnl, totalUsedBanks, vars.idx);
+
+ if (vars.CMD == MEMCOPY_CMD)
+ process_memcpy(&vars);
+
+ if (isFlashReadCMD(vars.CMD) || isFlashWriteCMD(vars.CMD))
+ process_flash_rw(&vars);
+
+ vars.indx_last_cmd[vars.chnl] = vars.idx;
+
+ /* Simple one sync to rule them all approach */
+ if (isOrderedPendingCMD(vars.idx))
+ process_force_ordering(&vars);
+
+ }
+}
+
+#if DEBUG_SYNC
+/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+* Function: CDMA_SyncCheck
+* Inputs: tag_count:- Number of commands in PendingCMD list
+* Outputs: NONE
+* Description: This function takes a long time to run!
+* So use only during testing with lld_emu. The job of this fn
+* is to go through the post-synced PendingCMD array, and check
+* for a) buffers getting accessed out of order (which should
+* not happen), and b) deadlocks. i.e. 2 channels waiting on 2
+* different sync points both of which occur on the other channel
+*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
+
+#include "flash.h"
+
+#define EOLIST(i) (chis[i] >= chMaxIndexes[i])
+
+static void print_ops(struct pending_cmd (*p)[MAX_CHANS + MAX_DESCS],
+ u32 rwop, u32 i, u32 chisi)
+{
+ if (rwop & 2)
+ nand_dbg_print(NAND_DBG_DEBUG,
+ "one or more read operations(indx:%d, tag:%d)",
+ chisi >> 16, p[i][chisi >> 16].Tag);
+ if (rwop & 1)
+ nand_dbg_print(NAND_DBG_DEBUG,
+ " one or more write operations(indx:%d, tag:%d)",
+ chisi & 0xFFFF, p[i][chisi & 0xFFFF].Tag);
+}
+
+/* Get sync channel from pending command */
+static u8 get_sync_ch_pcmd(struct pending_cmd (*p)[MAX_CHANS + MAX_DESCS],
+ int i, int chisi, int *syncNum, int *i2)
+{
+ u32 syncVal;
+
+ syncVal = p[i][chisi].ChanSync[0];
+ if (syncVal) {
+ *syncNum = getSyncFromChannel(syncVal);
+ *i2 = getChanFromChannel(syncVal) & ~(1 << i);
+ if ((*i2 != 1) && (*i2 != 2) && (*i2 != 4) && (*i2 != 8) &&
+ (*syncNum != FORCED_ORDERED_SYNC))
+ nand_dbg_print(NAND_DBG_DEBUG,
+ "SYNCCHECK: ASSERT FAIL: "
+ "second channel of sync(%d) got from sync val of "
+ "(ch:%d, indx:%d, tag:%d) is not a valid one!\n",
+ *i2, i, chisi, p[i][chisi].Tag);
+ *i2 = (*i2 == 1) ? 0 : (*i2 == 2 ? 1 : (*i2 == 4 ? 2 :
+ (i != 3 ? 3 : 2)));
+ }
+
+ return (syncVal != 0);
+}
+
+static u32 check_ordering(struct pending_cmd (*p)[MAX_CHANS + MAX_DESCS],
+ u32 ch1, u32 ch1_fromi, u32 ch1_toi,
+ u32 ch2, u32 ch2_fromi, u32 ch2_toi)
+{
+ u32 sync2syncops[2], i, j;
+ u32 rwop1, rwop2, lastcmd[2][CACHE_BLOCK_NUMBER];
+ u32 chi, ch, chfromi, chtoi;
+ u32 allok = 1;
+
+ for (chi = 0; chi < 2; chi++) {
+ if (chi) {
+ ch = ch2;
+ chfromi = ch2_fromi;
+ chtoi = ch2_toi;
+ } else {
+ ch = ch1;
+ chfromi = ch1_fromi;
+ chtoi = ch1_toi;
+ }
+
+ sync2syncops[chi] = 0;
+
+ for (j = 0; j < CACHE_BLOCK_NUMBER; j++)
+ lastcmd[chi][j] = 0;
+
+ for (i = chfromi; i <= chtoi; i++) {
+ for (j = 0; j < CACHE_BLOCK_NUMBER; j++) {
+ if ((isFlashReadCMD(p[ch][i].CMD) &&
+ (p[ch][i].DataAddr ==
+ Cache.ItemArray[j].pContent)) ||
+ ((p[ch][i].CMD == MEMCOPY_CMD) &&
+ isWithinRange(p[ch][i].DataDestAddr,
+ Cache.ItemArray[j].pContent,
+ DeviceInfo.wBlockDataSize)
+ )) {
+ sync2syncops[chi] |= (1 << (j << 1));
+ lastcmd[chi][j] &= 0xFFFF0000;
+ lastcmd[chi][j] |= (i & 0xFFFF);
+ }
+ if ((isFlashWriteCMD(p[ch][i].CMD) &&
+ (p[ch][i].DataAddr ==
+ Cache.ItemArray[j].pContent)) ||
+ ((p[ch][i].CMD == MEMCOPY_CMD) &&
+ isWithinRange(p[ch][i].DataSrcAddr,
+ Cache.ItemArray[j].pContent,
+ DeviceInfo.wBlockDataSize))) {
+ sync2syncops[chi] |=
+ (1 << ((j << 1) + 1));
+ lastcmd[chi][j] &= 0xFFFF;
+ lastcmd[chi][j] |=
+ ((i & 0xFFFF) << 16);
+ }
+ }
+ }
+ }
+
+ for (j = 0; j < CACHE_BLOCK_NUMBER; j++) {
+ rwop1 = (sync2syncops[0] >> (j << 1)) & 3;
+ rwop2 = (sync2syncops[1] >> (j << 1)) & 3;
+ if (((rwop1 & 1) && rwop2) || ((rwop2 & 1) && rwop1)) {
+ nand_dbg_print(NAND_DBG_DEBUG,
+ "SYNCCHECK: ORDERING PROBLEM "
+ "in cache buffer %d: Between "
+ "(ch:%d, indx:%d, tag:%d) & "
+ "(ch:%d, indx:%d, tag:%d), "
+ "there has been\n",
+ j, ch1, ch1_fromi,
+ p[ch1][ch1_fromi].Tag,
+ ch1, ch1_toi,
+ p[ch1][ch1_toi].Tag);
+ print_ops(p, rwop1, ch1,
+ lastcmd[0][j]);
+ nand_dbg_print(NAND_DBG_DEBUG,
+ ".\nWhich are not ordered w.r.t to ");
+ print_ops(p, rwop2, ch2,
+ lastcmd[1][j]);
+ nand_dbg_print(NAND_DBG_DEBUG,
+ "\nbetween (ch:%d, indx:%d, tag:%d) & "
+ "(ch:%d, indx:%d, tag:%d).\n",
+ ch2, ch2_fromi,
+ p[ch2][ch2_fromi].Tag,
+ ch2, ch2_toi,
+ p[ch2][ch2_toi].Tag);
+ allok = 0;
+ }
+ }
+
+ return allok;
+}
+
+static int lookfor_deadlocks(struct pending_cmd (*p)[MAX_CHANS + MAX_DESCS],
+ int *chis, int *chMaxIndexes)
+{
+ int i, j, done, ch1, ch2, snum, snum2;
+
+ done = 0;
+ for (i = 0; (!done) && (i < totalUsedBanks); i++) {
+ if (!EOLIST(i) &&
+ get_sync_ch_pcmd(p, i, chis[i], &snum, &ch1)) {
+ j = 0;
+ ch2 = ch1;
+ ch1 = i;
+ snum2 = snum;
+ snum = 0xFF;
+ while ((snum != snum2) && (j <= totalUsedBanks) &&
+ !EOLIST(ch2) && (ch2 != i) &&
+ ((snum == 0xFF) ||
+ (snum2 != FORCED_ORDERED_SYNC))) {
+ ch1 = ch2;
+ snum = snum2;
+ get_sync_ch_pcmd(p, ch1, chis[ch1],
+ &snum2, &ch2);
+ j++;
+ }
+ if ((j <= totalUsedBanks) && (snum != snum2)) {
+ nand_dbg_print(NAND_DBG_DEBUG,
+ "SYNCCHECK: DEADLOCK:\n");
+ ch1 = i;
+ snum = 0xFF;
+ get_sync_ch_pcmd(p, ch1, chis[ch1],
+ &snum2, &ch2);
+ debug_boundary_error(ch2, totalUsedBanks, 0);
+ while (!EOLIST(ch2) && (ch2 != i) &&
+ ((snum == 0xFF) ||
+ (snum2 != FORCED_ORDERED_SYNC))) {
+ nand_dbg_print(NAND_DBG_DEBUG,
+ "Channel %d, cmdindx %d, "
+ "tag %d is waiting for "
+ "sync number %d "
+ "from channel %d\n",
+ ch1, chis[ch1],
+ p[ch1][chis[ch1]].Tag,
+ snum2, ch2);
+ ch1 = ch2;
+ snum = snum2;
+ get_sync_ch_pcmd(p, ch1, chis[ch1],
+ &snum2, &ch2);
+ debug_boundary_error(ch2,
+ totalUsedBanks, 0);
+ }
+ nand_dbg_print(NAND_DBG_DEBUG,
+ "Channel %d, cmdindx %d, tag %d "
+ "is waiting for sync number %d "
+ "from channel %d",
+ ch1, chis[ch1],
+ p[ch1][chis[ch1]].Tag,
+ snum2, ch2);
+ if (!EOLIST(ch2))
+ nand_dbg_print(NAND_DBG_DEBUG,
+ ", which is the initial channel!\n");
+ else if (snum2 != FORCED_ORDERED_SYNC)
+ nand_dbg_print(NAND_DBG_DEBUG,
+ " which does not have that "
+ "sync number!\n");
+ else
+ nand_dbg_print(NAND_DBG_DEBUG,
+ " which is th forced ordered "
+ "sync number that cannot proceed "
+ "until all channels reach it!\n");
+ nand_dbg_print(NAND_DBG_DEBUG,
+ "Sync checking is aborting.\n");
+ done = 1;
+ }
+ if (j > totalUsedBanks) {
+ nand_dbg_print(NAND_DBG_DEBUG,
+ "SYNCCHECK: DEADLOCK: "
+ "Unknown case. "
+ "Infinite loop in deadlock check. "
+ "Aborting.\n");
+ done = 1;
+ }
+ }
+ }
+
+ return done;
+}
+
+static void cfo_helper_1(struct pending_cmd (*p)[MAX_CHANS + MAX_DESCS],
+ int *chis, int *chMaxIndexes, int (*namb)[MAX_CHANS],
+ int i, int ch1, int syncNum)
+{
+ int k;
+
+ for (k = 0; k < totalUsedBanks; k++) {
+ if ((k != i) && (k != ch1)) {
+ if (namb[ch1][k] > namb[i][k]) {
+ if (!check_ordering(p, i, namb[k][i] + 1,
+ chis[i], k, namb[i][k] + 1,
+ namb[ch1][k]))
+ nand_dbg_print(NAND_DBG_DEBUG,
+ "Above problem occured when "
+ "analyzing sync %d between "
+ "(ch:%d, indx:%d, tag:%d) & "
+ "(ch:%d, indx:%d, tag:%d)\n",
+ syncNum, i, chis[i],
+ p[i][chis[i]].Tag,
+ ch1, chis[ch1],
+ p[ch1][chis[ch1]].Tag);
+ namb[i][k] = namb[ch1][k];
+ } else if (namb[ch1][k] < namb[i][k]) {
+ if (!check_ordering(p, ch1,
+ namb[k][ch1] + 1,
+ chis[ch1], k,
+ namb[ch1][k] + 1,
+ namb[i][k]))
+ nand_dbg_print(NAND_DBG_DEBUG,
+ "Above problem occured when "
+ "analyzing sync %d between "
+ "(ch:%d, indx:%d, tag:%d) & "
+ "(ch:%d, indx:%d, tag:%d)\n",
+ syncNum, i, chis[i],
+ p[i][chis[i]].Tag,
+ ch1, chis[ch1],
+ p[ch1][chis[ch1]].Tag);
+ namb[ch1][k] = namb[i][k];
+ }
+ }
+ }
+}
+
+static void cfo_helper_2(struct pending_cmd (*p)[MAX_CHANS + MAX_DESCS],
+ int *chis, int *chMaxIndexes, int (*namb)[MAX_CHANS],
+ int i, int ch1, u8 *pidxchgd)
+{
+ int k, m, n;
+ int sync_num, ch2;
+
+ for (k = 0; k < totalUsedBanks; k++) {
+ if ((k != i) && (k != ch1)) {
+ if (!EOLIST(k) && get_sync_ch_pcmd(p, k,
+ chis[k], &sync_num, &ch2)) {
+ if (sync_num != FORCED_ORDERED_SYNC)
+ k = totalUsedBanks + 2;
+ }
+ }
+ }
+
+ if (k == totalUsedBanks) {
+ for (m = 0; m < (totalUsedBanks - 1); m++) {
+ for (n = m + 1; n < totalUsedBanks; n++) {
+ if (!check_ordering(p, m, namb[n][m] + 1,
+ chis[m], n, namb[m][n] + 1, chis[n]))
+ nand_dbg_print(NAND_DBG_DEBUG,
+ "Above problem occured when "
+ "analyzing sync %d between "
+ "(ch:%d, indx:%d, tag:%d) & "
+ "(ch:%d, indx:%d, tag:%d)\n",
+ sync_num, m, chis[m],
+ p[m][chis[m]].Tag,
+ n, chis[n],
+ p[n][chis[n]].Tag);
+ namb[n][m] = chis[m];
+ namb[m][n] = chis[n];
+ }
+ chis[m]++;
+ }
+ chis[m]++;
+ *pidxchgd = 1;
+ }
+}
+
+static int check_for_ording(struct pending_cmd (*p)[MAX_CHANS + MAX_DESCS],
+ int *chis, int *chMaxIndexes, int (*namb)[MAX_CHANS])
+{
+ int i, done, ch1, ch2, syncNum, syncNum2;
+ u8 indexchgd;
+
+ indexchgd = 0;
+ for (i = 0; (i < totalUsedBanks) && !done && !indexchgd; i++) {
+ if (!EOLIST(i) &&
+ get_sync_ch_pcmd(p, i, chis[i], &syncNum, &ch1)) {
+ debug_boundary_error(ch1, totalUsedBanks, 0);
+ if (!EOLIST(ch1) && get_sync_ch_pcmd(p, ch1,
+ chis[ch1], &syncNum2, &ch2)) {
+ debug_boundary_error(ch2, totalUsedBanks, 0);
+ if ((syncNum == syncNum2) &&
+ (syncNum != FORCED_ORDERED_SYNC)) {
+ if (ch2 != i) {
+ nand_dbg_print(NAND_DBG_DEBUG,
+ "SYNCCHECK: ILLEGAL CASE: "
+ "Channel %d, cmdindx %d, "
+ "tag %d is waiting for "
+ "sync number %d "
+ "from channel %d, "
+ "which is waiting for "
+ "the same sync number "
+ "from channel %d. "
+ "Sync checking is aborting\n",
+ i, chis[i],
+ p[i][chis[i]].Tag,
+ syncNum, ch1, ch2);
+ done = 1;
+ } else {
+ if (!(debug_sync_cnt %
+ DBG_SNC_PRINTEVERY)) {
+ nand_dbg_print(
+ NAND_DBG_DEBUG,
+ "SYNCCHECK: "
+ "syncnum %d "
+ "betn Ch %d, "
+ "cmdindx %d, "
+ "tag %d & Ch %d, "
+ "cmdindx %d, tag %d. "
+ "chis="
+ "{%d, %d, %d, %d}\n",
+ syncNum, i,
+ chis[i],
+ p[i][chis[i]].Tag,
+ ch1, chis[ch1],
+ p[ch1][chis[ch1]].Tag,
+ chis[0], chis[1],
+ chis[2], chis[3]);
+ }
+ if (!check_ordering(p, i,
+ namb[ch1][i]+1,
+ chis[i], ch1,
+ namb[i][ch1]+1,
+ chis[ch1]))
+ nand_dbg_print(
+ NAND_DBG_DEBUG,
+ "Above problem "
+ "occured when "
+ "analyzing "
+ "sync %d "
+ "between "
+ "(ch:%d, indx:%d, "
+ "tag:%d) & "
+ "(ch:%d, indx:%d, "
+ "tag:%d)\n",
+ syncNum, i, chis[i],
+ p[i][chis[i]].Tag,
+ ch1, chis[ch1],
+ p[ch1][chis[ch1]].Tag);
+
+ namb[ch1][i] = chis[i];
+ namb[i][ch1] = chis[ch1];
+
+ cfo_helper_1(p, chis,
+ chMaxIndexes,
+ namb, i, ch1,
+ syncNum);
+
+ chis[i]++;
+ chis[ch1]++;
+ indexchgd = 1;
+ }
+ } else if ((syncNum == syncNum2) &&
+ (syncNum == FORCED_ORDERED_SYNC)) {
+ cfo_helper_2(p, chis, chMaxIndexes,
+ namb, i, ch1, &indexchgd);
+ }
+ }
+ }
+ }
+
+ return done;
+}
+
+void CDMA_CheckSyncPoints(u16 tag_count)
+{
+ struct pending_cmd p_cmd_ch[MAX_CHANS][MAX_CHANS + MAX_DESCS];
+ int namb[MAX_CHANS][MAX_CHANS];
+ int chMaxIndexes[MAX_CHANS];
+ int chis[MAX_CHANS];
+ u32 i, j, k, alldone;
+
+ /* Initial Checks */
+ if (CACHE_BLOCK_NUMBER > 16) {
+ nand_dbg_print(NAND_DBG_DEBUG,
+ "SYNCCHECK: INIT FAILED: SyncCheck can only "
+ "work with upto 16 cache blocks \n");
+ return;
+ }
+
+ /* Initializations */
+ for (i = 0; i < totalUsedBanks; i++) {
+ chis[i] = 0;
+ for (j = 0; j < totalUsedBanks; j++)
+ namb[i][j] = -1;
+ }
+
+ pcmd_per_ch(p_cmd_ch, tag_count, chMaxIndexes);
+
+ if (!(debug_sync_cnt % DBG_SNC_PRINTEVERY)) {
+ nand_dbg_print(NAND_DBG_DEBUG, "SYNCCHECK: Cache Ptrs:");
+ for (j = 0; j < CACHE_BLOCK_NUMBER; j++)
+ nand_dbg_print(NAND_DBG_DEBUG, " %p",
+ Cache.ItemArray[j].pContent);
+ nand_dbg_print(NAND_DBG_DEBUG, "\n");
+ }
+
+ alldone = 0;
+ while (!alldone) {
+ for (i = 0; i < totalUsedBanks; i++) {
+ while (!EOLIST(i)) {
+ if (!p_cmd_ch[i][chis[i]].ChanSync[0])
+ chis[i]++;
+ else
+ break;
+ }
+ }
+ alldone = lookfor_deadlocks(p_cmd_ch, chis, chMaxIndexes);
+ alldone = check_for_ording(p_cmd_ch, chis, chMaxIndexes,
+ namb);
+ if (!alldone) {
+ alldone = 1;
+ for (i = 0; alldone && (i < totalUsedBanks); i++) {
+ if (!EOLIST(i))
+ alldone = 0;
+ }
+ }
+ }
+
+ for (i = 0; i < totalUsedBanks; i++) {
+ for (k = i + 1; k < totalUsedBanks; k++) {
+ if (!check_ordering(p_cmd_ch, i, namb[k][i] + 1,
+ chMaxIndexes[i] - 1, k, namb[i][k] + 1,
+ chMaxIndexes[k] - 1))
+ nand_dbg_print(NAND_DBG_DEBUG,
+ "Above problem occured when doing "
+ "end of list checks on channels %d & %d\n",
+ i, k);
+ }
+ }
+}
+
+#endif
+#endif
+
diff --git a/drivers/staging/mrst_nand/lld_cdma.h b/drivers/staging/mrst_nand/lld_cdma.h
new file mode 100644
index 0000000..5d19791
--- /dev/null
+++ b/drivers/staging/mrst_nand/lld_cdma.h
@@ -0,0 +1,138 @@
+/*
+ * NAND Flash Controller Device Driver
+ * Copyright (c) 2009, Intel Corporation and its suppliers.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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.
+ *
+ * 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.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+/* header for LLD_CDMA.c module */
+
+#ifndef _LLD_CDMA_
+#define _LLD_CDMA_
+
+#include "flash.h"
+
+#define DEBUG_SYNC 1
+
+/*/////////// CDMA specific MACRO definition */
+#define MAX_DESCS (255)
+#define MAX_CHANS (4)
+#define MAX_SYNC_POINTS (16)
+
+#define CHANNEL_SYNC_MASK (0x000F)
+#define CHANNEL_DMA_MASK (0x00F0)
+#define CHANNEL_ID_MASK (0x0300)
+#define CHANNEL_CONT_MASK (0x4000)
+#define CHANNEL_INTR_MASK (0x8000)
+
+#define CHANNEL_SYNC_OFFSET (0)
+#define CHANNEL_DMA_OFFSET (4)
+#define CHANNEL_ID_OFFSET (8)
+#define CHANNEL_CONT_OFFSET (14)
+#define CHANNEL_INTR_OFFSET (15)
+
+#if CMD_DMA
+u16 CDMA_Data_CMD(u8 tag, u8 CMD, u8 *data, u32 block,
+ u16 page, u16 count, u16 flags);
+u16 CDMA_MemCopy_CMD(u8 tag, u8 *dest, u8 *src, u16 ByteCount,
+ u16 flags);
+u16 CDMA_Execute_CMDs(u16 tag_count);
+void CDMA_AddSyncPoints(u16 tag_count);
+void CDMA_CheckSyncPoints(u16 tag_count);
+void PrintPendingCMDs(u16 tag_count);
+void PrintPendingCMDsPerChannel(u16 tag_count);
+void PrintCDMA_Descriptors(void);
+u32 CDMA_Memory_Pool_Size(void);
+int CDMA_Mem_Config(u8 *pMem);
+
+extern u8 g_SBDCmdIndex;
+
+#endif
+
+#if FLASH_CDMA
+/*/////////// prototypes: APIs for LLD_CDMA */
+u16 CDMA_Flash_Init(void);
+int is_cdma_interrupt(void);
+u16 CDMA_Event_Status(void);
+#endif
+
+/* CMD-DMA Descriptor Struct. These are defined by the CMD_DMA HW */
+struct cdma_descriptor {
+ u32 NxtPointerHi;
+ u32 NxtPointerLo;
+ u32 FlashPointerHi;
+ u32 FlashPointerLo;
+ u32 CommandType;
+ u32 MemAddrHi;
+ u32 MemAddrLo;
+ u32 CommandFlags;
+ u32 Channel;
+ u32 Status;
+ u32 MemCopyPointerHi;
+ u32 MemCopyPointerLo;
+ u32 Reserved12;
+ u32 Reserved13;
+ u32 Reserved14;
+ u32 Tag;
+};
+
+/* This struct holds one MemCopy descriptor as defined by the HW */
+struct memcpy_descriptor {
+ u32 NxtPointerHi;
+ u32 NxtPointerLo;
+ u32 SrcAddrHi;
+ u32 SrcAddrLo;
+ u32 DestAddrHi;
+ u32 DestAddrLo;
+ u32 XferSize;
+ u32 MemCopyFlags;
+ u32 MemCopyStatus;
+ u32 reserved9;
+ u32 reserved10;
+ u32 reserved11;
+ u32 reserved12;
+ u32 reserved13;
+ u32 reserved14;
+ u32 reserved15;
+};
+
+/* Pending CMD table entries (includes MemCopy parameters */
+struct pending_cmd {
+ u8 Tag;
+ u8 CMD;
+ u8 *DataAddr;
+ u32 Block;
+ u16 Page;
+ u16 PageCount;
+ u8 *DataDestAddr;
+ u8 *DataSrcAddr;
+ u16 MemCopyByteCnt;
+ u16 Flags;
+ u16 ChanSync[MAX_CHANS + 1];
+ u16 Status;
+ u8 SBDCmdIndex;
+};
+
+extern struct pending_cmd PendingCMD[MAX_DESCS + MAX_CHANS];
+
+#if DEBUG_SYNC
+extern u32 debug_sync_cnt;
+#endif
+
+/* Definitions for CMD DMA descriptor chain fields */
+#define CMD_DMA_DESC_COMP 0x8000
+#define CMD_DMA_DESC_FAIL 0x4000
+
+#endif /*_LLD_CDMA_*/
diff --git a/drivers/staging/mrst_nand/lld_emu.c b/drivers/staging/mrst_nand/lld_emu.c
new file mode 100644
index 0000000..8b17970
--- /dev/null
+++ b/drivers/staging/mrst_nand/lld_emu.c
@@ -0,0 +1,788 @@
+/*
+ * NAND Flash Controller Device Driver
+ * Copyright (c) 2009, Intel Corporation and its suppliers.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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.
+ *
+ * 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.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+#include <linux/fs.h>
+#include <linux/slab.h>
+#include "flash.h"
+#include "ffsdefs.h"
+#include "lld_emu.h"
+#include "lld.h"
+#if CMD_DMA
+#include "lld_cdma.h"
+#endif
+
+#define GLOB_LLD_PAGES 64
+#define GLOB_LLD_PAGE_SIZE (512+16)
+#define GLOB_LLD_PAGE_DATA_SIZE 512
+#define GLOB_LLD_BLOCKS 2048
+
+#if (CMD_DMA && FLASH_EMU)
+#include "lld_cdma.h"
+u32 totalUsedBanks;
+u32 valid_banks[MAX_CHANS];
+#endif
+
+#if FLASH_EMU /* This is for entire module */
+
+static u8 *flash_memory[GLOB_LLD_BLOCKS * GLOB_LLD_PAGES];
+
+/* Read nand emu file and then fill it's content to flash_memory */
+int emu_load_file_to_mem(void)
+{
+ mm_segment_t fs;
+ struct file *nef_filp = NULL;
+ struct inode *inode = NULL;
+ loff_t nef_size = 0;
+ loff_t tmp_file_offset, file_offset;
+ ssize_t nread;
+ int i, rc = -EINVAL;
+
+ nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
+ __FILE__, __LINE__, __func__);
+
+ fs = get_fs();
+ set_fs(get_ds());
+
+ nef_filp = filp_open("/root/nand_emu_file", O_RDWR | O_LARGEFILE, 0);
+ if (IS_ERR(nef_filp)) {
+ printk(KERN_ERR "filp_open error: "
+ "Unable to open nand emu file!\n");
+ return PTR_ERR(nef_filp);
+ }
+
+ if (nef_filp->f_path.dentry) {
+ inode = nef_filp->f_path.dentry->d_inode;
+ } else {
+ printk(KERN_ERR "Can not get valid inode!\n");
+ goto out;
+ }
+
+ nef_size = i_size_read(inode->i_mapping->host);
+ if (nef_size <= 0) {
+ printk(KERN_ERR "Invalid nand emu file size: "
+ "0x%llx\n", nef_size);
+ goto out;
+ } else {
+ nand_dbg_print(NAND_DBG_DEBUG, "nand emu file size: %lld\n",
+ nef_size);
+ }
+
+ file_offset = 0;
+ for (i = 0; i < GLOB_LLD_BLOCKS * GLOB_LLD_PAGES; i++) {
+ tmp_file_offset = file_offset;
+ nread = vfs_read(nef_filp,
+ (char __user *)flash_memory[i],
+ GLOB_LLD_PAGE_SIZE, &tmp_file_offset);
+ if (nread < GLOB_LLD_PAGE_SIZE) {
+ printk(KERN_ERR "%s, Line %d - "
+ "nand emu file partial read: "
+ "%d bytes\n", __FILE__, __LINE__, (int)nread);
+ goto out;
+ }
+ file_offset += GLOB_LLD_PAGE_SIZE;
+ }
+ rc = 0;
+
+out:
+ filp_close(nef_filp, current->files);
+ set_fs(fs);
+ return rc;
+}
+
+/* Write contents of flash_memory to nand emu file */
+int emu_write_mem_to_file(void)
+{
+ mm_segment_t fs;
+ struct file *nef_filp = NULL;
+ struct inode *inode = NULL;
+ loff_t nef_size = 0;
+ loff_t tmp_file_offset, file_offset;
+ ssize_t nwritten;
+ int i, rc = -EINVAL;
+
+ nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
+ __FILE__, __LINE__, __func__);
+
+ fs = get_fs();
+ set_fs(get_ds());
+
+ nef_filp = filp_open("/root/nand_emu_file", O_RDWR | O_LARGEFILE, 0);
+ if (IS_ERR(nef_filp)) {
+ printk(KERN_ERR "filp_open error: "
+ "Unable to open nand emu file!\n");
+ return PTR_ERR(nef_filp);
+ }
+
+ if (nef_filp->f_path.dentry) {
+ inode = nef_filp->f_path.dentry->d_inode;
+ } else {
+ printk(KERN_ERR "Invalid " "nef_filp->f_path.dentry value!\n");
+ goto out;
+ }
+
+ nef_size = i_size_read(inode->i_mapping->host);
+ if (nef_size <= 0) {
+ printk(KERN_ERR "Invalid "
+ "nand emu file size: 0x%llx\n", nef_size);
+ goto out;
+ } else {
+ nand_dbg_print(NAND_DBG_DEBUG, "nand emu file size: "
+ "%lld\n", nef_size);
+ }
+
+ file_offset = 0;
+ for (i = 0; i < GLOB_LLD_BLOCKS * GLOB_LLD_PAGES; i++) {
+ tmp_file_offset = file_offset;
+ nwritten = vfs_write(nef_filp,
+ (char __user *)flash_memory[i],
+ GLOB_LLD_PAGE_SIZE, &tmp_file_offset);
+ if (nwritten < GLOB_LLD_PAGE_SIZE) {
+ printk(KERN_ERR "%s, Line %d - "
+ "nand emu file partial write: "
+ "%d bytes\n", __FILE__, __LINE__, (int)nwritten);
+ goto out;
+ }
+ file_offset += GLOB_LLD_PAGE_SIZE;
+ }
+ rc = 0;
+
+out:
+ filp_close(nef_filp, current->files);
+ set_fs(fs);
+ return rc;
+}
+
+/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+* Function: emu_Flash_Init
+* Inputs: none
+* Outputs: PASS=0 (notice 0=ok here)
+* Description: Creates & initializes the flash RAM array.
+*
+*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
+u16 emu_Flash_Init(void)
+{
+ int i;
+
+ nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
+ __FILE__, __LINE__, __func__);
+
+ flash_memory[0] = (u8 *)vmalloc(GLOB_LLD_PAGE_SIZE *
+ GLOB_LLD_BLOCKS *
+ GLOB_LLD_PAGES *
+ sizeof(u8));
+ if (!flash_memory[0]) {
+ printk(KERN_ERR "Fail to allocate memory "
+ "for nand emulator!\n");
+ return ERR;
+ }
+
+ memset((char *)(flash_memory[0]), 0xFF,
+ GLOB_LLD_PAGE_SIZE * GLOB_LLD_BLOCKS * GLOB_LLD_PAGES *
+ sizeof(u8));
+
+ for (i = 1; i < GLOB_LLD_BLOCKS * GLOB_LLD_PAGES; i++)
+ flash_memory[i] = flash_memory[i - 1] + GLOB_LLD_PAGE_SIZE;
+
+ emu_load_file_to_mem(); /* Load nand emu file to mem */
+
+ return PASS;
+}
+
+/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+* Function: emu_Flash_Release
+* Inputs: none
+* Outputs: PASS=0 (notice 0=ok here)
+* Description: Releases the flash.
+*
+*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
+u16 emu_Flash_Release()
+{
+ nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
+ __FILE__, __LINE__, __func__);
+
+ emu_write_mem_to_file(); /* Write back mem to nand emu file */
+
+ vfree(flash_memory[0]);
+ return PASS;
+}
+
+/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+* Function: emu_Read_Device_ID
+* Inputs: none
+* Outputs: PASS=1 FAIL=0
+* Description: Reads the info from the controller registers.
+* Sets up DeviceInfo structure with device parameters
+*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
+
+u16 emu_Read_Device_ID(void)
+{
+ nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
+ __FILE__, __LINE__, __func__);
+
+ DeviceInfo.wDeviceMaker = 0;
+ DeviceInfo.wDeviceType = 8;
+ DeviceInfo.wSpectraStartBlock = 36;
+ DeviceInfo.wSpectraEndBlock = GLOB_LLD_BLOCKS - 1;
+ DeviceInfo.wTotalBlocks = GLOB_LLD_BLOCKS;
+ DeviceInfo.wPagesPerBlock = GLOB_LLD_PAGES;
+ DeviceInfo.wPageSize = GLOB_LLD_PAGE_SIZE;
+ DeviceInfo.wPageDataSize = GLOB_LLD_PAGE_DATA_SIZE;
+ DeviceInfo.wPageSpareSize = GLOB_LLD_PAGE_SIZE -
+ GLOB_LLD_PAGE_DATA_SIZE;
+ DeviceInfo.wBlockSize = DeviceInfo.wPageSize * GLOB_LLD_PAGES;
+ DeviceInfo.wBlockDataSize = DeviceInfo.wPageDataSize * GLOB_LLD_PAGES;
+ DeviceInfo.wDataBlockNum = (u32) (DeviceInfo.wSpectraEndBlock -
+ DeviceInfo.wSpectraStartBlock
+ + 1);
+ DeviceInfo.MLCDevice = 1; /* Emulate MLC device */
+ DeviceInfo.nBitsInPageNumber =
+ (u8)GLOB_Calc_Used_Bits(DeviceInfo.wPagesPerBlock);
+ DeviceInfo.nBitsInPageDataSize =
+ (u8)GLOB_Calc_Used_Bits(DeviceInfo.wPageDataSize);
+ DeviceInfo.nBitsInBlockDataSize =
+ (u8)GLOB_Calc_Used_Bits(DeviceInfo.wBlockDataSize);
+
+#if CMD_DMA
+ totalUsedBanks = 4;
+ valid_banks[0] = 1;
+ valid_banks[1] = 1;
+ valid_banks[2] = 1;
+ valid_banks[3] = 1;
+#endif
+
+ return PASS;
+}
+
+/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+* Function: emu_Flash_Reset
+* Inputs: none
+* Outputs: PASS=0 (notice 0=ok here)
+* Description: Reset the flash
+*
+*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
+u16 emu_Flash_Reset(void)
+{
+ nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
+ __FILE__, __LINE__, __func__);
+
+ return PASS;
+}
+
+/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+* Function: emu_Erase_Block
+* Inputs: Address
+* Outputs: PASS=0 (notice 0=ok here)
+* Description: Erase a block
+*
+*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
+u16 emu_Erase_Block(u32 block_add)
+{
+ int i;
+
+ nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
+ __FILE__, __LINE__, __func__);
+
+ if (block_add >= DeviceInfo.wTotalBlocks) {
+ printk(KERN_ERR "emu_Erase_Block error! "
+ "Too big block address: %d\n", block_add);
+ return FAIL;
+ }
+
+ nand_dbg_print(NAND_DBG_DEBUG, "Erasing block %d\n",
+ (int)block_add);
+
+ for (i = block_add * GLOB_LLD_PAGES;
+ i < ((block_add + 1) * GLOB_LLD_PAGES); i++) {
+ if (flash_memory[i]) {
+ memset((u8 *)(flash_memory[i]), 0xFF,
+ DeviceInfo.wPageSize * sizeof(u8));
+ }
+ }
+
+ return PASS;
+}
+
+/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+* Function: emu_Write_Page_Main
+* Inputs: Write buffer address pointer
+* Block number
+* Page number
+* Number of pages to process
+* Outputs: PASS=0 (notice 0=ok here)
+* Description: Write the data in the buffer to main area of flash
+*
+*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
+u16 emu_Write_Page_Main(u8 *write_data, u32 Block,
+ u16 Page, u16 PageCount)
+{
+ int i;
+
+ nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
+ __FILE__, __LINE__, __func__);
+
+ if (Block >= DeviceInfo.wTotalBlocks)
+ return FAIL;
+
+ if (Page + PageCount > DeviceInfo.wPagesPerBlock)
+ return FAIL;
+
+ nand_dbg_print(NAND_DBG_DEBUG, "emu_Write_Page_Main: "
+ "lba %u Page %u PageCount %u\n",
+ (unsigned int)Block,
+ (unsigned int)Page, (unsigned int)PageCount);
+
+ for (i = 0; i < PageCount; i++) {
+ if (NULL == flash_memory[Block * GLOB_LLD_PAGES + Page]) {
+ printk(KERN_ERR "Run out of memory\n");
+ return FAIL;
+ }
+ memcpy((u8 *) (flash_memory[Block * GLOB_LLD_PAGES + Page]),
+ write_data, DeviceInfo.wPageDataSize);
+ write_data += DeviceInfo.wPageDataSize;
+ Page++;
+ }
+
+ return PASS;
+}
+
+/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+* Function: emu_Read_Page_Main
+* Inputs: Read buffer address pointer
+* Block number
+* Page number
+* Number of pages to process
+* Outputs: PASS=0 (notice 0=ok here)
+* Description: Read the data from the flash main area to the buffer
+*
+*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
+u16 emu_Read_Page_Main(u8 *read_data, u32 Block,
+ u16 Page, u16 PageCount)
+{
+ int i;
+
+ nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
+ __FILE__, __LINE__, __func__);
+
+ if (Block >= DeviceInfo.wTotalBlocks)
+ return FAIL;
+
+ if (Page + PageCount > DeviceInfo.wPagesPerBlock)
+ return FAIL;
+
+ nand_dbg_print(NAND_DBG_DEBUG, "emu_Read_Page_Main: "
+ "lba %u Page %u PageCount %u\n",
+ (unsigned int)Block,
+ (unsigned int)Page, (unsigned int)PageCount);
+
+ for (i = 0; i < PageCount; i++) {
+ if (NULL == flash_memory[Block * GLOB_LLD_PAGES + Page]) {
+ memset(read_data, 0xFF, DeviceInfo.wPageDataSize);
+ } else {
+ memcpy(read_data,
+ (u8 *) (flash_memory[Block * GLOB_LLD_PAGES
+ + Page]),
+ DeviceInfo.wPageDataSize);
+ }
+ read_data += DeviceInfo.wPageDataSize;
+ Page++;
+ }
+
+ return PASS;
+}
+
+#ifndef ELDORA
+/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+* Function: emu_Read_Page_Main_Spare
+* Inputs: Write Buffer
+* Address
+* Buffer size
+* Outputs: PASS=0 (notice 0=ok here)
+* Description: Read from flash main+spare area
+*
+*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
+u16 emu_Read_Page_Main_Spare(u8 *read_data, u32 Block,
+ u16 Page, u16 PageCount)
+{
+ int i;
+
+ nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
+ __FILE__, __LINE__, __func__);
+
+ if (Block >= DeviceInfo.wTotalBlocks) {
+ printk(KERN_ERR "Read Page Main+Spare "
+ "Error: Block Address too big\n");
+ return FAIL;
+ }
+
+ if (Page + PageCount > DeviceInfo.wPagesPerBlock) {
+ printk(KERN_ERR "Read Page Main+Spare "
+ "Error: Page number too big\n");
+ return FAIL;
+ }
+
+ nand_dbg_print(NAND_DBG_DEBUG, "Read Page Main + Spare - "
+ "No. of pages %u block %u start page %u\n",
+ (unsigned int)PageCount,
+ (unsigned int)Block, (unsigned int)Page);
+
+ for (i = 0; i < PageCount; i++) {
+ if (NULL == flash_memory[Block * GLOB_LLD_PAGES + Page]) {
+ memset(read_data, 0xFF, DeviceInfo.wPageSize);
+ } else {
+ memcpy(read_data, (u8 *) (flash_memory[Block *
+ GLOB_LLD_PAGES
+ + Page]),
+ DeviceInfo.wPageSize);
+ }
+
+ read_data += DeviceInfo.wPageSize;
+ Page++;
+ }
+
+ return PASS;
+}
+
+/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+* Function: emu_Write_Page_Main_Spare
+* Inputs: Write buffer
+* address
+* buffer length
+* Outputs: PASS=0 (notice 0=ok here)
+* Description: Write the buffer to main+spare area of flash
+*
+*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
+u16 emu_Write_Page_Main_Spare(u8 *write_data, u32 Block,
+ u16 Page, u16 page_count)
+{
+ u16 i;
+
+ nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
+ __FILE__, __LINE__, __func__);
+
+ if (Block >= DeviceInfo.wTotalBlocks) {
+ printk(KERN_ERR "Write Page Main + Spare "
+ "Error: Block Address too big\n");
+ return FAIL;
+ }
+
+ if (Page + page_count > DeviceInfo.wPagesPerBlock) {
+ printk(KERN_ERR "Write Page Main + Spare "
+ "Error: Page number too big\n");
+ return FAIL;
+ }
+
+ nand_dbg_print(NAND_DBG_DEBUG, "Write Page Main+Spare - "
+ "No. of pages %u block %u start page %u\n",
+ (unsigned int)page_count,
+ (unsigned int)Block, (unsigned int)Page);
+
+ for (i = 0; i < page_count; i++) {
+ if (NULL == flash_memory[Block * GLOB_LLD_PAGES + Page]) {
+ printk(KERN_ERR "Run out of memory!\n");
+ return FAIL;
+ }
+ memcpy((u8 *) (flash_memory[Block * GLOB_LLD_PAGES + Page]),
+ write_data, DeviceInfo.wPageSize);
+ write_data += DeviceInfo.wPageSize;
+ Page++;
+ }
+
+ return PASS;
+}
+
+/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+* Function: emu_Write_Page_Spare
+* Inputs: Write buffer
+* Address
+* buffer size
+* Outputs: PASS=0 (notice 0=ok here)
+* Description: Write the buffer in the spare area
+*
+*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
+u16 emu_Write_Page_Spare(u8 *write_data, u32 Block,
+ u16 Page, u16 PageCount)
+{
+ nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
+ __FILE__, __LINE__, __func__);
+
+ if (Block >= DeviceInfo.wTotalBlocks) {
+ printk(KERN_ERR "Read Page Spare Error: "
+ "Block Address too big\n");
+ return FAIL;
+ }
+
+ if (Page + PageCount > DeviceInfo.wPagesPerBlock) {
+ printk(KERN_ERR "Read Page Spare Error: "
+ "Page number too big\n");
+ return FAIL;
+ }
+
+ nand_dbg_print(NAND_DBG_DEBUG, "Write Page Spare- "
+ "block %u page %u\n",
+ (unsigned int)Block, (unsigned int)Page);
+
+ if (NULL == flash_memory[Block * GLOB_LLD_PAGES + Page]) {
+ printk(KERN_ERR "Run out of memory!\n");
+ return FAIL;
+ }
+
+ memcpy((u8 *) (flash_memory[Block * GLOB_LLD_PAGES + Page] +
+ DeviceInfo.wPageDataSize), write_data,
+ (DeviceInfo.wPageSize - DeviceInfo.wPageDataSize));
+
+ return PASS;
+}
+
+/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+* Function: emu_Read_Page_Spare
+* Inputs: Write Buffer
+* Address
+* Buffer size
+* Outputs: PASS=0 (notice 0=ok here)
+* Description: Read data from the spare area
+*
+*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
+u16 emu_Read_Page_Spare(u8 *write_data, u32 Block,
+ u16 Page, u16 PageCount)
+{
+ nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
+ __FILE__, __LINE__, __func__);
+
+ if (Block >= DeviceInfo.wTotalBlocks) {
+ printk(KERN_ERR "Read Page Spare "
+ "Error: Block Address too big\n");
+ return FAIL;
+ }
+
+ if (Page + PageCount > DeviceInfo.wPagesPerBlock) {
+ printk(KERN_ERR "Read Page Spare "
+ "Error: Page number too big\n");
+ return FAIL;
+ }
+
+ nand_dbg_print(NAND_DBG_DEBUG, "Read Page Spare- "
+ "block %u page %u\n",
+ (unsigned int)Block, (unsigned int)Page);
+
+ if (NULL == flash_memory[Block * GLOB_LLD_PAGES + Page]) {
+ memset(write_data, 0xFF,
+ (DeviceInfo.wPageSize - DeviceInfo.wPageDataSize));
+ } else {
+ memcpy(write_data,
+ (u8 *) (flash_memory[Block * GLOB_LLD_PAGES + Page]
+ + DeviceInfo.wPageDataSize),
+ (DeviceInfo.wPageSize - DeviceInfo.wPageDataSize));
+ }
+
+ return PASS;
+}
+
+/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+* Function: emu_Enable_Disable_Interrupts
+* Inputs: enable or disable
+* Outputs: none
+* Description: NOP
+*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
+void emu_Enable_Disable_Interrupts(u16 INT_ENABLE)
+{
+ nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
+ __FILE__, __LINE__, __func__);
+}
+
+u16 emu_Get_Bad_Block(u32 block)
+{
+ return 0;
+}
+
+#if CMD_DMA
+/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+* Support for CDMA functions
+************************************
+* emu_CDMA_Flash_Init
+* CDMA_process_data command (use LLD_CDMA)
+* CDMA_MemCopy_CMD (use LLD_CDMA)
+* emu_CDMA_execute all commands
+* emu_CDMA_Event_Status
+*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
+u16 emu_CDMA_Flash_Init(void)
+{
+ u16 i;
+
+ nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
+ __FILE__, __LINE__, __func__);
+
+ for (i = 0; i < MAX_DESCS + MAX_CHANS; i++) {
+ PendingCMD[i].CMD = 0;
+ PendingCMD[i].Tag = 0;
+ PendingCMD[i].DataAddr = 0;
+ PendingCMD[i].Block = 0;
+ PendingCMD[i].Page = 0;
+ PendingCMD[i].PageCount = 0;
+ PendingCMD[i].DataDestAddr = 0;
+ PendingCMD[i].DataSrcAddr = 0;
+ PendingCMD[i].MemCopyByteCnt = 0;
+ PendingCMD[i].ChanSync[0] = 0;
+ PendingCMD[i].ChanSync[1] = 0;
+ PendingCMD[i].ChanSync[2] = 0;
+ PendingCMD[i].ChanSync[3] = 0;
+ PendingCMD[i].ChanSync[4] = 0;
+ PendingCMD[i].Status = 3;
+ }
+
+ return PASS;
+}
+
+static void emu_isr(int irq, void *dev_id)
+{
+ /* TODO: ... */
+}
+
+/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+* Function: CDMA_Execute_CMDs
+* Inputs: tag_count: the number of pending cmds to do
+* Outputs: PASS/FAIL
+* Description: execute each command in the pending CMD array
+*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
+u16 emu_CDMA_Execute_CMDs(u16 tag_count)
+{
+ u16 i, j;
+ u8 CMD; /* cmd parameter */
+ u8 *data;
+ u32 block;
+ u16 page;
+ u16 count;
+ u16 status = PASS;
+
+ nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
+ __FILE__, __LINE__, __func__);
+
+ nand_dbg_print(NAND_DBG_TRACE, "At start of Execute CMDs: "
+ "Tag Count %u\n", tag_count);
+
+ for (i = 0; i < totalUsedBanks; i++) {
+ PendingCMD[i].CMD = DUMMY_CMD;
+ PendingCMD[i].Tag = 0xFF;
+ PendingCMD[i].Block =
+ (DeviceInfo.wTotalBlocks / totalUsedBanks) * i;
+
+ for (j = 0; j <= MAX_CHANS; j++)
+ PendingCMD[i].ChanSync[j] = 0;
+ }
+
+ CDMA_Execute_CMDs(tag_count);
+
+#if DEBUG_SYNC
+ if (!(debug_sync_cnt % DBG_SNC_PRINTEVERY)) {
+ nand_dbg_print(NAND_DBG_DEBUG, "_%lu_", debug_sync_cnt);
+#endif
+#ifdef VERBOSE
+ PrintPendingCMDs(tag_count);
+#endif
+#if DEBUG_SYNC
+#ifdef VERBOSE
+ PrintPendingCMDsPerChannel(tag_count);
+#endif
+ }
+ debug_sync_cnt++;
+#endif
+
+ for (i = MAX_CHANS;
+ i < tag_count + MAX_CHANS; i++) {
+ CMD = PendingCMD[i].CMD;
+ data = PendingCMD[i].DataAddr;
+ block = PendingCMD[i].Block;
+ page = PendingCMD[i].Page;
+ count = PendingCMD[i].PageCount;
+
+ switch (CMD) {
+ case ERASE_CMD:
+ emu_Erase_Block(block);
+ PendingCMD[i].Status = PASS;
+ break;
+ case WRITE_MAIN_CMD:
+ emu_Write_Page_Main(data, block, page, count);
+ PendingCMD[i].Status = PASS;
+ break;
+ case WRITE_MAIN_SPARE_CMD:
+ emu_Write_Page_Main_Spare(data, block, page, count);
+ PendingCMD[i].Status = PASS;
+ break;
+ case READ_MAIN_CMD:
+ emu_Read_Page_Main(data, block, page, count);
+ PendingCMD[i].Status = PASS;
+ break;
+ case MEMCOPY_CMD:
+ memcpy(PendingCMD[i].DataDestAddr,
+ PendingCMD[i].DataSrcAddr,
+ PendingCMD[i].MemCopyByteCnt);
+ case DUMMY_CMD:
+ PendingCMD[i].Status = PASS;
+ break;
+ default:
+ PendingCMD[i].Status = FAIL;
+ break;
+ }
+ }
+
+ /*
+ * Temperory adding code to reset PendingCMD array for basic testing.
+ * It should be done at the end of event status function.
+ */
+ for (i = tag_count + MAX_CHANS; i < MAX_DESCS; i++) {
+ PendingCMD[i].CMD = 0;
+ PendingCMD[i].Tag = 0;
+ PendingCMD[i].DataAddr = 0;
+ PendingCMD[i].Block = 0;
+ PendingCMD[i].Page = 0;
+ PendingCMD[i].PageCount = 0;
+ PendingCMD[i].DataDestAddr = 0;
+ PendingCMD[i].DataSrcAddr = 0;
+ PendingCMD[i].MemCopyByteCnt = 0;
+ PendingCMD[i].ChanSync[0] = 0;
+ PendingCMD[i].ChanSync[1] = 0;
+ PendingCMD[i].ChanSync[2] = 0;
+ PendingCMD[i].ChanSync[3] = 0;
+ PendingCMD[i].ChanSync[4] = 0;
+ PendingCMD[i].Status = CMD_NOT_DONE;
+ }
+
+ nand_dbg_print(NAND_DBG_TRACE, "At end of Execute CMDs.\n");
+
+ emu_isr(0, 0); /* This is a null isr now. Need fill it in future */
+
+ return status;
+}
+
+/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+* Function: emu_Event_Status
+* Inputs: none
+* Outputs: Event_Status code
+* Description: This function can also be used to force errors
+*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
+u16 emu_CDMA_Event_Status(void)
+{
+ nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
+ __FILE__, __LINE__, __func__);
+
+ return EVENT_PASS;
+}
+
+#endif /* CMD_DMA */
+#endif /* !ELDORA */
+#endif /* FLASH_EMU */
diff --git a/drivers/staging/mrst_nand/lld_emu.h b/drivers/staging/mrst_nand/lld_emu.h
new file mode 100644
index 0000000..a34a552
--- /dev/null
+++ b/drivers/staging/mrst_nand/lld_emu.h
@@ -0,0 +1,51 @@
+/*
+ * NAND Flash Controller Device Driver
+ * Copyright (c) 2009, Intel Corporation and its suppliers.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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.
+ *
+ * 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.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+#ifndef _LLD_EMU_
+#define _LLD_EMU_
+
+#include "ffsport.h"
+#include "ffsdefs.h"
+
+/* prototypes: emulator API functions */
+extern u16 emu_Flash_Reset(void);
+extern u16 emu_Flash_Init(void);
+extern u16 emu_Flash_Release(void);
+extern u16 emu_Read_Device_ID(void);
+extern u16 emu_Erase_Block(u32 block_addr);
+extern u16 emu_Write_Page_Main(u8 *write_data, u32 Block,
+ u16 Page, u16 PageCount);
+extern u16 emu_Read_Page_Main(u8 *read_data, u32 Block, u16 Page,
+ u16 PageCount);
+extern u16 emu_Event_Status(void);
+extern void emu_Enable_Disable_Interrupts(u16 INT_ENABLE);
+extern u16 emu_Write_Page_Main_Spare(u8 *write_data, u32 Block,
+ u16 Page, u16 PageCount);
+extern u16 emu_Write_Page_Spare(u8 *write_data, u32 Block,
+ u16 Page, u16 PageCount);
+extern u16 emu_Read_Page_Main_Spare(u8 *read_data, u32 Block,
+ u16 Page, u16 PageCount);
+extern u16 emu_Read_Page_Spare(u8 *read_data, u32 Block, u16 Page,
+ u16 PageCount);
+extern u16 emu_Get_Bad_Block(u32 block);
+
+u16 emu_CDMA_Flash_Init(void);
+u16 emu_CDMA_Execute_CMDs(u16 tag_count);
+u16 emu_CDMA_Event_Status(void);
+#endif /*_LLD_EMU_*/
diff --git a/drivers/staging/mrst_nand/lld_nand.c b/drivers/staging/mrst_nand/lld_nand.c
new file mode 100644
index 0000000..56ef843
--- /dev/null
+++ b/drivers/staging/mrst_nand/lld_nand.c
@@ -0,0 +1,3113 @@
+/*
+ * NAND Flash Controller Device Driver
+ * Copyright (c) 2009, Intel Corporation and its suppliers.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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.
+ *
+ * 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.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+#include "lld.h"
+#include "lld_nand.h"
+
+#include "spectraswconfig.h"
+#include "flash.h"
+#include "ffsdefs.h"
+
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <linux/wait.h>
+#include <linux/mutex.h>
+
+#if (FLASH_NAND || FLASH_CDMA)
+#include "NAND_Regs_4.h"
+
+#define SPECTRA_NAND_NAME "nd"
+
+#define CEIL_DIV(X, Y) (((X)%(Y)) ? ((X)/(Y)+1) : ((X)/(Y)))
+
+#define INT_IDLE_STATE 0
+#define INT_READ_PAGE_MAIN 0x01
+#define INT_WRITE_PAGE_MAIN 0x02
+#define INT_PIPELINE_READ_AHEAD 0x04
+#define INT_PIPELINE_WRITE_AHEAD 0x08
+#define INT_MULTI_PLANE_READ 0x10
+#define INT_MULTI_PLANE_WRITE 0x11
+
+struct mrst_nand_info {
+ struct pci_dev *dev;
+ u32 state;
+ u32 flash_bank;
+ u8 *read_data;
+ u8 *write_data;
+ u32 block;
+ u16 page;
+ u32 use_dma;
+ void __iomem *ioaddr; /* Mapped address */
+ int ret;
+ struct completion complete;
+};
+
+static struct mrst_nand_info info;
+
+int totalUsedBanks;
+u32 GLOB_valid_banks[LLD_MAX_FLASH_BANKS];
+
+/* Ugly hack to fix code that used an 8k bytes or 512bytes array
+ * in the < 4kB Linux kernel stack */
+/* static byte page_main_spare[MAX_PAGE_MAINSPARE_AREA]; */
+static u8 page_spare[MAX_PAGE_SPARE_AREA];
+static u8 pReadSpareBuf[MAX_PAGE_SPARE_AREA];
+
+void __iomem *FlashReg;
+void __iomem *FlashMem;
+
+u16 conf_parameters[] = {
+ 0x0000,
+ 0x0000,
+ 0x01F4,
+ 0x01F4,
+ 0x01F4,
+ 0x01F4,
+ 0x0000,
+ 0x0000,
+ 0x0001,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0040,
+ 0x0001,
+ 0x000A,
+ 0x000A,
+ 0x000A,
+ 0x0000,
+ 0x0000,
+ 0x0005,
+ 0x0012,
+ 0x000C
+};
+
+u16 NAND_Get_Bad_Block(u32 block)
+{
+ u32 status = PASS;
+ u32 flag_bytes = 0;
+ u32 skip_bytes = DeviceInfo.wSpareSkipBytes;
+ u32 page, i;
+
+ if (ioread32(FlashReg + ECC_ENABLE))
+ flag_bytes = DeviceInfo.wNumPageSpareFlag;
+
+ for (page = 0; page < 2; page++) {
+ status = NAND_Read_Page_Spare(pReadSpareBuf, block, page, 1);
+ if (status != PASS)
+ return READ_ERROR;
+ for (i = flag_bytes; i < (flag_bytes + skip_bytes); i++)
+ if (pReadSpareBuf[i] != 0xff)
+ return DEFECTIVE_BLOCK;
+ }
+
+ for (page = 1; page < 3; page++) {
+ status = NAND_Read_Page_Spare(pReadSpareBuf, block,
+ DeviceInfo.wPagesPerBlock - page , 1);
+ if (status != PASS)
+ return READ_ERROR;
+ for (i = flag_bytes; i < (flag_bytes + skip_bytes); i++)
+ if (pReadSpareBuf[i] != 0xff)
+ return DEFECTIVE_BLOCK;
+ }
+
+ return GOOD_BLOCK;
+}
+
+
+u16 NAND_Flash_Reset(void)
+{
+ u32 i;
+ u32 intr_status_rst_comp[4] = {INTR_STATUS0__RST_COMP,
+ INTR_STATUS1__RST_COMP,
+ INTR_STATUS2__RST_COMP,
+ INTR_STATUS3__RST_COMP};
+ u32 intr_status[4] = {INTR_STATUS0, INTR_STATUS1,
+ INTR_STATUS2, INTR_STATUS3};
+ u32 device_reset_banks[4] = {DEVICE_RESET__BANK0,
+ DEVICE_RESET__BANK1,
+ DEVICE_RESET__BANK2,
+ DEVICE_RESET__BANK3};
+
+ nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
+ __FILE__, __LINE__, __func__);
+
+ for (i = 0 ; i < LLD_MAX_FLASH_BANKS; i++)
+ iowrite32(intr_status_rst_comp[i], FlashReg + intr_status[i]);
+
+ for (i = 0 ; i < LLD_MAX_FLASH_BANKS; i++) {
+ if (!GLOB_valid_banks[i])
+ break;
+ iowrite32(device_reset_banks[i], FlashReg + DEVICE_RESET);
+ while (!(ioread32(FlashReg + intr_status[i]) &
+ intr_status_rst_comp[i]))
+ ;
+ }
+
+ for (i = 0; i < LLD_MAX_FLASH_BANKS; i++)
+ iowrite32(intr_status_rst_comp[i], FlashReg + intr_status[i]);
+
+ return PASS;
+}
+
+static void NAND_ONFi_Timing_Mode(u16 mode)
+{
+ u16 Trea[6] = {40, 30, 25, 20, 20, 16};
+ u16 Trp[6] = {50, 25, 17, 15, 12, 10};
+ u16 Treh[6] = {30, 15, 15, 10, 10, 7};
+ u16 Trc[6] = {100, 50, 35, 30, 25, 20};
+ u16 Trhoh[6] = {0, 15, 15, 15, 15, 15};
+ u16 Trloh[6] = {0, 0, 0, 0, 5, 5};
+ u16 Tcea[6] = {100, 45, 30, 25, 25, 25};
+ u16 Tadl[6] = {200, 100, 100, 100, 70, 70};
+ u16 Trhw[6] = {200, 100, 100, 100, 100, 100};
+ u16 Trhz[6] = {200, 100, 100, 100, 100, 100};
+ u16 Twhr[6] = {120, 80, 80, 60, 60, 60};
+ u16 Tcs[6] = {70, 35, 25, 25, 20, 15};
+
+ u16 TclsRising = 1;
+ u16 data_invalid_rhoh, data_invalid_rloh, data_invalid;
+ u16 dv_window = 0;
+ u16 en_lo, en_hi;
+ u16 acc_clks;
+ u16 addr_2_data, re_2_we, re_2_re, we_2_re, cs_cnt;
+
+ nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
+ __FILE__, __LINE__, __func__);
+
+ en_lo = CEIL_DIV(Trp[mode], CLK_X);
+ en_hi = CEIL_DIV(Treh[mode], CLK_X);
+
+#if ONFI_BLOOM_TIME
+ if ((en_hi * CLK_X) < (Treh[mode] + 2))
+ en_hi++;
+#endif
+
+ if ((en_lo + en_hi) * CLK_X < Trc[mode])
+ en_lo += CEIL_DIV((Trc[mode] - (en_lo + en_hi) * CLK_X), CLK_X);
+
+ if ((en_lo + en_hi) < CLK_MULTI)
+ en_lo += CLK_MULTI - en_lo - en_hi;
+
+ while (dv_window < 8) {
+ data_invalid_rhoh = en_lo * CLK_X + Trhoh[mode];
+
+ data_invalid_rloh = (en_lo + en_hi) * CLK_X + Trloh[mode];
+
+ data_invalid =
+ data_invalid_rhoh <
+ data_invalid_rloh ? data_invalid_rhoh : data_invalid_rloh;
+
+ dv_window = data_invalid - Trea[mode];
+
+ if (dv_window < 8)
+ en_lo++;
+ }
+
+ acc_clks = CEIL_DIV(Trea[mode], CLK_X);
+
+ while (((acc_clks * CLK_X) - Trea[mode]) < 3)
+ acc_clks++;
+
+ if ((data_invalid - acc_clks * CLK_X) < 2)
+ nand_dbg_print(NAND_DBG_WARN, "%s, Line %d: Warning!\n",
+ __FILE__, __LINE__);
+
+ addr_2_data = CEIL_DIV(Tadl[mode], CLK_X);
+ re_2_we = CEIL_DIV(Trhw[mode], CLK_X);
+ re_2_re = CEIL_DIV(Trhz[mode], CLK_X);
+ we_2_re = CEIL_DIV(Twhr[mode], CLK_X);
+ cs_cnt = CEIL_DIV((Tcs[mode] - Trp[mode]), CLK_X);
+ if (!TclsRising)
+ cs_cnt = CEIL_DIV(Tcs[mode], CLK_X);
+ if (cs_cnt == 0)
+ cs_cnt = 1;
+
+ if (Tcea[mode]) {
+ while (((cs_cnt * CLK_X) + Trea[mode]) < Tcea[mode])
+ cs_cnt++;
+ }
+
+ iowrite32(acc_clks, FlashReg + ACC_CLKS);
+ iowrite32(re_2_we, FlashReg + RE_2_WE);
+ iowrite32(re_2_re, FlashReg + RE_2_RE);
+ iowrite32(we_2_re, FlashReg + WE_2_RE);
+ iowrite32(addr_2_data, FlashReg + ADDR_2_DATA);
+ iowrite32(en_lo, FlashReg + RDWR_EN_LO_CNT);
+ iowrite32(en_hi, FlashReg + RDWR_EN_HI_CNT);
+ iowrite32(cs_cnt, FlashReg + CS_SETUP_CNT);
+}
+
+static void index_addr(u32 address, u32 data)
+{
+ iowrite32(address, FlashMem);
+ iowrite32(data, FlashMem + 0x10);
+}
+
+static void index_addr_read_data(u32 address, u32 *pdata)
+{
+ iowrite32(address, FlashMem);
+ *pdata = ioread32(FlashMem + 0x10);
+}
+
+static void set_ecc_config(void)
+{
+ if ((ioread32(FlashReg + ECC_CORRECTION) & ECC_CORRECTION__VALUE)
+ == 1) {
+ DeviceInfo.wECCBytesPerSector = 4;
+ DeviceInfo.wECCBytesPerSector *= DeviceInfo.wDevicesConnected;
+ DeviceInfo.wNumPageSpareFlag =
+ DeviceInfo.wPageSpareSize -
+ DeviceInfo.wPageDataSize /
+ (ECC_SECTOR_SIZE * DeviceInfo.wDevicesConnected) *
+ DeviceInfo.wECCBytesPerSector
+ - DeviceInfo.wSpareSkipBytes;
+ } else {
+ DeviceInfo.wECCBytesPerSector =
+ (ioread32(FlashReg + ECC_CORRECTION) &
+ ECC_CORRECTION__VALUE) * 13 / 8;
+ if ((DeviceInfo.wECCBytesPerSector) % 2 == 0)
+ DeviceInfo.wECCBytesPerSector += 2;
+ else
+ DeviceInfo.wECCBytesPerSector += 1;
+
+ DeviceInfo.wECCBytesPerSector *= DeviceInfo.wDevicesConnected;
+ DeviceInfo.wNumPageSpareFlag = DeviceInfo.wPageSpareSize -
+ DeviceInfo.wPageDataSize /
+ (ECC_SECTOR_SIZE * DeviceInfo.wDevicesConnected) *
+ DeviceInfo.wECCBytesPerSector
+ - DeviceInfo.wSpareSkipBytes;
+ }
+
+}
+
+static u16 get_onfi_nand_para(void)
+{
+ int i;
+ u16 blks_lun_l, blks_lun_h, n_of_luns;
+ u32 blockperlun, id;
+
+ iowrite32(DEVICE_RESET__BANK0, FlashReg + DEVICE_RESET);
+
+ while (!((ioread32(FlashReg + INTR_STATUS0) &
+ INTR_STATUS0__RST_COMP) |
+ (ioread32(FlashReg + INTR_STATUS0) &
+ INTR_STATUS0__TIME_OUT)))
+ ;
+
+ if (ioread32(FlashReg + INTR_STATUS0) & INTR_STATUS0__RST_COMP) {
+ iowrite32(DEVICE_RESET__BANK1, FlashReg + DEVICE_RESET);
+ while (!((ioread32(FlashReg + INTR_STATUS1) &
+ INTR_STATUS1__RST_COMP) |
+ (ioread32(FlashReg + INTR_STATUS1) &
+ INTR_STATUS1__TIME_OUT)))
+ ;
+
+ if (ioread32(FlashReg + INTR_STATUS1) &
+ INTR_STATUS1__RST_COMP) {
+ iowrite32(DEVICE_RESET__BANK2,
+ FlashReg + DEVICE_RESET);
+ while (!((ioread32(FlashReg + INTR_STATUS2) &
+ INTR_STATUS2__RST_COMP) |
+ (ioread32(FlashReg + INTR_STATUS2) &
+ INTR_STATUS2__TIME_OUT)))
+ ;
+
+ if (ioread32(FlashReg + INTR_STATUS2) &
+ INTR_STATUS2__RST_COMP) {
+ iowrite32(DEVICE_RESET__BANK3,
+ FlashReg + DEVICE_RESET);
+ while (!((ioread32(FlashReg + INTR_STATUS3) &
+ INTR_STATUS3__RST_COMP) |
+ (ioread32(FlashReg + INTR_STATUS3) &
+ INTR_STATUS3__TIME_OUT)))
+ ;
+ } else {
+ printk(KERN_ERR "Getting a time out for bank 2!\n");
+ }
+ } else {
+ printk(KERN_ERR "Getting a time out for bank 1!\n");
+ }
+ }
+
+ iowrite32(INTR_STATUS0__TIME_OUT, FlashReg + INTR_STATUS0);
+ iowrite32(INTR_STATUS1__TIME_OUT, FlashReg + INTR_STATUS1);
+ iowrite32(INTR_STATUS2__TIME_OUT, FlashReg + INTR_STATUS2);
+ iowrite32(INTR_STATUS3__TIME_OUT, FlashReg + INTR_STATUS3);
+
+ DeviceInfo.wONFIDevFeatures =
+ ioread32(FlashReg + ONFI_DEVICE_FEATURES);
+ DeviceInfo.wONFIOptCommands =
+ ioread32(FlashReg + ONFI_OPTIONAL_COMMANDS);
+ DeviceInfo.wONFITimingMode =
+ ioread32(FlashReg + ONFI_TIMING_MODE);
+ DeviceInfo.wONFIPgmCacheTimingMode =
+ ioread32(FlashReg + ONFI_PGM_CACHE_TIMING_MODE);
+
+ n_of_luns = ioread32(FlashReg + ONFI_DEVICE_NO_OF_LUNS) &
+ ONFI_DEVICE_NO_OF_LUNS__NO_OF_LUNS;
+ blks_lun_l = ioread32(FlashReg + ONFI_DEVICE_NO_OF_BLOCKS_PER_LUN_L);
+ blks_lun_h = ioread32(FlashReg + ONFI_DEVICE_NO_OF_BLOCKS_PER_LUN_U);
+
+ blockperlun = (blks_lun_h << 16) | blks_lun_l;
+
+ DeviceInfo.wTotalBlocks = n_of_luns * blockperlun;
+
+ if (!(ioread32(FlashReg + ONFI_TIMING_MODE) &
+ ONFI_TIMING_MODE__VALUE))
+ return FAIL;
+
+ for (i = 5; i > 0; i--) {
+ if (ioread32(FlashReg + ONFI_TIMING_MODE) & (0x01 << i))
+ break;
+ }
+
+#if MODE5_WORKAROUND
+ if (i == 5)
+ i = 4;
+#endif
+
+ NAND_ONFi_Timing_Mode(i);
+
+ index_addr(MODE_11 | 0, 0x90);
+ index_addr(MODE_11 | 1, 0);
+
+ for (i = 0; i < 3; i++)
+ index_addr_read_data(MODE_11 | 2, &id);
+
+ nand_dbg_print(NAND_DBG_DEBUG, "3rd ID: 0x%x\n", id);
+
+ DeviceInfo.MLCDevice = id & 0x0C;
+
+ return PASS;
+}
+
+static void get_samsung_nand_para(void)
+{
+ u8 no_of_planes;
+ u32 blk_size;
+ u64 plane_size, capacity;
+ u32 id_bytes[5];
+ int i;
+
+ index_addr((u32)(MODE_11 | 0), 0x90);
+ index_addr((u32)(MODE_11 | 1), 0);
+ for (i = 0; i < 5; i++)
+ index_addr_read_data((u32)(MODE_11 | 2), &id_bytes[i]);
+
+ nand_dbg_print(NAND_DBG_DEBUG,
+ "ID bytes: 0x%x, 0x%x, 0x%x, 0x%x, 0x%x\n",
+ id_bytes[0], id_bytes[1], id_bytes[2],
+ id_bytes[3], id_bytes[4]);
+
+ no_of_planes = 1 << ((id_bytes[4] & 0x0c) >> 2);
+ plane_size = (u64)64 << ((id_bytes[4] & 0x70) >> 4);
+ blk_size = 64 << ((ioread32(FlashReg + DEVICE_PARAM_1) & 0x30) >> 4);
+ capacity = (u64)128 * plane_size * no_of_planes;
+
+ DeviceInfo.wTotalBlocks = (u32)GLOB_u64_Div(capacity, blk_size);
+}
+
+static void find_valid_banks(void)
+{
+ u32 id[LLD_MAX_FLASH_BANKS];
+ int i;
+
+ totalUsedBanks = 0;
+ for (i = 0; i < LLD_MAX_FLASH_BANKS; i++) {
+ index_addr((u32)(MODE_11 | (i << 24) | 0), 0x90);
+ index_addr((u32)(MODE_11 | (i << 24) | 1), 0);
+ index_addr_read_data((u32)(MODE_11 | (i << 24) | 2), &id[i]);
+
+ nand_dbg_print(NAND_DBG_DEBUG,
+ "Return 1st ID for bank[%d]: %x\n", i, id[i]);
+
+ if (i == 0) {
+ if (id[i] & 0x0ff)
+ GLOB_valid_banks[i] = 1;
+ } else {
+ if ((id[i] & 0x0ff) == (id[0] & 0x0ff))
+ GLOB_valid_banks[i] = 1;
+ }
+
+ totalUsedBanks += GLOB_valid_banks[i];
+ }
+
+ nand_dbg_print(NAND_DBG_DEBUG,
+ "totalUsedBanks: %d\n", totalUsedBanks);
+}
+
+static void detect_partition_feature(void)
+{
+ if (ioread32(FlashReg + FEATURES) & FEATURES__PARTITION) {
+ if ((ioread32(FlashReg + PERM_SRC_ID_1) &
+ PERM_SRC_ID_1__SRCID) == SPECTRA_PARTITION_ID) {
+ DeviceInfo.wSpectraStartBlock =
+ ((ioread32(FlashReg + MIN_MAX_BANK_1) &
+ MIN_MAX_BANK_1__MIN_VALUE) *
+ DeviceInfo.wTotalBlocks)
+ +
+ (ioread32(FlashReg + MIN_BLK_ADDR_1) &
+ MIN_BLK_ADDR_1__VALUE);
+
+ DeviceInfo.wSpectraEndBlock =
+ (((ioread32(FlashReg + MIN_MAX_BANK_1) &
+ MIN_MAX_BANK_1__MAX_VALUE) >> 2) *
+ DeviceInfo.wTotalBlocks)
+ +
+ (ioread32(FlashReg + MAX_BLK_ADDR_1) &
+ MAX_BLK_ADDR_1__VALUE);
+
+ DeviceInfo.wTotalBlocks *= totalUsedBanks;
+
+ if (DeviceInfo.wSpectraEndBlock >=
+ DeviceInfo.wTotalBlocks) {
+ DeviceInfo.wSpectraEndBlock =
+ DeviceInfo.wTotalBlocks - 1;
+ }
+
+ DeviceInfo.wDataBlockNum =
+ DeviceInfo.wSpectraEndBlock -
+ DeviceInfo.wSpectraStartBlock + 1;
+ } else {
+ DeviceInfo.wTotalBlocks *= totalUsedBanks;
+ DeviceInfo.wSpectraStartBlock = SPECTRA_START_BLOCK;
+ DeviceInfo.wSpectraEndBlock =
+ DeviceInfo.wTotalBlocks - 1;
+ DeviceInfo.wDataBlockNum =
+ DeviceInfo.wSpectraEndBlock -
+ DeviceInfo.wSpectraStartBlock + 1;
+ }
+ } else {
+ DeviceInfo.wTotalBlocks *= totalUsedBanks;
+ DeviceInfo.wSpectraStartBlock = SPECTRA_START_BLOCK;
+ DeviceInfo.wSpectraEndBlock = DeviceInfo.wTotalBlocks - 1;
+ DeviceInfo.wDataBlockNum =
+ DeviceInfo.wSpectraEndBlock -
+ DeviceInfo.wSpectraStartBlock + 1;
+ }
+}
+
+static void dump_device_info(void)
+{
+ nand_dbg_print(NAND_DBG_DEBUG, "DeviceInfo:\n");
+ nand_dbg_print(NAND_DBG_DEBUG, "DeviceMaker: 0x%x\n",
+ DeviceInfo.wDeviceMaker);
+ nand_dbg_print(NAND_DBG_DEBUG, "DeviceType: 0x%x\n",
+ DeviceInfo.wDeviceType);
+ nand_dbg_print(NAND_DBG_DEBUG, "SpectraStartBlock: %d\n",
+ DeviceInfo.wSpectraStartBlock);
+ nand_dbg_print(NAND_DBG_DEBUG, "SpectraEndBlock: %d\n",
+ DeviceInfo.wSpectraEndBlock);
+ nand_dbg_print(NAND_DBG_DEBUG, "TotalBlocks: %d\n",
+ DeviceInfo.wTotalBlocks);
+ nand_dbg_print(NAND_DBG_DEBUG, "PagesPerBlock: %d\n",
+ DeviceInfo.wPagesPerBlock);
+ nand_dbg_print(NAND_DBG_DEBUG, "PageSize: %d\n",
+ DeviceInfo.wPageSize);
+ nand_dbg_print(NAND_DBG_DEBUG, "PageDataSize: %d\n",
+ DeviceInfo.wPageDataSize);
+ nand_dbg_print(NAND_DBG_DEBUG, "PageSpareSize: %d\n",
+ DeviceInfo.wPageSpareSize);
+ nand_dbg_print(NAND_DBG_DEBUG, "NumPageSpareFlag: %d\n",
+ DeviceInfo.wNumPageSpareFlag);
+ nand_dbg_print(NAND_DBG_DEBUG, "ECCBytesPerSector: %d\n",
+ DeviceInfo.wECCBytesPerSector);
+ nand_dbg_print(NAND_DBG_DEBUG, "BlockSize: %d\n",
+ DeviceInfo.wBlockSize);
+ nand_dbg_print(NAND_DBG_DEBUG, "BlockDataSize: %d\n",
+ DeviceInfo.wBlockDataSize);
+ nand_dbg_print(NAND_DBG_DEBUG, "DataBlockNum: %d\n",
+ DeviceInfo.wDataBlockNum);
+ nand_dbg_print(NAND_DBG_DEBUG, "PlaneNum: %d\n",
+ DeviceInfo.bPlaneNum);
+ nand_dbg_print(NAND_DBG_DEBUG, "DeviceMainAreaSize: %d\n",
+ DeviceInfo.wDeviceMainAreaSize);
+ nand_dbg_print(NAND_DBG_DEBUG, "DeviceSpareAreaSize: %d\n",
+ DeviceInfo.wDeviceSpareAreaSize);
+ nand_dbg_print(NAND_DBG_DEBUG, "DevicesConnected: %d\n",
+ DeviceInfo.wDevicesConnected);
+ nand_dbg_print(NAND_DBG_DEBUG, "DeviceWidth: %d\n",
+ DeviceInfo.wDeviceWidth);
+ nand_dbg_print(NAND_DBG_DEBUG, "HWRevision: 0x%x\n",
+ DeviceInfo.wHWRevision);
+ nand_dbg_print(NAND_DBG_DEBUG, "HWFeatures: 0x%x\n",
+ DeviceInfo.wHWFeatures);
+ nand_dbg_print(NAND_DBG_DEBUG, "ONFIDevFeatures: 0x%x\n",
+ DeviceInfo.wONFIDevFeatures);
+ nand_dbg_print(NAND_DBG_DEBUG, "ONFIOptCommands: 0x%x\n",
+ DeviceInfo.wONFIOptCommands);
+ nand_dbg_print(NAND_DBG_DEBUG, "ONFITimingMode: 0x%x\n",
+ DeviceInfo.wONFITimingMode);
+ nand_dbg_print(NAND_DBG_DEBUG, "ONFIPgmCacheTimingMode: 0x%x\n",
+ DeviceInfo.wONFIPgmCacheTimingMode);
+ nand_dbg_print(NAND_DBG_DEBUG, "MLCDevice: %s\n",
+ DeviceInfo.MLCDevice ? "Yes" : "No");
+ nand_dbg_print(NAND_DBG_DEBUG, "SpareSkipBytes: %d\n",
+ DeviceInfo.wSpareSkipBytes);
+ nand_dbg_print(NAND_DBG_DEBUG, "BitsInPageNumber: %d\n",
+ DeviceInfo.nBitsInPageNumber);
+ nand_dbg_print(NAND_DBG_DEBUG, "BitsInPageDataSize: %d\n",
+ DeviceInfo.nBitsInPageDataSize);
+ nand_dbg_print(NAND_DBG_DEBUG, "BitsInBlockDataSize: %d\n",
+ DeviceInfo.nBitsInBlockDataSize);
+}
+
+u16 NAND_Read_Device_ID(void)
+{
+ u16 status = PASS;
+ u8 mfg_code, dev_code;
+ u8 no_of_planes;
+ u32 tmp;
+
+ nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
+ __FILE__, __LINE__, __func__);
+
+ iowrite32(0x02, FlashReg + SPARE_AREA_SKIP_BYTES);
+ iowrite32(0xffff, FlashReg + SPARE_AREA_MARKER);
+ DeviceInfo.wDeviceMaker = ioread32(FlashReg + MANUFACTURER_ID);
+ DeviceInfo.wDeviceType = (((ioread32(FlashReg + DEVICE_WIDTH) >> 2)
+ > 0) ? 16 : 8);
+ DeviceInfo.wPagesPerBlock = ioread32(FlashReg + PAGES_PER_BLOCK);
+ DeviceInfo.wPageDataSize =
+ ioread32(FlashReg + LOGICAL_PAGE_DATA_SIZE);
+
+ /* Note: When using the Micon 4K NAND device, the controller will report
+ * Page Spare Size as 216 bytes. But Micron's Spec say it's 218 bytes.
+ * And if force set it to 218 bytes, the controller can not work
+ * correctly. So just let it be. But keep in mind that this bug may
+ * cause
+ * other problems in future. - Yunpeng 2008-10-10
+ */
+ DeviceInfo.wPageSpareSize =
+ ioread32(FlashReg + LOGICAL_PAGE_SPARE_SIZE);
+
+ DeviceInfo.wPageSize =
+ DeviceInfo.wPageDataSize + DeviceInfo.wPageSpareSize;
+ DeviceInfo.wBlockSize =
+ DeviceInfo.wPageSize * DeviceInfo.wPagesPerBlock;
+ DeviceInfo.wBlockDataSize =
+ DeviceInfo.wPagesPerBlock * DeviceInfo.wPageDataSize;
+ DeviceInfo.wHWRevision = ioread32(FlashReg + REVISION);
+
+ DeviceInfo.wDeviceMainAreaSize =
+ ioread32(FlashReg + DEVICE_MAIN_AREA_SIZE);
+ DeviceInfo.wDeviceSpareAreaSize =
+ ioread32(FlashReg + DEVICE_SPARE_AREA_SIZE);
+
+ DeviceInfo.wDeviceWidth = ioread32(FlashReg + DEVICE_WIDTH);
+ DeviceInfo.wDevicesConnected = ioread32(FlashReg + DEVICES_CONNECTED);
+ DeviceInfo.wHWFeatures = ioread32(FlashReg + FEATURES);
+
+ /* nand_dbg_print(NAND_DBG_DEBUG, "Will disable ECC for now:\n");*/
+ /* iowrite32(0, FlashReg + ECC_ENABLE); */
+
+ DeviceInfo.MLCDevice = ioread32(FlashReg + DEVICE_PARAM_0) & 0x0c;
+ DeviceInfo.wSpareSkipBytes = ioread32(FlashReg +
+ SPARE_AREA_SKIP_BYTES)
+ * DeviceInfo.wDevicesConnected;
+
+ DeviceInfo.nBitsInPageNumber =
+ (u8)GLOB_Calc_Used_Bits(DeviceInfo.wPagesPerBlock);
+ DeviceInfo.nBitsInPageDataSize =
+ (u8)GLOB_Calc_Used_Bits(DeviceInfo.wPageDataSize);
+ DeviceInfo.nBitsInBlockDataSize =
+ (u8)GLOB_Calc_Used_Bits(DeviceInfo.wBlockDataSize);
+
+#if SUPPORT_8BITECC
+ if ((ioread32(FlashReg + DEVICE_MAIN_AREA_SIZE) < 4096) ||
+ (ioread32(FlashReg + DEVICE_SPARE_AREA_SIZE) <= 128))
+ iowrite32(8, FlashReg + ECC_CORRECTION);
+#endif
+
+ nand_dbg_print(NAND_DBG_DEBUG, "FEATURES register value: 0x%x\n",
+ ioread32(FlashReg + FEATURES));
+ nand_dbg_print(NAND_DBG_DEBUG, "ECC_CORRECTION register value: 0x%x\n",
+ ioread32(FlashReg + ECC_CORRECTION));
+
+ /* Toshiba NAND */
+ if ((ioread32(FlashReg + MANUFACTURER_ID) == 0x98) &&
+ (ioread32(FlashReg + DEVICE_MAIN_AREA_SIZE) == 4096) &&
+ (ioread32(FlashReg + DEVICE_SPARE_AREA_SIZE) == 64)) {
+ iowrite32(216, FlashReg + DEVICE_SPARE_AREA_SIZE);
+ tmp = ioread32(FlashReg + DEVICES_CONNECTED) *
+ ioread32(FlashReg + DEVICE_SPARE_AREA_SIZE);
+ iowrite32(tmp, FlashReg + LOGICAL_PAGE_SPARE_SIZE);
+ DeviceInfo.wDeviceSpareAreaSize =
+ ioread32(FlashReg + DEVICE_SPARE_AREA_SIZE);
+ DeviceInfo.wPageSpareSize =
+ ioread32(FlashReg + LOGICAL_PAGE_SPARE_SIZE);
+#if SUPPORT_15BITECC
+ iowrite32(15, FlashReg + ECC_CORRECTION);
+#elif SUPPORT_8BITECC
+ iowrite32(8, FlashReg + ECC_CORRECTION);
+#endif
+ }
+
+ set_ecc_config();
+
+ mfg_code = DeviceInfo.wDeviceMaker;
+ dev_code = DeviceInfo.wDeviceType;
+
+ if (ioread32(FlashReg + ONFI_DEVICE_NO_OF_LUNS) &
+ ONFI_DEVICE_NO_OF_LUNS__ONFI_DEVICE) { /* ONFI 1.0 NAND */
+ if (FAIL == get_onfi_nand_para())
+ return FAIL;
+ } else if (mfg_code == 0xEC) { /* Samsung NAND */
+ get_samsung_nand_para();
+ } else {
+#if GLOB_DEVTSBA_ALT_BLK_NFO
+ u8 *tsba_ptr = (u8 *)GLOB_DEVTSBA_ALT_BLK_ADD;
+ DeviceInfo.wTotalBlocks = (1 << *tsba_ptr);
+ if (DeviceInfo.wTotalBlocks < 512)
+ DeviceInfo.wTotalBlocks = GLOB_HWCTL_DEFAULT_BLKS;
+#else
+ DeviceInfo.wTotalBlocks = GLOB_HWCTL_DEFAULT_BLKS;
+#endif
+ }
+
+ no_of_planes = ioread32(FlashReg + NUMBER_OF_PLANES) &
+ NUMBER_OF_PLANES__VALUE;
+
+ switch (no_of_planes) {
+ case 0:
+ case 1:
+ case 3:
+ case 7:
+ DeviceInfo.bPlaneNum = no_of_planes + 1;
+ break;
+ default:
+ status = FAIL;
+ break;
+ }
+
+ find_valid_banks();
+
+ detect_partition_feature();
+
+ dump_device_info();
+
+ return status;
+}
+
+u16 NAND_UnlockArrayAll(void)
+{
+ u64 start_addr, end_addr;
+
+ nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
+ __FILE__, __LINE__, __func__);
+
+ start_addr = 0;
+ end_addr = ((u64)DeviceInfo.wBlockSize *
+ (DeviceInfo.wTotalBlocks - 1)) >>
+ DeviceInfo.nBitsInPageDataSize;
+
+ index_addr((u32)(MODE_10 | (u32)start_addr), 0x10);
+ index_addr((u32)(MODE_10 | (u32)end_addr), 0x11);
+
+ return PASS;
+}
+
+void NAND_LLD_Enable_Disable_Interrupts(u16 INT_ENABLE)
+{
+ nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
+ __FILE__, __LINE__, __func__);
+
+ if (INT_ENABLE)
+ iowrite32(1, FlashReg + GLOBAL_INT_ENABLE);
+ else
+ iowrite32(0, FlashReg + GLOBAL_INT_ENABLE);
+}
+
+u16 NAND_Erase_Block(u32 block)
+{
+ u16 status = PASS;
+ u64 flash_add;
+ u16 flash_bank;
+ u32 intr_status = 0;
+ u32 intr_status_addresses[4] = {INTR_STATUS0,
+ INTR_STATUS1, INTR_STATUS2, INTR_STATUS3};
+
+ nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
+ __FILE__, __LINE__, __func__);
+
+ flash_add = (u64)(block % (DeviceInfo.wTotalBlocks / totalUsedBanks))
+ * DeviceInfo.wBlockDataSize;
+
+ flash_bank = block / (DeviceInfo.wTotalBlocks / totalUsedBanks);
+
+ if (block >= DeviceInfo.wTotalBlocks)
+ status = FAIL;
+
+ if (status == PASS) {
+ intr_status = intr_status_addresses[flash_bank];
+
+ iowrite32(INTR_STATUS0__ERASE_COMP | INTR_STATUS0__ERASE_FAIL,
+ FlashReg + intr_status);
+
+ index_addr((u32)(MODE_10 | (flash_bank << 24) |
+ (flash_add >> DeviceInfo.nBitsInPageDataSize)), 1);
+
+ while (!(ioread32(FlashReg + intr_status) &
+ (INTR_STATUS0__ERASE_COMP | INTR_STATUS0__ERASE_FAIL)))
+ ;
+
+ if (ioread32(FlashReg + intr_status) &
+ INTR_STATUS0__ERASE_FAIL)
+ status = FAIL;
+
+ iowrite32(INTR_STATUS0__ERASE_COMP | INTR_STATUS0__ERASE_FAIL,
+ FlashReg + intr_status);
+ }
+
+ return status;
+}
+
+static u32 Boundary_Check_Block_Page(u32 block, u16 page,
+ u16 page_count)
+{
+ u32 status = PASS;
+
+ if (block >= DeviceInfo.wTotalBlocks)
+ status = FAIL;
+
+ if (page + page_count > DeviceInfo.wPagesPerBlock)
+ status = FAIL;
+
+ return status;
+}
+
+u16 NAND_Read_Page_Spare(u8 *read_data, u32 block, u16 page,
+ u16 page_count)
+{
+ u32 status = PASS;
+ u32 i;
+ u64 flash_add;
+ u32 PageSpareSize = DeviceInfo.wPageSpareSize;
+ u32 spareFlagBytes = DeviceInfo.wNumPageSpareFlag;
+ u32 flash_bank;
+ u32 intr_status = 0;
+ u32 intr_status_addresses[4] = {INTR_STATUS0,
+ INTR_STATUS1, INTR_STATUS2, INTR_STATUS3};
+
+ if (block >= DeviceInfo.wTotalBlocks) {
+ printk(KERN_ERR "block too big: %d\n", (int)block);
+ status = FAIL;
+ }
+
+ if (page >= DeviceInfo.wPagesPerBlock) {
+ printk(KERN_ERR "page too big: %d\n", page);
+ status = FAIL;
+ }
+
+ if (page_count > 1) {
+ printk(KERN_ERR "page count too big: %d\n", page_count);
+ status = FAIL;
+ }
+
+ flash_add = (u64)(block % (DeviceInfo.wTotalBlocks / totalUsedBanks))
+ * DeviceInfo.wBlockDataSize +
+ (u64)page * DeviceInfo.wPageDataSize;
+
+ flash_bank = block / (DeviceInfo.wTotalBlocks / totalUsedBanks);
+
+ if (status == PASS) {
+ intr_status = intr_status_addresses[flash_bank];
+ iowrite32(ioread32(FlashReg + intr_status),
+ FlashReg + intr_status);
+
+ index_addr((u32)(MODE_10 | (flash_bank << 24) |
+ (flash_add >> DeviceInfo.nBitsInPageDataSize)),
+ 0x41);
+ index_addr((u32)(MODE_10 | (flash_bank << 24) |
+ (flash_add >> DeviceInfo.nBitsInPageDataSize)),
+ 0x2000 | page_count);
+ while (!(ioread32(FlashReg + intr_status) &
+ INTR_STATUS0__LOAD_COMP))
+ ;
+
+ iowrite32((u32)(MODE_01 | (flash_bank << 24) |
+ (flash_add >> DeviceInfo.nBitsInPageDataSize)),
+ FlashMem);
+
+ for (i = 0; i < (PageSpareSize / 4); i++)
+ *((u32 *)page_spare + i) =
+ ioread32(FlashMem + 0x10);
+
+ if (ioread32(FlashReg + ECC_ENABLE)) {
+ for (i = 0; i < spareFlagBytes; i++)
+ read_data[i] =
+ page_spare[PageSpareSize -
+ spareFlagBytes + i];
+ for (i = 0; i < (PageSpareSize - spareFlagBytes); i++)
+ read_data[spareFlagBytes + i] =
+ page_spare[i];
+ } else {
+ for (i = 0; i < PageSpareSize; i++)
+ read_data[i] = page_spare[i];
+ }
+
+ index_addr((u32)(MODE_10 | (flash_bank << 24) |
+ (flash_add >> DeviceInfo.nBitsInPageDataSize)), 0x42);
+ }
+
+ return status;
+}
+
+u16 NAND_Write_Page_Spare(u8 *write_data, u32 block, u16 page,
+ u16 page_count)
+{
+ printk(KERN_ERR
+ "Error! This function (NAND_Write_Page_Spare) should never"
+ " be called!\n");
+ return ERR;
+}
+
+#if DDMA
+/* op value: 0 - DDMA read; 1 - DDMA write */
+static void ddma_trans(u8 *data, u64 flash_add,
+ u32 flash_bank, int op, u32 numPages)
+{
+ /* Map virtual address to bus address for DDMA */
+ data = (u8 *)GLOB_MEMMAP_TOBUS((u32 *)data);
+
+ index_addr((u32)(MODE_10 | (flash_bank << 24) |
+ (flash_add >> DeviceInfo.nBitsInPageDataSize)),
+ (u16)(2 << 12) | (op << 8) | numPages);
+
+ index_addr((u32)(MODE_10 | (flash_bank << 24) |
+ ((u16)(0x0FFFF & ((u32)data >> 16)) << 8)),
+ (u16)(2 << 12) | (2 << 8) | 0);
+
+ index_addr((u32)(MODE_10 | (flash_bank << 24) |
+ ((u16)(0x0FFFF & (u32)data) << 8)),
+ (u16)(2 << 12) | (3 << 8) | 0);
+
+ index_addr((u32)(MODE_10 | (flash_bank << 24) |
+ (1 << 16) | (0x40 << 8)),
+ (u16)(2 << 12) | (4 << 8) | 0);
+}
+
+#endif
+
+/* If data in buf are all 0xff, then return 1; otherwise return 0 */
+static int check_all_1(u8 *buf)
+{
+ int i, j, cnt;
+
+ for (i = 0; i < DeviceInfo.wPageDataSize; i++) {
+ if (buf[i] != 0xff) {
+ cnt = 0;
+ nand_dbg_print(NAND_DBG_WARN,
+ "the first non-0xff data byte is: %d\n", i);
+ for (j = i; j < DeviceInfo.wPageDataSize; j++) {
+ nand_dbg_print(NAND_DBG_WARN, "0x%x ", buf[j]);
+ cnt++;
+ if (cnt > 8)
+ break;
+ }
+ nand_dbg_print(NAND_DBG_WARN, "\n");
+ return 0;
+ }
+ }
+
+ return 1;
+}
+
+static int do_ecc_new(unsigned long bank, u8 *buf,
+ u32 block, u16 page)
+{
+ int status = PASS;
+ u16 err_page = 0;
+ u16 err_byte;
+ u8 err_sect;
+ u8 err_dev;
+ u16 err_fix_info;
+ u16 err_addr;
+ u32 ecc_sect_size;
+ u8 *err_pos;
+ u32 err_page_addr[4] = {ERR_PAGE_ADDR0,
+ ERR_PAGE_ADDR1, ERR_PAGE_ADDR2, ERR_PAGE_ADDR3};
+
+ ecc_sect_size = ECC_SECTOR_SIZE * (DeviceInfo.wDevicesConnected);
+
+ do {
+ err_page = ioread32(FlashReg + err_page_addr[bank]);
+ err_addr = ioread32(FlashReg + ECC_ERROR_ADDRESS);
+ err_byte = err_addr & ECC_ERROR_ADDRESS__OFFSET;
+ err_sect = ((err_addr & ECC_ERROR_ADDRESS__SECTOR_NR) >> 12);
+ err_fix_info = ioread32(FlashReg + ERR_CORRECTION_INFO);
+ err_dev = ((err_fix_info & ERR_CORRECTION_INFO__DEVICE_NR)
+ >> 8);
+ if (err_fix_info & ERR_CORRECTION_INFO__ERROR_TYPE) {
+ nand_dbg_print(NAND_DBG_WARN,
+ "%s, Line %d Uncorrectable ECC error "
+ "when read block %d page %d."
+ "PTN_INTR register: 0x%x "
+ "err_page: %d, err_sect: %d, err_byte: %d, "
+ "err_dev: %d, ecc_sect_size: %d, "
+ "err_fix_info: 0x%x\n",
+ __FILE__, __LINE__, block, page,
+ ioread32(FlashReg + PTN_INTR),
+ err_page, err_sect, err_byte, err_dev,
+ ecc_sect_size, (u32)err_fix_info);
+
+ if (check_all_1(buf))
+ nand_dbg_print(NAND_DBG_WARN, "%s, Line %d"
+ "All 0xff!\n",
+ __FILE__, __LINE__);
+ else
+ nand_dbg_print(NAND_DBG_WARN, "%s, Line %d"
+ "Not all 0xff!\n",
+ __FILE__, __LINE__);
+ status = FAIL;
+ } else {
+ /* glob_mdelay(200); */ /* Add for test */
+ nand_dbg_print(NAND_DBG_WARN,
+ "%s, Line %d Found ECC error "
+ "when read block %d page %d."
+ "err_page: %d, err_sect: %d, err_byte: %d, "
+ "err_dev: %d, ecc_sect_size: %d, "
+ "err_fix_info: 0x%x\n",
+ __FILE__, __LINE__, block, page,
+ err_page, err_sect, err_byte, err_dev,
+ ecc_sect_size, (u32)err_fix_info);
+ if (err_byte < ecc_sect_size) {
+ err_pos = buf +
+ (err_page - page) *
+ DeviceInfo.wPageDataSize +
+ err_sect * ecc_sect_size +
+ err_byte *
+ DeviceInfo.wDevicesConnected +
+ err_dev;
+
+ *err_pos ^= err_fix_info &
+ ERR_CORRECTION_INFO__BYTEMASK;
+ } else {
+ nand_dbg_print(NAND_DBG_WARN,
+ "!!!Error - Too big err_byte!\n");
+ }
+ }
+ } while (!(err_fix_info & ERR_CORRECTION_INFO__LAST_ERR_INFO));
+
+ return status;
+}
+
+u16 NAND_Read_Page_Main_Polling(u8 *read_data,
+ u32 block, u16 page, u16 page_count)
+{
+ u32 status = PASS;
+ u64 flash_add;
+ u32 intr_status = 0;
+ u32 flash_bank;
+ u32 intr_status_addresses[4] = {INTR_STATUS0,
+ INTR_STATUS1, INTR_STATUS2, INTR_STATUS3};
+
+ nand_dbg_print(NAND_DBG_WARN, "%s, Line %d, Function: %s\n",
+ __FILE__, __LINE__, __func__);
+
+ status = Boundary_Check_Block_Page(block, page, page_count);
+ if (status != PASS)
+ return status;
+
+ flash_add = (u64)(block % (DeviceInfo.wTotalBlocks / totalUsedBanks))
+ * DeviceInfo.wBlockDataSize +
+ (u64)page * DeviceInfo.wPageDataSize;
+ flash_bank = block / (DeviceInfo.wTotalBlocks / totalUsedBanks);
+
+ iowrite32(0, FlashReg + TRANSFER_SPARE_REG);
+
+ intr_status = intr_status_addresses[flash_bank];
+ iowrite32(ioread32(FlashReg + intr_status), FlashReg + intr_status);
+
+ if (page_count > 1) {
+ if (ioread32(FlashReg + MULTIPLANE_OPERATION))
+ status = NAND_Multiplane_Read(read_data,
+ block, page, page_count);
+ else
+ status = NAND_Pipeline_Read_Ahead_Polling(read_data,
+ block, page, page_count);
+ return status;
+ }
+
+ iowrite32(1, FlashReg + DMA_ENABLE);
+ while (!(ioread32(FlashReg + DMA_ENABLE) & DMA_ENABLE__FLAG))
+ ;
+
+ iowrite32(0, FlashReg + TRANSFER_SPARE_REG);
+ iowrite32(ioread32(FlashReg + intr_status), FlashReg + intr_status);
+
+ ddma_trans(read_data, flash_add, flash_bank, 0, 1);
+
+ if (ioread32(FlashReg + ECC_ENABLE)) {
+ while (!(ioread32(FlashReg + intr_status) &
+ (INTR_STATUS0__ECC_TRANSACTION_DONE |
+ INTR_STATUS0__ECC_ERR)))
+ ;
+
+ if (ioread32(FlashReg + intr_status) &
+ INTR_STATUS0__ECC_ERR) {
+ iowrite32(INTR_STATUS0__ECC_ERR,
+ FlashReg + intr_status);
+ status = do_ecc_new(flash_bank, read_data,
+ block, page);
+ }
+
+ if (ioread32(FlashReg + intr_status) &
+ INTR_STATUS0__ECC_TRANSACTION_DONE &
+ INTR_STATUS0__ECC_ERR)
+ iowrite32(INTR_STATUS0__ECC_TRANSACTION_DONE |
+ INTR_STATUS0__ECC_ERR,
+ FlashReg + intr_status);
+ else if (ioread32(FlashReg + intr_status) &
+ INTR_STATUS0__ECC_TRANSACTION_DONE)
+ iowrite32(INTR_STATUS0__ECC_TRANSACTION_DONE,
+ FlashReg + intr_status);
+ else if (ioread32(FlashReg + intr_status) &
+ INTR_STATUS0__ECC_ERR)
+ iowrite32(INTR_STATUS0__ECC_ERR,
+ FlashReg + intr_status);
+ } else {
+ while (!(ioread32(FlashReg + intr_status) &
+ INTR_STATUS0__DMA_CMD_COMP))
+ ;
+ iowrite32(INTR_STATUS0__DMA_CMD_COMP, FlashReg + intr_status);
+ }
+
+ iowrite32(ioread32(FlashReg + intr_status), FlashReg + intr_status);
+
+ iowrite32(0, FlashReg + DMA_ENABLE);
+ while ((ioread32(FlashReg + DMA_ENABLE) & DMA_ENABLE__FLAG))
+ ;
+
+ return status;
+}
+
+u16 NAND_Pipeline_Read_Ahead_Polling(u8 *read_data,
+ u32 block, u16 page, u16 page_count)
+{
+ u32 status = PASS;
+ u32 NumPages = page_count;
+ u64 flash_add;
+ u32 flash_bank;
+ u32 intr_status = 0;
+ u32 intr_status_addresses[4] = {INTR_STATUS0,
+ INTR_STATUS1, INTR_STATUS2, INTR_STATUS3};
+ u32 ecc_done_OR_dma_comp;
+
+ nand_dbg_print(NAND_DBG_WARN, "%s, Line %d, Function: %s\n",
+ __FILE__, __LINE__, __func__);
+
+ status = Boundary_Check_Block_Page(block, page, page_count);
+
+ if (page_count < 2)
+ status = FAIL;
+
+ flash_add = (u64)(block % (DeviceInfo.wTotalBlocks / totalUsedBanks))
+ *DeviceInfo.wBlockDataSize +
+ (u64)page * DeviceInfo.wPageDataSize;
+
+ flash_bank = block / (DeviceInfo.wTotalBlocks / totalUsedBanks);
+
+ if (status == PASS) {
+ intr_status = intr_status_addresses[flash_bank];
+ iowrite32(ioread32(FlashReg + intr_status),
+ FlashReg + intr_status);
+
+ iowrite32(1, FlashReg + DMA_ENABLE);
+ while (!(ioread32(FlashReg + DMA_ENABLE) & DMA_ENABLE__FLAG))
+ ;
+
+ iowrite32(0, FlashReg + TRANSFER_SPARE_REG);
+
+ index_addr((u32)(MODE_10 | (flash_bank << 24) |
+ (flash_add >> DeviceInfo.nBitsInPageDataSize)), 0x42);
+ ddma_trans(read_data, flash_add, flash_bank, 0, NumPages);
+
+ ecc_done_OR_dma_comp = 0;
+ while (1) {
+ if (ioread32(FlashReg + ECC_ENABLE)) {
+ while (!ioread32(FlashReg + intr_status))
+ ;
+
+ if (ioread32(FlashReg + intr_status) &
+ INTR_STATUS0__ECC_ERR) {
+ iowrite32(INTR_STATUS0__ECC_ERR,
+ FlashReg + intr_status);
+ status = do_ecc_new(flash_bank,
+ read_data, block, page);
+ } else if (ioread32(FlashReg + intr_status) &
+ INTR_STATUS0__DMA_CMD_COMP) {
+ iowrite32(INTR_STATUS0__DMA_CMD_COMP,
+ FlashReg + intr_status);
+
+ if (1 == ecc_done_OR_dma_comp)
+ break;
+
+ ecc_done_OR_dma_comp = 1;
+ } else if (ioread32(FlashReg + intr_status) &
+ INTR_STATUS0__ECC_TRANSACTION_DONE) {
+ iowrite32(
+ INTR_STATUS0__ECC_TRANSACTION_DONE,
+ FlashReg + intr_status);
+
+ if (1 == ecc_done_OR_dma_comp)
+ break;
+
+ ecc_done_OR_dma_comp = 1;
+ }
+ } else {
+ while (!(ioread32(FlashReg + intr_status) &
+ INTR_STATUS0__DMA_CMD_COMP))
+ ;
+
+ iowrite32(INTR_STATUS0__DMA_CMD_COMP,
+ FlashReg + intr_status);
+ break;
+ }
+
+ iowrite32((~INTR_STATUS0__ECC_ERR) &
+ (~INTR_STATUS0__ECC_TRANSACTION_DONE) &
+ (~INTR_STATUS0__DMA_CMD_COMP),
+ FlashReg + intr_status);
+
+ }
+
+ iowrite32(ioread32(FlashReg + intr_status),
+ FlashReg + intr_status);
+
+ iowrite32(0, FlashReg + DMA_ENABLE);
+
+ while ((ioread32(FlashReg + DMA_ENABLE) & DMA_ENABLE__FLAG))
+ ;
+ }
+ return status;
+}
+
+u16 NAND_Read_Page_Main(u8 *read_data, u32 block, u16 page,
+ u16 page_count)
+{
+ u32 status = PASS;
+ u64 flash_add;
+ u32 intr_status = 0;
+ u32 flash_bank;
+ u32 intr_status_addresses[4] = {INTR_STATUS0,
+ INTR_STATUS1, INTR_STATUS2, INTR_STATUS3};
+#if DDMA
+ int ret;
+#else
+ u32 i;
+#endif
+
+ nand_dbg_print(NAND_DBG_DEBUG, "%s, Line %d, Function: %s\n",
+ __FILE__, __LINE__, __func__);
+
+ status = Boundary_Check_Block_Page(block, page, page_count);
+ if (status != PASS)
+ return status;
+
+ flash_add = (u64)(block % (DeviceInfo.wTotalBlocks / totalUsedBanks))
+ * DeviceInfo.wBlockDataSize +
+ (u64)page * DeviceInfo.wPageDataSize;
+ flash_bank = block / (DeviceInfo.wTotalBlocks / totalUsedBanks);
+
+ iowrite32(0, FlashReg + TRANSFER_SPARE_REG);
+
+ intr_status = intr_status_addresses[flash_bank];
+ iowrite32(ioread32(FlashReg + intr_status), FlashReg + intr_status);
+
+ if (page_count > 1) {
+ if (ioread32(FlashReg + MULTIPLANE_OPERATION))
+ status = NAND_Multiplane_Read(read_data,
+ block, page, page_count);
+ else
+ status = NAND_Pipeline_Read_Ahead(read_data,
+ block, page, page_count);
+ return status;
+ }
+
+#if DDMA
+ iowrite32(1, FlashReg + DMA_ENABLE);
+ while (!(ioread32(FlashReg + DMA_ENABLE) & DMA_ENABLE__FLAG))
+ ;
+
+ iowrite32(0, FlashReg + TRANSFER_SPARE_REG);
+ iowrite32(ioread32(FlashReg + intr_status), FlashReg + intr_status);
+
+ /* Fill the mrst_nand_info structure */
+ info.state = INT_READ_PAGE_MAIN;
+ info.read_data = read_data;
+ info.flash_bank = flash_bank;
+ info.block = block;
+ info.page = page;
+ info.ret = PASS;
+
+ ddma_trans(read_data, flash_add, flash_bank, 0, 1);
+
+ iowrite32(1, FlashReg + GLOBAL_INT_ENABLE); /* Enable Interrupt */
+
+ ret = wait_for_completion_timeout(&info.complete, 10 * HZ);
+ if (!ret)
+ printk(KERN_ERR "Wait for completion timeout "
+ "in %s, Line %d\n", __FILE__, __LINE__);
+ status = info.ret;
+
+ iowrite32(ioread32(FlashReg + intr_status), FlashReg + intr_status);
+
+ iowrite32(0, FlashReg + DMA_ENABLE);
+ while ((ioread32(FlashReg + DMA_ENABLE) & DMA_ENABLE__FLAG))
+ ;
+#else
+ index_addr((u32)(MODE_10 | (flash_bank << 24) |
+ (flash_add >> DeviceInfo.nBitsInPageDataSize)),
+ 0x42);
+ index_addr((u32)(MODE_10 | (flash_bank << 24) |
+ (flash_add >> DeviceInfo.nBitsInPageDataSize)),
+ 0x2000 | page_count);
+
+ while (!(ioread32(FlashReg + intr_status) & INTR_STATUS0__LOAD_COMP))
+ ;
+
+ iowrite32((u32)(MODE_01 | (flash_bank << 24) |
+ (flash_add >> DeviceInfo.nBitsInPageDataSize)), FlashMem);
+
+ for (i = 0; i < DeviceInfo.wPageDataSize / 4; i++)
+ *(((u32 *)read_data) + i) = ioread32(FlashMem + 0x10);
+
+ if (ioread32(FlashReg + ECC_ENABLE)) {
+ while (!(ioread32(FlashReg + intr_status) &
+ (INTR_STATUS0__ECC_TRANSACTION_DONE |
+ INTR_STATUS0__ECC_ERR)))
+ ;
+ if (ioread32(FlashReg + intr_status) & INTR_STATUS0__ECC_ERR) {
+ iowrite32(INTR_STATUS0__ECC_ERR,
+ FlashReg + intr_status);
+ status = do_ecc_new(flash_bank, read_data,
+ block, page);
+ }
+
+ if (ioread32(FlashReg + intr_status) &
+ INTR_STATUS0__ECC_TRANSACTION_DONE &
+ INTR_STATUS0__ECC_ERR)
+ iowrite32(INTR_STATUS0__ECC_TRANSACTION_DONE |
+ INTR_STATUS0__ECC_ERR,
+ FlashReg + intr_status);
+ else if (ioread32(FlashReg + intr_status) &
+ INTR_STATUS0__ECC_TRANSACTION_DONE)
+ iowrite32(INTR_STATUS0__ECC_TRANSACTION_DONE,
+ FlashReg + intr_status);
+ else if (ioread32(FlashReg + intr_status) &
+ INTR_STATUS0__ECC_ERR)
+ iowrite32(INTR_STATUS0__ECC_ERR,
+ FlashReg + intr_status);
+ }
+
+#endif
+
+ return status;
+}
+
+void Conv_Spare_Data_Log2Phy_Format(u8 *data)
+{
+ int i;
+ const u32 spareFlagBytes = DeviceInfo.wNumPageSpareFlag;
+ const u32 PageSpareSize = DeviceInfo.wPageSpareSize;
+
+ if (ioread32(FlashReg + ECC_ENABLE)) {
+ for (i = spareFlagBytes - 1; i >= 0; i++)
+ data[PageSpareSize - spareFlagBytes + i] = data[i];
+ }
+}
+
+void Conv_Spare_Data_Phy2Log_Format(u8 *data)
+{
+ int i;
+ const u32 spareFlagBytes = DeviceInfo.wNumPageSpareFlag;
+ const u32 PageSpareSize = DeviceInfo.wPageSpareSize;
+
+ if (ioread32(FlashReg + ECC_ENABLE)) {
+ for (i = 0; i < spareFlagBytes; i++)
+ data[i] = data[PageSpareSize - spareFlagBytes + i];
+ }
+}
+
+
+void Conv_Main_Spare_Data_Log2Phy_Format(u8 *data, u16 page_count)
+{
+ const u32 PageSize = DeviceInfo.wPageSize;
+ const u32 PageDataSize = DeviceInfo.wPageDataSize;
+ const u32 eccBytes = DeviceInfo.wECCBytesPerSector;
+ const u32 spareSkipBytes = DeviceInfo.wSpareSkipBytes;
+ const u32 spareFlagBytes = DeviceInfo.wNumPageSpareFlag;
+ u32 eccSectorSize;
+ u32 page_offset;
+ int i, j;
+
+ eccSectorSize = ECC_SECTOR_SIZE * (DeviceInfo.wDevicesConnected);
+ if (ioread32(FlashReg + ECC_ENABLE)) {
+ while (page_count > 0) {
+ page_offset = (page_count - 1) * PageSize;
+ j = (DeviceInfo.wPageDataSize / eccSectorSize);
+ for (i = spareFlagBytes - 1; i >= 0; i--)
+ data[page_offset +
+ (eccSectorSize + eccBytes) * j + i] =
+ data[page_offset + PageDataSize + i];
+ for (j--; j >= 1; j--) {
+ for (i = eccSectorSize - 1; i >= 0; i--)
+ data[page_offset +
+ (eccSectorSize + eccBytes) * j + i] =
+ data[page_offset +
+ eccSectorSize * j + i];
+ }
+ for (i = (PageSize - spareSkipBytes) - 1;
+ i >= PageDataSize; i--)
+ data[page_offset + i + spareSkipBytes] =
+ data[page_offset + i];
+ page_count--;
+ }
+ }
+}
+
+void Conv_Main_Spare_Data_Phy2Log_Format(u8 *data, u16 page_count)
+{
+ const u32 PageSize = DeviceInfo.wPageSize;
+ const u32 PageDataSize = DeviceInfo.wPageDataSize;
+ const u32 eccBytes = DeviceInfo.wECCBytesPerSector;
+ const u32 spareSkipBytes = DeviceInfo.wSpareSkipBytes;
+ const u32 spareFlagBytes = DeviceInfo.wNumPageSpareFlag;
+ u32 eccSectorSize;
+ u32 page_offset;
+ int i, j;
+
+ eccSectorSize = ECC_SECTOR_SIZE * (DeviceInfo.wDevicesConnected);
+ if (ioread32(FlashReg + ECC_ENABLE)) {
+ while (page_count > 0) {
+ page_offset = (page_count - 1) * PageSize;
+ for (i = PageDataSize;
+ i < PageSize - spareSkipBytes;
+ i++)
+ data[page_offset + i] =
+ data[page_offset + i +
+ spareSkipBytes];
+ for (j = 1;
+ j < DeviceInfo.wPageDataSize / eccSectorSize;
+ j++) {
+ for (i = 0; i < eccSectorSize; i++)
+ data[page_offset +
+ eccSectorSize * j + i] =
+ data[page_offset +
+ (eccSectorSize + eccBytes) * j
+ + i];
+ }
+ for (i = 0; i < spareFlagBytes; i++)
+ data[page_offset + PageDataSize + i] =
+ data[page_offset +
+ (eccSectorSize + eccBytes) * j + i];
+ page_count--;
+ }
+ }
+}
+
+u16 NAND_Multiplane_Read(u8 *read_data, u32 block, u16 page,
+ u16 page_count)
+{
+ u32 status = PASS;
+ u32 NumPages = page_count;
+ u64 flash_add;
+ u32 flash_bank;
+ u32 intr_status = 0;
+ u32 intr_status_addresses[4] = {INTR_STATUS0,
+ INTR_STATUS1, INTR_STATUS2, INTR_STATUS3};
+
+#if DDMA
+ u32 ecc_done_OR_dma_comp;
+#else
+ u32 PageSize = DeviceInfo.wPageDataSize;
+ u32 sector_count = 0;
+ u32 SectorStart, SectorEnd;
+ u32 bSectorsPerPage = 4;
+ u32 i, page_num = 0;
+ u32 plane = 0;
+ u8 *read_data_l = read_data;
+#endif
+
+ nand_dbg_print(NAND_DBG_WARN, "%s, Line %d, Function: %s\n",
+ __FILE__, __LINE__, __func__);
+
+ status = Boundary_Check_Block_Page(block, page, page_count);
+
+ flash_add = (u64)(block % (DeviceInfo.wTotalBlocks / totalUsedBanks))
+ * DeviceInfo.wBlockDataSize +
+ (u64)page * DeviceInfo.wPageDataSize;
+
+ flash_bank = block / (DeviceInfo.wTotalBlocks / totalUsedBanks);
+
+ if (status == PASS) {
+ intr_status = intr_status_addresses[flash_bank];
+ iowrite32(ioread32(FlashReg + intr_status),
+ FlashReg + intr_status);
+
+ iowrite32(0, FlashReg + TRANSFER_SPARE_REG);
+ iowrite32(0x01, FlashReg + MULTIPLANE_OPERATION);
+#if DDMA
+
+ iowrite32(1, FlashReg + DMA_ENABLE);
+ while (!(ioread32(FlashReg + DMA_ENABLE) & DMA_ENABLE__FLAG))
+ ;
+ index_addr((u32)(MODE_10 | (flash_bank << 24) |
+ (flash_add >> DeviceInfo.nBitsInPageDataSize)), 0x42);
+ ddma_trans(read_data, flash_add, flash_bank, 0, NumPages);
+
+ ecc_done_OR_dma_comp = 0;
+ while (1) {
+ if (ioread32(FlashReg + ECC_ENABLE)) {
+ while (!ioread32(FlashReg + intr_status))
+ ;
+
+ if (ioread32(FlashReg + intr_status) &
+ INTR_STATUS0__ECC_ERR) {
+ iowrite32(INTR_STATUS0__ECC_ERR,
+ FlashReg + intr_status);
+ status = do_ecc_new(flash_bank,
+ read_data, block, page);
+ } else if (ioread32(FlashReg + intr_status) &
+ INTR_STATUS0__DMA_CMD_COMP) {
+ iowrite32(INTR_STATUS0__DMA_CMD_COMP,
+ FlashReg + intr_status);
+
+ if (1 == ecc_done_OR_dma_comp)
+ break;
+
+ ecc_done_OR_dma_comp = 1;
+ } else if (ioread32(FlashReg + intr_status) &
+ INTR_STATUS0__ECC_TRANSACTION_DONE) {
+ iowrite32(
+ INTR_STATUS0__ECC_TRANSACTION_DONE,
+ FlashReg + intr_status);
+
+ if (1 == ecc_done_OR_dma_comp)
+ break;
+
+ ecc_done_OR_dma_comp = 1;
+ }
+ } else {
+ while (!(ioread32(FlashReg + intr_status) &
+ INTR_STATUS0__DMA_CMD_COMP))
+ ;
+ iowrite32(INTR_STATUS0__DMA_CMD_COMP,
+ FlashReg + intr_status);
+ break;
+ }
+
+ iowrite32((~INTR_STATUS0__ECC_ERR) &
+ (~INTR_STATUS0__ECC_TRANSACTION_DONE) &
+ (~INTR_STATUS0__DMA_CMD_COMP),
+ FlashReg + intr_status);
+
+ }
+
+ iowrite32(ioread32(FlashReg + intr_status),
+ FlashReg + intr_status);
+
+ iowrite32(0, FlashReg + DMA_ENABLE);
+
+ while ((ioread32(FlashReg + DMA_ENABLE) & DMA_ENABLE__FLAG))
+ ;
+
+ iowrite32(0, FlashReg + MULTIPLANE_OPERATION);
+
+#else
+
+ if (ioread32(FlashReg + ECC_ENABLE))
+ iowrite32(INTR_STATUS0__ECC_ERR,
+ FlashReg + intr_status);
+
+ index_addr((u32)(MODE_10 | (flash_bank << 24) |
+ (flash_add >> DeviceInfo.nBitsInPageDataSize)),
+ 0x42);
+ index_addr((u32)(MODE_10 | (flash_bank << 24) |
+ (flash_add >> DeviceInfo.nBitsInPageDataSize)),
+ 0x2000 | page_count);
+
+ while (NumPages > 0) {
+ if (plane == 0) {
+ iowrite32((u32)(MODE_01 | (flash_bank << 24) |
+ ((flash_add +
+ page_num * DeviceInfo.wPageDataSize)
+ >> DeviceInfo.nBitsInPageDataSize)),
+ FlashMem);
+ plane = 1;
+ } else {
+ iowrite32((u32)(MODE_01 | (flash_bank << 24) |
+ ((flash_add +
+ DeviceInfo.wBlockDataSize +
+ page_num * DeviceInfo.wPageDataSize)
+ >> DeviceInfo.nBitsInPageDataSize)),
+ FlashMem);
+ plane = 0;
+ }
+
+ for (sector_count = 0; sector_count < bSectorsPerPage;
+ sector_count++) {
+ SectorStart = sector_count *
+ (DeviceInfo.wPageDataSize /
+ (4 * bSectorsPerPage));
+ SectorEnd = (sector_count + 1) *
+ (DeviceInfo.wPageDataSize /
+ (4 * bSectorsPerPage));
+
+ for (i = SectorStart; i < SectorEnd; i++)
+ *(((u32 *)read_data_l) + i) =
+ ioread32(FlashMem + 0x10);
+
+ if (ioread32(FlashReg + ECC_ENABLE)) {
+ if (ioread32(FlashReg + intr_status) &
+ INTR_STATUS0__ECC_ERR) {
+ iowrite32(
+ INTR_STATUS0__ECC_ERR,
+ FlashReg + intr_status);
+ status = do_ecc_new(
+ flash_bank,
+ read_data,
+ block, page);
+ }
+ }
+ }
+
+ if (plane == 0)
+ page_num++;
+
+ read_data_l += PageSize;
+ --NumPages;
+ }
+
+ if (ioread32(FlashReg + ECC_ENABLE)) {
+ while (!(ioread32(FlashReg + intr_status) &
+ (INTR_STATUS0__ECC_TRANSACTION_DONE |
+ INTR_STATUS0__ECC_ERR)))
+ ;
+
+ if (ioread32(FlashReg + intr_status) &
+ INTR_STATUS0__ECC_ERR) {
+ iowrite32(INTR_STATUS0__ECC_ERR,
+ FlashReg + intr_status);
+ status = do_ecc_new(flash_bank,
+ read_data, block, page);
+ while (!(ioread32(FlashReg + intr_status) &
+ INTR_STATUS0__ECC_TRANSACTION_DONE))
+ ;
+
+ iowrite32(INTR_STATUS0__ECC_TRANSACTION_DONE,
+ FlashReg + intr_status);
+ } else if (ioread32(FlashReg + intr_status) &
+ INTR_STATUS0__ECC_TRANSACTION_DONE) {
+ iowrite32(INTR_STATUS0__ECC_TRANSACTION_DONE,
+ FlashReg + intr_status);
+ }
+ }
+
+ iowrite32(0, FlashReg + MULTIPLANE_OPERATION);
+
+#endif
+ }
+ return status;
+}
+
+u16 NAND_Pipeline_Read_Ahead(u8 *read_data, u32 block,
+ u16 page, u16 page_count)
+{
+ u32 status = PASS;
+ u32 NumPages = page_count;
+ u64 flash_add;
+ u32 flash_bank;
+ u32 intr_status = 0;
+ u32 intr_status_addresses[4] = {INTR_STATUS0,
+ INTR_STATUS1, INTR_STATUS2, INTR_STATUS3};
+#if DDMA
+ int ret;
+#else
+ u32 PageSize = DeviceInfo.wPageDataSize;
+ u32 sector_count = 0;
+ u32 SectorStart, SectorEnd;
+ u32 bSectorsPerPage = 4;
+ u32 i, page_num = 0;
+ u8 *read_data_l = read_data;
+#endif
+ nand_dbg_print(NAND_DBG_DEBUG, "%s, Line %d, Function: %s\n",
+ __FILE__, __LINE__, __func__);
+
+ status = Boundary_Check_Block_Page(block, page, page_count);
+
+ if (page_count < 2)
+ status = FAIL;
+
+ if (status != PASS)
+ return status;
+
+ flash_add = (u64)(block % (DeviceInfo.wTotalBlocks / totalUsedBanks))
+ *DeviceInfo.wBlockDataSize +
+ (u64)page * DeviceInfo.wPageDataSize;
+
+ flash_bank = block / (DeviceInfo.wTotalBlocks / totalUsedBanks);
+
+ intr_status = intr_status_addresses[flash_bank];
+ iowrite32(ioread32(FlashReg + intr_status), FlashReg + intr_status);
+
+#if DDMA
+ iowrite32(1, FlashReg + DMA_ENABLE);
+ while (!(ioread32(FlashReg + DMA_ENABLE) & DMA_ENABLE__FLAG))
+ ;
+
+ iowrite32(0, FlashReg + TRANSFER_SPARE_REG);
+
+ /* Fill the mrst_nand_info structure */
+ info.state = INT_PIPELINE_READ_AHEAD;
+ info.read_data = read_data;
+ info.flash_bank = flash_bank;
+ info.block = block;
+ info.page = page;
+ info.ret = PASS;
+
+ index_addr((u32)(MODE_10 | (flash_bank << 24) |
+ (flash_add >> DeviceInfo.nBitsInPageDataSize)), 0x42);
+
+ ddma_trans(read_data, flash_add, flash_bank, 0, NumPages);
+
+ iowrite32(1, FlashReg + GLOBAL_INT_ENABLE); /* Enable Interrupt */
+
+ ret = wait_for_completion_timeout(&info.complete, 10 * HZ);
+ if (!ret)
+ printk(KERN_ERR "Wait for completion timeout "
+ "in %s, Line %d\n", __FILE__, __LINE__);
+
+ status = info.ret;
+
+ iowrite32(ioread32(FlashReg + intr_status), FlashReg + intr_status);
+
+ iowrite32(0, FlashReg + DMA_ENABLE);
+
+ while ((ioread32(FlashReg + DMA_ENABLE) & DMA_ENABLE__FLAG))
+ ;
+
+#else
+ iowrite32(0, FlashReg + TRANSFER_SPARE_REG);
+
+ iowrite32(ioread32(FlashReg + intr_status), FlashReg + intr_status);
+
+ index_addr((u32)(MODE_10 | (flash_bank << 24) |
+ (flash_add >> DeviceInfo.nBitsInPageDataSize)), 0x42);
+
+ index_addr((u32)(MODE_10 | (flash_bank << 24) |
+ (flash_add >> DeviceInfo.nBitsInPageDataSize)),
+ 0x2000 | NumPages);
+
+ while (NumPages > 0) {
+ iowrite32((u32)(MODE_01 | (flash_bank << 24) |
+ ((flash_add + page_num * DeviceInfo.wPageDataSize) >>
+ DeviceInfo.nBitsInPageDataSize)), FlashMem);
+
+ for (sector_count = 0; sector_count < bSectorsPerPage;
+ sector_count++) {
+ SectorStart = sector_count *
+ (DeviceInfo.wPageDataSize /
+ (4 * bSectorsPerPage));
+ SectorEnd = (sector_count + 1) *
+ (DeviceInfo.wPageDataSize /
+ (4 * bSectorsPerPage));
+
+ for (i = SectorStart; i < SectorEnd; i++)
+ *(((u32 *)read_data_l) + i) =
+ ioread32(FlashMem + 0x10);
+
+ if (ioread32(FlashReg + ECC_ENABLE)) {
+ if (ioread32(FlashReg + intr_status) &
+ INTR_STATUS0__ECC_ERR) {
+ iowrite32(INTR_STATUS0__ECC_ERR,
+ FlashReg + intr_status);
+ status = do_ecc_new(flash_bank,
+ read_data, block, page);
+ }
+ }
+ }
+
+ read_data_l += PageSize;
+ --NumPages;
+ page_num++;
+ }
+
+ if (ioread32(FlashReg + ECC_ENABLE)) {
+ while (!(ioread32(FlashReg + intr_status) &
+ (INTR_STATUS0__ECC_TRANSACTION_DONE |
+ INTR_STATUS0__ECC_ERR)))
+ ;
+
+ if (ioread32(FlashReg + intr_status) &
+ INTR_STATUS0__ECC_ERR) {
+ iowrite32(INTR_STATUS0__ECC_ERR,
+ FlashReg + intr_status);
+ status = do_ecc_new(flash_bank, read_data,
+ block, page);
+ while (!(ioread32(FlashReg + intr_status) &
+ INTR_STATUS0__ECC_TRANSACTION_DONE))
+ ;
+
+ iowrite32(INTR_STATUS0__ECC_TRANSACTION_DONE,
+ FlashReg + intr_status);
+ } else if (ioread32(FlashReg + intr_status) &
+ INTR_STATUS0__ECC_TRANSACTION_DONE) {
+ iowrite32(INTR_STATUS0__ECC_TRANSACTION_DONE,
+ FlashReg + intr_status);
+ }
+ }
+#endif
+
+ return status;
+}
+
+
+#endif
+#if FLASH_NAND
+
+u16 NAND_Write_Page_Main(u8 *write_data, u32 block, u16 page,
+ u16 page_count)
+{
+ u32 status = PASS;
+ u64 flash_add;
+ u32 intr_status = 0;
+ u32 flash_bank;
+ u32 intr_status_addresses[4] = {INTR_STATUS0,
+ INTR_STATUS1, INTR_STATUS2, INTR_STATUS3};
+#if DDMA
+ int ret;
+#else
+ u32 i;
+#endif
+
+ nand_dbg_print(NAND_DBG_DEBUG, "%s, Line %d, Function: %s\n",
+ __FILE__, __LINE__, __func__);
+
+ status = Boundary_Check_Block_Page(block, page, page_count);
+ if (status != PASS)
+ return status;
+
+ flash_add = (u64)(block % (DeviceInfo.wTotalBlocks / totalUsedBanks))
+ * DeviceInfo.wBlockDataSize +
+ (u64)page * DeviceInfo.wPageDataSize;
+
+ flash_bank = block / (DeviceInfo.wTotalBlocks / totalUsedBanks);
+
+ intr_status = intr_status_addresses[flash_bank];
+
+ iowrite32(0, FlashReg + TRANSFER_SPARE_REG);
+
+ iowrite32(INTR_STATUS0__PROGRAM_COMP |
+ INTR_STATUS0__PROGRAM_FAIL, FlashReg + intr_status);
+
+ if (page_count > 1) {
+ if (ioread32(FlashReg + MULTIPLANE_OPERATION))
+ status = NAND_Multiplane_Write(write_data,
+ block, page, page_count);
+ else
+ status = NAND_Pipeline_Write_Ahead(write_data,
+ block, page, page_count);
+ return status;
+ }
+
+#if DDMA
+ iowrite32(1, FlashReg + DMA_ENABLE);
+ while (!(ioread32(FlashReg + DMA_ENABLE) & DMA_ENABLE__FLAG))
+ ;
+
+ iowrite32(0, FlashReg + TRANSFER_SPARE_REG);
+
+ iowrite32(ioread32(FlashReg + intr_status), FlashReg + intr_status);
+
+ /* Fill the mrst_nand_info structure */
+ info.state = INT_WRITE_PAGE_MAIN;
+ info.write_data = write_data;
+ info.flash_bank = flash_bank;
+ info.block = block;
+ info.page = page;
+ info.ret = PASS;
+
+ ddma_trans(write_data, flash_add, flash_bank, 1, 1);
+
+ iowrite32(1, FlashReg + GLOBAL_INT_ENABLE); /* Enable interrupt */
+
+ ret = wait_for_completion_timeout(&info.complete, 10 * HZ);
+ if (!ret)
+ printk(KERN_ERR "Wait for completion timeout "
+ "in %s, Line %d\n", __FILE__, __LINE__);
+
+ status = info.ret;
+
+ iowrite32(ioread32(FlashReg + intr_status), FlashReg + intr_status);
+
+ iowrite32(0, FlashReg + DMA_ENABLE);
+ while (ioread32(FlashReg + DMA_ENABLE) & DMA_ENABLE__FLAG)
+ ;
+
+#else
+ iowrite32((u32)(MODE_01 | (flash_bank << 24) |
+ (flash_add >> DeviceInfo.nBitsInPageDataSize)), FlashMem);
+
+ for (i = 0; i < DeviceInfo.wPageDataSize / 4; i++)
+ iowrite32(*(((u32 *)write_data) + i), FlashMem + 0x10);
+
+ while (!(ioread32(FlashReg + intr_status) &
+ (INTR_STATUS0__PROGRAM_COMP | INTR_STATUS0__PROGRAM_FAIL)))
+ ;
+
+ if (ioread32(FlashReg + intr_status) & INTR_STATUS0__PROGRAM_FAIL)
+ status = FAIL;
+
+ iowrite32(INTR_STATUS0__PROGRAM_COMP |
+ INTR_STATUS0__PROGRAM_FAIL, FlashReg + intr_status);
+
+#endif
+
+ return status;
+}
+
+void NAND_ECC_Ctrl(int enable)
+{
+ if (enable) {
+ nand_dbg_print(NAND_DBG_WARN,
+ "Will enable ECC in %s, Line %d, Function: %s\n",
+ __FILE__, __LINE__, __func__);
+ iowrite32(1, FlashReg + ECC_ENABLE);
+ } else {
+ nand_dbg_print(NAND_DBG_WARN,
+ "Will disable ECC in %s, Line %d, Function: %s\n",
+ __FILE__, __LINE__, __func__);
+ iowrite32(0, FlashReg + ECC_ENABLE);
+ }
+}
+
+u32 NAND_Memory_Pool_Size(void)
+{
+ return MAX_PAGE_MAINSPARE_AREA;
+}
+
+int NAND_Mem_Config(u8 *pMem)
+{
+ return 0;
+}
+
+u16 NAND_Write_Page_Main_Spare(u8 *write_data, u32 block,
+ u16 page, u16 page_count)
+{
+ u32 status = PASS;
+ u32 i, j, page_num = 0;
+ u32 PageSize = DeviceInfo.wPageSize;
+ u32 PageDataSize = DeviceInfo.wPageDataSize;
+ u32 eccBytes = DeviceInfo.wECCBytesPerSector;
+ u32 spareFlagBytes = DeviceInfo.wNumPageSpareFlag;
+ u32 spareSkipBytes = DeviceInfo.wSpareSkipBytes;
+ u64 flash_add;
+ u32 eccSectorSize;
+ u32 flash_bank;
+ u32 intr_status = 0;
+ u32 intr_status_addresses[4] = {INTR_STATUS0,
+ INTR_STATUS1, INTR_STATUS2, INTR_STATUS3};
+ u8 *page_main_spare;
+
+ nand_dbg_print(NAND_DBG_WARN, "%s, Line %d, Function: %s\n",
+ __FILE__, __LINE__, __func__);
+
+ page_main_spare = kmalloc(DeviceInfo.wPageSize, GFP_ATOMIC);
+ if (!page_main_spare) {
+ printk(KERN_ERR "Failed to kmalloc memory in %s Line %d, exit.\n",
+ __FILE__, __LINE__);
+ return FAIL;
+ }
+
+ eccSectorSize = ECC_SECTOR_SIZE * (DeviceInfo.wDevicesConnected);
+
+ status = Boundary_Check_Block_Page(block, page, page_count);
+
+ flash_bank = block / (DeviceInfo.wTotalBlocks / totalUsedBanks);
+
+ if (status == PASS) {
+ intr_status = intr_status_addresses[flash_bank];
+
+ iowrite32(1, FlashReg + TRANSFER_SPARE_REG);
+
+ while ((status != FAIL) && (page_count > 0)) {
+ flash_add = (u64)(block %
+ (DeviceInfo.wTotalBlocks / totalUsedBanks)) *
+ DeviceInfo.wBlockDataSize +
+ (u64)page * DeviceInfo.wPageDataSize;
+
+ iowrite32(ioread32(FlashReg + intr_status),
+ FlashReg + intr_status);
+
+ iowrite32((u32)(MODE_01 | (flash_bank << 24) |
+ (flash_add >>
+ DeviceInfo.nBitsInPageDataSize)),
+ FlashMem);
+
+ if (ioread32(FlashReg + ECC_ENABLE)) {
+ for (j = 0;
+ j <
+ DeviceInfo.wPageDataSize / eccSectorSize;
+ j++) {
+ for (i = 0; i < eccSectorSize; i++)
+ page_main_spare[(eccSectorSize +
+ eccBytes) * j +
+ i] =
+ write_data[eccSectorSize *
+ j + i];
+
+ for (i = 0; i < eccBytes; i++)
+ page_main_spare[(eccSectorSize +
+ eccBytes) * j +
+ eccSectorSize +
+ i] =
+ write_data[PageDataSize +
+ spareFlagBytes +
+ eccBytes * j +
+ i];
+ }
+
+ for (i = 0; i < spareFlagBytes; i++)
+ page_main_spare[(eccSectorSize +
+ eccBytes) * j + i] =
+ write_data[PageDataSize + i];
+
+ for (i = PageSize - 1; i >= PageDataSize +
+ spareSkipBytes; i--)
+ page_main_spare[i] = page_main_spare[i -
+ spareSkipBytes];
+
+ for (i = PageDataSize; i < PageDataSize +
+ spareSkipBytes; i++)
+ page_main_spare[i] = 0xff;
+
+ for (i = 0; i < PageSize / 4; i++)
+ iowrite32(
+ *((u32 *)page_main_spare + i),
+ FlashMem + 0x10);
+ } else {
+
+ for (i = 0; i < PageSize / 4; i++)
+ iowrite32(*((u32 *)write_data + i),
+ FlashMem + 0x10);
+ }
+
+ while (!(ioread32(FlashReg + intr_status) &
+ (INTR_STATUS0__PROGRAM_COMP |
+ INTR_STATUS0__PROGRAM_FAIL)))
+ ;
+
+ if (ioread32(FlashReg + intr_status) &
+ INTR_STATUS0__PROGRAM_FAIL)
+ status = FAIL;
+
+ iowrite32(ioread32(FlashReg + intr_status),
+ FlashReg + intr_status);
+
+ page_num++;
+ page_count--;
+ write_data += PageSize;
+ }
+
+ iowrite32(0, FlashReg + TRANSFER_SPARE_REG);
+ }
+
+ kfree(page_main_spare);
+ return status;
+}
+
+u16 NAND_Read_Page_Main_Spare(u8 *read_data, u32 block, u16 page,
+ u16 page_count)
+{
+ u32 status = PASS;
+ u32 i, j;
+ u64 flash_add = 0;
+ u32 PageSize = DeviceInfo.wPageSize;
+ u32 PageDataSize = DeviceInfo.wPageDataSize;
+ u32 PageSpareSize = DeviceInfo.wPageSpareSize;
+ u32 eccBytes = DeviceInfo.wECCBytesPerSector;
+ u32 spareFlagBytes = DeviceInfo.wNumPageSpareFlag;
+ u32 spareSkipBytes = DeviceInfo.wSpareSkipBytes;
+ u32 eccSectorSize;
+ u32 flash_bank;
+ u32 intr_status = 0;
+ u8 *read_data_l = read_data;
+ u32 intr_status_addresses[4] = {INTR_STATUS0,
+ INTR_STATUS1, INTR_STATUS2, INTR_STATUS3};
+ u8 *page_main_spare;
+
+ nand_dbg_print(NAND_DBG_WARN, "%s, Line %d, Function: %s\n",
+ __FILE__, __LINE__, __func__);
+
+ page_main_spare = kmalloc(DeviceInfo.wPageSize, GFP_ATOMIC);
+ if (!page_main_spare) {
+ printk(KERN_ERR "Failed to kmalloc memory in %s Line %d, exit.\n",
+ __FILE__, __LINE__);
+ return FAIL;
+ }
+
+ eccSectorSize = ECC_SECTOR_SIZE * (DeviceInfo.wDevicesConnected);
+
+ status = Boundary_Check_Block_Page(block, page, page_count);
+
+ flash_bank = block / (DeviceInfo.wTotalBlocks / totalUsedBanks);
+
+ if (status == PASS) {
+ intr_status = intr_status_addresses[flash_bank];
+
+ iowrite32(1, FlashReg + TRANSFER_SPARE_REG);
+
+ iowrite32(ioread32(FlashReg + intr_status),
+ FlashReg + intr_status);
+
+ while ((status != FAIL) && (page_count > 0)) {
+ flash_add = (u64)(block %
+ (DeviceInfo.wTotalBlocks / totalUsedBanks))
+ * DeviceInfo.wBlockDataSize +
+ (u64)page * DeviceInfo.wPageDataSize;
+
+ index_addr((u32)(MODE_10 | (flash_bank << 24) |
+ (flash_add >> DeviceInfo.nBitsInPageDataSize)),
+ 0x43);
+ index_addr((u32)(MODE_10 | (flash_bank << 24) |
+ (flash_add >> DeviceInfo.nBitsInPageDataSize)),
+ 0x2000 | page_count);
+
+ while (!(ioread32(FlashReg + intr_status) &
+ INTR_STATUS0__LOAD_COMP))
+ ;
+
+ iowrite32((u32)(MODE_01 | (flash_bank << 24) |
+ (flash_add >>
+ DeviceInfo.nBitsInPageDataSize)),
+ FlashMem);
+
+ for (i = 0; i < PageSize / 4; i++)
+ *(((u32 *)page_main_spare) + i) =
+ ioread32(FlashMem + 0x10);
+
+ if (ioread32(FlashReg + ECC_ENABLE)) {
+ for (i = PageDataSize; i < PageSize -
+ spareSkipBytes; i++)
+ page_main_spare[i] = page_main_spare[i +
+ spareSkipBytes];
+
+ for (j = 0;
+ j < DeviceInfo.wPageDataSize / eccSectorSize;
+ j++) {
+
+ for (i = 0; i < eccSectorSize; i++)
+ read_data_l[eccSectorSize * j +
+ i] =
+ page_main_spare[
+ (eccSectorSize +
+ eccBytes) * j + i];
+
+ for (i = 0; i < eccBytes; i++)
+ read_data_l[PageDataSize +
+ spareFlagBytes +
+ eccBytes * j + i] =
+ page_main_spare[
+ (eccSectorSize +
+ eccBytes) * j +
+ eccSectorSize + i];
+ }
+
+ for (i = 0; i < spareFlagBytes; i++)
+ read_data_l[PageDataSize + i] =
+ page_main_spare[(eccSectorSize +
+ eccBytes) * j + i];
+ } else {
+ for (i = 0; i < (PageDataSize + PageSpareSize);
+ i++)
+ read_data_l[i] = page_main_spare[i];
+
+ }
+
+ if (ioread32(FlashReg + ECC_ENABLE)) {
+ while (!(ioread32(FlashReg + intr_status) &
+ (INTR_STATUS0__ECC_TRANSACTION_DONE |
+ INTR_STATUS0__ECC_ERR)))
+ ;
+
+ if (ioread32(FlashReg + intr_status) &
+ INTR_STATUS0__ECC_ERR) {
+ iowrite32(INTR_STATUS0__ECC_ERR,
+ FlashReg + intr_status);
+ status = do_ecc_new(flash_bank,
+ read_data, block, page);
+ }
+
+ if (ioread32(FlashReg + intr_status) &
+ INTR_STATUS0__ECC_TRANSACTION_DONE &
+ INTR_STATUS0__ECC_ERR) {
+ iowrite32(INTR_STATUS0__ECC_ERR |
+ INTR_STATUS0__ECC_TRANSACTION_DONE,
+ FlashReg + intr_status);
+ } else if (ioread32(FlashReg + intr_status) &
+ INTR_STATUS0__ECC_TRANSACTION_DONE) {
+ iowrite32(
+ INTR_STATUS0__ECC_TRANSACTION_DONE,
+ FlashReg + intr_status);
+ } else if (ioread32(FlashReg + intr_status) &
+ INTR_STATUS0__ECC_ERR) {
+ iowrite32(INTR_STATUS0__ECC_ERR,
+ FlashReg + intr_status);
+ }
+ }
+
+ page++;
+ page_count--;
+ read_data_l += PageSize;
+ }
+ }
+
+ iowrite32(0, FlashReg + TRANSFER_SPARE_REG);
+
+ index_addr((u32)(MODE_10 | (flash_bank << 24) |
+ (flash_add >> DeviceInfo.nBitsInPageDataSize)), 0x42);
+
+ kfree(page_main_spare);
+ return status;
+}
+
+u16 NAND_Pipeline_Write_Ahead(u8 *write_data, u32 block,
+ u16 page, u16 page_count)
+{
+ u16 status = PASS;
+ u32 NumPages = page_count;
+ u64 flash_add;
+ u32 flash_bank;
+ u32 intr_status = 0;
+ u32 intr_status_addresses[4] = {INTR_STATUS0,
+ INTR_STATUS1, INTR_STATUS2, INTR_STATUS3};
+#if DDMA
+ int ret;
+#else
+ u32 PageSize = DeviceInfo.wPageDataSize;
+ u32 i, page_num = 0;
+#endif
+
+ nand_dbg_print(NAND_DBG_DEBUG, "%s, Line %d, Function: %s\n",
+ __FILE__, __LINE__, __func__);
+
+ status = Boundary_Check_Block_Page(block, page, page_count);
+
+ if (page_count < 2)
+ status = FAIL;
+
+ if (status != PASS)
+ return status;
+
+ flash_add = (u64)(block % (DeviceInfo.wTotalBlocks / totalUsedBanks))
+ * DeviceInfo.wBlockDataSize +
+ (u64)page * DeviceInfo.wPageDataSize;
+
+ flash_bank = block / (DeviceInfo.wTotalBlocks / totalUsedBanks);
+
+ intr_status = intr_status_addresses[flash_bank];
+ iowrite32(ioread32(FlashReg + intr_status), FlashReg + intr_status);
+
+#if DDMA
+ iowrite32(1, FlashReg + DMA_ENABLE);
+ while (!(ioread32(FlashReg + DMA_ENABLE) & DMA_ENABLE__FLAG))
+ ;
+
+ iowrite32(0, FlashReg + TRANSFER_SPARE_REG);
+
+ /* Fill the mrst_nand_info structure */
+ info.state = INT_PIPELINE_WRITE_AHEAD;
+ info.write_data = write_data;
+ info.flash_bank = flash_bank;
+ info.block = block;
+ info.page = page;
+ info.ret = PASS;
+
+ index_addr((u32)(MODE_10 | (flash_bank << 24) |
+ (flash_add >> DeviceInfo.nBitsInPageDataSize)), 0x42);
+
+ ddma_trans(write_data, flash_add, flash_bank, 1, NumPages);
+
+ iowrite32(1, FlashReg + GLOBAL_INT_ENABLE); /* Enable interrupt */
+
+ ret = wait_for_completion_timeout(&info.complete, 10 * HZ);
+ if (!ret)
+ printk(KERN_ERR "Wait for completion timeout "
+ "in %s, Line %d\n", __FILE__, __LINE__);
+
+ status = info.ret;
+
+ iowrite32(ioread32(FlashReg + intr_status), FlashReg + intr_status);
+
+ iowrite32(0, FlashReg + DMA_ENABLE);
+ while ((ioread32(FlashReg + DMA_ENABLE) & DMA_ENABLE__FLAG))
+ ;
+
+#else
+
+ iowrite32(0, FlashReg + TRANSFER_SPARE_REG);
+
+ index_addr((u32)(MODE_10 | (flash_bank << 24) |
+ (flash_add >> DeviceInfo.nBitsInPageDataSize)), 0x42);
+
+ index_addr((u32)(MODE_10 | (flash_bank << 24) |
+ (flash_add >> DeviceInfo.nBitsInPageDataSize)),
+ 0x2100 | NumPages);
+
+ while (NumPages > 0) {
+ iowrite32((u32)(MODE_01 | (flash_bank << 24) |
+ ((flash_add + page_num * DeviceInfo.wPageDataSize) >>
+ DeviceInfo.nBitsInPageDataSize)), FlashMem);
+
+ for (i = 0; i < DeviceInfo.wPageDataSize / 4; i++)
+ iowrite32(*((u32 *)write_data + i), FlashMem + 0x10);
+
+ while (!(ioread32(FlashReg + intr_status) &
+ INTR_STATUS0__INT_ACT))
+ ;
+
+ iowrite32(INTR_STATUS0__INT_ACT, FlashReg + intr_status);
+
+ write_data += PageSize;
+ --NumPages;
+ page_num++;
+ }
+
+ while (!(ioread32(FlashReg + intr_status) &
+ (INTR_STATUS0__PROGRAM_COMP | INTR_STATUS0__PROGRAM_FAIL)))
+ ;
+
+ if (ioread32(FlashReg + intr_status) & INTR_STATUS0__PROGRAM_FAIL)
+ status = FAIL;
+
+ iowrite32(INTR_STATUS0__PROGRAM_COMP | INTR_STATUS0__PROGRAM_FAIL,
+ FlashReg + intr_status);
+
+#endif
+
+ return status;
+}
+
+u16 NAND_Multiplane_Write(u8 *write_data, u32 block, u16 page,
+ u16 page_count)
+{
+ u16 status = PASS;
+ u32 NumPages = page_count;
+ u64 flash_add;
+ u32 flash_bank;
+ u32 intr_status = 0;
+ u32 intr_status_addresses[4] = {INTR_STATUS0,
+ INTR_STATUS1, INTR_STATUS2, INTR_STATUS3};
+#if DDMA
+ u16 status2 = PASS;
+ u32 t;
+#else
+ u32 PageSize = DeviceInfo.wPageDataSize;
+ u32 i, page_num = 0;
+ u32 plane = 0;
+#endif
+
+ nand_dbg_print(NAND_DBG_WARN, "%s, Line %d, Function: %s\n",
+ __FILE__, __LINE__, __func__);
+
+ status = Boundary_Check_Block_Page(block, page, page_count);
+ if (status != PASS)
+ return status;
+
+ flash_add = (u64)(block % (DeviceInfo.wTotalBlocks / totalUsedBanks))
+ * DeviceInfo.wBlockDataSize +
+ (u64)page * DeviceInfo.wPageDataSize;
+
+ flash_bank = block / (DeviceInfo.wTotalBlocks / totalUsedBanks);
+
+ intr_status = intr_status_addresses[flash_bank];
+ iowrite32(ioread32(FlashReg + intr_status), FlashReg + intr_status);
+
+ iowrite32(0, FlashReg + TRANSFER_SPARE_REG);
+ iowrite32(0x01, FlashReg + MULTIPLANE_OPERATION);
+
+#if DDMA
+
+ iowrite32(1, FlashReg + DMA_ENABLE);
+ while (!(ioread32(FlashReg + DMA_ENABLE) & DMA_ENABLE__FLAG))
+ ;
+
+ iowrite32(0, FlashReg + TRANSFER_SPARE_REG);
+
+ index_addr((u32)(MODE_10 | (flash_bank << 24) |
+ (flash_add >> DeviceInfo.nBitsInPageDataSize)), 0x42);
+
+ ddma_trans(write_data, flash_add, flash_bank, 1, NumPages);
+
+ while (1) {
+ while (!ioread32(FlashReg + intr_status))
+ ;
+
+ if (ioread32(FlashReg + intr_status) &
+ INTR_STATUS0__DMA_CMD_COMP) {
+ iowrite32(INTR_STATUS0__DMA_CMD_COMP,
+ FlashReg + intr_status);
+ status = PASS;
+ if (status2 == FAIL)
+ status = FAIL;
+ break;
+ } else if (ioread32(FlashReg + intr_status) &
+ INTR_STATUS0__PROGRAM_FAIL) {
+ status2 = FAIL;
+ status = FAIL;
+ t = ioread32(FlashReg + intr_status) &
+ INTR_STATUS0__PROGRAM_FAIL;
+ iowrite32(t, FlashReg + intr_status);
+ } else {
+ iowrite32((~INTR_STATUS0__PROGRAM_FAIL) &
+ (~INTR_STATUS0__DMA_CMD_COMP),
+ FlashReg + intr_status);
+ }
+ }
+
+ iowrite32(ioread32(FlashReg + intr_status), FlashReg + intr_status);
+
+ iowrite32(0, FlashReg + DMA_ENABLE);
+
+ while ((ioread32(FlashReg + DMA_ENABLE) & DMA_ENABLE__FLAG))
+ ;
+
+ iowrite32(0, FlashReg + MULTIPLANE_OPERATION);
+
+#else
+ iowrite32(0, FlashReg + TRANSFER_SPARE_REG);
+
+ index_addr((u32)(MODE_10 | (flash_bank << 24) |
+ (flash_add >> DeviceInfo.nBitsInPageDataSize)),
+ 0x42);
+ index_addr((u32)(MODE_10 | (flash_bank << 24) |
+ (flash_add >> DeviceInfo.nBitsInPageDataSize)),
+ 0x2100 | NumPages);
+
+ while (NumPages > 0) {
+ if (0 == plane) {
+ iowrite32((u32)(MODE_01 | (flash_bank << 24) |
+ ((flash_add +
+ page_num * DeviceInfo.wPageDataSize) >>
+ DeviceInfo.nBitsInPageDataSize)),
+ FlashMem);
+ plane = 1;
+ } else {
+ iowrite32((u32)(MODE_01 | (flash_bank << 24) |
+ ((flash_add + DeviceInfo.wBlockDataSize +
+ page_num * DeviceInfo.wPageDataSize) >>
+ DeviceInfo.nBitsInPageDataSize)),
+ FlashMem);
+ plane = 0;
+ }
+
+ for (i = 0; i < DeviceInfo.wPageDataSize / 4; i++)
+ iowrite32(*((u32 *)write_data + i),
+ FlashMem + 0x10);
+
+ write_data += PageSize;
+
+ if (0 == plane)
+ page_num++;
+
+ --NumPages;
+ }
+
+ while (!(ioread32(FlashReg + intr_status) &
+ (INTR_STATUS0__PROGRAM_COMP |
+ INTR_STATUS0__PROGRAM_FAIL)))
+ ;
+
+ if (ioread32(FlashReg + intr_status) & INTR_STATUS0__PROGRAM_FAIL)
+ status = FAIL;
+
+ iowrite32(INTR_STATUS0__PROGRAM_COMP | INTR_STATUS0__PROGRAM_FAIL,
+ FlashReg + intr_status);
+
+ iowrite32(0, FlashReg + MULTIPLANE_OPERATION);
+#endif
+
+ return status;
+}
+
+u16 NAND_LLD_Event_Status(void)
+{
+ nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
+ __FILE__, __LINE__, __func__);
+
+ return PASS;
+}
+
+static void handle_nand_int_read(struct mrst_nand_info *dev)
+{
+ u32 intr_status_addresses[4] = {INTR_STATUS0,
+ INTR_STATUS1, INTR_STATUS2, INTR_STATUS3};
+ u32 intr_status;
+ u32 ecc_done_OR_dma_comp = 0;
+
+ nand_dbg_print(NAND_DBG_DEBUG, "%s, Line %d, Function: %s\n",
+ __FILE__, __LINE__, __func__);
+
+ dev->ret = PASS;
+ intr_status = intr_status_addresses[dev->flash_bank];
+
+ while (1) {
+ if (ioread32(FlashReg + ECC_ENABLE)) {
+ if (ioread32(FlashReg + intr_status) &
+ INTR_STATUS0__ECC_ERR) {
+ iowrite32(INTR_STATUS0__ECC_ERR,
+ FlashReg + intr_status);
+ dev->ret = do_ecc_new(dev->flash_bank,
+ dev->read_data,
+ dev->block, dev->page);
+ } else if (ioread32(FlashReg + intr_status) &
+ INTR_STATUS0__DMA_CMD_COMP) {
+ iowrite32(INTR_STATUS0__DMA_CMD_COMP,
+ FlashReg + intr_status);
+ if (1 == ecc_done_OR_dma_comp)
+ break;
+ ecc_done_OR_dma_comp = 1;
+ } else if (ioread32(FlashReg + intr_status) &
+ INTR_STATUS0__ECC_TRANSACTION_DONE) {
+ iowrite32(INTR_STATUS0__ECC_TRANSACTION_DONE,
+ FlashReg + intr_status);
+ if (1 == ecc_done_OR_dma_comp)
+ break;
+ ecc_done_OR_dma_comp = 1;
+ }
+ } else {
+ if (ioread32(FlashReg + intr_status) &
+ INTR_STATUS0__DMA_CMD_COMP) {
+ iowrite32(INTR_STATUS0__DMA_CMD_COMP,
+ FlashReg + intr_status);
+ break;
+ } else {
+ printk(KERN_ERR "Illegal INTS "
+ "(offset addr 0x%x) value: 0x%x\n",
+ intr_status,
+ ioread32(FlashReg + intr_status));
+ }
+ }
+
+ iowrite32((~INTR_STATUS0__ECC_ERR) &
+ (~INTR_STATUS0__ECC_TRANSACTION_DONE) &
+ (~INTR_STATUS0__DMA_CMD_COMP),
+ FlashReg + intr_status);
+ }
+}
+
+static void handle_nand_int_write(struct mrst_nand_info *dev)
+{
+ u32 intr_status;
+ u32 intr[4] = {INTR_STATUS0, INTR_STATUS1,
+ INTR_STATUS2, INTR_STATUS3};
+ int status = PASS;
+
+ nand_dbg_print(NAND_DBG_DEBUG, "%s, Line %d, Function: %s\n",
+ __FILE__, __LINE__, __func__);
+
+ dev->ret = PASS;
+ intr_status = intr[dev->flash_bank];
+
+ while (1) {
+ while (!ioread32(FlashReg + intr_status))
+ ;
+
+ if (ioread32(FlashReg + intr_status) &
+ INTR_STATUS0__DMA_CMD_COMP) {
+ iowrite32(INTR_STATUS0__DMA_CMD_COMP,
+ FlashReg + intr_status);
+ if (FAIL == status)
+ dev->ret = FAIL;
+ break;
+ } else if (ioread32(FlashReg + intr_status) &
+ INTR_STATUS0__PROGRAM_FAIL) {
+ status = FAIL;
+ iowrite32(INTR_STATUS0__PROGRAM_FAIL,
+ FlashReg + intr_status);
+ } else {
+ iowrite32((~INTR_STATUS0__PROGRAM_FAIL) &
+ (~INTR_STATUS0__DMA_CMD_COMP),
+ FlashReg + intr_status);
+ }
+ }
+}
+
+static irqreturn_t ddma_isr(int irq, void *dev_id)
+{
+ struct mrst_nand_info *dev = dev_id;
+ u32 int_mask, ints0, ints1, ints2, ints3, ints_offset;
+ u32 intr[4] = {INTR_STATUS0, INTR_STATUS1,
+ INTR_STATUS2, INTR_STATUS3};
+
+ int_mask = INTR_STATUS0__DMA_CMD_COMP |
+ INTR_STATUS0__ECC_TRANSACTION_DONE |
+ INTR_STATUS0__ECC_ERR |
+ INTR_STATUS0__PROGRAM_FAIL |
+ INTR_STATUS0__ERASE_FAIL;
+
+ ints0 = ioread32(FlashReg + INTR_STATUS0);
+ ints1 = ioread32(FlashReg + INTR_STATUS1);
+ ints2 = ioread32(FlashReg + INTR_STATUS2);
+ ints3 = ioread32(FlashReg + INTR_STATUS3);
+
+ ints_offset = intr[dev->flash_bank];
+
+ nand_dbg_print(NAND_DBG_DEBUG,
+ "INTR0: 0x%x, INTR1: 0x%x, INTR2: 0x%x, INTR3: 0x%x, "
+ "DMA_INTR: 0x%x, "
+ "dev->state: 0x%x, dev->flash_bank: %d\n",
+ ints0, ints1, ints2, ints3,
+ ioread32(FlashReg + DMA_INTR),
+ dev->state, dev->flash_bank);
+
+ if (!(ioread32(FlashReg + ints_offset) & int_mask)) {
+ iowrite32(ints0, FlashReg + INTR_STATUS0);
+ iowrite32(ints1, FlashReg + INTR_STATUS1);
+ iowrite32(ints2, FlashReg + INTR_STATUS2);
+ iowrite32(ints3, FlashReg + INTR_STATUS3);
+ nand_dbg_print(NAND_DBG_WARN,
+ "ddma_isr: Invalid interrupt for NAND controller. "
+ "Ignore it\n");
+ return IRQ_NONE;
+ }
+
+ switch (dev->state) {
+ case INT_READ_PAGE_MAIN:
+ case INT_PIPELINE_READ_AHEAD:
+ /* Disable controller interrupts */
+ iowrite32(0, FlashReg + GLOBAL_INT_ENABLE);
+ handle_nand_int_read(dev);
+ break;
+ case INT_WRITE_PAGE_MAIN:
+ case INT_PIPELINE_WRITE_AHEAD:
+ iowrite32(0, FlashReg + GLOBAL_INT_ENABLE);
+ handle_nand_int_write(dev);
+ break;
+ default:
+ printk(KERN_ERR "ddma_isr - Illegal state: 0x%x\n",
+ dev->state);
+ return IRQ_NONE;
+ }
+
+ dev->state = INT_IDLE_STATE;
+ complete(&dev->complete);
+ return IRQ_HANDLED;
+}
+
+static const struct pci_device_id nand_pci_ids[] = {
+ {
+ .vendor = 0x8086,
+ .device = 0x0809,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ },
+ { /* end: all zeroes */ }
+};
+
+static int dump_pci_config_register(struct pci_dev *dev)
+{
+ int err = 0;
+ unsigned int data32;
+ u16 data16;
+ u8 data8;
+
+ nand_dbg_print(NAND_DBG_DEBUG, "Dump MRST PCI Config Registers:\n");
+
+ err = pci_read_config_word(dev, PCI_VENDOR_ID, &data16);
+ if (err) {
+ printk(KERN_ERR "Read PCI_VENDOR_ID fail, "
+ "error code: %d\n", err);
+ return err;
+ } else {
+ nand_dbg_print(NAND_DBG_DEBUG, "PCI_VENDOR_ID: 0x%x\n", data16);
+ }
+
+ err = pci_read_config_word(dev, PCI_DEVICE_ID, &data16);
+ if (err) {
+ printk(KERN_ERR "Read PCI_DEVICE_ID fail, "
+ "error code: %d\n", err);
+ return err;
+ } else {
+ nand_dbg_print(NAND_DBG_DEBUG, "PCI_DEVICE_ID: 0x%x\n", data16);
+ }
+
+ err = pci_read_config_word(dev, PCI_COMMAND, &data16);
+ if (err) {
+ printk(KERN_ERR "Read PCI_COMMAND fail, "
+ "error code: %d\n", err);
+ return err;
+ } else {
+ nand_dbg_print(NAND_DBG_DEBUG, "PCI_COMMAND: 0x%x\n", data16);
+ }
+
+ err = pci_read_config_word(dev, PCI_STATUS, &data16);
+ if (err) {
+ printk(KERN_ERR "Read PCI_STATUS fail, "
+ "error code: %d\n", err);
+ return err;
+ } else {
+ nand_dbg_print(NAND_DBG_DEBUG, "PCI_STATUS: 0x%x\n", data16);
+ }
+
+ err = pci_read_config_byte(dev, PCI_CLASS_REVISION, &data8);
+ if (err) {
+ printk(KERN_ERR "Read PCI_CLASS_REVISION fail, "
+ "error code: %d\n", err);
+ return err;
+ } else {
+ nand_dbg_print(NAND_DBG_DEBUG, "PCI_CLASS_REVISION: 0x%x\n",
+ data8);
+ }
+
+ err = pci_read_config_byte(dev, PCI_CLASS_PROG, &data8);
+ if (err) {
+ printk(KERN_ERR "Read PCI_CLASS_PROG fail, "
+ "error code: %d\n", err);
+ return err;
+ } else {
+ nand_dbg_print(NAND_DBG_DEBUG, "PCI_CLASS_PROG: 0x%x\n", data8);
+ }
+
+ err = pci_read_config_word(dev, PCI_CLASS_DEVICE, &data16);
+ if (err) {
+ printk(KERN_ERR "Read PCI_CLASS_DEVICE fail, "
+ "error code: %d\n", err);
+ return err;
+ } else {
+ nand_dbg_print(NAND_DBG_DEBUG, "PCI_CLASS_DEVICE: 0x%x\n",
+ data16);
+ }
+
+ err = pci_read_config_byte(dev, PCI_CACHE_LINE_SIZE, &data8);
+ if (err) {
+ printk(KERN_ERR "Read PCI_CACHE_LINE_SIZE fail, "
+ "error code: %d\n", err);
+ return err;
+ } else {
+ nand_dbg_print(NAND_DBG_DEBUG, "PCI_CACHE_LINE_SIZE: 0x%x\n",
+ data8);
+ }
+
+ err = pci_read_config_byte(dev, PCI_LATENCY_TIMER, &data8);
+ if (err) {
+ printk(KERN_ERR "Read PCI_LATENCY_TIMER fail, "
+ "error code: %d\n", err);
+ return err;
+ } else {
+ nand_dbg_print(NAND_DBG_DEBUG, "PCI_LATENCY_TIMER: 0x%x\n",
+ data8);
+ }
+
+ err = pci_read_config_byte(dev, PCI_HEADER_TYPE, &data8);
+ if (err) {
+ printk(KERN_ERR "Read PCI_HEADER_TYPE fail, "
+ "error code: %d\n", err);
+ return err;
+ } else {
+ nand_dbg_print(NAND_DBG_DEBUG, "PCI_HEADER_TYPE: 0x%x\n",
+ data8);
+ }
+
+ err = pci_read_config_byte(dev, PCI_BIST, &data8);
+ if (err) {
+ printk(KERN_ERR "Read PCI_BIST fail, " "error code: %d\n", err);
+ return err;
+ } else {
+ nand_dbg_print(NAND_DBG_DEBUG, "PCI_BIST: 0x%x\n", data8);
+ }
+
+ err = pci_read_config_dword(dev, PCI_BASE_ADDRESS_0, &data32);
+ if (err) {
+ printk(KERN_ERR "Read PCI_BASE_ADDRESS_0 fail, "
+ "error code: %d\n", err);
+ return err;
+ } else {
+ nand_dbg_print(NAND_DBG_DEBUG, "PCI_BASE_ADDRESS_0: 0x%x\n",
+ data32);
+ }
+
+ err = pci_read_config_dword(dev, PCI_BASE_ADDRESS_1, &data32);
+ if (err) {
+ printk(KERN_ERR "Read PCI_BASE_ADDRESS_1 fail, "
+ "error code: %d\n", err);
+ return err;
+ } else {
+ nand_dbg_print(NAND_DBG_DEBUG, "PCI_BASE_ADDRESS_1: 0x%x\n",
+ data32);
+ }
+
+ err = pci_read_config_dword(dev, PCI_BASE_ADDRESS_2, &data32);
+ if (err) {
+ printk(KERN_ERR "Read PCI_BASE_ADDRESS_2 fail, "
+ "error code: %d\n", err);
+ return err;
+ } else {
+ nand_dbg_print(NAND_DBG_DEBUG, "PCI_BASE_ADDRESS_2: 0x%x\n",
+ data32);
+ }
+
+ err = pci_read_config_dword(dev, PCI_BASE_ADDRESS_3, &data32);
+ if (err) {
+ printk(KERN_ERR "Read PCI_BASE_ADDRESS_3 fail, "
+ "error code: %d\n", err);
+ return err;
+ } else {
+ nand_dbg_print(NAND_DBG_DEBUG, "PCI_BASE_ADDRESS_3: 0x%x\n",
+ data32);
+ }
+
+ err = pci_read_config_dword(dev, PCI_BASE_ADDRESS_4, &data32);
+ if (err) {
+ printk(KERN_ERR "Read PCI_BASE_ADDRESS_4 fail, "
+ "error code: %d\n", err);
+ return err;
+ } else {
+ nand_dbg_print(NAND_DBG_DEBUG, "PCI_BASE_ADDRESS_4: 0x%x\n",
+ data32);
+ }
+
+ err = pci_read_config_dword(dev, PCI_BASE_ADDRESS_5, &data32);
+ if (err) {
+ printk(KERN_ERR "Read PCI_BASE_ADDRESS_5 fail, "
+ "error code: %d\n", err);
+ return err;
+ } else {
+ nand_dbg_print(NAND_DBG_DEBUG, "PCI_BASE_ADDRESS_5: 0x%x\n",
+ data32);
+ }
+
+ err = pci_read_config_dword(dev, PCI_CARDBUS_CIS, &data32);
+ if (err) {
+ printk(KERN_ERR "Read PCI_CARDBUS_CIS fail, "
+ "error code: %d\n", err);
+ return err;
+ } else {
+ nand_dbg_print(NAND_DBG_DEBUG, "PCI_CARDBUS_CIS: 0x%x\n",
+ data32);
+ }
+
+ err = pci_read_config_word(dev, PCI_SUBSYSTEM_VENDOR_ID, &data16);
+ if (err) {
+ printk(KERN_ERR "Read PCI_SUBSYSTEM_VENDOR_ID fail, "
+ "error code: %d\n", err);
+ return err;
+ } else {
+ nand_dbg_print(NAND_DBG_DEBUG,
+ "PCI_SUBSYSTEM_VENDOR_ID: 0x%x\n", data16);
+ }
+
+ err = pci_read_config_word(dev, PCI_SUBSYSTEM_ID, &data16);
+ if (err) {
+ printk(KERN_ERR "Read PCI_SUBSYSTEM_ID fail, "
+ "error code: %d\n", err);
+ return err;
+ } else {
+ nand_dbg_print(NAND_DBG_DEBUG, "PCI_SUBSYSTEM_ID: 0x%x\n",
+ data16);
+ }
+
+ err = pci_read_config_dword(dev, PCI_ROM_ADDRESS, &data32);
+ if (err) {
+ printk(KERN_ERR "Read PCI_ROM_ADDRESS fail, "
+ "error code: %d\n", err);
+ return err;
+ } else {
+ nand_dbg_print(NAND_DBG_DEBUG, "PCI_ROM_ADDRESS: 0x%x\n",
+ data32);
+ }
+
+ err = pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &data8);
+ if (err) {
+ printk(KERN_ERR "Read PCI_INTERRUPT_LINE fail, "
+ "error code: %d\n", err);
+ return err;
+ } else {
+ nand_dbg_print(NAND_DBG_DEBUG, "PCI_INTERRUPT_LINE: 0x%x\n",
+ data8);
+ }
+
+ err = pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &data8);
+ if (err) {
+ printk(KERN_ERR "Read PCI_INTERRUPT_PIN fail, "
+ "error code: %d\n", err);
+ return err;
+ } else {
+ nand_dbg_print(NAND_DBG_DEBUG, "PCI_INTERRUPT_PIN: 0x%x\n",
+ data8);
+ }
+
+ err = pci_read_config_byte(dev, PCI_MIN_GNT, &data8);
+ if (err) {
+ printk(KERN_ERR "Read PCI_MIN_GNT fail, "
+ "error code: %d\n", err);
+ return err;
+ } else {
+ nand_dbg_print(NAND_DBG_DEBUG, "PCI_MIN_GNT: 0x%x\n", data8);
+ }
+
+ err = pci_read_config_byte(dev, PCI_MAX_LAT, &data8);
+ if (err) {
+ printk(KERN_ERR "Read PCI_MAX_LAT fail, "
+ "error code: %d\n", err);
+ return err;
+ } else {
+ nand_dbg_print(NAND_DBG_DEBUG, "PCI_MAX_LAT: 0x%x\n", data8);
+ }
+
+ return err;
+}
+
+static int nand_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
+{
+ int ret = -ENODEV;
+ unsigned long csr_base;
+ unsigned long csr_len;
+ struct mrst_nand_info *pndev = &info;
+
+ nand_dbg_print(NAND_DBG_WARN, "%s, Line %d, Function: %s\n",
+ __FILE__, __LINE__, __func__);
+
+ ret = pci_enable_device(dev);
+ if (ret) {
+ printk(KERN_ERR "Spectra: pci_enable_device failed.\n");
+ return ret;
+ }
+
+ dump_pci_config_register(dev);
+
+ pci_set_master(dev);
+ pndev->dev = dev;
+
+ csr_base = pci_resource_start(dev, 0);
+ if (!csr_base) {
+ printk(KERN_ERR "Spectra: pci_resource_start failed!\n");
+ return -ENODEV;
+ }
+
+ csr_len = pci_resource_len(dev, 0);
+ if (!csr_len) {
+ printk(KERN_ERR "Spectra: pci_resource_len failed!\n");
+ return -ENODEV;
+ }
+
+ ret = pci_request_regions(dev, SPECTRA_NAND_NAME);
+ if (ret) {
+ printk(KERN_ERR "Spectra: Unable to request "
+ "memory region\n");
+ goto failed_req_csr;
+ }
+
+ pndev->ioaddr = ioremap_nocache(csr_base, csr_len);
+ if (!pndev->ioaddr) {
+ printk(KERN_ERR "Spectra: Unable to remap memory region\n");
+ ret = -ENOMEM;
+ goto failed_remap_csr;
+ }
+ nand_dbg_print(NAND_DBG_DEBUG, "Spectra: CSR 0x%08lx -> 0x%p (0x%lx)\n",
+ csr_base, pndev->ioaddr, csr_len);
+
+#if DDMA
+ init_completion(&pndev->complete);
+ nand_dbg_print(NAND_DBG_DEBUG, "Spectra: IRQ %d\n", dev->irq);
+ if (request_irq(dev->irq, ddma_isr, IRQF_SHARED,
+ SPECTRA_NAND_NAME, &info)) {
+ printk(KERN_ERR "Spectra: Unable to allocate IRQ\n");
+ ret = -ENODEV;
+ iounmap(pndev->ioaddr);
+ goto failed_remap_csr;
+ }
+#endif
+
+ pci_set_drvdata(dev, pndev);
+
+ return 0;
+
+failed_remap_csr:
+ pci_release_regions(dev);
+failed_req_csr:
+
+ return ret;
+}
+
+static void nand_pci_remove(struct pci_dev *dev)
+{
+ struct mrst_nand_info *pndev = pci_get_drvdata(dev);
+
+ nand_dbg_print(NAND_DBG_WARN, "%s, Line %d, Function: %s\n",
+ __FILE__, __LINE__, __func__);
+#if CMD_DMA
+ free_irq(dev->irq, pndev);
+#endif
+ iounmap(pndev->ioaddr);
+ pci_release_regions(dev);
+ pci_disable_device(dev);
+}
+
+MODULE_DEVICE_TABLE(pci, nand_pci_ids);
+
+static struct pci_driver nand_pci_driver = {
+ .name = SPECTRA_NAND_NAME,
+ .id_table = nand_pci_ids,
+ .probe = nand_pci_probe,
+ .remove = nand_pci_remove,
+};
+
+u16 NAND_Flash_Init(void)
+{
+ int retval;
+ u32 int_mask = INTR_STATUS0__DMA_CMD_COMP |
+ INTR_STATUS0__ECC_TRANSACTION_DONE |
+ INTR_STATUS0__ECC_ERR |
+ INTR_STATUS0__PROGRAM_FAIL |
+ INTR_STATUS0__ERASE_FAIL;
+
+ nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
+ __FILE__, __LINE__, __func__);
+
+ FlashReg = GLOB_MEMMAP_NOCACHE(GLOB_HWCTL_REG_BASE,
+ GLOB_HWCTL_REG_SIZE);
+ if (!FlashReg) {
+ printk(KERN_ERR "Spectra: ioremap_nocache failed!");
+ return -ENOMEM;
+ }
+ nand_dbg_print(NAND_DBG_WARN,
+ "Spectra: Remapped reg base address: "
+ "0x%p, len: %d\n",
+ FlashReg, GLOB_HWCTL_REG_SIZE);
+
+ FlashMem = GLOB_MEMMAP_NOCACHE(GLOB_HWCTL_MEM_BASE,
+ GLOB_HWCTL_MEM_SIZE);
+ if (!FlashMem) {
+ printk(KERN_ERR "Spectra: ioremap_nocache failed!");
+ return -ENOMEM;
+ }
+
+ nand_dbg_print(NAND_DBG_WARN,
+ "Spectra: Remapped flash base address: "
+ "0x%p, len: %d\n",
+ (void *)FlashMem, GLOB_HWCTL_MEM_SIZE);
+
+ NAND_Flash_Reset();
+
+ iowrite32(0, FlashReg + GLOBAL_INT_ENABLE);
+/*
+ iowrite32(0, FlashReg + INTR_EN0);
+ iowrite32(0, FlashReg + INTR_EN1);
+ iowrite32(0, FlashReg + INTR_EN2);
+ iowrite32(0, FlashReg + INTR_EN3);
+*/
+
+ iowrite32(int_mask, FlashReg + INTR_EN0);
+ iowrite32(int_mask, FlashReg + INTR_EN1);
+ iowrite32(int_mask, FlashReg + INTR_EN2);
+ iowrite32(int_mask, FlashReg + INTR_EN3);
+
+ iowrite32(0xFFFF, FlashReg + INTR_STATUS0);
+ iowrite32(0xFFFF, FlashReg + INTR_STATUS1);
+ iowrite32(0xFFFF, FlashReg + INTR_STATUS2);
+ iowrite32(0xFFFF, FlashReg + INTR_STATUS3);
+
+ iowrite32(0x0F, FlashReg + RB_PIN_ENABLED);
+ iowrite32(CHIP_EN_DONT_CARE__FLAG, FlashReg + CHIP_ENABLE_DONT_CARE);
+
+ /* Should set value for these registers when init */
+ iowrite32(1, FlashReg + ECC_ENABLE);
+ iowrite32(0, FlashReg + TWO_ROW_ADDR_CYCLES);
+
+ /* Enable the 2 lines code will enable pipeline_rw_ahead feature */
+ /* and improve performance for about 10%. But will also cause a */
+ /* 1 or 2 bit error when do a 300MB+ file copy/compare testing. */
+ /* Suspect it's an ECC FIFO overflow issue. -- Yunpeng 2009.03.26 */
+ /* iowrite32(1, FlashReg + CACHE_WRITE_ENABLE); */
+ /* iowrite32(1, FlashReg + CACHE_READ_ENABLE); */
+
+ retval = pci_register_driver(&nand_pci_driver);
+ if (retval)
+ return -ENOMEM;
+
+ return PASS;
+}
+
+#endif
+
+#if FLASH_CDMA
+u16 NAND_Flash_Init(void)
+{
+ nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
+ __FILE__, __LINE__, __func__);
+
+ FlashReg = GLOB_MEMMAP_NOCACHE(GLOB_HWCTL_REG_BASE,
+ GLOB_HWCTL_REG_SIZE);
+ if (!FlashReg) {
+ printk(KERN_ERR "Spectra: ioremap_nocache failed!");
+ return -ENOMEM;
+ }
+ nand_dbg_print(NAND_DBG_WARN,
+ "Spectra: Remapped reg base address: "
+ "0x%p, len: %d\n",
+ FlashReg, GLOB_HWCTL_REG_SIZE);
+
+ FlashMem = GLOB_MEMMAP_NOCACHE(GLOB_HWCTL_MEM_BASE,
+ GLOB_HWCTL_MEM_SIZE);
+ if (!FlashMem) {
+ printk(KERN_ERR "Spectra: ioremap_nocache failed!");
+ return -ENOMEM;
+ }
+
+ nand_dbg_print(NAND_DBG_WARN,
+ "Spectra: Remapped flash base address: "
+ "0x%p, len: %d\n",
+ (void *)FlashMem, GLOB_HWCTL_MEM_SIZE);
+
+ NAND_Flash_Reset();
+
+ iowrite32(0, FlashReg + GLOBAL_INT_ENABLE);
+
+ iowrite32(0, FlashReg + INTR_EN0);
+ iowrite32(0, FlashReg + INTR_EN1);
+ iowrite32(0, FlashReg + INTR_EN2);
+ iowrite32(0, FlashReg + INTR_EN3);
+
+ iowrite32(0xFFFF, FlashReg + INTR_STATUS0);
+ iowrite32(0xFFFF, FlashReg + INTR_STATUS1);
+ iowrite32(0xFFFF, FlashReg + INTR_STATUS2);
+ iowrite32(0xFFFF, FlashReg + INTR_STATUS3);
+
+ iowrite32(0x0F, FlashReg + RB_PIN_ENABLED);
+ iowrite32(CHIP_EN_DONT_CARE__FLAG, FlashReg + CHIP_ENABLE_DONT_CARE);
+
+ iowrite32(1, FlashReg + ECC_ENABLE);
+ iowrite32(0, FlashReg + TWO_ROW_ADDR_CYCLES);
+
+ /* Enable the 2 lines code will enable pipeline_rw_ahead feature */
+ /* and improve performance for about 10%. But will also cause a */
+ /* 1 or 2 bit error when do a 300MB+ file copy/compare testing. */
+ /* Suspect it's an ECC FIFO overflow issue. -- Yunpeng 2009.03.26 */
+ /* iowrite32(1, FlashReg + CACHE_WRITE_ENABLE); */
+ /* iowrite32(1, FlashReg + CACHE_READ_ENABLE); */
+
+ return PASS;
+}
+
+#endif
+
diff --git a/drivers/staging/mrst_nand/lld_nand.h b/drivers/staging/mrst_nand/lld_nand.h
new file mode 100644
index 0000000..88d0554
--- /dev/null
+++ b/drivers/staging/mrst_nand/lld_nand.h
@@ -0,0 +1,116 @@
+/*
+ * NAND Flash Controller Device Driver
+ * Copyright (c) 2009, Intel Corporation and its suppliers.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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.
+ *
+ * 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.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+#ifndef _LLD_NAND_
+#define _LLD_NAND_
+
+#ifdef ELDORA
+#include "defs.h"
+#else
+#include "flash.h"
+#include "ffsport.h"
+#endif
+
+#define MODE_00 0x00000000
+#define MODE_01 0x04000000
+#define MODE_10 0x08000000
+#define MODE_11 0x0C000000
+
+
+#define DATA_TRANSFER_MODE 0
+#define PROTECTION_PER_BLOCK 1
+#define LOAD_WAIT_COUNT 2
+#define PROGRAM_WAIT_COUNT 3
+#define ERASE_WAIT_COUNT 4
+#define INT_MONITOR_CYCLE_COUNT 5
+#define READ_BUSY_PIN_ENABLED 6
+#define MULTIPLANE_OPERATION_SUPPORT 7
+#define PRE_FETCH_MODE 8
+#define CE_DONT_CARE_SUPPORT 9
+#define COPYBACK_SUPPORT 10
+#define CACHE_WRITE_SUPPORT 11
+#define CACHE_READ_SUPPORT 12
+#define NUM_PAGES_IN_BLOCK 13
+#define ECC_ENABLE_SELECT 14
+#define WRITE_ENABLE_2_READ_ENABLE 15
+#define ADDRESS_2_DATA 16
+#define READ_ENABLE_2_WRITE_ENABLE 17
+#define TWO_ROW_ADDRESS_CYCLES 18
+#define MULTIPLANE_ADDRESS_RESTRICT 19
+#define ACC_CLOCKS 20
+#define READ_WRITE_ENABLE_LOW_COUNT 21
+#define READ_WRITE_ENABLE_HIGH_COUNT 22
+
+#define ECC_SECTOR_SIZE 512
+#define LLD_MAX_FLASH_BANKS 4
+
+
+u16 NAND_Flash_Init(void);
+u16 NAND_Flash_Reset(void);
+u16 NAND_Read_Device_ID(void);
+u16 NAND_Erase_Block(u32 flash_add);
+u16 NAND_Write_Page_Main(u8 *write_data, u32 block, u16 page,
+ u16 page_count);
+u16 NAND_Read_Page_Main(u8 *read_data, u32 block, u16 page,
+ u16 page_count);
+u16 NAND_UnlockArrayAll(void);
+u16 NAND_Write_Page_Main_Spare(u8 *write_data, u32 block,
+ u16 page, u16 page_count);
+u16 NAND_Write_Page_Spare(u8 *read_data, u32 block, u16 page,
+ u16 page_count);
+u16 NAND_Read_Page_Main_Spare(u8 *read_data, u32 block, u16 page,
+ u16 page_count);
+u16 NAND_Read_Page_Spare(u8 *read_data, u32 block, u16 page,
+ u16 page_count);
+u16 NAND_LLD_Event_Status(void);
+void NAND_LLD_Enable_Disable_Interrupts(u16 INT_ENABLE);
+u16 NAND_Get_Bad_Block(u32 block);
+
+u32 NAND_Memory_Pool_Size(void);
+int NAND_Mem_Config(u8 *pMem);
+
+u16 NAND_Pipeline_Read_Ahead(u8 *read_data, u32 block, u16 page,
+ u16 page_count);
+u16 NAND_Pipeline_Write_Ahead(u8 *write_data, u32 block,
+ u16 page, u16 page_count);
+u16 NAND_Multiplane_Read(u8 *read_data, u32 block, u16 page,
+ u16 page_count);
+u16 NAND_Multiplane_Write(u8 *write_data, u32 block, u16 page,
+ u16 page_count);
+void NAND_ECC_Ctrl(int enable);
+u16 NAND_Read_Page_Main_Polling(u8 *read_data,
+ u32 block, u16 page, u16 page_count);
+u16 NAND_Pipeline_Read_Ahead_Polling(u8 *read_data,
+ u32 block, u16 page, u16 page_count);
+
+void Conv_Spare_Data_Log2Phy_Format(u8 *data);
+void Conv_Spare_Data_Phy2Log_Format(u8 *data);
+void Conv_Main_Spare_Data_Log2Phy_Format(u8 *data, u16 page_count);
+void Conv_Main_Spare_Data_Phy2Log_Format(u8 *data, u16 page_count);
+
+extern void __iomem *FlashReg;
+extern void __iomem *FlashMem;
+
+extern int totalUsedBanks;
+extern u32 GLOB_valid_banks[LLD_MAX_FLASH_BANKS];
+
+#endif /*_LLD_NAND_*/
+
+
+
diff --git a/drivers/staging/mrst_nand/spectraswconfig.h b/drivers/staging/mrst_nand/spectraswconfig.h
new file mode 100644
index 0000000..f9e35e8
--- /dev/null
+++ b/drivers/staging/mrst_nand/spectraswconfig.h
@@ -0,0 +1,86 @@
+/*
+ * NAND Flash Controller Device Driver
+ * Copyright (c) 2009, Intel Corporation and its suppliers.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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.
+ *
+ * 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.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+#ifndef _SPECTRASWCONFIG_
+#define _SPECTRASWCONFIG_
+
+/***** Common Parameters *****/
+#define RETRY_TIMES 3
+
+#define READ_BADBLOCK_INFO 1
+#define READBACK_VERIFY 0
+#define AUTO_FORMAT_FLASH 0
+
+/***** Cache Parameters *****/
+#define PAGES_PER_CACHE_BLOCK 0
+#define CACHE_BLOCK_NUMBER 2
+
+/***** Block Table Parameters *****/
+#define BLOCK_TABLE_INDEX 0
+
+/***** Wear Leveling Parameters *****/
+#define WEAR_LEVELING_GATE 0x10
+#define WEAR_LEVELING_BLOCK_NUM 10
+
+#define DEBUG_BNDRY 0
+
+/***** Product Feature Support *****/
+
+#define FLASH_EMU defined(CONFIG_MRST_NAND_EMU)
+#define FLASH_NAND defined(CONFIG_MRST_NAND_HW)
+#define FLASH_CDMA 0
+#define CMD_DMA 0
+#define DDMA 1
+
+#define SPECTRA_PARTITION_ID 0
+
+/* Enable this macro if the number of flash blocks is larger than 16K. */
+#define SUPPORT_LARGE_BLOCKNUM 1
+
+/**** Block Table and Reserved Block Parameters *****/
+#define SPECTRA_START_BLOCK 3
+#define NUM_FREE_BLOCKS_GATE 30
+
+/**** Linux Block Driver Parameters ****/
+#define SBD_MEMPOOL_PTR 0x0c800000
+
+/**** Hardware Parameters ****/
+#define GLOB_HWCTL_REG_BASE 0xFFA40000
+#define GLOB_HWCTL_REG_SIZE 4096
+
+#define GLOB_HWCTL_MEM_BASE 0xFFA48000
+#define GLOB_HWCTL_MEM_SIZE 1024
+
+#define GLOB_HWCTL_DEFAULT_BLKS 2048
+
+/**** Toshiba Device Parameters ****/
+
+#define GLOB_DEVTSBA_ALT_BLK_NFO 1
+#define GLOB_DEVTSBA_ALT_BLK_ADD \
+ (GLOB_HWCTL_REG_BASE + (DEVICE_PARAM_2 << 2))
+
+#define SUPPORT_15BITECC 1
+#define SUPPORT_8BITECC 1
+
+#define CUSTOM_CONF_PARAMS 0
+
+#define ONFI_BLOOM_TIME 0
+#define MODE5_WORKAROUND 1
+
+#endif /*_SPECTRASWCONFIG_*/
--
1.5.4.5
On Fri, Jun 05, 2009 at 07:26:10AM +0800, Yunpeng Gao wrote:
> Hi Greg,
> I have fixed these compiling bugs in file ffsport.c.
Great.
> But just found that my email client (Outlook) will replace
> TAB with blanks automatically. So, unfortunately, all the
> TABs in my first submission patch have been changed to
> blanks by the Outlook.
Heh.
> So I'd like to use the Mutt email client and re-submit
> the patch as below (the bug-fix of ffsport.c has been included).
> Does it make sense?
Sure, I can replace the existing patch with this one if you want me to.
I'll go queue it up.
thanks,
greg k-h
On Fri, Jun 05, 2009 at 07:26:10AM +0800, Yunpeng Gao wrote:
> I have fixed these compiling bugs in file ffsport.c.
>
> But just found that my email client (Outlook) will replace
> TAB with blanks automatically. So, unfortunately, all the
> TABs in my first submission patch have been changed to
> blanks by the Outlook.
>
> So I'd like to use the Mutt email client and re-submit
> the patch as below (the bug-fix of ffsport.c has been included).
> Does it make sense?
>
Are you sure you included the fixed up patch?
With the patch you submitted below, I get the following build errors:
drivers/staging/mrst_nand/ffsport.c: In function ‘do_transfer’:
drivers/staging/mrst_nand/ffsport.c:360: error: implicit declaration of function ‘blk_rq_pos’
drivers/staging/mrst_nand/ffsport.c:376: error: implicit declaration of function ‘blk_rq_cur_sectors’
drivers/staging/mrst_nand/ffsport.c: In function ‘spectra_trans_thread’:
drivers/staging/mrst_nand/ffsport.c:499: error: implicit declaration of function ‘blk_fetch_request’
drivers/staging/mrst_nand/ffsport.c:499: warning: assignment makes pointer from integer without a cast
drivers/staging/mrst_nand/ffsport.c:515: error: implicit declaration of function ‘__blk_end_request_cur’
drivers/staging/mrst_nand/ffsport.c:520: error: implicit declaration of function ‘__blk_end_request_all’
drivers/staging/mrst_nand/ffsport.c: In function ‘SBD_setup_device’:
drivers/staging/mrst_nand/ffsport.c:741: error: implicit declaration of function ‘blk_queue_logical_block_size’
make[3]: *** [drivers/staging/mrst_nand/ffsport.o] Error 1
make[3]: *** Waiting for unfinished jobs....
I'll just drop this patch for now, can you resend it to me when it is
fixed up properly?
thanks,
greg k-h
Hi *,
the following pops up from time to time when I place a call (might also
happened on incoming calls).
machine is an AMD K8 dual core running a x86_64 2.6.29.4-grsec kernel.
please, let me know if you need more details.
cheers,
Mathias
[88563.318126] ------------[ cut here ]------------
[88563.318129] WARNING: at kernel/softirq.c:124 local_bh_enable+0x8f/0xb0()
[88563.318130] Hardware name: empty
[88563.318132] Modules linked in: usbtouchscreen dvb_usb_cinergyT2 dummy
bonding snd_emu10k1 snd_rawmidi snd_ac97_codec ath9k ac97_bus snd_pcm
snd_page_alloc snd_util_mem forcedeth snd_hwdep
[88563.318141] Pid: 826, comm: mISDN_hfc-pci.1 Not tainted 2.6.29.4-grsec #13
[88563.318142] Call Trace:
[88563.318147] [<ffffffff8025909a>] warn_slowpath+0xea/0x160
[88563.318149] [<ffffffff8025ee0f>] local_bh_enable+0x8f/0xb0
[88563.318152] [<ffffffff8065f284>] sk_filter+0x44/0xa0
[88563.318154] [<ffffffff8064548d>] sock_queue_rcv_skb+0x5d/0x120
[88563.318156] [<ffffffff8060410f>] mISDN_send+0x4f/0xa0
[88563.318159] [<ffffffff8060790e>] l2up_create+0x7e/0x100
[88563.318161] [<ffffffff8060b6e0>] l2_got_tei+0x0/0x90
[88563.318163] [<ffffffff8060b722>] l2_got_tei+0x42/0x90
[88563.318164] [<ffffffff80602d32>] mISDN_FsmEvent+0x82/0x100
[88563.318167] [<ffffffff8060cb00>] tei_id_assign+0x0/0x120
[88563.318168] [<ffffffff80602d32>] mISDN_FsmEvent+0x82/0x100
[88563.318170] [<ffffffff8060e373>] mgr_send+0x4d3/0x660
[88563.318172] [<ffffffff8061ac8e>] hfcpci_l2l1D+0x19e/0x2f0
[88563.318174] [<ffffffff80606591>] mISDNStackd+0x431/0x680
[88563.318177] [<ffffffff80270950>] autoremove_wake_function+0x0/0x30
[88563.318179] [<ffffffff80606160>] mISDNStackd+0x0/0x680
[88563.318181] [<ffffffff80270547>] kthread+0x47/0x80
[88563.318183] [<ffffffff802226fa>] child_rip+0xa/0x20
[88563.318185] [<ffffffff80270500>] kthread+0x0/0x80
[88563.318186] [<ffffffff802226f0>] child_rip+0x0/0x20
[88563.318188] ---[ end trace 2a7bb9b2f669de5a ]---
(cc's added)
On Fri, 5 Jun 2009 00:07:12 +0200 Mathias Kretschmer <[email protected]> wrote:
> Hi *,
>
> the following pops up from time to time when I place a call (might also
> happened on incoming calls).
>
> machine is an AMD K8 dual core running a x86_64 2.6.29.4-grsec kernel.
>
> please, let me know if you need more details.
>
> cheers,
>
> Mathias
>
> [88563.318126] ------------[ cut here ]------------
> [88563.318129] WARNING: at kernel/softirq.c:124 local_bh_enable+0x8f/0xb0()
> [88563.318130] Hardware name: empty
> [88563.318132] Modules linked in: usbtouchscreen dvb_usb_cinergyT2 dummy
> bonding snd_emu10k1 snd_rawmidi snd_ac97_codec ath9k ac97_bus snd_pcm
> snd_page_alloc snd_util_mem forcedeth snd_hwdep
> [88563.318141] Pid: 826, comm: mISDN_hfc-pci.1 Not tainted 2.6.29.4-grsec #13
> [88563.318142] Call Trace:
> [88563.318147] [<ffffffff8025909a>] warn_slowpath+0xea/0x160
> [88563.318149] [<ffffffff8025ee0f>] local_bh_enable+0x8f/0xb0
> [88563.318152] [<ffffffff8065f284>] sk_filter+0x44/0xa0
> [88563.318154] [<ffffffff8064548d>] sock_queue_rcv_skb+0x5d/0x120
> [88563.318156] [<ffffffff8060410f>] mISDN_send+0x4f/0xa0
> [88563.318159] [<ffffffff8060790e>] l2up_create+0x7e/0x100
> [88563.318161] [<ffffffff8060b6e0>] l2_got_tei+0x0/0x90
> [88563.318163] [<ffffffff8060b722>] l2_got_tei+0x42/0x90
> [88563.318164] [<ffffffff80602d32>] mISDN_FsmEvent+0x82/0x100
> [88563.318167] [<ffffffff8060cb00>] tei_id_assign+0x0/0x120
> [88563.318168] [<ffffffff80602d32>] mISDN_FsmEvent+0x82/0x100
> [88563.318170] [<ffffffff8060e373>] mgr_send+0x4d3/0x660
> [88563.318172] [<ffffffff8061ac8e>] hfcpci_l2l1D+0x19e/0x2f0
> [88563.318174] [<ffffffff80606591>] mISDNStackd+0x431/0x680
> [88563.318177] [<ffffffff80270950>] autoremove_wake_function+0x0/0x30
> [88563.318179] [<ffffffff80606160>] mISDNStackd+0x0/0x680
> [88563.318181] [<ffffffff80270547>] kthread+0x47/0x80
> [88563.318183] [<ffffffff802226fa>] child_rip+0xa/0x20
> [88563.318185] [<ffffffff80270500>] kthread+0x0/0x80
> [88563.318186] [<ffffffff802226f0>] child_rip+0x0/0x20
> [88563.318188] ---[ end trace 2a7bb9b2f669de5a ]---
>
hm, tricky, who disabled interrupts? It could be
spin_lock_irqsave(&hc->lock, flags);
in hfcpci_l2l1D().
Hi Greg,
Thanks for your quick response.
The root cause of the build-errors in ffsport.c is that the kernel block layer APIs are different in linux-next tree (.../linux/kernel/git/sfr/linux-next.git) than in Linus' kernel tree (.../linux/kernel/git/torvalds/linux-2.6.git).
Yesterday, after modify code in ffsport.c to sync up with the block layer APIs changes, I have make the kernel against linux-next tree and found no build error / warnings.
Then I generated the patch again Linus' kernel tree, tag 'v2.6.30-rc8' and sent the patch to you. This patch uses the new block layer APIs and is target for the linux-next tree.
I guess the below build errors are caused by compiling the patch code in Linus' kernel tree. As the block layer API's in Linus' kernel tree is still the old one, it'll report this kind of 'implicit declaration of function ...' error. I'm sorry for the mis-communication.
Now, I'm a bit confused with the process :-) Which git tree should I select to generate patch against and submit to? The linux-next tree or Linus' kerner tree?
Thanks for your time.
Rgds,
Yunpeng
>-----Original Message-----
>From: Greg KH [mailto:[email protected]]
>Sent: 2009??6??5?? 1:52
>To: Gao, Yunpeng
>Cc: Greg KH; [email protected]
>Subject: Re: linux-next: Tree for June 3 (staging)
>
>Are you sure you included the fixed up patch?
>
>With the patch you submitted below, I get the following build errors:
>
>drivers/staging/mrst_nand/ffsport.c: In function ??do_transfer??:
>drivers/staging/mrst_nand/ffsport.c:360: error: implicit declaration of
>function ??blk_rq_pos??
>drivers/staging/mrst_nand/ffsport.c:376: error: implicit declaration of
>function ??blk_rq_cur_sectors??
>drivers/staging/mrst_nand/ffsport.c: In function ??spectra_trans_thread??:
>drivers/staging/mrst_nand/ffsport.c:499: error: implicit declaration of
>function ??blk_fetch_request??
>drivers/staging/mrst_nand/ffsport.c:499: warning: assignment makes pointer
>from integer without a cast
>drivers/staging/mrst_nand/ffsport.c:515: error: implicit declaration of
>function ??__blk_end_request_cur??
>drivers/staging/mrst_nand/ffsport.c:520: error: implicit declaration of
>function ??__blk_end_request_all??
>drivers/staging/mrst_nand/ffsport.c: In function ??SBD_setup_device??:
>drivers/staging/mrst_nand/ffsport.c:741: error: implicit declaration of
>function ??blk_queue_logical_block_size??
>make[3]: *** [drivers/staging/mrst_nand/ffsport.o] Error 1
>make[3]: *** Waiting for unfinished jobs....
>
>
>I'll just drop this patch for now, can you resend it to me when it is
>fixed up properly?
>
>thanks,
>
>greg k-h
????{.n?+???????+%?????ݶ??w??{.n?+????{??G?????{ay?ʇڙ?,j??f???h?????????z_??(?階?ݢj"???m??????G????????????&???~???iO???z??v?^?m????????????I?
Hi,
I'm currently see this too from time to time, but have no idea about it.
On Freitag, 5. Juni 2009 04:59:48 Andrew Morton wrote:
> (cc's added)
>
> On Fri, 5 Jun 2009 00:07:12 +0200 Mathias Kretschmer <[email protected]>
wrote:
> > Hi *,
> >
> > the following pops up from time to time when I place a call (might also
> > happened on incoming calls).
> >
> > machine is an AMD K8 dual core running a x86_64 2.6.29.4-grsec kernel.
> >
> > please, let me know if you need more details.
> >
> > cheers,
> >
> > Mathias
> >
> > [88563.318126] ------------[ cut here ]------------
> > [88563.318129] WARNING: at kernel/softirq.c:124
> > local_bh_enable+0x8f/0xb0() [88563.318130] Hardware name: empty
> > [88563.318132] Modules linked in: usbtouchscreen dvb_usb_cinergyT2 dummy
> > bonding snd_emu10k1 snd_rawmidi snd_ac97_codec ath9k ac97_bus snd_pcm
> > snd_page_alloc snd_util_mem forcedeth snd_hwdep
> > [88563.318141] Pid: 826, comm: mISDN_hfc-pci.1 Not tainted 2.6.29.4-grsec
> > #13 [88563.318142] Call Trace:
> > [88563.318147] [<ffffffff8025909a>] warn_slowpath+0xea/0x160
> > [88563.318149] [<ffffffff8025ee0f>] local_bh_enable+0x8f/0xb0
> > [88563.318152] [<ffffffff8065f284>] sk_filter+0x44/0xa0
> > [88563.318154] [<ffffffff8064548d>] sock_queue_rcv_skb+0x5d/0x120
> > [88563.318156] [<ffffffff8060410f>] mISDN_send+0x4f/0xa0
> > [88563.318159] [<ffffffff8060790e>] l2up_create+0x7e/0x100
> > [88563.318161] [<ffffffff8060b6e0>] l2_got_tei+0x0/0x90
> > [88563.318163] [<ffffffff8060b722>] l2_got_tei+0x42/0x90
> > [88563.318164] [<ffffffff80602d32>] mISDN_FsmEvent+0x82/0x100
> > [88563.318167] [<ffffffff8060cb00>] tei_id_assign+0x0/0x120
> > [88563.318168] [<ffffffff80602d32>] mISDN_FsmEvent+0x82/0x100
> > [88563.318170] [<ffffffff8060e373>] mgr_send+0x4d3/0x660
> > [88563.318172] [<ffffffff8061ac8e>] hfcpci_l2l1D+0x19e/0x2f0
> > [88563.318174] [<ffffffff80606591>] mISDNStackd+0x431/0x680
> > [88563.318177] [<ffffffff80270950>] autoremove_wake_function+0x0/0x30
> > [88563.318179] [<ffffffff80606160>] mISDNStackd+0x0/0x680
> > [88563.318181] [<ffffffff80270547>] kthread+0x47/0x80
> > [88563.318183] [<ffffffff802226fa>] child_rip+0xa/0x20
> > [88563.318185] [<ffffffff80270500>] kthread+0x0/0x80
> > [88563.318186] [<ffffffff802226f0>] child_rip+0x0/0x20
> > [88563.318188] ---[ end trace 2a7bb9b2f669de5a ]---
>
> hm, tricky, who disabled interrupts?
Yes, indeed I have no idea what exactely is going on.
> It could be
>
> spin_lock_irqsave(&hc->lock, flags);
>
> in hfcpci_l2l1D().
I do not think that this function is really in the call trace, in my dumps I
see also traces without hfcpci_l2l1D in it.
And I see no way back to mgr_send from hfcpci_l2l1D from the design
the HW functions are decoupled from the stack thread via queues, so
here should be no direct callback.
The common part is, that it seems always happen on successful TEI
assign.
Karsten
On Friday 05 June 2009 05:31:21 Gao, Yunpeng wrote:
> Hi Greg,
>
> Thanks for your quick response.
>
> The root cause of the build-errors in ffsport.c is that the kernel block layer APIs are different in linux-next tree (.../linux/kernel/git/sfr/linux-next.git) than in Linus' kernel tree (.../linux/kernel/git/torvalds/linux-2.6.git).
>
> Yesterday, after modify code in ffsport.c to sync up with the block layer APIs changes, I have make the kernel against linux-next tree and found no build error / warnings.
>
> Then I generated the patch again Linus' kernel tree, tag 'v2.6.30-rc8' and sent the patch to you. This patch uses the new block layer APIs and is target for the linux-next tree.
>
> I guess the below build errors are caused by compiling the patch code in Linus' kernel tree. As the block layer API's in Linus' kernel tree is still the old one, it'll report this kind of 'implicit declaration of function ...' error. I'm sorry for the mis-communication.
>
> Now, I'm a bit confused with the process :-) Which git tree should I select to generate patch against and submit to? The linux-next tree or Linus' kerner tree?
One solution would be to generate the _main_ patch against Linus' tree
(for Greg to include in staging tree) and then generate _incremental_
patch with changes to account for block layer API update (for Stephen
to include in linux-next)..
Thanks.
Bart
On Friday 05 June 2009 01:26:10 Yunpeng Gao wrote:
[...]
> Subject: [PATCH] First submission of Intel Moorestown platform NAND flash driver
>
> This driver is a standalone linux block device driver. It acts as
> a normal hard disk. Please reference the README file for the detail.
>
> Signed-off-by: Gao Yunpeng <[email protected]>
[...]
> --- /dev/null
> +++ b/drivers/staging/mrst_nand/Kconfig
> @@ -0,0 +1,27 @@
> +
> +menuconfig MRST_NAND
> + tristate "Moorestown NAND Flash controller"
> + depends on BLOCK
> + default m
New drivers shouldn't be enabled by default.
Please remove the 'default m' line.
Thanks.
Bart
On Fri, Jun 05, 2009 at 08:58:19PM +0200, Bartlomiej Zolnierkiewicz wrote:
> On Friday 05 June 2009 05:31:21 Gao, Yunpeng wrote:
> > Hi Greg,
> >
> > Thanks for your quick response.
> >
> > The root cause of the build-errors in ffsport.c is that the kernel block layer APIs are different in linux-next tree (.../linux/kernel/git/sfr/linux-next.git) than in Linus' kernel tree (.../linux/kernel/git/torvalds/linux-2.6.git).
> >
> > Yesterday, after modify code in ffsport.c to sync up with the block layer APIs changes, I have make the kernel against linux-next tree and found no build error / warnings.
> >
> > Then I generated the patch again Linus' kernel tree, tag 'v2.6.30-rc8' and sent the patch to you. This patch uses the new block layer APIs and is target for the linux-next tree.
> >
> > I guess the below build errors are caused by compiling the patch code in Linus' kernel tree. As the block layer API's in Linus' kernel tree is still the old one, it'll report this kind of 'implicit declaration of function ...' error. I'm sorry for the mis-communication.
> >
> > Now, I'm a bit confused with the process :-) Which git tree should I select to generate patch against and submit to? The linux-next tree or Linus' kerner tree?
>
> One solution would be to generate the _main_ patch against Linus' tree
> (for Greg to include in staging tree) and then generate _incremental_
> patch with changes to account for block layer API update (for Stephen
> to include in linux-next)..
Yeah, that would be the best thing.
Sorry about this, but could you send me both patches? That way I can
merge them both properly when needed.
thanks,
greg k-h
> > +menuconfig MRST_NAND
> > + tristate "Moorestown NAND Flash controller"
> > + depends on BLOCK
> > + default m
>
> New drivers shouldn't be enabled by default.
I think that rather depends on the driver - in this case I'd tend to
agree as its not a common standard PC driver.
>-----Original Message-----
>From: Alan Cox [mailto:[email protected]]
>Sent: 2009??6??6?? 4:15
>To: Bartlomiej Zolnierkiewicz
>Cc: Gao, Yunpeng; Greg KH; [email protected]
>Subject: Re: linux-next: Tree for June 3 (staging)
>
>> > +menuconfig MRST_NAND
>> > + tristate "Moorestown NAND Flash controller"
>> > + depends on BLOCK
>> > + default m
>>
>> New drivers shouldn't be enabled by default.
>
>I think that rather depends on the driver - in this case I'd tend to
>agree as its not a common standard PC driver.
Thanks to Alan and Bartlomiej. I'll fix it to 'default n' and submit patches.
Thanks.
Rgds,
Yunpeng
????{.n?+???????+%?????ݶ??w??{.n?+????{??G?????{ay?ʇڙ?,j??f???h?????????z_??(?階?ݢj"???m??????G????????????&???~???iO???z??v?^?m????????????I?
>-----Original Message-----
>From: Bartlomiej Zolnierkiewicz [mailto:[email protected]]
>Sent: 2009??6??6?? 2:58
>To: Gao, Yunpeng
>Cc: Greg KH; Greg KH; [email protected]
>Subject: Re: linux-next: Tree for June 3 (staging)
>
>On Friday 05 June 2009 05:31:21 Gao, Yunpeng wrote:
>> Hi Greg,
>>
>> Thanks for your quick response.
>>
>> The root cause of the build-errors in ffsport.c is that the kernel block layer
>APIs are different in linux-next tree (.../linux/kernel/git/sfr/linux-next.git)
>than in Linus' kernel tree (.../linux/kernel/git/torvalds/linux-2.6.git).
>>
>> Yesterday, after modify code in ffsport.c to sync up with the block layer APIs
>changes, I have make the kernel against linux-next tree and found no build error
>/ warnings.
>>
>> Then I generated the patch again Linus' kernel tree, tag 'v2.6.30-rc8' and
>sent the patch to you. This patch uses the new block layer APIs and is target
>for the linux-next tree.
>>
>> I guess the below build errors are caused by compiling the patch code in Linus'
>kernel tree. As the block layer API's in Linus' kernel tree is still the old
>one, it'll report this kind of 'implicit declaration of function ...' error.
>I'm sorry for the mis-communication.
>>
>> Now, I'm a bit confused with the process :-) Which git tree should I select
>to generate patch against and submit to? The linux-next tree or Linus' kerner
>tree?
>
>One solution would be to generate the _main_ patch against Linus' tree
>(for Greg to include in staging tree) and then generate _incremental_
>patch with changes to account for block layer API update (for Stephen
>to include in linux-next)..
>
>Thanks.
>Bart
Hi Bart,
Thanks a lot for the good idea. I'll generate the two patches and send them to Greg then.
Thanks.
Rgds,
Yunpeng
????{.n?+???????+%?????ݶ??w??{.n?+????{??G?????{ay?ʇڙ?,j??f???h?????????z_??(?階?ݢj"???m??????G????????????&???~???iO???z??v?^?m????????????I?
On Sat, Jun 06, 2009 at 03:22:42AM +0800, Greg KH wrote:
> On Fri, Jun 05, 2009 at 08:58:19PM +0200, Bartlomiej Zolnierkiewicz wrote:
> > On Friday 05 June 2009 05:31:21 Gao, Yunpeng wrote:
> > > Hi Greg,
> > >
> > > Thanks for your quick response.
> > >
> > > The root cause of the build-errors in ffsport.c is that the kernel block layer APIs are different in linux-next tree (.../linux/kernel/git/sfr/linux-next.git) than in Linus' kernel tree (.../linux/kernel/git/torvalds/linux-2.6.git).
> > >
> > > Yesterday, after modify code in ffsport.c to sync up with the block layer APIs changes, I have make the kernel against linux-next tree and found no build error / warnings.
> > >
> > > Then I generated the patch again Linus' kernel tree, tag 'v2.6.30-rc8' and sent the patch to you. This patch uses the new block layer APIs and is target for the linux-next tree.
> > >
> > > I guess the below build errors are caused by compiling the patch code in Linus' kernel tree. As the block layer API's in Linus' kernel tree is still the old one, it'll report this kind of 'implicit declaration of function ...' error. I'm sorry for the mis-communication.
> > >
> > > Now, I'm a bit confused with the process :-) Which git tree should I select to generate patch against and submit to? The linux-next tree or Linus' kerner tree?
> >
> > One solution would be to generate the _main_ patch against Linus' tree
> > (for Greg to include in staging tree) and then generate _incremental_
> > patch with changes to account for block layer API update (for Stephen
> > to include in linux-next)..
>
> Yeah, that would be the best thing.
>
> Sorry about this, but could you send me both patches? That way I can
> merge them both properly when needed.
>
> thanks,
>
> greg k-h
Hi Greg,
I have generated the two patches following what Bartlomiej suggested.
The first one is the _main_ patch against Linus' kernel tree
(tag v2.6.30-rc8) and the second one is an _incremental patch
accounting for the block layer API update in linux-next tree.
I'll send both of them to you later.
Thanks.
Rgd,
Yunpeng
On Freitag, 5. Juni 2009 12:01:03 Karsten Keil wrote:
> Hi,
>
> I'm currently see this too from time to time, but have no idea about it.
>
...
> > > [88563.318126] ------------[ cut here ]------------
> > > [88563.318129] WARNING: at kernel/softirq.c:124
> > > local_bh_enable+0x8f/0xb0() [88563.318130] Hardware name: empty
> > > [88563.318132] Modules linked in: usbtouchscreen dvb_usb_cinergyT2
> > > dummy bonding snd_emu10k1 snd_rawmidi snd_ac97_codec ath9k ac97_bus
> > > snd_pcm snd_page_alloc snd_util_mem forcedeth snd_hwdep
> > > [88563.318141] Pid: 826, comm: mISDN_hfc-pci.1 Not tainted
> > > 2.6.29.4-grsec #13 [88563.318142] Call Trace:
> > > [88563.318147] [<ffffffff8025909a>] warn_slowpath+0xea/0x160
> > > [88563.318149] [<ffffffff8025ee0f>] local_bh_enable+0x8f/0xb0
> > > [88563.318152] [<ffffffff8065f284>] sk_filter+0x44/0xa0
> > > [88563.318154] [<ffffffff8064548d>] sock_queue_rcv_skb+0x5d/0x120
> > > [88563.318156] [<ffffffff8060410f>] mISDN_send+0x4f/0xa0
> > > [88563.318159] [<ffffffff8060790e>] l2up_create+0x7e/0x100
> > > [88563.318161] [<ffffffff8060b6e0>] l2_got_tei+0x0/0x90
> > > [88563.318163] [<ffffffff8060b722>] l2_got_tei+0x42/0x90
> > > [88563.318164] [<ffffffff80602d32>] mISDN_FsmEvent+0x82/0x100
> > > [88563.318167] [<ffffffff8060cb00>] tei_id_assign+0x0/0x120
> > > [88563.318168] [<ffffffff80602d32>] mISDN_FsmEvent+0x82/0x100
> > > [88563.318170] [<ffffffff8060e373>] mgr_send+0x4d3/0x660
OK found it, it was in a inlined function call ph_data_ind() in mgr_send().
This patch should fix it (will send it upstream later).
From: Karsten Keil <[email protected]>
Date: Tue, 9 Jun 2009 14:38:39 +0200
Subject: [PATCH] mISDN: Do not disable IRQ in ph_data_ind()
This fix triggering the WARN_ON_ONCE(in_irq() || irqs_disabled()); in
local_bh_enable().
Here is no need to grab this lock, this was wrong at all and may
cause a deadlock and access to freed memory, since on a TEI remove
the current listelement can be deleted under us. So this is clearly
a case for list_for_each_entry_safe.
Signed-off-by: Karsten Keil <[email protected]>
---
drivers/isdn/mISDN/tei.c | 7 ++-----
1 files changed, 2 insertions(+), 5 deletions(-)
diff --git a/drivers/isdn/mISDN/tei.c b/drivers/isdn/mISDN/tei.c
index bfcdd97..e04bad6 100644
--- a/drivers/isdn/mISDN/tei.c
+++ b/drivers/isdn/mISDN/tei.c
@@ -862,8 +862,7 @@ static int
ph_data_ind(struct manager *mgr, struct sk_buff *skb)
{
int ret = -EINVAL;
- struct layer2 *l2;
- u_long flags;
+ struct layer2 *l2, *nl2;
u_char mt;
if (skb->len < 8) {
@@ -908,11 +907,9 @@ ph_data_ind(struct manager *mgr, struct sk_buff *skb)
new_tei_req(mgr, &skb->data[4]);
goto done;
}
- read_lock_irqsave(&mgr->lock, flags);
- list_for_each_entry(l2, &mgr->layer2, list) {
+ list_for_each_entry_safe(l2, nl2, &mgr->layer2, list) {
tei_ph_data_ind(l2->tm, mt, &skb->data[4], skb->len - 4);
}
- read_unlock_irqrestore(&mgr->lock, flags);
done:
return ret;
}
--
1.6.0.2
Hi Karsten,
applied your patch. Not sure if it fixed anything, though.
Attached is another call trace which looks slightly different.
Cheers,
Mathias
On Tuesday 09 June 2009 15:05:31 Karsten Keil wrote:
> On Freitag, 5. Juni 2009 12:01:03 Karsten Keil wrote:
> > Hi,
> >
> > I'm currently see this too from time to time, but have no idea about it.
>
> ...
>
> > > > [88563.318126] ------------[ cut here ]------------
> > > > [88563.318129] WARNING: at kernel/softirq.c:124
> > > > local_bh_enable+0x8f/0xb0() [88563.318130] Hardware name: empty
> > > > [88563.318132] Modules linked in: usbtouchscreen dvb_usb_cinergyT2
> > > > dummy bonding snd_emu10k1 snd_rawmidi snd_ac97_codec ath9k ac97_bus
> > > > snd_pcm snd_page_alloc snd_util_mem forcedeth snd_hwdep
> > > > [88563.318141] Pid: 826, comm: mISDN_hfc-pci.1 Not tainted
> > > > 2.6.29.4-grsec #13 [88563.318142] Call Trace:
> > > > [88563.318147] [<ffffffff8025909a>] warn_slowpath+0xea/0x160
> > > > [88563.318149] [<ffffffff8025ee0f>] local_bh_enable+0x8f/0xb0
> > > > [88563.318152] [<ffffffff8065f284>] sk_filter+0x44/0xa0
> > > > [88563.318154] [<ffffffff8064548d>] sock_queue_rcv_skb+0x5d/0x120
> > > > [88563.318156] [<ffffffff8060410f>] mISDN_send+0x4f/0xa0
> > > > [88563.318159] [<ffffffff8060790e>] l2up_create+0x7e/0x100
> > > > [88563.318161] [<ffffffff8060b6e0>] l2_got_tei+0x0/0x90
> > > > [88563.318163] [<ffffffff8060b722>] l2_got_tei+0x42/0x90
> > > > [88563.318164] [<ffffffff80602d32>] mISDN_FsmEvent+0x82/0x100
> > > > [88563.318167] [<ffffffff8060cb00>] tei_id_assign+0x0/0x120
> > > > [88563.318168] [<ffffffff80602d32>] mISDN_FsmEvent+0x82/0x100
> > > > [88563.318170] [<ffffffff8060e373>] mgr_send+0x4d3/0x660
>
> OK found it, it was in a inlined function call ph_data_ind() in mgr_send().
>
> This patch should fix it (will send it upstream later).
>
>
> From: Karsten Keil <[email protected]>
> Date: Tue, 9 Jun 2009 14:38:39 +0200
> Subject: [PATCH] mISDN: Do not disable IRQ in ph_data_ind()
>
>
> This fix triggering the WARN_ON_ONCE(in_irq() || irqs_disabled()); in
> local_bh_enable().
>
> Here is no need to grab this lock, this was wrong at all and may
> cause a deadlock and access to freed memory, since on a TEI remove
> the current listelement can be deleted under us. So this is clearly
> a case for list_for_each_entry_safe.
>
> Signed-off-by: Karsten Keil <[email protected]>
> ---
> drivers/isdn/mISDN/tei.c | 7 ++-----
> 1 files changed, 2 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/isdn/mISDN/tei.c b/drivers/isdn/mISDN/tei.c
> index bfcdd97..e04bad6 100644
> --- a/drivers/isdn/mISDN/tei.c
> +++ b/drivers/isdn/mISDN/tei.c
> @@ -862,8 +862,7 @@ static int
> ph_data_ind(struct manager *mgr, struct sk_buff *skb)
> {
> int ret = -EINVAL;
> - struct layer2 *l2;
> - u_long flags;
> + struct layer2 *l2, *nl2;
> u_char mt;
>
> if (skb->len < 8) {
> @@ -908,11 +907,9 @@ ph_data_ind(struct manager *mgr, struct sk_buff *skb)
> new_tei_req(mgr, &skb->data[4]);
> goto done;
> }
> - read_lock_irqsave(&mgr->lock, flags);
> - list_for_each_entry(l2, &mgr->layer2, list) {
> + list_for_each_entry_safe(l2, nl2, &mgr->layer2, list) {
> tei_ph_data_ind(l2->tm, mt, &skb->data[4], skb->len - 4);
> }
> - read_unlock_irqrestore(&mgr->lock, flags);
> done:
> return ret;
> }