merge -r931:HEAD svn://yak/vol/projekte/msr_messen_steuern_regeln/ethercat/rep/trunk . stable-1.3
authorFlorian Pose <fp@igh-essen.com>
Wed, 03 Oct 2007 08:58:01 +0000
branchstable-1.3
changeset 1746 72e7507b3f1b
parent 1745 07fd94c5119d
child 1747 b6f23874f8d5
merge -r931:HEAD svn://yak/vol/projekte/msr_messen_steuern_regeln/ethercat/rep/trunk .
Doxyfile
Doxyfile.in
Kbuild
Kbuild.in
Makefile.am
NEWS
TODO
configure.ac
devices/Kbuild
devices/Kbuild.in
devices/Makefile.am
devices/e1000/Kbuild
devices/e1000/Kbuild.in
devices/e1000/Makefile.am
devices/e1000/e1000_main-2.6.13-ethercat.c
documentation/graphs/Makefile
documentation/graphs/fsm_coe_map.dot
dummy/Kbuild
dummy/Kbuild.in
dummy/Makefile.am
examples/mini/Kbuild
examples/mini/Kbuild.in
examples/mini/Makefile.am
examples/msr/Kbuild
examples/msr/Kbuild.in
examples/msr/Makefile.am
examples/rtai/Kbuild
examples/rtai/Kbuild.in
examples/rtai/Makefile.am
include/ecdb.h
include/ecrt.h
master/Kbuild
master/Kbuild.in
master/Makefile.am
master/canopen.c
master/canopen.h
master/datagram.c
master/device.c
master/device.h
master/fsm_change.c
master/fsm_change.h
master/fsm_coe.c
master/fsm_coe_map.c
master/fsm_coe_map.h
master/fsm_mapping.c
master/fsm_mapping.h
master/fsm_master.c
master/fsm_master.h
master/fsm_sii.c
master/fsm_sii.h
master/fsm_slave.c
master/fsm_slave.h
master/globals.h
master/master.c
master/master.h
master/module.c
master/slave.c
master/slave.h
master/sync.c
master/sync.h
--- a/Doxyfile	Thu Sep 13 11:08:46 2007 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1228 +0,0 @@
-# Doxyfile 1.4.4
-
-# This file describes the settings to be used by the documentation system
-# doxygen (www.doxygen.org) for a project
-#
-# All text after a hash (#) is considered a comment and will be ignored
-# The format is:
-#       TAG = value [value, ...]
-# For lists items can also be appended using:
-#       TAG += value [value, ...]
-# Values that contain spaces should be placed between quotes (" ")
-
-#---------------------------------------------------------------------------
-# Project related configuration options
-#---------------------------------------------------------------------------
-
-# The PROJECT_NAME tag is a single word (or a sequence of words surrounded 
-# by quotes) that should identify the project.
-
-PROJECT_NAME           = "IgH EtherCAT master"
-
-# The PROJECT_NUMBER tag can be used to enter a project or revision number. 
-# This could be handy for archiving the generated documentation or 
-# if some version control system is used.
-
-PROJECT_NUMBER         = 1.2
-
-# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) 
-# base path where the generated documentation will be put. 
-# If a relative path is entered, it will be relative to the location 
-# where doxygen was started. If left blank the current directory will be used.
-
-OUTPUT_DIRECTORY       = doxygen-output
-
-# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create 
-# 4096 sub-directories (in 2 levels) under the output directory of each output 
-# format and will distribute the generated files over these directories. 
-# Enabling this option can be useful when feeding doxygen a huge amount of 
-# source files, where putting all generated files in the same directory would 
-# otherwise cause performance problems for the file system.
-
-CREATE_SUBDIRS         = NO
-
-# The OUTPUT_LANGUAGE tag is used to specify the language in which all 
-# documentation generated by doxygen is written. Doxygen will use this 
-# information to generate all constant output in the proper language. 
-# The default language is English, other supported languages are: 
-# Brazilian, Catalan, Chinese, Chinese-Traditional, Croatian, Czech, Danish, 
-# Dutch, Finnish, French, German, Greek, Hungarian, Italian, Japanese, 
-# Japanese-en (Japanese with English messages), Korean, Korean-en, Norwegian, 
-# Polish, Portuguese, Romanian, Russian, Serbian, Slovak, Slovene, Spanish, 
-# Swedish, and Ukrainian.
-
-OUTPUT_LANGUAGE        = English
-
-# This tag can be used to specify the encoding used in the generated output. 
-# The encoding is not always determined by the language that is chosen, 
-# but also whether or not the output is meant for Windows or non-Windows users. 
-# In case there is a difference, setting the USE_WINDOWS_ENCODING tag to YES 
-# forces the Windows encoding (this is the default for the Windows binary), 
-# whereas setting the tag to NO uses a Unix-style encoding (the default for 
-# all platforms other than Windows).
-
-USE_WINDOWS_ENCODING   = NO
-
-# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will 
-# include brief member descriptions after the members that are listed in 
-# the file and class documentation (similar to JavaDoc). 
-# Set to NO to disable this.
-
-BRIEF_MEMBER_DESC      = YES
-
-# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend 
-# the brief description of a member or function before the detailed description. 
-# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the 
-# brief descriptions will be completely suppressed.
-
-REPEAT_BRIEF           = YES
-
-# This tag implements a quasi-intelligent brief description abbreviator 
-# that is used to form the text in various listings. Each string 
-# in this list, if found as the leading text of the brief description, will be 
-# stripped from the text and the result after processing the whole list, is 
-# used as the annotated text. Otherwise, the brief description is used as-is. 
-# If left blank, the following values are used ("$name" is automatically 
-# replaced with the name of the entity): "The $name class" "The $name widget" 
-# "The $name file" "is" "provides" "specifies" "contains" 
-# "represents" "a" "an" "the"
-
-ABBREVIATE_BRIEF       = 
-
-# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then 
-# Doxygen will generate a detailed section even if there is only a brief 
-# description.
-
-ALWAYS_DETAILED_SEC    = NO
-
-# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all 
-# inherited members of a class in the documentation of that class as if those 
-# members were ordinary class members. Constructors, destructors and assignment 
-# operators of the base classes will not be shown.
-
-INLINE_INHERITED_MEMB  = NO
-
-# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full 
-# path before files name in the file list and in the header files. If set 
-# to NO the shortest path that makes the file name unique will be used.
-
-FULL_PATH_NAMES        = NO
-
-# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag 
-# can be used to strip a user-defined part of the path. Stripping is 
-# only done if one of the specified strings matches the left-hand part of 
-# the path. The tag can be used to show relative paths in the file list. 
-# If left blank the directory from which doxygen is run is used as the 
-# path to strip.
-
-STRIP_FROM_PATH        = 
-
-# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of 
-# the path mentioned in the documentation of a class, which tells 
-# the reader which header file to include in order to use a class. 
-# If left blank only the name of the header file containing the class 
-# definition is used. Otherwise one should specify the include paths that 
-# are normally passed to the compiler using the -I flag.
-
-STRIP_FROM_INC_PATH    = 
-
-# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter 
-# (but less readable) file names. This can be useful is your file systems 
-# doesn't support long names like on DOS, Mac, or CD-ROM.
-
-SHORT_NAMES            = NO
-
-# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen 
-# will interpret the first line (until the first dot) of a JavaDoc-style 
-# comment as the brief description. If set to NO, the JavaDoc 
-# comments will behave just like the Qt-style comments (thus requiring an 
-# explicit @brief command for a brief description.
-
-JAVADOC_AUTOBRIEF      = YES
-
-# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen 
-# treat a multi-line C++ special comment block (i.e. a block of //! or /// 
-# comments) as a brief description. This used to be the default behaviour. 
-# The new default is to treat a multi-line C++ comment block as a detailed 
-# description. Set this tag to YES if you prefer the old behaviour instead.
-
-MULTILINE_CPP_IS_BRIEF = YES
-
-# If the DETAILS_AT_TOP tag is set to YES then Doxygen 
-# will output the detailed description near the top, like JavaDoc.
-# If set to NO, the detailed description appears after the member 
-# documentation.
-
-DETAILS_AT_TOP         = YES
-
-# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented 
-# member inherits the documentation from any documented member that it 
-# re-implements.
-
-INHERIT_DOCS           = YES
-
-# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC 
-# tag is set to YES, then doxygen will reuse the documentation of the first 
-# member in the group (if any) for the other members of the group. By default 
-# all members of a group must be documented explicitly.
-
-DISTRIBUTE_GROUP_DOC   = NO
-
-# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce 
-# a new page for each member. If set to NO, the documentation of a member will 
-# be part of the file/class/namespace that contains it.
-
-SEPARATE_MEMBER_PAGES  = NO
-
-# The TAB_SIZE tag can be used to set the number of spaces in a tab. 
-# Doxygen uses this value to replace tabs by spaces in code fragments.
-
-TAB_SIZE               = 4
-
-# This tag can be used to specify a number of aliases that acts 
-# as commands in the documentation. An alias has the form "name=value". 
-# For example adding "sideeffect=\par Side Effects:\n" will allow you to 
-# put the command \sideeffect (or @sideeffect) in the documentation, which 
-# will result in a user-defined paragraph with heading "Side Effects:". 
-# You can put \n's in the value part of an alias to insert newlines.
-
-ALIASES                = 
-
-# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C 
-# sources only. Doxygen will then generate output that is more tailored for C. 
-# For instance, some of the names that are used will be different. The list 
-# of all members will be omitted, etc.
-
-OPTIMIZE_OUTPUT_FOR_C  = YES
-
-# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java sources 
-# only. Doxygen will then generate output that is more tailored for Java. 
-# For instance, namespaces will be presented as packages, qualified scopes 
-# will look different, etc.
-
-OPTIMIZE_OUTPUT_JAVA   = NO
-
-# Set the SUBGROUPING tag to YES (the default) to allow class member groups of 
-# the same type (for instance a group of public functions) to be put as a 
-# subgroup of that type (e.g. under the Public Functions section). Set it to 
-# NO to prevent subgrouping. Alternatively, this can be done per class using 
-# the \nosubgrouping command.
-
-SUBGROUPING            = YES
-
-#---------------------------------------------------------------------------
-# Build related configuration options
-#---------------------------------------------------------------------------
-
-# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in 
-# documentation are documented, even if no documentation was available. 
-# Private class members and static file members will be hidden unless 
-# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES
-
-EXTRACT_ALL            = NO
-
-# If the EXTRACT_PRIVATE tag is set to YES all private members of a class 
-# will be included in the documentation.
-
-EXTRACT_PRIVATE        = YES
-
-# If the EXTRACT_STATIC tag is set to YES all static members of a file 
-# will be included in the documentation.
-
-EXTRACT_STATIC         = YES
-
-# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) 
-# defined locally in source files will be included in the documentation. 
-# If set to NO only classes defined in header files are included.
-
-EXTRACT_LOCAL_CLASSES  = YES
-
-# This flag is only useful for Objective-C code. When set to YES local 
-# methods, which are defined in the implementation section but not in 
-# the interface are included in the documentation. 
-# If set to NO (the default) only methods in the interface are included.
-
-EXTRACT_LOCAL_METHODS  = YES
-
-# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all 
-# undocumented members of documented classes, files or namespaces. 
-# If set to NO (the default) these members will be included in the 
-# various overviews, but no documentation section is generated. 
-# This option has no effect if EXTRACT_ALL is enabled.
-
-HIDE_UNDOC_MEMBERS     = NO
-
-# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all 
-# undocumented classes that are normally visible in the class hierarchy. 
-# If set to NO (the default) these classes will be included in the various 
-# overviews. This option has no effect if EXTRACT_ALL is enabled.
-
-HIDE_UNDOC_CLASSES     = NO
-
-# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all 
-# friend (class|struct|union) declarations. 
-# If set to NO (the default) these declarations will be included in the 
-# documentation.
-
-HIDE_FRIEND_COMPOUNDS  = NO
-
-# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any 
-# documentation blocks found inside the body of a function. 
-# If set to NO (the default) these blocks will be appended to the 
-# function's detailed documentation block.
-
-HIDE_IN_BODY_DOCS      = NO
-
-# The INTERNAL_DOCS tag determines if documentation 
-# that is typed after a \internal command is included. If the tag is set 
-# to NO (the default) then the documentation will be excluded. 
-# Set it to YES to include the internal documentation.
-
-INTERNAL_DOCS          = NO
-
-# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate 
-# file names in lower-case letters. If set to YES upper-case letters are also 
-# allowed. This is useful if you have classes or files whose names only differ 
-# in case and if your file system supports case sensitive file names. Windows 
-# and Mac users are advised to set this option to NO.
-
-CASE_SENSE_NAMES       = YES
-
-# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen 
-# will show members with their full class and namespace scopes in the 
-# documentation. If set to YES the scope will be hidden.
-
-HIDE_SCOPE_NAMES       = NO
-
-# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen 
-# will put a list of the files that are included by a file in the documentation 
-# of that file.
-
-SHOW_INCLUDE_FILES     = NO
-
-# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] 
-# is inserted in the documentation for inline members.
-
-INLINE_INFO            = YES
-
-# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen 
-# will sort the (detailed) documentation of file and class members 
-# alphabetically by member name. If set to NO the members will appear in 
-# declaration order.
-
-SORT_MEMBER_DOCS       = NO
-
-# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the 
-# brief documentation of file, namespace and class members alphabetically 
-# by member name. If set to NO (the default) the members will appear in 
-# declaration order.
-
-SORT_BRIEF_DOCS        = NO
-
-# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be 
-# sorted by fully-qualified names, including namespaces. If set to 
-# NO (the default), the class list will be sorted only by class name, 
-# not including the namespace part. 
-# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES.
-# Note: This option applies only to the class list, not to the 
-# alphabetical list.
-
-SORT_BY_SCOPE_NAME     = NO
-
-# The GENERATE_TODOLIST tag can be used to enable (YES) or 
-# disable (NO) the todo list. This list is created by putting \todo 
-# commands in the documentation.
-
-GENERATE_TODOLIST      = YES
-
-# The GENERATE_TESTLIST tag can be used to enable (YES) or 
-# disable (NO) the test list. This list is created by putting \test 
-# commands in the documentation.
-
-GENERATE_TESTLIST      = NO
-
-# The GENERATE_BUGLIST tag can be used to enable (YES) or 
-# disable (NO) the bug list. This list is created by putting \bug 
-# commands in the documentation.
-
-GENERATE_BUGLIST       = NO
-
-# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or 
-# disable (NO) the deprecated list. This list is created by putting 
-# \deprecated commands in the documentation.
-
-GENERATE_DEPRECATEDLIST= NO
-
-# The ENABLED_SECTIONS tag can be used to enable conditional 
-# documentation sections, marked by \if sectionname ... \endif.
-
-ENABLED_SECTIONS       = 
-
-# The MAX_INITIALIZER_LINES tag determines the maximum number of lines 
-# the initial value of a variable or define consists of for it to appear in 
-# the documentation. If the initializer consists of more lines than specified 
-# here it will be hidden. Use a value of 0 to hide initializers completely. 
-# The appearance of the initializer of individual variables and defines in the 
-# documentation can be controlled using \showinitializer or \hideinitializer 
-# command in the documentation regardless of this setting.
-
-MAX_INITIALIZER_LINES  = 30
-
-# Set the SHOW_USED_FILES tag to NO to disable the list of files generated 
-# at the bottom of the documentation of classes and structs. If set to YES the 
-# list will mention the files that were used to generate the documentation.
-
-SHOW_USED_FILES        = NO
-
-# If the sources in your project are distributed over multiple directories 
-# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy 
-# in the documentation. The default is YES.
-
-SHOW_DIRECTORIES       = YES
-
-# The FILE_VERSION_FILTER tag can be used to specify a program or script that 
-# doxygen should invoke to get the current version for each file (typically from the 
-# version control system). Doxygen will invoke the program by executing (via 
-# popen()) the command <command> <input-file>, where <command> is the value of 
-# the FILE_VERSION_FILTER tag, and <input-file> is the name of an input file 
-# provided by doxygen. Whatever the progam writes to standard output 
-# is used as the file version. See the manual for examples.
-
-FILE_VERSION_FILTER    = 
-
-#---------------------------------------------------------------------------
-# configuration options related to warning and progress messages
-#---------------------------------------------------------------------------
-
-# The QUIET tag can be used to turn on/off the messages that are generated 
-# by doxygen. Possible values are YES and NO. If left blank NO is used.
-
-QUIET                  = YES
-
-# The WARNINGS tag can be used to turn on/off the warning messages that are 
-# generated by doxygen. Possible values are YES and NO. If left blank 
-# NO is used.
-
-WARNINGS               = YES
-
-# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings 
-# for undocumented members. If EXTRACT_ALL is set to YES then this flag will 
-# automatically be disabled.
-
-WARN_IF_UNDOCUMENTED   = YES
-
-# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for 
-# potential errors in the documentation, such as not documenting some 
-# parameters in a documented function, or documenting parameters that 
-# don't exist or using markup commands wrongly.
-
-WARN_IF_DOC_ERROR      = YES
-
-# This WARN_NO_PARAMDOC option can be abled to get warnings for 
-# functions that are documented, but have no documentation for their parameters 
-# or return value. If set to NO (the default) doxygen will only warn about 
-# wrong or incomplete parameter documentation, but not about the absence of 
-# documentation.
-
-WARN_NO_PARAMDOC       = YES
-
-# The WARN_FORMAT tag determines the format of the warning messages that 
-# doxygen can produce. The string should contain the $file, $line, and $text 
-# tags, which will be replaced by the file and line number from which the 
-# warning originated and the warning text. Optionally the format may contain 
-# $version, which will be replaced by the version of the file (if it could 
-# be obtained via FILE_VERSION_FILTER)
-
-WARN_FORMAT            = "$file:$line: $text"
-
-# The WARN_LOGFILE tag can be used to specify a file to which warning 
-# and error messages should be written. If left blank the output is written 
-# to stderr.
-
-WARN_LOGFILE           = 
-
-#---------------------------------------------------------------------------
-# configuration options related to the input files
-#---------------------------------------------------------------------------
-
-# The INPUT tag can be used to specify the files and/or directories that contain 
-# documented source files. You may enter file names like "myfile.cpp" or 
-# directories like "/usr/src/myproject". Separate the files or directories 
-# with spaces.
-
-INPUT                  = master include devices/ecdev.h
-
-# If the value of the INPUT tag contains directories, you can use the 
-# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp 
-# and *.h) to filter out the source-files in the directories. If left 
-# blank the following patterns are tested: 
-# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx 
-# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm
-
-FILE_PATTERNS          = 
-
-# The RECURSIVE tag can be used to turn specify whether or not subdirectories 
-# should be searched for input files as well. Possible values are YES and NO. 
-# If left blank NO is used.
-
-RECURSIVE              = NO
-
-# The EXCLUDE tag can be used to specify files and/or directories that should 
-# excluded from the INPUT source files. This way you can easily exclude a 
-# subdirectory from a directory tree whose root is specified with the INPUT tag.
-
-EXCLUDE                = 
-
-# The EXCLUDE_SYMLINKS tag can be used select whether or not files or 
-# directories that are symbolic links (a Unix filesystem feature) are excluded 
-# from the input.
-
-EXCLUDE_SYMLINKS       = NO
-
-# If the value of the INPUT tag contains directories, you can use the 
-# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude 
-# certain files from those directories. Note that the wildcards are matched 
-# against the file with absolute path, so to exclude all test directories 
-# for example use the pattern */test/*
-
-EXCLUDE_PATTERNS       = *.mod.c
-
-# The EXAMPLE_PATH tag can be used to specify one or more files or 
-# directories that contain example code fragments that are included (see 
-# the \include command).
-
-EXAMPLE_PATH           = 
-
-# If the value of the EXAMPLE_PATH tag contains directories, you can use the 
-# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp 
-# and *.h) to filter out the source-files in the directories. If left 
-# blank all files are included.
-
-EXAMPLE_PATTERNS       = 
-
-# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be 
-# searched for input files to be used with the \include or \dontinclude 
-# commands irrespective of the value of the RECURSIVE tag. 
-# Possible values are YES and NO. If left blank NO is used.
-
-EXAMPLE_RECURSIVE      = NO
-
-# The IMAGE_PATH tag can be used to specify one or more files or 
-# directories that contain image that are included in the documentation (see 
-# the \image command).
-
-IMAGE_PATH             = 
-
-# The INPUT_FILTER tag can be used to specify a program that doxygen should 
-# invoke to filter for each input file. Doxygen will invoke the filter program 
-# by executing (via popen()) the command <filter> <input-file>, where <filter> 
-# is the value of the INPUT_FILTER tag, and <input-file> is the name of an 
-# input file. Doxygen will then use the output that the filter program writes 
-# to standard output.  If FILTER_PATTERNS is specified, this tag will be 
-# ignored.
-
-INPUT_FILTER           = 
-
-# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern 
-# basis.  Doxygen will compare the file name with each pattern and apply the 
-# filter if there is a match.  The filters are a list of the form: 
-# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further 
-# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER 
-# is applied to all files.
-
-FILTER_PATTERNS        = 
-
-# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using 
-# INPUT_FILTER) will be used to filter the input files when producing source 
-# files to browse (i.e. when SOURCE_BROWSER is set to YES).
-
-FILTER_SOURCE_FILES    = NO
-
-#---------------------------------------------------------------------------
-# configuration options related to source browsing
-#---------------------------------------------------------------------------
-
-# If the SOURCE_BROWSER tag is set to YES then a list of source files will 
-# be generated. Documented entities will be cross-referenced with these sources. 
-# Note: To get rid of all source code in the generated output, make sure also 
-# VERBATIM_HEADERS is set to NO.
-
-SOURCE_BROWSER         = YES
-
-# Setting the INLINE_SOURCES tag to YES will include the body 
-# of functions and classes directly in the documentation.
-
-INLINE_SOURCES         = NO
-
-# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct 
-# doxygen to hide any special comment blocks from generated source code 
-# fragments. Normal C and C++ comments will always remain visible.
-
-STRIP_CODE_COMMENTS    = YES
-
-# If the REFERENCED_BY_RELATION tag is set to YES (the default) 
-# then for each documented function all documented 
-# functions referencing it will be listed.
-
-REFERENCED_BY_RELATION = NO
-
-# If the REFERENCES_RELATION tag is set to YES (the default) 
-# then for each documented function all documented entities 
-# called/used by that function will be listed.
-
-REFERENCES_RELATION    = NO
-
-# If the USE_HTAGS tag is set to YES then the references to source code 
-# will point to the HTML generated by the htags(1) tool instead of doxygen 
-# built-in source browser. The htags tool is part of GNU's global source 
-# tagging system (see http://www.gnu.org/software/global/global.html). You 
-# will need version 4.8.6 or higher.
-
-USE_HTAGS              = NO
-
-# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen 
-# will generate a verbatim copy of the header file for each class for 
-# which an include is specified. Set to NO to disable this.
-
-VERBATIM_HEADERS       = YES
-
-#---------------------------------------------------------------------------
-# configuration options related to the alphabetical class index
-#---------------------------------------------------------------------------
-
-# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index 
-# of all compounds will be generated. Enable this if the project 
-# contains a lot of classes, structs, unions or interfaces.
-
-ALPHABETICAL_INDEX     = NO
-
-# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then 
-# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns 
-# in which this list will be split (can be a number in the range [1..20])
-
-COLS_IN_ALPHA_INDEX    = 5
-
-# In case all classes in a project start with a common prefix, all 
-# classes will be put under the same header in the alphabetical index. 
-# The IGNORE_PREFIX tag can be used to specify one or more prefixes that 
-# should be ignored while generating the index headers.
-
-IGNORE_PREFIX          = 
-
-#---------------------------------------------------------------------------
-# configuration options related to the HTML output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_HTML tag is set to YES (the default) Doxygen will 
-# generate HTML output.
-
-GENERATE_HTML          = YES
-
-# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. 
-# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
-# put in front of it. If left blank `html' will be used as the default path.
-
-HTML_OUTPUT            = html
-
-# The HTML_FILE_EXTENSION tag can be used to specify the file extension for 
-# each generated HTML page (for example: .htm,.php,.asp). If it is left blank 
-# doxygen will generate files with .html extension.
-
-HTML_FILE_EXTENSION    = .html
-
-# The HTML_HEADER tag can be used to specify a personal HTML header for 
-# each generated HTML page. If it is left blank doxygen will generate a 
-# standard header.
-
-HTML_HEADER            = 
-
-# The HTML_FOOTER tag can be used to specify a personal HTML footer for 
-# each generated HTML page. If it is left blank doxygen will generate a 
-# standard footer.
-
-HTML_FOOTER            = 
-
-# The HTML_STYLESHEET tag can be used to specify a user-defined cascading 
-# style sheet that is used by each HTML page. It can be used to 
-# fine-tune the look of the HTML output. If the tag is left blank doxygen 
-# will generate a default style sheet. Note that doxygen will try to copy 
-# the style sheet file to the HTML output directory, so don't put your own 
-# stylesheet in the HTML output directory as well, or it will be erased!
-
-HTML_STYLESHEET        = 
-
-# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, 
-# files or namespaces will be aligned in HTML using tables. If set to 
-# NO a bullet list will be used.
-
-HTML_ALIGN_MEMBERS     = YES
-
-# If the GENERATE_HTMLHELP tag is set to YES, additional index files 
-# will be generated that can be used as input for tools like the 
-# Microsoft HTML help workshop to generate a compressed HTML help file (.chm) 
-# of the generated HTML documentation.
-
-GENERATE_HTMLHELP      = NO
-
-# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can 
-# be used to specify the file name of the resulting .chm file. You 
-# can add a path in front of the file if the result should not be 
-# written to the html output directory.
-
-CHM_FILE               = 
-
-# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can 
-# be used to specify the location (absolute path including file name) of 
-# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run 
-# the HTML help compiler on the generated index.hhp.
-
-HHC_LOCATION           = 
-
-# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag 
-# controls if a separate .chi index file is generated (YES) or that 
-# it should be included in the master .chm file (NO).
-
-GENERATE_CHI           = NO
-
-# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag 
-# controls whether a binary table of contents is generated (YES) or a 
-# normal table of contents (NO) in the .chm file.
-
-BINARY_TOC             = NO
-
-# The TOC_EXPAND flag can be set to YES to add extra items for group members 
-# to the contents of the HTML help documentation and to the tree view.
-
-TOC_EXPAND             = NO
-
-# The DISABLE_INDEX tag can be used to turn on/off the condensed index at 
-# top of each HTML page. The value NO (the default) enables the index and 
-# the value YES disables it.
-
-DISABLE_INDEX          = NO
-
-# This tag can be used to set the number of enum values (range [1..20]) 
-# that doxygen will group on one line in the generated HTML documentation.
-
-ENUM_VALUES_PER_LINE   = 4
-
-# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be
-# generated containing a tree-like index structure (just like the one that 
-# is generated for HTML Help). For this to work a browser that supports 
-# JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+, 
-# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are 
-# probably better off using the HTML help feature.
-
-GENERATE_TREEVIEW      = YES
-
-# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be 
-# used to set the initial width (in pixels) of the frame in which the tree 
-# is shown.
-
-TREEVIEW_WIDTH         = 250
-
-#---------------------------------------------------------------------------
-# configuration options related to the LaTeX output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will 
-# generate Latex output.
-
-GENERATE_LATEX         = YES
-
-# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. 
-# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
-# put in front of it. If left blank `latex' will be used as the default path.
-
-LATEX_OUTPUT           = latex
-
-# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be 
-# invoked. If left blank `latex' will be used as the default command name.
-
-LATEX_CMD_NAME         = latex
-
-# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to 
-# generate index for LaTeX. If left blank `makeindex' will be used as the 
-# default command name.
-
-MAKEINDEX_CMD_NAME     = makeindex
-
-# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact 
-# LaTeX documents. This may be useful for small projects and may help to 
-# save some trees in general.
-
-COMPACT_LATEX          = NO
-
-# The PAPER_TYPE tag can be used to set the paper type that is used 
-# by the printer. Possible values are: a4, a4wide, letter, legal and 
-# executive. If left blank a4wide will be used.
-
-PAPER_TYPE             = a4wide
-
-# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX 
-# packages that should be included in the LaTeX output.
-
-EXTRA_PACKAGES         = 
-
-# The LATEX_HEADER tag can be used to specify a personal LaTeX header for 
-# the generated latex document. The header should contain everything until 
-# the first chapter. If it is left blank doxygen will generate a 
-# standard header. Notice: only use this tag if you know what you are doing!
-
-LATEX_HEADER           = 
-
-# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated 
-# is prepared for conversion to pdf (using ps2pdf). The pdf file will 
-# contain links (just like the HTML output) instead of page references 
-# This makes the output suitable for online browsing using a pdf viewer.
-
-PDF_HYPERLINKS         = NO
-
-# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of 
-# plain latex in the generated Makefile. Set this option to YES to get a 
-# higher quality PDF documentation.
-
-USE_PDFLATEX           = YES
-
-# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. 
-# command to the generated LaTeX files. This will instruct LaTeX to keep 
-# running if errors occur, instead of asking the user for help. 
-# This option is also used when generating formulas in HTML.
-
-LATEX_BATCHMODE        = NO
-
-# If LATEX_HIDE_INDICES is set to YES then doxygen will not 
-# include the index chapters (such as File Index, Compound Index, etc.) 
-# in the output.
-
-LATEX_HIDE_INDICES     = NO
-
-#---------------------------------------------------------------------------
-# configuration options related to the RTF output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output 
-# The RTF output is optimized for Word 97 and may not look very pretty with 
-# other RTF readers or editors.
-
-GENERATE_RTF           = NO
-
-# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. 
-# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
-# put in front of it. If left blank `rtf' will be used as the default path.
-
-RTF_OUTPUT             = rtf
-
-# If the COMPACT_RTF tag is set to YES Doxygen generates more compact 
-# RTF documents. This may be useful for small projects and may help to 
-# save some trees in general.
-
-COMPACT_RTF            = NO
-
-# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated 
-# will contain hyperlink fields. The RTF file will 
-# contain links (just like the HTML output) instead of page references. 
-# This makes the output suitable for online browsing using WORD or other 
-# programs which support those fields. 
-# Note: wordpad (write) and others do not support links.
-
-RTF_HYPERLINKS         = NO
-
-# Load stylesheet definitions from file. Syntax is similar to doxygen's 
-# config file, i.e. a series of assignments. You only have to provide 
-# replacements, missing definitions are set to their default value.
-
-RTF_STYLESHEET_FILE    = 
-
-# Set optional variables used in the generation of an rtf document. 
-# Syntax is similar to doxygen's config file.
-
-RTF_EXTENSIONS_FILE    = 
-
-#---------------------------------------------------------------------------
-# configuration options related to the man page output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_MAN tag is set to YES (the default) Doxygen will 
-# generate man pages
-
-GENERATE_MAN           = NO
-
-# The MAN_OUTPUT tag is used to specify where the man pages will be put. 
-# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
-# put in front of it. If left blank `man' will be used as the default path.
-
-MAN_OUTPUT             = man
-
-# The MAN_EXTENSION tag determines the extension that is added to 
-# the generated man pages (default is the subroutine's section .3)
-
-MAN_EXTENSION          = .3
-
-# If the MAN_LINKS tag is set to YES and Doxygen generates man output, 
-# then it will generate one additional man file for each entity 
-# documented in the real man page(s). These additional files 
-# only source the real man page, but without them the man command 
-# would be unable to find the correct page. The default is NO.
-
-MAN_LINKS              = NO
-
-#---------------------------------------------------------------------------
-# configuration options related to the XML output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_XML tag is set to YES Doxygen will 
-# generate an XML file that captures the structure of 
-# the code including all documentation.
-
-GENERATE_XML           = NO
-
-# The XML_OUTPUT tag is used to specify where the XML pages will be put. 
-# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
-# put in front of it. If left blank `xml' will be used as the default path.
-
-XML_OUTPUT             = xml
-
-# The XML_SCHEMA tag can be used to specify an XML schema, 
-# which can be used by a validating XML parser to check the 
-# syntax of the XML files.
-
-XML_SCHEMA             = 
-
-# The XML_DTD tag can be used to specify an XML DTD, 
-# which can be used by a validating XML parser to check the 
-# syntax of the XML files.
-
-XML_DTD                = 
-
-# If the XML_PROGRAMLISTING tag is set to YES Doxygen will 
-# dump the program listings (including syntax highlighting 
-# and cross-referencing information) to the XML output. Note that 
-# enabling this will significantly increase the size of the XML output.
-
-XML_PROGRAMLISTING     = YES
-
-#---------------------------------------------------------------------------
-# configuration options for the AutoGen Definitions output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will 
-# generate an AutoGen Definitions (see autogen.sf.net) file 
-# that captures the structure of the code including all 
-# documentation. Note that this feature is still experimental 
-# and incomplete at the moment.
-
-GENERATE_AUTOGEN_DEF   = NO
-
-#---------------------------------------------------------------------------
-# configuration options related to the Perl module output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_PERLMOD tag is set to YES Doxygen will 
-# generate a Perl module file that captures the structure of 
-# the code including all documentation. Note that this 
-# feature is still experimental and incomplete at the 
-# moment.
-
-GENERATE_PERLMOD       = NO
-
-# If the PERLMOD_LATEX tag is set to YES Doxygen will generate 
-# the necessary Makefile rules, Perl scripts and LaTeX code to be able 
-# to generate PDF and DVI output from the Perl module output.
-
-PERLMOD_LATEX          = NO
-
-# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be 
-# nicely formatted so it can be parsed by a human reader.  This is useful 
-# if you want to understand what is going on.  On the other hand, if this 
-# tag is set to NO the size of the Perl module output will be much smaller 
-# and Perl will parse it just the same.
-
-PERLMOD_PRETTY         = YES
-
-# The names of the make variables in the generated doxyrules.make file 
-# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. 
-# This is useful so different doxyrules.make files included by the same 
-# Makefile don't overwrite each other's variables.
-
-PERLMOD_MAKEVAR_PREFIX = 
-
-#---------------------------------------------------------------------------
-# Configuration options related to the preprocessor   
-#---------------------------------------------------------------------------
-
-# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will 
-# evaluate all C-preprocessor directives found in the sources and include 
-# files.
-
-ENABLE_PREPROCESSING   = YES
-
-# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro 
-# names in the source code. If set to NO (the default) only conditional 
-# compilation will be performed. Macro expansion can be done in a controlled 
-# way by setting EXPAND_ONLY_PREDEF to YES.
-
-MACRO_EXPANSION        = NO
-
-# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES 
-# then the macro expansion is limited to the macros specified with the 
-# PREDEFINED and EXPAND_AS_PREDEFINED tags.
-
-EXPAND_ONLY_PREDEF     = NO
-
-# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files 
-# in the INCLUDE_PATH (see below) will be search if a #include is found.
-
-SEARCH_INCLUDES        = YES
-
-# The INCLUDE_PATH tag can be used to specify one or more directories that 
-# contain include files that are not input files but should be processed by 
-# the preprocessor.
-
-INCLUDE_PATH           = 
-
-# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard 
-# patterns (like *.h and *.hpp) to filter out the header-files in the 
-# directories. If left blank, the patterns specified with FILE_PATTERNS will 
-# be used.
-
-INCLUDE_FILE_PATTERNS  = 
-
-# The PREDEFINED tag can be used to specify one or more macro names that 
-# are defined before the preprocessor is started (similar to the -D option of 
-# gcc). The argument of the tag is a list of macros of the form: name 
-# or name=definition (no spaces). If the definition and the = are 
-# omitted =1 is assumed. To prevent a macro definition from being 
-# undefined via #undef or recursively expanded use the := operator 
-# instead of the = operator.
-
-PREDEFINED             = 
-
-# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then 
-# this tag can be used to specify a list of macro names that should be expanded. 
-# The macro definition that is found in the sources will be used. 
-# Use the PREDEFINED tag if you want to use a different macro definition.
-
-EXPAND_AS_DEFINED      = 
-
-# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then 
-# doxygen's preprocessor will remove all function-like macros that are alone 
-# on a line, have an all uppercase name, and do not end with a semicolon. Such 
-# function macros are typically used for boiler-plate code, and will confuse 
-# the parser if not removed.
-
-SKIP_FUNCTION_MACROS   = YES
-
-#---------------------------------------------------------------------------
-# Configuration::additions related to external references   
-#---------------------------------------------------------------------------
-
-# The TAGFILES option can be used to specify one or more tagfiles. 
-# Optionally an initial location of the external documentation 
-# can be added for each tagfile. The format of a tag file without 
-# this location is as follows: 
-#   TAGFILES = file1 file2 ... 
-# Adding location for the tag files is done as follows: 
-#   TAGFILES = file1=loc1 "file2 = loc2" ... 
-# where "loc1" and "loc2" can be relative or absolute paths or 
-# URLs. If a location is present for each tag, the installdox tool 
-# does not have to be run to correct the links.
-# Note that each tag file must have a unique name
-# (where the name does NOT include the path)
-# If a tag file is not located in the directory in which doxygen 
-# is run, you must also specify the path to the tagfile here.
-
-TAGFILES               = 
-
-# When a file name is specified after GENERATE_TAGFILE, doxygen will create 
-# a tag file that is based on the input files it reads.
-
-GENERATE_TAGFILE       = 
-
-# If the ALLEXTERNALS tag is set to YES all external classes will be listed 
-# in the class index. If set to NO only the inherited external classes 
-# will be listed.
-
-ALLEXTERNALS           = NO
-
-# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed 
-# in the modules index. If set to NO, only the current project's groups will 
-# be listed.
-
-EXTERNAL_GROUPS        = YES
-
-# The PERL_PATH should be the absolute path and name of the perl script 
-# interpreter (i.e. the result of `which perl').
-
-PERL_PATH              = /usr/bin/perl
-
-#---------------------------------------------------------------------------
-# Configuration options related to the dot tool   
-#---------------------------------------------------------------------------
-
-# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will 
-# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base 
-# or super classes. Setting the tag to NO turns the diagrams off. Note that 
-# this option is superseded by the HAVE_DOT option below. This is only a 
-# fallback. It is recommended to install and use dot, since it yields more 
-# powerful graphs.
-
-CLASS_DIAGRAMS         = YES
-
-# If set to YES, the inheritance and collaboration graphs will hide 
-# inheritance and usage relations if the target is undocumented 
-# or is not a class.
-
-HIDE_UNDOC_RELATIONS   = YES
-
-# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is 
-# available from the path. This tool is part of Graphviz, a graph visualization 
-# toolkit from AT&T and Lucent Bell Labs. The other options in this section 
-# have no effect if this option is set to NO (the default)
-
-HAVE_DOT               = NO
-
-# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen 
-# will generate a graph for each documented class showing the direct and 
-# indirect inheritance relations. Setting this tag to YES will force the 
-# the CLASS_DIAGRAMS tag to NO.
-
-CLASS_GRAPH            = YES
-
-# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen 
-# will generate a graph for each documented class showing the direct and 
-# indirect implementation dependencies (inheritance, containment, and 
-# class references variables) of the class with other documented classes.
-
-COLLABORATION_GRAPH    = YES
-
-# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen 
-# will generate a graph for groups, showing the direct groups dependencies
-
-GROUP_GRAPHS           = YES
-
-# If the UML_LOOK tag is set to YES doxygen will generate inheritance and 
-# collaboration diagrams in a style similar to the OMG's Unified Modeling 
-# Language.
-
-UML_LOOK               = NO
-
-# If set to YES, the inheritance and collaboration graphs will show the 
-# relations between templates and their instances.
-
-TEMPLATE_RELATIONS     = YES
-
-# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT 
-# tags are set to YES then doxygen will generate a graph for each documented 
-# file showing the direct and indirect include dependencies of the file with 
-# other documented files.
-
-INCLUDE_GRAPH          = YES
-
-# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and 
-# HAVE_DOT tags are set to YES then doxygen will generate a graph for each 
-# documented header file showing the documented files that directly or 
-# indirectly include this file.
-
-INCLUDED_BY_GRAPH      = YES
-
-# If the CALL_GRAPH and HAVE_DOT tags are set to YES then doxygen will 
-# generate a call dependency graph for every global function or class method. 
-# Note that enabling this option will significantly increase the time of a run. 
-# So in most cases it will be better to enable call graphs for selected 
-# functions only using the \callgraph command.
-
-CALL_GRAPH             = NO
-
-# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen 
-# will graphical hierarchy of all classes instead of a textual one.
-
-GRAPHICAL_HIERARCHY    = YES
-
-# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES 
-# then doxygen will show the dependencies a directory has on other directories 
-# in a graphical way. The dependency relations are determined by the #include
-# relations between the files in the directories.
-
-DIRECTORY_GRAPH        = YES
-
-# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images 
-# generated by dot. Possible values are png, jpg, or gif
-# If left blank png will be used.
-
-DOT_IMAGE_FORMAT       = png
-
-# The tag DOT_PATH can be used to specify the path where the dot tool can be 
-# found. If left blank, it is assumed the dot tool can be found in the path.
-
-DOT_PATH               = 
-
-# The DOTFILE_DIRS tag can be used to specify one or more directories that 
-# contain dot files that are included in the documentation (see the 
-# \dotfile command).
-
-DOTFILE_DIRS           = 
-
-# The MAX_DOT_GRAPH_WIDTH tag can be used to set the maximum allowed width 
-# (in pixels) of the graphs generated by dot. If a graph becomes larger than 
-# this value, doxygen will try to truncate the graph, so that it fits within 
-# the specified constraint. Beware that most browsers cannot cope with very 
-# large images.
-
-MAX_DOT_GRAPH_WIDTH    = 1024
-
-# The MAX_DOT_GRAPH_HEIGHT tag can be used to set the maximum allows height 
-# (in pixels) of the graphs generated by dot. If a graph becomes larger than 
-# this value, doxygen will try to truncate the graph, so that it fits within 
-# the specified constraint. Beware that most browsers cannot cope with very 
-# large images.
-
-MAX_DOT_GRAPH_HEIGHT   = 1024
-
-# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the 
-# graphs generated by dot. A depth value of 3 means that only nodes reachable 
-# from the root by following a path via at most 3 edges will be shown. Nodes 
-# that lay further from the root node will be omitted. Note that setting this 
-# option to 1 or 2 may greatly reduce the computation time needed for large 
-# code bases. Also note that a graph may be further truncated if the graph's 
-# image dimensions are not sufficient to fit the graph (see MAX_DOT_GRAPH_WIDTH 
-# and MAX_DOT_GRAPH_HEIGHT). If 0 is used for the depth value (the default), 
-# the graph is not depth-constrained.
-
-MAX_DOT_GRAPH_DEPTH    = 0
-
-# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent 
-# background. This is disabled by default, which results in a white background. 
-# Warning: Depending on the platform used, enabling this option may lead to 
-# badly anti-aliased labels on the edges of a graph (i.e. they become hard to 
-# read).
-
-DOT_TRANSPARENT        = NO
-
-# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output 
-# files in one run (i.e. multiple -o and -T options on the command line). This 
-# makes dot run faster, but since only newer versions of dot (>1.8.10) 
-# support this, this feature is disabled by default.
-
-DOT_MULTI_TARGETS      = NO
-
-# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will 
-# generate a legend page explaining the meaning of the various boxes and 
-# arrows in the dot generated graphs.
-
-GENERATE_LEGEND        = YES
-
-# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will 
-# remove the intermediate dot files that are used to generate 
-# the various graphs.
-
-DOT_CLEANUP            = YES
-
-#---------------------------------------------------------------------------
-# Configuration::additions related to the search engine   
-#---------------------------------------------------------------------------
-
-# The SEARCHENGINE tag specifies whether or not a search engine should be 
-# used. If set to NO the values of all tags below this one will be ignored.
-
-SEARCHENGINE           = NO
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Doxyfile.in	Wed Oct 03 08:58:01 2007 +0000
@@ -0,0 +1,1228 @@
+# Doxyfile 1.4.4
+
+# This file describes the settings to be used by the documentation system
+# doxygen (www.doxygen.org) for a project
+#
+# All text after a hash (#) is considered a comment and will be ignored
+# The format is:
+#       TAG = value [value, ...]
+# For lists items can also be appended using:
+#       TAG += value [value, ...]
+# Values that contain spaces should be placed between quotes (" ")
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+
+# The PROJECT_NAME tag is a single word (or a sequence of words surrounded 
+# by quotes) that should identify the project.
+
+PROJECT_NAME           = "IgH EtherCAT master"
+
+# The PROJECT_NUMBER tag can be used to enter a project or revision number. 
+# This could be handy for archiving the generated documentation or 
+# if some version control system is used.
+
+PROJECT_NUMBER         = @VERSION@
+
+# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) 
+# base path where the generated documentation will be put. 
+# If a relative path is entered, it will be relative to the location 
+# where doxygen was started. If left blank the current directory will be used.
+
+OUTPUT_DIRECTORY       = doxygen-output
+
+# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create 
+# 4096 sub-directories (in 2 levels) under the output directory of each output 
+# format and will distribute the generated files over these directories. 
+# Enabling this option can be useful when feeding doxygen a huge amount of 
+# source files, where putting all generated files in the same directory would 
+# otherwise cause performance problems for the file system.
+
+CREATE_SUBDIRS         = NO
+
+# The OUTPUT_LANGUAGE tag is used to specify the language in which all 
+# documentation generated by doxygen is written. Doxygen will use this 
+# information to generate all constant output in the proper language. 
+# The default language is English, other supported languages are: 
+# Brazilian, Catalan, Chinese, Chinese-Traditional, Croatian, Czech, Danish, 
+# Dutch, Finnish, French, German, Greek, Hungarian, Italian, Japanese, 
+# Japanese-en (Japanese with English messages), Korean, Korean-en, Norwegian, 
+# Polish, Portuguese, Romanian, Russian, Serbian, Slovak, Slovene, Spanish, 
+# Swedish, and Ukrainian.
+
+OUTPUT_LANGUAGE        = English
+
+# This tag can be used to specify the encoding used in the generated output. 
+# The encoding is not always determined by the language that is chosen, 
+# but also whether or not the output is meant for Windows or non-Windows users. 
+# In case there is a difference, setting the USE_WINDOWS_ENCODING tag to YES 
+# forces the Windows encoding (this is the default for the Windows binary), 
+# whereas setting the tag to NO uses a Unix-style encoding (the default for 
+# all platforms other than Windows).
+
+USE_WINDOWS_ENCODING   = NO
+
+# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will 
+# include brief member descriptions after the members that are listed in 
+# the file and class documentation (similar to JavaDoc). 
+# Set to NO to disable this.
+
+BRIEF_MEMBER_DESC      = YES
+
+# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend 
+# the brief description of a member or function before the detailed description. 
+# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the 
+# brief descriptions will be completely suppressed.
+
+REPEAT_BRIEF           = YES
+
+# This tag implements a quasi-intelligent brief description abbreviator 
+# that is used to form the text in various listings. Each string 
+# in this list, if found as the leading text of the brief description, will be 
+# stripped from the text and the result after processing the whole list, is 
+# used as the annotated text. Otherwise, the brief description is used as-is. 
+# If left blank, the following values are used ("$name" is automatically 
+# replaced with the name of the entity): "The $name class" "The $name widget" 
+# "The $name file" "is" "provides" "specifies" "contains" 
+# "represents" "a" "an" "the"
+
+ABBREVIATE_BRIEF       = 
+
+# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then 
+# Doxygen will generate a detailed section even if there is only a brief 
+# description.
+
+ALWAYS_DETAILED_SEC    = NO
+
+# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all 
+# inherited members of a class in the documentation of that class as if those 
+# members were ordinary class members. Constructors, destructors and assignment 
+# operators of the base classes will not be shown.
+
+INLINE_INHERITED_MEMB  = NO
+
+# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full 
+# path before files name in the file list and in the header files. If set 
+# to NO the shortest path that makes the file name unique will be used.
+
+FULL_PATH_NAMES        = NO
+
+# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag 
+# can be used to strip a user-defined part of the path. Stripping is 
+# only done if one of the specified strings matches the left-hand part of 
+# the path. The tag can be used to show relative paths in the file list. 
+# If left blank the directory from which doxygen is run is used as the 
+# path to strip.
+
+STRIP_FROM_PATH        = 
+
+# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of 
+# the path mentioned in the documentation of a class, which tells 
+# the reader which header file to include in order to use a class. 
+# If left blank only the name of the header file containing the class 
+# definition is used. Otherwise one should specify the include paths that 
+# are normally passed to the compiler using the -I flag.
+
+STRIP_FROM_INC_PATH    = 
+
+# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter 
+# (but less readable) file names. This can be useful is your file systems 
+# doesn't support long names like on DOS, Mac, or CD-ROM.
+
+SHORT_NAMES            = NO
+
+# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen 
+# will interpret the first line (until the first dot) of a JavaDoc-style 
+# comment as the brief description. If set to NO, the JavaDoc 
+# comments will behave just like the Qt-style comments (thus requiring an 
+# explicit @brief command for a brief description.
+
+JAVADOC_AUTOBRIEF      = YES
+
+# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen 
+# treat a multi-line C++ special comment block (i.e. a block of //! or /// 
+# comments) as a brief description. This used to be the default behaviour. 
+# The new default is to treat a multi-line C++ comment block as a detailed 
+# description. Set this tag to YES if you prefer the old behaviour instead.
+
+MULTILINE_CPP_IS_BRIEF = YES
+
+# If the DETAILS_AT_TOP tag is set to YES then Doxygen 
+# will output the detailed description near the top, like JavaDoc.
+# If set to NO, the detailed description appears after the member 
+# documentation.
+
+DETAILS_AT_TOP         = YES
+
+# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented 
+# member inherits the documentation from any documented member that it 
+# re-implements.
+
+INHERIT_DOCS           = YES
+
+# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC 
+# tag is set to YES, then doxygen will reuse the documentation of the first 
+# member in the group (if any) for the other members of the group. By default 
+# all members of a group must be documented explicitly.
+
+DISTRIBUTE_GROUP_DOC   = NO
+
+# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce 
+# a new page for each member. If set to NO, the documentation of a member will 
+# be part of the file/class/namespace that contains it.
+
+SEPARATE_MEMBER_PAGES  = NO
+
+# The TAB_SIZE tag can be used to set the number of spaces in a tab. 
+# Doxygen uses this value to replace tabs by spaces in code fragments.
+
+TAB_SIZE               = 4
+
+# This tag can be used to specify a number of aliases that acts 
+# as commands in the documentation. An alias has the form "name=value". 
+# For example adding "sideeffect=\par Side Effects:\n" will allow you to 
+# put the command \sideeffect (or @sideeffect) in the documentation, which 
+# will result in a user-defined paragraph with heading "Side Effects:". 
+# You can put \n's in the value part of an alias to insert newlines.
+
+ALIASES                = 
+
+# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C 
+# sources only. Doxygen will then generate output that is more tailored for C. 
+# For instance, some of the names that are used will be different. The list 
+# of all members will be omitted, etc.
+
+OPTIMIZE_OUTPUT_FOR_C  = YES
+
+# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java sources 
+# only. Doxygen will then generate output that is more tailored for Java. 
+# For instance, namespaces will be presented as packages, qualified scopes 
+# will look different, etc.
+
+OPTIMIZE_OUTPUT_JAVA   = NO
+
+# Set the SUBGROUPING tag to YES (the default) to allow class member groups of 
+# the same type (for instance a group of public functions) to be put as a 
+# subgroup of that type (e.g. under the Public Functions section). Set it to 
+# NO to prevent subgrouping. Alternatively, this can be done per class using 
+# the \nosubgrouping command.
+
+SUBGROUPING            = YES
+
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+
+# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in 
+# documentation are documented, even if no documentation was available. 
+# Private class members and static file members will be hidden unless 
+# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES
+
+EXTRACT_ALL            = NO
+
+# If the EXTRACT_PRIVATE tag is set to YES all private members of a class 
+# will be included in the documentation.
+
+EXTRACT_PRIVATE        = YES
+
+# If the EXTRACT_STATIC tag is set to YES all static members of a file 
+# will be included in the documentation.
+
+EXTRACT_STATIC         = YES
+
+# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) 
+# defined locally in source files will be included in the documentation. 
+# If set to NO only classes defined in header files are included.
+
+EXTRACT_LOCAL_CLASSES  = YES
+
+# This flag is only useful for Objective-C code. When set to YES local 
+# methods, which are defined in the implementation section but not in 
+# the interface are included in the documentation. 
+# If set to NO (the default) only methods in the interface are included.
+
+EXTRACT_LOCAL_METHODS  = YES
+
+# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all 
+# undocumented members of documented classes, files or namespaces. 
+# If set to NO (the default) these members will be included in the 
+# various overviews, but no documentation section is generated. 
+# This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_MEMBERS     = NO
+
+# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all 
+# undocumented classes that are normally visible in the class hierarchy. 
+# If set to NO (the default) these classes will be included in the various 
+# overviews. This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_CLASSES     = NO
+
+# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all 
+# friend (class|struct|union) declarations. 
+# If set to NO (the default) these declarations will be included in the 
+# documentation.
+
+HIDE_FRIEND_COMPOUNDS  = NO
+
+# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any 
+# documentation blocks found inside the body of a function. 
+# If set to NO (the default) these blocks will be appended to the 
+# function's detailed documentation block.
+
+HIDE_IN_BODY_DOCS      = NO
+
+# The INTERNAL_DOCS tag determines if documentation 
+# that is typed after a \internal command is included. If the tag is set 
+# to NO (the default) then the documentation will be excluded. 
+# Set it to YES to include the internal documentation.
+
+INTERNAL_DOCS          = NO
+
+# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate 
+# file names in lower-case letters. If set to YES upper-case letters are also 
+# allowed. This is useful if you have classes or files whose names only differ 
+# in case and if your file system supports case sensitive file names. Windows 
+# and Mac users are advised to set this option to NO.
+
+CASE_SENSE_NAMES       = YES
+
+# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen 
+# will show members with their full class and namespace scopes in the 
+# documentation. If set to YES the scope will be hidden.
+
+HIDE_SCOPE_NAMES       = NO
+
+# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen 
+# will put a list of the files that are included by a file in the documentation 
+# of that file.
+
+SHOW_INCLUDE_FILES     = NO
+
+# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] 
+# is inserted in the documentation for inline members.
+
+INLINE_INFO            = YES
+
+# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen 
+# will sort the (detailed) documentation of file and class members 
+# alphabetically by member name. If set to NO the members will appear in 
+# declaration order.
+
+SORT_MEMBER_DOCS       = NO
+
+# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the 
+# brief documentation of file, namespace and class members alphabetically 
+# by member name. If set to NO (the default) the members will appear in 
+# declaration order.
+
+SORT_BRIEF_DOCS        = NO
+
+# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be 
+# sorted by fully-qualified names, including namespaces. If set to 
+# NO (the default), the class list will be sorted only by class name, 
+# not including the namespace part. 
+# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES.
+# Note: This option applies only to the class list, not to the 
+# alphabetical list.
+
+SORT_BY_SCOPE_NAME     = NO
+
+# The GENERATE_TODOLIST tag can be used to enable (YES) or 
+# disable (NO) the todo list. This list is created by putting \todo 
+# commands in the documentation.
+
+GENERATE_TODOLIST      = YES
+
+# The GENERATE_TESTLIST tag can be used to enable (YES) or 
+# disable (NO) the test list. This list is created by putting \test 
+# commands in the documentation.
+
+GENERATE_TESTLIST      = NO
+
+# The GENERATE_BUGLIST tag can be used to enable (YES) or 
+# disable (NO) the bug list. This list is created by putting \bug 
+# commands in the documentation.
+
+GENERATE_BUGLIST       = NO
+
+# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or 
+# disable (NO) the deprecated list. This list is created by putting 
+# \deprecated commands in the documentation.
+
+GENERATE_DEPRECATEDLIST= NO
+
+# The ENABLED_SECTIONS tag can be used to enable conditional 
+# documentation sections, marked by \if sectionname ... \endif.
+
+ENABLED_SECTIONS       = 
+
+# The MAX_INITIALIZER_LINES tag determines the maximum number of lines 
+# the initial value of a variable or define consists of for it to appear in 
+# the documentation. If the initializer consists of more lines than specified 
+# here it will be hidden. Use a value of 0 to hide initializers completely. 
+# The appearance of the initializer of individual variables and defines in the 
+# documentation can be controlled using \showinitializer or \hideinitializer 
+# command in the documentation regardless of this setting.
+
+MAX_INITIALIZER_LINES  = 30
+
+# Set the SHOW_USED_FILES tag to NO to disable the list of files generated 
+# at the bottom of the documentation of classes and structs. If set to YES the 
+# list will mention the files that were used to generate the documentation.
+
+SHOW_USED_FILES        = NO
+
+# If the sources in your project are distributed over multiple directories 
+# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy 
+# in the documentation. The default is YES.
+
+SHOW_DIRECTORIES       = YES
+
+# The FILE_VERSION_FILTER tag can be used to specify a program or script that 
+# doxygen should invoke to get the current version for each file (typically from the 
+# version control system). Doxygen will invoke the program by executing (via 
+# popen()) the command <command> <input-file>, where <command> is the value of 
+# the FILE_VERSION_FILTER tag, and <input-file> is the name of an input file 
+# provided by doxygen. Whatever the progam writes to standard output 
+# is used as the file version. See the manual for examples.
+
+FILE_VERSION_FILTER    = 
+
+#---------------------------------------------------------------------------
+# configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+
+# The QUIET tag can be used to turn on/off the messages that are generated 
+# by doxygen. Possible values are YES and NO. If left blank NO is used.
+
+QUIET                  = YES
+
+# The WARNINGS tag can be used to turn on/off the warning messages that are 
+# generated by doxygen. Possible values are YES and NO. If left blank 
+# NO is used.
+
+WARNINGS               = YES
+
+# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings 
+# for undocumented members. If EXTRACT_ALL is set to YES then this flag will 
+# automatically be disabled.
+
+WARN_IF_UNDOCUMENTED   = YES
+
+# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for 
+# potential errors in the documentation, such as not documenting some 
+# parameters in a documented function, or documenting parameters that 
+# don't exist or using markup commands wrongly.
+
+WARN_IF_DOC_ERROR      = YES
+
+# This WARN_NO_PARAMDOC option can be abled to get warnings for 
+# functions that are documented, but have no documentation for their parameters 
+# or return value. If set to NO (the default) doxygen will only warn about 
+# wrong or incomplete parameter documentation, but not about the absence of 
+# documentation.
+
+WARN_NO_PARAMDOC       = YES
+
+# The WARN_FORMAT tag determines the format of the warning messages that 
+# doxygen can produce. The string should contain the $file, $line, and $text 
+# tags, which will be replaced by the file and line number from which the 
+# warning originated and the warning text. Optionally the format may contain 
+# $version, which will be replaced by the version of the file (if it could 
+# be obtained via FILE_VERSION_FILTER)
+
+WARN_FORMAT            = "$file:$line: $text"
+
+# The WARN_LOGFILE tag can be used to specify a file to which warning 
+# and error messages should be written. If left blank the output is written 
+# to stderr.
+
+WARN_LOGFILE           = 
+
+#---------------------------------------------------------------------------
+# configuration options related to the input files
+#---------------------------------------------------------------------------
+
+# The INPUT tag can be used to specify the files and/or directories that contain 
+# documented source files. You may enter file names like "myfile.cpp" or 
+# directories like "/usr/src/myproject". Separate the files or directories 
+# with spaces.
+
+INPUT                  = master include devices/ecdev.h
+
+# If the value of the INPUT tag contains directories, you can use the 
+# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp 
+# and *.h) to filter out the source-files in the directories. If left 
+# blank the following patterns are tested: 
+# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx 
+# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm
+
+FILE_PATTERNS          = 
+
+# The RECURSIVE tag can be used to turn specify whether or not subdirectories 
+# should be searched for input files as well. Possible values are YES and NO. 
+# If left blank NO is used.
+
+RECURSIVE              = NO
+
+# The EXCLUDE tag can be used to specify files and/or directories that should 
+# excluded from the INPUT source files. This way you can easily exclude a 
+# subdirectory from a directory tree whose root is specified with the INPUT tag.
+
+EXCLUDE                = 
+
+# The EXCLUDE_SYMLINKS tag can be used select whether or not files or 
+# directories that are symbolic links (a Unix filesystem feature) are excluded 
+# from the input.
+
+EXCLUDE_SYMLINKS       = NO
+
+# If the value of the INPUT tag contains directories, you can use the 
+# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude 
+# certain files from those directories. Note that the wildcards are matched 
+# against the file with absolute path, so to exclude all test directories 
+# for example use the pattern */test/*
+
+EXCLUDE_PATTERNS       = *.mod.c
+
+# The EXAMPLE_PATH tag can be used to specify one or more files or 
+# directories that contain example code fragments that are included (see 
+# the \include command).
+
+EXAMPLE_PATH           = 
+
+# If the value of the EXAMPLE_PATH tag contains directories, you can use the 
+# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp 
+# and *.h) to filter out the source-files in the directories. If left 
+# blank all files are included.
+
+EXAMPLE_PATTERNS       = 
+
+# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be 
+# searched for input files to be used with the \include or \dontinclude 
+# commands irrespective of the value of the RECURSIVE tag. 
+# Possible values are YES and NO. If left blank NO is used.
+
+EXAMPLE_RECURSIVE      = NO
+
+# The IMAGE_PATH tag can be used to specify one or more files or 
+# directories that contain image that are included in the documentation (see 
+# the \image command).
+
+IMAGE_PATH             = 
+
+# The INPUT_FILTER tag can be used to specify a program that doxygen should 
+# invoke to filter for each input file. Doxygen will invoke the filter program 
+# by executing (via popen()) the command <filter> <input-file>, where <filter> 
+# is the value of the INPUT_FILTER tag, and <input-file> is the name of an 
+# input file. Doxygen will then use the output that the filter program writes 
+# to standard output.  If FILTER_PATTERNS is specified, this tag will be 
+# ignored.
+
+INPUT_FILTER           = 
+
+# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern 
+# basis.  Doxygen will compare the file name with each pattern and apply the 
+# filter if there is a match.  The filters are a list of the form: 
+# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further 
+# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER 
+# is applied to all files.
+
+FILTER_PATTERNS        = 
+
+# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using 
+# INPUT_FILTER) will be used to filter the input files when producing source 
+# files to browse (i.e. when SOURCE_BROWSER is set to YES).
+
+FILTER_SOURCE_FILES    = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to source browsing
+#---------------------------------------------------------------------------
+
+# If the SOURCE_BROWSER tag is set to YES then a list of source files will 
+# be generated. Documented entities will be cross-referenced with these sources. 
+# Note: To get rid of all source code in the generated output, make sure also 
+# VERBATIM_HEADERS is set to NO.
+
+SOURCE_BROWSER         = YES
+
+# Setting the INLINE_SOURCES tag to YES will include the body 
+# of functions and classes directly in the documentation.
+
+INLINE_SOURCES         = NO
+
+# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct 
+# doxygen to hide any special comment blocks from generated source code 
+# fragments. Normal C and C++ comments will always remain visible.
+
+STRIP_CODE_COMMENTS    = YES
+
+# If the REFERENCED_BY_RELATION tag is set to YES (the default) 
+# then for each documented function all documented 
+# functions referencing it will be listed.
+
+REFERENCED_BY_RELATION = NO
+
+# If the REFERENCES_RELATION tag is set to YES (the default) 
+# then for each documented function all documented entities 
+# called/used by that function will be listed.
+
+REFERENCES_RELATION    = NO
+
+# If the USE_HTAGS tag is set to YES then the references to source code 
+# will point to the HTML generated by the htags(1) tool instead of doxygen 
+# built-in source browser. The htags tool is part of GNU's global source 
+# tagging system (see http://www.gnu.org/software/global/global.html). You 
+# will need version 4.8.6 or higher.
+
+USE_HTAGS              = NO
+
+# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen 
+# will generate a verbatim copy of the header file for each class for 
+# which an include is specified. Set to NO to disable this.
+
+VERBATIM_HEADERS       = YES
+
+#---------------------------------------------------------------------------
+# configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+
+# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index 
+# of all compounds will be generated. Enable this if the project 
+# contains a lot of classes, structs, unions or interfaces.
+
+ALPHABETICAL_INDEX     = NO
+
+# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then 
+# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns 
+# in which this list will be split (can be a number in the range [1..20])
+
+COLS_IN_ALPHA_INDEX    = 5
+
+# In case all classes in a project start with a common prefix, all 
+# classes will be put under the same header in the alphabetical index. 
+# The IGNORE_PREFIX tag can be used to specify one or more prefixes that 
+# should be ignored while generating the index headers.
+
+IGNORE_PREFIX          = 
+
+#---------------------------------------------------------------------------
+# configuration options related to the HTML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_HTML tag is set to YES (the default) Doxygen will 
+# generate HTML output.
+
+GENERATE_HTML          = YES
+
+# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `html' will be used as the default path.
+
+HTML_OUTPUT            = html
+
+# The HTML_FILE_EXTENSION tag can be used to specify the file extension for 
+# each generated HTML page (for example: .htm,.php,.asp). If it is left blank 
+# doxygen will generate files with .html extension.
+
+HTML_FILE_EXTENSION    = .html
+
+# The HTML_HEADER tag can be used to specify a personal HTML header for 
+# each generated HTML page. If it is left blank doxygen will generate a 
+# standard header.
+
+HTML_HEADER            = 
+
+# The HTML_FOOTER tag can be used to specify a personal HTML footer for 
+# each generated HTML page. If it is left blank doxygen will generate a 
+# standard footer.
+
+HTML_FOOTER            = 
+
+# The HTML_STYLESHEET tag can be used to specify a user-defined cascading 
+# style sheet that is used by each HTML page. It can be used to 
+# fine-tune the look of the HTML output. If the tag is left blank doxygen 
+# will generate a default style sheet. Note that doxygen will try to copy 
+# the style sheet file to the HTML output directory, so don't put your own 
+# stylesheet in the HTML output directory as well, or it will be erased!
+
+HTML_STYLESHEET        = 
+
+# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, 
+# files or namespaces will be aligned in HTML using tables. If set to 
+# NO a bullet list will be used.
+
+HTML_ALIGN_MEMBERS     = YES
+
+# If the GENERATE_HTMLHELP tag is set to YES, additional index files 
+# will be generated that can be used as input for tools like the 
+# Microsoft HTML help workshop to generate a compressed HTML help file (.chm) 
+# of the generated HTML documentation.
+
+GENERATE_HTMLHELP      = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can 
+# be used to specify the file name of the resulting .chm file. You 
+# can add a path in front of the file if the result should not be 
+# written to the html output directory.
+
+CHM_FILE               = 
+
+# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can 
+# be used to specify the location (absolute path including file name) of 
+# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run 
+# the HTML help compiler on the generated index.hhp.
+
+HHC_LOCATION           = 
+
+# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag 
+# controls if a separate .chi index file is generated (YES) or that 
+# it should be included in the master .chm file (NO).
+
+GENERATE_CHI           = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag 
+# controls whether a binary table of contents is generated (YES) or a 
+# normal table of contents (NO) in the .chm file.
+
+BINARY_TOC             = NO
+
+# The TOC_EXPAND flag can be set to YES to add extra items for group members 
+# to the contents of the HTML help documentation and to the tree view.
+
+TOC_EXPAND             = NO
+
+# The DISABLE_INDEX tag can be used to turn on/off the condensed index at 
+# top of each HTML page. The value NO (the default) enables the index and 
+# the value YES disables it.
+
+DISABLE_INDEX          = NO
+
+# This tag can be used to set the number of enum values (range [1..20]) 
+# that doxygen will group on one line in the generated HTML documentation.
+
+ENUM_VALUES_PER_LINE   = 4
+
+# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be
+# generated containing a tree-like index structure (just like the one that 
+# is generated for HTML Help). For this to work a browser that supports 
+# JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+, 
+# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are 
+# probably better off using the HTML help feature.
+
+GENERATE_TREEVIEW      = YES
+
+# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be 
+# used to set the initial width (in pixels) of the frame in which the tree 
+# is shown.
+
+TREEVIEW_WIDTH         = 250
+
+#---------------------------------------------------------------------------
+# configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will 
+# generate Latex output.
+
+GENERATE_LATEX         = YES
+
+# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `latex' will be used as the default path.
+
+LATEX_OUTPUT           = latex
+
+# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be 
+# invoked. If left blank `latex' will be used as the default command name.
+
+LATEX_CMD_NAME         = latex
+
+# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to 
+# generate index for LaTeX. If left blank `makeindex' will be used as the 
+# default command name.
+
+MAKEINDEX_CMD_NAME     = makeindex
+
+# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact 
+# LaTeX documents. This may be useful for small projects and may help to 
+# save some trees in general.
+
+COMPACT_LATEX          = NO
+
+# The PAPER_TYPE tag can be used to set the paper type that is used 
+# by the printer. Possible values are: a4, a4wide, letter, legal and 
+# executive. If left blank a4wide will be used.
+
+PAPER_TYPE             = a4wide
+
+# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX 
+# packages that should be included in the LaTeX output.
+
+EXTRA_PACKAGES         = 
+
+# The LATEX_HEADER tag can be used to specify a personal LaTeX header for 
+# the generated latex document. The header should contain everything until 
+# the first chapter. If it is left blank doxygen will generate a 
+# standard header. Notice: only use this tag if you know what you are doing!
+
+LATEX_HEADER           = 
+
+# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated 
+# is prepared for conversion to pdf (using ps2pdf). The pdf file will 
+# contain links (just like the HTML output) instead of page references 
+# This makes the output suitable for online browsing using a pdf viewer.
+
+PDF_HYPERLINKS         = NO
+
+# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of 
+# plain latex in the generated Makefile. Set this option to YES to get a 
+# higher quality PDF documentation.
+
+USE_PDFLATEX           = YES
+
+# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. 
+# command to the generated LaTeX files. This will instruct LaTeX to keep 
+# running if errors occur, instead of asking the user for help. 
+# This option is also used when generating formulas in HTML.
+
+LATEX_BATCHMODE        = NO
+
+# If LATEX_HIDE_INDICES is set to YES then doxygen will not 
+# include the index chapters (such as File Index, Compound Index, etc.) 
+# in the output.
+
+LATEX_HIDE_INDICES     = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the RTF output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output 
+# The RTF output is optimized for Word 97 and may not look very pretty with 
+# other RTF readers or editors.
+
+GENERATE_RTF           = NO
+
+# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `rtf' will be used as the default path.
+
+RTF_OUTPUT             = rtf
+
+# If the COMPACT_RTF tag is set to YES Doxygen generates more compact 
+# RTF documents. This may be useful for small projects and may help to 
+# save some trees in general.
+
+COMPACT_RTF            = NO
+
+# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated 
+# will contain hyperlink fields. The RTF file will 
+# contain links (just like the HTML output) instead of page references. 
+# This makes the output suitable for online browsing using WORD or other 
+# programs which support those fields. 
+# Note: wordpad (write) and others do not support links.
+
+RTF_HYPERLINKS         = NO
+
+# Load stylesheet definitions from file. Syntax is similar to doxygen's 
+# config file, i.e. a series of assignments. You only have to provide 
+# replacements, missing definitions are set to their default value.
+
+RTF_STYLESHEET_FILE    = 
+
+# Set optional variables used in the generation of an rtf document. 
+# Syntax is similar to doxygen's config file.
+
+RTF_EXTENSIONS_FILE    = 
+
+#---------------------------------------------------------------------------
+# configuration options related to the man page output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_MAN tag is set to YES (the default) Doxygen will 
+# generate man pages
+
+GENERATE_MAN           = NO
+
+# The MAN_OUTPUT tag is used to specify where the man pages will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `man' will be used as the default path.
+
+MAN_OUTPUT             = man
+
+# The MAN_EXTENSION tag determines the extension that is added to 
+# the generated man pages (default is the subroutine's section .3)
+
+MAN_EXTENSION          = .3
+
+# If the MAN_LINKS tag is set to YES and Doxygen generates man output, 
+# then it will generate one additional man file for each entity 
+# documented in the real man page(s). These additional files 
+# only source the real man page, but without them the man command 
+# would be unable to find the correct page. The default is NO.
+
+MAN_LINKS              = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the XML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_XML tag is set to YES Doxygen will 
+# generate an XML file that captures the structure of 
+# the code including all documentation.
+
+GENERATE_XML           = NO
+
+# The XML_OUTPUT tag is used to specify where the XML pages will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `xml' will be used as the default path.
+
+XML_OUTPUT             = xml
+
+# The XML_SCHEMA tag can be used to specify an XML schema, 
+# which can be used by a validating XML parser to check the 
+# syntax of the XML files.
+
+XML_SCHEMA             = 
+
+# The XML_DTD tag can be used to specify an XML DTD, 
+# which can be used by a validating XML parser to check the 
+# syntax of the XML files.
+
+XML_DTD                = 
+
+# If the XML_PROGRAMLISTING tag is set to YES Doxygen will 
+# dump the program listings (including syntax highlighting 
+# and cross-referencing information) to the XML output. Note that 
+# enabling this will significantly increase the size of the XML output.
+
+XML_PROGRAMLISTING     = YES
+
+#---------------------------------------------------------------------------
+# configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will 
+# generate an AutoGen Definitions (see autogen.sf.net) file 
+# that captures the structure of the code including all 
+# documentation. Note that this feature is still experimental 
+# and incomplete at the moment.
+
+GENERATE_AUTOGEN_DEF   = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_PERLMOD tag is set to YES Doxygen will 
+# generate a Perl module file that captures the structure of 
+# the code including all documentation. Note that this 
+# feature is still experimental and incomplete at the 
+# moment.
+
+GENERATE_PERLMOD       = NO
+
+# If the PERLMOD_LATEX tag is set to YES Doxygen will generate 
+# the necessary Makefile rules, Perl scripts and LaTeX code to be able 
+# to generate PDF and DVI output from the Perl module output.
+
+PERLMOD_LATEX          = NO
+
+# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be 
+# nicely formatted so it can be parsed by a human reader.  This is useful 
+# if you want to understand what is going on.  On the other hand, if this 
+# tag is set to NO the size of the Perl module output will be much smaller 
+# and Perl will parse it just the same.
+
+PERLMOD_PRETTY         = YES
+
+# The names of the make variables in the generated doxyrules.make file 
+# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. 
+# This is useful so different doxyrules.make files included by the same 
+# Makefile don't overwrite each other's variables.
+
+PERLMOD_MAKEVAR_PREFIX = 
+
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor   
+#---------------------------------------------------------------------------
+
+# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will 
+# evaluate all C-preprocessor directives found in the sources and include 
+# files.
+
+ENABLE_PREPROCESSING   = YES
+
+# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro 
+# names in the source code. If set to NO (the default) only conditional 
+# compilation will be performed. Macro expansion can be done in a controlled 
+# way by setting EXPAND_ONLY_PREDEF to YES.
+
+MACRO_EXPANSION        = NO
+
+# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES 
+# then the macro expansion is limited to the macros specified with the 
+# PREDEFINED and EXPAND_AS_PREDEFINED tags.
+
+EXPAND_ONLY_PREDEF     = NO
+
+# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files 
+# in the INCLUDE_PATH (see below) will be search if a #include is found.
+
+SEARCH_INCLUDES        = YES
+
+# The INCLUDE_PATH tag can be used to specify one or more directories that 
+# contain include files that are not input files but should be processed by 
+# the preprocessor.
+
+INCLUDE_PATH           = 
+
+# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard 
+# patterns (like *.h and *.hpp) to filter out the header-files in the 
+# directories. If left blank, the patterns specified with FILE_PATTERNS will 
+# be used.
+
+INCLUDE_FILE_PATTERNS  = 
+
+# The PREDEFINED tag can be used to specify one or more macro names that 
+# are defined before the preprocessor is started (similar to the -D option of 
+# gcc). The argument of the tag is a list of macros of the form: name 
+# or name=definition (no spaces). If the definition and the = are 
+# omitted =1 is assumed. To prevent a macro definition from being 
+# undefined via #undef or recursively expanded use the := operator 
+# instead of the = operator.
+
+PREDEFINED             = 
+
+# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then 
+# this tag can be used to specify a list of macro names that should be expanded. 
+# The macro definition that is found in the sources will be used. 
+# Use the PREDEFINED tag if you want to use a different macro definition.
+
+EXPAND_AS_DEFINED      = 
+
+# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then 
+# doxygen's preprocessor will remove all function-like macros that are alone 
+# on a line, have an all uppercase name, and do not end with a semicolon. Such 
+# function macros are typically used for boiler-plate code, and will confuse 
+# the parser if not removed.
+
+SKIP_FUNCTION_MACROS   = YES
+
+#---------------------------------------------------------------------------
+# Configuration::additions related to external references   
+#---------------------------------------------------------------------------
+
+# The TAGFILES option can be used to specify one or more tagfiles. 
+# Optionally an initial location of the external documentation 
+# can be added for each tagfile. The format of a tag file without 
+# this location is as follows: 
+#   TAGFILES = file1 file2 ... 
+# Adding location for the tag files is done as follows: 
+#   TAGFILES = file1=loc1 "file2 = loc2" ... 
+# where "loc1" and "loc2" can be relative or absolute paths or 
+# URLs. If a location is present for each tag, the installdox tool 
+# does not have to be run to correct the links.
+# Note that each tag file must have a unique name
+# (where the name does NOT include the path)
+# If a tag file is not located in the directory in which doxygen 
+# is run, you must also specify the path to the tagfile here.
+
+TAGFILES               = 
+
+# When a file name is specified after GENERATE_TAGFILE, doxygen will create 
+# a tag file that is based on the input files it reads.
+
+GENERATE_TAGFILE       = 
+
+# If the ALLEXTERNALS tag is set to YES all external classes will be listed 
+# in the class index. If set to NO only the inherited external classes 
+# will be listed.
+
+ALLEXTERNALS           = NO
+
+# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed 
+# in the modules index. If set to NO, only the current project's groups will 
+# be listed.
+
+EXTERNAL_GROUPS        = YES
+
+# The PERL_PATH should be the absolute path and name of the perl script 
+# interpreter (i.e. the result of `which perl').
+
+PERL_PATH              = /usr/bin/perl
+
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool   
+#---------------------------------------------------------------------------
+
+# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will 
+# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base 
+# or super classes. Setting the tag to NO turns the diagrams off. Note that 
+# this option is superseded by the HAVE_DOT option below. This is only a 
+# fallback. It is recommended to install and use dot, since it yields more 
+# powerful graphs.
+
+CLASS_DIAGRAMS         = YES
+
+# If set to YES, the inheritance and collaboration graphs will hide 
+# inheritance and usage relations if the target is undocumented 
+# or is not a class.
+
+HIDE_UNDOC_RELATIONS   = YES
+
+# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is 
+# available from the path. This tool is part of Graphviz, a graph visualization 
+# toolkit from AT&T and Lucent Bell Labs. The other options in this section 
+# have no effect if this option is set to NO (the default)
+
+HAVE_DOT               = NO
+
+# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen 
+# will generate a graph for each documented class showing the direct and 
+# indirect inheritance relations. Setting this tag to YES will force the 
+# the CLASS_DIAGRAMS tag to NO.
+
+CLASS_GRAPH            = YES
+
+# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen 
+# will generate a graph for each documented class showing the direct and 
+# indirect implementation dependencies (inheritance, containment, and 
+# class references variables) of the class with other documented classes.
+
+COLLABORATION_GRAPH    = YES
+
+# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen 
+# will generate a graph for groups, showing the direct groups dependencies
+
+GROUP_GRAPHS           = YES
+
+# If the UML_LOOK tag is set to YES doxygen will generate inheritance and 
+# collaboration diagrams in a style similar to the OMG's Unified Modeling 
+# Language.
+
+UML_LOOK               = NO
+
+# If set to YES, the inheritance and collaboration graphs will show the 
+# relations between templates and their instances.
+
+TEMPLATE_RELATIONS     = YES
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT 
+# tags are set to YES then doxygen will generate a graph for each documented 
+# file showing the direct and indirect include dependencies of the file with 
+# other documented files.
+
+INCLUDE_GRAPH          = YES
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and 
+# HAVE_DOT tags are set to YES then doxygen will generate a graph for each 
+# documented header file showing the documented files that directly or 
+# indirectly include this file.
+
+INCLUDED_BY_GRAPH      = YES
+
+# If the CALL_GRAPH and HAVE_DOT tags are set to YES then doxygen will 
+# generate a call dependency graph for every global function or class method. 
+# Note that enabling this option will significantly increase the time of a run. 
+# So in most cases it will be better to enable call graphs for selected 
+# functions only using the \callgraph command.
+
+CALL_GRAPH             = NO
+
+# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen 
+# will graphical hierarchy of all classes instead of a textual one.
+
+GRAPHICAL_HIERARCHY    = YES
+
+# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES 
+# then doxygen will show the dependencies a directory has on other directories 
+# in a graphical way. The dependency relations are determined by the #include
+# relations between the files in the directories.
+
+DIRECTORY_GRAPH        = YES
+
+# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images 
+# generated by dot. Possible values are png, jpg, or gif
+# If left blank png will be used.
+
+DOT_IMAGE_FORMAT       = png
+
+# The tag DOT_PATH can be used to specify the path where the dot tool can be 
+# found. If left blank, it is assumed the dot tool can be found in the path.
+
+DOT_PATH               = 
+
+# The DOTFILE_DIRS tag can be used to specify one or more directories that 
+# contain dot files that are included in the documentation (see the 
+# \dotfile command).
+
+DOTFILE_DIRS           = 
+
+# The MAX_DOT_GRAPH_WIDTH tag can be used to set the maximum allowed width 
+# (in pixels) of the graphs generated by dot. If a graph becomes larger than 
+# this value, doxygen will try to truncate the graph, so that it fits within 
+# the specified constraint. Beware that most browsers cannot cope with very 
+# large images.
+
+MAX_DOT_GRAPH_WIDTH    = 1024
+
+# The MAX_DOT_GRAPH_HEIGHT tag can be used to set the maximum allows height 
+# (in pixels) of the graphs generated by dot. If a graph becomes larger than 
+# this value, doxygen will try to truncate the graph, so that it fits within 
+# the specified constraint. Beware that most browsers cannot cope with very 
+# large images.
+
+MAX_DOT_GRAPH_HEIGHT   = 1024
+
+# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the 
+# graphs generated by dot. A depth value of 3 means that only nodes reachable 
+# from the root by following a path via at most 3 edges will be shown. Nodes 
+# that lay further from the root node will be omitted. Note that setting this 
+# option to 1 or 2 may greatly reduce the computation time needed for large 
+# code bases. Also note that a graph may be further truncated if the graph's 
+# image dimensions are not sufficient to fit the graph (see MAX_DOT_GRAPH_WIDTH 
+# and MAX_DOT_GRAPH_HEIGHT). If 0 is used for the depth value (the default), 
+# the graph is not depth-constrained.
+
+MAX_DOT_GRAPH_DEPTH    = 0
+
+# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent 
+# background. This is disabled by default, which results in a white background. 
+# Warning: Depending on the platform used, enabling this option may lead to 
+# badly anti-aliased labels on the edges of a graph (i.e. they become hard to 
+# read).
+
+DOT_TRANSPARENT        = NO
+
+# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output 
+# files in one run (i.e. multiple -o and -T options on the command line). This 
+# makes dot run faster, but since only newer versions of dot (>1.8.10) 
+# support this, this feature is disabled by default.
+
+DOT_MULTI_TARGETS      = NO
+
+# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will 
+# generate a legend page explaining the meaning of the various boxes and 
+# arrows in the dot generated graphs.
+
+GENERATE_LEGEND        = YES
+
+# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will 
+# remove the intermediate dot files that are used to generate 
+# the various graphs.
+
+DOT_CLEANUP            = YES
+
+#---------------------------------------------------------------------------
+# Configuration::additions related to the search engine   
+#---------------------------------------------------------------------------
+
+# The SEARCHENGINE tag specifies whether or not a search engine should be 
+# used. If set to NO the values of all tags below this one will be ignored.
+
+SEARCHENGINE           = NO
--- a/Kbuild	Thu Sep 13 11:08:46 2007 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,36 +0,0 @@
-#------------------------------------------------------------------------------
-#
-#  $Id$
-#
-#  Copyright (C) 2006  Florian Pose, Ingenieurgemeinschaft IgH
-#
-#  This file is part of the IgH EtherCAT Master.
-#
-#  The IgH EtherCAT Master is free software; you can redistribute it
-#  and/or modify it under the terms of the GNU General Public License
-#  as published by the Free Software Foundation; either version 2 of the
-#  License, or (at your option) any later version.
-#
-#  The IgH EtherCAT Master is distributed in the hope that it will be
-#  useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
-#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-#  GNU General Public License for more details.
-#
-#  You should have received a copy of the GNU General Public License
-#  along with the IgH EtherCAT Master; if not, write to the Free Software
-#  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-#
-#  The right to use EtherCAT Technology is granted and comes free of
-#  charge under condition of compatibility of product made by
-#  Licensee. People intending to distribute/sell products based on the
-#  code, have to sign an agreement to guarantee that products using
-#  software based on IgH EtherCAT master stay compatible with the actual
-#  EtherCAT specification (which are released themselves as an open
-#  standard) as the (only) precondition to have the right to use EtherCAT
-#  Technology, IP and trade marks.
-#
-#------------------------------------------------------------------------------
-
-obj-m := master/ devices/ dummy/
-
-#------------------------------------------------------------------------------
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Kbuild.in	Wed Oct 03 08:58:01 2007 +0000
@@ -0,0 +1,36 @@
+#------------------------------------------------------------------------------
+#
+#  $Id$
+#
+#  Copyright (C) 2006  Florian Pose, Ingenieurgemeinschaft IgH
+#
+#  This file is part of the IgH EtherCAT Master.
+#
+#  The IgH EtherCAT Master is free software; you can redistribute it
+#  and/or modify it under the terms of the GNU General Public License
+#  as published by the Free Software Foundation; either version 2 of the
+#  License, or (at your option) any later version.
+#
+#  The IgH EtherCAT Master is distributed in the hope that it will be
+#  useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#  GNU General Public License for more details.
+#
+#  You should have received a copy of the GNU General Public License
+#  along with the IgH EtherCAT Master; if not, write to the Free Software
+#  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+#
+#  The right to use EtherCAT Technology is granted and comes free of
+#  charge under condition of compatibility of product made by
+#  Licensee. People intending to distribute/sell products based on the
+#  code, have to sign an agreement to guarantee that products using
+#  software based on IgH EtherCAT master stay compatible with the actual
+#  EtherCAT specification (which are released themselves as an open
+#  standard) as the (only) precondition to have the right to use EtherCAT
+#  Technology, IP and trade marks.
+#
+#------------------------------------------------------------------------------
+
+obj-m := master/ devices/ dummy/
+
+#------------------------------------------------------------------------------
--- a/Makefile.am	Thu Sep 13 11:08:46 2007 +0000
+++ b/Makefile.am	Wed Oct 03 08:58:01 2007 +0000
@@ -39,7 +39,7 @@
 	Doxyfile \
 	FEATURES \
 	globals.h \
-	Kbuild \
+	Kbuild.in \
 	README.EoE
 
 modules:
@@ -74,13 +74,13 @@
 		config.h.in \
 		config.log \
 		config.status \
-		config.kbuild \
 		configure.in \
 		configure \
 		Makefile \
 		Makefile.in \
 		stamp-h1 \
 		ChangeLog \
+        Kbuild \
 		*~
 
 doc:
--- a/NEWS	Thu Sep 13 11:08:46 2007 +0000
+++ b/NEWS	Wed Oct 03 08:58:01 2007 +0000
@@ -4,6 +4,19 @@
 
 -------------------------------------------------------------------------------
 
+Changes in version 1.3.2:
+
+* New feature: Read dynamic PDO mapping from SDO dictionary.
+* Implemented SII writing workaround for some broken slaves.
+* Improved handling for spontaneous AL state changes.
+* Master takes mailbox sync manager configurations from EEPROM words
+  0x0018-0x001b, if no sync manager configurations are provided.
+* Calculate checksum when writing EEPROM or alias address.
+* Fixed source MAC address setting bug.
+* Removed config.kbuild and replaced Kbuild files by Kbuild.in files.
+
+-------------------------------------------------------------------------------
+
 Changes in version 1.3.1:
 
 * Improved EoE handling: Avoided skipping of datagrams and release lock
--- a/TODO	Thu Sep 13 11:08:46 2007 +0000
+++ b/TODO	Wed Oct 03 08:58:01 2007 +0000
@@ -7,16 +7,16 @@
 -------------------------------------------------------------------------------
 
 * Future features:
-  - Interface/buffers for asynchronous domain IO.
   - Distributed clocks.
-  - Dynamic PDO mapping from SDO dictionary (see can-cia.org: cia301ds4).
   - Redundancy with 2 network adapters.
   - Mailbox handler
   - Support slaves, that don't support the LRW datagram, only LRD/LWR.
   - PDO reading in IDLE mode.
   - Replace Sysfs interface with cdev and user space program.
+  - Interface/buffers for asynchronous domain IO.
 
 * Smaller issues:
+  - Datagram debugging flag.
   - Clear sync managers in INIT.
   - Simplify FSMs with <state>_enter() functions.
   - Output intermediate results during lsec.
@@ -31,12 +31,12 @@
   - Interrupt master state machines state scan for other jobs.
   - Master state machine, slave configuration: Do not check every slave on
     a cycle.
-  - Do only execute one EoE handler per EoE cycle.
+  - Only execute one EoE handler per EoE cycle.
 
 * Less important issues:
   - Implement all EtherCAT datagram types.
   - File access over EtherCAT (FoE).
   - Allow VLAN tagging.
-  - Determine number of frames the NIC can handle.
+  - Determine number of frames, the NIC can handle.
 
 -------------------------------------------------------------------------------
--- a/configure.ac	Thu Sep 13 11:08:46 2007 +0000
+++ b/configure.ac	Wed Oct 03 08:58:01 2007 +0000
@@ -3,7 +3,7 @@
 #------------------------------------------------------------------------------
 
 AC_PREREQ(2.59)
-AC_INIT([ethercat],[1.3.1],[fp@igh-essen.com])
+AC_INIT([ethercat],[1.3.2],[fp@igh-essen.com])
 AC_CONFIG_AUX_DIR([autoconf])
 AM_INIT_AUTOMAKE([-Wall -Werror dist-bzip2])
 AC_PREFIX_DEFAULT([/opt/etherlab])
@@ -97,6 +97,7 @@
 )
 
 AM_CONDITIONAL(ENABLE_8139TOO, test "x$enable8139too" = "x1")
+AC_SUBST(ENABLE_8139TOO,[$enable8139too])
 
 AC_ARG_WITH([8139too-kernel],
     AC_HELP_STRING(
@@ -128,6 +129,8 @@
     AC_MSG_RESULT([$kernel8139too])
 fi
 
+AC_SUBST(KERNEL_8139TOO,[$kernel8139too])
+
 #------------------------------------------------------------------------------
 # e100 driver
 #------------------------------------------------------------------------------
@@ -149,6 +152,7 @@
 )
 
 AM_CONDITIONAL(ENABLE_E100, test "x$enablee100" = "x1")
+AC_SUBST(ENABLE_E100,[$enablee100])
 
 AC_ARG_WITH([e100-kernel],
     AC_HELP_STRING(
@@ -180,6 +184,8 @@
     AC_MSG_RESULT([$kernele100])
 fi
 
+AC_SUBST(KERNEL_E100,[$kernele100])
+
 #------------------------------------------------------------------------------
 # forcedeth driver
 #------------------------------------------------------------------------------
@@ -201,6 +207,7 @@
 )
 
 AM_CONDITIONAL(ENABLE_FORCEDETH, test "x$enableforcedeth" = "x1")
+AC_SUBST(ENABLE_FORCEDETH,[$enableforcedeth])
 
 AC_ARG_WITH([forcedeth-kernel],
     AC_HELP_STRING(
@@ -232,6 +239,8 @@
     AC_MSG_RESULT([$kernelforcedeth])
 fi
 
+AC_SUBST(KERNEL_FORCEDETH,[$kernelforcedeth])
+
 #------------------------------------------------------------------------------
 # e1000 driver
 #------------------------------------------------------------------------------
@@ -253,6 +262,7 @@
 )
 
 AM_CONDITIONAL(ENABLE_E1000, test "x$enablee1000" = "x1")
+AC_SUBST(ENABLE_E1000,[$enablee1000])
 
 AC_ARG_WITH([e1000-kernel],
     AC_HELP_STRING(
@@ -284,6 +294,8 @@
     AC_MSG_RESULT([$kernele1000])
 fi
 
+AC_SUBST(KERNEL_E1000,[$kernele1000])
+
 #------------------------------------------------------------------------------
 # RTAI path (optional)
 #------------------------------------------------------------------------------
@@ -310,8 +322,9 @@
         AC_MSG_ERROR([no RTAI installation found in ${rtaidir}!])
     fi
     AC_MSG_RESULT([$rtaidir])
-    AC_SUBST(RTAI_DIR,[$rtaidir])
-fi
+fi
+
+AC_SUBST(RTAI_DIR,[$rtaidir])
 
 #------------------------------------------------------------------------------
 # MSR path (optional)
@@ -339,8 +352,9 @@
         AC_MSG_ERROR([no MSR installation found in ${msrdir}!])
     fi
     AC_MSG_RESULT([$msrdir])
-    AC_SUBST(MSR_DIR,[$msrdir])
-fi
+fi
+
+AC_SUBST(MSR_DIR,[$msrdir])
 
 #------------------------------------------------------------------------------
 # Debug interface
@@ -366,6 +380,7 @@
     AC_DEFINE([EC_DEBUG_IF], [1], [Debug interfaces enabled])
 fi
 AM_CONDITIONAL(ENABLE_DEBUG_IF, test "x$dbg" = "x1")
+AC_SUBST(ENABLE_DEBUG_IF,[$dbg])
 
 #------------------------------------------------------------------------------
 # Debug ring
@@ -412,6 +427,7 @@
 )
 
 AM_CONDITIONAL(ENABLE_DUMMY, test "x$dummy" = "x1")
+AC_SUBST(ENABLE_DUMMY,[$dummy])
 
 #------------------------------------------------------------------------------
 # Ethernet-over-EtherCAT support
@@ -437,45 +453,32 @@
     AC_DEFINE([EC_EOE], [1], [EoE support enabled])
 fi
 AM_CONDITIONAL(ENABLE_EOE, test "x$eoe" = "x1")
-
-#------------------------------------------------------------------------------
-
-# Create config.kbuild
-
-echo configure: creating config.kbuild...
-
-cat > config.kbuild <<EOF
-# config.kbuild - created by configure
-ENABLE_8139TOO := ${enable8139too}
-KERNEL_8139TOO := ${kernel8139too}
-ENABLE_E100 := ${enablee100}
-KERNEL_E100 := ${kernele100}
-ENABLE_FORCEDETH := ${enableforcedeth}
-KERNEL_FORCEDETH := ${kernelforcedeth}
-ENABLE_E1000 := ${enablee1000}
-KERNEL_E1000 := ${kernele1000}
-RTAI_DIR := "${rtaidir}"
-MSR_DIR := "${msrdir}"
-ENABLE_DEBUG_IF := ${dbg}
-ENABLE_DUMMY := ${dummy}
-ENABLE_EOE := ${eoe}
-EOF
+AC_SUBST(ENABLE_EOE,[$eoe])
 
 #------------------------------------------------------------------------------
 
 AC_CONFIG_FILES([
+        Doxyfile
+        Kbuild
         Makefile
+        master/Kbuild
         master/Makefile
+        devices/Kbuild
         devices/Makefile
         devices/e1000/Makefile
+        devices/e1000/Kbuild
         script/Makefile
         script/init.d/Makefile
         script/sysconfig/Makefile
         include/Makefile
         examples/Makefile
+        examples/mini/Kbuild
         examples/mini/Makefile
+        examples/rtai/Kbuild
         examples/rtai/Makefile
+        examples/msr/Kbuild
         examples/msr/Makefile
+        dummy/Kbuild
         dummy/Makefile
 ])
 AC_OUTPUT
--- a/devices/Kbuild	Thu Sep 13 11:08:46 2007 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,67 +0,0 @@
-#------------------------------------------------------------------------------
-#
-#  $Id$
-#
-#  Copyright (C) 2006  Florian Pose, Ingenieurgemeinschaft IgH
-#
-#  This file is part of the IgH EtherCAT Master.
-#
-#  The IgH EtherCAT Master is free software; you can redistribute it
-#  and/or modify it under the terms of the GNU General Public License
-#  as published by the Free Software Foundation; either version 2 of the
-#  License, or (at your option) any later version.
-#
-#  The IgH EtherCAT Master is distributed in the hope that it will be
-#  useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
-#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-#  GNU General Public License for more details.
-#
-#  You should have received a copy of the GNU General Public License
-#  along with the IgH EtherCAT Master; if not, write to the Free Software
-#  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-#
-#  The right to use EtherCAT Technology is granted and comes free of
-#  charge under condition of compatibility of product made by
-#  Licensee. People intending to distribute/sell products based on the
-#  code, have to sign an agreement to guarantee that products using
-#  software based on IgH EtherCAT master stay compatible with the actual
-#  EtherCAT specification (which are released themselves as an open
-#  standard) as the (only) precondition to have the right to use EtherCAT
-#  Technology, IP and trade marks.
-#
-#------------------------------------------------------------------------------
-
-include $(src)/../config.kbuild
-
-REV := $(shell if test -s $(src)/../svnrevision; then \
-		cat $(src)/../svnrevision; \
-	else \
-		svnversion $(src)/.. 2>/dev/null || echo "unknown"; \
-	fi)
-
-ifeq ($(ENABLE_8139TOO),1)
-	EC_8139TOO_OBJ := 8139too-$(KERNEL_8139TOO)-ethercat.o
-	obj-m += ec_8139too.o
-	ec_8139too-objs := $(EC_8139TOO_OBJ)
-	CFLAGS_$(EC_8139TOO_OBJ) = -DSVNREV=$(REV)
-endif
-
-ifeq ($(ENABLE_E100),1)
-	EC_E100_OBJ := e100-$(KERNEL_E100)-ethercat.o
-	obj-m += ec_e100.o
-	ec_e100-objs := $(EC_E100_OBJ)
-	CFLAGS_$(EC_E100_OBJ) = -DSVNREV=$(REV)
-endif
-
-ifeq ($(ENABLE_FORCEDETH),1)
-	EC_FORCEDETH_OBJ := forcedeth-$(KERNEL_FORCEDETH)-ethercat.o
-	obj-m += ec_forcedeth.o
-	ec_forcedeth-objs := $(EC_FORCEDETH_OBJ)
-	CFLAGS_$(EC_FORCEDETH_OBJ) = -DSVNREV=$(REV)
-endif
-
-ifeq ($(ENABLE_E1000),1)
-    obj-m += e1000/
-endif
-
-#------------------------------------------------------------------------------
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/devices/Kbuild.in	Wed Oct 03 08:58:01 2007 +0000
@@ -0,0 +1,65 @@
+#------------------------------------------------------------------------------
+#
+#  $Id$
+#
+#  Copyright (C) 2006  Florian Pose, Ingenieurgemeinschaft IgH
+#
+#  This file is part of the IgH EtherCAT Master.
+#
+#  The IgH EtherCAT Master is free software; you can redistribute it
+#  and/or modify it under the terms of the GNU General Public License
+#  as published by the Free Software Foundation; either version 2 of the
+#  License, or (at your option) any later version.
+#
+#  The IgH EtherCAT Master is distributed in the hope that it will be
+#  useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#  GNU General Public License for more details.
+#
+#  You should have received a copy of the GNU General Public License
+#  along with the IgH EtherCAT Master; if not, write to the Free Software
+#  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+#
+#  The right to use EtherCAT Technology is granted and comes free of
+#  charge under condition of compatibility of product made by
+#  Licensee. People intending to distribute/sell products based on the
+#  code, have to sign an agreement to guarantee that products using
+#  software based on IgH EtherCAT master stay compatible with the actual
+#  EtherCAT specification (which are released themselves as an open
+#  standard) as the (only) precondition to have the right to use EtherCAT
+#  Technology, IP and trade marks.
+#
+#------------------------------------------------------------------------------
+
+REV := $(shell if test -s $(src)/../svnrevision; then \
+		cat $(src)/../svnrevision; \
+	else \
+		svnversion $(src)/.. 2>/dev/null || echo "unknown"; \
+	fi)
+
+ifeq (@ENABLE_8139TOO@,1)
+	EC_8139TOO_OBJ := 8139too-@KERNEL_8139TOO@-ethercat.o
+	obj-m += ec_8139too.o
+	ec_8139too-objs := $(EC_8139TOO_OBJ)
+	CFLAGS_$(EC_8139TOO_OBJ) = -DSVNREV=$(REV)
+endif
+
+ifeq (@ENABLE_E100@,1)
+	EC_E100_OBJ := e100-@KERNEL_E100@-ethercat.o
+	obj-m += ec_e100.o
+	ec_e100-objs := $(EC_E100_OBJ)
+	CFLAGS_$(EC_E100_OBJ) = -DSVNREV=$(REV)
+endif
+
+ifeq (@ENABLE_FORCEDETH@,1)
+	EC_FORCEDETH_OBJ := forcedeth-@KERNEL_FORCEDETH@-ethercat.o
+	obj-m += ec_forcedeth.o
+	ec_forcedeth-objs := $(EC_FORCEDETH_OBJ)
+	CFLAGS_$(EC_FORCEDETH_OBJ) = -DSVNREV=$(REV)
+endif
+
+ifeq (@ENABLE_E1000@,1)
+    obj-m += e1000/
+endif
+
+#------------------------------------------------------------------------------
--- a/devices/Makefile.am	Thu Sep 13 11:08:46 2007 +0000
+++ b/devices/Makefile.am	Wed Oct 03 08:58:01 2007 +0000
@@ -36,7 +36,7 @@
 DIST_SUBDIRS = e1000
 
 EXTRA_DIST = \
-	Kbuild \
+	Kbuild.in \
 	ecdev.h \
 	8139too-2.6.13-ethercat.c \
 	8139too-2.6.13-orig.c \
--- a/devices/e1000/Kbuild	Thu Sep 13 11:08:46 2007 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,53 +0,0 @@
-#------------------------------------------------------------------------------
-#
-#  $Id: Kbuild 790 2007-02-21 12:41:25Z fp $
-#
-#  Copyright (C) 2006  Florian Pose, Ingenieurgemeinschaft IgH
-#
-#  This file is part of the IgH EtherCAT Master.
-#
-#  The IgH EtherCAT Master is free software; you can redistribute it
-#  and/or modify it under the terms of the GNU General Public License
-#  as published by the Free Software Foundation; either version 2 of the
-#  License, or (at your option) any later version.
-#
-#  The IgH EtherCAT Master is distributed in the hope that it will be
-#  useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
-#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-#  GNU General Public License for more details.
-#
-#  You should have received a copy of the GNU General Public License
-#  along with the IgH EtherCAT Master; if not, write to the Free Software
-#  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-#
-#  The right to use EtherCAT Technology is granted and comes free of
-#  charge under condition of compatibility of product made by
-#  Licensee. People intending to distribute/sell products based on the
-#  code, have to sign an agreement to guarantee that products using
-#  software based on IgH EtherCAT master stay compatible with the actual
-#  EtherCAT specification (which are released themselves as an open
-#  standard) as the (only) precondition to have the right to use EtherCAT
-#  Technology, IP and trade marks.
-#
-#------------------------------------------------------------------------------
-
-TOPDIR := $(src)/../..
-include $(TOPDIR)/config.kbuild
-
-REV := $(shell if test -s $(TOPDIR)/svnrevision; then \
-		cat $(TOPDIR)/svnrevision; \
-	else \
-		svnversion $(TOPDIR) 2>/dev/null || echo "unknown"; \
-	fi)
-
-ifeq ($(ENABLE_E1000),1)
-	EC_E1000_OBJ := e1000_main-$(KERNEL_E1000)-ethercat.o \
-        e1000_hw-$(KERNEL_E1000)-ethercat.o \
-        e1000_ethtool-$(KERNEL_E1000)-ethercat.o \
-        e1000_param-$(KERNEL_E1000)-ethercat.o
-	obj-m += ec_e1000.o
-	ec_e1000-objs := $(EC_E1000_OBJ)
-	CFLAGS_e1000_main-$(KERNEL_E1000)-ethercat.o = -DSVNREV=$(REV)
-endif
-
-#------------------------------------------------------------------------------
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/devices/e1000/Kbuild.in	Wed Oct 03 08:58:01 2007 +0000
@@ -0,0 +1,52 @@
+#------------------------------------------------------------------------------
+#
+#  $Id: Kbuild 790 2007-02-21 12:41:25Z fp $
+#
+#  Copyright (C) 2006  Florian Pose, Ingenieurgemeinschaft IgH
+#
+#  This file is part of the IgH EtherCAT Master.
+#
+#  The IgH EtherCAT Master is free software; you can redistribute it
+#  and/or modify it under the terms of the GNU General Public License
+#  as published by the Free Software Foundation; either version 2 of the
+#  License, or (at your option) any later version.
+#
+#  The IgH EtherCAT Master is distributed in the hope that it will be
+#  useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#  GNU General Public License for more details.
+#
+#  You should have received a copy of the GNU General Public License
+#  along with the IgH EtherCAT Master; if not, write to the Free Software
+#  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+#
+#  The right to use EtherCAT Technology is granted and comes free of
+#  charge under condition of compatibility of product made by
+#  Licensee. People intending to distribute/sell products based on the
+#  code, have to sign an agreement to guarantee that products using
+#  software based on IgH EtherCAT master stay compatible with the actual
+#  EtherCAT specification (which are released themselves as an open
+#  standard) as the (only) precondition to have the right to use EtherCAT
+#  Technology, IP and trade marks.
+#
+#------------------------------------------------------------------------------
+
+TOPDIR := $(src)/../..
+
+REV := $(shell if test -s $(TOPDIR)/svnrevision; then \
+		cat $(TOPDIR)/svnrevision; \
+	else \
+		svnversion $(TOPDIR) 2>/dev/null || echo "unknown"; \
+	fi)
+
+ifeq (@ENABLE_E1000@,1)
+	EC_E1000_OBJ := e1000_main-@KERNEL_E1000@-ethercat.o \
+        e1000_hw-@KERNEL_E1000@-ethercat.o \
+        e1000_ethtool-@KERNEL_E1000@-ethercat.o \
+        e1000_param-@KERNEL_E1000@-ethercat.o
+	obj-m += ec_e1000.o
+	ec_e1000-objs := $(EC_E1000_OBJ)
+	CFLAGS_e1000_main-@KERNEL_E1000@-ethercat.o = -DSVNREV=$(REV)
+endif
+
+#------------------------------------------------------------------------------
--- a/devices/e1000/Makefile.am	Thu Sep 13 11:08:46 2007 +0000
+++ b/devices/e1000/Makefile.am	Wed Oct 03 08:58:01 2007 +0000
@@ -32,7 +32,7 @@
 #------------------------------------------------------------------------------
 
 EXTRA_DIST = \
-	Kbuild \
+	Kbuild.in \
 	e1000_ethtool-2.6.13-ethercat.c \
 	e1000_ethtool-2.6.13-orig.c \
 	e1000-2.6.13-ethercat.h \
--- a/devices/e1000/e1000_main-2.6.13-ethercat.c	Thu Sep 13 11:08:46 2007 +0000
+++ b/devices/e1000/e1000_main-2.6.13-ethercat.c	Wed Oct 03 08:58:01 2007 +0000
@@ -164,8 +164,8 @@
 static void e1000_vlan_rx_kill_vid(struct net_device *netdev, uint16_t vid);
 static void e1000_restore_vlan(struct e1000_adapter *adapter);
 
+#ifdef CONFIG_PM
 static int e1000_suspend(struct pci_dev *pdev, uint32_t state);
-#ifdef CONFIG_PM
 static int e1000_resume(struct pci_dev *pdev);
 #endif
 
@@ -2667,8 +2667,9 @@
 	struct e1000_adapter *adapter = netdev_priv(netdev);
 	struct e1000_hw *hw = &adapter->hw;
 	uint32_t icr = E1000_READ_REG(hw, ICR);
-#ifndef CONFIG_E1000_NAPI
 	unsigned int i;
+#ifdef CONFIG_E1000_NAPI
+	int work_done = 0;
 #endif
 
 	if(unlikely(!icr))
@@ -2681,15 +2682,22 @@
 	}
 
 #ifdef CONFIG_E1000_NAPI
-	if(!adapter->ecdev && likely(netif_rx_schedule_prep(netdev))) {
-
-		/* Disable interrupts and register for poll. The flush 
-		  of the posted write is intentionally left out.
-		*/
-
-		atomic_inc(&adapter->irq_sem);
-		E1000_WRITE_REG(hw, IMC, ~0);
-		__netif_rx_schedule(netdev);
+	if (adapter->ecdev) {
+		for(i = 0; i < E1000_MAX_INTR; i++)
+			if(unlikely(!adapter->clean_rx(adapter, &work_done, 100) &
+						!e1000_clean_tx_irq(adapter)))
+				break;
+	} else {
+		if(likely(netif_rx_schedule_prep(netdev))) {
+
+			/* Disable interrupts and register for poll. The flush 
+			   of the posted write is intentionally left out.
+			 */
+
+			atomic_inc(&adapter->irq_sem);
+			E1000_WRITE_REG(hw, IMC, ~0);
+			__netif_rx_schedule(netdev);
+		}
 	}
 #else
 	/* Writing IMC and IMS is needed for 82547.
@@ -3760,6 +3768,7 @@
 	return 0;
 }
 
+#ifdef CONFIG_PM
 static int
 e1000_suspend(struct pci_dev *pdev, uint32_t state)
 {
@@ -3853,7 +3862,6 @@
 	return 0;
 }
 
-#ifdef CONFIG_PM
 static int
 e1000_resume(struct pci_dev *pdev)
 {
--- a/documentation/graphs/Makefile	Thu Sep 13 11:08:46 2007 +0000
+++ b/documentation/graphs/Makefile	Wed Oct 03 08:58:01 2007 +0000
@@ -4,7 +4,11 @@
 #
 #-----------------------------------------------------------------------------
 
-GRAPHS := fsm_slave_conf.ps fsm_pdo_mapping.ps fsm_master.ps
+GRAPHS := \
+	fsm_slave_conf.ps \
+	fsm_pdo_mapping.ps \
+	fsm_master.ps \
+	fsm_coe_map.ps
 
 all: $(GRAPHS)
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/documentation/graphs/fsm_coe_map.dot	Wed Oct 03 08:58:01 2007 +0000
@@ -0,0 +1,33 @@
+
+/* $Id$ */
+
+digraph readpdomapping {
+    size="7,9"
+    center=1
+	ratio=fill
+
+    next_sync [shape=point,label=""]
+    next_pdo [shape=point,label=""]
+    next_pdo_entry [shape=point,label=""]
+
+    start -> next_sync [label="first SM"]
+
+    next_sync -> pdo_count [weight=5]
+    next_sync -> end
+
+    pdo_count -> next_pdo [weight=5]
+
+    next_pdo -> pdo [weight=5]
+    next_pdo -> next_sync
+
+    pdo -> pdo_entry_count [weight=5]
+
+    pdo_entry_count -> next_pdo_entry [weight=10]
+
+    next_pdo_entry -> pdo_entry [weight=5]
+    next_pdo_entry -> next_pdo
+
+    pdo_entry -> next_pdo_entry
+
+    end
+}
--- a/dummy/Kbuild	Thu Sep 13 11:08:46 2007 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,48 +0,0 @@
-#------------------------------------------------------------------------------
-#
-#  $Id: Kbuild 844 2007-03-08 18:15:25Z fp $
-#
-#  Copyright (C) 2006  Florian Pose, Ingenieurgemeinschaft IgH
-#
-#  This file is part of the IgH EtherCAT Master.
-#
-#  The IgH EtherCAT Master is free software; you can redistribute it
-#  and/or modify it under the terms of the GNU General Public License
-#  as published by the Free Software Foundation; either version 2 of the
-#  License, or (at your option) any later version.
-#
-#  The IgH EtherCAT Master is distributed in the hope that it will be
-#  useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
-#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-#  GNU General Public License for more details.
-#
-#  You should have received a copy of the GNU General Public License
-#  along with the IgH EtherCAT Master; if not, write to the Free Software
-#  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-#
-#  The right to use EtherCAT Technology is granted and comes free of
-#  charge under condition of compatibility of product made by
-#  Licensee. People intending to distribute/sell products based on the
-#  code, have to sign an agreement to guarantee that products using
-#  software based on IgH EtherCAT master stay compatible with the actual
-#  EtherCAT specification (which are released themselves as an open
-#  standard) as the (only) precondition to have the right to use EtherCAT
-#  Technology, IP and trade marks.
-#
-#------------------------------------------------------------------------------
-
-include $(src)/../config.kbuild
-
-REV := $(shell if test -s $(src)/../svnrevision; then \
-		cat $(src)/../svnrevision; \
-	else \
-		svnversion $(src) 2>/dev/null || echo "unknown"; \
-	fi)
-
-ifeq ($(ENABLE_DUMMY),1)
-    obj-m := ec_dummy.o
-	ec_dummy-objs := module.o master.o slave.o domain.o
-	CFLAGS_dummy.o := -DSVNREV=$(REV)
-endif
-
-#------------------------------------------------------------------------------
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dummy/Kbuild.in	Wed Oct 03 08:58:01 2007 +0000
@@ -0,0 +1,46 @@
+#------------------------------------------------------------------------------
+#
+#  $Id: Kbuild 844 2007-03-08 18:15:25Z fp $
+#
+#  Copyright (C) 2006  Florian Pose, Ingenieurgemeinschaft IgH
+#
+#  This file is part of the IgH EtherCAT Master.
+#
+#  The IgH EtherCAT Master is free software; you can redistribute it
+#  and/or modify it under the terms of the GNU General Public License
+#  as published by the Free Software Foundation; either version 2 of the
+#  License, or (at your option) any later version.
+#
+#  The IgH EtherCAT Master is distributed in the hope that it will be
+#  useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#  GNU General Public License for more details.
+#
+#  You should have received a copy of the GNU General Public License
+#  along with the IgH EtherCAT Master; if not, write to the Free Software
+#  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+#
+#  The right to use EtherCAT Technology is granted and comes free of
+#  charge under condition of compatibility of product made by
+#  Licensee. People intending to distribute/sell products based on the
+#  code, have to sign an agreement to guarantee that products using
+#  software based on IgH EtherCAT master stay compatible with the actual
+#  EtherCAT specification (which are released themselves as an open
+#  standard) as the (only) precondition to have the right to use EtherCAT
+#  Technology, IP and trade marks.
+#
+#------------------------------------------------------------------------------
+
+REV := $(shell if test -s $(src)/../svnrevision; then \
+		cat $(src)/../svnrevision; \
+	else \
+		svnversion $(src) 2>/dev/null || echo "unknown"; \
+	fi)
+
+ifeq (@ENABLE_DUMMY@,1)
+    obj-m := ec_dummy.o
+	ec_dummy-objs := module.o master.o slave.o domain.o
+	CFLAGS_dummy.o := -DSVNREV=$(REV)
+endif
+
+#------------------------------------------------------------------------------
--- a/dummy/Makefile.am	Thu Sep 13 11:08:46 2007 +0000
+++ b/dummy/Makefile.am	Wed Oct 03 08:58:01 2007 +0000
@@ -32,7 +32,7 @@
 #------------------------------------------------------------------------------
 
 EXTRA_DIST = \
-	Kbuild \
+	Kbuild.in \
 	module.c \
     master.c \
     slave.c \
--- a/examples/mini/Kbuild	Thu Sep 13 11:08:46 2007 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,38 +0,0 @@
-#------------------------------------------------------------------------------
-#
-#  $Id$
-#
-#  Copyright (C) 2006  Florian Pose, Ingenieurgemeinschaft IgH
-#
-#  This file is part of the IgH EtherCAT Master.
-#
-#  The IgH EtherCAT Master is free software; you can redistribute it
-#  and/or modify it under the terms of the GNU General Public License
-#  as published by the Free Software Foundation; either version 2 of the
-#  License, or (at your option) any later version.
-#
-#  The IgH EtherCAT Master is distributed in the hope that it will be
-#  useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
-#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-#  GNU General Public License for more details.
-#
-#  You should have received a copy of the GNU General Public License
-#  along with the IgH EtherCAT Master; if not, write to the Free Software
-#  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-#
-#  The right to use EtherCAT Technology is granted and comes free of
-#  charge under condition of compatibility of product made by
-#  Licensee. People intending to distribute/sell products based on the
-#  code, have to sign an agreement to guarantee that products using
-#  software based on IgH EtherCAT master stay compatible with the actual
-#  EtherCAT specification (which are released themselves as an open
-#  standard) as the (only) precondition to have the right to use EtherCAT
-#  Technology, IP and trade marks.
-#
-#------------------------------------------------------------------------------
-
-obj-m := ec_mini.o
-
-ec_mini-objs := mini.o
-
-#------------------------------------------------------------------------------
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/mini/Kbuild.in	Wed Oct 03 08:58:01 2007 +0000
@@ -0,0 +1,38 @@
+#------------------------------------------------------------------------------
+#
+#  $Id$
+#
+#  Copyright (C) 2006  Florian Pose, Ingenieurgemeinschaft IgH
+#
+#  This file is part of the IgH EtherCAT Master.
+#
+#  The IgH EtherCAT Master is free software; you can redistribute it
+#  and/or modify it under the terms of the GNU General Public License
+#  as published by the Free Software Foundation; either version 2 of the
+#  License, or (at your option) any later version.
+#
+#  The IgH EtherCAT Master is distributed in the hope that it will be
+#  useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#  GNU General Public License for more details.
+#
+#  You should have received a copy of the GNU General Public License
+#  along with the IgH EtherCAT Master; if not, write to the Free Software
+#  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+#
+#  The right to use EtherCAT Technology is granted and comes free of
+#  charge under condition of compatibility of product made by
+#  Licensee. People intending to distribute/sell products based on the
+#  code, have to sign an agreement to guarantee that products using
+#  software based on IgH EtherCAT master stay compatible with the actual
+#  EtherCAT specification (which are released themselves as an open
+#  standard) as the (only) precondition to have the right to use EtherCAT
+#  Technology, IP and trade marks.
+#
+#------------------------------------------------------------------------------
+
+obj-m := ec_mini.o
+
+ec_mini-objs := mini.o
+
+#------------------------------------------------------------------------------
--- a/examples/mini/Makefile.am	Thu Sep 13 11:08:46 2007 +0000
+++ b/examples/mini/Makefile.am	Wed Oct 03 08:58:01 2007 +0000
@@ -35,7 +35,9 @@
 #
 #------------------------------------------------------------------------------
 
-EXTRA_DIST = Kbuild mini.c
+EXTRA_DIST = \
+	Kbuild.in \
+	mini.c
 
 all:
 	$(MAKE) -C "$(LINUX_SOURCE_DIR)" M="@abs_srcdir@" modules
--- a/examples/msr/Kbuild	Thu Sep 13 11:08:46 2007 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,58 +0,0 @@
-#------------------------------------------------------------------------------
-#
-#  $Id$
-#
-#  Copyright (C) 2006  Florian Pose, Ingenieurgemeinschaft IgH
-#
-#  This file is part of the IgH EtherCAT Master.
-#
-#  The IgH EtherCAT Master is free software; you can redistribute it
-#  and/or modify it under the terms of the GNU General Public License
-#  as published by the Free Software Foundation; either version 2 of the
-#  License, or (at your option) any later version.
-#
-#  The IgH EtherCAT Master is distributed in the hope that it will be
-#  useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
-#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-#  GNU General Public License for more details.
-#
-#  You should have received a copy of the GNU General Public License
-#  along with the IgH EtherCAT Master; if not, write to the Free Software
-#  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-#
-#  The right to use EtherCAT Technology is granted and comes free of
-#  charge under condition of compatibility of product made by
-#  Licensee. People intending to distribute/sell products based on the
-#  code, have to sign an agreement to guarantee that products using
-#  software based on IgH EtherCAT master stay compatible with the actual
-#  EtherCAT specification (which are released themselves as an open
-#  standard) as the (only) precondition to have the right to use EtherCAT
-#  Technology, IP and trade marks.
-#
-#------------------------------------------------------------------------------
-
-include $(src)/../../config.kbuild
-
-MODULE := ec_msr_sample
-
-obj-m := $(MODULE).o
-
-$(MODULE)-objs := msr_sample.o \
-                        rt_lib/msr-core/msr_lists.o \
-                        rt_lib/msr-core/msr_main.o \
-                        rt_lib/msr-core/msr_charbuf.o \
-                        rt_lib/msr-core/msr_reg.o \
-                        rt_lib/msr-core/msr_interpreter.o \
-                        rt_lib/msr-core/msr_messages.o \
-                        rt_lib/msr-core/msr_proc.o \
-                        rt_lib/msr-core/msr_error_reg.o \
-                        rt_lib/msr-utils/msr_utils.o \
-                        rt_lib/msr-utils/msr_time.o \
-                        rt_lib/msr-math/msr_base64.o \
-                        rt_lib/msr-math/msr_hex_bin.o \
-                        libm.o
-
-EXTRA_CFLAGS := -I$(MSR_DIR)/include -I$(RTAI_DIR)/include \
-                -D_SIMULATION -mhard-float
-
-#------------------------------------------------------------------------------
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/msr/Kbuild.in	Wed Oct 03 08:58:01 2007 +0000
@@ -0,0 +1,56 @@
+#------------------------------------------------------------------------------
+#
+#  $Id$
+#
+#  Copyright (C) 2006  Florian Pose, Ingenieurgemeinschaft IgH
+#
+#  This file is part of the IgH EtherCAT Master.
+#
+#  The IgH EtherCAT Master is free software; you can redistribute it
+#  and/or modify it under the terms of the GNU General Public License
+#  as published by the Free Software Foundation; either version 2 of the
+#  License, or (at your option) any later version.
+#
+#  The IgH EtherCAT Master is distributed in the hope that it will be
+#  useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#  GNU General Public License for more details.
+#
+#  You should have received a copy of the GNU General Public License
+#  along with the IgH EtherCAT Master; if not, write to the Free Software
+#  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+#
+#  The right to use EtherCAT Technology is granted and comes free of
+#  charge under condition of compatibility of product made by
+#  Licensee. People intending to distribute/sell products based on the
+#  code, have to sign an agreement to guarantee that products using
+#  software based on IgH EtherCAT master stay compatible with the actual
+#  EtherCAT specification (which are released themselves as an open
+#  standard) as the (only) precondition to have the right to use EtherCAT
+#  Technology, IP and trade marks.
+#
+#------------------------------------------------------------------------------
+
+MODULE := ec_msr_sample
+
+obj-m := $(MODULE).o
+
+$(MODULE)-objs := msr_sample.o \
+                        rt_lib/msr-core/msr_lists.o \
+                        rt_lib/msr-core/msr_main.o \
+                        rt_lib/msr-core/msr_charbuf.o \
+                        rt_lib/msr-core/msr_reg.o \
+                        rt_lib/msr-core/msr_interpreter.o \
+                        rt_lib/msr-core/msr_messages.o \
+                        rt_lib/msr-core/msr_proc.o \
+                        rt_lib/msr-core/msr_error_reg.o \
+                        rt_lib/msr-utils/msr_utils.o \
+                        rt_lib/msr-utils/msr_time.o \
+                        rt_lib/msr-math/msr_base64.o \
+                        rt_lib/msr-math/msr_hex_bin.o \
+                        libm.o
+
+EXTRA_CFLAGS := -I@MSR_DIR@/include -I@RTAI_DIR@/include \
+                -D_SIMULATION -mhard-float
+
+#------------------------------------------------------------------------------
--- a/examples/msr/Makefile.am	Thu Sep 13 11:08:46 2007 +0000
+++ b/examples/msr/Makefile.am	Wed Oct 03 08:58:01 2007 +0000
@@ -32,7 +32,7 @@
 #------------------------------------------------------------------------------
 
 EXTRA_DIST = \
-	Kbuild \
+	Kbuild.in \
 	libm.o_shipped \
 	msr_sample.c \
 	msrserv.pl \
--- a/examples/rtai/Kbuild	Thu Sep 13 11:08:46 2007 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,42 +0,0 @@
-#------------------------------------------------------------------------------
-#
-#  $Id$
-#
-#  Copyright (C) 2006  Florian Pose, Ingenieurgemeinschaft IgH
-#
-#  This file is part of the IgH EtherCAT Master.
-#
-#  The IgH EtherCAT Master is free software; you can redistribute it
-#  and/or modify it under the terms of the GNU General Public License
-#  as published by the Free Software Foundation; either version 2 of the
-#  License, or (at your option) any later version.
-#
-#  The IgH EtherCAT Master is distributed in the hope that it will be
-#  useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
-#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-#  GNU General Public License for more details.
-#
-#  You should have received a copy of the GNU General Public License
-#  along with the IgH EtherCAT Master; if not, write to the Free Software
-#  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-#
-#  The right to use EtherCAT Technology is granted and comes free of
-#  charge under condition of compatibility of product made by
-#  Licensee. People intending to distribute/sell products based on the
-#  code, have to sign an agreement to guarantee that products using
-#  software based on IgH EtherCAT master stay compatible with the actual
-#  EtherCAT specification (which are released themselves as an open
-#  standard) as the (only) precondition to have the right to use EtherCAT
-#  Technology, IP and trade marks.
-#
-#------------------------------------------------------------------------------
-
-include $(src)/../../config.kbuild
-
-obj-m := ec_rtai_sample.o
-
-ec_rtai_sample-objs := rtai_sample.o
-
-EXTRA_CFLAGS := -I$(RTAI_DIR)/include
-
-#------------------------------------------------------------------------------
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/rtai/Kbuild.in	Wed Oct 03 08:58:01 2007 +0000
@@ -0,0 +1,40 @@
+#------------------------------------------------------------------------------
+#
+#  $Id$
+#
+#  Copyright (C) 2006  Florian Pose, Ingenieurgemeinschaft IgH
+#
+#  This file is part of the IgH EtherCAT Master.
+#
+#  The IgH EtherCAT Master is free software; you can redistribute it
+#  and/or modify it under the terms of the GNU General Public License
+#  as published by the Free Software Foundation; either version 2 of the
+#  License, or (at your option) any later version.
+#
+#  The IgH EtherCAT Master is distributed in the hope that it will be
+#  useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#  GNU General Public License for more details.
+#
+#  You should have received a copy of the GNU General Public License
+#  along with the IgH EtherCAT Master; if not, write to the Free Software
+#  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+#
+#  The right to use EtherCAT Technology is granted and comes free of
+#  charge under condition of compatibility of product made by
+#  Licensee. People intending to distribute/sell products based on the
+#  code, have to sign an agreement to guarantee that products using
+#  software based on IgH EtherCAT master stay compatible with the actual
+#  EtherCAT specification (which are released themselves as an open
+#  standard) as the (only) precondition to have the right to use EtherCAT
+#  Technology, IP and trade marks.
+#
+#------------------------------------------------------------------------------
+
+obj-m := ec_rtai_sample.o
+
+ec_rtai_sample-objs := rtai_sample.o
+
+EXTRA_CFLAGS := -I@RTAI_DIR@/include
+
+#------------------------------------------------------------------------------
--- a/examples/rtai/Makefile.am	Thu Sep 13 11:08:46 2007 +0000
+++ b/examples/rtai/Makefile.am	Wed Oct 03 08:58:01 2007 +0000
@@ -33,7 +33,9 @@
 #
 #------------------------------------------------------------------------------
 
-EXTRA_DIST = Kbuild rtai_sample.c
+EXTRA_DIST = \
+	Kbuild.in \
+	rtai_sample.c
 
 all:
 	$(MAKE) -C "$(LINUX_SOURCE_DIR)" M="@abs_srcdir@" modules
--- a/include/ecdb.h	Thu Sep 13 11:08:46 2007 +0000
+++ b/include/ecdb.h	Wed Oct 03 08:58:01 2007 +0000
@@ -35,8 +35,8 @@
    \file
    EtherCAT Slave Database.
 
-   \warn Please do not create any dependencies to this file! It may be changed
-   between releases. Provide a copy, if you want to use it in foreign
+   \attention Please do not create any dependencies to this file! It may be
+   changed between releases. Provide a copy, if you want to use it in foreign
    projects.
 */
 
@@ -49,6 +49,8 @@
 
 /** \cond */
 
+#define Beckhoff_EK1100 0x00000002, 0x044C2C52
+
 #define Beckhoff_BK1120 0x00000002, 0x04602C22
 
 #define Beckhoff_EL1004 0x00000002, 0x03EC3052
--- a/include/ecrt.h	Thu Sep 13 11:08:46 2007 +0000
+++ b/include/ecrt.h	Wed Oct 03 08:58:01 2007 +0000
@@ -59,10 +59,24 @@
 
 /*****************************************************************************/
 
+/**
+ * EtherCAT real-time interface major version number.
+ */
 #define ECRT_VER_MAJOR 1
+
+/**
+ * EtherCAT real-time interface minor version number.
+ */
 #define ECRT_VER_MINOR 3
 
+/**
+ * EtherCAT real-time interface version word generator.
+ */
 #define ECRT_VERSION(a,b) (((a) << 8) + (b))
+
+/**
+ * EtherCAT real-time interface version word.
+ */
 #define ECRT_VERSION_MAGIC ECRT_VERSION(ECRT_VER_MAJOR, ECRT_VER_MINOR)
 
 /*****************************************************************************/
--- a/master/Kbuild	Thu Sep 13 11:08:46 2007 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,57 +0,0 @@
-#------------------------------------------------------------------------------
-#
-#  $Id$
-#
-#  Copyright (C) 2006  Florian Pose, Ingenieurgemeinschaft IgH
-#
-#  This file is part of the IgH EtherCAT Master.
-#
-#  The IgH EtherCAT Master is free software; you can redistribute it
-#  and/or modify it under the terms of the GNU General Public License
-#  as published by the Free Software Foundation; either version 2 of the
-#  License, or (at your option) any later version.
-#
-#  The IgH EtherCAT Master is distributed in the hope that it will be
-#  useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
-#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-#  GNU General Public License for more details.
-#
-#  You should have received a copy of the GNU General Public License
-#  along with the IgH EtherCAT Master; if not, write to the Free Software
-#  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-#
-#  The right to use EtherCAT Technology is granted and comes free of
-#  charge under condition of compatibility of product made by
-#  Licensee. People intending to distribute/sell products based on the
-#  code, have to sign an agreement to guarantee that products using
-#  software based on IgH EtherCAT master stay compatible with the actual
-#  EtherCAT specification (which are released themselves as an open
-#  standard) as the (only) precondition to have the right to use EtherCAT
-#  Technology, IP and trade marks.
-#
-#------------------------------------------------------------------------------
-
-include $(src)/../config.kbuild
-
-obj-m := ec_master.o
-
-ec_master-objs := module.o master.o device.o pdo.o sync.o fmmu.o slave.o \
-    datagram.o domain.o mailbox.o canopen.o fsm_sii.o fsm_change.o \
-    fsm_coe.o fsm_mapping.o fsm_slave.o fsm_master.o
-
-ifeq ($(ENABLE_EOE),1)
-	ec_master-objs += ethernet.o
-endif
-ifeq ($(ENABLE_DEBUG_IF),1)
-	ec_master-objs += debug.o
-endif
-
-REV := $(shell if test -s $(src)/../svnrevision; then \
-		cat $(src)/../svnrevision; \
-	else \
-		svnversion $(src) 2>/dev/null || echo "unknown"; \
-	fi)
-
-CFLAGS_module.o := -DSVNREV=$(REV)
-
-#------------------------------------------------------------------------------
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/master/Kbuild.in	Wed Oct 03 08:58:01 2007 +0000
@@ -0,0 +1,55 @@
+#------------------------------------------------------------------------------
+#
+#  $Id$
+#
+#  Copyright (C) 2006  Florian Pose, Ingenieurgemeinschaft IgH
+#
+#  This file is part of the IgH EtherCAT Master.
+#
+#  The IgH EtherCAT Master is free software; you can redistribute it
+#  and/or modify it under the terms of the GNU General Public License
+#  as published by the Free Software Foundation; either version 2 of the
+#  License, or (at your option) any later version.
+#
+#  The IgH EtherCAT Master is distributed in the hope that it will be
+#  useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#  GNU General Public License for more details.
+#
+#  You should have received a copy of the GNU General Public License
+#  along with the IgH EtherCAT Master; if not, write to the Free Software
+#  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+#
+#  The right to use EtherCAT Technology is granted and comes free of
+#  charge under condition of compatibility of product made by
+#  Licensee. People intending to distribute/sell products based on the
+#  code, have to sign an agreement to guarantee that products using
+#  software based on IgH EtherCAT master stay compatible with the actual
+#  EtherCAT specification (which are released themselves as an open
+#  standard) as the (only) precondition to have the right to use EtherCAT
+#  Technology, IP and trade marks.
+#
+#------------------------------------------------------------------------------
+
+obj-m := ec_master.o
+
+ec_master-objs := module.o master.o device.o pdo.o sync.o fmmu.o slave.o \
+    datagram.o domain.o mailbox.o canopen.o fsm_sii.o fsm_change.o \
+    fsm_coe.o fsm_coe_map.o fsm_mapping.o fsm_slave.o fsm_master.o xmldev.o
+
+ifeq (@ENABLE_EOE@,1)
+	ec_master-objs += ethernet.o
+endif
+ifeq (@ENABLE_DEBUG_IF@,1)
+	ec_master-objs += debug.o
+endif
+
+REV := $(shell if test -s $(src)/../svnrevision; then \
+		cat $(src)/../svnrevision; \
+	else \
+		svnversion $(src) 2>/dev/null || echo "unknown"; \
+	fi)
+
+CFLAGS_module.o := -DSVNREV=$(REV)
+
+#------------------------------------------------------------------------------
--- a/master/Makefile.am	Thu Sep 13 11:08:46 2007 +0000
+++ b/master/Makefile.am	Wed Oct 03 08:58:01 2007 +0000
@@ -32,7 +32,7 @@
 #------------------------------------------------------------------------------
 
 EXTRA_DIST = \
-	Kbuild \
+	Kbuild.in \
 	canopen.c canopen.h \
 	datagram.c datagram.h \
 	debug.c	debug.h \
--- a/master/canopen.c	Thu Sep 13 11:08:46 2007 +0000
+++ b/master/canopen.c	Wed Oct 03 08:58:01 2007 +0000
@@ -51,10 +51,6 @@
 void ec_sdo_clear(struct kobject *);
 void ec_sdo_entry_clear(struct kobject *);
 
-void ec_sdo_request_init_read(ec_sdo_request_t *, ec_sdo_t *,
-                              ec_sdo_entry_t *);
-void ec_sdo_request_clear(ec_sdo_request_t *);
-
 /*****************************************************************************/
 
 /** \cond */
@@ -175,6 +171,33 @@
 
 /*****************************************************************************/
 
+/**
+ * Get and SDO entry from an SDO via its subindex.
+ * \return pointer to SDO entry, or NULL.
+ */
+
+ec_sdo_entry_t *ec_sdo_get_entry(
+        ec_sdo_t *sdo, /**< SDO */
+        uint8_t subindex /**< entry subindex */
+        )
+{
+    ec_sdo_entry_t *entry;
+
+    list_for_each_entry(entry, &sdo->entries, list) {
+        if (entry->subindex != subindex) continue;
+        return entry;
+    }
+
+    return NULL;
+}
+
+/*****************************************************************************/
+
+/**
+ * Print SDO information to a buffer.
+ * /return size of bytes written to buffer.
+ */ 
+
 ssize_t ec_sdo_info(ec_sdo_t *sdo, /**< SDO */
                     char *buffer /**< target buffer */
                     )
@@ -190,6 +213,11 @@
 
 /*****************************************************************************/
 
+/**
+ * Show an SDO as Sysfs attribute.
+ * /return size of bytes written to buffer.
+ */ 
+
 ssize_t ec_show_sdo_attribute(struct kobject *kobj, /**< kobject */
                               struct attribute *attr,
                               char *buffer
@@ -272,6 +300,11 @@
 }
 
 /*****************************************************************************/
+ 
+/**
+ * Print SDO entry information to a buffer.
+ * \return number of bytes written.
+ */
 
 ssize_t ec_sdo_entry_info(ec_sdo_entry_t *entry, /**< SDO entry */
                           char *buffer /**< target buffer */
@@ -290,6 +323,11 @@
 
 /*****************************************************************************/
 
+/**
+ * Format entry data based on the CANopen data type and print it to a buffer.
+ * \return number of bytes written.
+ */
+
 ssize_t ec_sdo_entry_format_data(ec_sdo_entry_t *entry, /**< SDO entry */
                                  ec_sdo_request_t *request, /**< SDO request */
                                  char *buffer /**< target buffer */
@@ -363,16 +401,22 @@
 
 /*****************************************************************************/
 
+/**
+ * Start SDO entry reading.
+ * This function blocks, until reading is finished, and is interruptible as
+ * long as the master state machine has not begun with reading.
+ * \return number of bytes written to buffer, or error code.
+ */
+
 ssize_t ec_sdo_entry_read_value(ec_sdo_entry_t *entry, /**< SDO entry */
                                 char *buffer /**< target buffer */
                                 )
 {
-    ec_sdo_t *sdo = entry->sdo;
-    ec_master_t *master = sdo->slave->master;
+    ec_master_t *master = entry->sdo->slave->master;
     off_t off = 0;
     ec_sdo_request_t request;
 
-    ec_sdo_request_init_read(&request, sdo, entry);
+    ec_sdo_request_init_read(&request, entry);
 
     // schedule request.
     down(&master->sdo_sem);
@@ -407,6 +451,11 @@
 
 /*****************************************************************************/
 
+/**
+ * Show an SDO entry as Sysfs attribute.
+ * /return size of bytes written to buffer.
+ */ 
+
 ssize_t ec_show_sdo_entry_attribute(struct kobject *kobj, /**< kobject */
                                     struct attribute *attr,
                                     char *buffer
@@ -431,11 +480,9 @@
 */
 
 void ec_sdo_request_init_read(ec_sdo_request_t *req, /**< SDO request */
-                              ec_sdo_t *sdo, /**< SDO */
                               ec_sdo_entry_t *entry /**< SDO entry */
                               )
 {
-    req->sdo = sdo;
     req->entry = entry;
     req->data = NULL;
     req->size = 0;
--- a/master/canopen.h	Thu Sep 13 11:08:46 2007 +0000
+++ b/master/canopen.h	Wed Oct 03 08:58:01 2007 +0000
@@ -53,7 +53,7 @@
    CANopen SDO.
 */
 
-typedef struct
+struct ec_sdo
 {
     struct kobject kobj; /**< kobject */
     struct list_head list; /**< list item */
@@ -63,8 +63,7 @@
     char *name; /**< SDO name */
     uint8_t subindices; /**< subindices */
     struct list_head entries; /**< entry list */
-}
-ec_sdo_t;
+};
 
 /*****************************************************************************/
 
@@ -109,11 +108,10 @@
 typedef struct
 {
     struct list_head list; /**< list item */
-    ec_sdo_t *sdo;
-    ec_sdo_entry_t *entry;
+    ec_sdo_entry_t *entry; /**< SDO entry */
     uint8_t *data; /**< pointer to SDO data */
     size_t size; /**< size of SDO data */
-    ec_request_state_t state;
+    ec_request_state_t state; /**< SDO request state */
 }
 ec_sdo_request_t;
 
@@ -121,10 +119,14 @@
 
 int ec_sdo_init(ec_sdo_t *, uint16_t, ec_slave_t *);
 void ec_sdo_destroy(ec_sdo_t *);
+ec_sdo_entry_t *ec_sdo_get_entry(ec_sdo_t *, uint8_t);
 
 int ec_sdo_entry_init(ec_sdo_entry_t *, uint8_t, ec_sdo_t *);
 void ec_sdo_entry_destroy(ec_sdo_entry_t *);
 
+void ec_sdo_request_init_read(ec_sdo_request_t *, ec_sdo_entry_t *);
+void ec_sdo_request_clear(ec_sdo_request_t *);
+
 /*****************************************************************************/
 
 #endif
--- a/master/datagram.c	Thu Sep 13 11:08:46 2007 +0000
+++ b/master/datagram.c	Wed Oct 03 08:58:01 2007 +0000
@@ -309,7 +309,7 @@
  */
 
 void ec_datagram_print_wc_error(
-        const ec_datagram_t *datagram
+        const ec_datagram_t *datagram /**< EtherCAT datagram */
         )
 {
     if (datagram->working_counter == 0)
--- a/master/device.c	Thu Sep 13 11:08:46 2007 +0000
+++ b/master/device.c	Wed Oct 03 08:58:01 2007 +0000
@@ -168,7 +168,7 @@
 
     for (i = 0; i < EC_TX_RING_SIZE; i++) {
         device->tx_skb[i]->dev = net_dev;
-        eth = (struct ethhdr *) (device->tx_skb[i]->data + ETH_HLEN);
+        eth = (struct ethhdr *) (device->tx_skb[i]->data);
         memcpy(eth->h_source, net_dev->dev_addr, ETH_ALEN);
     }
 }
@@ -288,17 +288,17 @@
         ec_print_data(skb->data + ETH_HLEN, size);
     }
 
-#ifdef EC_DEBUG_IF
-    ec_debug_send(&device->dbg, skb->data, ETH_HLEN + size);
-#endif
-#ifdef EC_DEBUG_RING
-    ec_device_debug_ring_append(
-            device, TX, skb->data + ETH_HLEN, size);
-#endif
-
     // start sending
-    device->dev->hard_start_xmit(skb, device->dev);
-    device->tx_count++;
+    if (device->dev->hard_start_xmit(skb, device->dev) == NETDEV_TX_OK) {
+		device->tx_count++;
+#ifdef EC_DEBUG_IF
+		ec_debug_send(&device->dbg, skb->data, ETH_HLEN + size);
+#endif
+#ifdef EC_DEBUG_RING
+		ec_device_debug_ring_append(
+				device, TX, skb->data + ETH_HLEN, size);
+#endif
+	}
 }
 
 /*****************************************************************************/
--- a/master/device.h	Thu Sep 13 11:08:46 2007 +0000
+++ b/master/device.h	Wed Oct 03 08:58:01 2007 +0000
@@ -47,6 +47,12 @@
 #include "../devices/ecdev.h"
 #include "globals.h"
 
+/**
+ * Size of the transmit ring.
+ * This memory ring is used to transmit frames. It is necessary to use
+ * different memory regions, because otherwise the network device DMA could
+ * send the same data twice, if it is called twice.
+ */
 #define EC_TX_RING_SIZE 2
 
 #ifdef EC_DEBUG_IF
@@ -87,7 +93,7 @@
     uint8_t open; /**< true, if the net_device has been opened */
     uint8_t link_state; /**< device link state */
     struct sk_buff *tx_skb[EC_TX_RING_SIZE]; /**< transmit skb ring */
-    unsigned int tx_ring_index;
+    unsigned int tx_ring_index; /**< last ring entry used to transmit */
     cycles_t cycles_poll; /**< cycles of last poll */
 #ifdef EC_DEBUG_RING
     struct timeval timeval_poll;
--- a/master/fsm_change.c	Thu Sep 13 11:08:46 2007 +0000
+++ b/master/fsm_change.c	Wed Oct 03 08:58:01 2007 +0000
@@ -66,6 +66,7 @@
 {
     fsm->state = NULL;
     fsm->datagram = datagram;
+    fsm->spontaneous_change = 0;
 }
 
 /*****************************************************************************/
@@ -223,6 +224,7 @@
     // read AL status from slave
     ec_datagram_nprd(datagram, slave->station_address, 0x0130, 2);
     fsm->retries = EC_FSM_RETRIES;
+    fsm->spontaneous_change = 0;
     fsm->state = ec_fsm_change_state_status;
 }
 
@@ -281,10 +283,11 @@
             // Slave spontaneously changed its state just before the new state
             // was written. Accept current state as old state and wait for
             // state change
+            fsm->spontaneous_change = 1;
             fsm->old_state = slave->current_state;
             EC_WARN("Slave %i changed to %s in the meantime.\n",
                     slave->ring_position, cur_state);
-            goto again;
+            goto check_again;
         }
 
         // state change error
@@ -309,11 +312,11 @@
         ec_state_string(fsm->requested_state, state_str);
         fsm->state = ec_fsm_change_state_error;
         EC_ERR("Timeout while setting state %s on slave %i.\n",
-               state_str, slave->ring_position);
-        return;
-    }
-
- again:
+                state_str, slave->ring_position);
+        return;
+    }
+
+ check_again:
     // no timeout yet. check again
     ec_datagram_nprd(datagram, slave->station_address, 0x0130, 2);
     fsm->retries = EC_FSM_RETRIES;
--- a/master/fsm_change.h	Thu Sep 13 11:08:46 2007 +0000
+++ b/master/fsm_change.h	Wed Oct 03 08:58:01 2007 +0000
@@ -78,6 +78,7 @@
     ec_slave_state_t old_state; /**< prior slave state */
     unsigned long jiffies_start; /**< change timer */
     uint8_t take_time; /**< take sending timestamp */
+    uint8_t spontaneous_change; /**< spontaneous state change detected */
 };
 
 /*****************************************************************************/
--- a/master/fsm_coe.c	Thu Sep 13 11:08:46 2007 +0000
+++ b/master/fsm_coe.c	Wed Oct 03 08:58:01 2007 +0000
@@ -1158,13 +1158,12 @@
     ec_slave_t *slave = fsm->slave;
     ec_master_t *master = slave->master;
     ec_sdo_request_t *request = fsm->request;
-    ec_sdo_t *sdo = request->sdo;
     ec_sdo_entry_t *entry = request->entry;
     uint8_t *data;
 
     if (master->debug_level)
         EC_DBG("Uploading SDO 0x%04X:%i from slave %i.\n",
-               sdo->index, entry->subindex, slave->ring_position);
+               entry->sdo->index, entry->subindex, slave->ring_position);
 
     if (!(data = ec_slave_mbox_prepare_send(slave, datagram, 0x03, 10))) {
         fsm->state = ec_fsm_coe_error;
@@ -1173,7 +1172,7 @@
 
     EC_WRITE_U16(data, 0x2 << 12); // SDO request
     EC_WRITE_U8 (data + 2, 0x2 << 5); // initiate upload request
-    EC_WRITE_U16(data + 3, sdo->index);
+    EC_WRITE_U16(data + 3, entry->sdo->index);
     EC_WRITE_U8 (data + 5, entry->subindex);
     memset(data + 6, 0x00, 4);
 
@@ -1289,7 +1288,6 @@
     uint8_t *data, mbox_prot;
     size_t rec_size, data_size;
     ec_sdo_request_t *request = fsm->request;
-    ec_sdo_t *sdo = request->sdo;
     ec_sdo_entry_t *entry = request->entry;
     uint32_t complete_size;
     unsigned int expedited, size_specified;
@@ -1340,7 +1338,7 @@
     if (EC_READ_U16(data) >> 12 == 0x2 && // SDO request
         EC_READ_U8 (data + 2) >> 5 == 0x4) { // abort SDO transfer request
         EC_ERR("SDO upload 0x%04X:%X aborted on slave %i.\n",
-               sdo->index, entry->subindex, slave->ring_position);
+               entry->sdo->index, entry->subindex, slave->ring_position);
         ec_canopen_abort_msg(EC_READ_U32(data + 6));
         fsm->state = ec_fsm_coe_error;
 	return;
@@ -1348,9 +1346,9 @@
 
     if (EC_READ_U16(data) >> 12 != 0x3 || // SDO response
         EC_READ_U8 (data + 2) >> 5 != 0x2 || // upload response
-        EC_READ_U16(data + 3) != sdo->index || // index
+        EC_READ_U16(data + 3) != entry->sdo->index || // index
         EC_READ_U8 (data + 5) != entry->subindex) { // subindex
-        EC_ERR("SDO upload 0x%04X:%X failed:\n", sdo->index, entry->subindex);
+        EC_ERR("SDO upload 0x%04X:%X failed:\n", entry->sdo->index, entry->subindex);
         EC_ERR("Invalid SDO upload response at slave %i!\n",
                slave->ring_position);
         ec_print_data(data, rec_size);
@@ -1531,7 +1529,6 @@
     uint8_t *data, mbox_prot;
     size_t rec_size, data_size;
     ec_sdo_request_t *request = fsm->request;
-    ec_sdo_t *sdo = request->sdo;
     ec_sdo_entry_t *entry = request->entry;
     uint32_t seg_size;
     unsigned int last_segment;
@@ -1582,7 +1579,7 @@
     if (EC_READ_U16(data) >> 12 == 0x2 && // SDO request
         EC_READ_U8 (data + 2) >> 5 == 0x4) { // abort SDO transfer request
         EC_ERR("SDO upload 0x%04X:%X aborted on slave %i.\n",
-               sdo->index, entry->subindex, slave->ring_position);
+               entry->sdo->index, entry->subindex, slave->ring_position);
         ec_canopen_abort_msg(EC_READ_U32(data + 6));
         fsm->state = ec_fsm_coe_error;
 	return;
@@ -1590,7 +1587,7 @@
 
     if (EC_READ_U16(data) >> 12 != 0x3 || // SDO response
         EC_READ_U8 (data + 2) >> 5 != 0x0) { // upload segment response
-        EC_ERR("SDO upload 0x%04X:%X failed:\n", sdo->index, entry->subindex);
+        EC_ERR("SDO upload 0x%04X:%X failed:\n", entry->sdo->index, entry->subindex);
         EC_ERR("Invalid SDO upload segment response at slave %i!\n",
                slave->ring_position);
         ec_print_data(data, rec_size);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/master/fsm_coe_map.c	Wed Oct 03 08:58:01 2007 +0000
@@ -0,0 +1,537 @@
+/******************************************************************************
+ *
+ *  $Id: fsm_coe.c 920 2007-09-12 10:07:55Z fp $
+ *
+ *  Copyright (C) 2006  Florian Pose, Ingenieurgemeinschaft IgH
+ *
+ *  This file is part of the IgH EtherCAT Master.
+ *
+ *  The IgH EtherCAT Master is free software; you can redistribute it
+ *  and/or modify it under the terms of the GNU General Public License
+ *  as published by the Free Software Foundation; either version 2 of the
+ *  License, or (at your option) any later version.
+ *
+ *  The IgH EtherCAT Master is distributed in the hope that it will be
+ *  useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with the IgH EtherCAT Master; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ *  The right to use EtherCAT Technology is granted and comes free of
+ *  charge under condition of compatibility of product made by
+ *  Licensee. People intending to distribute/sell products based on the
+ *  code, have to sign an agreement to guarantee that products using
+ *  software based on IgH EtherCAT master stay compatible with the actual
+ *  EtherCAT specification (which are released themselves as an open
+ *  standard) as the (only) precondition to have the right to use EtherCAT
+ *  Technology, IP and trade marks.
+ *
+ *****************************************************************************/
+
+/**
+   \file
+   EtherCAT CoE mapping state machines.
+*/
+
+/*****************************************************************************/
+
+#include "globals.h"
+#include "master.h"
+#include "mailbox.h"
+#include "canopen.h"
+#include "fsm_coe_map.h"
+
+/*****************************************************************************/
+
+void ec_fsm_coe_map_state_start(ec_fsm_coe_map_t *);
+void ec_fsm_coe_map_state_pdo_count(ec_fsm_coe_map_t *);
+void ec_fsm_coe_map_state_pdo(ec_fsm_coe_map_t *);
+void ec_fsm_coe_map_state_pdo_entry_count(ec_fsm_coe_map_t *);
+void ec_fsm_coe_map_state_pdo_entry(ec_fsm_coe_map_t *);
+
+void ec_fsm_coe_map_state_end(ec_fsm_coe_map_t *);
+void ec_fsm_coe_map_state_error(ec_fsm_coe_map_t *);
+
+void ec_fsm_coe_map_action_next_sync(ec_fsm_coe_map_t *);
+void ec_fsm_coe_map_action_next_pdo(ec_fsm_coe_map_t *);
+void ec_fsm_coe_map_action_next_pdo_entry(ec_fsm_coe_map_t *);
+
+void ec_fsm_coe_map_clear_pdos(ec_fsm_coe_map_t *);
+
+/*****************************************************************************/
+
+/**
+   Constructor.
+*/
+
+void ec_fsm_coe_map_init(
+        ec_fsm_coe_map_t *fsm, /**< finite state machine */
+        ec_fsm_coe_t *fsm_coe /**< CoE state machine to use */
+        )
+{
+    fsm->state = NULL;
+    fsm->fsm_coe = fsm_coe;
+    INIT_LIST_HEAD(&fsm->pdos);
+}
+
+/*****************************************************************************/
+
+/**
+   Destructor.
+*/
+
+void ec_fsm_coe_map_clear(ec_fsm_coe_map_t *fsm /**< finite state machine */)
+{
+    ec_fsm_coe_map_clear_pdos(fsm);
+}
+
+/*****************************************************************************/
+
+/**
+ * Clear FSM PDOs.
+ */
+
+void ec_fsm_coe_map_clear_pdos(
+        ec_fsm_coe_map_t *fsm /**< finite state machine */
+        )
+{
+    ec_pdo_t *pdo, *next;
+
+    // free all PDOs
+    list_for_each_entry_safe(pdo, next, &fsm->pdos, list) {
+        list_del(&pdo->list);
+        ec_pdo_clear(pdo);
+        kfree(pdo);
+    }
+}
+
+/*****************************************************************************/
+
+/**
+   Starts to upload an SDO from a slave.
+*/
+
+void ec_fsm_coe_map_start(
+        ec_fsm_coe_map_t *fsm, /**< finite state machine */
+        ec_slave_t *slave /**< EtherCAT slave */
+        )
+{
+    fsm->slave = slave;
+    fsm->state = ec_fsm_coe_map_state_start;
+}
+
+/*****************************************************************************/
+
+/**
+   Executes the current state of the state machine.
+   \return false, if state machine has terminated
+*/
+
+int ec_fsm_coe_map_exec(ec_fsm_coe_map_t *fsm /**< finite state machine */)
+{
+    fsm->state(fsm);
+
+    return fsm->state != ec_fsm_coe_map_state_end
+        && fsm->state != ec_fsm_coe_map_state_error;
+}
+
+/*****************************************************************************/
+
+/**
+   Returns, if the state machine terminated with success.
+   \return non-zero if successful.
+*/
+
+int ec_fsm_coe_map_success(ec_fsm_coe_map_t *fsm /**< Finite state machine */)
+{
+    return fsm->state == ec_fsm_coe_map_state_end;
+}
+
+/******************************************************************************
+ *  state functions
+ *****************************************************************************/
+
+/**
+ * Start reading mapping.
+ */
+
+void ec_fsm_coe_map_state_start(
+        ec_fsm_coe_map_t *fsm /**< finite state machine */
+        )
+{
+    // read mapping of first sync manager
+    fsm->sync_index = 0;
+    ec_fsm_coe_map_action_next_sync(fsm);
+}
+
+/*****************************************************************************/
+
+/**
+ * Read mapping of next sync manager.
+ */
+
+void ec_fsm_coe_map_action_next_sync(
+        ec_fsm_coe_map_t *fsm /**< finite state machine */
+        )
+{
+    ec_slave_t *slave = fsm->slave;
+    ec_sdo_entry_t *entry;
+
+    for (; fsm->sync_index < slave->sii_sync_count; fsm->sync_index++) {
+        if (!(fsm->sync_sdo = ec_slave_get_sdo(slave, 0x1C10 + fsm->sync_index)))
+            continue;
+
+        if (slave->master->debug_level)
+            EC_DBG("Reading PDO mapping of sync manager %u of slave %u.\n",
+                    fsm->sync_index, slave->ring_position);
+
+        ec_fsm_coe_map_clear_pdos(fsm);
+
+        if (!(entry = ec_sdo_get_entry(fsm->sync_sdo, 0))) {
+            EC_ERR("SDO 0x%04X has no subindex 0 on slave %u.\n",
+                    fsm->sync_sdo->index,
+                    fsm->slave->ring_position);
+            fsm->state = ec_fsm_coe_map_state_error;
+            return;
+        }
+
+        ec_sdo_request_init_read(&fsm->request, entry);
+        fsm->state = ec_fsm_coe_map_state_pdo_count;
+        ec_fsm_coe_upload(fsm->fsm_coe, fsm->slave, &fsm->request);
+        ec_fsm_coe_exec(fsm->fsm_coe); // execute immediately
+        return;
+    }
+
+    fsm->state = ec_fsm_coe_map_state_end;
+}
+
+/*****************************************************************************/
+
+/**
+ * Count mapped PDOs.
+ */
+
+void ec_fsm_coe_map_state_pdo_count(
+        ec_fsm_coe_map_t *fsm /**< finite state machine */
+        )
+{
+    if (ec_fsm_coe_exec(fsm->fsm_coe)) return;
+
+    if (!ec_fsm_coe_success(fsm->fsm_coe)) {
+        EC_ERR("Failed to read number of mapped PDOs from slave %u.\n",
+                fsm->slave->ring_position);
+        fsm->state = ec_fsm_coe_map_state_error;
+        return;
+    }
+
+    fsm->sync_subindices = EC_READ_U8(fsm->request.data);
+
+    if (fsm->slave->master->debug_level)
+        EC_DBG("  %u PDOs mapped.\n", fsm->sync_subindices);
+
+    // read first PDO
+    fsm->sync_subindex = 1;
+    ec_fsm_coe_map_action_next_pdo(fsm);
+}
+
+/*****************************************************************************/
+
+/**
+ * Read next PDO.
+ */
+
+void ec_fsm_coe_map_action_next_pdo(
+        ec_fsm_coe_map_t *fsm /**< finite state machine */
+        )
+{
+    ec_sdo_entry_t *entry;
+
+    if (fsm->sync_subindex <= fsm->sync_subindices) {
+        if (!(entry = ec_sdo_get_entry(fsm->sync_sdo,
+                        fsm->sync_subindex))) {
+            EC_ERR("SDO 0x%04X has no subindex %u on slave %u.\n",
+                    fsm->sync_sdo->index,
+                    fsm->sync_subindex,
+                    fsm->slave->ring_position);
+            fsm->state = ec_fsm_coe_map_state_error;
+            return;
+        }
+
+        ec_sdo_request_init_read(&fsm->request, entry);
+        fsm->state = ec_fsm_coe_map_state_pdo;
+        ec_fsm_coe_upload(fsm->fsm_coe, fsm->slave, &fsm->request);
+        ec_fsm_coe_exec(fsm->fsm_coe); // execute immediately
+        return;
+    }
+
+    {
+        ec_sync_t *sync = fsm->slave->sii_syncs + fsm->sync_index;
+        ec_pdo_t *pdo;
+
+        // exchange sync manager PDO mapping
+        ec_sync_clear_pdos(sync);
+        list_for_each_entry(pdo, &fsm->pdos, list) {
+            ec_sync_add_pdo(sync, pdo);
+        }
+        ec_fsm_coe_map_clear_pdos(fsm);
+
+        // next sync manager
+        fsm->sync_index++;
+        ec_fsm_coe_map_action_next_sync(fsm);
+    }
+}
+
+/*****************************************************************************/
+
+/**
+ * Fetch PDO information.
+ */
+
+void ec_fsm_coe_map_state_pdo(
+        ec_fsm_coe_map_t *fsm /**< finite state machine */
+        )
+{
+    if (ec_fsm_coe_exec(fsm->fsm_coe)) return;
+
+    if (!ec_fsm_coe_success(fsm->fsm_coe)) {
+        EC_ERR("Failed to read mapped PDO index from slave %u.\n",
+                fsm->slave->ring_position);
+        fsm->state = ec_fsm_coe_map_state_error;
+        return;
+    }
+
+    {
+        ec_sdo_entry_t *entry;
+
+        if (!(fsm->pdo = (ec_pdo_t *)
+                    kmalloc(sizeof(ec_pdo_t), GFP_KERNEL))) {
+            EC_ERR("Failed to allocate PDO.\n");
+            fsm->state = ec_fsm_coe_map_state_error;
+            return;
+        }
+
+        ec_pdo_init(fsm->pdo);
+        fsm->pdo->index = EC_READ_U16(fsm->request.data);
+        fsm->pdo->type =
+            ec_sync_get_pdo_type(fsm->slave->sii_syncs + fsm->sync_index);
+
+        if (fsm->slave->master->debug_level)
+            EC_DBG("  PDO 0x%04X.\n", fsm->pdo->index);
+
+        if (!(fsm->pdo_sdo = ec_slave_get_sdo(fsm->slave, fsm->pdo->index))) {
+            EC_ERR("Slave %u has no SDO 0x%04X.\n",
+                    fsm->slave->ring_position, fsm->pdo->index);
+            ec_pdo_clear(fsm->pdo);
+            kfree(fsm->pdo);
+            fsm->state = ec_fsm_coe_map_state_error;
+            return;
+        }
+
+        if (fsm->pdo_sdo->name && strlen(fsm->pdo_sdo->name)) {
+            if (!(fsm->pdo->name = (char *)
+                        kmalloc(strlen(fsm->pdo_sdo->name) + 1, GFP_KERNEL))) {
+                EC_ERR("Failed to allocate PDO name.\n");
+                ec_pdo_clear(fsm->pdo);
+                kfree(fsm->pdo);
+                fsm->state = ec_fsm_coe_map_state_error;
+                return;
+            }
+            memcpy(fsm->pdo->name, fsm->pdo_sdo->name,
+                    strlen(fsm->pdo_sdo->name) + 1);
+        } else {
+            fsm->pdo->name = NULL;
+        }
+
+        if (!(entry = ec_sdo_get_entry(fsm->pdo_sdo, 0))) {
+            EC_ERR("SDO 0x%04X has no subindex 0 on slave %u.\n",
+                    fsm->pdo_sdo->index,
+                    fsm->slave->ring_position);
+            ec_pdo_clear(fsm->pdo);
+            kfree(fsm->pdo);
+            fsm->state = ec_fsm_coe_map_state_error;
+            return;
+        }
+
+        list_add_tail(&fsm->pdo->list, &fsm->pdos);
+
+        ec_sdo_request_init_read(&fsm->request, entry);
+        fsm->state = ec_fsm_coe_map_state_pdo_entry_count;
+        ec_fsm_coe_upload(fsm->fsm_coe, fsm->slave, &fsm->request);
+        ec_fsm_coe_exec(fsm->fsm_coe); // execute immediately
+        return;
+    }
+}
+
+/*****************************************************************************/
+
+/**
+ * Read number of PDO entries.
+ */
+
+void ec_fsm_coe_map_state_pdo_entry_count(
+        ec_fsm_coe_map_t *fsm /**< finite state machine */
+        )
+{
+    if (ec_fsm_coe_exec(fsm->fsm_coe)) return;
+
+    if (!ec_fsm_coe_success(fsm->fsm_coe)) {
+        EC_ERR("Failed to read number of mapped PDO entries from slave %u.\n",
+                fsm->slave->ring_position);
+        fsm->state = ec_fsm_coe_map_state_error;
+        return;
+    }
+
+    fsm->pdo_subindices = EC_READ_U8(fsm->request.data);
+
+    if (fsm->slave->master->debug_level)
+        EC_DBG("    %u PDO entries mapped.\n", fsm->pdo_subindices);
+
+    // read first PDO entry
+    fsm->pdo_subindex = 1;
+    ec_fsm_coe_map_action_next_pdo_entry(fsm);
+}
+
+/*****************************************************************************/
+
+/**
+ * Read next PDO entry.
+ */
+
+void ec_fsm_coe_map_action_next_pdo_entry(
+        ec_fsm_coe_map_t *fsm /**< finite state machine */
+        )
+{
+    ec_sdo_entry_t *entry;
+
+    if (fsm->pdo_subindex <= fsm->pdo_subindices) {
+        if (!(entry = ec_sdo_get_entry(fsm->pdo_sdo,
+                        fsm->pdo_subindex))) {
+            EC_ERR("SDO 0x%04X has no subindex %u on slave %u.\n",
+                    fsm->pdo_sdo->index, fsm->pdo_subindex,
+                    fsm->slave->ring_position);
+            fsm->state = ec_fsm_coe_map_state_error;
+            return;
+        }
+
+        ec_sdo_request_init_read(&fsm->request, entry);
+        fsm->state = ec_fsm_coe_map_state_pdo_entry;
+        ec_fsm_coe_upload(fsm->fsm_coe, fsm->slave, &fsm->request);
+        ec_fsm_coe_exec(fsm->fsm_coe); // execute immediately
+        return;
+    }
+
+    // next PDO
+    fsm->sync_subindex++;
+    ec_fsm_coe_map_action_next_pdo(fsm);
+}
+
+/*****************************************************************************/
+
+/**
+ * Read PDO entry information.
+ */
+
+void ec_fsm_coe_map_state_pdo_entry(
+        ec_fsm_coe_map_t *fsm /**< finite state machine */
+        )
+{
+    if (ec_fsm_coe_exec(fsm->fsm_coe)) return;
+
+    if (!ec_fsm_coe_success(fsm->fsm_coe)) {
+        EC_ERR("Failed to read index of mapped PDO entry from slave %u.\n",
+                fsm->slave->ring_position);
+        fsm->state = ec_fsm_coe_map_state_error;
+        return;
+    }
+
+    {
+        uint32_t pdo_entry_info;
+        ec_sdo_t *sdo;
+        ec_sdo_entry_t *entry;
+        ec_pdo_entry_t *pdo_entry;
+
+        pdo_entry_info = EC_READ_U32(fsm->request.data);
+
+        if (!(pdo_entry = (ec_pdo_entry_t *)
+                    kmalloc(sizeof(ec_pdo_entry_t), GFP_KERNEL))) {
+            EC_ERR("Failed to allocate PDO entry.\n");
+            fsm->state = ec_fsm_coe_map_state_error;
+            return;
+        }
+
+        pdo_entry->index = pdo_entry_info >> 16;
+        pdo_entry->subindex = (pdo_entry_info >> 8) & 0xFF;
+        pdo_entry->bit_length = pdo_entry_info & 0xFF;
+
+        if (!(sdo = ec_slave_get_sdo(fsm->slave, pdo_entry->index))) {
+            EC_ERR("Slave %u has no SDO 0x%04X.\n",
+                    fsm->slave->ring_position, pdo_entry->index);
+            kfree(pdo_entry);
+            fsm->state = ec_fsm_coe_map_state_error;
+            return;
+        }
+
+        if (!(entry = ec_sdo_get_entry(sdo, pdo_entry->subindex))) {
+            EC_ERR("Slave %u has no SDO entry 0x%04X:%u.\n",
+                    fsm->slave->ring_position, pdo_entry->index,
+                    pdo_entry->subindex);
+            kfree(pdo_entry);
+            fsm->state = ec_fsm_coe_map_state_error;
+            return;
+        }
+
+        if (entry->description && strlen(entry->description)) {
+            if (!(pdo_entry->name = (char *)
+                        kmalloc(strlen(entry->description) + 1, GFP_KERNEL))) {
+                EC_ERR("Failed to allocate PDO entry name.\n");
+                kfree(pdo_entry);
+                fsm->state = ec_fsm_coe_map_state_error;
+                return;
+            }
+            memcpy(pdo_entry->name, entry->description, strlen(entry->description) + 1);
+        } else {
+            pdo_entry->name = NULL;
+        }
+
+        if (fsm->slave->master->debug_level) {
+            EC_DBG("    PDO entry 0x%04X \"%s\" (%u bit).\n",
+                    pdo_entry->index, pdo_entry->name ? pdo_entry->name : "???",
+                    pdo_entry->bit_length);
+        }
+
+        list_add_tail(&pdo_entry->list, &fsm->pdo->entries);
+
+        // next PDO entry
+        fsm->pdo_subindex++;
+        ec_fsm_coe_map_action_next_pdo_entry(fsm);
+    }
+}
+
+/*****************************************************************************/
+
+/**
+   State: ERROR.
+*/
+
+void ec_fsm_coe_map_state_error(
+        ec_fsm_coe_map_t *fsm /**< finite state machine */
+        )
+{
+}
+
+/*****************************************************************************/
+
+/**
+   State: END.
+*/
+
+void ec_fsm_coe_map_state_end(
+        ec_fsm_coe_map_t *fsm /**< finite state machine */
+        )
+{
+}
+
+/*****************************************************************************/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/master/fsm_coe_map.h	Wed Oct 03 08:58:01 2007 +0000
@@ -0,0 +1,88 @@
+/******************************************************************************
+ *
+ *  $Id: fsm_coe.h 702 2006-12-18 18:10:52Z fp $
+ *
+ *  Copyright (C) 2006  Florian Pose, Ingenieurgemeinschaft IgH
+ *
+ *  This file is part of the IgH EtherCAT Master.
+ *
+ *  The IgH EtherCAT Master is free software; you can redistribute it
+ *  and/or modify it under the terms of the GNU General Public License
+ *  as published by the Free Software Foundation; either version 2 of the
+ *  License, or (at your option) any later version.
+ *
+ *  The IgH EtherCAT Master is distributed in the hope that it will be
+ *  useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with the IgH EtherCAT Master; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ *  The right to use EtherCAT Technology is granted and comes free of
+ *  charge under condition of compatibility of product made by
+ *  Licensee. People intending to distribute/sell products based on the
+ *  code, have to sign an agreement to guarantee that products using
+ *  software based on IgH EtherCAT master stay compatible with the actual
+ *  EtherCAT specification (which are released themselves as an open
+ *  standard) as the (only) precondition to have the right to use EtherCAT
+ *  Technology, IP and trade marks.
+ *
+ *****************************************************************************/
+
+/**
+   \file
+   EtherCAT CoE mapping state machines.
+*/
+
+/*****************************************************************************/
+
+#ifndef __EC_FSM_COE_MAP__
+#define __EC_FSM_COE_MAP__
+
+#include "globals.h"
+#include "datagram.h"
+#include "slave.h"
+#include "fsm_coe.h"
+
+/*****************************************************************************/
+
+typedef struct ec_fsm_coe_map ec_fsm_coe_map_t; /**< \see ec_fsm_coe_map */
+
+/**
+ */
+
+struct ec_fsm_coe_map
+{
+    void (*state)(ec_fsm_coe_map_t *); /**< CoE mapping state function */
+    ec_fsm_coe_t *fsm_coe; /**< CoE state machine to use */
+
+    ec_slave_t *slave; /**< EtherCAT slave */
+    ec_sdo_request_t request; /**< SDO request */
+
+    unsigned int sync_index; /**< index of the current sync manager */
+    ec_sdo_t *sync_sdo; /**< pointer to the sync managers mapping SDO */
+    uint8_t sync_subindices; /**< number of mapped PDOs */
+    uint16_t sync_subindex; /**< current subindex in mapping SDO */
+
+    struct list_head pdos; /**< list of mapped PDOs */
+    ec_pdo_t *pdo; /**< current PDO */
+    ec_sdo_t *pdo_sdo; /**< current PDO SDO */
+    uint8_t pdo_subindices; /**< number of PDO entries */
+    uint16_t pdo_subindex; /**< current subindex in PDO SDO */
+};
+
+/*****************************************************************************/
+
+void ec_fsm_coe_map_init(ec_fsm_coe_map_t *, ec_fsm_coe_t *);
+void ec_fsm_coe_map_clear(ec_fsm_coe_map_t *);
+
+void ec_fsm_coe_map_start(ec_fsm_coe_map_t *, ec_slave_t *);
+
+int ec_fsm_coe_map_exec(ec_fsm_coe_map_t *);
+int ec_fsm_coe_map_success(ec_fsm_coe_map_t *);
+
+/*****************************************************************************/
+
+#endif
--- a/master/fsm_mapping.c	Thu Sep 13 11:08:46 2007 +0000
+++ b/master/fsm_mapping.c	Wed Oct 03 08:58:01 2007 +0000
@@ -138,10 +138,11 @@
 }
 
 /******************************************************************************
- * PDO mapping state machine
+ * state functions
  *****************************************************************************/
 
 /**
+ * Start mapping configuration.
  */
 
 void ec_fsm_mapping_state_start(
@@ -155,6 +156,7 @@
 /*****************************************************************************/
 
 /**
+ * Process mapping of next sync manager.
  */
 
 void ec_fsm_mapping_next_sync(
@@ -200,6 +202,7 @@
 /*****************************************************************************/
 
 /**
+ * Process mapping of next PDO.
  */
 
 ec_pdo_t *ec_fsm_mapping_next_pdo(
@@ -223,6 +226,7 @@
 /*****************************************************************************/
 
 /**
+ * Set the number of mapped PDOs to zero.
  */
 
 void ec_fsm_mapping_state_zero_count(
@@ -268,6 +272,7 @@
 /*****************************************************************************/
 
 /**
+ * Add a PDO to the sync managers mapping.
  */
 
 void ec_fsm_mapping_state_add_pdo(
@@ -318,6 +323,7 @@
 /*****************************************************************************/
 
 /**
+ * Set the number of mapped PDOs.
  */
 
 void ec_fsm_mapping_state_pdo_count(
--- a/master/fsm_mapping.h	Thu Sep 13 11:08:46 2007 +0000
+++ b/master/fsm_mapping.h	Wed Oct 03 08:58:01 2007 +0000
@@ -66,7 +66,7 @@
     ec_pdo_t *pdo; /**< current PDO */
     ec_sdo_data_t sdodata; /**< SDO configuration data */
     uint16_t sdo_value; /**< SDO value */
-    unsigned int pdo_count;
+    unsigned int pdo_count; /**< number of mapped PDOs */
 };
 
 /*****************************************************************************/
--- a/master/fsm_master.c	Thu Sep 13 11:08:46 2007 +0000
+++ b/master/fsm_master.c	Wed Oct 03 08:58:01 2007 +0000
@@ -60,6 +60,7 @@
 void ec_fsm_master_state_scan_slaves(ec_fsm_master_t *);
 void ec_fsm_master_state_write_eeprom(ec_fsm_master_t *);
 void ec_fsm_master_state_sdodict(ec_fsm_master_t *);
+void ec_fsm_master_state_pdomap(ec_fsm_master_t *);
 void ec_fsm_master_state_sdo_request(ec_fsm_master_t *);
 void ec_fsm_master_state_end(ec_fsm_master_t *);
 void ec_fsm_master_state_error(ec_fsm_master_t *);
@@ -90,6 +91,7 @@
     ec_fsm_sii_init(&fsm->fsm_sii, fsm->datagram);
     ec_fsm_change_init(&fsm->fsm_change, fsm->datagram);
     ec_fsm_coe_init(&fsm->fsm_coe, fsm->datagram);
+    ec_fsm_coe_map_init(&fsm->fsm_coe_map, &fsm->fsm_coe);
 }
 
 /*****************************************************************************/
@@ -105,6 +107,7 @@
     ec_fsm_sii_clear(&fsm->fsm_sii);
     ec_fsm_change_clear(&fsm->fsm_change);
     ec_fsm_coe_clear(&fsm->fsm_coe);
+    ec_fsm_coe_map_clear(&fsm->fsm_coe_map);
 }
 
 /*****************************************************************************/
@@ -329,8 +332,8 @@
         up(&master->eeprom_sem);
 
         slave = request->slave;
-        if (slave->online_state == EC_SLAVE_OFFLINE || slave->error_flag) {
-            EC_ERR("Discarding EEPROM data, slave %i not ready.\n",
+        if (slave->online_state == EC_SLAVE_OFFLINE) {
+            EC_ERR("Discarding EEPROM data, slave %i offline.\n",
                     slave->ring_position);
             request->state = EC_REQUEST_FAILURE;
             wake_up(&master->eeprom_queue);
@@ -343,8 +346,8 @@
                     slave->ring_position);
         fsm->eeprom_request = request;
         fsm->eeprom_index = 0;
-        ec_fsm_sii_write(&fsm->fsm_sii, request->slave, request->offset,
-                request->words, EC_FSM_SII_NODE);
+        ec_fsm_sii_write(&fsm->fsm_sii, request->slave, request->word_offset,
+                request->data, EC_FSM_SII_NODE);
         fsm->state = ec_fsm_master_state_write_eeprom;
         fsm->state(fsm); // execute immediately
         return 1;
@@ -382,7 +385,7 @@
         request->state = EC_REQUEST_IN_PROGRESS;
         up(&master->sdo_sem);
 
-        slave = request->sdo->slave;
+        slave = request->entry->sdo->slave;
         if (slave->current_state == EC_SLAVE_STATE_INIT ||
                 slave->online_state == EC_SLAVE_OFFLINE ||
                 slave->error_flag) {
@@ -414,6 +417,7 @@
 /*****************************************************************************/
 
 /**
+ * Check for slaves that are not configured and configure them.
  */
 
 int ec_fsm_master_action_configure(
@@ -521,6 +525,29 @@
             return;
         }
 
+        // check, if slaves have their PDO mapping to be read.
+        list_for_each_entry(slave, &master->slaves, list) {
+            if (!(slave->sii_mailbox_protocols & EC_MBOX_COE)
+                || slave->pdo_mapping_fetched
+                || !slave->sdo_dictionary_fetched
+                || slave->current_state == EC_SLAVE_STATE_INIT
+                || slave->online_state == EC_SLAVE_OFFLINE) continue;
+
+            if (master->debug_level) {
+                EC_DBG("Fetching PDO mapping from slave %i via CoE.\n",
+                       slave->ring_position);
+            }
+
+            slave->pdo_mapping_fetched = 1;
+
+            // start fetching PDO mapping
+            fsm->idle = 0;
+            fsm->state = ec_fsm_master_state_pdomap;
+            ec_fsm_coe_map_start(&fsm->fsm_coe_map, slave);
+            ec_fsm_coe_map_exec(&fsm->fsm_coe_map); // execute immediately
+            return;
+        }
+
         // check for pending EEPROM write operations.
         if (ec_fsm_master_action_process_eeprom(fsm))
             return; // EEPROM write request found
@@ -945,10 +972,10 @@
     }
 
     fsm->eeprom_index++;
-    if (fsm->eeprom_index < request->size) {
+    if (fsm->eeprom_index < request->word_size) {
         ec_fsm_sii_write(&fsm->fsm_sii, slave,
-                request->offset + fsm->eeprom_index,
-                request->words + fsm->eeprom_index,
+                request->word_offset + fsm->eeprom_index,
+                request->data + fsm->eeprom_index * 2,
                 EC_FSM_SII_NODE);
         ec_fsm_sii_exec(&fsm->fsm_sii); // execute immediately
         return;
@@ -956,8 +983,8 @@
 
     // finished writing EEPROM
     if (master->debug_level)
-        EC_DBG("Finished writing EEPROM data to slave %i.\n",
-                slave->ring_position);
+        EC_DBG("Finished writing %u words of EEPROM data to slave %u.\n",
+                request->word_size, slave->ring_position);
     request->state = EC_REQUEST_COMPLETE;
     wake_up(&master->eeprom_queue);
 
@@ -1003,6 +1030,27 @@
 /*****************************************************************************/
 
 /**
+ * Scan the PDO mapping of a slave.
+ */
+
+void ec_fsm_master_state_pdomap(
+        ec_fsm_master_t *fsm /**< master state machine */
+        )
+{
+    if (ec_fsm_coe_map_exec(&fsm->fsm_coe_map)) return;
+
+    if (!ec_fsm_coe_map_success(&fsm->fsm_coe_map)) {
+        fsm->state = ec_fsm_master_state_error;
+        return;
+    }
+
+    // fetching of PDO mapping finished
+    fsm->state = ec_fsm_master_state_end;
+}
+
+/*****************************************************************************/
+
+/**
    Master state: SDO REQUEST.
 */
 
--- a/master/fsm_master.h	Thu Sep 13 11:08:46 2007 +0000
+++ b/master/fsm_master.h	Wed Oct 03 08:58:01 2007 +0000
@@ -48,6 +48,7 @@
 #include "canopen.h"
 
 #include "fsm_slave.h"
+#include "fsm_coe_map.h"
 
 /*****************************************************************************/
 
@@ -57,12 +58,12 @@
 
 typedef struct
 {
-    struct list_head list;
-    ec_slave_t *slave;
-    off_t offset;
-    size_t size;
-    const uint16_t *words;
-    ec_request_state_t state;
+    struct list_head list; /**< list head */
+    ec_slave_t *slave; /**< EtherCAT slave */
+    off_t word_offset; /**< SII address in words */
+    size_t word_size; /**< data size in words */
+    const uint8_t *data; /**< pointer to the data */
+    ec_request_state_t state; /**< state of the request */
 }
 ec_eeprom_write_request_t;
 
@@ -99,6 +100,7 @@
     ec_fsm_sii_t fsm_sii; /**< SII state machine */
     ec_fsm_change_t fsm_change; /**< State change state machine */
     ec_fsm_coe_t fsm_coe; /**< CoE state machine */
+    ec_fsm_coe_map_t fsm_coe_map; /**< CoE mapping state machine */
 };
 
 /*****************************************************************************/
--- a/master/fsm_sii.c	Thu Sep 13 11:08:46 2007 +0000
+++ b/master/fsm_sii.c	Wed Oct 03 08:58:01 2007 +0000
@@ -43,16 +43,28 @@
 #include "master.h"
 #include "fsm_sii.h"
 
-/*****************************************************************************/
-
-void ec_fsm_sii_start_reading(ec_fsm_sii_t *);
-void ec_fsm_sii_read_check(ec_fsm_sii_t *);
-void ec_fsm_sii_read_fetch(ec_fsm_sii_t *);
-void ec_fsm_sii_start_writing(ec_fsm_sii_t *);
-void ec_fsm_sii_write_check(ec_fsm_sii_t *);
-void ec_fsm_sii_write_check2(ec_fsm_sii_t *);
-void ec_fsm_sii_end(ec_fsm_sii_t *);
-void ec_fsm_sii_error(ec_fsm_sii_t *);
+/**
+ * Read/Write timeout. [ms]
+ */
+#define EEPROM_TIMEOUT 10
+
+/**
+ * Time before evaluating answer at writing. [ms]
+ */
+#define EEPROM_INHIBIT  5
+
+//#define SII_DEBUG
+
+/*****************************************************************************/
+
+void ec_fsm_sii_state_start_reading(ec_fsm_sii_t *);
+void ec_fsm_sii_state_read_check(ec_fsm_sii_t *);
+void ec_fsm_sii_state_read_fetch(ec_fsm_sii_t *);
+void ec_fsm_sii_state_start_writing(ec_fsm_sii_t *);
+void ec_fsm_sii_state_write_check(ec_fsm_sii_t *);
+void ec_fsm_sii_state_write_check2(ec_fsm_sii_t *);
+void ec_fsm_sii_state_end(ec_fsm_sii_t *);
+void ec_fsm_sii_state_error(ec_fsm_sii_t *);
 
 /*****************************************************************************/
 
@@ -86,13 +98,13 @@
 
 void ec_fsm_sii_read(ec_fsm_sii_t *fsm, /**< finite state machine */
                      ec_slave_t *slave, /**< slave to read from */
-                     uint16_t offset, /**< offset to read from */
+                     uint16_t word_offset, /**< offset to read from */
                      ec_fsm_sii_addressing_t mode /**< addressing scheme */
                      )
 {
-    fsm->state = ec_fsm_sii_start_reading;
+    fsm->state = ec_fsm_sii_state_start_reading;
     fsm->slave = slave;
-    fsm->offset = offset;
+    fsm->word_offset = word_offset;
     fsm->mode = mode;
 }
 
@@ -104,14 +116,14 @@
 
 void ec_fsm_sii_write(ec_fsm_sii_t *fsm, /**< finite state machine */
                       ec_slave_t *slave, /**< slave to read from */
-                      uint16_t offset, /**< offset to read from */
-                      const uint16_t *value, /**< pointer to 2 bytes of data */
+                      uint16_t word_offset, /**< offset to read from */
+                      const uint8_t *value, /**< pointer to 2 bytes of data */
                       ec_fsm_sii_addressing_t mode /**< addressing scheme */
                       )
 {
-    fsm->state = ec_fsm_sii_start_writing;
+    fsm->state = ec_fsm_sii_state_start_writing;
     fsm->slave = slave;
-    fsm->offset = offset;
+    fsm->word_offset = word_offset;
     fsm->mode = mode;
     memcpy(fsm->value, value, 2);
 }
@@ -127,7 +139,8 @@
 {
     fsm->state(fsm);
 
-    return fsm->state != ec_fsm_sii_end && fsm->state != ec_fsm_sii_error;
+    return fsm->state != ec_fsm_sii_state_end
+		&& fsm->state != ec_fsm_sii_state_error;
 }
 
 /*****************************************************************************/
@@ -139,11 +152,11 @@
 
 int ec_fsm_sii_success(ec_fsm_sii_t *fsm /**< Finite state machine */)
 {
-    return fsm->state == ec_fsm_sii_end;
+    return fsm->state == ec_fsm_sii_state_end;
 }
 
 /******************************************************************************
- *  SII state machine
+ * state functions
  *****************************************************************************/
 
 /**
@@ -151,7 +164,9 @@
    Starts reading the slave information interface.
 */
 
-void ec_fsm_sii_start_reading(ec_fsm_sii_t *fsm /**< finite state machine */)
+void ec_fsm_sii_state_start_reading(
+		ec_fsm_sii_t *fsm /**< finite state machine */
+		)
 {
     ec_datagram_t *datagram = fsm->datagram;
 
@@ -165,11 +180,17 @@
             break;
     }
 
-    EC_WRITE_U8 (datagram->data,     0x00); // read-only access
+    EC_WRITE_U8 (datagram->data,     0x80); // two address octets
     EC_WRITE_U8 (datagram->data + 1, 0x01); // request read operation
-    EC_WRITE_U16(datagram->data + 2, fsm->offset);
+    EC_WRITE_U16(datagram->data + 2, fsm->word_offset);
+
+#ifdef SII_DEBUG
+	EC_DBG("reading SII data:\n");
+	ec_print_data(datagram->data, 4);
+#endif
+
     fsm->retries = EC_FSM_RETRIES;
-    fsm->state = ec_fsm_sii_read_check;
+    fsm->state = ec_fsm_sii_state_read_check;
 }
 
 /*****************************************************************************/
@@ -179,7 +200,9 @@
    Checks, if the SII-read-datagram has been sent and issues a fetch datagram.
 */
 
-void ec_fsm_sii_read_check(ec_fsm_sii_t *fsm /**< finite state machine */)
+void ec_fsm_sii_state_read_check(
+		ec_fsm_sii_t *fsm /**< finite state machine */
+		)
 {
     ec_datagram_t *datagram = fsm->datagram;
 
@@ -187,7 +210,7 @@
         return;
 
     if (datagram->state != EC_DATAGRAM_RECEIVED) {
-        fsm->state = ec_fsm_sii_error;
+        fsm->state = ec_fsm_sii_state_error;
         EC_ERR("Failed to receive SII read datagram from slave %i"
                 " (datagram state %i).\n",
                fsm->slave->ring_position, datagram->state);
@@ -195,7 +218,7 @@
     }
 
     if (datagram->working_counter != 1) {
-        fsm->state = ec_fsm_sii_error;
+        fsm->state = ec_fsm_sii_state_error;
         EC_ERR("Reception of SII read datagram failed on slave %i: ",
                 fsm->slave->ring_position);
         ec_datagram_print_wc_error(datagram);
@@ -216,7 +239,7 @@
     }
 
     fsm->retries = EC_FSM_RETRIES;
-    fsm->state = ec_fsm_sii_read_fetch;
+    fsm->state = ec_fsm_sii_state_read_fetch;
 }
 
 /*****************************************************************************/
@@ -226,7 +249,9 @@
    Fetches the result of an SII-read datagram.
 */
 
-void ec_fsm_sii_read_fetch(ec_fsm_sii_t *fsm /**< finite state machine */)
+void ec_fsm_sii_state_read_fetch(
+		ec_fsm_sii_t *fsm /**< finite state machine */
+		)
 {
     ec_datagram_t *datagram = fsm->datagram;
 
@@ -234,7 +259,7 @@
         return;
 
     if (datagram->state != EC_DATAGRAM_RECEIVED) {
-        fsm->state = ec_fsm_sii_error;
+        fsm->state = ec_fsm_sii_state_error;
         EC_ERR("Failed to receive SII check/fetch datagram from slave %i"
                 " (datagram state %i).\n",
                fsm->slave->ring_position, datagram->state);
@@ -242,79 +267,78 @@
     }
 
     if (datagram->working_counter != 1) {
-        fsm->state = ec_fsm_sii_error;
+        fsm->state = ec_fsm_sii_state_error;
         EC_ERR("Reception of SII check/fetch datagram failed on slave %i: ",
                 fsm->slave->ring_position);
         ec_datagram_print_wc_error(datagram);
         return;
     }
 
+#ifdef SII_DEBUG
+	EC_DBG("checking SII read state:\n");
+	ec_print_data(datagram->data, 10);
+#endif
+
+    if (EC_READ_U8(datagram->data + 1) & 0x20) {
+        EC_ERR("SII: Error on last SII command!\n");
+        fsm->state = ec_fsm_sii_state_error;
+        return;
+    }
+
     // check "busy bit"
-    if (EC_READ_U8(datagram->data + 1) & 0x81) {
+    if (EC_READ_U8(datagram->data + 1) & 0x81) { // busy bit or
+												 // read operation busy
         // still busy... timeout?
         if (datagram->cycles_received
-            - fsm->cycles_start >= (cycles_t) 10 * cpu_khz) {
-            if (!fsm->check_once_more) {
+            - fsm->cycles_start >= (cycles_t) EEPROM_TIMEOUT * cpu_khz) {
+            if (fsm->check_once_more) {
+				fsm->check_once_more = 0;
+			} else {
                 EC_ERR("SII: Read timeout.\n");
-                fsm->state = ec_fsm_sii_error;
-#if 0
-                EC_DBG("SII busy: %02X %02X %02X %02X\n",
-                       EC_READ_U8(datagram->data + 0),
-                       EC_READ_U8(datagram->data + 1),
-                       EC_READ_U8(datagram->data + 2),
-                       EC_READ_U8(datagram->data + 3));
-#endif
+                fsm->state = ec_fsm_sii_state_error;
                 return;
             }
-            fsm->check_once_more = 0;
         }
 
         // issue check/fetch datagram again
-        switch (fsm->mode) {
-            case EC_FSM_SII_POSITION:
-                ec_datagram_aprd(datagram, fsm->slave->ring_position, 0x502, 10);
-                break;
-            case EC_FSM_SII_NODE:
-                ec_datagram_nprd(datagram, fsm->slave->station_address, 0x502, 10);
-                break;
-        }
         fsm->retries = EC_FSM_RETRIES;
         return;
     }
 
-#if 0
-    EC_DBG("SII rec: %02X %02X %02X %02X - %02X %02X %02X %02X\n",
-           EC_READ_U8(datagram->data + 0), EC_READ_U8(datagram->data + 1),
-           EC_READ_U8(datagram->data + 2), EC_READ_U8(datagram->data + 3),
-           EC_READ_U8(datagram->data + 6), EC_READ_U8(datagram->data + 7),
-           EC_READ_U8(datagram->data + 8), EC_READ_U8(datagram->data + 9));
-#endif
-
     // SII value received.
     memcpy(fsm->value, datagram->data + 6, 4);
-    fsm->state = ec_fsm_sii_end;
+    fsm->state = ec_fsm_sii_state_end;
 }
 
 /*****************************************************************************/
 
 /**
    SII state: START WRITING.
-   Starts reading the slave information interface.
-*/
-
-void ec_fsm_sii_start_writing(ec_fsm_sii_t *fsm /**< finite state machine */)
+   Starts writing a word through the slave information interface.
+*/
+
+void ec_fsm_sii_state_start_writing(
+		ec_fsm_sii_t *fsm /**< finite state machine */
+		)
 {
     ec_datagram_t *datagram = fsm->datagram;
 
     // initiate write operation
     ec_datagram_npwr(datagram, fsm->slave->station_address, 0x502, 8);
-    EC_WRITE_U8 (datagram->data,     0x01); // enable write access
+    EC_WRITE_U8 (datagram->data,     0x81); // two address octets
+											// + enable write access
     EC_WRITE_U8 (datagram->data + 1, 0x02); // request write operation
-    EC_WRITE_U32(datagram->data + 2, fsm->offset);
+    EC_WRITE_U16(datagram->data + 2, fsm->word_offset);
+	memset(datagram->data + 4, 0x00, 2);
     memcpy(datagram->data + 6, fsm->value, 2);
 
+#ifdef SII_DEBUG
+	EC_DBG("writing SII data:\n");
+	ec_print_data(datagram->data, 8);
+#endif
+
     fsm->retries = EC_FSM_RETRIES;
-    fsm->state = ec_fsm_sii_write_check;
+    fsm->state = ec_fsm_sii_state_write_check;
 }
 
 /*****************************************************************************/
@@ -323,7 +347,9 @@
    SII state: WRITE CHECK.
 */
 
-void ec_fsm_sii_write_check(ec_fsm_sii_t *fsm /**< finite state machine */)
+void ec_fsm_sii_state_write_check(
+		ec_fsm_sii_t *fsm /**< finite state machine */
+		)
 {
     ec_datagram_t *datagram = fsm->datagram;
 
@@ -331,7 +357,7 @@
         return;
 
     if (datagram->state != EC_DATAGRAM_RECEIVED) {
-        fsm->state = ec_fsm_sii_error;
+        fsm->state = ec_fsm_sii_state_error;
         EC_ERR("Failed to receive SII write datagram for slave %i"
                 " (datagram state %i).\n",
                fsm->slave->ring_position, datagram->state);
@@ -339,7 +365,7 @@
     }
 
     if (datagram->working_counter != 1) {
-        fsm->state = ec_fsm_sii_error;
+        fsm->state = ec_fsm_sii_state_error;
         EC_ERR("Reception of SII write datagram failed on slave %i: ",
                 fsm->slave->ring_position);
         ec_datagram_print_wc_error(datagram);
@@ -349,10 +375,10 @@
     fsm->cycles_start = datagram->cycles_sent;
     fsm->check_once_more = 1;
 
-    // issue check/fetch datagram
+    // issue check datagram
     ec_datagram_nprd(datagram, fsm->slave->station_address, 0x502, 2);
     fsm->retries = EC_FSM_RETRIES;
-    fsm->state = ec_fsm_sii_write_check2;
+    fsm->state = ec_fsm_sii_state_write_check2;
 }
 
 /*****************************************************************************/
@@ -361,7 +387,9 @@
    SII state: WRITE CHECK 2.
 */
 
-void ec_fsm_sii_write_check2(ec_fsm_sii_t *fsm /**< finite state machine */)
+void ec_fsm_sii_state_write_check2(
+		ec_fsm_sii_t *fsm /**< finite state machine */
+		)
 {
     ec_datagram_t *datagram = fsm->datagram;
 
@@ -369,7 +397,7 @@
         return;
 
     if (datagram->state != EC_DATAGRAM_RECEIVED) {
-        fsm->state = ec_fsm_sii_error;
+        fsm->state = ec_fsm_sii_state_error;
         EC_ERR("Failed to receive SII write check datagram from slave %i"
                 " (datagram state %i).\n",
                fsm->slave->ring_position, datagram->state);
@@ -377,38 +405,63 @@
     }
 
     if (datagram->working_counter != 1) {
-        fsm->state = ec_fsm_sii_error;
+        fsm->state = ec_fsm_sii_state_error;
         EC_ERR("Reception of SII write check datagram failed on slave %i: ",
                 fsm->slave->ring_position);
         ec_datagram_print_wc_error(datagram);
         return;
     }
 
-    if (EC_READ_U8(datagram->data + 1) & 0x82) {
+#ifdef SII_DEBUG
+	EC_DBG("checking SII write state:\n");
+	ec_print_data(datagram->data, 2);
+#endif
+
+    if (EC_READ_U8(datagram->data + 1) & 0x20) {
+        EC_ERR("SII: Error on last SII command!\n");
+        fsm->state = ec_fsm_sii_state_error;
+        return;
+    }
+
+	/* FIXME: some slaves never answer with the busy flag set...
+	 * wait a few ms for the write operation to complete. */
+	if (datagram->cycles_received - fsm->cycles_start
+			< (cycles_t) EEPROM_INHIBIT * cpu_khz) {
+#ifdef SII_DEBUG
+		EC_DBG("too early.\n");
+#endif
+        // issue check datagram again
+        fsm->retries = EC_FSM_RETRIES;
+        return;
+	}
+
+    if (EC_READ_U8(datagram->data + 1) & 0x82) { // busy bit or
+												 // write operation busy bit
         // still busy... timeout?
         if (datagram->cycles_received
-            - fsm->cycles_start >= (cycles_t) 10 * cpu_khz) {
-            if (!fsm->check_once_more) {
+            - fsm->cycles_start >= (cycles_t) EEPROM_TIMEOUT * cpu_khz) {
+            if (fsm->check_once_more) {
+				fsm->check_once_more = 0;
+			} else {
                 EC_ERR("SII: Write timeout.\n");
-                fsm->state = ec_fsm_sii_error;
+                fsm->state = ec_fsm_sii_state_error;
                 return;
             }
-            fsm->check_once_more = 0;
         }
 
-        // issue check/fetch datagram again
+        // issue check datagram again
         fsm->retries = EC_FSM_RETRIES;
         return;
     }
 
     if (EC_READ_U8(datagram->data + 1) & 0x40) {
         EC_ERR("SII: Write operation failed!\n");
-        fsm->state = ec_fsm_sii_error;
+        fsm->state = ec_fsm_sii_state_error;
         return;
     }
 
     // success
-    fsm->state = ec_fsm_sii_end;
+    fsm->state = ec_fsm_sii_state_end;
 }
 
 /*****************************************************************************/
@@ -417,7 +470,9 @@
    State: ERROR.
 */
 
-void ec_fsm_sii_error(ec_fsm_sii_t *fsm /**< finite state machine */)
+void ec_fsm_sii_state_error(
+		ec_fsm_sii_t *fsm /**< finite state machine */
+		)
 {
 }
 
@@ -427,8 +482,10 @@
    State: END.
 */
 
-void ec_fsm_sii_end(ec_fsm_sii_t *fsm /**< finite state machine */)
-{
-}
-
-/*****************************************************************************/
+void ec_fsm_sii_state_end(
+		ec_fsm_sii_t *fsm /**< finite state machine */
+		)
+{
+}
+
+/*****************************************************************************/
--- a/master/fsm_sii.h	Thu Sep 13 11:08:46 2007 +0000
+++ b/master/fsm_sii.h	Wed Oct 03 08:58:01 2007 +0000
@@ -48,6 +48,9 @@
 
 /*****************************************************************************/
 
+/**
+ * SII access addressing mode.
+ */
 typedef enum
 {
     EC_FSM_SII_POSITION,
@@ -70,7 +73,7 @@
     unsigned int retries; /**< retries upon datagram timeout */
 
     void (*state)(ec_fsm_sii_t *); /**< SII state function */
-    uint16_t offset; /**< input: offset in SII */
+    uint16_t word_offset; /**< input: word offset in SII */
     ec_fsm_sii_addressing_t mode; /**< reading via APRD or NPRD */
     uint8_t value[4]; /**< raw SII value (32bit) */
     cycles_t cycles_start; /**< start timestamp */
@@ -85,7 +88,7 @@
 void ec_fsm_sii_read(ec_fsm_sii_t *, ec_slave_t *,
                      uint16_t, ec_fsm_sii_addressing_t);
 void ec_fsm_sii_write(ec_fsm_sii_t *, ec_slave_t *, uint16_t,
-        const uint16_t *, ec_fsm_sii_addressing_t);
+        const uint8_t *, ec_fsm_sii_addressing_t);
 
 int ec_fsm_sii_exec(ec_fsm_sii_t *);
 int ec_fsm_sii_success(ec_fsm_sii_t *);
--- a/master/fsm_slave.c	Thu Sep 13 11:08:46 2007 +0000
+++ b/master/fsm_slave.c	Wed Oct 03 08:58:01 2007 +0000
@@ -403,14 +403,15 @@
     cat_size = EC_READ_U16(fsm->fsm_sii.value + 2);
 
     if (cat_type != 0xFFFF) { // not the last category
-        fsm->sii_offset += cat_size + 2;
-        if (fsm->sii_offset >= EC_MAX_EEPROM_SIZE) {
+        off_t next_offset = 2UL + fsm->sii_offset + cat_size;
+        if (next_offset >= EC_MAX_EEPROM_SIZE) {
             EC_WARN("EEPROM size of slave %i exceeds"
-                    " %i words (0xffff limiter missing?).\n",
+                    " %u words (0xffff limiter missing?).\n",
                     slave->ring_position, EC_MAX_EEPROM_SIZE);
             slave->eeprom_size = EC_FIRST_EEPROM_CATEGORY_OFFSET * 2;
             goto alloc_eeprom;
         }
+        fsm->sii_offset = next_offset;
         ec_fsm_sii_read(&fsm->fsm_sii, slave, fsm->sii_offset,
                         EC_FSM_SII_NODE);
         ec_fsm_sii_exec(&fsm->fsm_sii); // execute state immediately
@@ -421,17 +422,18 @@
 
 alloc_eeprom:
     if (slave->eeprom_data) {
-        EC_INFO("Freeing old EEPROM data on slave %i...\n",
+        EC_WARN("Freeing old EEPROM data on slave %i...\n",
                 slave->ring_position);
         kfree(slave->eeprom_data);
     }
 
     if (!(slave->eeprom_data =
-          (uint8_t *) kmalloc(slave->eeprom_size, GFP_ATOMIC))) {
-        fsm->slave->error_flag = 1;
-        fsm->state = ec_fsm_slave_state_error;
-        EC_ERR("Failed to allocate EEPROM data on slave %i.\n",
-               slave->ring_position);
+                (uint8_t *) kmalloc(slave->eeprom_size, GFP_ATOMIC))) {
+        EC_ERR("Failed to allocate %u bytes of EEPROM data for slave %u.\n",
+               slave->eeprom_size, slave->ring_position);
+        slave->eeprom_size = 0;
+        slave->error_flag = 1;
+        fsm->state = ec_fsm_slave_state_error;
         return;
     }
 
@@ -452,7 +454,7 @@
 void ec_fsm_slave_scan_state_eeprom_data(ec_fsm_slave_t *fsm /**< slave state machine */)
 {
     ec_slave_t *slave = fsm->slave;
-    uint16_t *cat_word, cat_type, cat_size;
+    uint16_t *cat_word, cat_type, cat_size, eeprom_word_size = slave->eeprom_size / 2;
 
     if (ec_fsm_sii_exec(&fsm->fsm_sii)) return;
 
@@ -466,7 +468,7 @@
 
     // 2 words fetched
 
-    if (fsm->sii_offset + 2 <= slave->eeprom_size / 2) { // 2 words fit
+    if (fsm->sii_offset + 2 <= eeprom_word_size) { // 2 words fit
         memcpy(slave->eeprom_data + fsm->sii_offset * 2,
                fsm->fsm_sii.value, 4);
     }
@@ -475,7 +477,7 @@
                fsm->fsm_sii.value, 2);
     }
 
-    if (fsm->sii_offset + 2 < slave->eeprom_size / 2) {
+    if (fsm->sii_offset + 2 < eeprom_word_size) {
         // fetch the next 2 words
         fsm->sii_offset += 2;
         ec_fsm_sii_read(&fsm->fsm_sii, slave, fsm->sii_offset,
@@ -507,39 +509,65 @@
     slave->sii_mailbox_protocols =
         EC_READ_U16(slave->eeprom_data + 2 * 0x001C);
 
+    if (eeprom_word_size < EC_FIRST_EEPROM_CATEGORY_OFFSET + 1) {
+        EC_ERR("Unexpected end of EEPROM data in slave %u:"
+                " First category header missing.\n",
+                slave->ring_position);
+        goto end;
+    }
+
     // evaluate category data
-    cat_word = (uint16_t *) slave->eeprom_data + EC_FIRST_EEPROM_CATEGORY_OFFSET;
+    cat_word =
+        (uint16_t *) slave->eeprom_data + EC_FIRST_EEPROM_CATEGORY_OFFSET;
     while (EC_READ_U16(cat_word) != 0xFFFF) {
+
+        // type and size words must fit
+        if (cat_word + 2 - (uint16_t *) slave->eeprom_data
+                > eeprom_word_size) {
+            EC_ERR("Unexpected end of EEPROM data in slave %u:"
+                    " Category header incomplete.\n",
+                    slave->ring_position);
+            goto end;
+        }
+
         cat_type = EC_READ_U16(cat_word) & 0x7FFF;
         cat_size = EC_READ_U16(cat_word + 1);
+        cat_word += 2;
+
+        if (cat_word + cat_size - (uint16_t *) slave->eeprom_data
+                > eeprom_word_size) {
+            EC_WARN("Unexpected end of EEPROM data in slave %u:"
+                    " Category data incomplete.\n",
+                    slave->ring_position);
+            goto end;
+        }
 
         switch (cat_type) {
             case 0x000A:
-                if (ec_slave_fetch_sii_strings(
-                            slave, (uint8_t *) (cat_word + 2)))
+                if (ec_slave_fetch_sii_strings(slave, (uint8_t *) cat_word,
+                            cat_size * 2))
                     goto end;
                 break;
             case 0x001E:
-                ec_slave_fetch_sii_general(
-                        slave, (uint8_t *) (cat_word + 2));
+                if (ec_slave_fetch_sii_general(slave, (uint8_t *) cat_word,
+                            cat_size * 2))
+                    goto end;
                 break;
             case 0x0028:
                 break;
             case 0x0029:
-                if (ec_slave_fetch_sii_syncs(
-                            slave, (uint8_t *) (cat_word + 2), cat_size))
+                if (ec_slave_fetch_sii_syncs(slave, (uint8_t *) cat_word,
+                            cat_size * 2))
                     goto end;
                 break;
             case 0x0032:
-                if (ec_slave_fetch_sii_pdos(
-                            slave, (uint8_t *) (cat_word + 2),
-                            cat_size, EC_TX_PDO))
+                if (ec_slave_fetch_sii_pdos( slave, (uint8_t *) cat_word,
+                            cat_size * 2, EC_TX_PDO))
                     goto end;
                 break;
             case 0x0033:
-                if (ec_slave_fetch_sii_pdos(
-                            slave, (uint8_t *) (cat_word + 2),
-                            cat_size, EC_RX_PDO))
+                if (ec_slave_fetch_sii_pdos( slave, (uint8_t *) cat_word,
+                            cat_size * 2, EC_RX_PDO))
                     goto end;
                 break;
             default:
@@ -548,7 +576,13 @@
                             cat_type, slave->ring_position);
         }
 
-        cat_word += cat_size + 2;
+        cat_word += cat_size;
+        if (cat_word - (uint16_t *) slave->eeprom_data >= eeprom_word_size) {
+            EC_WARN("Unexpected end of EEPROM data in slave %u:"
+                    " Next category header missing.\n",
+                    slave->ring_position);
+            goto end;
+        }
     }
 
     fsm->state = ec_fsm_slave_state_end;
@@ -594,7 +628,8 @@
     if (ec_fsm_change_exec(&fsm->fsm_change)) return;
 
     if (!ec_fsm_change_success(&fsm->fsm_change)) {
-        slave->error_flag = 1;
+        if (!fsm->fsm_change.spontaneous_change)
+            slave->error_flag = 1;
         fsm->state = ec_fsm_slave_state_error;
         return;
     }
@@ -662,6 +697,7 @@
 /*****************************************************************************/
 
 /**
+ * Check for mailbox sync managers to be configured.
  */
 
 void ec_fsm_slave_conf_enter_mbox_sync(
@@ -683,8 +719,11 @@
         return;
     }
 
-    if (!slave->sii_mailbox_protocols || slave->sii_sync_count < 2) {
-        // no mailbox sync managers to be configured
+    if (!slave->sii_mailbox_protocols) {
+        // no mailbox protocols supported
+        if (master->debug_level)
+            EC_DBG("Slave %i does not support mailbox communication.\n",
+                    slave->ring_position);
         ec_fsm_slave_conf_enter_preop(fsm);
         return;
     }
@@ -694,14 +733,41 @@
                slave->ring_position);
     }
 
-    // configure sync managers
-    ec_datagram_npwr(datagram, slave->station_address, 0x0800,
-                     EC_SYNC_SIZE * slave->sii_sync_count);
-    memset(datagram->data, 0x00, EC_SYNC_SIZE * slave->sii_sync_count);
-
-    for (i = 0; i < 2; i++) {
-        ec_sync_config(&slave->sii_syncs[i],
-                datagram->data + EC_SYNC_SIZE * i);
+    if (slave->sii_sync_count >= 2) {
+        // configure sync managers
+        ec_datagram_npwr(datagram, slave->station_address, 0x0800,
+                EC_SYNC_SIZE * slave->sii_sync_count);
+        memset(datagram->data, 0x00, EC_SYNC_SIZE * slave->sii_sync_count);
+
+        for (i = 0; i < 2; i++) {
+            ec_sync_config(&slave->sii_syncs[i],
+                    datagram->data + EC_SYNC_SIZE * i);
+        }
+    } else { // no mailbox sync manager configurations provided
+        ec_sync_t sync;
+
+        if (master->debug_level)
+            EC_DBG("Slave %i does not provide"
+                    " mailbox sync manager configurations.\n",
+                    slave->ring_position);
+
+        ec_datagram_npwr(datagram, slave->station_address, 0x0800,
+                EC_SYNC_SIZE * 2);
+        memset(datagram->data, 0x00, EC_SYNC_SIZE * 2);
+
+        ec_sync_init(&sync, slave, 0);
+        sync.physical_start_address = slave->sii_rx_mailbox_offset;
+        sync.length = slave->sii_rx_mailbox_size;
+        sync.control_register = 0x26;
+        sync.enable = 1;
+        ec_sync_config(&sync, datagram->data + EC_SYNC_SIZE * sync.index);
+
+        ec_sync_init(&sync, slave, 1);
+        sync.physical_start_address = slave->sii_tx_mailbox_offset;
+        sync.length = slave->sii_tx_mailbox_size;
+        sync.control_register = 0x22;
+        sync.enable = 1;
+        ec_sync_config(&sync, datagram->data + EC_SYNC_SIZE * sync.index);
     }
 
     fsm->retries = EC_FSM_RETRIES;
@@ -745,6 +811,7 @@
 /*****************************************************************************/
 
 /**
+ * Request PREOP state.
  */
 
 void ec_fsm_slave_conf_enter_preop(ec_fsm_slave_t *fsm /**< slave state machine */)
@@ -768,7 +835,8 @@
     if (ec_fsm_change_exec(&fsm->fsm_change)) return;
 
     if (!ec_fsm_change_success(&fsm->fsm_change)) {
-        slave->error_flag = 1;
+        if (!fsm->fsm_change.spontaneous_change)
+            slave->error_flag = 1;
         fsm->state = ec_fsm_slave_state_error;
         return;
     }
@@ -795,6 +863,7 @@
 /*****************************************************************************/
 
 /**
+ * Check for SDO configurations to be applied.
  */
 
 void ec_fsm_slave_conf_enter_sdoconf(ec_fsm_slave_t *fsm /**< slave state machine */)
@@ -850,6 +919,7 @@
 /*****************************************************************************/
 
 /**
+ * Check for alternative PDO mappings to be applied.
  */
 
 void ec_fsm_slave_conf_enter_mapconf(
@@ -896,6 +966,7 @@
 /*****************************************************************************/
 
 /**
+ * Check for PDO sync managers to be configured.
  */
 
 void ec_fsm_slave_conf_enter_pdo_sync(
@@ -928,6 +999,7 @@
 /*****************************************************************************/
 
 /**
+ * Configure PDO sync managers.
  */
 
 void ec_fsm_slave_conf_state_pdo_sync(ec_fsm_slave_t *fsm /**< slave state machine */)
@@ -961,7 +1033,8 @@
 /*****************************************************************************/
 
 /**
-*/
+ * Check for FMMUs to be configured.
+ */
 
 void ec_fsm_slave_conf_enter_fmmu(ec_fsm_slave_t *fsm /**< slave state machine */)
 {
@@ -1023,6 +1096,7 @@
 /*****************************************************************************/
 
 /**
+ * Request SAVEOP state.
  */
 
 void ec_fsm_slave_conf_enter_saveop(ec_fsm_slave_t *fsm /**< slave state machine */)
@@ -1046,7 +1120,8 @@
     if (ec_fsm_change_exec(&fsm->fsm_change)) return;
 
     if (!ec_fsm_change_success(&fsm->fsm_change)) {
-        fsm->slave->error_flag = 1;
+        if (!fsm->fsm_change.spontaneous_change)
+            fsm->slave->error_flag = 1;
         fsm->state = ec_fsm_slave_state_error;
         return;
     }
@@ -1086,7 +1161,8 @@
     if (ec_fsm_change_exec(&fsm->fsm_change)) return;
 
     if (!ec_fsm_change_success(&fsm->fsm_change)) {
-        slave->error_flag = 1;
+        if (!fsm->fsm_change.spontaneous_change)
+            slave->error_flag = 1;
         fsm->state = ec_fsm_slave_state_error;
         return;
     }
--- a/master/fsm_slave.h	Thu Sep 13 11:08:46 2007 +0000
+++ b/master/fsm_slave.h	Wed Oct 03 08:58:01 2007 +0000
@@ -66,7 +66,7 @@
 
     void (*state)(ec_fsm_slave_t *); /**< state function */
     ec_sdo_data_t *sdodata; /**< SDO configuration data */
-    uint16_t sii_offset; 
+    uint16_t sii_offset; /**< SII offset in words */
 
     ec_fsm_sii_t fsm_sii; /**< SII state machine */
     ec_fsm_change_t fsm_change; /**< State change state machine */
--- a/master/globals.h	Thu Sep 13 11:08:46 2007 +0000
+++ b/master/globals.h	Wed Oct 03 08:58:01 2007 +0000
@@ -201,4 +201,8 @@
 
 /*****************************************************************************/
 
+typedef struct ec_sdo ec_sdo_t; /**< \see ec_sdo */
+
+/*****************************************************************************/
+
 #endif
--- a/master/master.c	Thu Sep 13 11:08:46 2007 +0000
+++ b/master/master.c	Wed Oct 03 08:58:01 2007 +0000
@@ -57,13 +57,11 @@
 /*****************************************************************************/
 
 void ec_master_destroy_domains(ec_master_t *);
-void ec_master_sync_io(ec_master_t *);
 static int ec_master_idle_thread(ec_master_t *);
 static int ec_master_operation_thread(ec_master_t *);
 #ifdef EC_EOE
 void ec_master_eoe_run(unsigned long);
 #endif
-void ec_master_check_sdo(unsigned long);
 ssize_t ec_show_master_attribute(struct kobject *, struct attribute *, char *);
 ssize_t ec_store_master_attribute(struct kobject *, struct attribute *,
                                   const char *, size_t);
@@ -917,10 +915,15 @@
 
 /*****************************************************************************/
 
+/**
+ * Prints the device information to a buffer.
+ * \return number of bytes written.
+ */
+
 ssize_t ec_master_device_info(
-        const ec_device_t *device,
-        const uint8_t *mac,
-        char *buffer
+        const ec_device_t *device, /**< EtherCAT device */
+        const uint8_t *mac, /**< MAC address */
+        char *buffer /**< target buffer */
         )
 {
     unsigned int frames_lost;
--- a/master/master.h	Thu Sep 13 11:08:46 2007 +0000
+++ b/master/master.h	Wed Oct 03 08:58:01 2007 +0000
@@ -132,7 +132,7 @@
 
     int debug_level; /**< master debug level */
     ec_stats_t stats; /**< cyclic statistics */
-    unsigned int pdo_slaves_offline; /** number of slaves, for which PDOs
+    unsigned int pdo_slaves_offline; /**< number of slaves, for which PDOs
                                        were registered and that are offline
                                        (used for bus status) */
     unsigned int frames_timed_out; /**< there were frame timeouts in the last
--- a/master/module.c	Thu Sep 13 11:08:46 2007 +0000
+++ b/master/module.c	Wed Oct 03 08:58:01 2007 +0000
@@ -71,7 +71,7 @@
 
 static uint8_t macs[MAX_MASTERS][2][ETH_ALEN]; /**< MAC addresses */
 
-char *ec_master_version_str = EC_MASTER_VERSION;
+char *ec_master_version_str = EC_MASTER_VERSION; /**< master version string */
 
 /*****************************************************************************/
 
@@ -194,6 +194,10 @@
  * MAC address functions
  ****************************************************************************/
 
+/**
+ * \return true, if two MAC addresses are equal.
+ */
+
 int ec_mac_equal(const uint8_t *mac1, const uint8_t *mac2)
 {
     unsigned int i;
@@ -207,7 +211,15 @@
                 
 /*****************************************************************************/
 
-ssize_t ec_mac_print(const uint8_t *mac, char *buffer)
+/**
+ * Print a MAC address to a buffer.
+ * \return number of bytes written.
+ */
+
+ssize_t ec_mac_print(
+        const uint8_t *mac, /**< MAC address */
+        char *buffer /**< target buffer */
+        )
 {
     off_t off = 0;
     unsigned int i;
@@ -222,6 +234,10 @@
 
 /*****************************************************************************/
 
+/**
+ * \return true, if the MAC address is all-zero.
+ */
+
 int ec_mac_is_zero(const uint8_t *mac)
 {
     unsigned int i;
@@ -235,6 +251,10 @@
 
 /*****************************************************************************/
 
+/**
+ * \return true, if the given MAC address is the broadcast address.
+ */
+
 int ec_mac_is_broadcast(const uint8_t *mac)
 {
     unsigned int i;
@@ -248,6 +268,13 @@
 
 /*****************************************************************************/
 
+/**
+ * Parse a MAC address from a string.
+ * The MAC address must follow the regexp
+ * "([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2}".
+   \return 0 on success, else < 0
+ */
+
 static int ec_mac_parse(uint8_t *mac, const char *src, int allow_empty)
 {
     unsigned int i, value;
--- a/master/slave.c	Thu Sep 13 11:08:46 2007 +0000
+++ b/master/slave.c	Wed Oct 03 08:58:01 2007 +0000
@@ -154,6 +154,7 @@
     INIT_LIST_HEAD(&slave->sdo_confs);
 
     slave->sdo_dictionary_fetched = 0;
+    slave->pdo_mapping_fetched = 0;
     slave->jiffies_preop = 0;
 
     for (i = 0; i < 4; i++) {
@@ -281,7 +282,8 @@
 /*****************************************************************************/
 
 /**
-*/
+ * SDO kobject clear method.
+ */
 
 void ec_slave_sdos_clear(struct kobject *kobj /**< kobject for SDOs */)
 {
@@ -373,6 +375,7 @@
 /*****************************************************************************/
 
 /**
+ * Request a slave state and resets the error flag.
  */
 
 void ec_slave_request_state(ec_slave_t *slave, /**< EtherCAT slave */
@@ -387,12 +390,14 @@
 
 /**
    Fetches data from a STRING category.
+   \todo range checking
    \return 0 in case of success, else < 0
 */
 
 int ec_slave_fetch_sii_strings(
         ec_slave_t *slave, /**< EtherCAT slave */
-        const uint8_t *data /**< category data */
+        const uint8_t *data, /**< category data */
+        size_t data_size /**< number of bytes */
         )
 {
     int i;
@@ -443,13 +448,20 @@
    \return 0 in case of success, else < 0
 */
 
-void ec_slave_fetch_sii_general(
+int ec_slave_fetch_sii_general(
         ec_slave_t *slave, /**< EtherCAT slave */
-        const uint8_t *data /**< category data */
+        const uint8_t *data, /**< category data */
+        size_t data_size /**< size in bytes */
         )
 {
     unsigned int i;
 
+    if (data_size != 32) {
+        EC_ERR("Wrong size of general category (%u/32) in slave %u.\n",
+                data_size, slave->ring_position);
+        return -1;
+    }
+
     slave->sii_group = ec_slave_sii_string(slave, data[0]);
     slave->sii_image = ec_slave_sii_string(slave, data[1]);
     slave->sii_order = ec_slave_sii_string(slave, data[2]);
@@ -460,6 +472,8 @@
             (data[4] & (0x03 << (i * 2))) >> (i * 2);
 
     slave->sii_current_on_ebus = EC_READ_S16(data + 0x0C);
+
+    return 0;
 }
 
 /*****************************************************************************/
@@ -472,19 +486,26 @@
 int ec_slave_fetch_sii_syncs(
         ec_slave_t *slave, /**< EtherCAT slave */
         const uint8_t *data, /**< category data */
-        size_t word_count /**< number of words */
+        size_t data_size /**< number of bytes */
         )
 {
     unsigned int i;
     ec_sync_t *sync;
-
-    // sync manager struct is 4 words long
-    slave->sii_sync_count = word_count / 4;
-
-    if (!(slave->sii_syncs =
-                kmalloc(sizeof(ec_sync_t) * slave->sii_sync_count,
-                    GFP_KERNEL))) {
-        EC_ERR("Failed to allocate memory for sync managers.\n");
+    size_t memsize;
+
+    // one sync manager struct is 4 words long
+    if (data_size % 8) {
+        EC_ERR("Invalid SII sync manager size %u in slave %u.\n",
+                data_size, slave->ring_position);
+        return -1;
+    }
+
+    slave->sii_sync_count = data_size / 8;
+
+    memsize = sizeof(ec_sync_t) * slave->sii_sync_count;
+    if (!(slave->sii_syncs = kmalloc(memsize, GFP_KERNEL))) {
+        EC_ERR("Failed to allocate %u bytes for sync managers.\n",
+                memsize);
         slave->sii_sync_count = 0;
         return -1;
     }
@@ -512,7 +533,7 @@
 int ec_slave_fetch_sii_pdos(
         ec_slave_t *slave, /**< EtherCAT slave */
         const uint8_t *data, /**< category data */
-        size_t word_count, /**< number of words */
+        size_t data_size, /**< number of bytes */
         ec_pdo_type_t pdo_type /**< PDO type */
         )
 {
@@ -520,7 +541,7 @@
     ec_pdo_entry_t *entry;
     unsigned int entry_count, i;
 
-    while (word_count >= 4) {
+    while (data_size >= 8) {
         if (!(pdo = kmalloc(sizeof(ec_pdo_t), GFP_KERNEL))) {
             EC_ERR("Failed to allocate PDO memory.\n");
             return -1;
@@ -534,7 +555,7 @@
         pdo->name = ec_slave_sii_string(slave, EC_READ_U8(data + 5));
         list_add_tail(&pdo->list, &slave->sii_pdos);
 
-        word_count -= 4;
+        data_size -= 8;
         data += 8;
 
         for (i = 0; i < entry_count; i++) {
@@ -549,7 +570,7 @@
             entry->bit_length = EC_READ_U8(data + 5);
             list_add_tail(&entry->list, &pdo->entries);
 
-            word_count -= 4;
+            data_size -= 8;
             data += 8;
         }
 
@@ -794,7 +815,7 @@
 
         list_for_each_entry(pdo, &sync->pdos, list) {
             off += sprintf(buffer + off, "    %s 0x%04X \"%s\"\n",
-                    pdo->type == EC_RX_PDO ? "RXPDO" : "TXPDO",
+                    pdo->type == EC_RX_PDO ? "RxPdo" : "TxPdo",
                     pdo->index, pdo->name ? pdo->name : "???");
 
             list_for_each_entry(pdo_entry, &pdo->entries, list) {
@@ -807,12 +828,13 @@
         }
     }
 
-    if (!list_empty(&slave->sii_pdos))
+    // type-cast to avoid warnings on some compilers
+    if (!list_empty((struct list_head *) &slave->sii_pdos))
         off += sprintf(buffer + off, "\nAvailable PDOs:\n");
 
     list_for_each_entry(pdo, &slave->sii_pdos, list) {
         off += sprintf(buffer + off, "  %s 0x%04X \"%s\"",
-                       pdo->type == EC_RX_PDO ? "RXPDO" : "TXPDO",
+                       pdo->type == EC_RX_PDO ? "RxPdo" : "TxPdo",
                        pdo->index, pdo->name ? pdo->name : "???");
         if (pdo->sync_index >= 0)
             off += sprintf(buffer + off, ", default mapping: SM%u.\n",
@@ -828,7 +850,8 @@
         }
     }
 
-    if (!list_empty(&slave->sdo_confs))
+    // type-cast to avoid warnings on some compilers
+    if (!list_empty((struct list_head *) &slave->sdo_confs))
         off += sprintf(buffer + off, "\nSDO configurations:\n");
 
     list_for_each_entry(sdodata, &slave->sdo_confs, list) {
@@ -854,7 +877,9 @@
  * \return 0 case of success, otherwise error code.
  */
 
-int ec_slave_schedule_eeprom_writing(ec_eeprom_write_request_t *request)
+int ec_slave_schedule_eeprom_writing(
+        ec_eeprom_write_request_t *request /**< EEPROM write request */
+        )
 {
     ec_master_t *master = request->slave->master;
 
@@ -889,6 +914,49 @@
 /*****************************************************************************/
 
 /**
+ * Calculates the EEPROM checksum field.
+ *
+ * The checksum is generated with the polynom x^8+x^2+x+1 (0x07) and an
+ * initial value of 0xff (see IEC 61158-6-12 ch. 5.4).
+ *
+ * The below code was originally generated with PYCRC
+ * http://www.tty1.net/pycrc
+ *
+ * ./pycrc.py --width=8 --poly=0x07 --reflect-in=0 --xor-in=0xff
+ *   --reflect-out=0 --xor-out=0 --generate c --algorithm=bit-by-bit
+ *
+ * \return CRC8
+ */
+
+uint8_t ec_slave_eeprom_crc(
+        const uint8_t *data, /**< pointer to data */
+        size_t length /**< number of bytes in \a data */
+        )
+{
+    unsigned int i;
+    uint8_t bit, byte, crc = 0x48;
+
+    while (length--) {
+        byte = *data++;
+        for (i = 0; i < 8; i++) {
+            bit = crc & 0x80;
+            crc = (crc << 1) | ((byte >> (7 - i)) & 0x01);
+            if (bit) crc ^= 0x07;
+        }
+    }
+
+    for (i = 0; i < 8; i++) {
+        bit = crc & 0x80;
+        crc <<= 1;
+        if (bit) crc ^= 0x07;
+    }
+
+    return crc;
+}
+
+/*****************************************************************************/
+
+/**
  * Writes complete EEPROM contents to a slave.
  * \return data size written in case of success, otherwise error code.
  */
@@ -902,6 +970,7 @@
     const uint16_t *cat_header;
     uint16_t cat_type, cat_size;
     int ret;
+    uint8_t crc;
 
     if (slave->master->mode != EC_MASTER_MODE_IDLE) { // FIXME
         EC_ERR("Writing EEPROMs only allowed in idle mode!\n");
@@ -916,24 +985,33 @@
     // init EEPROM write request
     INIT_LIST_HEAD(&request.list);
     request.slave = slave;
-    request.words = (const uint16_t *) data;
-    request.offset = 0;
-    request.size = size / 2;
-
-    if (request.size < 0x0041) {
+    request.data = data;
+    request.word_offset = 0;
+    request.word_size = size / 2;
+
+    if (request.word_size < 0x0041) {
         EC_ERR("EEPROM data too short! Dropping.\n");
         return -EINVAL;
     }
 
-    cat_header = request.words + EC_FIRST_EEPROM_CATEGORY_OFFSET;
+    // calculate checksum
+    crc = ec_slave_eeprom_crc(data, 14); // CRC over words 0 to 6
+    if (crc != data[14]) {
+        EC_WARN("EEPROM CRC incorrect. Must be 0x%02x.\n", crc);
+    }
+
+    cat_header = (const uint16_t *) request.data
+		+ EC_FIRST_EEPROM_CATEGORY_OFFSET;
     cat_type = EC_READ_U16(cat_header);
     while (cat_type != 0xFFFF) { // cycle through categories
-        if (cat_header + 1 > request.words + request.size) {
+        if (cat_header + 1 >
+				(const uint16_t *) request.data + request.word_size) {
             EC_ERR("EEPROM data corrupted! Dropping.\n");
             return -EINVAL;
         }
         cat_size = EC_READ_U16(cat_header + 1);
-        if (cat_header + cat_size + 2 > request.words + request.size) {
+        if (cat_header + cat_size + 2 >
+				(const uint16_t *) request.data + request.word_size) {
             EC_ERR("EEPROM data corrupted! Dropping.\n");
             return -EINVAL;
         }
@@ -962,11 +1040,12 @@
 {
     ec_eeprom_write_request_t request;
     char *remainder;
-    uint16_t alias, word;
+    uint16_t alias;
     int ret;
+    uint8_t eeprom_data[16], crc;
 
     if (slave->master->mode != EC_MASTER_MODE_IDLE) { // FIXME
-        EC_ERR("Writing EEPROMs only allowed in idle mode!\n");
+        EC_ERR("Writing to EEPROM is only allowed in idle mode!\n");
         return -EBUSY;
     }
 
@@ -975,16 +1054,29 @@
         EC_ERR("Invalid alias value! Dropping.\n");
         return -EINVAL;
     }
+
+    if (!slave->eeprom_data || slave->eeprom_size < 16) {
+        EC_ERR("Failed to read EEPROM contents from slave %u.\n",
+                slave->ring_position);
+        return -EINVAL;
+    }
+
+    // copy first 7 words of recent EEPROM contents
+    memcpy(eeprom_data, slave->eeprom_data, 14);
     
-    // correct endianess
-    EC_WRITE_U16(&word, alias);
+    // write new alias address in word 4
+    EC_WRITE_U16(eeprom_data + 8, alias);
+
+    // calculate new checksum over words 0 to 6
+    crc = ec_slave_eeprom_crc(eeprom_data, 14);
+    EC_WRITE_U16(eeprom_data + 14, crc);
 
     // init EEPROM write request
     INIT_LIST_HEAD(&request.list);
     request.slave = slave;
-    request.words = &word;
-    request.offset = 0x0004;
-    request.size = 1;
+    request.data = eeprom_data;
+    request.word_offset = 0x0000;
+    request.word_size = 8;
 
     if ((ret = ec_slave_schedule_eeprom_writing(&request)))
         return ret; // error code
@@ -1094,6 +1186,8 @@
 /*****************************************************************************/
 
 /**
+ * Get the sync manager for either Rx- or Tx-PDOs.
+ * \return pointer to sync manager, or NULL.
  */
 
 ec_sync_t *ec_slave_get_pdo_sync(
@@ -1207,6 +1301,28 @@
     *entry_count = entries;
 }
 
+/*****************************************************************************/
+
+/**
+ * Get an SDO from the dictionary.
+ * \returns The desired SDO, of NULL.
+ */
+
+ec_sdo_t *ec_slave_get_sdo(
+        ec_slave_t *slave /**< EtherCAT slave */,
+        uint16_t index /**< SDO index */
+        )
+{
+    ec_sdo_t *sdo;
+
+    list_for_each_entry(sdo, &slave->sdo_dictionary, list) {
+        if (sdo->index != index) continue;
+        return sdo;
+    }
+
+    return NULL;
+}
+
 /******************************************************************************
  *  Realtime interface
  *****************************************************************************/
@@ -1265,6 +1381,10 @@
 
 /*****************************************************************************/
 
+/**
+ * Clear slave's PDO mapping.
+ */
+
 void ecrt_slave_pdo_mapping_clear(
         ec_slave_t *slave, /**< EtherCAT slave */
         ec_direction_t dir /**< output/input */
@@ -1281,14 +1401,19 @@
         return;
 
     ec_sync_clear_pdos(sync);
-}
-
-/*****************************************************************************/
+    sync->alt_mapping = 1;
+}
+
+/*****************************************************************************/
+
+/**
+ * Add a PDO to the list of known mapped PDOs.
+ */
 
 int ecrt_slave_pdo_mapping_add(
         ec_slave_t *slave, /**< EtherCAT slave */
         ec_direction_t dir, /**< input/output */
-        uint16_t pdo_index /**< Index of PDO mapping list */)
+        uint16_t pdo_index /**< Index of mapped PDO */)
 {
     ec_pdo_t *pdo;
     ec_sync_t *sync;
@@ -1299,7 +1424,7 @@
         return -1;
     }
 
-    // does the slave provide the PDO list?
+    // does the slave provide the PDO?
     list_for_each_entry(pdo, &slave->sii_pdos, list) {
         if (pdo->index == pdo_index) {
             not_found = 0;
@@ -1327,10 +1452,19 @@
         return -1;
     }
 
-    return ec_sync_add_pdo(sync, pdo);
-}
-
-/*****************************************************************************/
+    if (ec_sync_add_pdo(sync, pdo))
+        return -1;
+
+    sync->alt_mapping = 1;
+    return 0;
+}
+
+/*****************************************************************************/
+
+/**
+ * Convenience function for ecrt_slave_pdo_mapping_clear() and
+ * ecrt_slave_pdo_mapping_add().
+ */
 
 int ecrt_slave_pdo_mapping(ec_slave_t *slave, /**< EtherCAT slave */
         ec_direction_t dir, /**< input/output */
--- a/master/slave.h	Thu Sep 13 11:08:46 2007 +0000
+++ b/master/slave.h	Wed Oct 03 08:58:01 2007 +0000
@@ -83,6 +83,7 @@
 /*****************************************************************************/
 
 /**
+ * EtherCAT slave online state.
  */
 
 typedef enum {
@@ -176,6 +177,8 @@
     struct list_head sdo_confs; /**< list of SDO configurations */
     uint8_t sdo_dictionary_fetched; /**< dictionary has been fetched */
     unsigned long jiffies_preop; /**< time, the slave went to PREOP */
+
+    uint8_t pdo_mapping_fetched; /**< PDO mapping has been fetched */
 };
 
 /*****************************************************************************/
@@ -194,8 +197,8 @@
 void ec_slave_set_online_state(ec_slave_t *, ec_slave_online_state_t);
 
 // SII categories
-int ec_slave_fetch_sii_strings(ec_slave_t *, const uint8_t *);
-void ec_slave_fetch_sii_general(ec_slave_t *, const uint8_t *);
+int ec_slave_fetch_sii_strings(ec_slave_t *, const uint8_t *, size_t);
+int ec_slave_fetch_sii_general(ec_slave_t *, const uint8_t *, size_t);
 int ec_slave_fetch_sii_syncs(ec_slave_t *, const uint8_t *, size_t);
 int ec_slave_fetch_sii_pdos(ec_slave_t *, const uint8_t *, size_t,
         ec_pdo_type_t);
@@ -205,6 +208,7 @@
 int ec_slave_validate(const ec_slave_t *, uint32_t, uint32_t);
 void ec_slave_sdo_dict_info(const ec_slave_t *,
         unsigned int *, unsigned int *);
+ec_sdo_t *ec_slave_get_sdo(ec_slave_t *, uint16_t);
 
 /*****************************************************************************/
 
--- a/master/sync.c	Thu Sep 13 11:08:46 2007 +0000
+++ b/master/sync.c	Wed Oct 03 08:58:01 2007 +0000
@@ -140,6 +140,8 @@
 /*****************************************************************************/
 
 /**
+ * Adds a PDO to the list of known mapped PDOs.
+ * \return 0 on success, else < 0
  */
 
 int ec_sync_add_pdo(
@@ -172,13 +174,13 @@
     mapped_pdo->sync_index = sync->index;
 
     list_add_tail(&mapped_pdo->list, &sync->pdos);
-    sync->alt_mapping = 1;
     return 0;
 }
 
 /*****************************************************************************/
 
 /**
+ * Clears the list of known mapped PDOs.
  */
 
 void ec_sync_clear_pdos(
@@ -193,8 +195,30 @@
         ec_pdo_clear(pdo);
         kfree(pdo);
     }
-
-    sync->alt_mapping = 1;
-}
-
-/*****************************************************************************/
+}
+
+/*****************************************************************************/
+
+/**
+ * \return Type of PDOs covered by the given sync manager.
+ */
+
+ec_pdo_type_t ec_sync_get_pdo_type(
+        const ec_sync_t *sync /**< EtherCAT sync manager */
+        )
+{
+    int index = sync->index;
+
+    if (sync->slave && sync->slave->sii_mailbox_protocols) {
+        index -= 2;
+    }
+
+    if (index < 0 || index > 1) {
+        EC_WARN("ec_sync_get_pdo_type(): invalid sync manager index.\n");
+        return EC_RX_PDO;
+    }
+
+    return (ec_pdo_type_t) index;
+}
+
+/*****************************************************************************/
--- a/master/sync.h	Thu Sep 13 11:08:46 2007 +0000
+++ b/master/sync.h	Wed Oct 03 08:58:01 2007 +0000
@@ -83,6 +83,8 @@
 int ec_sync_add_pdo(ec_sync_t *, const ec_pdo_t *);
 void ec_sync_clear_pdos(ec_sync_t *);
 
+ec_pdo_type_t ec_sync_get_pdo_type(const ec_sync_t *);
+
 /*****************************************************************************/
 
 #endif